diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 42150e1a2c55..000000000000 --- a/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -node_modules/ -/packages/core-js-bundle/ -/packages/core-js-pure/override/ -/tests/bundles/ -!**/.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 963704d08615..000000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,616 +0,0 @@ -'use strict'; -const SUPPORTED_NODE_VERSIONS = require('./package.json').engines.node; -const webpack = require('./.webpack.config.js'); - -const base = { - // possible errors: - // enforce 'for' loop update clause moving the counter in the right direction - 'for-direction': 'error', - // disallow window alert / confirm / prompt calls - 'no-alert': 'error', - // disallow comparing against -0 - 'no-compare-neg-zero': 'error', - // disallow use of console - 'no-console': 'error', - // disallow constant expressions in conditions - 'no-constant-condition': ['error', { checkLoops: false }], - // disallow control characters in regular expressions - 'no-control-regex': 'error', - // disallow use of debugger - 'no-debugger': 'error', - // disallow duplicate arguments in functions - 'no-dupe-args': 'error', - // disallow duplicate keys when creating object literals - 'no-dupe-keys': 'error', - // disallow a duplicate case label. - 'no-duplicate-case': 'error', - // disallow else after a return in an if - 'no-else-return': 'error', - // disallow empty statements - 'no-empty': 'error', - // disallow the use of empty character classes in regular expressions - 'no-empty-character-class': 'error', - // disallow unnecessary boolean casts - 'no-extra-boolean-cast': 'error', - // disallow unnecessary semicolons - 'no-extra-semi': 'error', - // disallow assigning to the exception in a catch block - 'no-ex-assign': 'error', - // disallow overwriting functions written as function declarations - 'no-func-assign': 'error', - // disallow invalid regular expression strings in the RegExp constructor - 'no-invalid-regexp': 'error', - // disallow irregular whitespace outside of strings and comments - 'no-irregular-whitespace': 'error', - // disallow characters which are made with multiple code points in character class syntax - 'no-misleading-character-class': 'error', - // disallow the use of object properties of the global object (Math and JSON) as functions - 'no-obj-calls': 'error', - // disallow use of Object.prototypes builtins directly - 'no-prototype-builtins': 'error', - // disallow multiple spaces in a regular expression literal - 'no-regex-spaces': 'error', - // disallow sparse arrays - 'no-sparse-arrays': 'error', - // disallow template literal placeholder syntax in regular strings - 'no-template-curly-in-string': 'error', - // avoid code that looks like two expressions but is actually one - 'no-unexpected-multiline': 'error', - // disallow negation of the left operand of an in expression - 'no-unsafe-negation': 'error', - // disallow comparisons with the value NaN - 'use-isnan': 'error', - // disallow unreachable statements after a return, throw, continue, or break statement - 'no-unreachable': 'error', - // ensure that the results of typeof are compared against a valid string - 'valid-typeof': 'error', - - // best practices: - // enforces return statements in callbacks of array's methods - 'array-callback-return': 'error', - // encourages use of dot notation whenever possible - 'dot-notation': ['error', { allowKeywords: true }], - // enforce newline before and after dot - 'dot-location': ['error', 'property'], - // disallow use of arguments.caller or arguments.callee - 'no-caller': 'error', - // disallow lexical declarations in case/default clauses - 'no-case-declarations': 'error', - // disallow empty functions, except for standalone funcs/arrows - 'no-empty-function': 'error', - // disallow empty destructuring patterns - 'no-empty-pattern': 'error', - // disallow use of eval() - 'no-eval': 'error', - // disallow adding to native types - 'no-extend-native': 'error', - // disallow unnecessary function binding - 'no-extra-bind': 'error', - // disallow unnecessary labels - 'no-extra-label': 'error', - // disallow fallthrough of case statements - 'no-fallthrough': 'error', - // disallow the use of leading or trailing decimal points in numeric literals - 'no-floating-decimal': 'error', - // disallow reassignments of native objects - 'no-global-assign': 'error', - // disallow use of eval()-like methods - 'no-implied-eval': 'error', - // disallow usage of __iterator__ property - 'no-iterator': 'error', - // disallow use of labels for anything other then loops and switches - 'no-labels': ['error', { allowLoop: false, allowSwitch: false }], - // disallow unnecessary nested blocks - 'no-lone-blocks': 'error', - // disallow function declarations and expressions inside loop statements - 'no-loop-func': 'error', - // disallow use of multiple spaces - 'no-multi-spaces': ['error', { ignoreEOLComments: true }], - // disallow use of multiline strings - 'no-multi-str': 'error', - // disallow use of new operator when not part of the assignment or comparison - 'no-new': 'error', - // disallow use of new operator for Function object - 'no-new-func': 'error', - // disallows creating new instances of String, Number, and Boolean - 'no-new-wrappers': 'error', - // disallow use of (old style) octal literals - 'no-octal': 'error', - // disallow use of octal escape sequences in string literals, such as var foo = 'Copyright \251'; - 'no-octal-escape': 'error', - // disallow usage of __proto__ property - 'no-proto': 'error', - // disallow declaring the same variable more then once - 'no-redeclare': 'error', - // disallow unnecessary calls to `.call()` and `.apply()` - 'no-useless-call': 'error', - // disallow redundant return statements - 'no-useless-return': 'error', - // disallow use of `javascript:` urls. - 'no-script-url': 'error', - // disallow self assignment - 'no-self-assign': 'error', - // disallow comparisons where both sides are exactly the same - 'no-self-compare': 'error', - // disallow use of comma operator - 'no-sequences': 'error', - // restrict what can be thrown as an exception - 'no-throw-literal': 'error', - // disallow usage of expressions in statement position - 'no-unused-expressions': ['error', { allowShortCircuit: true, allowTernary: true }], - // disallow unused labels - 'no-unused-labels': 'error', - // disallow unnecessary catch clauses - 'no-useless-catch': 'error', - // disallow useless string concatenation - 'no-useless-concat': 'error', - // disallow unnecessary string escaping - 'no-useless-escape': 'error', - // disallow void operators - 'no-void': 'error', - // disallow use of the with statement - 'no-with': 'error', - // require use of the second argument for parseInt() - radix: 'error', - - // variables: - // disallow catch clause parameters from shadowing variables in the outer scope - 'no-catch-shadow': 'error', - // disallow deletion of variables - 'no-delete-var': 'error', - // disallow labels that share a name with a variable - 'no-label-var': 'error', - // disallow declaration of variables already declared in the outer scope - 'no-shadow': 'error', - // disallow shadowing of names such as arguments - 'no-shadow-restricted-names': 'error', - // disallow use of undeclared variables unless mentioned in a /*global */ block - 'no-undef': ['error'], - // disallow initializing variables to undefined - 'no-undef-init': 'error', - // disallow declaration of variables that are not used in the code - 'no-unused-vars': ['error', { vars: 'local', args: 'after-used', ignoreRestSiblings: true }], - - // stylistic issues: - // enforce spacing inside array brackets - 'array-bracket-spacing': ['error', 'never'], - // enforce spacing inside single-line blocks - 'block-spacing': ['error', 'always'], - // enforce one true brace style - 'brace-style': ['error', '1tbs', { allowSingleLine: true }], - // require camel case names - camelcase: ['error', { properties: 'never' }], - // enforce trailing commas in multiline object literals - 'comma-dangle': ['error', 'always-multiline'], - // enforce spacing after comma - 'comma-spacing': 'error', - // enforce one true comma style - 'comma-style': ['error', 'last', { exceptions: { VariableDeclaration: true } }], - // disallow padding inside computed properties - 'computed-property-spacing': ['error', 'never'], - // enforce one newline at the end of files - 'eol-last': ['error', 'always'], - // disallow space between function identifier and application - 'func-call-spacing': 'error', - // this option sets a specific tab width for your code - 'indent-legacy': ['error', 2, { VariableDeclarator: 2, SwitchCase: 1 }], - // require a space before & after certain keywords - 'keyword-spacing': ['error', { before: true, after: true }], - // enforces spacing between keys and values in object literal properties - 'key-spacing': ['error', { beforeColon: false, afterColon: true }], - // enforce consistent linebreak style - 'linebreak-style': ['error', 'unix'], - // specify the maximum length of a line in your program - 'max-len': ['error', 120, 2], - // enforce a maximum depth that callbacks can be nested - 'max-nested-callbacks': ['error', 4], - // specify the maximum number of statement allowed in a function - 'max-statements': ['error', 40], - // require a capital letter for constructors - 'new-cap': ['error', { newIsCap: true, capIsNew: false }], - // require parentheses when invoking a constructor with no arguments - 'new-parens': 'error', - // disallow if as the only statement in an else block - 'no-lonely-if': 'error', - // disallow mixed spaces and tabs for indentation - 'no-mixed-spaces-and-tabs': 'error', - // disallow multiple empty lines and only one newline at the end - 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 1 }], - // disallow tabs - 'no-tabs': 'error', - // disallow trailing whitespace at the end of lines - 'no-trailing-spaces': 'error', - // disallow the use of boolean literals in conditional expressions and prefer `a || b` over `a ? a : b` - 'no-unneeded-ternary': ['error', { defaultAssignment: false }], - // disallow whitespace before properties - 'no-whitespace-before-property': 'error', - // enforce the location of single-line statements - 'nonblock-statement-body-position': ['error', 'beside'], - // enforce spaces inside braces - 'object-curly-spacing': ['error', 'always'], - // require newlines around variable declarations with initializations - 'one-var-declaration-per-line': ['error', 'initializations'], - // enforce padding within blocks - 'padded-blocks': ['error', 'never'], - // specify whether double or single quotes should be used - quotes: ['error', 'single', 'avoid-escape'], - // require or disallow use of quotes around object literal property names - 'quote-props': ['error', 'as-needed', { keywords: false }], - // require or disallow use of semicolons instead of ASI - semi: ['error', 'always'], - // enforce spacing before and after semicolons - 'semi-spacing': 'error', - // enforce location of semicolons - 'semi-style': ['error', 'last'], - // require or disallow space before blocks - 'space-before-blocks': 'error', - // require or disallow space before function opening parenthesis - 'space-before-function-paren': ['error', { anonymous: 'always', named: 'never' }], - // require or disallow spaces inside parentheses - 'space-in-parens': 'error', - // require spaces around operators - 'space-infix-ops': 'error', - // Require or disallow spaces before/after unary operators - 'space-unary-ops': 'error', - // require or disallow a space immediately following the // or /* in a comment - 'spaced-comment': ['error', 'always', { line: { exceptions: ['/'] }, block: { exceptions: ['*'] } }], - // enforce spacing around colons of switch statements - 'switch-colon-spacing': 'error', - // require or disallow the Unicode Byte Order Mark - 'unicode-bom': ['error', 'never'], - - // commonjs: - // require require() calls to be placed at top-level module scope - 'global-require': 'error', - // disallow require calls to be mixed with regular variable declarations - 'no-mixed-requires': ['error', { grouping: true, allowCall: false }], - // disallow new operators with calls to require - 'no-new-require': 'error', - // disallow string concatenation with `__dirname` and `__filename` - 'no-path-concat': 'error', - - // import: - // ensure all imports appear before other statements - 'import/first': 'error', - // forbid AMD imports - 'import/no-amd': 'error', - // forbid cycle dependencies - 'import/no-cycle': ['error', { commonjs: true }], - // ensure imports point to files / modules that can be resolved - 'import/no-unresolved': ['error', { commonjs: true }], - // forbid import of modules using absolute paths - 'import/no-absolute-path': 'error', - // forbid `require()` calls with expressions - 'import/no-dynamic-require': 'error', - // disallow importing from the same path more than once - 'import/no-duplicates': 'error', - // forbid a module from importing itself - 'import/no-self-import': 'error', - // forbid useless path segments - 'import/no-useless-path-segments': 'error', - - // node: - // enforce the style of file extensions in `import` declarations - 'node/file-extension-in-import': ['error', 'never'], - // disallow the assignment to `exports` - 'node/no-exports-assign': 'error', - - // es6: - // require parentheses around arrow function arguments - 'arrow-parens': ['error', 'as-needed'], - // enforce consistent spacing before and after the arrow in arrow functions - 'arrow-spacing': 'error', - // enforce the location of arrow function bodies - 'implicit-arrow-linebreak': ['error', 'beside'], - // disallow unnecessary computed property keys in object literals - 'no-useless-computed-key': 'error', - // disallow unnecessary constructors - 'no-useless-constructor': 'error', - // require let or const instead of var - 'no-var': 'error', - // disallow renaming import, export, and destructured assignments to the same name - 'no-useless-rename': 'error', - // require or disallow method and property shorthand syntax for object literals - 'object-shorthand': 'error', - // require using arrow functions for callbacks - 'prefer-arrow-callback': 'error', - // require const declarations for variables that are never reassigned after declared - 'prefer-const': ['error', { destructuring: 'all' }], - // require destructuring from arrays and/or objects - 'prefer-destructuring': 'error', - // require template literals instead of string concatenation - 'prefer-template': 'error', - // enforce spacing between rest and spread operators and their expressions - 'rest-spread-spacing': 'error', - // require or disallow spacing around embedded expressions of template strings - 'template-curly-spacing': ['error', 'always'], - - // require strict mode directives - strict: ['error', 'global'], - - // unicorn - // enforce a specific parameter name in catch clauses - 'unicorn/catch-error-name': ['error', { name: 'error', caughtErrorsIgnorePattern: '^err' }], - // enforce passing a message value when throwing a built-in error - 'unicorn/error-message': 'error', - // require escape sequences to use uppercase values - 'unicorn/escape-case': 'error', - // enforce a case style for filenames - 'unicorn/filename-case': ['error', { case: 'kebabCase' }], - // enforce importing index files with `.` - 'unicorn/import-index': 'error', - // enforce specifying rules to disable in eslint-disable comments - 'unicorn/no-abusive-eslint-disable': 'error', - // do not use leading/trailing space between `console.log` parameters - 'unicorn/no-console-spaces': 'error', - // enforce the use of unicode escapes instead of hexadecimal escapes - 'unicorn/no-hex-escape': 'error', - // disallow unreadable array destructuring - 'unicorn/no-unreadable-array-destructuring': 'error', - // disallow unsafe regular expressions - 'unicorn/no-unsafe-regex': 'error', - // disallow unused object properties - 'unicorn/no-unused-properties': 'error', - // enforce lowercase identifier and uppercase value for number literals - 'unicorn/number-literal-case': 'error', - // prefer the exponentiation operator over `Math.pow()` - 'unicorn/prefer-exponentiation-operator': 'error', - // prefer `String#slice` over `String#{ substr, substring }` - 'unicorn/prefer-string-slice': 'error', - // enforce the use of regex shorthands to improve readability - 'unicorn/regex-shorthand': 'error', - - // optimize regex literals - 'optimize-regex/optimize-regex': 'error', - - // sonarjs - // merging collapsible if statements increases the code's readability - 'sonarjs/no-collapsible-if': 'error', - // two branches in a conditional structure should not have exactly the same implementation - 'sonarjs/no-duplicated-branches': 'error', - // collection elements should not be replaced unconditionally - 'sonarjs/no-element-overwrite': 'error', - // function calls should not pass extra arguments - 'sonarjs/no-extra-arguments': 'error', - // related `if / else if` statements should not have the same condition - 'sonarjs/no-identical-conditions': 'error', - // functions should not have identical implementations - 'sonarjs/no-identical-functions': 'error', - // boolean checks should not be inverted - 'sonarjs/no-inverted-boolean-check': 'error', - // loops with at most one iteration should be refactored - 'sonarjs/no-one-iteration-loop': 'error', - // boolean literals should not be redundant - 'sonarjs/no-redundant-boolean': 'error', - // the output of functions that don't return anything should not be used - 'sonarjs/no-use-of-empty-return-value': 'error', - // local variables should not be declared and then immediately returned or thrown - 'sonarjs/prefer-immediate-return': 'error', - // object literal syntax should be used - 'sonarjs/prefer-object-literal': 'error', - // return of boolean expressions should not be wrapped into an `if-then-else` statement - 'sonarjs/prefer-single-boolean-return': 'error', - // a `while` loop should be used instead of a `for` loop with condition only - 'sonarjs/prefer-while': 'error', -}; - -const es3 = { - // disallow trailing commas in multiline object literals - 'comma-dangle': ['error', 'never'], - // encourages use of dot notation whenever possible - 'dot-notation': ['error', { allowKeywords: false }], - // disallow function or variable declarations in nested blocks - 'no-inner-declarations': 'error', - // require let or const instead of var - 'no-var': 'off', - // require or disallow method and property shorthand syntax for object literals - 'object-shorthand': 'off', - // require using arrow functions for callbacks - 'prefer-arrow-callback': 'off', - // require const declarations for variables that are never reassigned after declared - 'prefer-const': 'off', - // require template literals instead of string concatenation - 'prefer-template': 'off', - // require or disallow use of quotes around object literal property names - 'quote-props': ['error', 'as-needed', { keywords: true }], - // require strict mode directives - strict: 'off', - // prefer the exponentiation operator over `Math.pow()` - 'unicorn/prefer-exponentiation-operator': 'off', - // require destructuring from arrays and/or objects - 'prefer-destructuring': 'off', -}; - -const node = { - // disallow deprecated APIs - 'node/no-deprecated-api': 'error', - // disallow unsupported ECMAScript built-ins on the specified version - 'node/no-unsupported-features/es-builtins': ['error', { version: SUPPORTED_NODE_VERSIONS }], - // disallow unsupported ECMAScript syntax on the specified version - 'node/no-unsupported-features/es-syntax': ['error', { version: SUPPORTED_NODE_VERSIONS }], -}; - -const tests = { - // require strict mode directives - strict: 'off', - - // relax for testing: - // enforces return statements in callbacks of array's methods - 'array-callback-return': 'off', - // specify the maximum length of a line in your program - 'max-len': ['error', 180, 2], - // specify the maximum number of statement allowed in a function - 'max-statements': 'off', - // disallow function declarations and expressions inside loop statements - 'no-loop-func': 'off', - // disallow use of new operator when not part of the assignment or comparison - 'no-new': 'off', - // disallow use of new operator for Function object - 'no-new-func': 'off', - // disallows creating new instances of String, Number, and Boolean - 'no-new-wrappers': 'off', - // restrict what can be thrown as an exception - 'no-throw-literal': 'off', - // disallow usage of expressions in statement position - 'no-unused-expressions': 'off', - // disallow unnecessary calls to `.call()` and `.apply()` - 'no-useless-call': 'off', - // enforce passing a message value when throwing a built-in error - 'unicorn/error-message': 'off', - // functions should not have identical implementations - 'sonarjs/no-identical-functions': 'off', -}; - -const qunit = { - // ensure the correct number of assert arguments is used - 'qunit/assert-args': 'error', - // forbid the use of assert.equal - 'qunit/no-assert-equal': 'error', - // forbid binary logical expressions in assert arguments - 'qunit/no-assert-logical-expression': 'error', - // forbid async calls in loops - 'qunit/no-async-in-loops': 'error', - // forbid the use of asyncTest - 'qunit/no-async-test': 'error', - // forbid commented tests - 'qunit/no-commented-tests': 'error', - // forbid comparing relational expression to boolean in assertions - 'qunit/no-compare-relation-boolean': 'error', - // prevent early return in a qunit test - 'qunit/no-early-return': 'error', - // forbid the use of global qunit assertions - 'qunit/no-global-assertions': 'error', - // forbid the use of global expect - 'qunit/no-global-expect': 'error', - // forbid the use of global module / test / asyncTest - 'qunit/no-global-module-test': 'error', - // forbid use of global stop / start - 'qunit/no-global-stop-start': 'error', - // forbid identical test and module names - 'qunit/no-identical-names': 'error', - // forbid use of QUnit.init - 'qunit/no-init': 'error', - // forbid use of QUnit.jsDump - 'qunit/no-jsdump': 'error', - // forbid equality comparisons in assert.{ok, notOk} - 'qunit/no-ok-equality': 'error', - // forbid the use of QUnit.push - 'qunit/no-qunit-push': 'error', - // forbid QUnit.start within tests or test hooks - 'qunit/no-qunit-start-in-tests': 'error', - // forbid the use of QUnit.stop - 'qunit/no-qunit-stop': 'error', - // forbid overwriting of QUnit logging callbacks - 'qunit/no-reassign-log-callbacks': 'error', - // forbid use of QUnit.reset - 'qunit/no-reset': 'error', - // forbid setup / teardown module hooks - 'qunit/no-setup-teardown': 'error', - // forbid expect argument in QUnit.test - 'qunit/no-test-expect-argument': 'error', - // forbid assert.throws() with block, string, and message - 'qunit/no-throws-string': 'error', - // require that all async calls should be resolved in tests - 'qunit/resolve-async': 'error', -}; - -module.exports = { - root: true, - parserOptions: { - ecmaVersion: 2020, - }, - env: { - browser: true, - node: true, - worker: true, - }, - plugins: [ - 'import', - 'node', - 'optimize-regex', - 'qunit', - 'sonarjs', - 'unicorn', - ], - settings: { - 'import/resolver': { - webpack: { - config: webpack.options, - }, - }, - }, - reportUnusedDisableDirectives: true, - rules: base, - overrides: [ - { - files: [ - 'packages/core-js/**', - 'packages/core-js-pure/**', - 'tests/promises-aplus/**', - 'tests/compat/**', - ], - parserOptions: { - ecmaVersion: 3, - }, - rules: es3, - }, - { - files: [ - 'tests/helpers/**', - 'tests/pure/**', - 'tests/tests/**', - 'tests/wpt-url-resources/**', - 'tests/commonjs.js', - ], - parserOptions: { - sourceType: 'module', - }, - rules: tests, - }, - { - files: [ - 'tests/helpers/**', - 'tests/pure/**', - 'tests/tests/**', - ], - env: { - qunit: true, - }, - rules: qunit, - }, - { - files: [ - 'packages/core-js-builder/**', - 'packages/core-js-compat/**', - 'tests/commonjs.js', - '.eslintrc.js', - '.webpack.config.js', - 'babel.config.js', - 'Gruntfile.js', - ], - env: { - es6: true, - }, - rules: node, - }, - { - files: [ - 'tests/tests/**', - 'tests/compat/**', - ], - env: { - es6: true, - }, - globals: { - compositeKey: true, - compositeSymbol: true, - globalThis: true, - queueMicrotask: true, - AggregateError: true, - AsyncIterator: true, - Iterator: true, - Observable: true, - }, - }, - ], -}; diff --git a/.gitattributes b/.gitattributes index 07764a78d984..90eaec19360f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ -* text eol=lf \ No newline at end of file +* text eol=lf + +*.png binary diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 14c4721d84a5..461584df68e6 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,3 @@ open_collective: core-js patreon: zloirock -tidelift: npm/core-js +custom: https://boosty.to/zloirock diff --git a/.github/workflows/build-and-deploy-pages.yml b/.github/workflows/build-and-deploy-pages.yml new file mode 100644 index 000000000000..da6b2fc5b4f3 --- /dev/null +++ b/.github/workflows/build-and-deploy-pages.yml @@ -0,0 +1,106 @@ +name: Build and Deploy pages to GitHub Pages +on: [push, workflow_dispatch] + +permissions: + contents: read + pages: write + id-token: write + +jobs: + list-branches: + runs-on: ubuntu-latest + outputs: + branches: ${{ steps.set-branches.outputs.branches }} + steps: + - name: Checkout repo + uses: actions/checkout@v6 + with: + fetch-depth: 0 + - name: Get branch list and set output + id: set-branches + run: | + BRANCHES=$( + git branch -r | + grep -Ev 'HEAD|v1|v2' | + sed 's/^[ *]*//' | + sed 's/^origin\///' | + jq -R . | + jq -cs + ) + echo "branches=$BRANCHES" >> "$GITHUB_OUTPUT" + + build-compat-pages: + needs: list-branches + runs-on: ubuntu-latest + strategy: + matrix: + branch: ${{ fromJson(needs.list-branches.outputs.branches) }} + name: Build for ${{ matrix.branch }} + steps: + - uses: actions/checkout@v6 + with: + ref: ${{ matrix.branch }} + - name: Build cache key + id: cache-key + run: | + HASH=$(git rev-parse --short HEAD) + echo "CACHE_KEY=${{ matrix.branch }}-$HASH" >> "$GITHUB_ENV" + - name: Restore cached artifacts + id: artifacts-restore + uses: actions/cache/restore@v5 + with: + path: ${{ matrix.branch }} + key: ${{ env.CACHE_KEY }} + - uses: actions/setup-node@v6 + if: steps.artifacts-restore.outputs.cache-hit != 'true' + with: + node-version: 25 + cache: npm + - name: Build + if: steps.artifacts-restore.outputs.cache-hit != 'true' + run: | + npm run prepare-monorepo + npm run build-compat + npm run bundle + - name: Prepare build artifacts + if: steps.artifacts-restore.outputs.cache-hit != 'true' + run: | + mkdir -p ${{ matrix.branch }}/compat + cp tests/compat/index.html tests/compat/compat-data.js tests/compat/tests.js tests/compat/browsers-runner.js ${{ matrix.branch }}/compat + mkdir -p ${{ matrix.branch }}/bundles + cp tests/bundles/* ${{ matrix.branch }}/bundles + mkdir -p ${{ matrix.branch }}/unit-browser + cp tests/unit-browser/* ${{ matrix.branch }}/unit-browser + - name: Save cached artifacts + if: steps.artifacts-restore.outputs.cache-hit != 'true' + uses: actions/cache/save@v5 + with: + path: ${{ matrix.branch }} + key: ${{ env.CACHE_KEY }} + - name: Upload artifacts for branch ${{ matrix.branch }} + uses: actions/upload-artifact@v6 + with: + name: ${{ matrix.branch }} + path: ${{ matrix.branch }} + + combine-pages-and-deploy: + needs: build-compat-pages + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - uses: actions/checkout@v6 + - name: Download artifacts + uses: actions/download-artifact@v7 + with: + path: pages + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Upload GitHub Pages artifact + uses: actions/upload-pages-artifact@v4 + with: + path: pages + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.github/workflows/build-bundles.yml b/.github/workflows/build-bundles.yml new file mode 100644 index 000000000000..98e028f8f756 --- /dev/null +++ b/.github/workflows/build-bundles.yml @@ -0,0 +1,51 @@ +name: Build bundles + +on: push + +jobs: + build-and-upload: + runs-on: ubuntu-latest + + steps: + - name: Extract branch name + shell: bash + run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + id: extract_branch + + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Use Node.js + uses: actions/setup-node@v6 + with: + node-version: 25 + cache: npm + + - name: Install dependencies + run: npm run prepare-monorepo + + - name: Build bundle + run: npm run bundle-package minified-name core-js-bundle + + - name: Copy files to server over SSH + uses: appleboy/scp-action@v1 + with: + host: ${{ secrets.REMOTE_HOST }} + username: ci + key: ${{ secrets.CI_SSH_KEY }} + source: "packages/core-js-bundle/core-js-bundle.js" + target: "/var/www/core-js/bundles/${{ steps.extract_branch.outputs.branch }}/" + strip_components: 2 + + - name: Build esmodules bundle + run: npm run bundle-package esmodules minified-name core-js-bundle-esmodules + + - name: Copy files to server over SSH + uses: appleboy/scp-action@v1 + with: + host: ${{ secrets.REMOTE_HOST }} + username: ci + key: ${{ secrets.CI_SSH_KEY }} + source: "packages/core-js-bundle/core-js-bundle-esmodules.js" + target: "/var/www/core-js/bundles/${{ steps.extract_branch.outputs.branch }}/" + strip_components: 2 diff --git a/.github/workflows/build-website-for-branch.yml b/.github/workflows/build-website-for-branch.yml new file mode 100644 index 000000000000..7eafd02bd316 --- /dev/null +++ b/.github/workflows/build-website-for-branch.yml @@ -0,0 +1,62 @@ +name: Build website for branch + +on: + push: + branches-ignore: + - master + workflow_dispatch: + +jobs: + run-on-server: + runs-on: ubuntu-latest + + steps: + - name: Extract branch name + shell: bash + run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + id: extract_branch + + - name: Checkout code + uses: actions/checkout@v6 + with: + ref: ${{ steps.extract_branch.outputs.branch }} + + - name: Copy runner file to remote server + uses: garygrossgarten/github-action-scp@0.9.0 + with: + local: website/scripts/runner.mjs + remote: /var/www/core-js/runner.mjs + host: ${{ secrets.REMOTE_HOST }} + username: ci + privateKey: ${{ secrets.CI_SSH_KEY }} + + - name: Copy runner wrapper file to remote server + uses: garygrossgarten/github-action-scp@0.9.0 + with: + local: website/scripts/runner.sh + remote: /var/www/core-js/runner.sh + host: ${{ secrets.REMOTE_HOST }} + username: ci + privateKey: ${{ secrets.CI_SSH_KEY }} + + - name: Copy runner helpers file to remote server + uses: garygrossgarten/github-action-scp@0.9.0 + with: + local: website/scripts/helpers.mjs + remote: /var/www/core-js/helpers.mjs + host: ${{ secrets.REMOTE_HOST }} + username: ci + privateKey: ${{ secrets.CI_SSH_KEY }} + + - name: Setup SSH + uses: webfactory/ssh-agent@v0.9.1 + with: + ssh-private-key: ${{ secrets.CI_SSH_KEY }} + + - name: Make runner.sh executable on remote + run: | + ssh -o StrictHostKeyChecking=no ci@${{ secrets.REMOTE_HOST }} "chmod +x /var/www/core-js/runner.sh" + + - name: Run node runner.mjs on remote server + run: | + ssh -o StrictHostKeyChecking=no ci@${{ secrets.REMOTE_HOST }} "cd /var/www/core-js/ && ./runner.sh ${{ steps.extract_branch.outputs.branch }}" diff --git a/.github/workflows/build-website.yml b/.github/workflows/build-website.yml new file mode 100644 index 000000000000..7377a45980d6 --- /dev/null +++ b/.github/workflows/build-website.yml @@ -0,0 +1,62 @@ +name: Build website + +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + run-on-server: + runs-on: ubuntu-latest + + steps: + - name: Extract branch name + shell: bash + run: echo "branch=${GITHUB_REF#refs/heads/}" >> $GITHUB_OUTPUT + id: extract_branch + + - name: Checkout code + uses: actions/checkout@v6 + with: + ref: ${{ steps.extract_branch.outputs.branch }} + + - name: Copy runner file to remote server + uses: garygrossgarten/github-action-scp@0.9.0 + with: + local: website/scripts/runner.mjs + remote: /var/www/core-js/runner.mjs + host: ${{ secrets.REMOTE_HOST }} + username: ci + privateKey: ${{ secrets.CI_SSH_KEY }} + + - name: Copy runner wrapper file to remote server + uses: garygrossgarten/github-action-scp@0.9.0 + with: + local: website/scripts/runner.sh + remote: /var/www/core-js/runner.sh + host: ${{ secrets.REMOTE_HOST }} + username: ci + privateKey: ${{ secrets.CI_SSH_KEY }} + + - name: Copy runner helpers file to remote server + uses: garygrossgarten/github-action-scp@0.9.0 + with: + local: website/scripts/helpers.mjs + remote: /var/www/core-js/helpers.mjs + host: ${{ secrets.REMOTE_HOST }} + username: ci + privateKey: ${{ secrets.CI_SSH_KEY }} + + - name: Setup SSH + uses: webfactory/ssh-agent@v0.9.1 + with: + ssh-private-key: ${{ secrets.CI_SSH_KEY }} + + - name: Make runner.sh executable on remote + run: | + ssh -o StrictHostKeyChecking=no ci@${{ secrets.REMOTE_HOST }} "chmod +x /var/www/core-js/runner.sh" + + - name: Run node runner.mjs on remote server + run: | + ssh -o StrictHostKeyChecking=no ci@${{ secrets.REMOTE_HOST }} "cd /var/www/core-js/ && ./runner.sh" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000000..7b01c6333bbc --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,91 @@ +name: ci + +on: [push, pull_request] + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: 25 + cache: npm + - uses: actions/setup-python@v6 + with: + python-version: 3.14 + - run: npm run prepare-monorepo + - run: pip install codespell + - run: npx run-s lint-raw codespell + + karma: + runs-on: windows-2022 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: 25 + cache: npm + - run: npm run prepare-monorepo + - run: npx run-s bundle test-unit-karma + + bun: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: 25 + cache: npm + - uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + - run: npm run prepare-monorepo + - run: npx run-s bundle test-unit-bun + + promises-and-observables: + strategy: + matrix: + node: + - 20.9 + - 21 + - ^22.5.1 + - 23 + - 24 + - 25 + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node }} + cache: npm + - run: npm run prepare-monorepo + - run: npx run-s test-promises test-observables + + tests: + strategy: + matrix: + os: + - ubuntu-latest + - windows-latest + - macos-latest + node: + - 20.9 + - 21 + - ^22.5.1 + - 23 + - 24 + - 25 + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-node@v6 + with: + node-version: ${{ matrix.node }} + cache: npm + - run: npm run prepare-monorepo + - run: npx run-s bundle test-unit-node test-entries test-compat-data test-compat-tools test-builder diff --git a/.gitignore b/.gitignore index f48534948223..197b2072e68f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,22 @@ npm-shrinkwrap.json -package-lock.json yarn.lock node_modules/ *.tmp *.log *.bak *.swp +.DS_Store +.idea +/bundles/ +/docs/web/blog/ +/docs/web/changelog.md +/docs/web/contributing.md +/docs/web/security.md +/packages/core-js/features/ +/packages/core-js/es/index.js +/packages/core-js/full/index.js +/packages/core-js/stable/index.js /packages/core-js/LICENSE /packages/core-js-builder/LICENSE /packages/core-js-bundle/LICENSE @@ -17,9 +27,13 @@ node_modules/ /packages/core-js-compat/LICENSE /packages/core-js-compat/data.json /packages/core-js-compat/entries.json +/packages/core-js-compat/external.json +/packages/core-js-compat/modules.json /packages/core-js-compat/modules-by-versions.json +/packages/core-js-pure/actual/ /packages/core-js-pure/es/ /packages/core-js-pure/features/ +/packages/core-js-pure/full/ /packages/core-js-pure/internals/ /packages/core-js-pure/modules/ /packages/core-js-pure/proposals/ @@ -30,4 +44,11 @@ node_modules/ /packages/core-js-pure/index.js /packages/core-js-pure/configurator.js /packages/core-js-pure/postinstall.js -/tests/bundles/ +/tests/**/bundles/ +/tests/compat/*.jar +/tests/compat/compat-data.js +/tests/unit-global/index.js +/tests/unit-pure/index.js +/website/templates/ +/website/dist/ +/website/src/public/ diff --git a/.npmrc b/.npmrc index 43c97e719a5a..a145f5afba5f 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1,4 @@ -package-lock=false +audit=false +fund=false +lockfile-version=3 +loglevel=error diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index ceaca4f56aad..000000000000 --- a/.travis.yml +++ /dev/null @@ -1,12 +0,0 @@ -language: node_js -node_js: - - '13' - - '12' - - '10' - - '8' -os: - - windows - - linux - - osx - -sudo: false diff --git a/.webpack.config.js b/.webpack.config.js deleted file mode 100644 index 984ed2a600b0..000000000000 --- a/.webpack.config.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; -const resolve = require('path').resolve; - -module.exports = { - options: { - mode: 'none', - module: { - rules: [{ - test: /\.js$/, - exclude: /modules/, - use: { - loader: 'babel-loader', - }, - }], - }, - resolve: { - alias: { - 'core-js': resolve(__dirname, './packages/core-js'), - 'core-js-pure': resolve(__dirname, './packages/core-js-pure'), - }, - }, - node: { - global: false, - process: false, - setImmediate: false, - }, - stats: false, - output: { - path: resolve(__dirname, './tests/bundles'), - }, - }, - helpers: { - entry: './tests/helpers/qunit-helpers.js', - output: { filename: 'qunit-helpers.js' }, - }, - pure: { - entry: './tests/pure/index.js', - output: { filename: 'pure.js' }, - }, - tests: { - entry: './tests/tests/index.js', - output: { filename: 'tests.js' }, - }, - 'promises-aplus-tests': { - entry: 'promises-aplus-tests/lib/testFiles.js', - output: { filename: 'promises-aplus.js' }, - }, -}; diff --git a/CHANGELOG.md b/CHANGELOG.md index 61b5552b0553..fed6ab02a5f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,1747 @@ -## Changelog -##### Unreleased +# Changelog +### Unreleased +- Minor fix / optimization in the `RegExp` constructor (NCG and `dotAll`) polyfill +- Compat data improvements: + - [`Map` upsert proposal](https://github.com/tc39/proposal-upsert) features marked as [shipped in V8 ~ Chrome 145](https://issues.chromium.org/issues/434977728#comment4) + - [Joint iteration proposal](https://github.com/tc39/proposal-joint-iteration) features marked as [shipped in FF148](https://bugzilla.mozilla.org/show_bug.cgi?id=2003333#c8) + - Added [Deno 2.6](https://github.com/denoland/deno/releases/tag/v2.6.0) compat data mapping + - Added [Opera Android 93](https://forums.opera.com/topic/87267/opera-for-android-93) compat data mapping + +### [3.47.0 - 2025.11.18](https://github.com/zloirock/core-js/releases/tag/v3.47.0) +- Changes [v3.46.0...v3.47.0](https://github.com/zloirock/core-js/compare/v3.46.0...v3.47.0) (117 commits) +- [`JSON.parse` source text access proposal](https://github.com/tc39/proposal-json-parse-with-source) : + - Built-ins: + - `JSON.isRawJSON` + - `JSON.parse` + - `JSON.rawJSON` + - `JSON.stringify` + - Moved to stable ES, [November 2025 TC39 meeting](https://x.com/robpalmer2/status/1990603365236289653) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries + - Reworked `JSON.stringify` internals +- [`Iterator` sequencing proposal](https://github.com/tc39/proposal-iterator-sequencing): + - Built-ins: + - `Iterator.concat` + - Moved to stable ES, [November 2025 TC39 meeting](https://github.com/tc39/proposals/commit/33be3cb6d6743c7cc8628c547423f49078c0b655) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries +- [Joint iteration proposal](https://github.com/tc39/proposal-joint-iteration): + - Built-ins: + - `Iterator.zip` + - `Iterator.zipKeyed` + - Moved to stage 3, [November 2025 TC39 meeting](https://github.com/tc39/proposals/commit/6c0126b8f44323254c93045ee7ec216e49b83ddd) + - Added `/actual/` namespace entries, unconditional forced replacement changed to feature detection +- Fixed increasing `.size` in `URLSearchParams.prototype.append` polyfill in IE8- +- Compat data improvements: + - [`Iterator.concat`](https://github.com/tc39/proposal-iterator-sequencing) marked as [shipped in FF147](https://bugzilla.mozilla.org/show_bug.cgi?id=1986672#c4) + - [`Map` upsert proposal](https://github.com/tc39/proposal-upsert) features marked as shipped in Safari 26.2 + - `Math.sumPrecise` marked as shipped in Safari 26.2 + - `Uint8Array.{ fromBase64, prototype.setFromBase64 }` marked as fixed in Safari 26.2 + - Missed [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management) features [added in Bun 1.3.0](https://bun.com/blog/bun-v1.3#disposablestack-and-asyncdisposablestack) + - Added Oculus Quest Browser 41 compat data mapping + - Added Electron 40 compat data mapping + +### [3.46.0 - 2025.10.09](https://github.com/zloirock/core-js/releases/tag/v3.46.0) +- Changes [v3.45.1...v3.46.0](https://github.com/zloirock/core-js/compare/v3.45.1...v3.46.0) (116 commits) +- [`Map` upsert stage 3 proposal](https://github.com/tc39/proposal-upsert): + - Fixed [a FF `WeakMap.prototype.getOrInsertComputed` bug with callback calling before validation a key](https://bugzilla.mozilla.org/show_bug.cgi?id=1988369) +- [`Iterator` chunking proposal](https://github.com/tc39/proposal-iterator-chunking): + - Built-ins: + - `Iterator.prototype.chunks` + - `Iterator.prototype.windows` + - Moved to stage 2.7, [September 2025 TC39 meeting](https://github.com/tc39/proposals/commit/08e583103c6c244c05a26d9fee518ef8145ba2f6) + - `Iterator.prototype.sliding` method replaced with an extra parameter of `Iterator.prototype.windows` method, [tc39/proposal-iterator-chunking/#24](https://github.com/tc39/proposal-iterator-chunking/pull/24), [tc39/proposal-iterator-chunking/#26](https://github.com/tc39/proposal-iterator-chunking/pull/26) +- Fixed [`Iterator.zip` and `Iterator.zipKeyed`](https://github.com/tc39/proposal-joint-iteration) behavior with `mode: 'longest'` option, [#1469](https://github.com/zloirock/core-js/issues/1469), thanks [**@lionel-rowe**](https://github.com/lionel-rowe) +- Fixed work of `Object.groupBy` and [`Iterator.zipKeyed`](https://github.com/tc39/proposal-joint-iteration) together with `Symbol` polyfill - some cases of symbol keys on result `null`-prototype object were able to leak out to `for-in` +- Compat data improvements: + - [`Map` upsert proposal](https://github.com/tc39/proposal-upsert) features marked as shipped from FF144 + - Added [Node 25.0](https://github.com/nodejs/node/pull/59896) compat data mapping + - Added [Deno 2.5](https://github.com/denoland/deno/releases/tag/v2.5.0) compat data mapping + - Updated Electron 39 compat data mapping + - Updated Opera 121+ compat data mapping + - Added [Opera Android 92](https://forums.opera.com/topic/86530/opera-for-android-92) compat data mapping + - Added Oculus Quest Browser 40 compat data mapping + +### [3.45.1 - 2025.08.20](https://github.com/zloirock/core-js/releases/tag/v3.45.1) +- Changes [v3.45.0...v3.45.1](https://github.com/zloirock/core-js/compare/v3.45.0...v3.45.1) (30 commits) +- Fixed a conflict of native methods from [`Map` upsert proposal](https://github.com/tc39/proposal-upsert) with polyfilled methods in the pure version +- Added `bugs` fields to `package.json` of all packages +- Compat data improvements: + - [`Map` upsert proposal](https://github.com/tc39/proposal-upsert) features marked as shipped from Bun 1.2.20 + - Added Samsung Internet 29 compat data mapping + - Added Electron 39 compat data mapping + +### [3.45.0 - 2025.08.04](https://github.com/zloirock/core-js/releases/tag/v3.45.0) +- Changes [v3.44.0...v3.45.0](https://github.com/zloirock/core-js/compare/v3.44.0...v3.45.0) (70 commits) +- [`Uint8Array` to / from base64 and hex proposal](https://github.com/tc39/proposal-arraybuffer-base64): + - Built-ins: + - `Uint8Array.fromBase64` + - `Uint8Array.fromHex` + - `Uint8Array.prototype.setFromBase64` + - `Uint8Array.prototype.setFromHex` + - `Uint8Array.prototype.toBase64` + - `Uint8Array.prototype.toHex` + - Moved to stable ES, [July 2025 TC39 meeting](https://github.com/tc39/proposals/commit/d41fe182cdb90da3076ab711aae3944ed86bcf18) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries + - Added detection of a Webkit bug: `Uint8Array` fromBase64 / setFromBase64 does not throw an error on incorrect length of base64 string +- [`Math.sumPrecise` proposal](https://github.com/tc39/proposal-math-sum): + - Built-ins: + - `Math.sumPrecise` + - Moved to stable ES, [July 2025 TC39 meeting](https://github.com/tc39/proposals/commit/2616413ace9074bfd444adee9501fae4c8d66fcb) + - Added `es.` namespace module, `/es/` and `/stable/` namespaces entries +- [`Iterator` sequencing proposal](https://github.com/tc39/proposal-iterator-sequencing): + - Built-ins: + - `Iterator.concat` + - Moved to stage 3, [July 2025 TC39 meeting](https://github.com/tc39/proposals/commit/3eebab0f8594673dd08bc709d68c011016074c2e) + - Added `/actual/` namespace entries, unconditional forced replacement changed to feature detection +- [`Map` upsert proposal](https://github.com/tc39/proposal-upsert): + - Built-ins: + - `Map.prototype.getOrInsert` + - `Map.prototype.getOrInsertComputed` + - `WeakMap.prototype.getOrInsert` + - `WeakMap.prototype.getOrInsertComputed` + - Moved to stage 3, [July 2025 TC39 meeting](https://github.com/tc39/proposals/commit/a9c0dfa4e00ffb69aa4df91d8c0c26b064d67108) + - Added `/actual/` namespace entries, unconditional forced replacement changed to feature detection +- Added missing dependencies to some entries of static `Iterator` methods +- Fixed [Joint Iteration proposal](https://github.com/tc39/proposal-joint-iteration) in `/stage/` entries +- Compat data improvements: + - [`Uint8Array` to / from base64 and hex proposal](https://github.com/tc39/proposal-arraybuffer-base64) features marked as [supported from V8 ~ Chromium 140](https://issues.chromium.org/issues/42204568#comment37) + - [`Uint8Array.{ fromBase64, prototype.setFromBase64 }`](https://github.com/tc39/proposal-arraybuffer-base64) marked as unsupported in Safari and supported only from Bun 1.2.20 because of a bug: it does not throw an error on incorrect length of base64 string + - `%TypedArray%.prototype.with` marked as fixed in Safari 26.0 + - Updated Electron 38 compat data mapping + - Added [Opera Android 91](https://forums.opera.com/topic/86005/opera-for-android-91) compat data mapping + +### [3.44.0 - 2025.07.07](https://github.com/zloirock/core-js/releases/tag/v3.44.0) +- Changes [v3.43.0...v3.44.0](https://github.com/zloirock/core-js/compare/v3.43.0...v3.44.0) (87 commits) +- [`Uint8Array` to / from base64 and hex stage 3 proposal](https://github.com/tc39/proposal-arraybuffer-base64): + - Fixed [several V8 bugs](https://github.com/zloirock/core-js/issues/1439) in `Uint8Array.fromHex` and `Uint8Array.prototype.{ setFromBase64, toBase64, toHex }`, thanks [**@brc-dd**](https://github.com/brc-dd) +- [Joint iteration stage 2.7 proposal](https://github.com/tc39/proposal-joint-iteration): + - Uses `Get` in `Iterator.zipKeyed`, following [tc39/proposal-joint-iteration#43](https://github.com/tc39/proposal-joint-iteration/pull/43) +- [`Iterator` sequencing stage 2.7 proposal](https://github.com/tc39/proposal-iterator-sequencing): + - `Iterator.concat` no longer reuses `IteratorResult` object of concatenated iterators, following [tc39/proposal-iterator-sequencing#26](https://github.com/tc39/proposal-iterator-sequencing/pull/26) +- [`Iterator` chunking stage 2 proposal](https://github.com/tc39/proposal-iterator-chunking): + - Added built-ins: + - `Iterator.prototype.sliding` +- [`Number.prototype.clamp` stage 2 proposal](https://github.com/tc39/proposal-math-clamp): + - `clamp` no longer throws an error on `NaN` as `min` or `max`, following [tc39/proposal-math-clamp#d2387791c265edf66fbe2455eab919016717ce6f](https://github.com/tc39/proposal-math-clamp/commit/d2387791c265edf66fbe2455eab919016717ce6f) +- Fixed some cases of `Set.prototype.{ symmetricDifference, union }` detection +- Added missing dependencies to some entries of static `Iterator` methods +- Added missing `/full/{ instance, number/virtual }/clamp` entries +- Some minor stylistic changes +- Compat data improvements: + - Added Electron 38 and 39 compat data mapping + - Added Oculus Quest Browser 38 and 39 compat data mapping + - `Iterator` helpers marked as fixed and updated following the latest spec changes in Safari 26.0 + - `Set.prototype.{ difference, symmetricDifference, union }` marked as fixed in Safari 26.0 + - `SuppressedError` marked [as fixed](https://bugzilla.mozilla.org/show_bug.cgi?id=1971000) in FF141 + - `Error.isError` marked [as fixed](https://github.com/nodejs/node/pull/58691) in Node 24.3 + - `setImmediate` and `clearImmediate` marked as available [from Deno 2.4](https://github.com/denoland/deno/pull/29877) + - `Math.sumPrecise` marked as [shipped in Bun 1.2.18](https://github.com/oven-sh/bun/pull/20569) + - `%TypedArray%.prototype.with` marked as fixed in Bun 1.2.18 + +### [3.43.0 - 2025.06.09](https://github.com/zloirock/core-js/releases/tag/v3.43.0) +- Changes [v3.42.0...v3.43.0](https://github.com/zloirock/core-js/compare/v3.42.0...v3.43.0) (139 commits) +- [Explicit Resource Management proposals](https://github.com/tc39/proposal-explicit-resource-management): + - Built-ins: + - `Symbol.dispose` + - `Symbol.asyncDispose` + - `SuppressedError` + - `DisposableStack` + - `DisposableStack.prototype.dispose` + - `DisposableStack.prototype.use` + - `DisposableStack.prototype.adopt` + - `DisposableStack.prototype.defer` + - `DisposableStack.prototype.move` + - `DisposableStack.prototype[@@dispose]` + - `AsyncDisposableStack` + - `AsyncDisposableStack.prototype.disposeAsync` + - `AsyncDisposableStack.prototype.use` + - `AsyncDisposableStack.prototype.adopt` + - `AsyncDisposableStack.prototype.defer` + - `AsyncDisposableStack.prototype.move` + - `AsyncDisposableStack.prototype[@@asyncDispose]` + - `Iterator.prototype[@@dispose]` + - `AsyncIterator.prototype[@@asyncDispose]` + - Moved to stable ES, [May 2025 TC39 meeting](https://x.com/robpalmer2/status/1927744934343213085) + - Added `es.` namespace module, `/es/` and `/stable/` namespaces entries +- [`Array.fromAsync` proposal](https://github.com/tc39/proposal-array-from-async): + - Built-ins: + - `Array.fromAsync` + - Moved to stable ES, [May 2025 TC39 meeting](https://github.com/tc39/proposal-array-from-async/issues/14#issuecomment-2916645435) + - Added `es.` namespace module, `/es/` and `/stable/` namespaces entries +- [`Error.isError` proposal](https://github.com/tc39/proposal-is-error): + - Built-ins: + - `Error.isError` + - Moved to stable ES, [May 2025 TC39 meeting](https://github.com/tc39/proposals/commit/a5d4bb99d79f328533d0c36b0cd20597fa12c7a8) + - Added `es.` namespace module, `/es/` and `/stable/` namespaces entries +- Added [Joint iteration stage 2.7 proposal](https://github.com/tc39/proposal-joint-iteration): + - Added built-ins: + - `Iterator.zip` + - `Iterator.zipKeyed` +- Added [`Iterator` chunking stage 2 proposal](https://github.com/tc39/proposal-iterator-chunking): + - Added built-ins: + - `Iterator.prototype.chunks` + - `Iterator.prototype.windows` +- [`Number.prototype.clamp` proposal](https://github.com/tc39/proposal-math-clamp): + - Built-ins: + - `Number.prototype.clamp` + - Moved to stage 2, [May 2025 TC39 meeting](https://github.com/tc39/proposal-math-clamp/commit/a005f28a6a03e175b9671de1c8c70dd5b7b08c2d) + - `Math.clamp` was replaced with `Number.prototype.clamp` + - Removed a `RangeError` if `min <= max` or `+0` min and `-0` max, [tc39/proposal-math-clamp/#22](https://github.com/tc39/proposal-math-clamp/issues/22) +- Always check regular expression flags by `flags` getter [PR](https://github.com/tc39/ecma262/pull/2791). Native methods are not fixed, only own implementation updated for: + - `RegExp.prototype[@@match]` + - `RegExp.prototype[@@replace]` +- Improved handling of `RegExp` flags in polyfills of some methods in engines without proper support of `RegExp.prototype.flags` and without polyfill of this getter +- Added feature detection for [a WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=288595) that occurs when `this` is updated while `Set.prototype.difference` is being executed +- Added feature detection for [a WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=289430) that occurs when iterator record of a set-like object isn't called before cloning `this` in the following methods: + - `Set.prototype.symmetricDifference` + - `Set.prototype.union` +- Added feature detection for [a bug](https://issues.chromium.org/issues/336839115) in V8 ~ Chromium < 126. Following methods should throw an error on invalid iterator: + - `Iterator.prototype.drop` + - `Iterator.prototype.filter` + - `Iterator.prototype.flatMap` + - `Iterator.prototype.map` +- Added feature detection for [a WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=288714): incorrect exception thrown by `Iterator.from` when underlying iterator's `return` method is `null` +- Added feature detection for a FF bug: incorrect exception thrown by `Array.prototype.with` when index coercion fails +- Added feature detection for a WebKit bug: `TypedArray.prototype.with` should truncate negative fractional index to zero, but instead throws an error +- Worked around a bug of many different tools ([example](https://github.com/zloirock/core-js/pull/1368#issuecomment-2908034690)) with incorrect transforming and breaking JS syntax on getting a method from a number literal +- Fixed deoptimization of the `Promise` polyfill in the pure version +- Added some missed dependencies to `/iterator/flat-map` entries +- Some other minor fixes and improvements +- Compat data improvements: + - Added [Deno 2.3](https://github.com/denoland/deno/releases/tag/v2.3.0) and [Deno 2.3.2](https://github.com/denoland/deno/releases/tag/v2.3.2) compat data mapping + - Updated Electron 37 compat data mapping + - Added Opera Android 90 compat data mapping + - [`Error.isError`](https://github.com/tc39/proposal-is-error) marked not supported in Node because of [a bug](https://github.com/nodejs/node/issues/56497) + - `Set.prototype.difference` marked as not supported in Safari and supported only from Bun 1.2.5 because of [a bug](https://bugs.webkit.org/show_bug.cgi?id=288595) + - `Set.prototype.{ symmetricDifference, union }` marked as not supported in Safari and supported only from Bun 1.2.5 because of [a bug](https://bugs.webkit.org/show_bug.cgi?id=289430) + - `Iterator.from` marked as not supported in Safari and supported only from Bun 1.2.5 because of [a bug](https://bugs.webkit.org/show_bug.cgi?id=288714) + - Iterators closing on early errors in `Iterator` helpers marked as implemented from FF141 + - `Array.prototype.with` marked as supported only from FF140 because it throws an incorrect exception when index coercion fails + - `TypedArray.prototype.with` marked as unsupported in Bun and Safari because it should truncate negative fractional index to zero, but instead throws an error + - `DisposableStack` and `AsyncDisposableStack` marked as [shipped in FF141](https://bugzilla.mozilla.org/show_bug.cgi?id=1967744) (`SuppressedError` has [a bug](https://bugzilla.mozilla.org/show_bug.cgi?id=1971000)) + - `AsyncDisposableStack` bugs marked as fixed in Deno 2.3.2 + - `SuppressedError` bugs ([extra arguments support](https://github.com/oven-sh/bun/issues/9283) and [arity](https://github.com/oven-sh/bun/issues/9282)) marked as fixed in Bun 1.2.15 + +### [3.42.0 - 2025.04.30](https://github.com/zloirock/core-js/releases/tag/v3.42.0) +- Changes [v3.41.0...v3.42.0](https://github.com/zloirock/core-js/compare/v3.41.0...v3.42.0) (142 commits) +- [`Map` upsert proposal](https://github.com/tc39/proposal-upsert): + - Moved to stage 2.7, [April 2025 TC39 meeting](https://x.com/robpalmer2/status/1911882240109261148) + - Validation order of `WeakMap.prototype.getOrInsertComputed` updated following [tc39/proposal-upsert#79](https://github.com/tc39/proposal-upsert/pull/79) + - Built-ins: + - `Map.prototype.getOrInsert` + - `Map.prototype.getOrInsertComputed` + - `WeakMap.prototype.getOrInsert` + - `WeakMap.prototype.getOrInsertComputed` +- Don't call well-known `Symbol` methods for `RegExp` on primitive values following [tc39/ecma262#3009](https://github.com/tc39/ecma262/pull/3009): + - For avoid performance regression, temporarily, only in own `core-js` implementations + - Built-ins: + - `String.prototype.matchAll` + - `String.prototype.match` + - `String.prototype.replaceAll` + - `String.prototype.replace` + - `String.prototype.search` + - `String.prototype.split` +- Added workaround for the [`Uint8Array.prototype.setFromBase64`](https://github.com/tc39/proposal-arraybuffer-base64) [bug](https://bugs.webkit.org/show_bug.cgi?id=290829) in some of Linux builds of WebKit +- Implemented early-error iterator closing following [tc39/ecma262#3467](https://github.com/tc39/ecma262/pull/3467), including fix of [a WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=291195), in the following methods: + - `Iterator.prototype.drop` + - `Iterator.prototype.every` + - `Iterator.prototype.filter` + - `Iterator.prototype.find` + - `Iterator.prototype.flatMap` + - `Iterator.prototype.forEach` + - `Iterator.prototype.map` + - `Iterator.prototype.reduce` + - `Iterator.prototype.some` + - `Iterator.prototype.take` +- Fixed missing forced replacement of [`AsyncIterator` helpers](https://github.com/tc39/proposal-async-iterator-helpers) +- Added closing of sync iterator when async wrapper yields a rejection following [tc39/ecma262#2600](https://github.com/tc39/ecma262/pull/2600). Affected methods: + - [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async) (due to the lack of async feature detection capability - temporarily, only in own `core-js` implementation) + - [`AsyncIterator.from`](https://github.com/tc39/proposal-async-iterator-helpers) + - [`Iterator.prototype.toAsync`](https://github.com/tc39/proposal-async-iterator-helpers) +- Added detection for throwing on `undefined` initial parameter in `Iterator.prototype.reduce` (see [WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=291651)) +- `core-js-compat` and `core-js-builder` API: + - Added `'intersect'` support for `targets.esmodules` (Babel 7 behavior) + - Fixed handling of `targets.esmodules: true` (Babel 7 behavior) +- Compat data improvements: + - [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management) features disabled (again) in V8 ~ Chromium 135 and re-added in 136 + - [`RegExp.escape`](https://github.com/tc39/proposal-regex-escaping) marked as [shipped from V8 ~ Chromium 136](https://issues.chromium.org/issues/353856236#comment17) + - [`Error.isError`](https://github.com/tc39/proposal-is-error) marked as [shipped from FF138](https://bugzilla.mozilla.org/show_bug.cgi?id=1952249) + - [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management) features re-enabled in [Deno 2.2.10](https://github.com/denoland/deno/releases/tag/v2.2.10) + - [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers) features marked as supported from Deno 1.38.1 since it seems they were disabled in 1.38.0 + - `Iterator.prototype.{ drop, reduce, take }` methods marked as fixed in Bun 1.2.11 + - Added [NodeJS 24.0](https://github.com/nodejs/node/pull/57609) compat data mapping + - Updated Electron 36 and added Electron 37 compat data mapping + - Added Opera Android [88](https://forums.opera.com/topic/83800/opera-for-android-88) and [89](https://forums.opera.com/topic/84437/opera-for-android-89) compat data mapping + - Added Oculus Quest Browser 37 compat data mapping + +### [3.41.0 - 2025.03.01](https://github.com/zloirock/core-js/releases/tag/v3.41.0) +- Changes [v3.40.0...v3.41.0](https://github.com/zloirock/core-js/compare/v3.40.0...v3.41.0) (85 commits) +- [`RegExp.escape` proposal](https://github.com/tc39/proposal-regex-escaping): + - Built-ins: + - `RegExp.escape` + - Moved to stable ES, [February 2025 TC39 meeting](https://github.com/tc39/proposals/commit/b81fa9bccf4b51f33de0cbe797976a84d05d4b76) + - Added `es.` namespace module, `/es/` and `/stable/` namespaces entries +- [`Float16` proposal](https://github.com/tc39/proposal-float16array): + - Built-ins: + - `Math.f16round` + - `DataView.prototype.getFloat16` + - `DataView.prototype.setFloat16` + - Moved to stable ES, [February 2025 TC39 meeting](https://github.com/tc39/proposals/commit/b81fa9bccf4b51f33de0cbe797976a84d05d4b76) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries +- [`Math.clamp` stage 1 proposal](https://github.com/CanadaHonk/proposal-math-clamp): + - Built-ins: + - `Math.clamp` + - Extracted from [old `Math` extensions proposal](https://github.com/rwaldron/proposal-math-extensions), [February 2025 TC39 meeting](https://github.com/tc39/proposals/commit/0c24594aab19a50b86d0db7248cac5eb0ae35621) + - Added arguments validation + - Added new entries +- Added a workaround of a V8 `AsyncDisposableStack` bug, [tc39/proposal-explicit-resource-management/256](https://github.com/tc39/proposal-explicit-resource-management/issues/256) +- Compat data improvements: + - [`DisposableStack`, `SuppressedError` and `Iterator.prototype[@@dispose]`](https://github.com/tc39/proposal-explicit-resource-management) marked as [shipped from V8 ~ Chromium 134](https://issues.chromium.org/issues/42203506#comment24) + - [`Error.isError`](https://github.com/tc39/proposal-is-error) added and marked as [shipped from V8 ~ Chromium 134](https://issues.chromium.org/issues/382104870#comment4) + - [`Math.f16round` and `DataView.prototype.{ getFloat16, setFloat16 }`](https://github.com/tc39/proposal-float16array) marked as [shipped from V8 ~ Chromium 135](https://issues.chromium.org/issues/42203953#comment36) + - [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers) features marked as [shipped from Safari 18.4](https://developer.apple.com/documentation/safari-release-notes/safari-18_4-release-notes#New-Features) + - [`JSON.parse` source text access proposal](https://github.com/tc39/proposal-json-parse-with-source) features marked as [shipped from Safari 18.4](https://developer.apple.com/documentation/safari-release-notes/safari-18_4-release-notes#New-Features) + - [`Math.sumPrecise`](https://github.com/tc39/proposal-math-sum) marked as shipped from FF137 + - Added [Deno 2.2](https://github.com/denoland/deno/releases/tag/v2.2.0) compat data and compat data mapping + - Explicit Resource Management features are available in V8 ~ Chromium 134, but not in Deno 2.2 based on it + - Updated Electron 35 and added Electron 36 compat data mapping + - Updated [Opera Android 87](https://forums.opera.com/topic/75836/opera-for-android-87) compat data mapping + - Added Samsung Internet 28 compat data mapping + - Added Oculus Quest Browser 36 compat data mapping + +### [3.40.0 - 2025.01.08](https://github.com/zloirock/core-js/releases/tag/v3.40.0) +- Changes [v3.39.0...v3.40.0](https://github.com/zloirock/core-js/compare/v3.39.0...v3.40.0) (130 commits) +- Added [`Error.isError` stage 3 proposal](https://github.com/tc39/proposal-is-error): + - Added built-ins: + - `Error.isError` + - We have no bulletproof way to polyfill this method / check if the object is an error, so it's an enough naive implementation that is marked as `.sham` +- [Explicit Resource Management stage 3 proposal](https://github.com/tc39/proposal-explicit-resource-management): + - Updated the way async disposing of only sync disposable resources, [tc39/proposal-explicit-resource-management/218](https://github.com/tc39/proposal-explicit-resource-management/pull/218) +- [`Iterator` sequencing stage 2.7 proposal](https://github.com/tc39/proposal-iterator-sequencing): + - Reuse `IteratorResult` objects when possible, [tc39/proposal-iterator-sequencing/17](https://github.com/tc39/proposal-iterator-sequencing/issues/17), [tc39/proposal-iterator-sequencing/18](https://github.com/tc39/proposal-iterator-sequencing/pull/18), December 2024 TC39 meeting +- Added a fix of [V8 < 12.8](https://issues.chromium.org/issues/351332634) / [NodeJS < 22.10](https://github.com/nodejs/node/pull/54883) bug with handling infinite length of set-like objects in `Set` methods +- Optimized `DataView.prototype.{ getFloat16, setFloat16 }` performance, [#1379](https://github.com/zloirock/core-js/pull/1379), thanks [**@LeviPesin**](https://github.com/LeviPesin) +- Dropped unneeded feature detection of non-standard `%TypedArray%.prototype.toSpliced` +- Dropped possible re-usage of some non-standard / early stage features (like `Math.scale`) available on global +- Some other minor improvements +- Compat data improvements: + - [`RegExp.escape`](https://github.com/tc39/proposal-regex-escaping) marked as shipped from Safari 18.2 + - [`Promise.try`](https://github.com/tc39/proposal-promise-try) marked as shipped from Safari 18.2 + - [`Math.f16round` and `DataView.prototype.{ getFloat16, setFloat16 }`](https://github.com/tc39/proposal-float16array) marked as shipped from Safari 18.2 + - [`Uint8Array` to / from base64 and hex proposal](https://github.com/tc39/proposal-arraybuffer-base64) methods marked as shipped from Safari 18.2 + - [`JSON.parse` source text access proposal](https://github.com/tc39/proposal-json-parse-with-source) features marked as [shipped from FF135](https://bugzilla.mozilla.org/show_bug.cgi?id=1934622) + - [`RegExp.escape`](https://github.com/tc39/proposal-regex-escaping) marked as shipped [from FF134](https://bugzilla.mozilla.org/show_bug.cgi?id=1918235) + - [`Promise.try`](https://github.com/tc39/proposal-promise-try) marked as shipped from FF134 + - [`Symbol.dispose`, `Symbol.asyncDispose` and `Iterator.prototype[@@dispose]`](https://github.com/tc39/proposal-explicit-resource-management) marked as shipped from FF135 + - [`JSON.parse` source text access proposal](https://github.com/tc39/proposal-json-parse-with-source) features marked as shipped from Bun 1.1.43 + - Fixed NodeJS version where `URL.parse` was added - 22.1 instead of 22.0 + - Added [Deno 2.1](https://github.com/denoland/deno/releases/tag/v2.1.0) compat data mapping + - Added [Rhino 1.8.0](https://github.com/mozilla/rhino/releases/tag/Rhino1_8_0_Release) compat data with significant number of modern features + - Added Electron 35 compat data mapping + - Updated Opera 115+ compat data mapping + - Added Opera Android [86](https://forums.opera.com/topic/75006/opera-for-android-86) and 87 compat data mapping + +### [3.39.0 - 2024.10.31](https://github.com/zloirock/core-js/releases/tag/v3.39.0) +- Changes [v3.38.1...v3.39.0](https://github.com/zloirock/core-js/compare/v3.38.1...v3.39.0) +- [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers): + - Built-ins: + - `Iterator` + - `Iterator.from` + - `Iterator.prototype.drop` + - `Iterator.prototype.every` + - `Iterator.prototype.filter` + - `Iterator.prototype.find` + - `Iterator.prototype.flatMap` + - `Iterator.prototype.forEach` + - `Iterator.prototype.map` + - `Iterator.prototype.reduce` + - `Iterator.prototype.some` + - `Iterator.prototype.take` + - `Iterator.prototype.toArray` + - `Iterator.prototype[@@toStringTag]` + - Moved to stable ES, [October 2024 TC39 meeting](https://github.com/tc39/proposal-iterator-helpers/issues/284#event-14549961807) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries +- [`Promise.try`](https://github.com/tc39/proposal-promise-try): + - Built-ins: + - `Promise.try` + - Moved to stable ES, [October 2024 TC39 meeting](https://github.com/tc39/proposal-promise-try/commit/53d3351687274952b3b88f3ad024d9d68a9c1c93) + - Added `es.` namespace module, `/es/` and `/stable/` namespaces entries + - Fixed `/actual|full/promise/try` entries for the callback arguments support +- [`Math.sumPrecise` proposal](https://github.com/tc39/proposal-math-sum): + - Built-ins: + - `Math.sumPrecise` + - Moved to stage 3, [October 2024 TC39 meeting](https://github.com/tc39/proposal-math-sum/issues/19) + - Added `/actual/` namespace entries, unconditional forced replacement changed to feature detection +- Added [`Iterator` sequencing stage 2.7 proposal](https://github.com/tc39/proposal-iterator-sequencing): + - Added built-ins: + - `Iterator.concat` +- [`Map` upsert stage 2 proposal](https://github.com/tc39/proposal-upsert): + - [Updated to the new API following the October 2024 TC39 meeting](https://github.com/tc39/proposal-upsert/pull/58) + - Added built-ins: + - `Map.prototype.getOrInsert` + - `Map.prototype.getOrInsertComputed` + - `WeakMap.prototype.getOrInsert` + - `WeakMap.prototype.getOrInsertComputed` +- [Extractors proposal](https://github.com/tc39/proposal-extractors) moved to stage 2, [October 2024 TC39 meeting](https://github.com/tc39/proposals/commit/11bc489049fc5ce59b21e98a670a84f153a29a80) +- Usage of `@@species` pattern removed from `%TypedArray%` and `ArrayBuffer` methods, [tc39/ecma262/3450](https://github.com/tc39/ecma262/pull/3450): + - Built-ins: + - `%TypedArray%.prototype.filter` + - `%TypedArray%.prototype.filterReject` + - `%TypedArray%.prototype.map` + - `%TypedArray%.prototype.slice` + - `%TypedArray%.prototype.subarray` + - `ArrayBuffer.prototype.slice` +- Some other minor improvements +- Compat data improvements: + - [`Uint8Array` to / from base64 and hex proposal](https://github.com/tc39/proposal-arraybuffer-base64) methods marked as [shipped from FF133](https://bugzilla.mozilla.org/show_bug.cgi?id=1917885#c9) + - Added [NodeJS 23.0](https://nodejs.org/en/blog/release/v23.0.0) compat data mapping + - `self` descriptor [is fixed](https://github.com/denoland/deno/issues/24683) in Deno 1.46.0 + - Added Deno [1.46](https://github.com/denoland/deno/releases/tag/v1.46.0) and [2.0](https://github.com/denoland/deno/releases/tag/v2.0.0) compat data mapping + - [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers) methods marked as [shipped from Bun 1.1.31](https://github.com/oven-sh/bun/pull/14455) + - Added Electron 34 and updated Electron 33 compat data mapping + - Added [Opera Android 85](https://forums.opera.com/topic/74256/opera-for-android-85) compat data mapping + - Added Oculus Quest Browser 35 compat data mapping + +### [3.38.1 - 2024.08.20](https://github.com/zloirock/core-js/releases/tag/v3.38.1) +- Changes [v3.38.0...v3.38.1](https://github.com/zloirock/core-js/compare/v3.38.0...v3.38.1) +- Fixed some cases of `URLSearchParams` percent decoding, [#1357](https://github.com/zloirock/core-js/issues/1357), [#1361](https://github.com/zloirock/core-js/pull/1361), thanks [**@slowcheetah**](https://github.com/slowcheetah) +- Some stylistic changes and minor optimizations +- Compat data improvements: + - [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers) methods marked as [shipped from FF131](https://bugzilla.mozilla.org/show_bug.cgi?id=1896390) + - [`Math.f16round` and `DataView.prototype.{ getFloat16, setFloat16 }`](https://github.com/tc39/proposal-float16array) marked as shipped from Bun 1.1.23 + - [`RegExp.escape`](https://github.com/tc39/proposal-regex-escaping) marked as shipped from Bun 1.1.22 + - [`Promise.try`](https://github.com/tc39/proposal-promise-try) marked as shipped from Bun 1.1.22 + - [`Uint8Array` to / from base64 and hex proposal](https://github.com/tc39/proposal-arraybuffer-base64) methods marked as shipped from Bun 1.1.22 + - Added [Hermes 0.13](https://github.com/facebook/hermes/releases/tag/v0.13.0) compat data, similar to React Native 0.75 Hermes + - Added [Opera Android 84](https://forums.opera.com/topic/73545/opera-for-android-84) compat data mapping + +### [3.38.0 - 2024.08.05](https://github.com/zloirock/core-js/releases/tag/v3.38.0) +- Changes [v3.37.1...v3.38.0](https://github.com/zloirock/core-js/compare/v3.37.1...v3.38.0) +- [`RegExp.escape` proposal](https://github.com/tc39/proposal-regex-escaping): + - Built-ins: + - `RegExp.escape` + - Moved to stage 3, [June 2024](https://github.com/tc39/proposals/commit/4b8ee265248abfa2c88ed71b3c541ddd5a2eaffe) and [July 2024](https://github.com/tc39/proposals/commit/bdb2eea6c5e41a52f2d6047d7de1a31b5d188c4f) TC39 meetings + - Updated the way of escaping, [regex-escaping/77](https://github.com/tc39/proposal-regex-escaping/pull/77) + - Throw an error on non-strings, [regex-escaping/58](https://github.com/tc39/proposal-regex-escaping/pull/58) + - Added `/actual/` namespace entries, unconditional forced replacement changed to feature detection +- [`Promise.try` proposal](https://github.com/tc39/proposal-promise-try): + - Built-ins: + - `Promise.try` + - Moved to stage 3, [June 2024 TC39 meeting](https://github.com/tc39/proposals/commit/de20984cd7f7bc616682c557cb839abc100422cb) + - Added `/actual/` namespace entries, unconditional forced replacement changed to feature detection +- [`Uint8Array` to / from base64 and hex stage 3 proposal](https://github.com/tc39/proposal-arraybuffer-base64): + - Built-ins: + - `Uint8Array.fromBase64` + - `Uint8Array.fromHex` + - `Uint8Array.prototype.setFromBase64` + - `Uint8Array.prototype.setFromHex` + - `Uint8Array.prototype.toBase64` + - `Uint8Array.prototype.toHex` + - Added `Uint8Array.prototype.{ setFromBase64, setFromHex }` methods + - Added `Uint8Array.fromBase64` and `Uint8Array.prototype.setFromBase64` `lastChunkHandling` option, [proposal-arraybuffer-base64/33](https://github.com/tc39/proposal-arraybuffer-base64/pull/33) + - Added `Uint8Array.prototype.toBase64` `omitPadding` option, [proposal-arraybuffer-base64/60](https://github.com/tc39/proposal-arraybuffer-base64/pull/60) + - Added throwing a `TypeError` on arrays backed by detached buffers + - Unconditional forced replacement changed to feature detection +- Fixed `RegExp` named capture groups polyfill in combination with non-capturing groups, [#1352](https://github.com/zloirock/core-js/pull/1352), thanks [**@Ulop**](https://github.com/Ulop) +- Improved some cases of environment detection +- Uses [`process.getBuiltinModule`](https://nodejs.org/docs/latest/api/process.html#processgetbuiltinmoduleid) for getting built-in NodeJS modules where it's available +- Uses `https` instead of `http` in `URL` constructor feature detection to avoid extra notifications from some overly vigilant security scanners, [#1345](https://github.com/zloirock/core-js/issues/1345) +- Some minor optimizations +- Updated `browserslist` in `core-js-compat` dependencies that fixes an upstream issue with incorrect interpretation of some `browserslist` queries, [#1344](https://github.com/zloirock/core-js/issues/1344), [browserslist/829](https://github.com/browserslist/browserslist/issues/829), [browserslist/836](https://github.com/browserslist/browserslist/pull/836) +- Compat data improvements: + - Added [Safari 18.0](https://webkit.org/blog/15443/news-from-wwdc24-webkit-in-safari-18-beta/) compat data: + - Fixed [`Object.groupBy` and `Map.groupBy`](https://github.com/tc39/proposal-array-grouping) to [work for non-objects](https://bugs.webkit.org/show_bug.cgi?id=271524) + - Fixed [throwing a `RangeError` if `Set` methods are called on an object with negative size property](https://bugs.webkit.org/show_bug.cgi?id=267494) + - Fixed [`Set.prototype.symmetricDifference` to call `this.has` in each iteration](https://bugs.webkit.org/show_bug.cgi?id=272679) + - Fixed [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async) to [not call the `Array` constructor twice](https://bugs.webkit.org/show_bug.cgi?id=271703) + - Added [`URL.parse`](https://url.spec.whatwg.org/#dom-url-parse) + - [`Math.f16round` and `DataView.prototype.{ getFloat16, setFloat16 }`](https://github.com/tc39/proposal-float16array) marked as [shipped from FF129](https://bugzilla.mozilla.org/show_bug.cgi?id=1903329) + - [`Symbol.asyncDispose`](https://github.com/tc39/proposal-explicit-resource-management) added and marked as supported from V8 ~ Chromium 127 + - [`Promise.try`](https://github.com/tc39/proposal-promise-try) added and marked as supported [from V8 ~ Chromium 128](https://chromestatus.com/feature/6315704705089536) + - Added Deno [1.44](https://github.com/denoland/deno/releases/tag/v1.44.0) and [1.45](https://github.com/denoland/deno/releases/tag/v1.45.0) compat data mapping + - `self` descriptor [is broken in Deno 1.45.3](https://github.com/denoland/deno/issues/24683) (again) + - Added Electron 32 and 33 compat data mapping + - Added [Opera Android 83](https://forums.opera.com/topic/72570/opera-for-android-83) compat data mapping + - Added Samsung Internet 27 compat data mapping + - Added Oculus Quest Browser 34 compat data mapping + +### [3.37.1 - 2024.05.14](https://github.com/zloirock/core-js/releases/tag/v3.37.1) +- Changes [v3.37.0...v3.37.1](https://github.com/zloirock/core-js/compare/v3.37.0...v3.37.1) +- Fixed [`URL.parse`](https://url.spec.whatwg.org/#dom-url-parse) feature detection for some specific cases +- Compat data improvements: + - [`Set` methods proposal](https://github.com/tc39/proposal-set-methods) added and marked as [supported from FF 127](https://bugzilla.mozilla.org/show_bug.cgi?id=1868423) + - [`Symbol.dispose`](https://github.com/tc39/proposal-explicit-resource-management) added and marked as supported from V8 ~ Chromium 125 + - [`Math.f16round` and `DataView.prototype.{ getFloat16, setFloat16 }`](https://github.com/tc39/proposal-float16array) added and marked as [supported from Deno 1.43](https://github.com/denoland/deno/pull/23490) + - [`URL.parse`](https://url.spec.whatwg.org/#dom-url-parse) added and marked as [supported from Chromium 126](https://chromestatus.com/feature/6301071388704768) + - [`URL.parse`](https://url.spec.whatwg.org/#dom-url-parse) added and marked as [supported from NodeJS 22.0](https://github.com/nodejs/node/pull/52280) + - [`URL.parse`](https://url.spec.whatwg.org/#dom-url-parse) added and marked as [supported from Deno 1.43](https://github.com/denoland/deno/pull/23318) + - Added [Rhino 1.7.15](https://github.com/mozilla/rhino/releases/tag/Rhino1_7_15_Release) compat data, many features marked as supported + - Added [NodeJS 22.0](https://nodejs.org/en/blog/release/v22.0.0) compat data mapping + - Added [Deno 1.43](https://github.com/denoland/deno/releases/tag/v1.43.0) compat data mapping + - Added Electron 31 compat data mapping + - Updated [Opera Android 82](https://forums.opera.com/topic/71513/opera-for-android-82) compat data mapping + - Added Samsung Internet 26 compat data mapping + - Added Oculus Quest Browser 33 compat data mapping + +### [3.37.0 - 2024.04.17](https://github.com/zloirock/core-js/releases/tag/v3.37.0) +- Changes [v3.36.1...v3.37.0](https://github.com/zloirock/core-js/compare/v3.36.1...v3.37.0) +- [New `Set` methods proposal](https://github.com/tc39/proposal-set-methods): + - Built-ins: + - `Set.prototype.intersection` + - `Set.prototype.union` + - `Set.prototype.difference` + - `Set.prototype.symmetricDifference` + - `Set.prototype.isSubsetOf` + - `Set.prototype.isSupersetOf` + - `Set.prototype.isDisjointFrom` + - Moved to stable ES, [April 2024 TC39 meeting](https://github.com/tc39/proposals/commit/bda5a6bccbaca183e193f9e680889ea5b5462ce4) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries +- [Explicit Resource Management stage 3 proposal](https://github.com/tc39/proposal-explicit-resource-management): + - Some minor updates like [explicit-resource-management/217](https://github.com/tc39/proposal-explicit-resource-management/pull/217) +- Added [`Math.sumPrecise` stage 2.7 proposal](https://github.com/tc39/proposal-math-sum/): + - Built-ins: + - `Math.sumPrecise` +- [`Promise.try` proposal](https://github.com/tc39/proposal-promise-try): + - Built-ins: + - `Promise.try` + - Added optional arguments support, [promise-try/16](https://github.com/tc39/proposal-promise-try/pull/16) + - Moved to stage 2.7, [April 2024 TC39 meeting](https://github.com/tc39/proposals/commit/301fc9c7eef2344d2b443f32a9c24ecd5fbdbec0) +- [`RegExp.escape` stage 2 proposal](https://github.com/tc39/proposal-regex-escaping): + - Moved to hex-escape semantics, [regex-escaping/67](https://github.com/tc39/proposal-regex-escaping/pull/67) + - It's not the final change of the way of escaping, waiting for [regex-escaping/77](https://github.com/tc39/proposal-regex-escaping/pull/77) soon +- [Pattern matching stage 1 proposal](https://github.com/tc39/proposal-pattern-matching): + - Built-ins: + - `Symbol.customMatcher` + - Once again, [the used well-known symbol was renamed](https://github.com/tc39/proposal-pattern-matching/pull/295) + - Added new entries for that +- Added [Extractors stage 1 proposal](https://github.com/tc39/proposal-extractors): + - Built-ins: + - `Symbol.customMatcher` + - Since the `Symbol.customMatcher` well-known symbol from the pattern matching proposal is also used in the exactors proposal, added an entry also for this proposal +- Added [`URL.parse`](https://url.spec.whatwg.org/#dom-url-parse), [url/825](https://github.com/whatwg/url/pull/825) +- Engines bugs fixes: + - Added a fix of [Safari `{ Object, Map }.groupBy` bug that does not support iterable primitives](https://bugs.webkit.org/show_bug.cgi?id=271524) + - Added a fix of [Safari bug with double call of constructor in `Array.fromAsync`](https://bugs.webkit.org/show_bug.cgi?id=271703) +- Compat data improvements: + - [`URL.parse`](https://url.spec.whatwg.org/#dom-url-parse) added and marked as supported [from FF 126](https://bugzilla.mozilla.org/show_bug.cgi?id=1887611) + - [`URL.parse`](https://url.spec.whatwg.org/#dom-url-parse) added and marked as supported [from Bun 1.1.4](https://github.com/oven-sh/bun/pull/10129) + - [`URL.canParse`](https://url.spec.whatwg.org/#dom-url-canparse) fixed and marked as supported [from Bun 1.1.0](https://github.com/oven-sh/bun/pull/9710) + - [New `Set` methods](https://github.com/tc39/proposal-set-methods) fixed in JavaScriptCore and marked as supported from Bun 1.1.1 + - Added Opera Android 82 compat data mapping + +### [3.36.1 - 2024.03.19](https://github.com/zloirock/core-js/releases/tag/v3.36.1) +- Changes [v3.36.0...v3.36.1](https://github.com/zloirock/core-js/compare/v3.36.0...v3.36.1) +- Fixed some validation cases in `Object.setPrototypeOf`, [#1329](https://github.com/zloirock/core-js/issues/1329), thanks [**@minseok-choe**](https://github.com/minseok-choe) +- Fixed the order of validations in `Array.from`, [#1331](https://github.com/zloirock/core-js/pull/1331), thanks [**@minseok-choe**](https://github.com/minseok-choe) +- Added a fix of [Bun `queueMicrotask` arity](https://github.com/oven-sh/bun/issues/9249) +- Added a fix of [Bun `URL.canParse` arity](https://github.com/oven-sh/bun/issues/9250) +- Added a fix of Bun `SuppressedError` [extra arguments support](https://github.com/oven-sh/bun/issues/9283) and [arity](https://github.com/oven-sh/bun/issues/9282) +- Compat data improvements: + - [`value` argument of `URLSearchParams.prototype.{ has, delete }`](https://url.spec.whatwg.org/#dom-urlsearchparams-delete) marked as supported [from Bun 1.0.31](https://github.com/oven-sh/bun/issues/9263) + - Added React Native 0.74 Hermes compat data, `Array.prototype.{ toSpliced, toReversed, with }` and `atob` marked as supported + - Added Deno 1.41.3 compat data mapping + - Added Opera Android 81 compat data mapping + - Added Samsung Internet 25 compat data mapping + - Added Oculus Quest Browser 32 compat data mapping + - Updated Electron 30 compat data mapping + +### [3.36.0 - 2024.02.14](https://github.com/zloirock/core-js/releases/tag/v3.36.0) +- [`ArrayBuffer.prototype.transfer` and friends proposal](https://github.com/tc39/proposal-arraybuffer-transfer): + - Built-ins: + - `ArrayBuffer.prototype.detached` + - `ArrayBuffer.prototype.transfer` + - `ArrayBuffer.prototype.transferToFixedLength` + - Moved to stable ES, [Febrary 2024 TC39 meeting](https://github.com/tc39/proposals/commit/c84d3dde9a7d8ee4410ffa28624fc4c39247faca) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries +- [`Uint8Array` to / from base64 and hex proposal](https://github.com/tc39/proposal-arraybuffer-base64): + - Methods: + - `Uint8Array.fromBase64` + - `Uint8Array.fromHex` + - `Uint8Array.prototype.toBase64` + - `Uint8Array.prototype.toHex` + - Moved to stage 3, [Febrary 2024 TC39 meeting](https://github.com/tc39/proposals/commit/278ab28b8f849f2110d770e7b034b7ef59f14daf) + - Added `/actual/` namespace entries + - Skipped adding new methods of writing to existing arrays to clarification some moments +- [`Promise.try` proposal](https://github.com/tc39/proposal-promise-try) has been resurrected and moved to stage 2, [Febrary 2024 TC39 meeting](https://github.com/tc39/proposal-promise-try/issues/15) +- Added an entry point for [the new TC39 proposals stage](https://tc39.es/process-document/) - `core-js/stage/2.7` - still empty +- Fixed regression in `Set.prototype.intersection` feature detection +- Fixed a missed check in `Array.prototype.{ indexOf, lastIndexOf, includes }`, [#1325](https://github.com/zloirock/core-js/issues/1325), thanks [**@minseok-choe**](https://github.com/minseok-choe) +- Fixed a missed check in `Array.prototype.{ reduce, reduceRight }`, [#1327](https://github.com/zloirock/core-js/issues/1327), thanks [**@minseok-choe**](https://github.com/minseok-choe) +- Fixed `Array.from` and some other methods with proxy targets, [#1322](https://github.com/zloirock/core-js/issues/1322), thanks [**@minseok-choe**](https://github.com/minseok-choe) +- Fixed dependencies loading for modules from `ArrayBuffer.prototype.transfer` and friends proposal in some specific cases in IE10- +- Dropped context workaround from collection static methods entries since with current methods semantic it's no longer required +- Added instance methods polyfills to entries of collections static methods that produce collection instances +- Added missed `Date.prototype.toJSON` to `JSON.stringify` entries dependencies +- Added debugging info in some missed cases +- Compat data improvements: + - [`{ Map, Object }.groupBy`](https://github.com/tc39/proposal-array-grouping), [`Promise.withResolvers`](https://github.com/tc39/proposal-promise-with-resolvers), [`ArrayBuffer.prototype.transfer` and friends](https://github.com/tc39/proposal-arraybuffer-transfer) marked as supported from [Safari 17.4](https://developer.apple.com/documentation/safari-release-notes/safari-17_4-release-notes#JavaScript) + - [New `Set` methods](https://github.com/tc39/proposal-set-methods) [fixed](https://bugs.chromium.org/p/v8/issues/detail?id=14559#c4) and marked as supported from V8 ~ Chrome 123 + - Added [Deno 1.40](https://deno.com/blog/v1.40) compat data mapping + - `Symbol.metadata` marked as supported from [Deno 1.40.4](https://github.com/denoland/deno/releases/tag/v1.40.4) + - Updated Electron 30 compat data mapping + +### [3.35.1 - 2024.01.21](https://github.com/zloirock/core-js/releases/tag/v3.35.1) +- Fixed internal `ToLength` operation with bigints, [#1318](https://github.com/zloirock/core-js/issues/1318) +- Removed significant redundant code from `String.prototype.split` polyfill +- Fixed setting names of methods with symbol keys in some old engines +- Minor fix of prototype methods export logic in the pure version +- Compat data improvements: + - [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers) methods marked as supported from V8 ~ Chrome 122 + - Note that V8 ~ Chrome 122 add [`Set` methods](https://github.com/tc39/proposal-set-methods), but they have [a bug](https://bugs.chromium.org/p/v8/issues/detail?id=14559) [similar to Safari](https://bugs.webkit.org/show_bug.cgi?id=267494) + - `self` marked as fixed from Bun 1.0.22 + - [`SuppressedError` and `Symbol.{ dispose, asyncDispose }`](https://github.com/tc39/proposal-explicit-resource-management) marked as [supported from Bun 1.0.23](https://bun.sh/blog/bun-v1.0.23#resource-management-is-now-supported) + - Added Oculus Quest Browser 31 compat data mapping + - Updated Electron 29 and added Electron 30 compat data mapping + +### [3.35.0 - 2023.12.29](https://github.com/zloirock/core-js/releases/tag/v3.35.0) +- [`{ Map, Set, WeakMap, WeakSet }.{ from, of }`](https://github.com/tc39/proposal-setmap-offrom) became non-generic, following [this](https://github.com/tc39/proposal-setmap-offrom/issues/16#issuecomment-1843346541) and some other notes. Now they can be invoked without `this`, but no longer return subclass instances +- Fixed handling some cases of non-enumerable symbol keys from `Symbol` polyfill +- Removed unneeded NodeJS domains-related logic from `queueMicrotask` polyfill +- Fixed subclassing of wrapped `ArrayBuffer` +- Refactoring, many different minor optimizations +- Compat data improvements: + - [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async) marked as [supported from V8 ~ Chrome 121](https://bugs.chromium.org/p/v8/issues/detail?id=13321#c13) + - It seems that the ancient [`Array.prototype.push` bug](https://bugs.chromium.org/p/v8/issues/detail?id=12681) is fixed in V8 ~ Chrome 122 (Hallelujah!) + - [`ArrayBuffer.prototype.transfer` and friends proposal](https://github.com/tc39/proposal-arraybuffer-transfer) features marked as [supported from FF 122](https://bugzilla.mozilla.org/show_bug.cgi?id=1865103#c8) and Bun 1.0.19 + - [`Object.groupBy` and `Map.groupBy`](https://github.com/tc39/proposal-array-grouping) marked as supported from Bun 1.0.19 + - Since [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers) methods are still not disabled in Deno, the web compatibility issue why it was disabled in Chromium makes no sense for Deno and fixed in the spec, they marked as supported from Deno 1.37 + - Added Opera Android 80 and updated [Opera Android 79](https://forums.opera.com/topic/68490/opera-for-android-79) compat data mapping + - Added Samsung Internet 24 compat data mapping + +### [3.34.0 - 2023.12.06](https://github.com/zloirock/core-js/releases/tag/v3.34.0) +- [`Array` grouping proposal](https://github.com/tc39/proposal-array-grouping): + - Methods: + - `Object.groupBy` + - `Map.groupBy` + - Moved to stable ES, [November 2023 TC39 meeting](https://github.com/tc39/proposal-array-grouping/issues/60) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries +- [`Promise.withResolvers` proposal](https://github.com/tc39/proposal-promise-with-resolvers): + - Method: + - `Promise.withResolvers` + - Moved to stable ES, [November 2023 TC39 meeting](https://twitter.com/robpalmer2/status/1729216597623976407) + - Added `es.` namespace module, `/es/` and `/stable/` namespaces entries +- Fixed a web incompatibility issue of [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers), [proposal-iterator-helpers/287](https://github.com/tc39/proposal-iterator-helpers/pull/287) and some following changes, November 2023 TC39 meeting +- Added [`Uint8Array` to / from base64 and hex stage 2 proposal](https://github.com/tc39/proposal-arraybuffer-base64): + - Methods: + - `Uint8Array.fromBase64` + - `Uint8Array.fromHex` + - `Uint8Array.prototype.toBase64` + - `Uint8Array.prototype.toHex` +- Relaxed some specific cases of [`Number.fromString`](https://github.com/tc39/proposal-number-fromstring) validation before clarification of [proposal-number-fromstring/24](https://github.com/tc39/proposal-number-fromstring/issues/24) +- Fixed `@@toStringTag` property descriptors on DOM collections, [#1312](https://github.com/zloirock/core-js/issues/1312) +- Fixed the order of arguments validation in `Array` iteration methods, [#1313](https://github.com/zloirock/core-js/issues/1313) +- Some minor `atob` / `btoa` improvements +- Compat data improvements: + - [`Promise.withResolvers`](https://github.com/tc39/proposal-promise-with-resolvers) marked as shipped from FF121 + +### [3.33.3 - 2023.11.20](https://github.com/zloirock/core-js/releases/tag/v3.33.3) +- Fixed an issue getting the global object on Duktape, [#1303](https://github.com/zloirock/core-js/issues/1303) +- Avoid sharing internal `[[DedentMap]]` from [`String.dedent` proposal](https://github.com/tc39/proposal-string-dedent) between `core-js` instances before stabilization of the proposal +- Some internal untangling +- Compat data improvements: + - Added [Deno 1.38](https://deno.com/blog/v1.38) compat data mapping + - [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async) marked as [supported from Deno 1.38](https://github.com/denoland/deno/pull/21048) + - [`Symbol.{ dispose, asyncDispose }`](https://github.com/tc39/proposal-explicit-resource-management) marked as [supported from Deno 1.38](https://github.com/denoland/deno/pull/20845) + - Added Opera Android 79 compat data mapping + - Added Oculus Quest Browser 30 compat data mapping + - Updated Electron 28 and 29 compat data mapping + +### [3.33.2 - 2023.10.31](https://github.com/zloirock/core-js/releases/tag/v3.33.2) +- Simplified `structuredClone` polyfill, avoided second tree pass in cases of transferring +- Added support of [`SuppressedError`](https://github.com/tc39/proposal-explicit-resource-management#the-suppressederror-error) to `structuredClone` polyfill +- Removed unspecified unnecessary `ArrayBuffer` and `DataView` dependencies of `structuredClone` lack of which could cause errors in some entries in IE10- +- Fixed handling of fractional number part in [`Number.fromString`](https://github.com/tc39/proposal-number-fromstring) +- Compat data improvements: + - [`URL.canParse`](https://url.spec.whatwg.org/#dom-url-canparse) marked as [supported from Chromium 120](https://bugs.chromium.org/p/chromium/issues/detail?id=1425839) + - Updated Opera Android 78 compat data mapping + - Added Electron 29 compat data mapping + +### [3.33.1 - 2023.10.20](https://github.com/zloirock/core-js/releases/tag/v3.33.1) +- Added one more workaround of possible error with `Symbol` polyfill on global object, [#1289](https://github.com/zloirock/core-js/issues/1289#issuecomment-1768411444) +- Directly specified `type: commonjs` in `package.json` of all packages to avoid potential breakage in future Node versions, see [this issue](https://github.com/nodejs/TSC/issues/1445) +- Prevented potential issue with lack of some dependencies after automatic optimization polyfills of some methods in the pure version +- Some minor internal fixes and optimizations +- Compat data improvements: + - [`String.prototype.{ isWellFormed, toWellFormed }`](https://github.com/tc39/proposal-is-usv-string) marked as [supported from FF119](https://bugzilla.mozilla.org/show_bug.cgi?id=1850755) + - Added React Native 0.73 Hermes compat data, mainly fixes of [some issues](https://github.com/facebook/hermes/issues/770) + - Added [NodeJS 21.0 compat data mapping](https://nodejs.org/ru/blog/release/v21.0.0) + +### [3.33.0 - 2023.10.02](https://github.com/zloirock/core-js/releases/tag/v3.33.0) +- Re-introduced [`RegExp` escaping stage 2 proposal](https://github.com/tc39/proposal-regex-escaping), September 2023 TC39 meeting: + - Added `RegExp.escape` method with the new set of symbols for escaping + - Some years ago, it was presented in `core-js`, but it was removed after rejecting the old version of this proposal +- Added [`ArrayBuffer.prototype.{ transfer, transferToFixedLength }`](https://github.com/tc39/proposal-arraybuffer-transfer) and support transferring of `ArrayBuffer`s via [`structuredClone`](https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone) to engines with `MessageChannel` +- Optimized [`Math.f16round`](https://github.com/tc39/proposal-float16array) polyfill +- Fixed [some conversion cases](https://github.com/petamoriken/float16/issues/1046) of [`Math.f16round` and `DataView.prototype.{ getFloat16, setFloat16 }`](https://github.com/tc39/proposal-float16array) +- Fully forced polyfilling of [the TC39 `Observable` proposal](https://github.com/tc39/proposal-observable) because of incompatibility with [the new WHATWG `Observable` proposal](https://github.com/WICG/observable) +- Added an extra workaround of errors with exotic environment objects in `Symbol` polyfill, [#1289](https://github.com/zloirock/core-js/issues/1289) +- Some minor fixes and stylistic changes +- Compat data improvements: + - V8 unshipped [`Iterator` helpers](https://github.com/tc39/proposal-iterator-helpers) because of [some Web compatibility issues](https://github.com/tc39/proposal-iterator-helpers/issues/286) + - [`Promise.withResolvers`](https://github.com/tc39/proposal-promise-with-resolvers) marked as [supported from V8 ~ Chrome 119](https://chromestatus.com/feature/5810984110784512) + - [`Array` grouping proposal](https://github.com/tc39/proposal-array-grouping) features marked as [supported from FF119](https://bugzilla.mozilla.org/show_bug.cgi?id=1792650#c9) + - [`value` argument of `URLSearchParams.prototype.{ has, delete }`](https://url.spec.whatwg.org/#dom-urlsearchparams-delete) marked as properly supported from V8 ~ Chrome 118 + - [`URL.canParse`](https://url.spec.whatwg.org/#dom-url-canparse) and [`URLSearchParams.prototype.size`](https://url.spec.whatwg.org/#dom-urlsearchparams-size) marked as [supported from Bun 1.0.2](https://github.com/oven-sh/bun/releases/tag/bun-v1.0.2) + - Added Deno 1.37 compat data mapping + - Added Electron 28 compat data mapping + - Added Opera Android 78 compat data mapping + +### [3.32.2 - 2023.09.07](https://github.com/zloirock/core-js/releases/tag/v3.32.2) +- Fixed `structuredClone` feature detection `core-js@3.32.1` bug, [#1288](https://github.com/zloirock/core-js/issues/1288) +- Added a workaround of old WebKit + `eval` bug, [#1287](https://github.com/zloirock/core-js/pull/1287) +- Compat data improvements: + - Added Samsung Internet 23 compat data mapping + - Added Quest Browser 29 compat data mapping + +### [3.32.1 - 2023.08.19](https://github.com/zloirock/core-js/releases/tag/v3.32.1) +- Fixed some cases of IEEE754 rounding, [#1279](https://github.com/zloirock/core-js/issues/1279), thanks [**@petamoriken**](https://github.com/petamoriken) +- Prevented injection `process` polyfill to `core-js` via some bundlers or `esm.sh`, [#1277](https://github.com/zloirock/core-js/issues/1277) +- Some minor fixes and stylistic changes +- Compat data improvements: + - [`Promise.withResolvers`](https://github.com/tc39/proposal-promise-with-resolvers) marked as supported [from Bun 0.7.1](https://bun.sh/blog/bun-v0.7.1#bun-ismainthread-and-promise-withresolvers) + - Added Opera Android 77 compat data mapping + - Updated Electron 27 compat data mapping + +### [3.32.0 - 2023.07.28](https://github.com/zloirock/core-js/releases/tag/v3.32.0) +- [`Array` grouping proposal](https://github.com/tc39/proposal-array-grouping), July 2023 TC39 meeting updates: + - [Moved back to stage 3](https://github.com/tc39/proposal-array-grouping/issues/54) + - Added `/actual/` namespaces entries, unconditional forced replacement changed to feature detection +- [`Promise.withResolvers` proposal](https://github.com/tc39/proposal-promise-with-resolvers), July 2023 TC39 meeting updates: + - [Moved to stage 3](https://github.com/tc39/proposal-promise-with-resolvers/pull/18) + - Added `/actual/` namespaces entries, unconditional forced replacement changed to feature detection +- [`Set` methods stage 3 proposal](https://github.com/tc39/proposal-set-methods), July 2023 TC39 meeting updates: + - Throw on negative `Set` sizes, [proposal-set-methods/88](https://github.com/tc39/proposal-set-methods/pull/88) + - Removed `IsCallable` check in `GetKeysIterator`, [proposal-set-methods/101](https://github.com/tc39/proposal-set-methods/pull/101) +- [Iterator Helpers stage 3 proposal](https://github.com/tc39/proposal-iterator-helpers): + - Avoid creating observable `String` wrapper objects, July 2023 TC39 meeting update, [proposal-iterator-helpers/281](https://github.com/tc39/proposal-iterator-helpers/pull/281) + - `Iterator` is not constructible from the active function object (works as an abstract class) +- Async explicit resource management: + - Moved back into [the initial proposal](https://github.com/tc39/proposal-explicit-resource-management) -> moved to stage 3, [proposal-explicit-resource-management/154](https://github.com/tc39/proposal-explicit-resource-management/pull/154) + - Added `/actual/` namespace entries, unconditional forced replacement changed to feature detection + - Ignore return value of `[@@dispose]()` method when hint is `async-dispose`, [proposal-explicit-resource-management/180](https://github.com/tc39/proposal-explicit-resource-management/pull/180) + - Added ticks for empty resources, [proposal-explicit-resource-management/163](https://github.com/tc39/proposal-explicit-resource-management/pull/163) +- Added some methods from [`Float16Array` stage 3 proposal](https://github.com/tc39/proposal-float16array): + - There are some reason why I don't want to add `Float16Array` right now, however, make sense to add some methods from this proposal. + - Methods: + - `Math.f16round` + - `DataView.prototype.getFloat16` + - `DataView.prototype.setFloat16` +- Added [`DataView` get / set `Uint8Clamped` methods stage 1 proposal](https://github.com/tc39/proposal-dataview-get-set-uint8clamped): + - Methods: + - `DataView.prototype.getUint8Clamped` + - `DataView.prototype.setUint8Clamped` +- Used strict mode in some missed cases, [#1269](https://github.com/zloirock/core-js/issues/1269) +- Fixed [a Chromium 117 bug](https://bugs.chromium.org/p/v8/issues/detail?id=14222) in `value` argument of `URLSearchParams.prototype.{ has, delete }` +- Fixed early WebKit ~ Safari 17.0 beta `Set` methods implementation by the actual spec +- Fixed incorrect `Symbol.{ dispose, asyncDispose }` descriptors from [NodeJS 20.4](https://github.com/nodejs/node/issues/48699) / transpilers helpers / userland code +- Fixed forced polyfilling of some iterator helpers that should return wrapped iterator in the pure version +- Fixed and exposed [`AsyncIteratorPrototype` `core-js/configurator` option](https://github.com/zloirock/core-js#asynciterator-helpers), [#1268](https://github.com/zloirock/core-js/issues/1268) +- Compat data improvements: + - Sync [`Iterator` helpers proposal](https://github.com/tc39/proposal-iterator-helpers) features marked as [supported](https://chromestatus.com/feature/5102502917177344) from V8 ~ Chrome 117 + - [`Array` grouping proposal](https://github.com/tc39/proposal-array-grouping) features marked as [supported](https://chromestatus.com/feature/5714791975878656) from V8 ~ Chrome 117 + - Mark `Symbol.{ dispose, asyncDispose }` as supported from NodeJS 20.5.0 (as mentioned above, NodeJS 20.4.0 add it, but [with incorrect descriptors](https://github.com/nodejs/node/issues/48699)) + - Added Electron 27 compat data mapping + +### [3.31.1 - 2023.07.06](https://github.com/zloirock/core-js/releases/tag/v3.31.1) +- Fixed a `structuredClone` bug with cloning views of transferred buffers, [#1265](https://github.com/zloirock/core-js/issues/1265) +- Fixed the order of arguments validation in `DataView` methods +- Allowed cloning of [`Float16Array`](https://github.com/tc39/proposal-float16array) in `structuredClone` +- Compat data improvements: + - [`Set` methods proposal](https://github.com/tc39/proposal-set-methods) marked as [supported from Safari 17.0](https://developer.apple.com/documentation/safari-release-notes/safari-17-release-notes#JavaScript) + - New `URL` features: [`URL.canParse`](https://url.spec.whatwg.org/#dom-url-canparse), [`URLSearchParams.prototype.size`](https://url.spec.whatwg.org/#dom-urlsearchparams-size) and [`value` argument of `URLSearchParams.prototype.{ has, delete }`](https://url.spec.whatwg.org/#dom-urlsearchparams-delete) marked as [supported from Safari 17.0](https://developer.apple.com/documentation/safari-release-notes/safari-17-release-notes#Web-API) + - `value` argument of `URLSearchParams.prototype.{ has, delete }` marked as supported from [Deno 1.35](https://github.com/denoland/deno/pull/19654) + - `AggregateError` and well-formed `JSON.stringify` marked as [supported React Native 0.72 Hermes](https://reactnative.dev/blog/2023/06/21/0.72-metro-package-exports-symlinks#more-ecmascript-support-in-hermes) + - Added Deno 1.35 compat data mapping + - Added Quest Browser 28 compat data mapping + - Added missing NodeJS 12.16-12.22 compat data mapping + - Updated Opera Android 76 compat data mapping + +### [3.31.0 - 2023.06.12](https://github.com/zloirock/core-js/releases/tag/v3.31.0) +- [Well-formed unicode strings proposal](https://github.com/tc39/proposal-is-usv-string): + - Methods: + - `String.prototype.isWellFormed` method + - `String.prototype.toWellFormed` method + - Moved to stable ES, [May 2023 TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2023-05/may-15.md#well-formed-unicode-strings-for-stage-4) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries +- [`Array` grouping proposal](https://github.com/tc39/proposal-array-grouping), [May 2023 TC39 meeting updates](https://github.com/tc39/notes/blob/main/meetings/2023-05/may-16.md#arrayprototypegroup-rename-for-web-compatibility): + - Because of the [web compat issue](https://github.com/tc39/proposal-array-grouping/issues/44), [moved from prototype to static methods](https://github.com/tc39/proposal-array-grouping/pull/47). Added: + - `Object.groupBy` method + - `Map.groupBy` method (with the actual semantic - with a minor difference it was present [in the collections methods stage 1 proposal](https://github.com/tc39/proposal-collection-methods)) + - Demoted to stage 2 +- [Decorator Metadata proposal](https://github.com/tc39/proposal-decorator-metadata), [May 2023 TC39 meeting updates](https://github.com/tc39/notes/blob/main/meetings/2023-05/may-16.md#decorator-metadata-for-stage-3): + - Moved to stage 3 + - Added `Function.prototype[Symbol.metadata]` (`=== null`) + - Added `/actual/` entries +- [Iterator Helpers stage 3 proposal](https://github.com/tc39/proposal-iterator-helpers): + - Changed `Symbol.iterator` fallback from callable check to `undefined` / `null` check, [May 2023 TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2023-05/may-16.md#iterator-helpers-should-symboliterator-fallback-be-a-callable-check-or-an-undefinednull-check), [proposal-iterator-helpers/272](https://github.com/tc39/proposal-iterator-helpers/pull/272) + - Removed `IsCallable` check on `NextMethod`, deferring errors to `Call` site, [May 2023 TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2023-05/may-16.md#iterator-helpers-should-malformed-iterators-fail-early-or-fail-only-when-iterated), [proposal-iterator-helpers/274](https://github.com/tc39/proposal-iterator-helpers/pull/274) +- Added [`Promise.withResolvers` stage 2 proposal](https://github.com/tc39/proposal-promise-with-resolvers): + - `Promise.withResolvers` method +- [`Symbol` predicates stage 2 proposal](https://github.com/tc39/proposal-symbol-predicates): + - The methods renamed to end with `Symbol`, [May 2023 TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2023-05/may-15.md#symbol-predicates): + - `Symbol.isRegistered` -> `Symbol.isRegisteredSymbol` method + - `Symbol.isWellKnown` -> `Symbol.isWellKnownSymbol` method +- Added `value` argument of `URLSearchParams.prototype.{ has, delete }`, [url/735](https://github.com/whatwg/url/pull/735) +- Fixed some cases of increasing buffer size in `ArrayBuffer.prototype.{ transfer, transferToFixedLength }` polyfills +- Fixed awaiting async `AsyncDisposableStack.prototype.adopt` callback, [#1258](https://github.com/zloirock/core-js/issues/1258) +- Fixed `URLSearchParams#size` in ES3 engines (IE8-) +- Added a workaround in `Object.{ entries, values }` for some IE versions bug with invisible integer keys on `null`-prototype objects +- Added TypeScript definitions to `core-js-compat`, [#1235](https://github.com/zloirock/core-js/issues/1235), thanks [**@susnux**](https://github.com/susnux) +- Compat data improvements: + - [`Set.prototype.difference`](https://github.com/tc39/proposal-set-methods) that was missed in Bun because of [a bug](https://github.com/oven-sh/bun/issues/2309) added in 0.6.0 + - `Array.prototype.{ group, groupToMap }` marked as no longer supported in WebKit runtimes because of the mentioned above web compat issue. For example, it's disabled from Bun 0.6.2 + - Methods from the [change `Array` by copy proposal](https://github.com/tc39/proposal-change-array-by-copy) marked as supported from FF115 + - [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async) marked as supported from FF115 + - [`URL.canParse`](https://url.spec.whatwg.org/#dom-url-canparse) marked as supported from FF115 + - `value` argument of `URLSearchParams.prototype.{ has, delete }` marked as supported from [NodeJS 20.2.0](https://github.com/nodejs/node/pull/47885) and FF115 + - Added Deno 1.34 compat data mapping + - Added Electron 26 compat data mapping + - Added Samsung Internet 22 compat data mapping + - Added Opera Android 75 and 76 compat data mapping + - Added Quest Browser 27 compat data mapping + +### [3.30.2 - 2023.05.07](https://github.com/zloirock/core-js/releases/tag/v3.30.2) +- Added a fix for a NodeJS 20.0.0 [bug](https://github.com/nodejs/node/issues/47612) with cloning `File` via `structuredClone` +- Added protection from Terser unsafe `String` optimization, [#1242](https://github.com/zloirock/core-js/issues/1242) +- Added a workaround for getting proper global object in Figma plugins, [#1231](https://github.com/zloirock/core-js/issues/1231) +- Compat data improvements: + - Added NodeJS 20.0 compat data mapping + - Added Deno 1.33 compat data mapping + - [`URL.canParse`](https://url.spec.whatwg.org/#dom-url-canparse) marked as supported (fixed) from [NodeJS 20.1.0](https://github.com/nodejs/node/pull/47513) and [Deno 1.33.2](https://github.com/denoland/deno/pull/18896) + +### [3.30.1 - 2023.04.14](https://github.com/zloirock/core-js/releases/tag/v3.30.1) +- Added a fix for a NodeJS 19.9.0 `URL.canParse` [bug](https://github.com/nodejs/node/issues/47505) +- Compat data improvements: + - [`JSON.parse` source text access proposal](https://github.com/tc39/proposal-json-parse-with-source) features marked as [supported](https://chromestatus.com/feature/5121582673428480) from V8 ~ Chrome 114 + - [`ArrayBuffer.prototype.transfer` and friends proposal](https://github.com/tc39/proposal-arraybuffer-transfer) features marked as [supported](https://chromestatus.com/feature/5073244152922112) from V8 ~ Chrome 114 + - [`URLSearchParams.prototype.size`](https://github.com/whatwg/url/pull/734) marked as supported from V8 ~ Chrome 113 + +### [3.30.0 - 2023.04.04](https://github.com/zloirock/core-js/releases/tag/v3.30.0) +- Added [`URL.canParse` method](https://url.spec.whatwg.org/#dom-url-canparse), [url/763](https://github.com/whatwg/url/pull/763) +- [`Set` methods proposal](https://github.com/tc39/proposal-set-methods): + - Removed sort from `Set.prototype.intersection`, [March 2023 TC39 meeting](https://github.com/babel/proposals/issues/87#issuecomment-1478610425), [proposal-set-methods/94](https://github.com/tc39/proposal-set-methods/pull/94) +- Iterator Helpers proposals ([sync](https://github.com/tc39/proposal-iterator-helpers), [async](https://github.com/tc39/proposal-async-iterator-helpers)): + - Validate arguments before opening iterator, [March 2023 TC39 meeting](https://github.com/babel/proposals/issues/87#issuecomment-1478412430), [proposal-iterator-helpers/265](https://github.com/tc39/proposal-iterator-helpers/pull/265) +- Explicit Resource Management proposals ([sync](https://github.com/tc39/proposal-explicit-resource-management), [async](https://github.com/tc39/proposal-async-explicit-resource-management)): + - `(Async)DisposableStack.prototype.move` marks the original stack as disposed, [#1226](https://github.com/zloirock/core-js/issues/1226) + - Some simplifications like [proposal-explicit-resource-management/150](https://github.com/tc39/proposal-explicit-resource-management/pull/150) +- [`Iterator.range` proposal](https://github.com/tc39/proposal-Number.range): + - Moved to Stage 2, [March 2023 TC39 meeting](https://github.com/babel/proposals/issues/87#issuecomment-1480266760) +- [Decorator Metadata proposal](https://github.com/tc39/proposal-decorator-metadata): + - Returned to usage `Symbol.metadata`, [March 2023 TC39 meeting](https://github.com/babel/proposals/issues/87#issuecomment-1478790137), [proposal-decorator-metadata/12](https://github.com/tc39/proposal-decorator-metadata/pull/12) +- Compat data improvements: + - [`URLSearchParams.prototype.size`](https://github.com/whatwg/url/pull/734) marked as supported from FF112, NodeJS 19.8 and Deno 1.32 + - Added Safari 16.4 compat data + - Added Deno 1.32 compat data mapping + - Added Electron 25 and updated 24 compat data mapping + - Added Samsung Internet 21 compat data mapping + - Added Quest Browser 26 compat data mapping + - Updated Opera Android 74 compat data + +### [3.29.1 - 2023.03.13](https://github.com/zloirock/core-js/releases/tag/v3.29.1) +- Fixed dependencies of some entries +- Fixed `ToString` conversion / built-ins nature of some accessors +- [`String.prototype.{ isWellFormed, toWellFormed }`](https://github.com/tc39/proposal-is-usv-string) marked as supported from V8 ~ Chrome 111 +- Added Opera Android 74 compat data mapping + +### [3.29.0 - 2023.02.27](https://github.com/zloirock/core-js/releases/tag/v3.29.0) +- Added `URLSearchParams.prototype.size` getter, [url/734](https://github.com/whatwg/url/pull/734) +- Allowed cloning resizable `ArrayBuffer`s in the `structuredClone` polyfill +- Fixed wrong export in `/(stable|actual|full)/instance/unshift` entries, [#1207](https://github.com/zloirock/core-js/issues/1207) +- Compat data improvements: + - [`Set` methods proposal](https://github.com/tc39/proposal-set-methods) marked as supported from Bun 0.5.7 + - `String.prototype.toWellFormed` marked as fixed from Bun 0.5.7 + - Added Deno 1.31 compat data mapping + +### [3.28.0 - 2023.02.14](https://github.com/zloirock/core-js/releases/tag/v3.28.0) +- [Change `Array` by copy proposal](https://github.com/tc39/proposal-change-array-by-copy): + - Methods: + - `Array.prototype.toReversed` + - `Array.prototype.toSorted` + - `Array.prototype.toSpliced` + - `Array.prototype.with` + - `%TypedArray%.prototype.toReversed` + - `%TypedArray%.prototype.toSorted` + - `%TypedArray%.prototype.with` + - Moved to stable ES, [January 2023 TC39 meeting](https://github.com/babel/proposals/issues/86#issuecomment-1409261397) + - Added `es.` namespace modules, `/es/` and `/stable/` namespaces entries +- Added [`JSON.parse` source text access Stage 3 proposal](https://github.com/tc39/proposal-json-parse-with-source) + - Methods: + - `JSON.parse` patched for support `source` in `reviver` function arguments + - `JSON.rawJSON` + - `JSON.isRawJSON` + - `JSON.stringify` patched for support `JSON.rawJSON` +- Added [`ArrayBuffer.prototype.transfer` and friends Stage 3 proposal](https://github.com/tc39/proposal-arraybuffer-transfer): + - Built-ins: + - `ArrayBuffer.prototype.detached` + - `ArrayBuffer.prototype.transfer` (only in runtimes with native `structuredClone` with `ArrayBuffer` transfer support) + - `ArrayBuffer.prototype.transferToFixedLength` (only in runtimes with native `structuredClone` with `ArrayBuffer` transfer support) + - In backwards, in runtimes with native `ArrayBuffer.prototype.transfer`, but without proper `structuredClone`, added `ArrayBuffer` transfer support to `structuredClone` polyfill +- [Iterator Helpers](https://github.com/tc39/proposal-iterator-helpers) proposal: + - Split into 2 ([sync](https://github.com/tc39/proposal-iterator-helpers) and [async](https://github.com/tc39/proposal-async-iterator-helpers)) proposals, async version moved back to Stage 2, [January 2023 TC39 meeting](https://github.com/babel/proposals/issues/86#issuecomment-1410926068) + - Allowed interleaved mapping in `AsyncIterator` helpers, [proposal-iterator-helpers/262](https://github.com/tc39/proposal-iterator-helpers/pull/262) +- [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management) Stage 3 and [Async Explicit Resource Management](https://github.com/tc39/proposal-async-explicit-resource-management/) Stage 2 proposals: + - `InstallErrorCause` removed from `SuppressedError`, [January 2023 TC39 meeting](https://github.com/babel/proposals/issues/86#issuecomment-1410889704), [proposal-explicit-resource-management/145](https://github.com/tc39/proposal-explicit-resource-management/pull/146) + - Simplified internal behaviour of `{ AsyncDisposableStack, DisposableStack }.prototype.use`, [proposal-explicit-resource-management/143](https://github.com/tc39/proposal-explicit-resource-management/pull/143) +- Added [`Symbol` predicates Stage 2 proposal](https://github.com/tc39/proposal-symbol-predicates) + - Methods: + - `Symbol.isRegistered` + - `Symbol.isWellKnown` +- `Number.range` Stage 1 proposal and method [renamed to `Iterator.range`](https://github.com/tc39/proposal-Number.range) +- `Function.prototype.unThis` Stage 0 proposal and method [renamed to `Function.prototype.demethodize`](https://github.com/js-choi/proposal-function-demethodize) +- Fixed [Safari `String.prototype.toWellFormed` `ToString` conversion bug](https://bugs.webkit.org/show_bug.cgi?id=251757) +- Improved some cases handling of array-replacer in `JSON.stringify` symbols handling fix +- Fixed many other old `JSON.{ parse, stringify }` bugs (numbers instead of strings as keys in replacer, handling negative zeroes, spaces, some more handling symbols cases, etc.) +- Fixed configurability and `ToString` conversion of some accessors +- Added throwing proper errors on an incorrect context in some `ArrayBuffer` and `DataView` methods +- Some minor `DataView` and `%TypedArray%` polyfills optimizations +- Added proper error on the excess number of trailing `=` in the `atob` polyfill +- Fixed theoretically possible ReDoS vulnerabilities in `String.prototype.{ trim, trimEnd, trimRight }`, `parse(Int|Float)`, `Number`, `atob`, and `URL` polyfills in some ancient engines +- Compat data improvements: + - `RegExp.prototype.flags` marked as fixed from V8 ~ Chrome 111 + - Added Opera Android 73 compat data mapping +- Added TypeScript definitions to `core-js-builder` + +### [3.27.2 - 2023.01.19](https://github.com/zloirock/core-js/releases/tag/v3.27.2) +- [`Set` methods proposal](https://github.com/tc39/proposal-set-methods) updates: + - Closing of iterators of `Set`-like objects on early exit, [proposal-set-methods/85](https://github.com/tc39/proposal-set-methods/pull/85) + - Some other minor internal changes +- Added one more workaround of a `webpack` dev server bug on IE global methods, [#1161](https://github.com/zloirock/core-js/issues/1161) +- Fixed possible `String.{ raw, cooked }` error with empty template array +- Used non-standard V8 `Error.captureStackTrace` instead of stack parsing in new error classes / wrappers where it's possible +- Added detection correctness of iteration to `Promise.{ allSettled, any }` feature detection, Hermes issue +- Compat data improvements: + - [Change `Array` by copy proposal](https://github.com/tc39/proposal-change-array-by-copy) marked as supported from V8 ~ Chrome 110 + - Added Samsung Internet 20 compat data mapping + - Added Quest Browser 25 compat data mapping + - Added React Native 0.71 Hermes compat data + - Added Electron 23 and 24 compat data mapping + - `self` marked as fixed in Deno 1.29.3, [deno/17362](https://github.com/denoland/deno/pull/17362) +- Minor tweaks of minification settings for `core-js-bundle` +- Refactoring, some minor fixes, improvements, optimizations + +### [3.27.1 - 2022.12.30](https://github.com/zloirock/core-js/releases/tag/v3.27.1) +- Fixed a Chakra-based MS Edge (18-) bug that unfreeze (O_o) frozen arrays used as `WeakMap` keys +- Fixing of the previous bug also fixes some cases of `String.dedent` in MS Edge +- Fixed dependencies of some entries + +### [3.27.0 - 2022.12.26](https://github.com/zloirock/core-js/releases/tag/v3.27.0) +- [Iterator Helpers](https://github.com/tc39/proposal-iterator-helpers) proposal: + - Built-ins: + - `Iterator` + - `Iterator.from` + - `Iterator.prototype.drop` + - `Iterator.prototype.every` + - `Iterator.prototype.filter` + - `Iterator.prototype.find` + - `Iterator.prototype.flatMap` + - `Iterator.prototype.forEach` + - `Iterator.prototype.map` + - `Iterator.prototype.reduce` + - `Iterator.prototype.some` + - `Iterator.prototype.take` + - `Iterator.prototype.toArray` + - `Iterator.prototype.toAsync` + - `Iterator.prototype[@@toStringTag]` + - `AsyncIterator` + - `AsyncIterator.from` + - `AsyncIterator.prototype.drop` + - `AsyncIterator.prototype.every` + - `AsyncIterator.prototype.filter` + - `AsyncIterator.prototype.find` + - `AsyncIterator.prototype.flatMap` + - `AsyncIterator.prototype.forEach` + - `AsyncIterator.prototype.map` + - `AsyncIterator.prototype.reduce` + - `AsyncIterator.prototype.some` + - `AsyncIterator.prototype.take` + - `AsyncIterator.prototype.toArray` + - `AsyncIterator.prototype[@@toStringTag]` + - Moved to Stage 3, [November 2022 TC39 meeting](https://github.com/babel/proposals/issues/85#issuecomment-1333474304) + - Added `/actual/` entries, unconditional forced replacement disabled for features that survived to Stage 3 + - `.from` accept strings, `.flatMap` throws on strings returned from the callback, [proposal-iterator-helpers/244](https://github.com/tc39/proposal-iterator-helpers/pull/244), [proposal-iterator-helpers/250](https://github.com/tc39/proposal-iterator-helpers/pull/250) + - `.from` and `.flatMap` throws on non-object *iterators*, [proposal-iterator-helpers/253](https://github.com/tc39/proposal-iterator-helpers/pull/253) +- [`Set` methods proposal](https://github.com/tc39/proposal-set-methods): + - Built-ins: + - `Set.prototype.intersection` + - `Set.prototype.union` + - `Set.prototype.difference` + - `Set.prototype.symmetricDifference` + - `Set.prototype.isSubsetOf` + - `Set.prototype.isSupersetOf` + - `Set.prototype.isDisjointFrom` + - Moved to Stage 3, [November 2022 TC39 meeting](https://github.com/babel/proposals/issues/85#issuecomment-1332175557) + - Reimplemented with [new semantics](https://tc39.es/proposal-set-methods/): + - Optimized performance (iteration over lowest set) + - Accepted only `Set`-like objects as an argument, not all iterables + - Accepted only `Set`s as `this`, no `@@species` support, and other minor changes + - Added `/actual/` entries, unconditional forced replacement changed to feature detection + - For avoiding breaking changes: + - New versions of methods are implemented as new modules and available in new entries or entries where old versions of methods were not available before (like `/actual/` namespace) + - In entries where they were available before (like `/full/` namespace), those methods are available with fallbacks to old semantics (in addition to `Set`-like, they accept iterable objects). This behavior will be removed from the next major release +- [Well-Formed Unicode Strings](https://github.com/tc39/proposal-is-usv-string) proposal: + - Methods: + - `String.prototype.isWellFormed` + - `String.prototype.toWellFormed` + - Moved to Stage 3, [November 2022 TC39 meeting](https://github.com/babel/proposals/issues/85#issuecomment-1332180862) + - Added `/actual/` entries, disabled unconditional forced replacement +- [Explicit resource management](https://github.com/tc39/proposal-explicit-resource-management) Stage 3 and [Async explicit resource management](https://github.com/tc39/proposal-async-explicit-resource-management) Stage 2 proposals: + - Renamed from "`using` statement" and [split into 2 (sync and async) proposals](https://github.com/tc39/proposal-explicit-resource-management/pull/131) + - In addition to already present well-known symbols, added new built-ins: + - `Symbol.dispose` + - `Symbol.asyncDispose` + - `SuppressedError` + - `DisposableStack` + - `DisposableStack.prototype.dispose` + - `DisposableStack.prototype.use` + - `DisposableStack.prototype.adopt` + - `DisposableStack.prototype.defer` + - `DisposableStack.prototype.move` + - `DisposableStack.prototype[@@dispose]` + - `AsyncDisposableStack` + - `AsyncDisposableStack.prototype.disposeAsync` + - `AsyncDisposableStack.prototype.use` + - `AsyncDisposableStack.prototype.adopt` + - `AsyncDisposableStack.prototype.defer` + - `AsyncDisposableStack.prototype.move` + - `AsyncDisposableStack.prototype[@@asyncDispose]` + - `Iterator.prototype[@@dispose]` + - `AsyncIterator.prototype[@@asyncDispose]` + - Sync version of this proposal moved to Stage 3, [November 2022 TC39 meeting](https://github.com/babel/proposals/issues/85#issuecomment-1333747094) + - Added `/actual/` namespace entries for Stage 3 proposal +- Added [`String.dedent` stage 2 proposal](https://github.com/tc39/proposal-string-dedent) + - Method `String.dedent` + - Throws an error on non-frozen raw templates for avoiding possible breaking changes in the future, [proposal-string-dedent/75](https://github.com/tc39/proposal-string-dedent/issues/75) +- [Compat data targets](/packages/core-js-compat#targets-option) improvements: + - [React Native from 0.70 shipped with Hermes as the default engine.](https://reactnative.dev/blog/2022/07/08/hermes-as-the-default) However, bundled Hermes versions differ from standalone Hermes releases. So added **`react-native`** target for React Native with bundled Hermes. + - [According to the documentation](https://developer.oculus.com/documentation/web/browser-intro/), Oculus Browser was renamed to Meta Quest Browser, so `oculus` target was renamed to **`quest`**. + - `opera_mobile` target name is confusing since it contains data for the Chromium-based Android version, but iOS Opera is Safari-based. So `opera_mobile` target was renamed to **`opera-android`**. + - `android` target name is also confusing for someone - that means Android WebView, some think thinks that it's Chrome for Android, but they have some differences. For avoiding confusion, added **`chrome-android`** target. + - For consistency with two previous cases, added **`firefox-android`** target. + - For avoiding breaking changes, the `oculus` and `opera_mobile` fields are available in the compat data till the next major release. +- Compat data improvements: + - [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async) marked as supported from Bun 0.3.0 + - [`String.prototype.{ isWellFormed, toWellFormed }`](https://github.com/tc39/proposal-is-usv-string) marked as supported from Bun 0.4.0 + - [Change `Array` by copy proposal](https://github.com/tc39/proposal-change-array-by-copy) marked as supported from Deno 1.27, [deno/16429](https://github.com/denoland/deno/pull/16429) + - Added Deno 1.28 / 1.29 compat data mapping + - Added NodeJS 19.2 compat data mapping + - Added Samsung Internet 19.0 compat data mapping + - Added Quest Browser 24.0 compat data mapping + - Fixed the first version in the Chromium-based Edge compat data mapping +- `{ Map, WeakMap }.prototype.emplace` became stricter [by the spec draft](https://tc39.es/proposal-upsert/) +- Smoothed behavior of some conflicting proposals +- Removed some generic behavior (like `@@species` pattern) of some `.prototype` methods from the [new collections methods proposal](https://github.com/tc39/proposal-collection-methods) and the [`Array` deduplication proposal](https://github.com/tc39/proposal-array-unique) that *most likely* will not be implemented since it contradicts the current TC39 policy +- Added pure version of the `Number` constructor, [#1154](https://github.com/zloirock/core-js/issues/1154), [#1155](https://github.com/zloirock/core-js/issues/1155), thanks [@trosos](https://github.com/trosos) +- Added `set(Timeout|Interval|Immediate)` extra arguments fix for Bun 0.3.0- (similarly to IE9-), [bun/1633](https://github.com/oven-sh/bun/issues/1633) +- Fixed handling of sparse arrays in `structuredClone`, [#1156](https://github.com/zloirock/core-js/issues/1156) +- Fixed a theoretically possible future conflict of polyfills definitions in the pure version +- Some refactoring and optimization + +### [3.26.1 - 2022.11.14](https://github.com/zloirock/core-js/releases/tag/v3.26.1) +- Disabled forced replacing of `Array.fromAsync` since it's on Stage 3 +- Avoiding a check of the target in the internal `function-uncurry-this` helper where it's not required - minor optimization and preventing problems in some broken environments, a workaround of [#1141](https://github.com/zloirock/core-js/issues/1141) +- V8 will not ship `Array.prototype.{ group, groupToMap }` in V8 ~ Chromium 108, [proposal-array-grouping/44](https://github.com/tc39/proposal-array-grouping/issues/44#issuecomment-1306311107) + +### [3.26.0 - 2022.10.24](https://github.com/zloirock/core-js/releases/tag/v3.26.0) +- [`Array.fromAsync` proposal](https://github.com/tc39/proposal-array-from-async): + - Moved to Stage 3, [September TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2022-09/sep-14.md#arrayfromasync-for-stage-3) + - Avoid observable side effects of `%Array.prototype.values%` usage in array-like branch, [proposal-array-from-async/30](https://github.com/tc39/proposal-array-from-async/pull/30) +- Added [well-formed unicode strings stage 2 proposal](https://github.com/tc39/proposal-is-usv-string): + - `String.prototype.isWellFormed` + - `String.prototype.toWellFormed` +- Recent updates of the [iterator helpers proposal](https://github.com/tc39/proposal-iterator-helpers): + - Added a counter parameter to helpers, [proposal-iterator-helpers/211](https://github.com/tc39/proposal-iterator-helpers/pull/211) + - Don't await non-objects returned from functions passed to `AsyncIterator` helpers, [proposal-iterator-helpers/239](https://github.com/tc39/proposal-iterator-helpers/pull/239) + - `{ Iterator, AsyncIterator }.prototype.flatMap` supports returning both - iterables and iterators, [proposal-iterator-helpers/233](https://github.com/tc39/proposal-iterator-helpers/pull/233) + - Early exit on broken `.next` in missed cases of `{ Iterator, AsyncIterator }.from`, [proposal-iterator-helpers/232](https://github.com/tc39/proposal-iterator-helpers/pull/232) +- Added `self` polyfill as a part of [The Minimum Common Web Platform API](https://common-min-api.proposal.wintercg.org/), [specification](https://html.spec.whatwg.org/multipage/window-object.html#dom-self), [#1118](https://github.com/zloirock/core-js/issues/1118) +- Added `inverse` option to `core-js-compat`, [#1119](https://github.com/zloirock/core-js/issues/1119) +- Added `format` option to `core-js-builder`, [#1120](https://github.com/zloirock/core-js/issues/1120) +- Added NodeJS 19.0 compat data +- Added Deno 1.26 and 1.27 compat data +- Added Opera Android 72 compat data mapping +- Updated Electron 22 compat data mapping + +### [3.25.5 - 2022.10.04](https://github.com/zloirock/core-js/releases/tag/v3.25.5) +- Fixed regression with an error on reuse of some built-in methods from another realm, [#1133](https://github.com/zloirock/core-js/issues/1133) + +### [3.25.4 - 2022.10.03](https://github.com/zloirock/core-js/releases/tag/v3.25.4) +- Added a workaround of a Nashorn bug with `Function.prototype.{ call, apply, bind }` on string methods, [#1128](https://github.com/zloirock/core-js/issues/1128) +- Updated lists of `[Serializable]` and `[Transferable]` objects in the `structuredClone` polyfill. Mainly, for better error messages if polyfilling of cloning such types is impossible +- `Array.prototype.{ group, groupToMap }` marked as [supported from V8 ~ Chromium 108](https://chromestatus.com/feature/5714791975878656) +- Added Electron 22 compat data mapping + +### [3.25.3 - 2022.09.26](https://github.com/zloirock/core-js/releases/tag/v3.25.3) +- Forced polyfilling of `Array.prototype.groupToMap` in the pure version for returning wrapped `Map` instances +- Fixed existence of `Array.prototype.{ findLast, findLastIndex }` in `/stage/4` entry +- Added Opera Android 71 compat data mapping +- Some stylistic changes + +### [3.25.2 - 2022.09.19](https://github.com/zloirock/core-js/releases/tag/v3.25.2) +- Considering `document.all` as a callable in some missed cases +- Added Safari 16.0 compat data +- Added iOS Safari 16.0 compat data mapping +- Fixed some ancient iOS Safari versions compat data mapping + +### [3.25.1 - 2022.09.08](https://github.com/zloirock/core-js/releases/tag/v3.25.1) +- Added some fixes and workarounds of FF30- typed arrays bug that does not properly convert objects to numbers +- Added `sideEffects` field to `core-js-pure` `package.json` for better tree shaking, [#1117](https://github.com/zloirock/core-js/issues/1117) +- Dropped `semver` dependency from `core-js-compat` + - `semver` package (ironically) added [a breaking change and dropped NodeJS 8 support in the minor `7.1` version](https://github.com/npm/node-semver/commit/d61f828e64260a0a097f26210f5500), after that `semver` in `core-js-compat` was pinned to `7.0` since for avoiding breaking changes it should support NodeJS 8. However, since `core-js-compat` is usually used with other packages that use `semver` dependency, it causes multiple duplication of `semver` in dependencies. So I decided to remove `semver` dependency and replace it with a couple of simple helpers. +- Added Bun 0.1.6-0.1.11 compat data +- Added Deno 1.25 compat data mapping +- Updated Electron 21 compat data mapping +- Some stylistic changes, minor fixes, and improvements + +### [3.25.0 - 2022.08.25](https://github.com/zloirock/core-js/releases/tag/v3.25.0) +- Added [`Object.prototype.__proto__`](https://tc39.es/ecma262/#sec-object.prototype.__proto__) polyfill + - It's optional, legacy, and in some cases (mainly because of developers' mistakes) can cause problems, but [some libraries depend on it](https://github.com/denoland/deno/issues/13321), and most code can't work without the proper libraries' ecosystem + - Only for modern engines where this feature is missed (like Deno), it's not installed in IE10- since here we have no proper way setting of the prototype + - Without fixes of early implementations where it's not an accessor since those fixes are impossible + - Only for the global version +- Considering `document.all` as an object in some missed cases, see [ECMAScript Annex B 3.6](https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot) +- Avoiding unnecessary promise creation and validation result in `%WrapForValid(Async)IteratorPrototype%.return`, [proposal-iterator-helpers/215](https://github.com/tc39/proposal-iterator-helpers/pull/215) +- Fixed omitting the result of proxing `.return` in `%IteratorHelperPrototype%.return`, [#1116](https://github.com/zloirock/core-js/issues/1116) +- Fixed the order creation of properties of iteration result object of some iterators (`value` should be created before `done`) +- Fixed some cases of Safari < 13 bug - silent on non-writable array `.length` setting +- Fixed `ArrayBuffer.length` in V8 ~ Chrome 27- +- Relaxed condition of re-usage native `WeakMap` for internal states with multiple `core-js` copies +- Availability cloning of `FileList` in the `structuredClone` polyfill extended to some more old engines versions +- Some stylistic changes and minor fixes +- Throwing a `TypeError` in `core-js-compat` / `core-js-builder` in case of passing invalid module names / filters for avoiding unexpected result, related to [#1115](https://github.com/zloirock/core-js/issues/1115) +- Added missed NodeJS 13.2 to `esmodules` `core-js-compat` / `core-js-builder` target +- Added Electron 21 compat data mapping +- Added Oculus Browser 23.0 compat data mapping + +### [3.24.1 - 2022.07.30](https://github.com/zloirock/core-js/releases/tag/v3.24.1) +- NodeJS is ignored in `IS_BROWSER` detection to avoid a false positive with `jsdom`, [#1110](https://github.com/zloirock/core-js/issues/1110) +- Fixed detection of `@@species` support in `Promise` in some old engines +- `{ Array, %TypedArray% }.prototype.{ findLast, findLastIndex }` marked as shipped [in FF104](https://bugzilla.mozilla.org/show_bug.cgi?id=1775026) +- Added iOS Safari 15.6 compat data mapping +- Fixed Opera 15 compat data mapping + +### [3.24.0 - 2022.07.25](https://github.com/zloirock/core-js/releases/tag/v3.24.0) +- Recent updates of the [iterator helpers proposal](https://github.com/tc39/proposal-iterator-helpers), [#1101](https://github.com/zloirock/core-js/issues/1101): + - `.asIndexedPairs` renamed to `.indexed`, [proposal-iterator-helpers/183](https://github.com/tc39/proposal-iterator-helpers/pull/183): + - `Iterator.prototype.asIndexedPairs` -> `Iterator.prototype.indexed` + - `AsyncIterator.prototype.asIndexedPairs` -> `AsyncIterator.prototype.indexed` + - Avoid exposing spec fiction `%AsyncFromSyncIteratorPrototype%` in `AsyncIterator.from` and `Iterator.prototype.toAsync`, [proposal-iterator-helpers/182](https://github.com/tc39/proposal-iterator-helpers/pull/182), [proposal-iterator-helpers/202](https://github.com/tc39/proposal-iterator-helpers/pull/202) + - Avoid unnecessary promise creation in `%WrapForValidAsyncIteratorPrototype%.next`, [proposal-iterator-helpers/197](https://github.com/tc39/proposal-iterator-helpers/pull/197) + - Do not validate value in `%WrapForValid(Async)IteratorPrototype%.next`, [proposal-iterator-helpers/197](https://github.com/tc39/proposal-iterator-helpers/pull/197) and [proposal-iterator-helpers/205](https://github.com/tc39/proposal-iterator-helpers/pull/205) + - Do not forward the parameter of `.next` / `.return` to an underlying iterator by the extended iterator protocol, a part of [proposal-iterator-helpers/194](https://github.com/tc39/proposal-iterator-helpers/pull/194) + - `.throw` methods removed from all wrappers / helpers prototypes, a part of [proposal-iterator-helpers/194](https://github.com/tc39/proposal-iterator-helpers/pull/194) + - Close inner iterators of `{ Iterator, AsyncIterator }.prototype.flatMap` proxy iterators on `.return`, [proposal-iterator-helpers/195](https://github.com/tc39/proposal-iterator-helpers/pull/195) + - Throw `RangeError` on `NaN` in `{ Iterator, AsyncIterator }.prototype.{ drop, take }`, [proposal-iterator-helpers/181](https://github.com/tc39/proposal-iterator-helpers/pull/181) + - Many other updates and fixes of this proposal +- `%TypedArray%.prototype.toSpliced` method removed from the [change array by copy proposal](https://github.com/tc39/proposal-change-array-by-copy) and marked as obsolete in `core-js`, [proposal-change-array-by-copy/88](https://github.com/tc39/proposal-change-array-by-copy/issues/88) +- Polyfill `Promise` with `unhandledrejection` event support (browser style) in Deno < [1.24](https://github.com/denoland/deno/releases/tag/v1.24.0) +- Available new targets in `core-js-compat` / `core-js-builder` and added compat data for them: + - Bun (`bun`), compat data for 0.1.1-0.1.5, [#1103](https://github.com/zloirock/core-js/issues/1103) + - Hermes (`hermes`), compat data for 0.1-0.11, [#1099](https://github.com/zloirock/core-js/issues/1099) + - Oculus Browser (`oculus`), compat data mapping for 3.0-22.0, [#1098](https://github.com/zloirock/core-js/issues/1098) +- Added Samsung Internet 18.0 compat data mapping + +### [3.23.5 - 2022.07.18](https://github.com/zloirock/core-js/releases/tag/v3.23.5) +- Fixed a typo in the `structuredClone` feature detection, [#1106](https://github.com/zloirock/core-js/issues/1106) +- Added Opera Android 70 compat data mapping + +### [3.23.4 - 2022.07.10](https://github.com/zloirock/core-js/releases/tag/v3.23.4) +- Added a workaround of the Bun ~ 0.1.1 [bug](https://github.com/Jarred-Sumner/bun/issues/399) that define some globals with incorrect property descriptors and that causes a crash of `core-js` +- Added a fix of the FF103+ `structuredClone` bugs ([1774866](https://bugzilla.mozilla.org/show_bug.cgi?id=1774866) (fixed in FF104) and [1777321](https://bugzilla.mozilla.org/show_bug.cgi?id=1777321) (still not fixed)) that now can clone errors, but `.stack` of the clone is an empty string +- Fixed `{ Map, WeakMap }.prototype.emplace` logic, [#1102](https://github.com/zloirock/core-js/issues/1102) +- Fixed order of errors throwing on iterator helpers + +### [3.23.3 - 2022.06.26](https://github.com/zloirock/core-js/releases/tag/v3.23.3) +- Changed the order of operations in `%TypedArray%.prototype.toSpliced` following [proposal-change-array-by-copy/89](https://github.com/tc39/proposal-change-array-by-copy/issues/89) +- Fixed regression of some IE8- issues + +### [3.23.2 - 2022.06.21](https://github.com/zloirock/core-js/releases/tag/v3.23.2) +- Avoided creation of extra properties for the handling of `%TypedArray%` constructors in new methods, [#1092 (comment)](https://github.com/zloirock/core-js/issues/1092#issuecomment-1158760512) +- Added Deno 1.23 compat data mapping + +### [3.23.1 - 2022.06.14](https://github.com/zloirock/core-js/releases/tag/v3.23.1) +- Fixed possible error on multiple `core-js` copies, [#1091](https://github.com/zloirock/core-js/issues/1091) +- Added `v` flag to `RegExp.prototype.flags` implementation in case if current V8 bugs will not be fixed before this flag implementation + +### [3.23.0 - 2022.06.14](https://github.com/zloirock/core-js/releases/tag/v3.23.0) +- [`Array` find from last](https://github.com/tc39/proposal-array-find-from-last) moved to the stable ES, according to June 2022 TC39 meeting: + - `Array.prototype.findLast` + - `Array.prototype.findLastIndex` + - `%TypedArray%.prototype.findLast` + - `%TypedArray%.prototype.findLastIndex` +- Methods from [the `Array` grouping proposal](https://github.com/tc39/proposal-array-grouping) [renamed](https://github.com/tc39/proposal-array-grouping/pull/39), according to June 2022 TC39 meeting: + - `Array.prototype.groupBy` -> `Array.prototype.group` + - `Array.prototype.groupByToMap` -> `Array.prototype.groupToMap` +- Changed the order of operations in `%TypedArray%.prototype.with` following [proposal-change-array-by-copy/86](https://github.com/tc39/proposal-change-array-by-copy/issues/86), according to June 2022 TC39 meeting +- [Decorator Metadata proposal](https://github.com/tc39/proposal-decorator-metadata) extracted from [Decorators proposal](https://github.com/tc39/proposal-decorators) as a separate stage 2 proposal, according to March 2022 TC39 meeting, `Symbol.metadataKey` replaces `Symbol.metadata` +- Added `Array.prototype.push` polyfill with some fixes for modern engines +- Added `Array.prototype.unshift` polyfill with some fixes for modern engines +- Fixed a bug in the order of getting flags in `RegExp.prototype.flags` in the actual version of V8 +- Fixed property descriptors of some `Math` and `Number` constants +- Added a workaround of V8 `ArrayBufferDetaching` protector cell invalidation and performance degradation on `structuredClone` feature detection, one more case of [#679](https://github.com/zloirock/core-js/issues/679) +- Added detection of NodeJS [bug](https://github.com/nodejs/node/issues/41038) in `structuredClone` that can not clone `DOMException` (just in case for future versions that will fix other issues) +- Compat data: + - Added NodeJS 18.3 compat data mapping + - Added and fixed Deno 1.22 and 1.21 compat data mapping + - Added Opera Android 69 compat data mapping + - Updated Electron 20.0 compat data mapping + +### [3.22.8 - 2022.06.02](https://github.com/zloirock/core-js/releases/tag/v3.22.8) +- Fixed possible multiple call of `ToBigInt` / `ToNumber` conversion of the argument passed to `%TypedArray%.prototype.fill` in V8 ~ Chrome < 59, Safari < 14.1, FF < 55, Edge <=18 +- Fixed some cases of `DeletePropertyOrThrow` in IE9- +- Fixed the kind of error (`TypeError` instead of `Error`) on incorrect `exec` result in `RegExp.prototype.test` polyfill +- Fixed dependencies of `{ actual, full, features }/typed-array/at` entries +- Added Electron 20.0 compat data mapping +- Added iOS Safari 15.5 compat data mapping +- Refactoring + +### [3.22.7 - 2022.05.24](https://github.com/zloirock/core-js/releases/tag/v3.22.7) +- Added a workaround for V8 ~ Chrome 53 bug with non-writable prototype of some methods, [#1083](https://github.com/zloirock/core-js/issues/1083) + +### [3.22.6 - 2022.05.23](https://github.com/zloirock/core-js/releases/tag/v3.22.6) +- Fixed possible double call of `ToNumber` conversion on arguments of `Math.{ fround, trunc }` polyfills +- `Array.prototype.includes` marked as [fixed](https://bugzilla.mozilla.org/show_bug.cgi?id=1767541) in FF102 + +### [3.22.5 - 2022.05.10](https://github.com/zloirock/core-js/releases/tag/v3.22.5) +- Ensured that polyfilled constructors `.prototype` is non-writable +- Ensured that polyfilled methods `.prototype` is not defined +- Added detection and fix of a V8 ~ Chrome <103 [bug](https://bugs.chromium.org/p/v8/issues/detail?id=12542) of `struturedClone` that returns `null` if cloned object contains multiple references to one error + +### [3.22.4 - 2022.05.03](https://github.com/zloirock/core-js/releases/tag/v3.22.4) +- Ensured proper `.length` of polyfilled functions even in compressed code (excepting some ancient engines) +- Ensured proper `.name` of polyfilled accessors (excepting some ancient engines) +- Ensured proper source / `ToString` conversion of polyfilled accessors +- Actualized Rhino compat data +- Refactoring + +### [3.22.3 - 2022.04.28](https://github.com/zloirock/core-js/releases/tag/v3.22.3) +- Added a fix for FF99+ `Array.prototype.includes` broken on sparse arrays + +### [3.22.2 - 2022.04.21](https://github.com/zloirock/core-js/releases/tag/v3.22.2) +- Fixed `URLSearchParams` in IE8- that was broken in the previous release +- Fixed `__lookupGetter__` entries + +### [3.22.1 - 2022.04.20](https://github.com/zloirock/core-js/releases/tag/v3.22.1) +- Improved some cases of `RegExp` flags handling +- Prevented experimental warning in NodeJS ~ 18.0 on detection `fetch` API +- Added NodeJS 18.0 compat data + +### [3.22.0 - 2022.04.15](https://github.com/zloirock/core-js/releases/tag/v3.22.0) +- [Change `Array` by copy proposal](https://github.com/tc39/proposal-change-array-by-copy): + - Moved to Stage 3, [March TC39 meeting](https://github.com/babel/proposals/issues/81#issuecomment-1083449843) + - Disabled forced replacement and added `/actual/` entry points for methods from this proposal + - `Array.prototype.toSpliced` throws a `TypeError` instead of `RangeError` if the result length is more than `MAX_SAFE_INTEGER`, [proposal-change-array-by-copy/70](https://github.com/tc39/proposal-change-array-by-copy/pull/70) +- Added some more `atob` / `btoa` fixes: + - NodeJS <17.9 `atob` does not ignore spaces, [node/42530](https://github.com/nodejs/node/issues/42530) + - Actual NodeJS `atob` does not validate encoding, [node/42646](https://github.com/nodejs/node/issues/42646) + - FF26- implementation does not properly convert argument to string + - IE / Edge <16 implementation have wrong arity +- Added `/full/` namespace as the replacement for `/features/` since it's more descriptive in context of the rest namespaces (`/es/` ⊆ `/stable/` ⊆ `/actual/` ⊆ `/full/`) +- Avoided propagation of removed parts of proposals to upper stages. For example, `%TypedArray%.prototype.groupBy` was removed from the `Array` grouping proposal a long time ago. We can't completely remove this method since it's a breaking change. But this proposal has been promoted to stage 3 - so the proposal should be promoted without this method, this method should not be available in `/actual/` entries - but it should be available in early-stage entries to avoid breakage. +- Significant internal refactoring and splitting of modules (but without exposing to public API since it will be a breaking change - it will be exposed in the next major version) +- Bug fixes: + - Fixed work of non-standard V8 `Error` features with wrapped `Error` constructors, [#1061](https://github.com/zloirock/core-js/issues/1061) + - `null` and `undefined` allowed as the second argument of `structuredClone`, [#1056](https://github.com/zloirock/core-js/issues/1056) +- Tooling: + - Stabilized proposals are filtered out from the `core-js-compat` -> `core-js-builder` -> `core-js-bundle` output. That mean that if the output contains, for example, `es.object.has-own`, the legacy reference to it, `esnext.object.has-own`, no longer added. + - Aligned modules filters of [`core-js-builder`](https://github.com/zloirock/core-js/tree/master/packages/core-js-builder) and [`core-js-compat`](https://github.com/zloirock/core-js/tree/master/packages/core-js-compat), now it's `modules` and `exclude` options + - Added support of entry points, modules, regexes, and arrays of them to those filters + - Missed `targets` option of `core-js-compat` means that the `targets` filter just will not be applied, so the result will contain modules required for all possible engines +- Compat data: + - `.stack` property on `DOMException` marked as supported from Deno [1.15](https://github.com/denoland/deno/releases/tag/v1.15.0) + - Added Deno 1.21 compat data mapping + - Added Electron 19.0 and updated 18.0 compat data mapping + - Added Samsung Internet 17.0 compat data mapping + - Added Opera Android 68 compat data mapping + +### [3.21.1 - 2022.02.17](https://github.com/zloirock/core-js/releases/tag/v3.21.1) +- Added a [bug](https://bugs.webkit.org/show_bug.cgi?id=236541)fix for the WebKit `Array.prototype.{ groupBy, groupByToMap }` implementation +- `core-js-compat` targets parser transforms engine names to lower case +- `atob` / `btoa` marked as [fixed](https://github.com/nodejs/node/pull/41478) in NodeJS 17.5 +- Added Electron 18.0 compat data mapping +- Added Deno 1.20 compat data mapping + +### [3.21.0 - 2022.02.02](https://github.com/zloirock/core-js/releases/tag/v3.21.0) +- Added [Base64 utility methods](https://developer.mozilla.org/en-US/docs/Glossary/Base64): + - `atob` + - `btoa` +- Added the proper validation of arguments to some methods from web standards +- Forced replacement of all features from early-stage proposals for avoiding possible web compatibility issues in the future +- Added Rhino 1.7.14 compat data +- Added Deno 1.19 compat data mapping +- Added Opera Android 66 and 67 compat data mapping +- Added iOS Safari 15.3 and 15.4 compat data mapping + +### [3.20.3 - 2022.01.15](https://github.com/zloirock/core-js/releases/tag/v3.20.3) +- Detects and replaces broken third-party `Function#bind` polyfills, uses only native `Function#bind` in the internals +- `structuredClone` should throw an error if no arguments passed +- Changed the structure of notes in `__core-js_shared__` + +### [3.20.2 - 2022.01.02](https://github.com/zloirock/core-js/releases/tag/v3.20.2) +- Added a fix of [a V8 ~ Chrome 36- `Object.{ defineProperty, defineProperties }` bug](https://bugs.chromium.org/p/v8/issues/detail?id=3334), [Babel issue](https://github.com/babel/babel/issues/14056) +- Added fixes of some different `%TypedArray%.prototype.set` bugs, affects modern engines (like Chrome < 95 or Safari < 14.1) + +### [3.20.1 - 2021.12.23](https://github.com/zloirock/core-js/releases/tag/v3.20.1) +- Fixed the order of calling reactions of already fulfilled / rejected promises in `Promise.prototype.then`, [#1026](https://github.com/zloirock/core-js/issues/1026) +- Fixed possible memory leak in specific promise chains +- Fixed some missed dependencies of entries +- Added Deno 1.18 compat data mapping + +### [3.20.0 - 2021.12.16](https://github.com/zloirock/core-js/releases/tag/v3.20.0) +- Added `structuredClone` method [from the HTML spec](https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone), [see MDN](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone) + - Includes all cases of cloning and transferring of required ECMAScript and platform types that can be polyfilled, for the details see [the caveats](https://github.com/zloirock/core-js#caveats-when-using-structuredclone-polyfill) + - Uses native structured cloning algorithm implementations where it's possible + - Includes the new semantic of errors cloning from [`html/5749`](https://github.com/whatwg/html/pull/5749) +- Added `DOMException` polyfill, [the Web IDL spec](https://webidl.spec.whatwg.org/#idl-DOMException), [see MDN](https://developer.mozilla.org/en-US/docs/Web/API/DOMException) + - Includes `DOMException` and its attributes polyfills with fixes of many different engines bugs + - Includes `DOMException#stack` property polyfill in engines that should have it + - Reuses native `DOMException` implementations where it's possible (for example, in old NodeJS where it's not exposed as global) +- Added [support of `cause` on all Error types](https://github.com/tc39/proposal-error-cause) +- Added `Error.prototype.toString` method polyfill with fixes of many different bugs of JS engines +- Added `Number.prototype.toExponential` method polyfill with fixes of many different bugs of JS engines +- [`Array` grouping proposal](https://github.com/tc39/proposal-array-grouping): + - Moved to stage 3 + - Added `Array.prototype.groupByToMap` method + - Removed `@@species` support +- Added [change `Array` by copy stage 2 proposal](https://github.com/tc39/proposal-change-array-by-copy): + - `Array.prototype.toReversed` + - `Array.prototype.toSorted` + - `Array.prototype.toSpliced` + - `Array.prototype.with` + - `%TypedArray%.prototype.toReversed` + - `%TypedArray%.prototype.toSorted` + - `%TypedArray%.prototype.toSpliced` + - `%TypedArray%.prototype.with` +- Added `Iterator.prototype.toAsync` method from [the iterator helpers stage 2 proposal](https://github.com/tc39/proposal-iterator-helpers) +- [`Array.fromAsync` proposal](https://github.com/tc39/proposal-array-from-async) moved to stage 2 +- Added [`String.cooked` stage 1 proposal](https://github.com/tc39/proposal-string-cooked) +- Added [`Function.prototype.unThis` stage 0 proposal](https://github.com/js-choi/proposal-function-un-this) +- Added [`Function.{ isCallable, isConstructor }` stage 0 proposal](https://github.com/caitp/TC39-Proposals/blob/trunk/tc39-reflect-isconstructor-iscallable.md): + - `Function.isCallable` + - `Function.isConstructor` +- Added a workaround of most cases breakage modern `String#at` after loading obsolete `String#at` proposal module, [#1019](https://github.com/zloirock/core-js/issues/1019) +- Fixed `Array.prototype.{ values, @@iterator }.name` in V8 ~ Chrome 45- +- Fixed validation of typed arrays in typed arrays iteration methods in V8 ~ Chrome 50- +- Extension of the API, [#1012](https://github.com/zloirock/core-js/issues/1012) + - Added a new `core-js/actual/**` namespace + - Added entry points for each finished post-ES6 proposal + +### [3.19.3 - 2021.12.06](https://github.com/zloirock/core-js/releases/tag/v3.19.3) +- Fixed internal slots check in methods of some built-in types, [#1017](https://github.com/zloirock/core-js/issues/1017) +- Fixed `URLSearchParams` iterator `.next` that should be enumerable [by the spec](https://webidl.spec.whatwg.org/#es-iterator-prototype-object) +- Refactored `Subscription` +- Added NodeJS 17.2 compat data mapping + +### [3.19.2 - 2021.11.29](https://github.com/zloirock/core-js/releases/tag/v3.19.2) +- Added a workaround for a UC Browser specific version bug with unobservable `RegExp#sticky` flag, [#1008](https://github.com/zloirock/core-js/issues/1008), [#1015](https://github.com/zloirock/core-js/issues/1015) +- Added handling of comments and specific spaces to `Function#name` polyfill, [#1010](https://github.com/zloirock/core-js/issues/1010), thanks [@ildar-shaimordanov](https://github.com/ildar-shaimordanov) +- Prevented some theoretical cases of breaking / observing the internal state by patching `Array.prototype[@@species]` +- Refactored `URL` and `URLSearchParams` +- Added iOS Safari 15.2 compat data mapping +- Added Electron 17.0 compat data mapping +- Updated Deno compat data mapping + +### [3.19.1 - 2021.11.03](https://github.com/zloirock/core-js/releases/tag/v3.19.1) +- Added a workaround for FF26- bug where `ArrayBuffer`s are non-extensible, but `Object.isExtensible` does not report it: + - Fixed in `Object.{ isExtensible, isSealed, isFrozen }` and `Reflect.isExtensible` + - Fixed handling of `ArrayBuffer`s as collections keys +- Fixed `Object#toString` on `AggregateError` in IE10- +- Fixed possible lack of dependencies of `WeakMap` in IE8- +- `.findLast` methods family marked as supported [from Chrome 97](https://chromestatus.com/features#milestone%3D97) +- Fixed inheritance of Electron compat data `web.` modules +- Fixed Safari 15.1 compat data (some features were not added) +- Added iOS Safari 15.1 compat data mapping + +### [3.19.0 - 2021.10.25](https://github.com/zloirock/core-js/releases/tag/v3.19.0) +- Most built-ins are encapsulated in `core-js` for preventing possible cases of breaking / observing the internal state by patching / deleting of them + - Avoid `.call` / `.apply` prototype methods that could be patched + - Avoid `instanceof` operator - implicit `.prototype` / `@@hasInstance` access that could be patched + - Avoid `RegExp#test`, `String#match` and some over methods - implicit `.exec` and `RegExp` well-known symbols access that could be patched +- Clearing of `Error` stack from extra entries experimentally added to `AggregateError`, [#996](https://github.com/zloirock/core-js/pull/996), in case lack of problems it will be extended to other cases +- In engines with native `Symbol` support, new well-known symbols created with usage `Symbol.for` for ensuring the same keys in different realms, [#998](https://github.com/zloirock/core-js/issues/998) +- Added a workaround of [a BrowserFS NodeJS `process` polyfill bug](https://github.com/jvilk/bfs-process/issues/5) that incorrectly reports V8 version that's used in some cases of `core-js` feature detection +- Fixed normalization of `message` `AggregateError` argument +- Fixed order of arguments conversion in `Math.scale`, [a spec draft bug](https://github.com/rwaldron/proposal-math-extensions/issues/24) +- Fixed `core-js-builder` work in NodeJS 17, added a workaround of [`webpack` + NodeJS 17 issue](https://github.com/webpack/webpack/issues/14532) +- Added NodeJS 17.0 compat data mapping +- Added Opera Android 65 compat data mapping +- Updated Electron 16.0 compat data mapping +- Many other minor fixes and improvements + +### [3.18.3 - 2021.10.13](https://github.com/zloirock/core-js/releases/tag/v3.18.3) +- Fixed the prototype chain of `AggregateError` constructor that should contain `Error` constructor +- Fixed incorrect `AggregateError.prototype` properties descriptors +- Fixed `InstallErrorCause` internal operation +- Added NodeJS 16.11 compat data mapping +- Added Deno 1.16 compat data mapping +- `Object.hasOwn` marked as supported from Safari 15.1 + +### [3.18.2 - 2021.10.06](https://github.com/zloirock/core-js/releases/tag/v3.18.2) +- Early `{ Array, %TypedArray% }.fromAsync` errors moved to the promise, per the latest changes of the spec draft +- Internal `ToInteger(OrInfinity)` operation returns `+0` for `-0` argument, ES2020+ update +- Fixed theoretical problems with handling bigint in `Number` constructor wrapper +- Fixed `String.raw` with extra arguments +- Fixed some missed dependencies in entry points +- Some other minor fixes and improvements +- Refactoring + +### [3.18.1 - 2021.09.27](https://github.com/zloirock/core-js/releases/tag/v3.18.1) +- Fixed `String.prototype.substr` feature detection and compat data +- Removed mistakenly added `.forEach` from prototypes of some DOM collections where it shouldn't be, [#988](https://github.com/zloirock/core-js/issues/988), [#987](https://github.com/zloirock/core-js/issues/987), thanks [@moorejs](https://github.com/moorejs) +- Added `cause` to `AggregateError` constructor implementation (still without adding to the feature detection) +- Families of `.at` and `.findLast` methods marked as supported in Safari TP +- Added Electron 16.0 compat data mapping + +### [3.18.0 - 2021.09.20](https://github.com/zloirock/core-js/releases/tag/v3.18.0) +- Added [`Array.fromAsync` stage 1 proposal](https://github.com/tc39/proposal-array-from-async): + - `Array.fromAsync` + - `%TypedArray%.fromAsync` +- `.name` and `.toString()` on polyfilled functions improved in many different cases +- Improved internal `IsConstructor` and `IsCallable` checks +- Fixed some internal cases of `GetMethod` operation +- Fixed a bug of MS Edge 18- `parseInt` / `parseFloat` with boxed symbols +- Fixed `es.array.{ index-of, last-index-of }` compat data +- Added Deno 1.15 compat data mapping +- Some other minor fixes and optimizations + +### [3.17.3 - 2021.09.09](https://github.com/zloirock/core-js/releases/tag/v3.17.3) +- Fixed some possible problems related to possible extension of `%IteratorPrototype%` and `%AsyncIteratorPrototype%` in the future +- Fixed `DOMTokenList.prototype.{ forEach, @@iterator, keys, values, entries }` in old WebKit versions where `element.classList` is not an instance of global `DOMTokenList` +- Added NodeJS 16.9 compat data mapping +- Added Samsung Internet 16.0 compat data mapping + +### [3.17.2 - 2021.09.03](https://github.com/zloirock/core-js/releases/tag/v3.17.2) +- Fixed missed cases of ES3 reserved words usage, related to [#980](https://github.com/zloirock/core-js/issues/980) +- Fixed dependencies in one missed entry point +- Some other minor fixes and optimizations + +### [3.17.1 - 2021.09.02](https://github.com/zloirock/core-js/releases/tag/v3.17.1) +- Fixed missed `modules-by-versions` data + +### [3.17.0 - 2021.09.02](https://github.com/zloirock/core-js/releases/tag/v3.17.0) +- [Accessible `Object.prototype.hasOwnProperty` (`Object.hasOwn`) proposal](https://github.com/tc39/proposal-accessible-object-hasownproperty) moved to the stable ES, [per August 2021 TC39 meeting](https://github.com/babel/proposals/issues/76#issuecomment-909288348) +- [Relative indexing method (`.at`) proposal](https://github.com/tc39/proposal-relative-indexing-method) moved to the stable ES, [per August 2021 TC39 meeting](https://github.com/babel/proposals/issues/76#issuecomment-909285053) +- Exposed by default the stable version of `String.prototype.at`. It was not exposed because of the conflict with the alternative obsolete proposal (that will be completely removed in the next major version). For the backward compatibility, in the case of loading this proposal, it will be overwritten. +- Some more iteration closing fixes +- Fixed an ES3 reserved words usage, [#980](https://github.com/zloirock/core-js/issues/980) + +### [3.16.4 - 2021.08.29](https://github.com/zloirock/core-js/releases/tag/v3.16.4) +- `AsyncFromSyncIterator` made stricter, related mainly to `AsyncIterator.from` and `AsyncIterator.prototype.flatMap` +- Handling of optional `.next` arguments in `(Async)Iterator` methods is aligned with the current spec draft (mainly - ignoring the first passed to `.next` argument in built-in generators) +- Behavior of `.next`, `.return`, `.throw` methods on `AsyncIterator` helpers proxy iterators aligned with the current spec draft (built-in async generators) (mainly - some early errors moved to returned promises) +- Fixed some cases of safe iteration closing +- Fixed dependencies of some entry points + +### [3.16.3 - 2021.08.25](https://github.com/zloirock/core-js/releases/tag/v3.16.3) +- Fixed `CreateAsyncFromSyncIterator` semantic in `AsyncIterator.from`, related to [#765](https://github.com/zloirock/core-js/issues/765) +- Added a workaround of a specific case of broken `Object.prototype`, [#973](https://github.com/zloirock/core-js/issues/973) + +### [3.16.2 - 2021.08.17](https://github.com/zloirock/core-js/releases/tag/v3.16.2) +- Added a workaround of a Closure Compiler unsafe optimization, [#972](https://github.com/zloirock/core-js/issues/972) +- One more fix crashing of `Object.create(null)` on WSH, [#970](https://github.com/zloirock/core-js/issues/970) +- Added Deno 1.14 compat data mapping + +### [3.16.1 - 2021.08.09](https://github.com/zloirock/core-js/releases/tag/v3.16.1) +- Fixed microtask implementation on iOS Pebble, [#967](https://github.com/zloirock/core-js/issues/967) +- Fixed some entry points +- Improved old Safari compat data + +### [3.16.0 - 2021.07.30](https://github.com/zloirock/core-js/releases/tag/v3.16.0) +- [`Array` find from last proposal](https://github.com/tc39/proposal-array-find-from-last) moved to the stage 3, [July 2021 TC39 meeting](https://github.com/tc39/proposal-array-find-from-last/pull/47) +- [`Array` filtering stage 1 proposal](https://github.com/tc39/proposal-array-filtering): + - `Array.prototype.filterReject` replaces `Array.prototype.filterOut` + - `%TypedArray%.prototype.filterReject` replaces `%TypedArray%.prototype.filterOut` +- Added [`Array` grouping stage 1 proposal](https://github.com/tc39/proposal-array-grouping): + - `Array.prototype.groupBy` + - `%TypedArray%.prototype.groupBy` +- Work with symbols made stricter: some missed before cases of methods that should throw an error on symbols now works as they should +- Handling `@@toPrimitive` in some cases of `ToPrimitive` internal logic made stricter +- Fixed work of `Request` with polyfilled `URLSearchParams`, [#965](https://github.com/zloirock/core-js/issues/965) +- Fixed possible exposing of collections elements metadata in some cases, [#427](https://github.com/zloirock/core-js/issues/427) +- Fixed crashing of `Object.create(null)` on WSH, [#966](https://github.com/zloirock/core-js/issues/966) +- Fixed some cases of typed arrays subclassing logic +- Fixed a minor bug related to string conversion in `RegExp#exec` +- Fixed `Date.prototype.getYear` feature detection +- Fixed content of some entry points +- Some minor optimizations and refactoring +- Deno: + - Added Deno support (sure, after bundling since Deno does not support CommonJS) + - Allowed `deno` target in `core-js-compat` / `core-js-builder` + - A bundle for Deno published on [deno.land/x/corejs](https://deno.land/x/corejs) +- Added / updated compat data / mapping: + - Deno 1.0-1.13 + - NodeJS up to 16.6 + - iOS Safari up to 15.0 + - Samsung Internet up to 15.0 + - Opera Android up to 64 + - `Object.hasOwn` marked as supported from [V8 9.3](https://chromestatus.com/feature/5662263404920832) and [FF92](https://bugzilla.mozilla.org/show_bug.cgi?id=1721149) + - `Date.prototype.getYear` marked as not supported in IE8- +- Added `summary` option to `core-js-builder`, see more info in the [`README`](https://github.com/zloirock/core-js/blob/master/packages/core-js-builder/README.md), [#910](https://github.com/zloirock/core-js/issues/910) + +### [3.15.2 - 2021.06.29](https://github.com/zloirock/core-js/releases/tag/v3.15.2) +- Worked around breakage related to `zone.js` loaded before `core-js`, [#953](https://github.com/zloirock/core-js/issues/953) +- Added NodeJS 16.4 -> Chrome 91 compat data mapping + +### [3.15.1 - 2021.06.23](https://github.com/zloirock/core-js/releases/tag/v3.15.1) +- Fixed cloning of regex through `RegExp` constructor, [#948](https://github.com/zloirock/core-js/issues/948) + +### [3.15.0 - 2021.06.21](https://github.com/zloirock/core-js/releases/tag/v3.15.0) +- Added `RegExp` named capture groups polyfill, [#521](https://github.com/zloirock/core-js/issues/521), [#944](https://github.com/zloirock/core-js/issues/944) +- Added `RegExp` `dotAll` flag polyfill, [#792](https://github.com/zloirock/core-js/issues/792), [#944](https://github.com/zloirock/core-js/issues/944) +- Added missed polyfills of [Annex B](https://tc39.es/ecma262/#sec-additional-built-in-properties) features (required mainly for some non-browser engines), [#336](https://github.com/zloirock/core-js/issues/336), [#945](https://github.com/zloirock/core-js/issues/945): + - `escape` + - `unescape` + - `String.prototype.substr` + - `Date.prototype.getYear` + - `Date.prototype.setYear` + - `Date.prototype.toGMTString` +- Fixed detection of forbidden host code points in `URL` polyfill +- Allowed `rhino` target in `core-js-compat` / `core-js-builder`, added compat data for `rhino` 1.7.13, [#942](https://github.com/zloirock/core-js/issues/942), thanks [@gausie](https://github.com/gausie) +- `.at` marked as supported from FF90 + +### [3.14.0 - 2021.06.05](https://github.com/zloirock/core-js/releases/tag/v3.14.0) +- Added polyfill of stable sort in `{ Array, %TypedArray% }.prototype.sort`, [#769](https://github.com/zloirock/core-js/issues/769), [#941](https://github.com/zloirock/core-js/issues/941) +- Fixed `Safari` 14.0- `%TypedArray%.prototype.sort` validation of arguments bug +- `.at` marked as supported from V8 9.2 + +### [3.13.1 - 2021.05.29](https://github.com/zloirock/core-js/releases/tag/v3.13.1) +- Overwrites `get-own-property-symbols` third-party `Symbol` polyfill if it's used since it causes a stack overflow, [#774](https://github.com/zloirock/core-js/issues/774) +- Added a workaround of possible browser crash on `Object.prototype` accessors methods in WebKit ~ Android 4.0, [#232](https://github.com/zloirock/core-js/issues/232) + +### [3.13.0 - 2021.05.26](https://github.com/zloirock/core-js/releases/tag/v3.13.0) +- Accessible `Object#hasOwnProperty` (`Object.hasOwn`) proposal moved to the stage 3, [May 2021 TC39 meeting](https://github.com/babel/proposals/issues/74#issuecomment-848121673) + +### [3.12.1 - 2021.05.09](https://github.com/zloirock/core-js/releases/tag/v3.12.1) +- Fixed some cases of `Function#toString` with multiple `core-js` instances +- Fixed some possible `String#split` polyfill problems in V8 5.1 + +### [3.12.0 - 2021.05.06](https://github.com/zloirock/core-js/releases/tag/v3.12.0) +- Added well-known symbol `Symbol.metadata` for [decorators stage 2 proposal](https://github.com/tc39/proposal-decorators) +- Added well-known symbol `Symbol.matcher` for [pattern matching stage 1 proposal](https://github.com/tc39/proposal-pattern-matching) +- Fixed regression of V8 ~ Node 0.12 `String(Symbol())` bug, [#933](https://github.com/zloirock/core-js/issues/933) + +### [3.11.3 - 2021.05.05](https://github.com/zloirock/core-js/releases/tag/v3.11.3) +- Native promise-based APIs `Promise#{ catch, finally }` returns polyfilled `Promise` instances when it's required + +### [3.11.2 - 2021.05.03](https://github.com/zloirock/core-js/releases/tag/v3.11.2) +- Added a workaround of WebKit ~ iOS 10.3 Safari `Promise` bug, [#932](https://github.com/zloirock/core-js/issues/932) +- `Promise#then` of incorrect native `Promise` implementations with correct subclassing no longer wrapped +- Changed the order of `Promise` feature detection, removed unhandled rejection tracking check in non-browser non-node platforms + +### [3.11.1 - 2021.04.28](https://github.com/zloirock/core-js/releases/tag/v3.11.1) +- Made `instanceof Promise` and `.constructor === Promise` work with polyfilled `Promise` for all native promise-based APIs +- Added a workaround for some buggy V8 versions \~4.5 related to fixing of `%TypedArray%` static methods, [#564](https://github.com/zloirock/core-js/issues/564) + +### [3.11.0 - 2021.04.22](https://github.com/zloirock/core-js/releases/tag/v3.11.0) +- Added [accessible `Object#hasOwnProperty` stage 2 proposal](https://github.com/tc39/proposal-accessible-object-hasownproperty) + - `Object.hasOwn` method +- Fixed a possible `RegExp` constructor problem with multiple global `core-js` instances + +### [3.10.2 - 2021.04.19](https://github.com/zloirock/core-js/releases/tag/v3.10.2) +- `URL` and `URLSearchParams` marked as supported from Safari 14.0 +- Polyfilled built-in constructors protected from calling on instances + +### [3.10.1 - 2021.04.08](https://github.com/zloirock/core-js/releases/tag/v3.10.1) +- Prevented possible `RegExp#split` problems in old engines, [#751](https://github.com/zloirock/core-js/issues/751), [#919](https://github.com/zloirock/core-js/issues/919) +- Detection of Safari 10 string padding bug extended to some Safari-based browsers + +### [3.10.0 - 2021.03.31](https://github.com/zloirock/core-js/releases/tag/v3.10.0) +- [`Array` find from last proposal](https://github.com/tc39/proposal-array-find-from-last) moved to the stage 2, [March TC39 meeting](https://github.com/babel/proposals/issues/71#issuecomment-795916535) +- Prevented possible `RegExp#exec` problems in some old engines, [#920](https://github.com/zloirock/core-js/issues/920) +- Updated compat data mapping: + - NodeJS up to 16.0 + - Electron up to 13.0 + - Samsung Internet up to 14.0 + - Opera Android up to 62 + - The rest automatically + +### [3.9.1 - 2021.03.01](https://github.com/zloirock/core-js/releases/tag/v3.9.1) +- Added a workaround for Chrome 38-40 bug which does not allow to inherit symbols (incl. well-known) from DOM collections prototypes to instances, [#37](https://github.com/zloirock/core-js/issues/37) +- Used `NumericRangeIterator` as toStringTag instead of `RangeIterator` in `{ Number, BigInt }.range` iterator, per [this PR](https://github.com/tc39/proposal-Number.range/pull/46) +- TypedArray constructors marked as supported from Safari 14.0 +- Updated compat data mapping for iOS Safari and Opera for Android + +### [3.9.0 - 2021.02.19](https://github.com/zloirock/core-js/releases/tag/v3.9.0) +- Added [`Array` find from last stage 1 proposal](https://github.com/tc39/proposal-array-find-from-last) + - `Array#findLast` + - `Array#findLastIndex` + - `%TypedArray%#findLast` + - `%TypedArray%#findLastIndex` +- Added `%TypedArray%#uniqueBy` method for [array deduplication stage 1 proposal](https://github.com/tc39/proposal-array-unique) + - `%TypedArray%#uniqueBy` +- Dropped `ToLength` detection from array methods feature detection which could cause hanging FF11-21 and some versions of old WebKit, [#764](https://github.com/zloirock/core-js/issues/764) +- Minified bundle from `core-js-bundle` uses `terser` instead of `uglify-js` + +### [3.8.3 - 2021.01.19](https://github.com/zloirock/core-js/releases/tag/v3.8.3) +- Fixed some more issues related to FF44- legacy `Iterator`, [#906](https://github.com/zloirock/core-js/issues/906) + +### [3.8.2 - 2021.01.03](https://github.com/zloirock/core-js/releases/tag/v3.8.2) +- Fixed handling of special replacements patterns in `String#replaceAll`, [#900](https://github.com/zloirock/core-js/issues/900) +- Fixed iterators dependencies of `Promise.any` and `Promise.allSettled` entries +- Fixed microtask implementation on WebOS, [#898](https://github.com/zloirock/core-js/issues/898), [#901](https://github.com/zloirock/core-js/issues/901) + +### [3.8.1 - 2020.12.06](https://github.com/zloirock/core-js/releases/tag/v3.8.1) +- Fixed work of new `%TypedArray%` methods on `BigInt` arrays +- Added ESNext methods to ES3 workaround for `Number` constructor wrapper + +### [3.8.0 - 2020.11.26](https://github.com/zloirock/core-js/releases/tag/v3.8.0) +- Added [relative indexing method stage 3 proposal](https://github.com/tc39/proposal-relative-indexing-method) + - `Array#at` + - `%TypedArray%#at` +- Added [`Number.range` stage 1 proposal](https://github.com/tc39/proposal-Number.range) + - `Number.range` + - `BigInt.range` +- Added [array filtering stage 1 proposal](https://github.com/tc39/proposal-array-filtering) + - `Array#filterOut` + - `%TypedArray%#filterOut` +- Added [array deduplication stage 1 proposal](https://github.com/tc39/proposal-array-unique) + - `Array#uniqueBy` +- Added code points / code units explicit feature detection in `String#at` for preventing breakage code which use obsolete `String#at` proposal polyfill +- Added the missed `(es|stable)/instance/replace-all` entries +- Updated compat data mapping for Opera - from Opera 69, the difference with Chrome versions increased to 14 +- Compat data mapping for modern Android WebView to Chrome moved from targets parser directly to compat data +- Deprecate `core-js-builder` `blacklist` option in favor of `exclude` + +### [2.6.12 [LEGACY] - 2020.11.26](https://github.com/zloirock/core-js/releases/tag/v2.6.12) +- Added code points / code units explicit feature detection in `String#at` for preventing breakage code which use obsolete `String#at` proposal polyfill +- Added `OPEN_SOURCE_CONTRIBUTOR` detection in `postinstall` +- Added Drone CI detection in `postinstall` + +### [3.7.0 - 2020.11.06](https://github.com/zloirock/core-js/releases/tag/v3.7.0) +- `String#replaceAll` moved to the stable ES, [per June TC39 meeting](https://github.com/tc39/notes/blob/master/meetings/2020-06/june-2.md#stringprototypereplaceall-for-stage-4) +- `Promise.any` and `AggregateError` moved to the stable ES, [per July TC39 meeting](https://github.com/tc39/notes/blob/master/meetings/2020-07/july-21.md#promiseany--aggregateerror-for-stage-4) +- Added `Reflect[@@toStringTag]`, [per July TC39 meeting](https://github.com/tc39/ecma262/pull/2057) +- Forced replacement of `Array#{ reduce, reduceRight }` in Chrome 80-82 because of [a bug](https://bugs.chromium.org/p/chromium/issues/detail?id=1049982), [#766](https://github.com/zloirock/core-js/issues/766) +- Following the changes in [the `upsert` proposal](https://github.com/tc39/proposal-upsert), `{ Map, WeakMap }#emplace` replace `{ Map, WeakMap }#upsert`, these obsolete methods will be removed in the next major release +- [By the current spec](https://tc39.es/ecma262/#sec-aggregate-error-constructor), `AggregateError#errors` is own data property +- Added correct iteration closing in the iteration helpers according to the current version of [the proposal](https://tc39.es/proposal-iterator-helpers) +- `process.nextTick` have a less priority than `Promise` in the microtask implementation, [#855](https://github.com/zloirock/core-js/issues/855) +- Fixed microtask implementation in engines with `MutationObserver`, but without `document`, [#865](https://github.com/zloirock/core-js/issues/865), [#866](https://github.com/zloirock/core-js/issues/866) +- Fixed `core-js-builder` with an empty (after the targets engines or another filtration) modules list, [#822](https://github.com/zloirock/core-js/issues/822) +- Fixed possible twice call of `window.onunhandledrejection`, [#760](https://github.com/zloirock/core-js/issues/760) +- Fixed some possible problems related multiple global copies of `core-js`, [#880](https://github.com/zloirock/core-js/issues/880) +- Added a workaround for 3rd party `Reflect.set` polyfill bug, [#847](https://github.com/zloirock/core-js/issues/847) +- Updated compat data: + - Chrome up to 86 + - FF up to 82 + - Safari up to 14 +- Updated compat data mapping: + - iOS up to 14 + - NodeJS up to 15.0 + - Electron up to 11.0 + - Samsung Internet up to 13.0 + - Opera Android up to 60 + - The rest automatically +- Updated all required dependencies + +### [3.6.5 - 2020.04.09](https://github.com/zloirock/core-js/releases/tag/v3.6.5) +- Updated Browserslist [#755](https://github.com/zloirock/core-js/issues/755) +- Fixed `setImmediate` in Safari [#770](https://github.com/zloirock/core-js/issues/770), thanks [@dtinth](https://github.com/dtinth) +- Fixed some regexp, thanks [@scottarc](https://github.com/scottarc) +- Added OPEN_SOURCE_CONTRIBUTOR detection in `postinstall`, thanks [@scottarc](https://github.com/scottarc) +- Added Drone CI in `postinstall` CI detection [#781](https://github.com/zloirock/core-js/issues/781) + +### [3.6.4 - 2020.01.14](https://github.com/zloirock/core-js/releases/tag/v3.6.4) +- Prevented a possible almost infinite loop in non-standard implementations of some backward iteration array methods + +### [3.6.3 - 2020.01.11](https://github.com/zloirock/core-js/releases/tag/v3.6.3) +- Fixed replacement of substitutes of undefined capture groups in `.replace` in Safari 13.0-, [#471](https://github.com/zloirock/core-js/issues/471), [#745](https://github.com/zloirock/core-js/issues/745), thanks [@mattclough1](https://github.com/mattclough1) +- Improved compat data for old engines + +### [3.6.2 - 2020.01.07](https://github.com/zloirock/core-js/releases/tag/v3.6.2) +- Fixed early implementations of `Array#{ every, forEach, includes, indexOf, lastIndexOf, reduce, reduceRight, slice, some, splice }` for the usage of `ToLength` +- Added `RegExp#exec` dependency to methods which depends on the correctness of logic of this method (`3.6.0-3.6.1` issue), [#741](https://github.com/zloirock/core-js/issues/741) +- Refactored some internals + +### [3.6.1 - 2019.12.25](https://github.com/zloirock/core-js/releases/tag/v3.6.1) +- Fixed a bug related `Symbol` with multiple copies of `core-js` (for `3.4.2-3.6.0`), [#736](https://github.com/zloirock/core-js/issues/736) +- Refactored some tools + +### [3.6.0 - 2019.12.19](https://github.com/zloirock/core-js/releases/tag/v3.6.0) +- Added support of sticky (`y`) `RegExp` flag, [#372](https://github.com/zloirock/core-js/issues/372), [#732](https://github.com/zloirock/core-js/issues/732), [#492](https://github.com/zloirock/core-js/issues/492), thanks [@cvle](https://github.com/cvle) and [@nicolo-ribaudo](https://github.com/nicolo-ribaudo) +- Added `RegExp#test` delegation to `RegExp#exec`, [#732](https://github.com/zloirock/core-js/issues/732), thanks [@cvle](https://github.com/cvle) +- Fixed some cases of `Object.create(null)` in IE8-, [#727](https://github.com/zloirock/core-js/issues/727), [#728](https://github.com/zloirock/core-js/issues/728), thanks [@aleen42](https://github.com/aleen42) +- Allowed object of minimum environment versions as `core-js-compat` and `core-js-builder` `targets` argument +- Allowed corresponding to Babel `targets.esmodules`, `targets.browsers`, `targets.node` options in `core-js-compat` and `core-js-builder` +- Engines in compat data and results of targets parsing sorted alphabetically +- Fixed `features/instance/match-all` entry compat data +- Fixed `Array.prototype[@@unscopables]` descriptor (was writable) +- Added Samsung Internet 11 compat data mapping + +### [3.5.0 - 2019.12.12](https://github.com/zloirock/core-js/releases/tag/v3.5.0) +- Added [object iteratoration stage 1 proposal](https://github.com/tc39/proposal-object-iteration): + - `Object.iterateKeys` + - `Object.iterateValues` + - `Object.iterateEntries` + +### [3.4.8 - 2019.12.09](https://github.com/zloirock/core-js/releases/tag/v3.4.8) +- Added one more workaround for broken in previous versions `inspectSource` helper, [#719](https://github.com/zloirock/core-js/issues/719) +- Added Opera Mobile compat data +- Updated Samsung Internet, iOS, old Node and Android compat data mapping +- `es.string.match-all` marked as completely supported in FF73 +- Generate `core-js-compat/modules` since often we need just the list of `core-js` modules + +### [2.6.11 [LEGACY] - 2019.12.09](https://github.com/zloirock/core-js/releases/tag/v2.6.11) +- Returned usage of `node -e` in the `postinstall` scripts for better cross-platform compatibility, [#582](https://github.com/zloirock/core-js/issues/582) +- Improved CI detection in the `postinstall` script, [#707](https://github.com/zloirock/core-js/issues/707) + +### [3.4.7 - 2019.12.03](https://github.com/zloirock/core-js/releases/tag/v3.4.7) +- Fixed an NPM publishing issue + +### [3.4.6 - 2019.12.03](https://github.com/zloirock/core-js/releases/tag/v3.4.6) +- Improved iOS compat data - added missed mapping iOS 12.2 -> Safari 12.1, added bug fixes from patch releases +- Added Safari 13.1 compat data +- Added missed in `core-js-compat` helpers `ie_mob` normalization +- Normalize the result of `getModulesListForTargetVersion` `core-js-compat` helper +- Improved CI detection in the `postinstall` script, [#707](https://github.com/zloirock/core-js/issues/707) + +### [3.4.5 - 2019.11.28](https://github.com/zloirock/core-js/releases/tag/v3.4.5) +- Detect incorrect order of operations in `Object.assign`, MS Edge bug +- Detect usage of `ToLength` in `Array#{ filter, map }`, FF48-49 and MS Edge 14- issues +- Detect incorrect MS Edge 17-18 `Reflect.set` which allows setting the property to object with non-writable property on the prototype +- Fixed `inspectSource` helper with multiple `core-js` copies and some related features like some edge cases of `Promise` feature detection + +### [3.4.4 - 2019.11.27](https://github.com/zloirock/core-js/releases/tag/v3.4.4) +- Added feature detection for Safari [non-generic `Promise#finally` bug](https://bugs.webkit.org/show_bug.cgi?id=200829) **(critical for `core-js-pure`)** +- Fixed missed `esnext.string.code-points` in `core-js/features/string` entry point +- Updated `Iterator` proposal feature detection for the case of non-standard `Iterator` in FF44- + +### [3.4.3 - 2019.11.26](https://github.com/zloirock/core-js/releases/tag/v3.4.3) +- Fixed missed `es.json.stringify` and some modules from iteration helpers proposal in some entry points **(includes the root entry point)** +- Added a workaround of `String#{ endsWith, startsWith }` MDN polyfills bugs, [#702](https://github.com/zloirock/core-js/issues/702) +- Fixed `.size` property descriptor of `Map` / `Set` in the pure version +- Refactoring, some internal improvements + +### [3.4.2 - 2019.11.22](https://github.com/zloirock/core-js/releases/tag/v3.4.2) +- Don't use polyfilled symbols as internal uids, a workaround for some incorrect use cases +- `String#replaceAll` is available only in nightly FF builds +- Improved `Promise` feature detection for the case of V8 6.6 with multiple `core-js` copies +- Some internals optimizations +- Added Node 13.2 -> V8 7.9 compat data mapping +- Returned usage of `node -e` in `postinstall` scripts + +### [3.4.1 - 2019.11.12](https://github.com/zloirock/core-js/releases/tag/v3.4.1) +- Throw when `(Async)Iterator#flatMap` mapper returns a non-iterable, per [tc39/proposal-iterator-helpers/55](https://github.com/tc39/proposal-iterator-helpers/issues/55) and [tc39/proposal-iterator-helpers/59](https://github.com/tc39/proposal-iterator-helpers/pull/59) +- Removed own `AggregateError#toString`, per [tc39/proposal-promise-any/49](https://github.com/tc39/proposal-promise-any/pull/49) +- Global `core-js` `Promise` polyfill passes feature detection in the pure versions +- Fixed indexes in `String#replaceAll` callbacks +- `String#replaceAll` marked as supported by FF72 + +### [3.4.0 - 2019.11.07](https://github.com/zloirock/core-js/releases/tag/v3.4.0) +- Added [well-formed `JSON.stringify`](https://github.com/tc39/proposal-well-formed-stringify), ES2019 feature, thanks [@ExE-Boss](https://github.com/ExE-Boss) and [@WebReflection](https://github.com/WebReflection) for the idea +- Fixed `Math.signbit`, [#687](https://github.com/zloirock/core-js/issues/687), thanks [@chicoxyzzy](https://github.com/chicoxyzzy) + +### [3.3.6 - 2019.11.01](https://github.com/zloirock/core-js/releases/tag/v3.3.6) +- Don't detect Chakra-based Edge as Chrome in the `userAgent` parsing +- Fixed inheritance in typed array constructors wrappers, [#683](https://github.com/zloirock/core-js/issues/683) +- Added one more workaround for correct work of early `fetch` implementations with polyfilled `URLSearchParams`, [#680](https://github.com/zloirock/core-js/issues/680) + +### [3.3.5 - 2019.10.29](https://github.com/zloirock/core-js/releases/tag/v3.3.5) - Added a workaround of V8 deoptimization which causes serious performance degradation (~4x in my tests) of `Array#concat`, [#679](https://github.com/zloirock/core-js/issues/679) - Added a workaround of V8 deoptimization which causes slightly performance degradation of `Promise`, [#679](https://github.com/zloirock/core-js/issues/679) - Added `(Async)Iterator.prototype.constructor -> (Async)Iterator` per [this issue](https://github.com/tc39/proposal-iterator-helpers/issues/60) - Added compat data for Chromium-based Edge -##### 3.3.4 - 2019.10.25 +### [3.3.4 - 2019.10.25](https://github.com/zloirock/core-js/releases/tag/v3.3.4) - Added a workaround of V8 deoptimization which causes serious performance degradation (~20x in my tests) of some `RegExp`-related methods like `String#split`, [#306](https://github.com/zloirock/core-js/issues/306) - Added a workaround of V8 deoptimization which causes serious performance degradation (up to 100x in my tests) of `Array#splice` and slightly `Array#{ filter, map }`, [#677](https://github.com/zloirock/core-js/issues/677) - Fixed work of `fetch` with polyfilled `URLSearchParams`, [#674](https://github.com/zloirock/core-js/issues/674) @@ -13,17 +1749,17 @@ - Added compat data for Chrome 80 - `package-lock.json` no longer generated in libraries -##### 3.3.3 - 2019.10.22 +### [3.3.3 - 2019.10.22](https://github.com/zloirock/core-js/releases/tag/v3.3.3) - `gopher` removed from `URL` special cases per [this issue](https://github.com/whatwg/url/issues/342) and [this PR](https://github.com/whatwg/url/pull/453) - Added compat data for iOS 13 and Node 13.0 -##### 3.3.2 - 2019.10.14 -- Fixed compatibility of `core-js-compat` with Node 6 and Yarn, [#669](https://github.com/zloirock/core-js/issues/669) +### [3.3.2 - 2019.10.14](https://github.com/zloirock/core-js/releases/tag/v3.3.2) +- Fixed compatibility of `core-js-compat` with Node 6 and Yarn, [#669](https://github.com/zloirock/core-js/issues/669) -##### 3.3.1 - 2019.10.13 -- Fixed a NPM publishing issue +### [3.3.1 - 2019.10.13](https://github.com/zloirock/core-js/releases/tag/v3.3.1) +- Fixed an NPM publishing issue -##### 3.3.0 - 2019.10.13 +### [3.3.0 - 2019.10.13](https://github.com/zloirock/core-js/releases/tag/v3.3.0) - **`String#{ matchAll, replaceAll }` throws an error on non-global regex argument per [the decision from TC39 meetings](https://github.com/tc39/ecma262/pull/1716) (+ [this PR](https://github.com/tc39/proposal-string-replaceall/pull/24)). It's a breaking change, but since it's a breaking change in the ES spec, it's added at the minor release** - `globalThis` moved to stable ES, [per October TC39 meeting](https://github.com/babel/proposals/issues/60#issuecomment-537217903) - `Promise.any` moved to stage 3, some minor internal changes, [per October TC39 meeting](https://github.com/babel/proposals/issues/60#issuecomment-538084885) @@ -73,15 +1809,15 @@ - Fixed missed cases [access the `.next` method once, at the beginning, of the iteration protocol](https://github.com/tc39/ecma262/issues/976) - Show similar `postinstall` messages only once per `npm i`, [#597](https://github.com/zloirock/core-js/issues/597), thanks [@remy](https://github.com/remy) -##### 2.6.10 [LEGACY] - 2019.10.13 +### [2.6.10 [LEGACY] - 2019.10.13](https://github.com/zloirock/core-js/releases/tag/v2.6.10) - Show similar `postinstall` messages only once per `npm i`, [#597](https://github.com/zloirock/core-js/issues/597) -##### 3.2.1 - 2019.08.12 +### [3.2.1 - 2019.08.12](https://github.com/zloirock/core-js/releases/tag/v3.2.1) - Added a workaround for possible recursion in microtasks caused by conflicts with other `Promise` polyfills, [#615](https://github.com/zloirock/core-js/issues/615) -##### 3.2.0 - 2019.08.09 +### [3.2.0 - 2019.08.09](https://github.com/zloirock/core-js/releases/tag/v3.2.0) - `Promise.allSettled` moved to stable ES, per July TC39 meeting -- `Promise.any` moved to stage 2, `.errors` property of `AggregateError` instances maked non-enumerable, per July TC39 meeting +- `Promise.any` moved to stage 2, `.errors` property of `AggregateError` instances made non-enumerable, per July TC39 meeting - `using` statement proposal moved to stage 2, added `Symbol.asyncDispose`, per July TC39 meeting - Added `Array.isTemplateObject` [stage 2 proposal](https://github.com/tc39/proposal-array-is-template-object), per June TC39 meeting - Added `Map#updateOrInsert` [stage 1 proposal](https://docs.google.com/presentation/d/1_xtrGSoN1-l2Q74eCXPHBbbrBHsVyqArWN0ebnW-pVQ/), per July TC39 meeting @@ -95,36 +1831,36 @@ - Removed `core-js-pure` dependency from `core-js-compat`, [#590](https://github.com/zloirock/core-js/issues/590) - Fixed generation of `core-js-compat` on Windows, [#606](https://github.com/zloirock/core-js/issues/606) -##### 3.1.4 - 2019.06.15 +### [3.1.4 - 2019.06.15](https://github.com/zloirock/core-js/releases/tag/v3.1.4) - Refactoring. Many minor internal improvements and fixes like: - Improved `Symbol.keyFor` complexity to `O(1)` - Fixed the order of arguments validation in `String.prototype.{ endsWith, includes, startsWith }` - - Internal implementation of `RegExp#flags` helper now respect `dotAll` flag (mainly ralated to the `pure` version) - - Performace optimizations related old V8 + - Internal implementation of `RegExp#flags` helper now respect `dotAll` flag (mainly related to the `pure` version) + - Performance optimizations related old V8 - Etc. -##### 3.1.3 - 2019.05.27 +### [3.1.3 - 2019.05.27](https://github.com/zloirock/core-js/releases/tag/v3.1.3) - Fixed `core-js/features/reflect/delete-metadata` entry point - Some fixes and improvements of the `postinstall` script like support `npm` color config ([#556](https://github.com/zloirock/core-js/issues/556)) or adding support of `ADBLOCK` env variable - Refactoring and some minor fixes -##### 2.6.9 [LEGACY] - 2019.05.27 +### [2.6.9 [LEGACY] - 2019.05.27](https://github.com/zloirock/core-js/releases/tag/v2.6.9) - Some fixes and improvements of the `postinstall` script like support `npm` color config ([#556](https://github.com/zloirock/core-js/issues/556)) or adding support of `ADBLOCK` env variable -##### 3.1.2 - 2019.05.22 +### [3.1.2 - 2019.05.22](https://github.com/zloirock/core-js/releases/tag/v3.1.2) - Added a workaround of a strange `npx` bug on `postinstall`, [#551](https://github.com/zloirock/core-js/issues/551) -##### 2.6.8 [LEGACY] - 2019.05.22 +### [2.6.8 [LEGACY] - 2019.05.22](https://github.com/zloirock/core-js/releases/tag/v2.6.8) - Added a workaround of a strange `npx` bug on `postinstall`, [#551](https://github.com/zloirock/core-js/issues/551) -##### 3.1.1 - 2019.05.21 +### [3.1.1 - 2019.05.21](https://github.com/zloirock/core-js/releases/tag/v3.1.1) - Added one more workaround of alternative not completely correct `Symbol` polyfills, [#550](https://github.com/zloirock/core-js/issues/550), [#554](https://github.com/zloirock/core-js/issues/554) - Reverted `esnext.string.match-all` in some entry points for fix autogeneration of `core-js-compat/entries` and backward `@babel/preset-env` compatibility -##### 2.6.7 [LEGACY] - 2019.05.21 +### [2.6.7 [LEGACY] - 2019.05.21](https://github.com/zloirock/core-js/releases/tag/v2.6.7) - Added one more workaround of alternative not completely correct `Symbol` polyfills, [#550](https://github.com/zloirock/core-js/issues/550), [#554](https://github.com/zloirock/core-js/issues/554) -##### 3.1.0 - 2019.05.20 +### [3.1.0 - 2019.05.20](https://github.com/zloirock/core-js/releases/tag/v3.1.0) - `String#matchAll` moved to stable ES, exposed `Symbol.matchAll`, [#516](https://github.com/zloirock/core-js/issues/516) - `Promise.allSettled` moved to stage 3, [#515](https://github.com/zloirock/core-js/issues/515) - `String#replaceAll` moved to stage 2, behavior updated by the spec draft, [#524](https://github.com/zloirock/core-js/issues/524) @@ -138,20 +1874,20 @@ - Show a message on `postinstall` - Added compat data for Chrome 76, FF 67, Node 12 -##### 2.6.6 [LEGACY] - 2019.05.20 +### [2.6.6 [LEGACY] - 2019.05.20](https://github.com/zloirock/core-js/releases/tag/v2.6.6) - Fixed IE8- non-enumerable properties support in `Object.{ assign, entries, values }`, [#541](https://github.com/zloirock/core-js/issues/541) - Fixed support of primitives in `Object.getOwnPropertySymbols` in Chrome 38 / 39, [#539](https://github.com/zloirock/core-js/issues/539) - Show a message on `postinstall` -##### 3.0.1 - 2019.04.06 +### [3.0.1 - 2019.04.06](https://github.com/zloirock/core-js/releases/tag/v3.0.1) - Fixed some cases of work with malformed URI sequences in `URLSearchParams`, [#525](https://github.com/zloirock/core-js/issues/525) - Added a workaround for a rollup issue, [#513](https://github.com/zloirock/core-js/issues/513) -##### 3.0.0 - 2019.03.19 +### [3.0.0 - 2019.03.19](https://github.com/zloirock/core-js/releases/tag/v3.0.0) - Features - Add new features: - `Object.fromEntries` ([ECMAScript 2019](https://github.com/tc39/proposal-object-from-entries)) - - `Symbol#description` ([ECMAScript 2019](https://tc39.github.io/ecma262/#sec-symbol.prototype.description)) + - `Symbol#description` ([ECMAScript 2019](https://tc39.es/ecma262/#sec-symbol.prototype.description)) - New `Set` methods ([stage 2 proposal](https://github.com/tc39/proposal-set-methods)) - `Set#difference` - `Set#intersection` @@ -276,7 +2012,7 @@ - `delay` - Add `.sham` flag to features which can't be properly polyfilled and / or not recommended for usage: - `Symbol` constructor - we can't add new primitives. `Object.prototype` accessors too expensive. - - `Object.{create, defineProperty, defineProperties, getOwnPropertyDescriptor, getOwnPropertyDescriptos}`, `Reflect.{defineProperty, getOwnPropertyDescriptor}` can't be properly polyfilled without descriptors support. + - `Object.{create, defineProperty, defineProperties, getOwnPropertyDescriptor, getOwnPropertyDescriptors}`, `Reflect.{defineProperty, getOwnPropertyDescriptor}` can't be properly polyfilled without descriptors support. - `Object.{freeze, seal, preventExtensions}`, `Reflect.preventExtensions` can't be properly polyfilled in ES3 environment. - `Object.getPrototypeOf` can be deceived in ES3 environment. - `Reflect.construct` can't be polyfilled for a correct work with `newTarget` argument on built-ins. @@ -338,59 +2074,59 @@ - ESLint used on tests and tools. - Source code refactored for improving readability. -##### 2.6.5 - 2019.02.15 +### [2.6.5 - 2019.02.15](https://github.com/zloirock/core-js/releases/tag/v2.6.5) - Fixed buggy `String#padStart` and `String#padEnd` mobile Safari implementations, [#414](https://github.com/zloirock/core-js/issues/414). -##### 2.6.4 - 2019.02.07 +### [2.6.4 - 2019.02.07](https://github.com/zloirock/core-js/releases/tag/v2.6.4) - Added a workaround against crushing an old IE11.0.9600.16384 build, [#485](https://github.com/zloirock/core-js/issues/485). -##### 2.6.3 - 2019.01.22 +### [2.6.3 - 2019.01.22](https://github.com/zloirock/core-js/releases/tag/v2.6.3) - Added a workaround for `babel-minify` bug, [#479](https://github.com/zloirock/core-js/issues/479) -##### 2.6.2 - 2019.01.10 +### [2.6.2 - 2019.01.10](https://github.com/zloirock/core-js/releases/tag/v2.6.2) - Fixed handling of `$` in `String#replace`, [#471](https://github.com/zloirock/core-js/issues/471) -##### 2.6.1 - 2018.12.18 +### [2.6.1 - 2018.12.18](https://github.com/zloirock/core-js/releases/tag/v2.6.1) - Fixed an issue with minified version, [#463](https://github.com/zloirock/core-js/issues/463), [#465](https://github.com/zloirock/core-js/issues/465) -##### 2.6.0 - 2018.12.05 +### [2.6.0 - 2018.12.05](https://github.com/zloirock/core-js/releases/tag/v2.6.0) - Add direct `.exec` calling to `RegExp#{@@replace, @@split, @@match, @@search}`. Also, added fixes for `RegExp#exec` method. [#428](https://github.com/zloirock/core-js/issues/428), [#435](https://github.com/zloirock/core-js/issues/435), [#458](https://github.com/zloirock/core-js/issues/458), thanks [**@nicolo-ribaudo**](https://github.com/nicolo-ribaudo). -##### 2.5.7 - 2018.05.26 +### [2.5.7 - 2018.05.26](https://github.com/zloirock/core-js/releases/tag/v2.5.7) - Get rid of reserved variable name `final`, related [#400](https://github.com/zloirock/core-js/issues/400) -##### 2.5.6 - 2018.05.07 +### [2.5.6 - 2018.05.07](https://github.com/zloirock/core-js/releases/tag/v2.5.6) - Forced replace native `Promise` in V8 6.6 (Node 10 and Chrome 66) because of [a bug with resolving custom thenables](https://bugs.chromium.org/p/chromium/issues/detail?id=830565) - Added a workaround for usage buggy native LG WebOS 2 `Promise` in microtask implementation, [#396](https://github.com/zloirock/core-js/issues/396) - Added modern version internal debugging information about used versions -##### 2.5.5 - 2018.04.08 +### [2.5.5 - 2018.04.08](https://github.com/zloirock/core-js/releases/tag/v2.5.5) - Fix some edge cases of `Reflect.set`, [#392](https://github.com/zloirock/core-js/issues/392) and [#393](https://github.com/zloirock/core-js/issues/393) -##### 2.5.4 - 2018.03.27 +### [2.5.4 - 2018.03.27](https://github.com/zloirock/core-js/releases/tag/v2.5.4) - Fixed one case of deoptimization built-in iterators in V8, related [#377](https://github.com/zloirock/core-js/issues/377) - Fixed some cases of iterators feature detection, [#368](https://github.com/zloirock/core-js/issues/368) - Fixed manually entered NodeJS domains issue in `Promise`, [#367](https://github.com/zloirock/core-js/issues/367) - Fixed `Number.{parseInt, parseFloat}` entry points - Fixed `__(define|lookup)[GS]etter__` export in the `library` version -##### 2.5.3 - 2017.12.12 +### [2.5.3 - 2017.12.12](https://github.com/zloirock/core-js/releases/tag/v2.5.3) - Fixed calling `onunhandledrejectionhandler` multiple times for one `Promise` chain, [#318](https://github.com/zloirock/core-js/issues/318) - Forced replacement of `String#{padStart, padEnd}` in Safari 10 because of [a bug](https://bugs.webkit.org/show_bug.cgi?id=161944), [#280](https://github.com/zloirock/core-js/issues/280) - Fixed `Array#@@iterator` in a very rare version of `WebKit`, [#236](https://github.com/zloirock/core-js/issues/236) and [#237](https://github.com/zloirock/core-js/issues/237) - One more [#345](https://github.com/zloirock/core-js/issues/345)-related fix -##### 2.5.2 - 2017.12.09 +### [2.5.2 - 2017.12.09](https://github.com/zloirock/core-js/releases/tag/v2.5.2) - `MutationObserver` no longer used for microtask implementation in iOS Safari because of bug with scrolling, [#339](https://github.com/zloirock/core-js/issues/339) - Fixed `JSON.stringify(undefined, replacer)` case in the wrapper from the `Symbol` polyfill, [#345](https://github.com/zloirock/core-js/issues/345) - `Array()` calls changed to `new Array()` for V8 optimisation -##### 2.5.1 - 2017.09.01 +### [2.5.1 - 2017.09.01](https://github.com/zloirock/core-js/releases/tag/v2.5.1) - Updated `Promise#finally` per [tc39/proposal-promise-finally#37](https://github.com/tc39/proposal-promise-finally/issues/37) - Optimized usage of some internal helpers for reducing size of `shim` version - Fixed some entry points for virtual methods -##### 2.5.0 - 2017.08.05 +### [2.5.0 - 2017.08.05](https://github.com/zloirock/core-js/releases/tag/v2.5.0) - Added `Promise#finally` [stage 3 proposal](https://github.com/tc39/proposal-promise-finally), [#225](https://github.com/zloirock/core-js/issues/225) - Added `Promise.try` [stage 1 proposal](https://github.com/tc39/proposal-promise-try) - Added `Array#flatten` and `Array#flatMap` [stage 1 proposal](https://tc39.github.io/proposal-flatMap) @@ -411,9 +2147,9 @@ - `Math.RAD_PER_DEG` - `Math.radians` - `Math.scale` -- Added `Math.signbit` [stage 1 proposal](http://jfbastien.github.io/papers/Math.signbit.html) +- Added `Math.signbit` [stage 1 proposal](https://github.com/tc39/proposal-Math.signbit) - Updated `global` [stage 3 proposal](https://github.com/tc39/proposal-global) - added `global` global object, `System.global` deprecated -- Updated `Object.getOwnPropertyDescriptors` to the [final version](https://tc39.github.io/ecma262/2017/#sec-object.getownpropertydescriptors) - it should not create properties if descriptors are `undefined` +- Updated `Object.getOwnPropertyDescriptors` to the [final version](https://tc39.es/ecma262/2017/#sec-object.getownpropertydescriptors) - it should not create properties if descriptors are `undefined` - Updated the list of iterable DOM collections, [#249](https://github.com/zloirock/core-js/issues/249), added: - `CSSStyleDeclaration#@@iterator` - `CSSValueList#@@iterator` @@ -442,11 +2178,11 @@ - `TextTrackList#@@iterator` - `TouchList#@@iterator` - Updated stages of proposals: - - [`Object.getOwnPropertyDescriptors`](https://github.com/tc39/proposal-object-getownpropertydescriptors) to [stage 4 (ES2017)](https://tc39.github.io/ecma262/2017/#sec-object.getownpropertydescriptors) - - [String padding](https://github.com/tc39/proposal-string-pad-start-end) to [stage 4 (ES2017)](https://tc39.github.io/ecma262/2017/#sec-string.prototype.padend) - - [`global`](https://github.com/tc39/proposal-global) to [stage 3](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-09/sept-28.md#revisit-systemglobal--global) - - [String trimming](https://github.com/tc39/proposal-string-left-right-trim) to [stage 2](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-07/jul-27.md#10iic-trimstarttrimend) -- Updated typed arrays to the modern (ES2016+) arguments validation, + - [`Object.getOwnPropertyDescriptors`](https://github.com/tc39/proposal-object-getownpropertydescriptors) to [stage 4 (ES2017)](https://tc39.es/ecma262/2017/#sec-object.getownpropertydescriptors) + - [String padding](https://github.com/tc39/proposal-string-pad-start-end) to [stage 4 (ES2017)](https://tc39.es/ecma262/2017/#sec-string.prototype.padend) + - [`global`](https://github.com/tc39/proposal-global) to [stage 3](https://github.com/tc39/notes/blob/main/meetings/2016-09/sept-28.md#revisit-systemglobal--global) + - [String trimming](https://github.com/tc39/proposal-string-left-right-trim) to [stage 2](https://github.com/tc39/notes/blob/main/meetings/2016-07/jul-27.md#10iic-trimstarttrimend) +- Updated typed arrays to the modern (ES2016+) arguments validation, [#293](https://github.com/zloirock/core-js/pull/293) - Fixed `%TypedArray%.from` Safari bug, [#285](https://github.com/zloirock/core-js/issues/285) - Fixed compatibility with old version of Prototype.js, [#278](https://github.com/zloirock/core-js/issues/278), [#289](https://github.com/zloirock/core-js/issues/289) @@ -462,64 +2198,64 @@ - Updated many dev dependencies (`webpack`, `uglify`, etc) - Some other minor fixes and optimizations -##### 2.4.1 - 2016.07.18 +### [2.4.1 - 2016.07.18](https://github.com/zloirock/core-js/releases/tag/v2.4.1) - Fixed `script` tag for some parsers, [#204](https://github.com/zloirock/core-js/issues/204), [#216](https://github.com/zloirock/core-js/issues/216) - Removed some unused variables, [#217](https://github.com/zloirock/core-js/issues/217), [#218](https://github.com/zloirock/core-js/issues/218) - Fixed MS Edge `Reflect.construct` and `Reflect.apply` - they should not allow primitive as `argumentsList` argument -##### 1.2.7 [LEGACY] - 2016.07.18 +### [1.2.7 [LEGACY] - 2016.07.18](https://github.com/zloirock/core-js/releases/tag/v1.2.7) - Some fixes for issues like [#159](https://github.com/zloirock/core-js/issues/159), [#186](https://github.com/zloirock/core-js/issues/186), [#194](https://github.com/zloirock/core-js/issues/194), [#207](https://github.com/zloirock/core-js/issues/207) -##### 2.4.0 - 2016.05.08 +### [2.4.0 - 2016.05.08](https://github.com/zloirock/core-js/releases/tag/v2.4.0) - Added `Observable`, [stage 1 proposal](https://github.com/zenparsing/es-observable) - Fixed behavior `Object.{getOwnPropertySymbols, getOwnPropertyDescriptor}` and `Object#propertyIsEnumerable` on `Object.prototype` - `Reflect.construct` and `Reflect.apply` should throw an error if `argumentsList` argument is not an object, [#194](https://github.com/zloirock/core-js/issues/194) -##### 2.3.0 - 2016.04.24 -- Added `asap` for enqueuing microtasks, [stage 0 proposal](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask) +### [2.3.0 - 2016.04.24](https://github.com/zloirock/core-js/releases/tag/v2.3.0) +- Added `asap` for enqueuing microtasks, [stage 0 proposal](https://github.com/tc39/notes/blob/main/meetings/2014-09/sept-25.md#510-globalasap-for-enqueuing-a-microtask) - Added well-known symbol `Symbol.asyncIterator` for [stage 2 async iteration proposal](https://github.com/tc39/proposal-async-iteration) - Added well-known symbol `Symbol.observable` for [stage 1 observables proposal](https://github.com/zenparsing/es-observable) -- `String#{padStart, padEnd}` returns original string if filler is empty string, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-29.md#stringprototypepadstartpadend) -- `Object.values` and `Object.entries` moved to stage 4 from 3, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-29.md#objectvalues--objectentries) -- `System.global` moved to stage 2 from 1, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-29.md#systemglobal) -- `Map#toJSON` and `Set#toJSON` rejected and will be removed from the next major release, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-31.md#mapprototypetojsonsetprototypetojson) -- `Error.isError` withdrawn and will be removed from the next major release, [TC39 meeting notes](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-03/march-29.md#erroriserror) +- `String#{padStart, padEnd}` returns original string if filler is empty string, [TC39 meeting notes](https://github.com/tc39/notes/blob/main/meetings/2016-03/march-29.md#stringprototypepadstartpadend) +- `Object.values` and `Object.entries` moved to stage 4 from 3, [TC39 meeting notes](https://github.com/tc39/notes/blob/main/meetings/2016-03/march-29.md#objectvalues--objectentries) +- `System.global` moved to stage 2 from 1, [TC39 meeting notes](https://github.com/tc39/notes/blob/main/meetings/2016-03/march-29.md#systemglobal) +- `Map#toJSON` and `Set#toJSON` rejected and will be removed from the next major release, [TC39 meeting notes](https://github.com/tc39/notes/blob/main/meetings/2016-03/march-31.md#mapprototypetojsonsetprototypetojson) +- `Error.isError` withdrawn and will be removed from the next major release, [TC39 meeting notes](https://github.com/tc39/notes/blob/main/meetings/2016-03/march-29.md#erroriserror) - Added fallback for `Function#name` on non-extensible functions and functions with broken `toString` conversion, [#193](https://github.com/zloirock/core-js/issues/193) -##### 2.2.2 - 2016.04.06 +### [2.2.2 - 2016.04.06](https://github.com/zloirock/core-js/releases/tag/v2.2.2) - Added conversion `-0` to `+0` to `Array#{indexOf, lastIndexOf}`, [ES2016 fix](https://github.com/tc39/ecma262/pull/316) - Added fixes for some `Math` methods in Tor Browser - `Array.{from, of}` no longer calls prototype setters - Added workaround over Chrome DevTools strange behavior, [#186](https://github.com/zloirock/core-js/issues/186) -##### 2.2.1 - 2016.03.19 +### [2.2.1 - 2016.03.19](https://github.com/zloirock/core-js/releases/tag/v2.2.1) - Fixed `Object.getOwnPropertyNames(window)` `2.1+` versions bug, [#181](https://github.com/zloirock/core-js/issues/181) -##### 2.2.0 - 2016.03.15 +### [2.2.0 - 2016.03.15](https://github.com/zloirock/core-js/releases/tag/v2.2.0) - Added `String#matchAll`, [proposal](https://github.com/tc39/String.prototype.matchAll) - Added `Object#__(define|lookup)[GS]etter__`, [annex B ES2017](https://github.com/tc39/ecma262/pull/381) - Added `@@toPrimitive` methods to `Date` and `Symbol` - Fixed `%TypedArray%#slice` in Edge ~ 13 (throws with `@@species` and wrapped / inherited constructor) - Some other minor fixes -##### 2.1.5 - 2016.03.12 +### [2.1.5 - 2016.03.12](https://github.com/zloirock/core-js/releases/tag/v2.1.5) - Improved support NodeJS domains in `Promise#then`, [#180](https://github.com/zloirock/core-js/issues/180) - Added fallback for `Date#toJSON` bug in Qt Script, [#173](https://github.com/zloirock/core-js/issues/173#issuecomment-193972502) -##### 2.1.4 - 2016.03.08 +### [2.1.4 - 2016.03.08](https://github.com/zloirock/core-js/releases/tag/v2.1.4) - Added fallback for `Symbol` polyfill in Qt Script, [#173](https://github.com/zloirock/core-js/issues/173) - Added one more fallback for IE11 `Script Access Denied` error with iframes, [#165](https://github.com/zloirock/core-js/issues/165) -##### 2.1.3 - 2016.02.29 +### [2.1.3 - 2016.02.29](https://github.com/zloirock/core-js/releases/tag/v2.1.3) - Added fallback for [`es6-promise` package bug](https://github.com/stefanpenner/es6-promise/issues/169), [#176](https://github.com/zloirock/core-js/issues/176) -##### 2.1.2 - 2016.02.29 +### [2.1.2 - 2016.02.29](https://github.com/zloirock/core-js/releases/tag/v2.1.2) - Some minor `Promise` fixes: - Browsers `rejectionhandled` event better HTML spec complaint - Errors in unhandled rejection handlers should not cause any problems - Fixed typo in feature detection -##### 2.1.1 - 2016.02.22 +### [2.1.1 - 2016.02.22](https://github.com/zloirock/core-js/releases/tag/v2.1.1) - Some `Promise` improvements: - Feature detection: - **Added detection unhandled rejection tracking support - now it's available everywhere**, [#140](https://github.com/zloirock/core-js/issues/140) @@ -527,7 +2263,7 @@ - Removed usage `Object.setPrototypeOf` from feature detection and noisy console message about it in FF - `Promise.all` fixed for some very specific cases -##### 2.1.0 - 2016.02.09 +### [2.1.0 - 2016.02.09](https://github.com/zloirock/core-js/releases/tag/v2.1.0) - **API**: - ES5 polyfills are split and logic, used in other polyfills, moved to internal modules - **All entry point works in ES3 environment like IE8- without `core-js/(library/)es5`** @@ -539,13 +2275,13 @@ - Should not be changed only several features like `Array.isArray` and `Date.now` - Some ES5 polyfills required for modern engines - All old entry points should work fine, but in the next major release API can be changed - - `Object.getOwnPropertyDescriptors` moved to the stage 3, [January TC39 meeting](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-01/2016-01-28.md#objectgetownpropertydescriptors-to-stage-3-jordan-harband-low-priority-but-super-quick) + - `Object.getOwnPropertyDescriptors` moved to the stage 3, [January TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2016-01/2016-01-28.md#objectgetownpropertydescriptors-to-stage-3-jordan-harband-low-priority-but-super-quick) - Added `umd` option for [custom build process](https://github.com/zloirock/core-js#custom-build-from-external-scripts), [#169](https://github.com/zloirock/core-js/issues/169) - Returned entry points for `Array` statics, removed in `2.0`, for compatibility with `babel` `6` and for future fixes - **Deprecated**: - - `Reflect.enumerate` deprecated and will be removed from the next major release, [January TC39 meeting](https://github.com/rwaldron/tc39-notes/blob/master/es7/2016-01/2016-01-28.md#5xix-revisit-proxy-enumerate---revisit-decision-to-exhaust-iterator) + - `Reflect.enumerate` deprecated and will be removed from the next major release, [January TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2016-01/2016-01-28.md#5xix-revisit-proxy-enumerate---revisit-decision-to-exhaust-iterator) - **New Features**: - - Added [`Reflect` metadata API](https://github.com/jonathandturner/decorators/blob/master/specs/metadata.md) as a pre-strawman feature, [#152](https://github.com/zloirock/core-js/issues/152): + - Added [`Reflect` metadata API](https://rbuckton.github.io/reflect-metadata/) as a pre-strawman feature, [#152](https://github.com/zloirock/core-js/issues/152): - `Reflect.defineMetadata` - `Reflect.deleteMetadata` - `Reflect.getMetadata` @@ -565,45 +2301,45 @@ - Additional fixes for `String#split` (`RegExp#@@split`) - **Improvements**: - Correct subclassing wrapped collections, `Number` and `RegExp` constructors with native class syntax - - Correct support `SharedArrayBuffer` and buffers from other realms in typed arrays wrappers + - Correct support `SharedArrayBuffer` and buffers from other realms in typed arrays wrappers - Additional validations for `Object.{defineProperty, getOwnPropertyDescriptor}` and `Reflect.defineProperty` - **Bug Fixes**: - Fixed some cases `Array#lastIndexOf` with negative second argument -##### 2.0.3 - 2016.01.11 +### [2.0.3 - 2016.01.11](https://github.com/zloirock/core-js/releases/tag/v2.0.3) - Added fallback for V8 ~ Chrome 49 `Promise` subclassing bug causes unhandled rejection on feature detection, [#159](https://github.com/zloirock/core-js/issues/159) - Added fix for very specific environments with global `window === null` -##### 2.0.2 - 2016.01.04 +### [2.0.2 - 2016.01.04](https://github.com/zloirock/core-js/releases/tag/v2.0.2) - Temporarily removed `length` validation from `Uint8Array` constructor wrapper. Reason - [bug in `ws` module](https://github.com/websockets/ws/pull/645) (-> `socket.io`) which passes to `Buffer` constructor -> `Uint8Array` float and uses [the `V8` bug](https://code.google.com/p/v8/issues/detail?id=4552) for conversion to int (by the spec should be thrown an error). [It creates problems for many people.](https://github.com/karma-runner/karma/issues/1768) I hope, it will be returned after fixing this bug in `V8`. -##### 2.0.1 - 2015.12.31 +### [2.0.1 - 2015.12.31](https://github.com/zloirock/core-js/releases/tag/v2.0.1) - Forced usage `Promise.resolve` polyfill in the `library` version for correct work with wrapper - `Object.assign` should be defined in the strict mode -> throw an error on extension non-extensible objects, [#154](https://github.com/zloirock/core-js/issues/154) -##### 2.0.0 - 2015.12.24 +### [2.0.0 - 2015.12.24](https://github.com/zloirock/core-js/releases/tag/v2.0.0) - Added implementations and fixes [Typed Arrays](https://github.com/zloirock/core-js#ecmascript-6-typed-arrays)-related features - `ArrayBuffer`, `ArrayBuffer.isView`, `ArrayBuffer#slice` - `DataView` with all getter / setter methods - `Int8Array`, `Uint8Array`, `Uint8ClampedArray`, `Int16Array`, `Uint16Array`, `Int32Array`, `Uint32Array`, `Float32Array` and `Float64Array` constructors - `%TypedArray%.{for, of}`, `%TypedArray%#{copyWithin, every, fill, filter, find, findIndex, forEach, indexOf, includes, join, lastIndexOf, map, reduce, reduceRight, reverse, set, slice, some, sort, subarray, values, keys, entries, @@iterator, ...}` -- Added [`System.global`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/tc39/proposal-global), [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-19.md#systemglobal-jhd) -- Added [`Error.isError`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/ljharb/proposal-is-error), [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-19.md#jhd-erroriserror) +- Added [`System.global`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/tc39/proposal-global), [November TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2015-11/nov-19.md#systemglobal-jhd) +- Added [`Error.isError`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/ljharb/proposal-is-error), [November TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2015-11/nov-19.md#jhd-erroriserror) - Added [`Math.{iaddh, isubh, imulh, umulh}`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://gist.github.com/BrendanEich/4294d5c212a6d2254703) -- `RegExp.escape` moved from the `es7` to the non-standard `core` namespace, [July TC39 meeting](https://github.com/rwaldron/tc39-notes/blob/master/es7/2015-07/july-28.md#62-regexpescape) - too slow, but it's condition of stability, [#116](https://github.com/zloirock/core-js/issues/116) +- `RegExp.escape` moved from the `es7` to the non-standard `core` namespace, [July TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2015-07/july-28.md#62-regexpescape) - too slow, but it's condition of stability, [#116](https://github.com/zloirock/core-js/issues/116) - [`Promise`](https://github.com/zloirock/core-js#ecmascript-6-promise) - Some performance optimisations - Added basic support [`rejectionHandled` event / `onrejectionhandled` handler](https://github.com/zloirock/core-js#unhandled-rejection-tracking) to the polyfill - - Removed usage `@@species` from `Promise.{all, race}`, [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-18.md#conclusionresolution-2) + - Removed usage `@@species` from `Promise.{all, race}`, [November TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2015-11/nov-18.md#conclusionresolution-2) - Some improvements [collections polyfills](https://github.com/zloirock/core-js#ecmascript-6-collections) - `O(1)` and preventing possible leaks with frozen keys, [#134](https://github.com/zloirock/core-js/issues/134) - Correct observable state object keys -- Renamed `String#{padLeft, padRight}` -> [`String#{padStart, padEnd}`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/tc39/proposal-string-pad-start-end), [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-17.md#conclusionresolution-2) (they want to rename it on each meeting?O_o), [#132](https://github.com/zloirock/core-js/issues/132) -- Added [`String#{trimStart, trimEnd}` as aliases for `String#{trimLeft, trimRight}`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/sebmarkbage/ecmascript-string-left-right-trim), [November TC39 meeting](https://github.com/rwaldron/tc39-notes/tree/master/es7/2015-11/nov-17.md#conclusionresolution-2) -- Added [annex B HTML methods](https://github.com/zloirock/core-js#ecmascript-6-string) - ugly, but also [the part of the spec](http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.anchor) -- Added little fix for [`Date#toString`](https://github.com/zloirock/core-js#ecmascript-6-date) - `new Date(NaN).toString()` [should be `'Invalid Date'`](http://www.ecma-international.org/ecma-262/6.0/#sec-todatestring) +- Renamed `String#{padLeft, padRight}` -> [`String#{padStart, padEnd}`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/tc39/proposal-string-pad-start-end), [November TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2015-11/nov-17.md#conclusionresolution-2) (they want to rename it on each meeting?O_o), [#132](https://github.com/zloirock/core-js/issues/132) +- Added [`String#{trimStart, trimEnd}` as aliases for `String#{trimLeft, trimRight}`](https://github.com/zloirock/core-js#ecmascript-7-proposals), [proposal](https://github.com/sebmarkbage/ecmascript-string-left-right-trim), [November TC39 meeting](https://github.com/tc39/notes/blob/main/meetings/2015-11/nov-17.md#conclusionresolution-2) +- Added [annex B HTML methods](https://github.com/zloirock/core-js#ecmascript-6-string) - ugly, but also [the part of the spec](https://262.ecma-international.org/6.0/#sec-string.prototype.anchor) +- Added little fix for [`Date#toString`](https://github.com/zloirock/core-js#ecmascript-6-date) - `new Date(NaN).toString()` [should be `'Invalid Date'`](https://262.ecma-international.org/6.0/#sec-todatestring) - Added [`{keys, values, entries, @@iterator}` methods to DOM collections](https://github.com/zloirock/core-js#iterable-dom-collections) which should have [iterable interface](https://heycam.github.io/webidl/#idl-iterable) or should be [inherited from `Array`](https://heycam.github.io/webidl/#LegacyArrayClass) - `NodeList`, `DOMTokenList`, `MediaList`, `StyleSheetList`, `CSSRuleList`. -- Removed Mozilla `Array` generics - [deprecated and will be removed from FF](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Array_generic_methods), [looks like strawman is dead](http://wiki.ecmascript.org/doku.php?id=strawman:array_statics), available [alternative shim](https://github.com/plusdude/array-generics) +- Removed Mozilla `Array` generics - [deprecated and will be removed from FF](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Array_generic_methods), [looks like strawman is dead](https://web.archive.org/web/20160805230354/http://wiki.ecmascript.org/doku.php?id=strawman:array_statics), available [alternative shim](https://github.com/plusdude/array-generics) - Removed `core.log` module - CommonJS API - Added entry points for [virtual methods](https://github.com/zloirock/core-js#commonjs-and-prototype-methods-without-global-namespace-pollution) @@ -617,408 +2353,408 @@ - `{Map, Set}#forEach` non-generic, [#144](https://github.com/zloirock/core-js/issues/144) - Many other improvements -##### 1.2.6 - 2015.11.09 -* Reject with `TypeError` on attempt resolve promise itself -* Correct behavior with broken `Promise` subclass constructors / methods -* Added `Promise`-based fallback for microtask -* Fixed V8 and FF `Array#{values, @@iterator}.name` -* Fixed IE7- `[1, 2].join(undefined) -> '1,2'` -* Some other fixes / improvements / optimizations - -##### 1.2.5 - 2015.11.02 -* Some more `Number` constructor fixes: - * Fixed V8 ~ Node 0.8 bug: `Number('+0x1')` should be `NaN` - * Fixed `Number(' 0b1\n')` case, should be `1` - * Fixed `Number()` case, should be `0` - -##### 1.2.4 - 2015.11.01 -* Fixed `Number('0b12') -> NaN` case in the shim -* Fixed V8 ~ Chromium 40- bug - `Weak(Map|Set)#{delete, get, has}` should not throw errors [#124](https://github.com/zloirock/core-js/issues/124) -* Some other fixes and optimizations - -##### 1.2.3 - 2015.10.23 -* Fixed some problems related old V8 bug `Object('a').propertyIsEnumerable(0) // => false`, for example, `Object.assign({}, 'qwe')` from the last release -* Fixed `.name` property and `Function#toString` conversion some polyfilled methods -* Fixed `Math.imul` arity in Safari 8- - -##### 1.2.2 - 2015.10.18 -* Improved optimisations for V8 -* Fixed build process from external packages, [#120](https://github.com/zloirock/core-js/pull/120) -* One more `Object.{assign, values, entries}` fix for [**very** specific case](https://github.com/ljharb/proposal-object-values-entries/issues/5) - -##### 1.2.1 - 2015.10.02 -* Replaced fix `JSON.stringify` + `Symbol` behavior from `.toJSON` method to wrapping `JSON.stringify` - little more correct, [compat-table/642](https://github.com/kangax/compat-table/pull/642) -* Fixed typo which broke tasks scheduler in WebWorkers in old FF, [#114](https://github.com/zloirock/core-js/pull/114) - -##### 1.2.0 - 2015.09.27 -* Added browser [`Promise` rejection hook](#unhandled-rejection-tracking), [#106](https://github.com/zloirock/core-js/issues/106) -* Added correct [`IsRegExp`](http://www.ecma-international.org/ecma-262/6.0/#sec-isregexp) logic to [`String#{includes, startsWith, endsWith}`](https://github.com/zloirock/core-js/#ecmascript-6-string) and [`RegExp` constructor](https://github.com/zloirock/core-js/#ecmascript-6-regexp), `@@match` case, [example](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match#Disabling_the_isRegExp_check) -* Updated [`String#leftPad`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) [with proposal](https://github.com/ljharb/proposal-string-pad-left-right/issues/6): string filler truncated from the right side -* Replaced V8 [`Object.assign`](https://github.com/zloirock/core-js/#ecmascript-6-object) - its properties order not only [incorrect](https://github.com/sindresorhus/object-assign/issues/22), it is non-deterministic and it causes some problems -* Fixed behavior with deleted in getters properties for `Object.{`[`assign`](https://github.com/zloirock/core-js/#ecmascript-6-object)`, `[`entries, values`](https://github.com/zloirock/core-js/#ecmascript-7-proposals)`}`, [example](http://goo.gl/iQE01c) -* Fixed [`Math.sinh`](https://github.com/zloirock/core-js/#ecmascript-6-math) with very small numbers in V8 near Chromium 38 -* Some other fixes and optimizations - -##### 1.1.4 - 2015.09.05 -* Fixed support symbols in FF34-35 [`Object.assign`](https://github.com/zloirock/core-js/#ecmascript-6-object) -* Fixed [collections iterators](https://github.com/zloirock/core-js/#ecmascript-6-iterators) in FF25-26 -* Fixed non-generic WebKit [`Array.of`](https://github.com/zloirock/core-js/#ecmascript-6-array) -* Some other fixes and optimizations - -##### 1.1.3 - 2015.08.29 -* Fixed support Node.js domains in [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise), [#103](https://github.com/zloirock/core-js/issues/103) - -##### 1.1.2 - 2015.08.28 -* Added `toJSON` method to [`Symbol`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) polyfill and to MS Edge implementation for expected `JSON.stringify` result w/o patching this method -* Replaced [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) implementations w/o correct support third argument -* Fixed `global` detection with changed `document.domain` in ~IE8, [#100](https://github.com/zloirock/core-js/issues/100) - -##### 1.1.1 - 2015.08.20 -* Added more correct microtask implementation for [`Promise`](#ecmascript-6-promise) - -##### 1.1.0 - 2015.08.17 -* Updated [string padding](https://github.com/zloirock/core-js/#ecmascript-7-proposals) to [actual proposal](https://github.com/ljharb/proposal-string-pad-left-right) - renamed, minor internal changes: - * `String#lpad` -> `String#padLeft` - * `String#rpad` -> `String#padRight` -* Added [string trim functions](#ecmascript-7-proposals) - [proposal](https://github.com/sebmarkbage/ecmascript-string-left-right-trim), defacto standard - required only for IE11- and fixed for some old engines: - * `String#trimLeft` - * `String#trimRight` -* [`String#trim`](https://github.com/zloirock/core-js/#ecmascript-6-string) fixed for some engines by es6 spec and moved from `es5` to single `es6` module -* Splitted [`es6.object.statics-accept-primitives`](https://github.com/zloirock/core-js/#ecmascript-6-object) -* Caps for `freeze`-family `Object` methods moved from `es5` to `es6` namespace and joined with [es6 wrappers](https://github.com/zloirock/core-js/#ecmascript-6-object) -* `es5` [namespace](https://github.com/zloirock/core-js/#commonjs) also includes modules, moved to `es6` namespace - you can use it as before -* Increased `MessageChannel` priority in `$.task`, [#95](https://github.com/zloirock/core-js/issues/95) -* Does not get `global.Symbol` on each getting iterator, if you wanna use alternative `Symbol` shim - add it before `core-js` -* [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) optimized and fixed for some cases -* Simplified [`Reflect.enumerate`](https://github.com/zloirock/core-js/#ecmascript-6-reflect), see [this question](https://esdiscuss.org/topic/question-about-enumerate-and-property-decision-timing) -* Some corrections in [`Math.acosh`](https://github.com/zloirock/core-js/#ecmascript-6-math) -* Fixed [`Math.imul`](https://github.com/zloirock/core-js/#ecmascript-6-math) for old WebKit -* Some fixes in string / RegExp [well-known symbols](https://github.com/zloirock/core-js/#ecmascript-6-regexp) logic -* Some other fixes and optimizations - -##### 1.0.1 - 2015.07.31 -* Some fixes for final MS Edge, replaced broken native `Reflect.defineProperty` -* Some minor fixes and optimizations -* Changed compression `client/*.min.js` options for safe `Function#name` and `Function#length`, should be fixed [#92](https://github.com/zloirock/core-js/issues/92) - -##### 1.0.0 - 2015.07.22 -* Added logic for [well-known symbols](https://github.com/zloirock/core-js/#ecmascript-6-regexp): - * `Symbol.match` - * `Symbol.replace` - * `Symbol.split` - * `Symbol.search` -* Actualized and optimized work with iterables: - * Optimized [`Map`, `Set`, `WeakMap`, `WeakSet` constructors](https://github.com/zloirock/core-js/#ecmascript-6-collections), [`Promise.all`, `Promise.race`](https://github.com/zloirock/core-js/#ecmascript-6-promise) for default `Array Iterator` - * Optimized [`Array.from`](https://github.com/zloirock/core-js/#ecmascript-6-array) for default `Array Iterator` - * Added [`core.getIteratorMethod`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) helper -* Uses enumerable properties in shimmed instances - collections, iterators, etc for optimize performance -* Added support native constructors to [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) with 2 arguments -* Added support native constructors to [`Function#bind`](https://github.com/zloirock/core-js/#ecmascript-5) shim with `new` -* Removed obsolete `.clear` methods native [`Weak`-collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) -* Maximum modularity, reduced minimal custom build size, separated into submodules: - * [`es6.reflect`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) - * [`es6.regexp`](https://github.com/zloirock/core-js/#ecmascript-6-regexp) - * [`es6.math`](https://github.com/zloirock/core-js/#ecmascript-6-math) - * [`es6.number`](https://github.com/zloirock/core-js/#ecmascript-6-number) - * [`es7.object.to-array`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) - * [`core.object`](https://github.com/zloirock/core-js/#object) - * [`core.string`](https://github.com/zloirock/core-js/#escaping-strings) - * [`core.iter-helpers`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) - * Internal modules (`$`, `$.iter`, etc) -* Many other optimizations -* Final cleaning non-standard features - * Moved `$for` to [separate library](https://github.com/zloirock/forof). This work for syntax - `for-of` loop and comprehensions - * Moved `Date#{format, formatUTC}` to [separate library](https://github.com/zloirock/dtf). Standard way for this - `ECMA-402` - * Removed `Math` methods from `Number.prototype`. Slight sugar for simple `Math` methods calling - * Removed `{Array#, Array, Dict}.turn` - * Removed `core.global` -* Uses `ToNumber` instead of `ToLength` in [`Number Iterator`](https://github.com/zloirock/core-js/#number-iterator), `Array.from(2.5)` will be `[0, 1, 2]` instead of `[0, 1]` -* Fixed [#85](https://github.com/zloirock/core-js/issues/85) - invalid `Promise` unhandled rejection message in nested `setTimeout` -* Fixed [#86](https://github.com/zloirock/core-js/issues/86) - support FF extensions -* Fixed [#89](https://github.com/zloirock/core-js/issues/89) - behavior `Number` constructor in strange case - -##### 0.9.18 - 2015.06.17 -* Removed `/` from [`RegExp.escape`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) escaped characters - -##### 0.9.17 - 2015.06.14 -* Updated [`RegExp.escape`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) to the [latest proposal](https://github.com/benjamingr/RexExp.escape) -* Fixed conflict with webpack dev server + IE buggy behavior - -##### 0.9.16 - 2015.06.11 -* More correct order resolving thenable in [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) polyfill -* Uses polyfill instead of [buggy V8 `Promise`](https://github.com/zloirock/core-js/issues/78) - -##### 0.9.15 - 2015.06.09 -* [Collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) from `library` version return wrapped native instances -* Fixed collections prototype methods in `library` version -* Optimized [`Math.hypot`](https://github.com/zloirock/core-js/#ecmascript-6-math) - -##### 0.9.14 - 2015.06.04 -* Updated [`Promise.resolve` behavior](https://esdiscuss.org/topic/fixing-promise-resolve) -* Added fallback for IE11 buggy `Object.getOwnPropertyNames` + iframe -* Some other fixes - -##### 0.9.13 - 2015.05.25 -* Added fallback for [`Symbol` polyfill](https://github.com/zloirock/core-js/#ecmascript-6-symbol) for old Android -* Some other fixes - -##### 0.9.12 - 2015.05.24 -* Different instances `core-js` should use / recognize the same symbols -* Some fixes - -##### 0.9.11 - 2015.05.18 -* Simplified [custom build](https://github.com/zloirock/core-js/#custom-build) - * Added custom build js api - * Added `grunt-cli` to `devDependencies` for `npm run grunt` -* Some fixes - -##### 0.9.10 - 2015.05.16 -* Wrapped `Function#toString` for correct work wrapped methods / constructors with methods similar to the [`lodash` `isNative`](https://github.com/lodash/lodash/issues/1197) -* Added proto versions of methods to export object in `default` version for consistency with `library` version - -##### 0.9.9 - 2015.05.14 -* Wrapped `Object#propertyIsEnumerable` for [`Symbol` polyfill](https://github.com/zloirock/core-js/#ecmascript-6-symbol) -* [Added proto versions of methods to `library` for ES7 bind syntax](https://github.com/zloirock/core-js/issues/65) -* Some other fixes - -##### 0.9.8 - 2015.05.12 -* Fixed [`Math.hypot`](https://github.com/zloirock/core-js/#ecmascript-6-math) with negative arguments -* Added `Object#toString.toString` as fallback for [`lodash` `isNative`](https://github.com/lodash/lodash/issues/1197) - -##### 0.9.7 - 2015.05.07 -* Added [support DOM collections](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Streamlining_cross-browser_behavior) to IE8- `Array#slice` - -##### 0.9.6 - 2015.05.01 -* Added [`String#lpad`, `String#rpad`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) - -##### 0.9.5 - 2015.04.30 -* Added cap for `Function#@@hasInstance` -* Some fixes and optimizations - -##### 0.9.4 - 2015.04.27 -* Fixed `RegExp` constructor - -##### 0.9.3 - 2015.04.26 -* Some fixes and optimizations - -##### 0.9.2 - 2015.04.25 -* More correct [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) unhandled rejection tracking and resolving / rejection priority - -##### 0.9.1 - 2015.04.25 -* Fixed `__proto__`-based [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) subclassing in some environments - -##### 0.9.0 - 2015.04.24 -* Added correct [symbols](https://github.com/zloirock/core-js/#ecmascript-6-symbol) descriptors - * Fixed behavior `Object.{assign, create, defineProperty, defineProperties, getOwnPropertyDescriptor, getOwnPropertyDescriptors}` with symbols - * Added [single entry points](https://github.com/zloirock/core-js/#commonjs) for `Object.{create, defineProperty, defineProperties}` -* Added [`Map#toJSON`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) -* Removed non-standard methods `Object#[_]` and `Function#only` - they solves syntax problems, but now in compilers available arrows and ~~in near future will be available~~ [available](http://babeljs.io/blog/2015/05/14/function-bind/) [bind syntax](https://github.com/zenparsing/es-function-bind) -* Removed non-standard undocumented methods `Symbol.{pure, set}` -* Some fixes and internal changes - -##### 0.8.4 - 2015.04.18 -* Uses `webpack` instead of `browserify` for browser builds - more compression-friendly result - -##### 0.8.3 - 2015.04.14 -* Fixed `Array` statics with single entry points - -##### 0.8.2 - 2015.04.13 -* [`Math.fround`](https://github.com/zloirock/core-js/#ecmascript-6-math) now also works in IE9- -* Added [`Set#toJSON`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) -* Some optimizations and fixes - -##### 0.8.1 - 2015.04.03 -* Fixed `Symbol.keyFor` - -##### 0.8.0 - 2015.04.02 -* Changed [CommonJS API](https://github.com/zloirock/core-js/#commonjs) -* Splitted and renamed some modules -* Added support ES3 environment (ES5 polyfill) to **all** default versions - size increases slightly (+ ~4kb w/o gzip), many issues disappear, if you don't need it - [simply include only required namespaces / features / modules](https://github.com/zloirock/core-js/#commonjs) -* Removed [abstract references](https://github.com/zenparsing/es-abstract-refs) support - proposal has been superseded =\ -* [`$for.isIterable` -> `core.isIterable`, `$for.getIterator` -> `core.getIterator`](https://github.com/zloirock/core-js/#ecmascript-6-iterators), temporary available in old namespace -* Fixed iterators support in v8 `Promise.all` and `Promise.race` -* Many other fixes - -##### 0.7.2 - 2015.03.09 -* Some fixes - -##### 0.7.1 - 2015.03.07 -* Some fixes - -##### 0.7.0 - 2015.03.06 -* Rewritten and splitted into [CommonJS modules](https://github.com/zloirock/core-js/#commonjs) - -##### 0.6.1 - 2015.02.24 -* Fixed support [`Object.defineProperty`](https://github.com/zloirock/core-js/#ecmascript-5) with accessors on DOM elements on IE8 - -##### 0.6.0 - 2015.02.23 -* Added support safe closing iteration - calling `iterator.return` on abort iteration, if it exists -* Added basic support [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) unhandled rejection tracking in shim -* Added [`Object.getOwnPropertyDescriptors`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) -* Removed `console` cap - creates too many problems -* Restructuring [namespaces](https://github.com/zloirock/core-js/#custom-build) -* Some fixes - -##### 0.5.4 - 2015.02.15 -* Some fixes - -##### 0.5.3 - 2015.02.14 -* Added [support binary and octal literals](https://github.com/zloirock/core-js/#ecmascript-6-number) to `Number` constructor -* Added [`Date#toISOString`](https://github.com/zloirock/core-js/#ecmascript-5) - -##### 0.5.2 - 2015.02.10 -* Some fixes - -##### 0.5.1 - 2015.02.09 -* Some fixes - -##### 0.5.0 - 2015.02.08 -* Systematization of modules -* Splitted [`es6` module](https://github.com/zloirock/core-js/#ecmascript-6) -* Splitted `console` module: `web.console` - only cap for missing methods, `core.log` - bound methods & additional features -* Added [`delay` method](https://github.com/zloirock/core-js/#delay) -* Some fixes - -##### 0.4.10 - 2015.01.28 -* [`Object.getOwnPropertySymbols`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) polyfill returns array of wrapped keys - -##### 0.4.9 - 2015.01.27 -* FF20-24 fix - -##### 0.4.8 - 2015.01.25 -* Some [collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) fixes - -##### 0.4.7 - 2015.01.25 -* Added support frozen objects as [collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) keys - -##### 0.4.6 - 2015.01.21 -* Added [`Object.getOwnPropertySymbols`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) -* Added [`NodeList.prototype[@@iterator]`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) -* Added basic `@@species` logic - getter in native constructors -* Removed `Function#by` -* Some fixes - -##### 0.4.5 - 2015.01.16 -* Some fixes - -##### 0.4.4 - 2015.01.11 -* Enabled CSP support - -##### 0.4.3 - 2015.01.10 -* Added `Function` instances `name` property for IE9+ - -##### 0.4.2 - 2015.01.10 -* `Object` static methods accept primitives -* `RegExp` constructor can alter flags (IE9+) -* Added `Array.prototype[Symbol.unscopables]` - -##### 0.4.1 - 2015.01.05 -* Some fixes - -##### 0.4.0 - 2015.01.03 -* Added [`es6.reflect`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) module: - * Added `Reflect.apply` - * Added `Reflect.construct` - * Added `Reflect.defineProperty` - * Added `Reflect.deleteProperty` - * Added `Reflect.enumerate` - * Added `Reflect.get` - * Added `Reflect.getOwnPropertyDescriptor` - * Added `Reflect.getPrototypeOf` - * Added `Reflect.has` - * Added `Reflect.isExtensible` - * Added `Reflect.preventExtensions` - * Added `Reflect.set` - * Added `Reflect.setPrototypeOf` -* `core-js` methods now can use external `Symbol.iterator` polyfill -* Some fixes - -##### 0.3.3 - 2014.12.28 -* [Console cap](https://github.com/zloirock/core-js/#console) excluded from node.js default builds - -##### 0.3.2 - 2014.12.25 -* Added cap for [ES5](https://github.com/zloirock/core-js/#ecmascript-5) freeze-family methods -* Fixed `console` bug - -##### 0.3.1 - 2014.12.23 -* Some fixes - -##### 0.3.0 - 2014.12.23 -* Optimize [`Map` & `Set`](https://github.com/zloirock/core-js/#ecmascript-6-collections): - * Use entries chain on hash table - * Fast & correct iteration - * Iterators moved to [`es6`](https://github.com/zloirock/core-js/#ecmascript-6) and [`es6.collections`](https://github.com/zloirock/core-js/#ecmascript-6-collections) modules - -##### 0.2.5 - 2014.12.20 -* `console` no longer shortcut for `console.log` (compatibility problems) -* Some fixes - -##### 0.2.4 - 2014.12.17 -* Better compliance of ES6 -* Added [`Math.fround`](https://github.com/zloirock/core-js/#ecmascript-6-math) (IE10+) -* Some fixes - -##### 0.2.3 - 2014.12.15 -* [Symbols](https://github.com/zloirock/core-js/#ecmascript-6-symbol): - * Added option to disable addition setter to `Object.prototype` for Symbol polyfill: - * Added `Symbol.useSimple` - * Added `Symbol.useSetter` - * Added cap for well-known Symbols: - * Added `Symbol.hasInstance` - * Added `Symbol.isConcatSpreadable` - * Added `Symbol.match` - * Added `Symbol.replace` - * Added `Symbol.search` - * Added `Symbol.species` - * Added `Symbol.split` - * Added `Symbol.toPrimitive` - * Added `Symbol.unscopables` - -##### 0.2.2 - 2014.12.13 -* Added [`RegExp#flags`](https://github.com/zloirock/core-js/#ecmascript-6-regexp) ([December 2014 Draft Rev 29](http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts#december_6_2014_draft_rev_29)) -* Added [`String.raw`](https://github.com/zloirock/core-js/#ecmascript-6-string) - -##### 0.2.1 - 2014.12.12 -* Repair converting -0 to +0 in [native collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) - -##### 0.2.0 - 2014.12.06 -* Added [`es7.proposals`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) and [`es7.abstract-refs`](https://github.com/zenparsing/es-abstract-refs) modules -* Added [`String#at`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) -* Added real [`String Iterator`](https://github.com/zloirock/core-js/#ecmascript-6-iterators), older versions used Array Iterator -* Added abstract references support: - * Added `Symbol.referenceGet` - * Added `Symbol.referenceSet` - * Added `Symbol.referenceDelete` - * Added `Function#@@referenceGet` - * Added `Map#@@referenceGet` - * Added `Map#@@referenceSet` - * Added `Map#@@referenceDelete` - * Added `WeakMap#@@referenceGet` - * Added `WeakMap#@@referenceSet` - * Added `WeakMap#@@referenceDelete` - * Added `Dict.{...methods}[@@referenceGet]` -* Removed deprecated `.contains` methods -* Some fixes - -##### 0.1.5 - 2014.12.01 -* Added [`Array#copyWithin`](https://github.com/zloirock/core-js/#ecmascript-6-array) -* Added [`String#codePointAt`](https://github.com/zloirock/core-js/#ecmascript-6-string) -* Added [`String.fromCodePoint`](https://github.com/zloirock/core-js/#ecmascript-6-string) - -##### 0.1.4 - 2014.11.27 -* Added [`Dict.mapPairs`](https://github.com/zloirock/core-js/#dict) - -##### 0.1.3 - 2014.11.20 -* [TC39 November meeting](https://github.com/rwaldron/tc39-notes/tree/master/es6/2014-11): - * [`.contains` -> `.includes`](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-11/nov-18.md#51--44-arrayprototypecontains-and-stringprototypecontains) - * `String#contains` -> [`String#includes`](https://github.com/zloirock/core-js/#ecmascript-6-string) - * `Array#contains` -> [`Array#includes`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) - * `Dict.contains` -> [`Dict.includes`](https://github.com/zloirock/core-js/#dict) - * [Removed `WeakMap#clear`](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-11/nov-19.md#412-should-weakmapweakset-have-a-clear-method-markm) - * [Removed `WeakSet#clear`](https://github.com/rwaldron/tc39-notes/blob/master/es6/2014-11/nov-19.md#412-should-weakmapweakset-have-a-clear-method-markm) - -##### 0.1.2 - 2014.11.19 -* `Map` & `Set` bug fix - -##### 0.1.1 - 2014.11.18 -* Public release \ No newline at end of file +### [1.2.6 - 2015.11.09](https://github.com/zloirock/core-js/releases/tag/v1.2.6) +- Reject with `TypeError` on attempt resolve promise itself +- Correct behavior with broken `Promise` subclass constructors / methods +- Added `Promise`-based fallback for microtask +- Fixed V8 and FF `Array#{values, @@iterator}.name` +- Fixed IE7- `[1, 2].join(undefined) -> '1,2'` +- Some other fixes / improvements / optimizations + +### [1.2.5 - 2015.11.02](https://github.com/zloirock/core-js/releases/tag/v1.2.5) +- Some more `Number` constructor fixes: + - Fixed V8 ~ Node 0.8 bug: `Number('+0x1')` should be `NaN` + - Fixed `Number(' 0b1\n')` case, should be `1` + - Fixed `Number()` case, should be `0` + +### [1.2.4 - 2015.11.01](https://github.com/zloirock/core-js/releases/tag/v1.2.4) +- Fixed `Number('0b12') -> NaN` case in the shim +- Fixed V8 ~ Chromium 40- bug - `Weak(Map|Set)#{delete, get, has}` should not throw errors [#124](https://github.com/zloirock/core-js/issues/124) +- Some other fixes and optimizations + +### [1.2.3 - 2015.10.23](https://github.com/zloirock/core-js/releases/tag/v1.2.3) +- Fixed some problems related old V8 bug `Object('a').propertyIsEnumerable(0) // => false`, for example, `Object.assign({}, 'qwe')` from the last release +- Fixed `.name` property and `Function#toString` conversion some polyfilled methods +- Fixed `Math.imul` arity in Safari 8- + +### [1.2.2 - 2015.10.18](https://github.com/zloirock/core-js/releases/tag/v1.2.2) +- Improved optimisations for V8 +- Fixed build process from external packages, [#120](https://github.com/zloirock/core-js/pull/120) +- One more `Object.{assign, values, entries}` fix for [**very** specific case](https://github.com/ljharb/proposal-object-values-entries/issues/5) + +### [1.2.1 - 2015.10.02](https://github.com/zloirock/core-js/releases/tag/v1.2.1) +- Replaced fix `JSON.stringify` + `Symbol` behavior from `.toJSON` method to wrapping `JSON.stringify` - little more correct, [compat-table/642](https://github.com/kangax/compat-table/pull/642) +- Fixed typo which broke tasks scheduler in WebWorkers in old FF, [#114](https://github.com/zloirock/core-js/pull/114) + +### [1.2.0 - 2015.09.27](https://github.com/zloirock/core-js/releases/tag/v1.2.0) +- Added browser [`Promise` rejection hook](#unhandled-rejection-tracking), [#106](https://github.com/zloirock/core-js/issues/106) +- Added correct [`IsRegExp`](https://262.ecma-international.org/6.0/#sec-isregexp) logic to [`String#{includes, startsWith, endsWith}`](https://github.com/zloirock/core-js/#ecmascript-6-string) and [`RegExp` constructor](https://github.com/zloirock/core-js/#ecmascript-6-regexp), `@@match` case, [example](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match#Disabling_the_isRegExp_check) +- Updated [`String#leftPad`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) [with proposal](https://github.com/ljharb/proposal-string-pad-left-right/issues/6): string filler truncated from the right side +- Replaced V8 [`Object.assign`](https://github.com/zloirock/core-js/#ecmascript-6-object) - its properties order not only incorrect, it is non-deterministic and it causes some problems +- Fixed behavior with deleted in getters properties for `Object.{`[`assign`](https://github.com/zloirock/core-js/#ecmascript-6-object)`, `[`entries, values`](https://github.com/zloirock/core-js/#ecmascript-7-proposals)`}`, [example](http://goo.gl/iQE01c) +- Fixed [`Math.sinh`](https://github.com/zloirock/core-js/#ecmascript-6-math) with very small numbers in V8 near Chromium 38 +- Some other fixes and optimizations + +### [1.1.4 - 2015.09.05](https://github.com/zloirock/core-js/releases/tag/v1.1.4) +- Fixed support symbols in FF34-35 [`Object.assign`](https://github.com/zloirock/core-js/#ecmascript-6-object) +- Fixed [collections iterators](https://github.com/zloirock/core-js/#ecmascript-6-iterators) in FF25-26 +- Fixed non-generic WebKit [`Array.of`](https://github.com/zloirock/core-js/#ecmascript-6-array) +- Some other fixes and optimizations + +### [1.1.3 - 2015.08.29](https://github.com/zloirock/core-js/releases/tag/v1.1.3) +- Fixed support Node.js domains in [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise), [#103](https://github.com/zloirock/core-js/issues/103) + +### [1.1.2 - 2015.08.28](https://github.com/zloirock/core-js/releases/tag/v1.1.2) +- Added `toJSON` method to [`Symbol`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) polyfill and to MS Edge implementation for expected `JSON.stringify` result w/o patching this method +- Replaced [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) implementations w/o correct support third argument +- Fixed `global` detection with changed `document.domain` in \~IE8, [#100](https://github.com/zloirock/core-js/issues/100) + +### [1.1.1 - 2015.08.20](https://github.com/zloirock/core-js/releases/tag/v1.1.1) +- Added more correct microtask implementation for [`Promise`](#ecmascript-6-promise) + +### [1.1.0 - 2015.08.17](https://github.com/zloirock/core-js/releases/tag/v1.1.0) +- Updated [string padding](https://github.com/zloirock/core-js/#ecmascript-7-proposals) to [actual proposal](https://github.com/ljharb/proposal-string-pad-left-right) - renamed, minor internal changes: + - `String#lpad` -> `String#padLeft` + - `String#rpad` -> `String#padRight` +- Added [string trim functions](#ecmascript-7-proposals) - [proposal](https://github.com/sebmarkbage/ecmascript-string-left-right-trim), defacto standard - required only for IE11- and fixed for some old engines: + - `String#trimLeft` + - `String#trimRight` +- [`String#trim`](https://github.com/zloirock/core-js/#ecmascript-6-string) fixed for some engines by es6 spec and moved from `es5` to single `es6` module +- Split [`es6.object.statics-accept-primitives`](https://github.com/zloirock/core-js/#ecmascript-6-object) +- Caps for `freeze`-family `Object` methods moved from `es5` to `es6` namespace and joined with [es6 wrappers](https://github.com/zloirock/core-js/#ecmascript-6-object) +- `es5` [namespace](https://github.com/zloirock/core-js/#commonjs) also includes modules, moved to `es6` namespace - you can use it as before +- Increased `MessageChannel` priority in `$.task`, [#95](https://github.com/zloirock/core-js/issues/95) +- Does not get `global.Symbol` on each getting iterator, if you wanna use alternative `Symbol` shim - add it before `core-js` +- [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) optimized and fixed for some cases +- Simplified [`Reflect.enumerate`](https://github.com/zloirock/core-js/#ecmascript-6-reflect), see [this question](https://esdiscuss.org/topic/question-about-enumerate-and-property-decision-timing) +- Some corrections in [`Math.acosh`](https://github.com/zloirock/core-js/#ecmascript-6-math) +- Fixed [`Math.imul`](https://github.com/zloirock/core-js/#ecmascript-6-math) for old WebKit +- Some fixes in string / RegExp [well-known symbols](https://github.com/zloirock/core-js/#ecmascript-6-regexp) logic +- Some other fixes and optimizations + +### [1.0.1 - 2015.07.31](https://github.com/zloirock/core-js/releases/tag/v1.0.1) +- Some fixes for final MS Edge, replaced broken native `Reflect.defineProperty` +- Some minor fixes and optimizations +- Changed compression `client/*.min.js` options for safe `Function#name` and `Function#length`, should be fixed [#92](https://github.com/zloirock/core-js/issues/92) + +### [1.0.0 - 2015.07.22](https://github.com/zloirock/core-js/releases/tag/v1.0.0) +- Added logic for [well-known symbols](https://github.com/zloirock/core-js/#ecmascript-6-regexp): + - `Symbol.match` + - `Symbol.replace` + - `Symbol.split` + - `Symbol.search` +- Actualized and optimized work with iterables: + - Optimized [`Map`, `Set`, `WeakMap`, `WeakSet` constructors](https://github.com/zloirock/core-js/#ecmascript-6-collections), [`Promise.all`, `Promise.race`](https://github.com/zloirock/core-js/#ecmascript-6-promise) for default `Array Iterator` + - Optimized [`Array.from`](https://github.com/zloirock/core-js/#ecmascript-6-array) for default `Array Iterator` + - Added [`core.getIteratorMethod`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) helper +- Uses enumerable properties in shimmed instances - collections, iterators, etc for optimize performance +- Added support native constructors to [`Reflect.construct`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) with 2 arguments +- Added support native constructors to [`Function#bind`](https://github.com/zloirock/core-js/#ecmascript-5) shim with `new` +- Removed obsolete `.clear` methods native [`Weak`-collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) +- Maximum modularity, reduced minimal custom build size, separated into submodules: + - [`es6.reflect`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) + - [`es6.regexp`](https://github.com/zloirock/core-js/#ecmascript-6-regexp) + - [`es6.math`](https://github.com/zloirock/core-js/#ecmascript-6-math) + - [`es6.number`](https://github.com/zloirock/core-js/#ecmascript-6-number) + - [`es7.object.to-array`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) + - [`core.object`](https://github.com/zloirock/core-js/#object) + - [`core.string`](https://github.com/zloirock/core-js/#escaping-strings) + - [`core.iter-helpers`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) + - Internal modules (`$`, `$.iter`, etc) +- Many other optimizations +- Final cleaning non-standard features + - Moved `$for` to [separate library](https://github.com/zloirock/forof). This work for syntax - `for-of` loop and comprehensions + - Moved `Date#{format, formatUTC}` to [separate library](https://github.com/zloirock/dtf). Standard way for this - `ECMA-402` + - Removed `Math` methods from `Number.prototype`. Slight sugar for simple `Math` methods calling + - Removed `{Array#, Array, Dict}.turn` + - Removed `core.global` +- Uses `ToNumber` instead of `ToLength` in [`Number Iterator`](https://github.com/zloirock/core-js/#number-iterator), `Array.from(2.5)` will be `[0, 1, 2]` instead of `[0, 1]` +- Fixed [#85](https://github.com/zloirock/core-js/issues/85) - invalid `Promise` unhandled rejection message in nested `setTimeout` +- Fixed [#86](https://github.com/zloirock/core-js/issues/86) - support FF extensions +- Fixed [#89](https://github.com/zloirock/core-js/issues/89) - behavior `Number` constructor in strange case + +### [0.9.18 - 2015.06.17](https://github.com/zloirock/core-js/releases/tag/v0.9.18) +- Removed `/` from [`RegExp.escape`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) escaped characters + +### [0.9.17 - 2015.06.14](https://github.com/zloirock/core-js/releases/tag/v0.9.17) +- Updated [`RegExp.escape`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) to the [latest proposal](https://github.com/benjamingr/RexExp.escape) +- Fixed conflict with webpack dev server + IE buggy behavior + +### [0.9.16 - 2015.06.11](https://github.com/zloirock/core-js/releases/tag/v0.9.16) +- More correct order resolving thenable in [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) polyfill +- Uses polyfill instead of [buggy V8 `Promise`](https://github.com/zloirock/core-js/issues/78) + +### [0.9.15 - 2015.06.09](https://github.com/zloirock/core-js/releases/tag/v0.9.15) +- [Collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) from `library` version return wrapped native instances +- Fixed collections prototype methods in `library` version +- Optimized [`Math.hypot`](https://github.com/zloirock/core-js/#ecmascript-6-math) + +### [0.9.14 - 2015.06.04](https://github.com/zloirock/core-js/releases/tag/v0.9.14) +- Updated [`Promise.resolve` behavior](https://esdiscuss.org/topic/fixing-promise-resolve) +- Added fallback for IE11 buggy `Object.getOwnPropertyNames` + iframe +- Some other fixes + +### [0.9.13 - 2015.05.25](https://github.com/zloirock/core-js/releases/tag/v0.9.13) +- Added fallback for [`Symbol` polyfill](https://github.com/zloirock/core-js/#ecmascript-6-symbol) for old Android +- Some other fixes + +### [0.9.12 - 2015.05.24](https://github.com/zloirock/core-js/releases/tag/v0.9.12) +- Different instances `core-js` should use / recognize the same symbols +- Some fixes + +### [0.9.11 - 2015.05.18](https://github.com/zloirock/core-js/releases/tag/v0.9.11) +- Simplified [custom build](https://github.com/zloirock/core-js/#custom-build) + - Added custom build js api + - Added `grunt-cli` to `devDependencies` for `npm run grunt` +- Some fixes + +### [0.9.10 - 2015.05.16](https://github.com/zloirock/core-js/releases/tag/v0.9.10) +- Wrapped `Function#toString` for correct work wrapped methods / constructors with methods similar to the [`lodash` `isNative`](https://github.com/lodash/lodash/issues/1197) +- Added proto versions of methods to export object in `default` version for consistency with `library` version + +### [0.9.9 - 2015.05.14](https://github.com/zloirock/core-js/releases/tag/v0.9.9) +- Wrapped `Object#propertyIsEnumerable` for [`Symbol` polyfill](https://github.com/zloirock/core-js/#ecmascript-6-symbol) +- [Added proto versions of methods to `library` for ES7 bind syntax](https://github.com/zloirock/core-js/issues/65) +- Some other fixes + +### [0.9.8 - 2015.05.12](https://github.com/zloirock/core-js/releases/tag/v0.9.8) +- Fixed [`Math.hypot`](https://github.com/zloirock/core-js/#ecmascript-6-math) with negative arguments +- Added `Object#toString.toString` as fallback for [`lodash` `isNative`](https://github.com/lodash/lodash/issues/1197) + +### [0.9.7 - 2015.05.07](https://github.com/zloirock/core-js/releases/tag/v0.9.7) +- Added [support DOM collections](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Streamlining_cross-browser_behavior) to IE8- `Array#slice` + +### [0.9.6 - 2015.05.01](https://github.com/zloirock/core-js/releases/tag/v0.9.6) +- Added [`String#lpad`, `String#rpad`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) + +### [0.9.5 - 2015.04.30](https://github.com/zloirock/core-js/releases/tag/v0.9.5) +- Added cap for `Function#@@hasInstance` +- Some fixes and optimizations + +### [0.9.4 - 2015.04.27](https://github.com/zloirock/core-js/releases/tag/v0.9.4) +- Fixed `RegExp` constructor + +### [0.9.3 - 2015.04.26](https://github.com/zloirock/core-js/releases/tag/v0.9.3) +- Some fixes and optimizations + +### [0.9.2 - 2015.04.25](https://github.com/zloirock/core-js/releases/tag/v0.9.2) +- More correct [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) unhandled rejection tracking and resolving / rejection priority + +### [0.9.1 - 2015.04.25](https://github.com/zloirock/core-js/releases/tag/v0.9.1) +- Fixed `__proto__`-based [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) subclassing in some environments + +### [0.9.0 - 2015.04.24](https://github.com/zloirock/core-js/releases/tag/v0.9.0) +- Added correct [symbols](https://github.com/zloirock/core-js/#ecmascript-6-symbol) descriptors + - Fixed behavior `Object.{assign, create, defineProperty, defineProperties, getOwnPropertyDescriptor, getOwnPropertyDescriptors}` with symbols + - Added [single entry points](https://github.com/zloirock/core-js/#commonjs) for `Object.{create, defineProperty, defineProperties}` +- Added [`Map#toJSON`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) +- Removed non-standard methods `Object#[_]` and `Function#only` - they solves syntax problems, but now in compilers available arrows and ~~in near future will be available~~ [available](https://babeljs.io/blog/2015/05/14/function-bind/) [bind syntax](https://github.com/zenparsing/es-function-bind) +- Removed non-standard undocumented methods `Symbol.{pure, set}` +- Some fixes and internal changes + +### [0.8.4 - 2015.04.18](https://github.com/zloirock/core-js/releases/tag/v0.8.4) +- Uses `webpack` instead of `browserify` for browser builds - more compression-friendly result + +### [0.8.3 - 2015.04.14](https://github.com/zloirock/core-js/releases/tag/v0.8.3) +- Fixed `Array` statics with single entry points + +### [0.8.2 - 2015.04.13](https://github.com/zloirock/core-js/releases/tag/v0.8.2) +- [`Math.fround`](https://github.com/zloirock/core-js/#ecmascript-6-math) now also works in IE9- +- Added [`Set#toJSON`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) +- Some optimizations and fixes + +### [0.8.1 - 2015.04.03](https://github.com/zloirock/core-js/releases/tag/v0.8.1) +- Fixed `Symbol.keyFor` + +### [0.8.0 - 2015.04.02](https://github.com/zloirock/core-js/releases/tag/v0.8.0) +- Changed [CommonJS API](https://github.com/zloirock/core-js/#commonjs) +- Split and renamed some modules +- Added support ES3 environment (ES5 polyfill) to **all** default versions - size increases slightly (+ ~4kb w/o gzip), many issues disappear, if you don't need it - [simply include only required namespaces / features / modules](https://github.com/zloirock/core-js/#commonjs) +- Removed [abstract references](https://github.com/zenparsing/es-abstract-refs) support - proposal has been superseded =\ +- [`$for.isIterable` -> `core.isIterable`, `$for.getIterator` -> `core.getIterator`](https://github.com/zloirock/core-js/#ecmascript-6-iterators), temporary available in old namespace +- Fixed iterators support in v8 `Promise.all` and `Promise.race` +- Many other fixes + +### [0.7.2 - 2015.03.09](https://github.com/zloirock/core-js/releases/tag/v0.7.2) +- Some fixes + +### [0.7.1 - 2015.03.07](https://github.com/zloirock/core-js/releases/tag/v0.7.1) +- Some fixes + +### [0.7.0 - 2015.03.06](https://github.com/zloirock/core-js/releases/tag/v0.7.0) +- Rewritten and split into [CommonJS modules](https://github.com/zloirock/core-js/#commonjs) + +### [0.6.1 - 2015.02.24](https://github.com/zloirock/core-js/releases/tag/v0.6.1) +- Fixed support [`Object.defineProperty`](https://github.com/zloirock/core-js/#ecmascript-5) with accessors on DOM elements on IE8 + +### [0.6.0 - 2015.02.23](https://github.com/zloirock/core-js/releases/tag/v0.6.0) +- Added support safe closing iteration - calling `iterator.return` on abort iteration, if it exists +- Added basic support [`Promise`](https://github.com/zloirock/core-js/#ecmascript-6-promise) unhandled rejection tracking in shim +- Added [`Object.getOwnPropertyDescriptors`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) +- Removed `console` cap - creates too many problems +- Restructuring [namespaces](https://github.com/zloirock/core-js/#custom-build) +- Some fixes + +### [0.5.4 - 2015.02.15](https://github.com/zloirock/core-js/releases/tag/v0.5.4) +- Some fixes + +### [0.5.3 - 2015.02.14](https://github.com/zloirock/core-js/releases/tag/v0.5.3) +- Added [support binary and octal literals](https://github.com/zloirock/core-js/#ecmascript-6-number) to `Number` constructor +- Added [`Date#toISOString`](https://github.com/zloirock/core-js/#ecmascript-5) + +### [0.5.2 - 2015.02.10](https://github.com/zloirock/core-js/releases/tag/v0.5.2) +- Some fixes + +### [0.5.1 - 2015.02.09](https://github.com/zloirock/core-js/releases/tag/v0.5.1) +- Some fixes + +### [0.5.0 - 2015.02.08](https://github.com/zloirock/core-js/releases/tag/v0.5.0) +- Systematization of modules +- Split [`es6` module](https://github.com/zloirock/core-js/#ecmascript-6) +- Split `console` module: `web.console` - only cap for missing methods, `core.log` - bound methods & additional features +- Added [`delay` method](https://github.com/zloirock/core-js/#delay) +- Some fixes + +### [0.4.10 - 2015.01.28](https://github.com/zloirock/core-js/releases/tag/v0.4.10) +- [`Object.getOwnPropertySymbols`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) polyfill returns array of wrapped keys + +### [0.4.9 - 2015.01.27](https://github.com/zloirock/core-js/releases/tag/v0.4.9) +- FF20-24 fix + +### [0.4.8 - 2015.01.25](https://github.com/zloirock/core-js/releases/tag/v0.4.8) +- Some [collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) fixes + +### [0.4.7 - 2015.01.25](https://github.com/zloirock/core-js/releases/tag/v0.4.7) +- Added support frozen objects as [collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) keys + +### [0.4.6 - 2015.01.21](https://github.com/zloirock/core-js/releases/tag/v0.4.6) +- Added [`Object.getOwnPropertySymbols`](https://github.com/zloirock/core-js/#ecmascript-6-symbol) +- Added [`NodeList.prototype[@@iterator]`](https://github.com/zloirock/core-js/#ecmascript-6-iterators) +- Added basic `@@species` logic - getter in native constructors +- Removed `Function#by` +- Some fixes + +### [0.4.5 - 2015.01.16](https://github.com/zloirock/core-js/releases/tag/v0.4.5) +- Some fixes + +### [0.4.4 - 2015.01.11](https://github.com/zloirock/core-js/releases/tag/v0.4.4) +- Enabled CSP support + +### [0.4.3 - 2015.01.10](https://github.com/zloirock/core-js/releases/tag/v0.4.3) +- Added `Function` instances `name` property for IE9+ + +### [0.4.2 - 2015.01.10](https://github.com/zloirock/core-js/releases/tag/v0.4.2) +- `Object` static methods accept primitives +- `RegExp` constructor can alter flags (IE9+) +- Added `Array.prototype[Symbol.unscopables]` + +### [0.4.1 - 2015.01.05](https://github.com/zloirock/core-js/releases/tag/v0.4.1) +- Some fixes + +### [0.4.0 - 2015.01.03](https://github.com/zloirock/core-js/releases/tag/v0.4.0) +- Added [`es6.reflect`](https://github.com/zloirock/core-js/#ecmascript-6-reflect) module: + - Added `Reflect.apply` + - Added `Reflect.construct` + - Added `Reflect.defineProperty` + - Added `Reflect.deleteProperty` + - Added `Reflect.enumerate` + - Added `Reflect.get` + - Added `Reflect.getOwnPropertyDescriptor` + - Added `Reflect.getPrototypeOf` + - Added `Reflect.has` + - Added `Reflect.isExtensible` + - Added `Reflect.preventExtensions` + - Added `Reflect.set` + - Added `Reflect.setPrototypeOf` +- `core-js` methods now can use external `Symbol.iterator` polyfill +- Some fixes + +### [0.3.3 - 2014.12.28](https://github.com/zloirock/core-js/releases/tag/v0.3.3) +- [Console cap](https://github.com/zloirock/core-js/#console) excluded from node.js default builds + +### [0.3.2 - 2014.12.25](https://github.com/zloirock/core-js/releases/tag/v0.3.2) +- Added cap for [ES5](https://github.com/zloirock/core-js/#ecmascript-5) freeze-family methods +- Fixed `console` bug + +### [0.3.1 - 2014.12.23](https://github.com/zloirock/core-js/releases/tag/v0.3.1) +- Some fixes + +### [0.3.0 - 2014.12.23](https://github.com/zloirock/core-js/releases/tag/v0.3.0) +- Optimize [`Map` & `Set`](https://github.com/zloirock/core-js/#ecmascript-6-collections): + - Use entries chain on hash table + - Fast & correct iteration + - Iterators moved to [`es6`](https://github.com/zloirock/core-js/#ecmascript-6) and [`es6.collections`](https://github.com/zloirock/core-js/#ecmascript-6-collections) modules + +### [0.2.5 - 2014.12.20](https://github.com/zloirock/core-js/releases/tag/v0.2.5) +- `console` no longer shortcut for `console.log` (compatibility problems) +- Some fixes + +### [0.2.4 - 2014.12.17](https://github.com/zloirock/core-js/releases/tag/v0.2.4) +- Better compliance of ES6 +- Added [`Math.fround`](https://github.com/zloirock/core-js/#ecmascript-6-math) (IE10+) +- Some fixes + +### [0.2.3 - 2014.12.15](https://github.com/zloirock/core-js/releases/tag/v0.2.3) +- [Symbols](https://github.com/zloirock/core-js/#ecmascript-6-symbol): + - Added option to disable addition setter to `Object.prototype` for Symbol polyfill: + - Added `Symbol.useSimple` + - Added `Symbol.useSetter` + - Added cap for well-known Symbols: + - Added `Symbol.hasInstance` + - Added `Symbol.isConcatSpreadable` + - Added `Symbol.match` + - Added `Symbol.replace` + - Added `Symbol.search` + - Added `Symbol.species` + - Added `Symbol.split` + - Added `Symbol.toPrimitive` + - Added `Symbol.unscopables` + +### [0.2.2 - 2014.12.13](https://github.com/zloirock/core-js/releases/tag/v0.2.2) +- Added [`RegExp#flags`](https://github.com/zloirock/core-js/#ecmascript-6-regexp) ([December 2014 Draft Rev 29](https://web.archive.org/web/20170119181824/http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts)) +- Added [`String.raw`](https://github.com/zloirock/core-js/#ecmascript-6-string) + +### [0.2.1 - 2014.12.12](https://github.com/zloirock/core-js/releases/tag/v0.2.1) +- Repair converting -0 to +0 in [native collections](https://github.com/zloirock/core-js/#ecmascript-6-collections) + +### [0.2.0 - 2014.12.06](https://github.com/zloirock/core-js/releases/tag/v0.2.0) +- Added [`es7.proposals`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) and [`es7.abstract-refs`](https://github.com/zenparsing/es-abstract-refs) modules +- Added [`String#at`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) +- Added real [`String Iterator`](https://github.com/zloirock/core-js/#ecmascript-6-iterators), older versions used Array Iterator +- Added abstract references support: + - Added `Symbol.referenceGet` + - Added `Symbol.referenceSet` + - Added `Symbol.referenceDelete` + - Added `Function#@@referenceGet` + - Added `Map#@@referenceGet` + - Added `Map#@@referenceSet` + - Added `Map#@@referenceDelete` + - Added `WeakMap#@@referenceGet` + - Added `WeakMap#@@referenceSet` + - Added `WeakMap#@@referenceDelete` + - Added `Dict.{...methods}[@@referenceGet]` +- Removed deprecated `.contains` methods +- Some fixes + +### [0.1.5 - 2014.12.01](https://github.com/zloirock/core-js/releases/tag/v0.1.5) +- Added [`Array#copyWithin`](https://github.com/zloirock/core-js/#ecmascript-6-array) +- Added [`String#codePointAt`](https://github.com/zloirock/core-js/#ecmascript-6-string) +- Added [`String.fromCodePoint`](https://github.com/zloirock/core-js/#ecmascript-6-string) + +### [0.1.4 - 2014.11.27](https://github.com/zloirock/core-js/releases/tag/v0.1.4) +- Added [`Dict.mapPairs`](https://github.com/zloirock/core-js/#dict) + +### [0.1.3 - 2014.11.20](https://github.com/zloirock/core-js/releases/tag/v0.1.3) +- [TC39 November meeting](https://github.com/tc39/notes/blob/main/meetings/2014-11): + - [`.contains` -> `.includes`](https://github.com/tc39/notes/blob/main/meetings/2014-11/nov-18.md#51--44-arrayprototypecontains-and-stringprototypecontains) + - `String#contains` -> [`String#includes`](https://github.com/zloirock/core-js/#ecmascript-6-string) + - `Array#contains` -> [`Array#includes`](https://github.com/zloirock/core-js/#ecmascript-7-proposals) + - `Dict.contains` -> [`Dict.includes`](https://github.com/zloirock/core-js/#dict) + - [Removed `WeakMap#clear`](https://github.com/tc39/notes/blob/main/meetings/2014-11/nov-19.md#412-should-weakmapweakset-have-a-clear-method-markm) + - [Removed `WeakSet#clear`](https://github.com/tc39/notes/blob/main/meetings/2014-11/nov-19.md#412-should-weakmapweakset-have-a-clear-method-markm) + +### [0.1.2 - 2014.11.19](https://github.com/zloirock/core-js/releases/tag/v0.1.2) +- `Map` & `Set` bug fix + +### [0.1.1 - 2014.11.18](https://github.com/zloirock/core-js/releases/tag/v0.1.1) +- Public release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a586555c6720..54cb87c56d9a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,91 +1,140 @@ # Contributing -Contributions are always welcome. If you don't know what how you can help, you can check [issues](https://github.com/zloirock/core-js/issues) or ask @zloirock. +Contributions are always welcome. Feel free to ask [**@zloirock**](https://github.com/zloirock) if you have some questions. + +## I want to help with code, but I don't know how + +There is always some ["help wanted" issues](https://github.com/zloirock/core-js/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22help+wanted%22). You can look at them first. Sure, other help is also required - you could ask [**@zloirock**](https://github.com/zloirock) about it or open issues if you have some ideas. ## How to add a new polyfill - The polyfill implementation should be added to the [`packages/core-js/modules`](./packages/core-js/modules) directory. -- Any shared helpers should be added to the [`packages/core-js/internals`](./packages/core-js/internals) directory. -- If the implementation for the `pure` version differs from the global version, add it to [`packages/core-js-pure/override`](./packages/core-js-pure/override) directory. The rest parts of `core-js-pure` will be copied from `core-js` package. -- For export the polyfill, in almost all cases use `internals/export` helper. -- Add feature detection of the polyfill to [`tests/compat/tests.js`](./tests/compat/tests.js) and compatibility data to [`packages/core-js-compat/src/data.js`](./packages/core-js-compat/src/data.js) and [`packages/core-js-compat/src/modules-by-versions.js`](./packages/core-js-compat/src/modules-by-versions.js) (this data also used for getting default list of polyfills at bundling). -- Add it to entry points where it's required: directories [`packages/core-js/features`](./packages/core-js/features), [`packages/core-js/es`](./packages/core-js/es), [`packages/core-js/proposals`](./packages/core-js/proposals), [`packages/core-js/stage`](./packages/core-js/stage) and [`packages/core-js/web`](./packages/core-js/web). -- Add unit tests to [`tests/tests`](./tests/tests) and [`tests/pure`](./tests/pure). -- Add tests of entry points to [`tests/commonjs.js`](./tests/commonjs). -- Add documentation to [README.md](./README.md). +- The polyfill should properly work in ES3 and all possible engines. If in some engines it cannot be implemented (for example, it strictly requires more modern ES or unavailable platform features), it should not break any other `core-js` features or application in any way. +- Avoid possible observing / breakage polyfills via patching built-ins at runtime: cache all global built-ins in the polyfills code and don't call prototype methods from instances. +- Shared helpers should be added to the [`packages/core-js/internals`](./packages/core-js/internals) directory. Reuse already existing helpers. +- Avoid direct import from `/modules/` path in `/internals|modules/` since it will break optimizations via Babel / `swc`. Specify such dependencies in `/es|stable|actual/full/` entries and use something like [`internals/get-built-in`](./packages/core-js/internals/get-built-in.js) helpers. +- For export the polyfill, in all common cases use [`internals/export`](./packages/core-js/modules/export.js) helper. Use something else only if this helper is not applicable - for example, if you want to polyfill accessors. +- If the code of the pure version implementation should significantly differ from the global version (*that's not a frequent situation, in most cases [`internals/is-pure`](./packages/core-js/modules/is-pure.js) constant is enough*), you can add it to [`packages/core-js-pure/override`](./packages/core-js-pure/override) directory. The rest parts of `core-js-pure` will be copied from `core-js` package. +- Add the feature detection of the polyfill to [`tests/compat/tests.js`](./tests/compat/tests.js), add the compatibility data to [`packages/core-js-compat/src/data.mjs`](./packages/core-js-compat/src/data.mjs), how to do it [see below](#how-to-update-core-js-compat-data), and the name of the polyfill module to [`packages/core-js-compat/src/modules-by-versions.mjs`](./packages/core-js-compat/src/modules-by-versions.mjs) (this data is also used for getting the default list of polyfills at bundling and generation indexes). +- Add it to entry points where it's required: directories [`packages/core-js/es`](./packages/core-js/es), [`packages/core-js/stable`](./packages/core-js/stable), [`packages/core-js/actual`](./packages/core-js/actual), [`packages/core-js/full`](./packages/core-js/full), [`packages/core-js/proposals`](./packages/core-js/proposals), [`packages/core-js/stage`](./packages/core-js/stage) and [`packages/core-js/web`](./packages/core-js/web). +- Add unit tests to [`tests/unit-global`](./tests/unit-global) and [`tests/unit-pure`](./tests/unit-pure). +- Add tests of entry points to [`tests/entries/unit.mjs`](./tests/entries/unit.mjs). +- Make sure that you are following [our coding style](#style-and-standards) and [all tests](#testing) are passed. +- Document it in [site documentation](./docs/web/docs/) and [CHANGELOG.md](./CHANGELOG.md). + +[A simple example of adding a new polyfill.](https://github.com/zloirock/core-js/pull/1294/files) + +## How to update `core-js-compat` data + +For updating `core-js-compat` data: + +- If you want to add a new data for a browser, run in this browser `tests/compat/index.html` (tests and results for the actual release are available at [`http://zloirock.github.io/core-js/compat/`](http://zloirock.github.io/core-js/compat/)) and you will see what `core-js` modules are required for this browser. + +![compat-table](https://user-images.githubusercontent.com/2213682/217452234-ccdcfc5a-c7d3-40d1-ab3f-86902315b8c3.png) + +- If you want to add new data for NodeJS, run `npm run compat-node` with the installed required NodeJS version and you will see the results in the console. Use `npm run compat-node json` if you want to get the result as JSON. +- If you want to add new data for Deno, run `npm run compat-deno` with the installed required Deno version and you will see the results in the console. Use `npm run compat-deno json` if you want to get the result as JSON. +- If you want to add new data for Bun, run `npm run compat-bun` with the installed required Bun version and you will see the results in the console. +- If you want to add new data for Rhino, set the required Rhino version in `compat-rhino` NPM script in [`package.json`](./package.json), run `npm run compat-rhino` and you will see the results in the console. +- If you want to add new data for Hermes (incl. shipped with React Native), run `npm run compat-hermes YOUR_PATH_TO_HERMES` and you will see the results in the console. +- After getting this data, add it to [`packages/core-js-compat/src/data.mjs`](./packages/core-js-compat/src/data.mjs). +- If you want to add new mapping (for example, to add a new iOS Safari version based on Safari or NodeJS based on Chrome), add it to [`packages/core-js-compat/src/mapping.mjs`](./packages/core-js-compat/src/mapping.mjs). + +engine | how to run tests | base data inherits from | mandatory check | mapping for a new version +--- | --- | --- | --- | --- +`android` | browser runner | `chrome`, `chrome-android` | | +`bun` | bun runner | `safari` (only ES) | required | +`chrome` | browser runner | | required | +`chrome-android` | browser runner | `chrome` | | +`deno` | deno runner | `chrome` (only ES) | non-ES features | required +`edge` | browser runner | `ie`, `chrome` | required (<= 18) | +`electron` | browser runner | `chrome` | | required +`firefox` | browser runner | | required | +`firefox-android` | browser runner | `firefox` | | +`hermes` | hermes runner | | required | +`ie` | browser runner | | required | +`ios` | browser runner | `safari` | | if inconsistent (!= `safari`) +`node` | node runner | `chrome` (only ES) | non-ES features | required +`opera` | browser runner | `chrome` | | if inconsistent (!= `chrome` - 16) +`opera-android` | browser runner | `opera`, `chrome-android` | | required +`phantom` | browser runner | `safari` | | +`quest` | browser runner | `chrome-android` | | required +`react-native` | hermes runner | `hermes` | required | +`rhino` | rhino runner | | required | +`safari` | browser runner | | required | +`samsung` | browser runner | `chrome-android` | | required + +If you have no access to all required browsers / versions of browsers, use [Sauce Labs](https://saucelabs.com/), [BrowserStack](https://www.browserstack.com/) or [Cloud Browser](https://ieonchrome.com/). ## Style and standards -Coding style should follow our [`.eslintrc`](./.eslintrc.js). You can test it by calling [`npm run lint`](#testing). Different places have different syntax and standard library limitations: -- Polyfill implementations should use only ES3 syntax and standard library. Polyfills should not use another polyfill from the global namespace. -- In unit tests should be used modern syntax with our [minimalistic Babel config](./.babelrc). Unit tests for the `pure` version should not use any modern standard library features. -- In building tools and tests, performed in Node.js, should be used only available in Node.js 4 syntax and standard library. +The coding style should follow our [`eslint.config.js`](./tests/eslint/eslint.config.js). You can test it by calling [`npm run lint`](#testing). Different places have different syntax and standard library limitations: +- Polyfill implementations should use only ES3 syntax and standard library, they should not use other polyfills from the global scope. +- Unit tests should use the modern syntax with our [minimalistic Babel config](./babel.config.js). Unit tests for the pure version should not use any modern standard library features. +- Tools, scripts and tests, performed in NodeJS, should use only the syntax and the standard library available in NodeJS 8. -File names should be in kebab-case. Name of files with polyfills should follow naming convention `namespace.subnamespase-where-required.feature-name`, for example, `esnext.promise.try`. Top level namespace could be `es` for stable ECMAScript features, `esnext` for ECMAScript proposals, `web` for another web standards and `core` for helpers. +File names should be in the kebab-case. Name of polyfill modules should follow the naming convention `namespace.subnamespace-where-required.feature-name`, for example, `esnext.set.intersection`. The top-level namespace should be `es` for stable ECMAScript features, `esnext` for ECMAScript proposals and `web` for other web standards. ## Testing -Before testing, you should install dependencies: -``` -$ npm i -``` -You can run all tests by +Before testing, you should prepare monorepo and install dependencies: +```sh +npm run prepare-monorepo ``` -$ npm run test +You can run the most tests by +```sh +npm t ``` You can run parts of the test case separately: - Linting: -``` -$ npm run lint -``` -- Global version unit tests: -``` -$ npm run unit-tests -``` -- `pure` version unit tests: -``` -$ npm run unit-tests-pure -``` -- [Promises/A+ test case](https://github.com/promises-aplus/promises-tests): -``` -$ npm run promises-tests -``` + ```sh + npm run lint + ``` +- Unit test case in Karma (modern Chromium, Firefox, WebKit (Playwright), ancient WebKit (PhantomJS), IE11 (if available)): + ```sh + npx run-s prepare bundle test-unit-karma + ``` +- Unit test case in NodeJS: + ```sh + npx run-s prepare bundle test-unit-node + ``` +- Unit test case in Bun: + ```sh + npx run-s prepare bundle test-unit-bun + ``` +- [Test262](https://github.com/tc39/test262) test case (it's not included to the default tests): + ```sh + npx run-s prepare bundle-package test262 + ``` +- [Promises/A+](https://github.com/promises-aplus/promises-tests) and [ES6 `Promise`](https://github.com/promises-es6/promises-es6) test cases: + ```sh + npx run-s prepare test-promises + ``` - [ECMAScript `Observable` test case](https://github.com/tc39/proposal-observable): -``` -$ npm run observables-tests -``` + ```sh + npx run-s prepare test-observables + ``` - CommonJS entry points tests: -``` -$ npm run commonjs-tests -``` -If you want to run tests in a certain browser at first you should build packages and test bundles: -``` -$ npm run build -``` -- For running global version unit test case use this file: -``` -tests/tests.html -``` -- For running the `pure` version unit test case use this file: -``` -tests/pure.html -``` -- Before running [Promises/A+ test case](https://github.com/promises-aplus/promises-tests) in the browser you should bundle it: -``` -$ npm run bundle-promises-tests -``` -and after that use this file: -``` -tests/promises-aplus.html -``` - -## Updating `core-js-compat` data - -For updating `core-js-compat` data: - -- Clone `core-js` repo. -- If you wanna add new data for a browser, run in this browser `tests/compat/index.html` and you will see which `core-js` modules required for this browser. -- If you wanna add new data for Node.js, run `tests/compat/node-runner.js` in required Node.js version and you will see results in the console. -- After getting this data, add it to [`packages/core-js-compat/src/data.js`](./packages/core-js-compat/src/data.js). -- If you wanna add new mapping (for example, add a new iOS Safari version based on Safari or Node.js based on Chrome), add it to [`packages/core-js-compat/src/mapping.js`](./packages/core-js-compat/src/mapping.js). -- Add a pull request to `core-js` repo. + ```sh + npx run-s prepare test-entries + ``` +- `core-js-compat` tools tests: + ```sh + npx run-s prepare test-compat-tools + ``` +- `core-js-builder` tests: + ```sh + npx run-s prepare test-builder + ``` +- If you want to run tests in a certain browser, at first, you should build packages and test bundles: + ```sh + npx run-s prepare bundle + ``` +- For running the global version of the unit test case, use this file: + ```sh + tests/unit-browser/global.html + ``` +- For running the pure version of the unit test case, use this file: + ```sh + tests/unit-browser/pure.html + ``` diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index daae32c1c6a8..000000000000 --- a/Gruntfile.js +++ /dev/null @@ -1,179 +0,0 @@ -/* eslint-disable unicorn/filename-case */ -'use strict'; -const webpack = require('./.webpack.config.js'); -const { banner } = require('./packages/core-js-builder/config'); - -process.env.CHROME_BIN = require('puppeteer').executablePath(); - -module.exports = grunt => { - grunt.loadNpmTasks('grunt-contrib-clean'); - grunt.loadNpmTasks('grunt-contrib-copy'); - grunt.loadNpmTasks('grunt-contrib-uglify'); - grunt.loadNpmTasks('grunt-karma'); - grunt.loadNpmTasks('grunt-webpack'); - grunt.initConfig({ - pkg: grunt.file.readJSON('./package.json'), - uglify: { - build: { - files: { - './packages/core-js-bundle/minified.js': './packages/core-js-bundle/index.js', - }, - options: { - mangle: { - keep_fnames: true, - }, - compress: { - keep_fnames: true, - pure_getters: true, - }, - output: { - max_line_len: 32000, - }, - ie8: true, - sourceMap: true, - banner, - }, - }, - }, - clean: { - 'core-js': [ - './packages/core-js/LICENSE', - ], - 'core-js-pure': [ - './packages/core-js-pure/*', - '!./packages/core-js-pure/override', - '!./packages/core-js-pure/.npmignore', - '!./packages/core-js-pure/package.json', - '!./packages/core-js-pure/README.md', - ], - 'core-js-builder': [ - './packages/core-js-builder/LICENSE', - ], - 'core-js-bundle': [ - './packages/core-js-bundle/scripts', - './packages/core-js-bundle/LICENSE', - ], - 'core-js-compat': [ - './packages/core-js-compat/data.json', - './packages/core-js-compat/LICENSE', - ], - tests: [ - './tests/bundles/*', - ], - }, - copy: { - 'core-js': { - files: [ - { - expand: true, - src: ['LICENSE'], - dest: './packages/core-js/', - }, - ], - }, - 'core-js-pure': { - files: [ - { - expand: true, - src: ['LICENSE'], - dest: './packages/core-js-pure/', - }, { - expand: true, - cwd: './packages/core-js/', - src: [ - 'es/**', - 'features/**', - 'internals/**', - 'modules/**', - 'proposals/**', - 'stable/**', - 'stage/**', - 'web/**', - 'index.js', - 'configurator.js', - 'postinstall.js', - ], - dest: './packages/core-js-pure/', - }, { - expand: true, - cwd: './packages/core-js-pure/override/', - src: '**', - dest: './packages/core-js-pure', - }, - ], - }, - 'core-js-builder': { - files: [ - { - expand: true, - src: ['LICENSE'], - dest: './packages/core-js-builder/', - }, - ], - }, - 'core-js-bundle': { - files: [ - { - expand: true, - src: ['LICENSE'], - dest: './packages/core-js-bundle/', - }, { - expand: true, - cwd: './packages/core-js/', - src: ['postinstall.js'], - dest: './packages/core-js-bundle/', - }, - ], - }, - 'core-js-compat': { - files: [ - { - expand: true, - src: ['LICENSE'], - dest: './packages/core-js-compat/', - }, - ], - }, - }, - karma: { - options: { - frameworks: ['qunit'], - basePath: '.', - browsers: ['HeadlessChrome', 'PhantomJS'], - customLaunchers: { - HeadlessChrome: { - base: 'ChromeHeadless', - flags: ['--no-sandbox', '--disable-setuid-sandbox'], - }, - }, - singleRun: true, - }, - tests: { - files: [ - 'tests/bundles/qunit-helpers.js', - 'packages/core-js-bundle/index.js', - 'tests/bundles/tests.js', - ].map(src => ({ src })), - }, - pure: { - files: [ - 'tests/bundles/qunit-helpers.js', - 'tests/bundles/pure.js', - ].map(src => ({ src })), - }, - }, - webpack, - }); - grunt.registerTask('bundle', function () { - // some dependencies of this module generated in grunt tasks, so we should load it here - // eslint-disable-next-line global-require - const builder = require('./packages/core-js-builder'); - const done = this.async(); - - builder({ filename: './packages/core-js-bundle/index.js' }).then(done).catch(error => { - // eslint-disable-next-line no-console - console.error(error); - process.exit(1); - }); - }); -}; diff --git a/LICENSE b/LICENSE index 834b267db78d..5cc1d065c701 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2019 Denis Pushkarev +Copyright (c) 2014-2025 Denis Pushkarev, 2025 CoreJS Company Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index f0f4329f7a56..63529be9465f 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,24 @@ -# core-js +![logo](https://user-images.githubusercontent.com/2213682/146607186-8e13ddef-26a4-4ebf-befd-5aac9d77c090.png) -[![Sponsors on Open Collective](https://opencollective.com/core-js/sponsors/badge.svg)](#raising-funds) [![Backers on Open Collective](https://opencollective.com/core-js/backers/badge.svg)](#raising-funds) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/zloirock/core-js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![version](https://img.shields.io/npm/v/core-js.svg)](https://www.npmjs.com/package/core-js) [![npm downloads](https://img.shields.io/npm/dm/core-js.svg)](https://npm-stat.com/charts.html?package=core-js&package=core-js-pure&package=core-js-compat&from=2014-11-18) [![Build Status](https://travis-ci.org/zloirock/core-js.svg)](https://travis-ci.org/zloirock/core-js) [![devDependency status](https://david-dm.org/zloirock/core-js/dev-status.svg)](https://david-dm.org/zloirock/core-js?type=dev) +
-> Modular standard library for JavaScript. Includes polyfills for [ECMAScript up to 2019](#ecmascript): [promises](#ecmascript-promise), [symbols](#ecmascript-symbol), [collections](#ecmascript-collections), iterators, [typed arrays](#ecmascript-typed-arrays), many other features, [ECMAScript proposals](#ecmascript-proposals), [some cross-platform WHATWG / W3C features and proposals](#web-standards) like [`URL`](#url-and-urlsearchparams). You can load only required features or use it without global namespace pollution. +[![fundraising](https://opencollective.com/core-js/all/badge.svg?label=fundraising)](https://opencollective.com/core-js) [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/zloirock/core-js/blob/master/CONTRIBUTING.md) [![version](https://img.shields.io/npm/v/core-js.svg)](https://www.npmjs.com/package/core-js) [![core-js downloads](https://img.shields.io/npm/dm/core-js.svg?label=npm%20i%20core-js)](https://npm-stat.com/charts.html?package=core-js&package=core-js-pure&package=core-js-compat&from=2014-11-18) [![core-js-pure downloads](https://img.shields.io/npm/dm/core-js-pure.svg?label=npm%20i%20core-js-pure)](https://npm-stat.com/charts.html?package=core-js&package=core-js-pure&package=core-js-compat&from=2014-11-18) -**If you looking documentation for obsolete `core-js@2`, please, check [this branch](https://github.com/zloirock/core-js/tree/v2).** +
-## As advertising: the author is looking for a good job -) +**Welcome to our new website, [core-js.io](https://core-js.io/), where our documentation is moving!** +--- + +**I highly recommend reading this: [So, what's next?](https://core-js.io/blog/2023-02-14-so-whats-next)** +--- + +> Modular standard library for JavaScript. Includes polyfills for [ECMAScript up to 2025](#ecmascript): [promises](#ecmascript-promise), [symbols](#ecmascript-symbol), [collections](#ecmascript-collections), iterators, [typed arrays](#ecmascript-typed-arrays), many other features, [ECMAScript proposals](#ecmascript-proposals), [some cross-platform WHATWG / W3C features and proposals](#web-standards) like [`URL`](#url-and-urlsearchparams). You can load only required features or use it without global namespace pollution. -## [core-js@3, babel and a look into the future](https://github.com/zloirock/core-js/tree/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md) +## [core-js@3, babel and a look into the future](https://core-js.io/blog/2019-03-19-core-js-3-babel-and-a-look-into-the-future) ## Raising funds -`core-js` isn't backed by a company, so the future of this project depends on you. Become a sponsor or a backer [**on Open Collective**](https://opencollective.com/core-js), [**on Patreon**](https://www.patreon.com/zloirock) or [**on Tidelift**](https://tidelift.com/subscription/pkg/npm-core-js?utm_source=npm-core-js&utm_medium=referral&utm_campaign=readme) if you are interested in `core-js`. +`core-js` isn't backed by a company, so the future of this project depends on you. Become a sponsor or a backer if you are interested in `core-js`: [**Open Collective**](https://opencollective.com/core-js), [**Patreon**](https://patreon.com/zloirock), [**Boosty**](https://boosty.to/zloirock), **Bitcoin ( bc1qlea7544qtsmj2rayg0lthvza9fau63ux0fstcz )**, [**Alipay**](https://user-images.githubusercontent.com/2213682/219464783-c17ad329-17ce-4795-82a7-f609493345ed.png). --- @@ -24,38 +30,71 @@ --- - -[*Example*](http://goo.gl/a2xexl): +[*Example of usage*](https://tinyurl.com/28zqjbun): ```js -import 'core-js'; // <- at the top of your entry point +import 'core-js/actual'; + +Promise.try(() => 42).then(it => console.log(it)); // => 42 + +Array.from(new Set([1, 2, 3]).union(new Set([3, 4, 5]))); // => [1, 2, 3, 4, 5] + +[1, 2].flatMap(it => [it, it]); // => [1, 1, 2, 2] -Array.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] -[1, [2, 3], [4, [5]]].flat(2); // => [1, 2, 3, 4, 5] -Promise.resolve(32).then(x => console.log(x)); // => 32 +Iterator.concat([1, 2], function * (i) { while (true) yield i++; }(3)) + .drop(1).take(5) + .filter(it => it % 2) + .map(it => it ** 2) + .toArray(); // => [9, 25] + +structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3]) ``` *You can load only required features*: ```js -import 'core-js/features/array/from'; // <- at the top of your entry point -import 'core-js/features/array/flat'; // <- at the top of your entry point -import 'core-js/features/set'; // <- at the top of your entry point -import 'core-js/features/promise'; // <- at the top of your entry point +import 'core-js/actual/promise'; +import 'core-js/actual/set'; +import 'core-js/actual/iterator'; +import 'core-js/actual/array/from'; +import 'core-js/actual/array/flat-map'; +import 'core-js/actual/structured-clone'; + +Promise.try(() => 42).then(it => console.log(it)); // => 42 + +Array.from(new Set([1, 2, 3]).union(new Set([3, 4, 5]))); // => [1, 2, 3, 4, 5] + +[1, 2].flatMap(it => [it, it]); // => [1, 1, 2, 2] + +Iterator.concat([1, 2], function * (i) { while (true) yield i++; }(3)) + .drop(1).take(5) + .filter(it => it % 2) + .map(it => it ** 2) + .toArray(); // => [9, 25] -Array.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] -[1, [2, 3], [4, [5]]].flat(2); // => [1, 2, 3, 4, 5] -Promise.resolve(32).then(x => console.log(x)); // => 32 +structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3]) ``` *Or use it without global namespace pollution*: ```js -import from from 'core-js-pure/features/array/from'; -import flat from 'core-js-pure/features/array/flat'; -import Set from 'core-js-pure/features/set'; -import Promise from 'core-js-pure/features/promise'; +import Promise from 'core-js-pure/actual/promise'; +import Set from 'core-js-pure/actual/set'; +import Iterator from 'core-js-pure/actual/iterator'; +import from from 'core-js-pure/actual/array/from'; +import flatMap from 'core-js-pure/actual/array/flat-map'; +import structuredClone from 'core-js-pure/actual/structured-clone'; + +Promise.try(() => 42).then(it => console.log(it)); // => 42 + +from(new Set([1, 2, 3]).union(new Set([3, 4, 5]))); // => [1, 2, 3, 4, 5] + +flatMap([1, 2], it => [it, it]); // => [1, 1, 2, 2] + +Iterator.concat([1, 2], function * (i) { while (true) yield i++; }(3)) + .drop(1).take(5) + .filter(it => it % 2) + .map(it => it ** 2) + .toArray(); // => [9, 25] -from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] -flat([1, [2, 3], [4, [5]]], 2); // => [1, 2, 3, 4, 5] -Promise.resolve(32).then(x => console.log(x)); // => 32 +structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3]) ``` ### Index @@ -67,15 +106,17 @@ Promise.resolve(32).then(x => console.log(x)); // => 32 - [`@babel/polyfill`](#babelpolyfill) - [`@babel/preset-env`](#babelpreset-env) - [`@babel/runtime`](#babelruntime) + - [swc](#swc) - [Configurable level of aggressiveness](#configurable-level-of-aggressiveness) - [Custom build](#custom-build) - - [Compatibility data](#compatibility-data) -- [Supported engines](#supported-engines) +- [Supported engines and compatibility data](#supported-engines-and-compatibility-data) - [Features](#features) - [ECMAScript](#ecmascript) - [ECMAScript: Object](#ecmascript-object) - [ECMAScript: Function](#ecmascript-function) + - [ECMAScript: Error](#ecmascript-error) - [ECMAScript: Array](#ecmascript-array) + - [ECMAScript: Iterator](#ecmascript-iterator) - [ECMAScript: String and RegExp](#ecmascript-string-and-regexp) - [ECMAScript: Number](#ecmascript-number) - [ECMAScript: Math](#ecmascript-math) @@ -83,20 +124,91 @@ Promise.resolve(32).then(x => console.log(x)); // => 32 - [ECMAScript: Promise](#ecmascript-promise) - [ECMAScript: Symbol](#ecmascript-symbol) - [ECMAScript: Collections](#ecmascript-collections) + - [ECMAScript: Explicit Resource Management](#ecmascript-explicit-resource-management) - [ECMAScript: Typed Arrays](#ecmascript-typed-arrays) - [ECMAScript: Reflect](#ecmascript-reflect) + - [ECMAScript: JSON](#ecmascript-json) + - [ECMAScript: globalThis](#ecmascript-globalthis) - [ECMAScript proposals](#ecmascript-proposals) - - [stage 4 proposals](#stage-4-proposals) - - [stage 3 proposals](#stage-3-proposals) - - [stage 2 proposals](#stage-2-proposals) - - [stage 1 proposals](#stage-1-proposals) - - [stage 0 proposals](#stage-0-proposals) - - [pre-stage 0 proposals](#pre-stage-0-proposals) + - [Finished proposals](#finished-proposals) + - [`globalThis`](#globalthis) + - [Relative indexing method](#relative-indexing-method) + - [`Array.prototype.includes`](#arrayprototypeincludes) + - [`Array.prototype.flat` / `Array.prototype.flatMap`](#arrayprototypeflat--arrayprototypeflatmap) + - [`Array` find from last](#array-find-from-last) + - [Change `Array` by copy](#change-array-by-copy) + - [`Array` grouping](#array-grouping) + - [`Array.fromAsync`](#arrayfromasync) + - [`ArrayBuffer.prototype.transfer` and friends](#arraybufferprototypetransfer-and-friends) + - [`Uint8Array` to / from base64 and hex](#uint8array-to--from-base64-and-hex) + - [`Error.isError`](#erroriserror) + - [Explicit Resource Management](#explicit-resource-management) + - [`Float16` methods](#float16-methods) + - [`Iterator` helpers](#iterator-helpers) + - [`Iterator` sequencing](#iterator-sequencing) + - [`Object.values` / `Object.entries`](#objectvalues--objectentries) + - [`Object.fromEntries`](#objectfromentries) + - [`Object.getOwnPropertyDescriptors`](#objectgetownpropertydescriptors) + - [Accessible `Object.prototype.hasOwnProperty`](#accessible-objectprototypehasownproperty) + - [`String` padding](#string-padding) + - [`String.prototype.matchAll`](#stringmatchall) + - [`String.prototype.replaceAll`](#stringreplaceall) + - [`String.prototype.trimStart` / `String.prototype.trimEnd`](#stringprototypetrimstart-stringprototypetrimend) + - [`RegExp` `s` (`dotAll`) flag](#regexp-s-dotall-flag) + - [`RegExp` named capture groups](#regexp-named-capture-groups) + - [`RegExp` escaping](#regexp-escaping) + - [`Promise.allSettled`](#promiseallsettled) + - [`Promise.any`](#promiseany) + - [`Promise.prototype.finally`](#promiseprototypefinally) + - [`Promise.try`](#promisetry) + - [`Promise.withResolvers`](#promisewithresolvers) + - [`Symbol.asyncIterator` for asynchronous iteration](#symbolasynciterator-for-asynchronous-iteration) + - [`Symbol.prototype.description`](#symbolprototypedescription) + - [`JSON.parse` source text access](#jsonparse-source-text-access) + - [Well-formed `JSON.stringify`](#well-formed-jsonstringify) + - [Well-formed unicode strings](#well-formed-unicode-strings) + - [New `Set` methods](#new-set-methods) + - [`Math.sumPrecise`](#mathsumprecise) + - [Stage 3 proposals](#stage-3-proposals) + - [Joint iteration](#joint-iteration) + - [`Map` upsert](#map-upsert) + - [`Symbol.metadata` for decorators metadata proposal](#symbolmetadata-for-decorators-metadata-proposal) + - [Stage 2.7 proposals](#stage-27-proposals) + - [`Iterator` chunking](#iterator-chunking) + - [Stage 2 proposals](#stage-2-proposals) + - [`AsyncIterator` helpers](#asynciterator-helpers) + - [`Iterator.range`](#iteratorrange) + - [`Array.isTemplateObject`](#arrayistemplateobject) + - [`Number.prototype.clamp`](#numberprototypeclamp) + - [`String.dedent`](#stringdedent) + - [`Symbol` predicates](#symbol-predicates) + - [`Symbol.customMatcher` for extractors](#symbolcustommatcher-for-extractors) + - [Stage 1 proposals](#stage-1-proposals) + - [`Observable`](#observable) + - [New collections methods](#new-collections-methods) + - [`.of` and `.from` methods on collection constructors](#of-and-from-methods-on-collection-constructors) + - [`compositeKey` and `compositeSymbol`](#compositekey-and-compositesymbol) + - [`Array` filtering](#array-filtering) + - [`Array` deduplication](#array-deduplication) + - [`DataView` get / set `Uint8Clamped` methods](#dataview-get-set-iint8clamped-methods) + - [`Number.fromString`](#numberfromstring) + - [`String.cooked`](#stringcooked) + - [`String.prototype.codePoints`](#stringprototypecodepoints) + - [`Symbol.customMatcher` for pattern matching](#symbolcustommatcher-for-pattern-matching) + - [Stage 0 proposals](#stage-0-proposals) + - [`Function.prototype.demethodize`](#functionprototypedemethodize) + - [`Function.{ isCallable, isConstructor }`](#function-iscallable-isconstructor-) + - [Pre-stage 0 proposals](#pre-stage-0-proposals) + - [`Reflect` metadata](#reflect-metadata) - [Web standards](#web-standards) + - [`self`](#self) + - [`structuredClone`](#structuredclone) + - [Base64 utility methods](#base64-utility-methods) - [`setTimeout` and `setInterval`](#settimeout-and-setinterval) - [`setImmediate`](#setimmediate) - [`queueMicrotask`](#queuemicrotask) - [`URL` and `URLSearchParams`](#url-and-urlsearchparams) + - [`DOMException`](#domexception) - [iterable DOM collections](#iterable-dom-collections) - [Iteration helpers](#iteration-helpers) - [Missing polyfills](#missing-polyfills) @@ -104,22 +216,20 @@ Promise.resolve(32).then(x => console.log(x)); // => 32 - [Security policy](https://github.com/zloirock/core-js/blob/master/SECURITY.md) - [Changelog](./CHANGELOG.md) -## Usage -### Installation: -``` +## Usage[⬆](#index) +### Installation:[⬆](#index) +```sh // global version -npm install --save core-js@3.3.4 +npm install --save core-js@3.47.0 // version without global namespace pollution -npm install --save core-js-pure@3.3.4 +npm install --save core-js-pure@3.47.0 // bundled global version -npm install --save core-js-bundle@3.3.4 +npm install --save core-js-bundle@3.47.0 ``` -Already bundled version of `core-js` [on CDN](https://unpkg.com/core-js-bundle@3.3.4) ([minified version](https://unpkg.com/core-js-bundle@3.3.4/minified.js)). - -### `postinstall` message +### `postinstall` message[⬆](#index) The `core-js` project needs your help, so the package shows a message about it after installation. If it causes problems for you, you can disable it: -``` +```sh ADBLOCK=true npm install // or DISABLE_OPENCOLLECTIVE=true npm install @@ -127,81 +237,95 @@ DISABLE_OPENCOLLECTIVE=true npm install npm install --loglevel silent ``` -### CommonJS API -You can import only-required-for-you polyfills, like in examples at the top of `README.md`. Available CommonJS entry points for all polyfilled methods / constructors and namespaces. Just some examples: +### CommonJS API[⬆](#index) +You can import only-required-for-you polyfills, like in the examples at the top of `README.md`. Available CommonJS entry points for all polyfilled methods / constructors and namespaces. Just some examples: -```js -// polyfill all `core-js` features: +```ts +// polyfill all `core-js` features, including early-stage proposals: import "core-js"; -// polyfill only stable `core-js` features - ES and web standards: +// or: +import "core-js/full"; +// polyfill all actual features - stable ES, web standards and stage 3 ES proposals: +import "core-js/actual"; +// polyfill only stable features - ES and web standards: import "core-js/stable"; // polyfill only stable ES features: import "core-js/es"; // if you want to polyfill `Set`: -// all `Set`-related features, with ES proposals: -import "core-js/features/set"; +// all `Set`-related features, with early-stage ES proposals: +import "core-js/full/set"; +// stable required for `Set` ES features, features from web standards and stage 3 ES proposals: +import "core-js/actual/set"; // stable required for `Set` ES features and features from web standards // (DOM collections iterator in this case): import "core-js/stable/set"; // only stable ES features required for `Set`: import "core-js/es/set"; // the same without global namespace pollution: -import Set from "core-js-pure/features/set"; +import Set from "core-js-pure/full/set"; +import Set from "core-js-pure/actual/set"; import Set from "core-js-pure/stable/set"; import Set from "core-js-pure/es/set"; -// if you want to polyfill just required methods: -import "core-js/features/set/intersection"; +// if you want to polyfill just the required methods: +import "core-js/full/set/intersection"; +import "core-js/actual/array/find-last"; import "core-js/stable/queue-microtask"; import "core-js/es/array/from"; -// polyfill reflect metadata proposal: -import "core-js/proposals/reflect-metadata"; +// polyfill iterator helpers proposal: +import "core-js/proposals/iterator-helpers"; // polyfill all stage 2+ proposals: import "core-js/stage/2"; ``` -##### Caveats when using CommonJS API: +> [!TIP] +> The usage of the `/actual/` namespace is recommended since it includes all actual JavaScript features and does not include unstable early-stage proposals that are available mainly for experiments. -* `modules` path is an internal API, does not inject all required dependencies and can be changed in minor or patch releases. Use it only for a custom build and/or if you know what are you doing. -* If you use `core-js` with the extension of native objects, recommended load all `core-js` modules at the top of the entry point of your application, otherwise, you can have conflicts. -* `core-js` is extremely modular and uses a lot of very tiny modules, because of that for usage in browsers bundle up `core-js` instead of usage loader for each file, otherwise, you will have hundreds of requests. +> [!WARNING] +> - The `modules` path is an internal API, does not inject all required dependencies and can be changed in minor or patch releases. Use it only for a custom build and/or if you know what are you doing. +> - If you use `core-js` with the extension of native objects, recommended to load all `core-js` modules at the top of the entry point of your application, otherwise, you can have conflicts. +> - For example, Google Maps use their own `Symbol.iterator`, conflicting with `Array.from`, `URLSearchParams` and / or something else from `core-js`, see [related issues](https://github.com/zloirock/core-js/search?q=Google+Maps&type=Issues). +> - Such conflicts are also resolvable by discovering and manually adding each conflicting entry from `core-js`. +> - `core-js` is extremely modular and uses a lot of very tiny modules, because of that for usage in browsers bundle up `core-js` instead of a usage loader for each file, otherwise, you will have hundreds of requests. -#### CommonJS and prototype methods without global namespace pollution +#### CommonJS and prototype methods without global namespace pollution[⬆](#index) In the `pure` version, we can't pollute prototypes of native constructors. Because of that, prototype methods transformed into static methods like in examples above. But with transpilers, we can use one more trick - [bind operator and virtual methods](https://github.com/tc39/proposal-bind-operator). Special for that, available `/virtual/` entry points. Example: -```js -import fill from 'core-js-pure/features/array/virtual/fill'; -import findIndex from 'core-js-pure/features/array/virtual/find-index'; - -Array(10)::fill(0).map((a, b) => b * b)::findIndex(it => it && !(it % 8)); // => 4 - -// or - -import { fill, findIndex } from 'core-js-pure/features/array/virtual'; +```ts +import fill from 'core-js-pure/actual/array/virtual/fill'; +import findIndex from 'core-js-pure/actual/array/virtual/find-index'; Array(10)::fill(0).map((a, b) => b * b)::findIndex(it => it && !(it % 8)); // => 4 ``` -### Babel +> [!WARNING] +> The bind operator is an early-stage ECMAScript proposal and usage of this syntax can be dangerous. + +### Babel[⬆](#index) `core-js` is integrated with `babel` and is the base for polyfilling-related `babel` features: -#### `@babel/polyfill` +#### `@babel/polyfill`[⬆](#index) -[`@babel/polyfill`](http://babeljs.io/docs/usage/polyfill) [**IS** just the import of stable `core-js` features and `regenerator-runtime`](https://github.com/babel/babel/blob/c8bb4500326700e7dc68ce8c4b90b6482c48d82f/packages/babel-polyfill/src/index.js) for generators and async functions, so if you load `@babel/polyfill` - you load the global version of `core-js` without ES proposals. +[`@babel/polyfill`](https://babeljs.io/docs/usage/polyfill) [**IS** just the import of stable `core-js` features and `regenerator-runtime`](https://github.com/babel/babel/blob/c8bb4500326700e7dc68ce8c4b90b6482c48d82f/packages/babel-polyfill/src/index.js) for generators and async functions, so loading `@babel/polyfill` means loading the global version of `core-js` without ES proposals. -Now it's deprecated in favour of separate inclusion of required parts of `core-js` and `regenerator-runtime` and, for preventing breaking changes, left on `core-js@2`. +Now it's deprecated in favor of separate inclusion of required parts of `core-js` and `regenerator-runtime` and, for backward compatibility, `@babel/polyfill` is still based on `core-js@2`. -As a full equal of `@babel/polyfill`, you can use this: +As a full equal of `@babel/polyfill`, you can use the following: ```js import 'core-js/stable'; import 'regenerator-runtime/runtime'; ``` -#### `@babel/preset-env` +#### `@babel/preset-env`[⬆](#index) + +[`@babel/preset-env`](https://github.com/babel/babel/tree/master/packages/babel-preset-env) has `useBuiltIns` option, which optimizes the use of the global version of `core-js`. With `useBuiltIns` option, you should also set `corejs` option to the used version of `core-js`, like `corejs: '3.47'`. -[`@babel/preset-env`](https://github.com/babel/babel/tree/master/packages/babel-preset-env) has `useBuiltIns` option, which optimizes working with global version of `core-js`. With `useBuiltIns` option, you should also set `corejs` option to used version of `core-js`, like `corejs: 3` or `corejs: '3.3'`. +> [!IMPORTANT] +> It is recommended to specify the used minor `core-js` version, like `corejs: '3.47'`, instead of `corejs: 3`, since with `corejs: 3` will not be injected modules which were added in minor `core-js` releases. + +--- - `useBuiltIns: 'entry'` replaces imports of `core-js` to import only required for a target environment modules. So, for example, ```js @@ -209,58 +333,65 @@ import 'core-js/stable'; ``` with `chrome 71` target will be replaced just to: ```js -import "core-js/modules/es.array.unscopables.flat"; -import "core-js/modules/es.array.unscopables.flat-map"; -import "core-js/modules/es.object.from-entries"; -import "core-js/modules/web.immediate"; +import 'core-js/modules/es.array.unscopables.flat'; +import 'core-js/modules/es.array.unscopables.flat-map'; +import 'core-js/modules/es.object.from-entries'; +import 'core-js/modules/web.immediate'; ``` It works for all entry points of global version of `core-js` and their combinations, for example for ```js import 'core-js/es'; import 'core-js/proposals/set-methods'; -import 'core-js/features/set/map'; +import 'core-js/full/set/map'; ``` -with `chrome 71` target you will have as a result: +with `chrome 71` target you will have as the result: ```js -import "core-js/modules/es.array.unscopables.flat"; -import "core-js/modules/es.array.unscopables.flat-map"; -import "core-js/modules/es.object.from-entries"; -import "core-js/modules/esnext.set.difference"; -import "core-js/modules/esnext.set.intersection"; -import "core-js/modules/esnext.set.is-disjoint-from"; -import "core-js/modules/esnext.set.is-subset-of"; -import "core-js/modules/esnext.set.is-superset-of"; -import "core-js/modules/esnext.set.map"; -import "core-js/modules/esnext.set.symmetric-difference"; -import "core-js/modules/esnext.set.union"; +import 'core-js/modules/es.array.unscopables.flat'; +import 'core-js/modules/es.array.unscopables.flat-map'; +import 'core-js/modules/es.object.from-entries'; +import 'core-js/modules/esnext.set.difference'; +import 'core-js/modules/esnext.set.intersection'; +import 'core-js/modules/esnext.set.is-disjoint-from'; +import 'core-js/modules/esnext.set.is-subset-of'; +import 'core-js/modules/esnext.set.is-superset-of'; +import 'core-js/modules/esnext.set.map'; +import 'core-js/modules/esnext.set.symmetric-difference'; +import 'core-js/modules/esnext.set.union'; ``` - `useBuiltIns: 'usage'` adds to the top of each file import of polyfills for features used in this file and not supported by target environments, so for: ```js // first file: -var set = new Set([1, 2, 3]); - +let set = new Set([1, 2, 3]); +``` +```js // second file: -var array = Array.of(1, 2, 3); +let array = Array.of(1, 2, 3); ``` -if target contains an old environment like `IE 11` we will have something like: +if the target contains an old environment like `IE 11` we will have something like: ```js // first file: import 'core-js/modules/es.array.iterator'; import 'core-js/modules/es.object.to-string'; import 'core-js/modules/es.set'; -var set = new Set([1, 2, 3]); +var set = new Set([1, 2, 3]); +``` +```js // second file: import 'core-js/modules/es.array.of'; + var array = Array.of(1, 2, 3); ``` -By default, `@babel/preset-env` with `useBuiltIns: 'usage'` option only polyfills stable features, but you can enable polyfilling of proposals by `proposals` option, as `corejs: { version: '3.3', proposals: true }`. +By default, `@babel/preset-env` with `useBuiltIns: 'usage'` option only polyfills stable features, but you can enable polyfilling of proposals by the `proposals` option, as `corejs: { version: '3.47', proposals: true }`. -#### `@babel/runtime` +> [!IMPORTANT] +> In the case of `useBuiltIns: 'usage'`, you should not add `core-js` imports by yourself, they will be added automatically. -[`@babel/runtime`](http://babeljs.io/docs/plugins/transform-runtime/) with `corejs: 3` option simplifies work with `core-js-pure`. It automatically replaces usage of modern features from JS standard library to imports from the version of `core-js` without global namespace pollution, so instead of: +#### `@babel/runtime`[⬆](#index) + +[`@babel/runtime`](https://babeljs.io/docs/plugins/transform-runtime/) with `corejs: 3` option simplifies work with the `core-js-pure`. It automatically replaces the usage of modern features from the JS standard library to imports from the version of `core-js` without global namespace pollution, so instead of: ```js import from from 'core-js-pure/stable/array/from'; import flat from 'core-js-pure/stable/array/flat'; @@ -280,79 +411,82 @@ Promise.resolve(32).then(x => console.log(x)); By default, `@babel/runtime` only polyfills stable features, but like in `@babel/preset-env`, you can enable polyfilling of proposals by `proposals` option, as `corejs: { version: 3, proposals: true }`. -**Warning!** If you use `@babel/preset-env` and `@babel/runtime` together, use `corejs` option only in one place since it's duplicate functionality and will cause conflicts. +> [!WARNING] +> If you use `@babel/preset-env` and `@babel/runtime` together, use `corejs` option only in one place since it's duplicate functionality and will cause conflicts. + +### swc[⬆](#index) + +Fast JavaScript transpiler `swc` [contains integration with `core-js`](https://swc.rs/docs/configuration/supported-browsers), that optimizes work with the global version of `core-js`. [Like `@babel/preset-env`](#babelpreset-env), it has 2 modes: `usage` and `entry`, but `usage` mode still works not so well as in `babel`. Example of configuration in `.swcrc`: +```json +{ + "env": { + "targets": "> 0.25%, not dead", + "mode": "entry", + "coreJs": "3.47" + } +} +``` -### Configurable level of aggressiveness +### Configurable level of aggressiveness[⬆](#index) -By default, `core-js` sets polyfills only when they are required. That means that `core-js` checks if a feature is available and works correctly or not and if it has no problems, `core-js` use native implementation. +By default, `core-js` sets polyfills only when they are required. That means that `core-js` checks if a feature is available and works correctly or not and if it has no problems, `core-js` uses native implementation. But sometimes `core-js` feature detection could be too strict for your case. For example, `Promise` constructor requires the support of unhandled rejection tracking and `@@species`. -Sometimes we could have inverse problem - knowingly broken environment with problems not covered by `core-js` feature detection. +Sometimes we could have an inverse problem - a knowingly broken environment with problems not covered by `core-js` feature detection. -For those cases, we could redefine this behaviour for certain polyfills: +For those cases, we could redefine this behavior for certain polyfills: ```js const configurator = require('core-js/configurator'); configurator({ - useNative: ['Promise'], // polyfills will be used only if natives completely unavailable + useNative: ['Promise'], // polyfills will be used only if natives are completely unavailable usePolyfill: ['Array.from', 'String.prototype.padEnd'], // polyfills will be used anyway - useFeatureDetection: ['Map', 'Set'], // default behaviour + useFeatureDetection: ['Map', 'Set'], // default behavior }); -require('core-js'); +require('core-js/actual'); ``` -It does not work with some features. Also, if you change the default behaviour, even `core-js` internals may not work correctly. +It does not work with some features. Also, if you change the default behavior, even `core-js` internals may not work correctly. -### Custom build +### Custom build[⬆](#index) -For some cases could be useful adding a blacklist of features or generation a polyfill for target engines. You could use [`core-js-builder`](/packages/core-js-builder) package for that. +For some cases could be useful to exclude some `core-js` features or generate a polyfill for target engines. You could use [`core-js-builder`](/packages/core-js-builder) package for that. -### Compatibility data +## Supported engines and compatibility data[⬆](#index) -[`core-js-compat`](/packages/core-js-compat) package contains data about the necessity of `core-js` modules and API for getting a list of required `core-js` modules by `browserslist` query. +`core-js` tries to support all possible JS engines and environments with ES3 support. Some features have a higher lower bar - for example, *some* accessors can properly work only from ES5, promises require a way to set a microtask or a task, etc. -## Supported engines -**Tested in:** -- Chrome 26+ -- Firefox 4+ -- Safari 5+ -- Opera 12+ -- Internet Explorer 8+ (sure, IE8 with ES3 limitations; IE7- also should work, but no longer tested) -- Edge -- Android Browser 2.3+ -- iOS Safari 5.1+ -- PhantomJS 1.9+ -- NodeJS 0.8+ +However, I have no possibility to test `core-js` absolutely everywhere - for example, testing in IE7- and some other ancient was stopped. The list of definitely supported engines you can see in the compatibility table by the link below. [Write](https://github.com/zloirock/core-js/issues) if you have issues or questions with the support of any engine. -...and it doesn't mean `core-js` will not work in other engines, they just have not been tested. +`core-js` project provides (as [`core-js-compat`](/packages/core-js-compat) package) all required data about the necessity of `core-js` modules, entry points, and tools for work with it - it's useful for integration with tools like `babel` or `swc`. If you wanna help, you could take a look at the related section of [`CONTRIBUTING.md`](/CONTRIBUTING.md#how-to-update-core-js-compat-data). The visualization of compatibility data and the browser tests runner is available [here](http://zloirock.github.io/core-js/master/compat/), the example: -## Features: +![compat-table](https://user-images.githubusercontent.com/2213682/217452234-ccdcfc5a-c7d3-40d1-ab3f-86902315b8c3.png) + +## Features:[⬆](#index) [*CommonJS entry points:*](#commonjs-api) ``` core-js(-pure) ``` -### ECMAScript +### ECMAScript[⬆](#index) [*CommonJS entry points:*](#commonjs-api) ``` core-js(-pure)/es ``` -#### ECMAScript: Object -Modules [`es.object.assign`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.assign.js), [`es.object.is`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.is.js), [`es.object.set-prototype-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.set-prototype-of.js), [`es.object.to-string`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.to-string.js), [`es.object.freeze`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.freeze.js), [`es.object.seal`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.seal.js), [`es.object.prevent-extensions`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.prevent-extensions.js), [`es.object.is-frozen`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.is-frozen.js), [`es.object.is-sealed`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.is-sealed.js), [`es.object.is-extensible`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.is-extensible.js), [`es.object.get-own-property-descriptor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.get-own-property-descriptor.js), [`es.object.get-own-property-descriptors`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.get-own-property-descriptors.js), [`es.object.get-prototype-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.get-prototype-of.js), [`es.object.keys`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.keys.js), [`es.object.values`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.values.js), [`es.object.entries`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.entries.js), [`es.object.get-own-property-names`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.get-own-property-names.js) and [`es.object.from-entries`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.from-entries.js). - -Just ES5 features: [`es.object.create`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.create.js), [`es.object.define-property`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.define-property.js) and [`es.object.define-properties`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.es.object.define-properties.js). +#### ECMAScript: Object[⬆](#index) +Modules [`es.object.assign`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.assign.js), [`es.object.create`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.create.js), [`es.object.define-getter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.define-getter.js), [`es.object.define-property`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.define-property.js), [`es.object.define-properties`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.define-properties.js), [`es.object.define-setter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.define-setter.js), [`es.object.entries`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.entries.js), [`es.object.freeze`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.freeze.js), [`es.object.from-entries`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.from-entries.js), [`es.object.get-own-property-descriptor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.get-own-property-descriptor.js), [`es.object.get-own-property-descriptors`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.get-own-property-descriptors.js), [`es.object.get-own-property-names`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.get-own-property-names.js), [`es.object.get-prototype-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.get-prototype-of.js), [`es.object.group-by`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.group-by.js), [`es.object.has-own`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.has-own.js), [`es.object.is`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.is.js), [`es.object.is-extensible`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.is-extensible.js), [`es.object.is-frozen`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.is-frozen.js), [`es.object.is-sealed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.is-sealed.js), [`es.object.keys`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.keys.js), [`es.object.lookup-setter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.lookup-setter.js), [`es.object.lookup-getter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.lookup-getter.js), [`es.object.prevent-extensions`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.prevent-extensions.js), [`es.object.proto`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.proto.js), [`es.object.to-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.to-string.js), [`es.object.seal`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.seal.js), [`es.object.set-prototype-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.set-prototype-of.js), [`es.object.values`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.object.values.js). -[ES2017 Annex B](https://tc39.github.io/ecma262/#sec-object.prototype.__defineGetter__) - modules [`es.object.define-setter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.define-setter.js), [`es.object.define-getter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.define-getter.js), [`es.object.lookup-setter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.lookup-setter.js) and [`es.object.lookup-getter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.object.lookup-getter.js) -```js +```ts class Object { toString(): string; // ES2015+ fix: @@toStringTag support __defineGetter__(property: PropertyKey, getter: Function): void; __defineSetter__(property: PropertyKey, setter: Function): void; __lookupGetter__(property: PropertyKey): Function | void; __lookupSetter__(property: PropertyKey): Function | void; + __proto__: Object | null; // required a way setting of prototype - will not in IE10-, it's for modern engines like Deno static assign(target: Object, ...sources: Array): Object; static create(prototype: Object | null, properties?: { [property: PropertyKey]: PropertyDescriptor }): Object; static defineProperties(object: Object, properties: { [property: PropertyKey]: PropertyDescriptor })): Object; @@ -364,6 +498,8 @@ class Object { static getOwnPropertyDescriptors(object: any): { [property: PropertyKey]: PropertyDescriptor }; static getOwnPropertyNames(object: any): Array; static getPrototypeOf(object: any): Object | null; + static groupBy(items: Iterable, callbackfn: (value: any, index: number) => key): { [key]: Array }; + static hasOwn(object: object, key: PropertyKey): boolean; static is(value1: any, value2: any): boolean; static isExtensible(object: any): boolean; static isFrozen(object: any): boolean; @@ -377,34 +513,37 @@ class Object { ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/object -core-js(-pure)/es|stable|features/object/assign -core-js(-pure)/es|stable|features/object/is -core-js(-pure)/es|stable|features/object/set-prototype-of -core-js(-pure)/es|stable|features/object/get-prototype-of -core-js(-pure)/es|stable|features/object/create -core-js(-pure)/es|stable|features/object/define-property -core-js(-pure)/es|stable|features/object/define-properties -core-js(-pure)/es|stable|features/object/get-own-property-descriptor -core-js(-pure)/es|stable|features/object/get-own-property-descriptors -core-js(-pure)/es|stable|features/object/keys -core-js(-pure)/es|stable|features/object/values -core-js(-pure)/es|stable|features/object/entries -core-js(-pure)/es|stable|features/object/get-own-property-names -core-js(-pure)/es|stable|features/object/freeze -core-js(-pure)/es|stable|features/object/from-entries -core-js(-pure)/es|stable|features/object/seal -core-js(-pure)/es|stable|features/object/prevent-extensions -core-js(-pure)/es|stable|features/object/is-frozen -core-js(-pure)/es|stable|features/object/is-sealed -core-js(-pure)/es|stable|features/object/is-extensible -core-js/es|stable|features/object/to-string -core-js(-pure)/es|stable|features/object/define-getter -core-js(-pure)/es|stable|features/object/define-setter -core-js(-pure)/es|stable|features/object/lookup-getter -core-js(-pure)/es|stable|features/object/lookup-setter -``` -[*Examples*](https://goo.gl/sqY5mD): +core-js(-pure)/es|stable|actual|full/object +core-js(-pure)/es|stable|actual|full/object/assign +core-js(-pure)/es|stable|actual|full/object/is +core-js(-pure)/es|stable|actual|full/object/set-prototype-of +core-js(-pure)/es|stable|actual|full/object/get-prototype-of +core-js(-pure)/es|stable|actual|full/object/create +core-js(-pure)/es|stable|actual|full/object/define-property +core-js(-pure)/es|stable|actual|full/object/define-properties +core-js(-pure)/es|stable|actual|full/object/get-own-property-descriptor +core-js(-pure)/es|stable|actual|full/object/get-own-property-descriptors +core-js(-pure)/es|stable|actual|full/object/group-by +core-js(-pure)/es|stable|actual|full/object/has-own +core-js(-pure)/es|stable|actual|full/object/keys +core-js(-pure)/es|stable|actual|full/object/values +core-js(-pure)/es|stable|actual|full/object/entries +core-js(-pure)/es|stable|actual|full/object/get-own-property-names +core-js(-pure)/es|stable|actual|full/object/freeze +core-js(-pure)/es|stable|actual|full/object/from-entries +core-js(-pure)/es|stable|actual|full/object/seal +core-js(-pure)/es|stable|actual|full/object/prevent-extensions +core-js/es|stable|actual|full/object/proto +core-js(-pure)/es|stable|actual|full/object/is-frozen +core-js(-pure)/es|stable|actual|full/object/is-sealed +core-js(-pure)/es|stable|actual|full/object/is-extensible +core-js/es|stable|actual|full/object/to-string +core-js(-pure)/es|stable|actual|full/object/define-getter +core-js(-pure)/es|stable|actual|full/object/define-setter +core-js(-pure)/es|stable|actual|full/object/lookup-getter +core-js(-pure)/es|stable|actual|full/object/lookup-setter +``` +*Examples*: ```js let foo = { q: 1, w: 2 }; let bar = { e: 3, r: 4 }; @@ -416,17 +555,15 @@ Object.is(0, -0); // => false Object.is(42, 42); // => true Object.is(42, '42'); // => false -function Parent() {} -function Child() {} +function Parent() { /* empty */ } +function Child() { /* empty */ } Object.setPrototypeOf(Child.prototype, Parent.prototype); new Child() instanceof Child; // => true new Child() instanceof Parent; // => true -let object = { - [Symbol.toStringTag]: 'Foo' -}; - -'' + object; // => '[object Foo]' +({ + [Symbol.toStringTag]: 'Foo', +}).toString(); // => '[object Foo]' Object.keys('qwe'); // => ['0', '1', '2'] Object.getPrototypeOf('qwe') === String.prototype; // => true @@ -459,10 +596,17 @@ class Unit { const units = new Set([new Unit(101), new Unit(102)]); Object.fromEntries(units.entries()); // => { unit101: Unit { id: 101 }, unit102: Unit { id: 102 } } + +Object.hasOwn({ foo: 42 }, 'foo'); // => true +Object.hasOwn({ foo: 42 }, 'bar'); // => false +Object.hasOwn({}, 'toString'); // => false + +Object.groupBy([1, 2, 3, 4, 5], it => it % 2); // => { 1: [1, 3, 5], 0: [2, 4] } ``` -#### ECMAScript: Function -Modules [`es.function.name`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.function.name.js), [`es.function.has-instance`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.function.has-instance.js). Just ES5: [`es.function.bind`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.function.bind.js). -```js + +#### ECMAScript: Function[⬆](#index) +Modules [`es.function.name`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.function.name.js), [`es.function.has-instance`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.function.has-instance.js). Just ES5: [`es.function.bind`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.function.bind.js). +```ts class Function { name: string; bind(thisArg: any, ...args: Array): Function; @@ -471,23 +615,99 @@ class Function { ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js/es|stable|features/function -core-js/es|stable|features/function/name -core-js/es|stable|features/function/has-instance -core-js/es|stable|features/function/bind -core-js/es|stable|features/function/virtual/bind +core-js/es|stable|actual|full/function +core-js/es|stable|actual|full/function/name +core-js/es|stable|actual|full/function/has-instance +core-js(-pure)/es|stable|actual|full/function/bind +core-js(-pure)/es|stable|actual|full/function/virtual/bind ``` -[*Example*](http://goo.gl/zqu3Wp): +[*Example*](https://tinyurl.com/22na9nbm): ```js -(function foo() {}).name // => 'foo' +(function foo() { /* empty */ }).name; // => 'foo' console.log.bind(console, 42)(43); // => 42 43 ``` -#### ECMAScript: Array -Modules [`es.array.from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.from.js), [`es.array.is-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.is-array.js), [`es.array.of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.of.js), [`es.array.copy-within`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.copy-within.js), [`es.array.fill`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.fill.js), [`es.array.find`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.find.js), [`es.array.find-index`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.find-index.js), [`es.array.iterator`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.iterator.js), [`es.array.includes`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.includes.js), [`es.array.slice`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.slice.js), [`es.array.join`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.join.js), [`es.array.index-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.index-of.js), [`es.array.last-index-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.last-index-of.js), [`es.array.every`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.every.js), [`es.array.some`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.some.js), [`es.array.for-each`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.for-each.js), [`es.array.map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.map.js), [`es.array.filter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.filter.js), [`es.array.reduce`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.reduce.js), [`es.array.reduce-right`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.reduce-right.js), [`es.array.reverse`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.reverse.js), [`es.array.sort`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.sort.js), [`es.array.flat`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.flat.js), [`es.array.flat-map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.flat-map.js), [`es.array.unscopables.flat`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.unscopables.flat.js) and [`es.array.unscopables.flat-map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array.unscopables.flat-map.js) +#### ECMAScript: Error[⬆](#index) +Modules [`es.aggregate-error`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.aggregate-error.js), [`es.aggregate-error.cause`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.aggregate-error.cause.js), [`es.error.cause`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.error.cause.js), [`es.error.is-error`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.error.is-error.js), [`es.suppressed-error.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.suppressed-error.constructor.js), [`es.error.to-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.error.to-string.js). +```ts +class Error { + static isError(value: any): boolean; + constructor(message: string, { cause: any }): %Error%; + toString(): string; // different fixes +} + +class [ + EvalError, + RangeError, + ReferenceError, + SyntaxError, + TypeError, + URIError, + WebAssembly.CompileError, + WebAssembly.LinkError, + WebAssembly.RuntimeError, +] extends Error { + constructor(message: string, { cause: any }): %Error%; +} + +class AggregateError extends Error { + constructor(errors: Iterable, message?: string, { cause: any }?): AggregateError; + errors: Array; + message: string; + cause: any; +} + +class SuppressedError extends Error { + constructor(error: any, suppressed: any, message?: string): SuppressedError; + error: any; + suppressed: any; + message: string; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/es|stable|actual|full/error +core-js/es|stable|actual|full/error/constructor +core-js(-pure)/es|stable|actual|full/error/is-error +core-js/es|stable|actual|full/error/to-string +core-js(-pure)/es|stable|actual|full/aggregate-error +core-js(-pure)/es|stable|actual|full/suppressed-error +``` +[*Example*](https://is.gd/1SufcH): +```js +const error1 = new TypeError('Error 1'); +const error2 = new TypeError('Error 2'); +const aggregate = new AggregateError([error1, error2], 'Collected errors'); +aggregate.errors[0] === error1; // => true +aggregate.errors[1] === error2; // => true + +const cause = new TypeError('Something wrong'); +const error = new TypeError('Here explained what`s wrong', { cause }); +error.cause === cause; // => true + +Error.prototype.toString.call({ message: 1, name: 2 }) === '2: 1'; // => true +``` + +[*Example*](https://tinyurl.com/23nauwoz): ```js +Error.isError(new Error('error')); // => true +Error.isError(new TypeError('error')); // => true +Error.isError(new DOMException('error')); // => true + +Error.isError(null); // => false +Error.isError({}); // => false +Error.isError(Object.create(Error.prototype)); // => false +``` + +> [!WARNING] +> We have no bulletproof way to polyfill this `Error.isError` / check if the object is an error, so it's an enough naive implementation. + +#### ECMAScript: Array[⬆](#index) +Modules [`es.array.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.from.js), [`es.array.from-async`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.from-async.js), [`es.array.is-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.is-array.js), [`es.array.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.of.js), [`es.array.copy-within`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.copy-within.js), [`es.array.fill`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.fill.js), [`es.array.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find.js), [`es.array.find-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-index.js), [`es.array.find-last`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last.js), [`es.array.find-last-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.find-last-index.js), [`es.array.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.iterator.js), [`es.array.includes`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.includes.js), [`es.array.push`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.push.js), [`es.array.slice`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.slice.js), [`es.array.join`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.join.js), [`es.array.unshift`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unshift.js), [`es.array.index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.index-of.js), [`es.array.last-index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.last-index-of.js), [`es.array.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.every.js), [`es.array.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.some.js), [`es.array.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.for-each.js), [`es.array.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.map.js), [`es.array.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.filter.js), [`es.array.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reduce.js), [`es.array.reduce-right`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reduce-right.js), [`es.array.reverse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.reverse.js), [`es.array.sort`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.sort.js), [`es.array.flat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.flat.js), [`es.array.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.flat-map.js), [`es.array.unscopables.flat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unscopables.flat.js), [`es.array.unscopables.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.unscopables.flat-map.js), [`es.array.at`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.at.js), [`es.array.to-reversed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-reversed.js), [`es.array.to-sorted`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-sorted.js), [`es.array.to-spliced`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.to-spliced.js), [`es.array.with`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array.with.js). +```ts class Array { + at(index: int): any; concat(...args: Array): Array; // with adding support of @@isConcatSpreadable and @@species copyWithin(target: number, start: number, end?: number): this; entries(): Iterator<[index, value]>; @@ -495,7 +715,9 @@ class Array { fill(value: any, start?: number, end?: number): this; filter(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): Array; // with adding support of @@species find(callbackfn: (value: any, index: number, target: any) => boolean), thisArg?: any): any; - findIndex(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): number; + findIndex(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): uint; + findLast(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): any; + findLastIndex(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): uint; flat(depthArg?: number = 1): Array; flatMap(mapFn: (value: any, index: number, target: any) => any, thisArg: any): Array; forEach(callbackfn: (value: any, index: number, target: any) => void, thisArg?: any): void; @@ -505,17 +727,24 @@ class Array { keys(): Iterator; lastIndexOf(searchElement: any, from?: number): number; map(mapFn: (value: any, index: number, target: any) => any, thisArg?: any): Array; // with adding support of @@species + push(...args: Array): uint; reduce(callbackfn: (memo: any, value: any, index: number, target: any) => any, initialValue?: any): any; reduceRight(callbackfn: (memo: any, value: any, index: number, target: any) => any, initialValue?: any): any; reverse(): this; // Safari 12.0 bug fix slice(start?: number, end?: number): Array; // with adding support of @@species splice(start?: number, deleteCount?: number, ...items: Array): Array; // with adding support of @@species some(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): boolean; - sort(comparefn?: (a: any, b: any) => number): this; + sort(comparefn?: (a: any, b: any) => number): this; // with modern behavior like stable sort + toReversed(): Array; + toSpliced(start?: number, deleteCount?: number, ...items: Array): Array; + toSorted(comparefn?: (a: any, b: any) => number): Array; + unshift(...args: Array): uint; values(): Iterator; + with(index: includes, value: any): Array; @@iterator(): Iterator; @@unscopables: { [newMethodNames: string]: true }; static from(items: Iterable | ArrayLike, mapFn?: (value: any, index: number) => any, thisArg?: any): Array; + static fromAsync(asyncItems: AsyncIterable | Iterable | ArrayLike, mapfn?: (value: any, index: number) => any, thisArg?: any): Array; static isArray(value: any): boolean; static of(...args: Array): Array; } @@ -526,69 +755,53 @@ class Arguments { ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/array -core-js(-pure)/es|stable|features/array/from -core-js(-pure)/es|stable|features/array/of -core-js(-pure)/es|stable|features/array/is-array -core-js(-pure)/es|stable|features/array/concat -core-js(-pure)/es|stable|features/array/entries -core-js(-pure)/es|stable|features/array/every -core-js(-pure)/es|stable|features/array/copy-within -core-js(-pure)/es|stable|features/array/fill -core-js(-pure)/es|stable|features/array/filter -core-js(-pure)/es|stable|features/array/find -core-js(-pure)/es|stable|features/array/find-index -core-js(-pure)/es|stable|features/array/flat -core-js(-pure)/es|stable|features/array/flat-map -core-js(-pure)/es|stable|features/array/for-each -core-js(-pure)/es|stable|features/array/includes -core-js(-pure)/es|stable|features/array/index-of -core-js(-pure)/es|stable|features/array/iterator -core-js(-pure)/es|stable|features/array/join -core-js(-pure)/es|stable|features/array/keys -core-js(-pure)/es|stable|features/array/last-index-of -core-js(-pure)/es|stable|features/array/map -core-js(-pure)/es|stable|features/array/reduce -core-js(-pure)/es|stable|features/array/reduce-right -core-js(-pure)/es|stable|features/array/reverse -core-js(-pure)/es|stable|features/array/slice -core-js(-pure)/es|stable|features/array/splice -core-js(-pure)/es|stable|features/array/some -core-js(-pure)/es|stable|features/array/sort -core-js(-pure)/es|stable|features/array/values -core-js(-pure)/es|stable|features/array/virtual/concat -core-js(-pure)/es|stable|features/array/virtual/copy-within -core-js(-pure)/es|stable|features/array/virtual/entries -core-js(-pure)/es|stable|features/array/virtual/every -core-js(-pure)/es|stable|features/array/virtual/fill -core-js(-pure)/es|stable|features/array/virtual/filter -core-js(-pure)/es|stable|features/array/virtual/find -core-js(-pure)/es|stable|features/array/virtual/find-index -core-js(-pure)/es|stable|features/array/virtual/flat -core-js(-pure)/es|stable|features/array/virtual/flat-map -core-js(-pure)/es|stable|features/array/virtual/for-each -core-js(-pure)/es|stable|features/array/virtual/includes -core-js(-pure)/es|stable|features/array/virtual/index-of -core-js(-pure)/es|stable|features/array/virtual/iterator -core-js(-pure)/es|stable|features/array/virtual/join -core-js(-pure)/es|stable|features/array/virtual/keys -core-js(-pure)/es|stable|features/array/virtual/last-index-of -core-js(-pure)/es|stable|features/array/virtual/map -core-js(-pure)/es|stable|features/array/virtual/reduce -core-js(-pure)/es|stable|features/array/virtual/reduce-right -core-js(-pure)/es|stable|features/array/virtual/reverse -core-js(-pure)/es|stable|features/array/virtual/slice -core-js(-pure)/es|stable|features/array/virtual/some -core-js(-pure)/es|stable|features/array/virtual/sort -core-js(-pure)/es|stable|features/array/virtual/splice -core-js(-pure)/es|stable|features/array/virtual/values -``` -[*Examples*](https://goo.gl/Tegvq4): +core-js(-pure)/es|stable|actual|full/array +core-js(-pure)/es|stable|actual|full/array/from +core-js(-pure)/es|stable|actual|full/array/from-async +core-js(-pure)/es|stable|actual|full/array/of +core-js(-pure)/es|stable|actual|full/array/is-array +core-js(-pure)/es|stable|actual|full/array(/virtual)/at +core-js(-pure)/es|stable|actual|full/array(/virtual)/concat +core-js(-pure)/es|stable|actual|full/array(/virtual)/copy-within +core-js(-pure)/es|stable|actual|full/array(/virtual)/entries +core-js(-pure)/es|stable|actual|full/array(/virtual)/every +core-js(-pure)/es|stable|actual|full/array(/virtual)/fill +core-js(-pure)/es|stable|actual|full/array(/virtual)/filter +core-js(-pure)/es|stable|actual|full/array(/virtual)/find +core-js(-pure)/es|stable|actual|full/array(/virtual)/find-index +core-js(-pure)/es|stable|actual|full/array(/virtual)/find-last +core-js(-pure)/es|stable|actual|full/array(/virtual)/find-last-index +core-js(-pure)/es|stable|actual|full/array(/virtual)/flat +core-js(-pure)/es|stable|actual|full/array(/virtual)/flat-map +core-js(-pure)/es|stable|actual|full/array(/virtual)/for-each +core-js(-pure)/es|stable|actual|full/array(/virtual)/includes +core-js(-pure)/es|stable|actual|full/array(/virtual)/index-of +core-js(-pure)/es|stable|actual|full/array(/virtual)/iterator +core-js(-pure)/es|stable|actual|full/array(/virtual)/join +core-js(-pure)/es|stable|actual|full/array(/virtual)/keys +core-js(-pure)/es|stable|actual|full/array(/virtual)/last-index-of +core-js(-pure)/es|stable|actual|full/array(/virtual)/map +core-js(-pure)/es|stable|actual|full/array(/virtual)/push +core-js(-pure)/es|stable|actual|full/array(/virtual)/reduce +core-js(-pure)/es|stable|actual|full/array(/virtual)/reduce-right +core-js(-pure)/es|stable|actual|full/array(/virtual)/reverse +core-js(-pure)/es|stable|actual|full/array(/virtual)/slice +core-js(-pure)/es|stable|actual|full/array(/virtual)/some +core-js(-pure)/es|stable|actual|full/array(/virtual)/sort +core-js(-pure)/es|stable|actual|full/array(/virtual)/splice +core-js(-pure)/es|stable|actual|full/array(/virtual)/to-reversed +core-js(-pure)/es|stable|actual|full/array(/virtual)/to-sorted +core-js(-pure)/es|stable|actual|full/array(/virtual)/to-spliced +core-js(-pure)/es|stable|actual|full/array(/virtual)/unshift +core-js(-pure)/es|stable|actual|full/array(/virtual)/values +core-js(-pure)/es|stable|actual|full/array(/virtual)/with +``` +[*Examples*](https://tinyurl.com/2oaa8x2x): ```js Array.from(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] Array.from({ 0: 1, 1: 2, 2: 3, length: 3 }); // => [1, 2, 3] Array.from('123', Number); // => [1, 2, 3] -Array.from('123', it => it * it); // => [1, 4, 9] +Array.from('123', it => it ** 2); // => [1, 4, 9] Array.of(1); // => [1] Array.of(1, 2, 3); // => [1, 2, 3] @@ -608,14 +821,13 @@ function isOdd(value) { } [4, 8, 15, 16, 23, 42].find(isOdd); // => 15 [4, 8, 15, 16, 23, 42].findIndex(isOdd); // => 2 -[4, 8, 15, 16, 23, 42].find(isNaN); // => undefined -[4, 8, 15, 16, 23, 42].findIndex(isNaN); // => -1 +[1, 2, 3, 4].findLast(isOdd); // => 3 +[1, 2, 3, 4].findLastIndex(isOdd); // => 2 Array(5).fill(42); // => [42, 42, 42, 42, 42] [1, 2, 3, 4, 5].copyWithin(0, 3); // => [4, 5, 3, 4, 5] - [1, 2, 3].includes(2); // => true [1, 2, 3].includes(4); // => false [1, 2, 3].includes(2, 2); // => false @@ -630,21 +842,106 @@ Array(1).includes(undefined); // => true [1, [2, [3, [4]]], 5].flat(3); // => [1, 2, 3, 4, 5] [{ a: 1, b: 2 }, { a: 3, b: 4 }, { a: 5, b: 6 }].flatMap(it => [it.a, it.b]); // => [1, 2, 3, 4, 5, 6] -``` -#### ECMAScript: String and RegExp -The main part of `String` features: modules [`es.string.from-code-point`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.from-code-point.js), [`es.string.raw`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.raw.js), [`es.string.iterator`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.iterator.js), [`es.string.split`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.split.js), [`es.string.code-point-at`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.code-point-at.js), [`es.string.ends-with`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.ends-with.js), [`es.string.includes`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.includes.js), [`es.string.repeat`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.repeat.js), [`es.string.pad-start`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.pad-start.js), [`es.string.pad-end`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.pad-end.js), [`es.string.starts-with`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.starts-with.js), [`es.string.trim`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.trim.js), [`es.string.trim-start`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.trim-start.js), [`es.string.trim-end`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.trim-end.js), [`es.string.match-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.match-all.js). +[1, 2, 3].at(1); // => 2 +[1, 2, 3].at(-1); // => 3 -Adding support of well-known [symbols](#ecmascript-symbol) `@@match`, `@@replace`, `@@search` and `@@split` and direct `.exec` calls to related `String` methods, modules [`es.string.match`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.match.js), [`es.string.replace`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.replace.js), [`es.string.search`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.search.js) and [`es.string.split`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.split.js). +const sequence = [1, 2, 3]; +sequence.toReversed(); // => [3, 2, 1] +sequence; // => [1, 2, 3] -Annex B HTML methods. Ugly, but it's also the part of the spec. Modules [`es.string.anchor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.anchor.js), [`es.string.big`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.big.js), [`es.string.blink`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.blink.js), [`es.string.bold`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.bold.js), [`es.string.fixed`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.fixed.js), [`es.string.fontcolor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.fontcolor.js), [`es.string.fontsize`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.fontsize.js), [`es.string.italics`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.italics.js), [`es.string.link`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.link.js), [`es.string.small`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.small.js), [`es.string.strike`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.strike.js), [`es.string.sub`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.sub.js) and [`es.string.sup`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.string.sup.js). +const initialArray = [1, 2, 3, 4]; +initialArray.toSpliced(1, 2, 5, 6, 7); // => [1, 5, 6, 7, 4] +initialArray; // => [1, 2, 3, 4] -`RegExp` features: modules [`es.regexp.constructor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.regexp.constructor.js) and [`es.regexp.flags`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.regexp.flags.js). +const outOfOrder = [3, 1, 2]; +outOfOrder.toSorted(); // => [1, 2, 3] +outOfOrder; // => [3, 1, 2] + +const correctionNeeded = [1, 1, 3]; +correctionNeeded.with(1, 2); // => [1, 2, 3] +correctionNeeded; // => [1, 1, 3] +``` + +[*`Array.fromAsync` example*](https://tinyurl.com/2bt9bhwn): +```js +await Array.fromAsync((async function * () { yield * [1, 2, 3]; })(), i => i ** 2); // => [1, 4, 9] +``` + +#### ECMAScript: Iterator[⬆](#index) +Modules [`es.iterator.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.constructor.js), [`es.iterator.concat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.concat.js), [`es.iterator.dispose`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.dispose.js), [`es.iterator.drop`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.drop.js), [`es.iterator.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.every.js), [`es.iterator.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.filter.js), [`es.iterator.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.find.js), [`es.iterator.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.flat-map.js), [`es.iterator.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.for-each.js), [`es.iterator.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.from.js), [`es.iterator.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.map.js), [`es.iterator.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.reduce.js), [`es.iterator.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.some.js), [`es.iterator.take`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.take.js), [`es.iterator.to-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.to-array.js) +```ts +class Iterator { + static concat(...items: Array): Iterator; + static from(iterable: Iterable | Iterator): Iterator; + drop(limit: uint): Iterator; + every(callbackfn: (value: any, counter: uint) => boolean): boolean; + filter(callbackfn: (value: any, counter: uint) => boolean): Iterator; + find(callbackfn: (value: any, counter: uint) => boolean)): any; + flatMap(callbackfn: (value: any, counter: uint) => Iterable | Iterator): Iterator; + forEach(callbackfn: (value: any, counter: uint) => void): void; + map(callbackfn: (value: any, counter: uint) => any): Iterator; + reduce(callbackfn: (memo: any, value: any, counter: uint) => any, initialValue: any): any; + some(callbackfn: (value: any, counter: uint) => boolean): boolean; + take(limit: uint): Iterator; + toArray(): Array; + @@dispose(): undefined; + @@toStringTag: 'Iterator' +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/es|stable|actual|full/iterator +core-js(-pure)/es|stable|actual|full/iterator/concat +core-js(-pure)/es|stable|actual|full/iterator/dispose +core-js(-pure)/es|stable|actual|full/iterator/drop +core-js(-pure)/es|stable|actual|full/iterator/every +core-js(-pure)/es|stable|actual|full/iterator/filter +core-js(-pure)/es|stable|actual|full/iterator/find +core-js(-pure)/es|stable|actual|full/iterator/flat-map +core-js(-pure)/es|stable|actual|full/iterator/for-each +core-js(-pure)/es|stable|actual|full/iterator/from +core-js(-pure)/es|stable|actual|full/iterator/map +core-js(-pure)/es|stable|actual|full/iterator/reduce +core-js(-pure)/es|stable|actual|full/iterator/some +core-js(-pure)/es|stable|actual|full/iterator/take +core-js(-pure)/es|stable|actual|full/iterator/to-array +``` +[Examples](https://tinyurl.com/24af2z7v): ```js +[1, 2, 3, 4, 5, 6, 7].values() + .drop(1) + .take(5) + .filter(it => it % 2) + .map(it => it ** 2) + .toArray(); // => [9, 25] + +Iterator.from({ + next: () => ({ done: Math.random() > 0.9, value: Math.random() * 10 | 0 }), +}).toArray(); // => [7, 6, 3, 0, 2, 8] + +Iterator.concat([0, 1].values(), [2, 3], function * () { + yield 4; + yield 5; +}()).toArray(); // => [0, 1, 2, 3, 4, 5] +``` + +> [!WARNING] +> - For preventing prototype pollution, in the `pure` version, new `%IteratorPrototype%` methods are not added to the real `%IteratorPrototype%`, they are available only on wrappers - instead of `[].values().map(fn)` use `Iterator.from([]).map(fn)`. + +#### ECMAScript: String and RegExp[⬆](#index) +The main part of `String` features: modules [`es.string.from-code-point`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.from-code-point.js), [`es.string.raw`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.raw.js), [`es.string.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.iterator.js), [`es.string.split`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.split.js), [`es.string.code-point-at`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.code-point-at.js), [`es.string.ends-with`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.ends-with.js), [`es.string.includes`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.includes.js), [`es.string.repeat`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.repeat.js), [`es.string.pad-start`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.pad-start.js), [`es.string.pad-end`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.pad-end.js), [`es.string.starts-with`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.starts-with.js), [`es.string.trim`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.trim.js), [`es.string.trim-start`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.trim-start.js), [`es.string.trim-end`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.trim-end.js), [`es.string.match-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.match-all.js), [`es.string.replace-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.replace-all.js), [`es.string.at-alternative`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.at-alternative.js), [`es.string.is-well-formed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.is-well-formed.js), [`es.string.to-well-formed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.to-well-formed.js). + +Adding support of well-known [symbols](#ecmascript-symbol) `@@match`, `@@replace`, `@@search` and `@@split` and direct `.exec` calls to related `String` methods, modules [`es.string.match`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.match.js), [`es.string.replace`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.replace.js), [`es.string.search`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.search.js) and [`es.string.split`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.split.js). + +Annex B methods. Modules [`es.string.anchor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.anchor.js), [`es.string.big`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.big.js), [`es.string.blink`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.blink.js), [`es.string.bold`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.bold.js), [`es.string.fixed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.fixed.js), [`es.string.fontcolor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.fontcolor.js), [`es.string.fontsize`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.fontsize.js), [`es.string.italics`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.italics.js), [`es.string.link`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.link.js), [`es.string.small`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.small.js), [`es.string.strike`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.strike.js), [`es.string.sub`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.sub.js), [`es.string.sup`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.sup.js), [`es.string.substr`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.string.substr.js), [`es.escape`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.escape.js) and [`es.unescape`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.unescape.js). + +`RegExp` features: modules [`es.regexp.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.regexp.constructor.js), [`es.regexp.escape`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.regexp.escape.js), [`es.regexp.dot-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.regexp.dot-all.js), [`es.regexp.flags`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.regexp.flags.js), [`es.regexp.sticky`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.regexp.sticky.js) and [`es.regexp.test`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.regexp.test.js). +```ts class String { static fromCodePoint(...codePoints: Array): string; static raw({ raw: Array }, ...substitutions: Array): string; - split(separator: string, limit?: number): Array; + at(index: int): string; includes(searchString: string, position?: number): boolean; startsWith(searchString: string, position?: number): boolean; endsWith(searchString: string, position?: number): boolean; @@ -655,13 +952,16 @@ class String { match(template: any): any; // ES2015+ fix for support @@match matchAll(regexp: RegExp): Iterator; replace(template: any, replacer: any): any; // ES2015+ fix for support @@replace + replaceAll(searchValue: string | RegExp, replaceString: string | (searchValue, index, this) => string): string; search(template: any): any; // ES2015+ fix for support @@search - split(template: any, limit: any): any; // ES2015+ fix for support @@split, some fixes for old engines + split(template: any, limit?: int): Array;; // ES2015+ fix for support @@split, some fixes for old engines trim(): string; trimLeft(): string; trimRight(): string; trimStart(): string; trimEnd(): string; + isWellFormed(): boolean; + toWellFormed(): string; anchor(name: string): string; big(): string; blink(): string; @@ -674,90 +974,84 @@ class String { small(): string; strike(): string; sub(): string; + substr(start: int, length?: int): string; sup(): string; @@iterator(): Iterator; } class RegExp { - constructor(pattern: RegExp | string, flags?: string): RegExp; // ES2015+ fix - can alter flags (IE9+) + // support of sticky (`y`) flag, dotAll (`s`) flag, named capture groups, can alter flags + constructor(pattern: RegExp | string, flags?: string): RegExp; + static escape(value: string): string exec(): Array | null; // IE8 fixes + test(string: string): boolean; // delegation to `.exec` toString(): string; // ES2015+ fix - generic @@match(string: string): Array | null; + @@matchAll(string: string): Iterator; @@replace(string: string, replaceValue: Function | string): string; @@search(string: string): number; @@split(string: string, limit: number): Array; - readonly attribute flags: string; // IE9+ -} -``` -[*CommonJS entry points:*](#commonjs-api) -``` -core-js(-pure)/es|stable|features/string -core-js(-pure)/es|stable|features/string/from-code-point -core-js(-pure)/es|stable|features/string/raw -core-js(-pure)/es|stable|features/string/code-point-at -core-js(-pure)/es|stable|features/string/ends-with -core-js(-pure)/es|stable|features/string/includes -core-js(-pure)/es|stable|features/string/starts-with -core-js/es|stable|features/string/match -core-js(-pure)/es|stable|features/string/match-all -core-js(-pure)/es|stable|features/string/repeat -core-js(-pure)/es|stable|features/string/pad-start -core-js(-pure)/es|stable|features/string/pad-end -core-js/es|stable|features/string/replace -core-js/es|stable|features/string/search -core-js/es|stable|features/string/split -core-js(-pure)/es|stable|features/string/trim -core-js(-pure)/es|stable|features/string/trim-start -core-js(-pure)/es|stable|features/string/trim-end -core-js(-pure)/es|stable|features/string/trim-left -core-js(-pure)/es|stable|features/string/trim-right -core-js(-pure)/es|stable|features/string/anchor -core-js(-pure)/es|stable|features/string/big -core-js(-pure)/es|stable|features/string/blink -core-js(-pure)/es|stable|features/string/bold -core-js(-pure)/es|stable|features/string/fixed -core-js(-pure)/es|stable|features/string/fontcolor -core-js(-pure)/es|stable|features/string/fontsize -core-js(-pure)/es|stable|features/string/italics -core-js(-pure)/es|stable|features/string/link -core-js(-pure)/es|stable|features/string/small -core-js(-pure)/es|stable|features/string/strike -core-js(-pure)/es|stable|features/string/sub -core-js(-pure)/es|stable|features/string/sup -core-js(-pure)/es|stable|features/string/iterator -core-js(-pure)/es|stable|features/string/virtual/includes -core-js(-pure)/es|stable|features/string/virtual/starts-with -core-js(-pure)/es|stable|features/string/virtual/ends-with -core-js(-pure)/es|stable|features/string/virtual/match-all -core-js(-pure)/es|stable|features/string/virtual/repeat -core-js(-pure)/es|stable|features/string/virtual/pad-start -core-js(-pure)/es|stable|features/string/virtual/pad-end -core-js(-pure)/es|stable|features/string/virtual/code-point-at -core-js(-pure)/es|stable|features/string/virtual/trim -core-js(-pure)/es|stable|features/string/virtual/trim-start -core-js(-pure)/es|stable|features/string/virtual/trim-end -core-js(-pure)/es|stable|features/string/virtual/trim-left -core-js(-pure)/es|stable|features/string/virtual/trim-right -core-js(-pure)/es|stable|features/string/virtual/anchor -core-js(-pure)/es|stable|features/string/virtual/big -core-js(-pure)/es|stable|features/string/virtual/blink -core-js(-pure)/es|stable|features/string/virtual/bold -core-js(-pure)/es|stable|features/string/virtual/fixed -core-js(-pure)/es|stable|features/string/virtual/fontcolor -core-js(-pure)/es|stable|features/string/virtual/fontsize -core-js(-pure)/es|stable|features/string/virtual/italics -core-js(-pure)/es|stable|features/string/virtual/link -core-js(-pure)/es|stable|features/string/virtual/small -core-js(-pure)/es|stable|features/string/virtual/strike -core-js(-pure)/es|stable|features/string/virtual/sub -core-js(-pure)/es|stable|features/string/virtual/sup -core-js(-pure)/es|stable|features/string/virtual/iterator -core-js/es|stable|features/regexp -core-js/es|stable|features/regexp/constructor -core-js(-pure)/es|stable|features/regexp/flags -core-js/es|stable|features/regexp/to-string -``` -[*Examples*](https://goo.gl/E6e7s6): + readonly attribute dotAll: boolean; // IE9+ + readonly attribute flags: string; // IE9+ + readonly attribute sticky: boolean; // IE9+ +} + +function escape(string: string): string; +function unescape(string: string): string; +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/es|stable|actual|full/string +core-js(-pure)/es|stable|actual|full/string/from-code-point +core-js(-pure)/es|stable|actual|full/string/raw +core-js/es|stable|actual|full/string/match +core-js/es|stable|actual|full/string/replace +core-js/es|stable|actual|full/string/search +core-js/es|stable|actual|full/string/split +core-js(-pure)/es|stable|actual/string(/virtual)/at +core-js(-pure)/es|stable|actual|full/string(/virtual)/code-point-at +core-js(-pure)/es|stable|actual|full/string(/virtual)/ends-with +core-js(-pure)/es|stable|actual|full/string(/virtual)/includes +core-js(-pure)/es|stable|actual|full/string(/virtual)/starts-with +core-js(-pure)/es|stable|actual|full/string(/virtual)/match-all +core-js(-pure)/es|stable|actual|full/string(/virtual)/pad-start +core-js(-pure)/es|stable|actual|full/string(/virtual)/pad-end +core-js(-pure)/es|stable|actual|full/string(/virtual)/repeat +core-js(-pure)/es|stable|actual|full/string(/virtual)/replace-all +core-js(-pure)/es|stable|actual|full/string(/virtual)/trim +core-js(-pure)/es|stable|actual|full/string(/virtual)/trim-start +core-js(-pure)/es|stable|actual|full/string(/virtual)/trim-end +core-js(-pure)/es|stable|actual|full/string(/virtual)/trim-left +core-js(-pure)/es|stable|actual|full/string(/virtual)/trim-right +core-js(-pure)/es|stable|actual|full/string(/virtual)/is-well-formed +core-js(-pure)/es|stable|actual|full/string(/virtual)/to-well-formed +core-js(-pure)/es|stable|actual|full/string(/virtual)/anchor +core-js(-pure)/es|stable|actual|full/string(/virtual)/big +core-js(-pure)/es|stable|actual|full/string(/virtual)/blink +core-js(-pure)/es|stable|actual|full/string(/virtual)/bold +core-js(-pure)/es|stable|actual|full/string(/virtual)/fixed +core-js(-pure)/es|stable|actual|full/string(/virtual)/fontcolor +core-js(-pure)/es|stable|actual|full/string(/virtual)/fontsize +core-js(-pure)/es|stable|actual|full/string(/virtual)/italics +core-js(-pure)/es|stable|actual|full/string(/virtual)/link +core-js(-pure)/es|stable|actual|full/string(/virtual)/small +core-js(-pure)/es|stable|actual|full/string(/virtual)/strike +core-js(-pure)/es|stable|actual|full/string(/virtual)/sub +core-js(-pure)/es|stable|actual|full/string(/virtual)/substr +core-js(-pure)/es|stable|actual|full/string(/virtual)/sup +core-js(-pure)/es|stable|actual|full/string(/virtual)/iterator +core-js/es|stable|actual|full/regexp +core-js/es|stable|actual|full/regexp/constructor +core-js(-pure)/es|stable|actual|full/regexp/escape +core-js/es|stable|actual|full/regexp/dot-all +core-js(-pure)/es|stable|actual|full/regexp/flags +core-js/es|stable|actual|full/regexp/sticky +core-js/es|stable|actual|full/regexp/test +core-js/es|stable|actual|full/regexp/to-string +core-js/es|stable|actual|full/escape +core-js/es|stable|actual|full/unescape +``` +[*Examples*](https://tinyurl.com/22uafm3p): ```js for (let value of 'a𠮷b') { console.log(value); // => 'a', '𠮷', 'b' @@ -781,17 +1075,34 @@ for (let value of 'a𠮷b') { String.fromCodePoint(97, 134071, 98); // => 'a𠮷b' let name = 'Bob'; -String.raw`Hi\n${name}!`; // => 'Hi\\nBob!' (ES2015 template string syntax) +String.raw`Hi\n${ name }!`; // => 'Hi\\nBob!' (ES2015 template string syntax) String.raw({ raw: 'test' }, 0, 1, 2); // => 't0e1s2t' -'foo'.bold(); // => 'foo' -'bar'.anchor('a"b'); // => 'bar' -'baz'.link('http://example.com/'); // => 'baz' +'foo'.bold(); // => 'foo' +'bar'.anchor('a"b'); // => 'bar' +'baz'.link('https://example.com/'); // => 'baz' + +RegExp('.', 's').test('\n'); // => true +RegExp('.', 's').dotAll; // => true + +RegExp('foo:(?\\w+),bar:(?\\w+)').exec('foo:abc,bar:def').groups; // => { foo: 'abc', bar: 'def' } + +'foo:abc,bar:def'.replace(RegExp('foo:(?\\w+),bar:(?\\w+)'), '$,$'); // => 'def,abc' +// eslint-disable-next-line regexp/no-useless-flag -- example RegExp(/./g, 'm'); // => /./m -/foo/.flags; // => '' -/foo/gim.flags; // => 'gim' +/foo/.flags; // => '' +/foo/gi.flags; // => 'gi' + +RegExp('foo', 'y').sticky; // => true + +const text = 'First line\nSecond line'; +const regex = RegExp('(?\\S+) line\\n?', 'y'); + +regex.exec(text).groups.index; // => 'First' +regex.exec(text).groups.index; // => 'Second' +regex.exec(text); // => null 'foo'.match({ [Symbol.match]: () => 1 }); // => 1 'foo'.replace({ [Symbol.replace]: () => 2 }); // => 2 @@ -805,20 +1116,46 @@ RegExp.prototype.toString.call({ source: 'foo', flags: 'bar' }); // => '/foo/bar ' hello '.trimStart(); // => 'hello ' ' hello '.trimEnd(); // => ' hello' -for (let [_, d, D] of '1111a2b3cccc'.matchAll(/(\d)(\D)/g)) { - console.log(d, D); // => 1 a, 2 b, 3 c +for (let { groups: { number, letter } } of '1111a2b3cccc'.matchAll(RegExp('(?\\d)(?\\D)', 'g'))) { + console.log(number, letter); // => 1 a, 2 b, 3 c } + +'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.' + +'abc'.at(1); // => 'b' +'abc'.at(-1); // => 'c' + +'a💩b'.isWellFormed(); // => true +'a\uD83Db'.isWellFormed(); // => false + +'a💩b'.toWellFormed(); // => 'a💩b' +'a\uD83Db'.toWellFormed(); // => 'a�b' ``` -#### ECMAScript: Number -Module [`es.number.constructor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.constructor.js). `Number` constructor support binary and octal literals, [*example*](http://goo.gl/jRd6b3): + +[*Example*](https://tinyurl.com/ykac4qgy): +```js +console.log(RegExp.escape('10$')); // => '\\x310\\$' +console.log(RegExp.escape('abcdefg_123456')); // => '\\x61bcdefg_123456' +console.log(RegExp.escape('Привет')); // => 'Привет' +console.log(RegExp.escape('(){}[]|,.?*+-^$=<>\\/#&!%:;@~\'"`')); +// => '\\(\\)\\{\\}\\[\\]\\|\\x2c\\.\\?\\*\\+\\x2d\\^\\$\\x3d\\x3c\\x3e\\\\\\/\\x23\\x26\\x21\\x25\\x3a\\x3b\\x40\\x7e\\x27\\x22\\x60' +console.log(RegExp.escape('\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF')); +// => '\\\t\\\n\\\v\\\f\\\r\\x20\\xa0\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029\\ufeff' +console.log(RegExp.escape('💩')); // => '💩' +console.log(RegExp.escape('\uD83D')); // => '\\ud83d' +``` + +#### ECMAScript: Number[⬆](#index) +Module [`es.number.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.constructor.js). `Number` constructor support binary and octal literals, [*example*](https://tinyurl.com/2659klkj): ```js Number('0b1010101'); // => 85 Number('0o7654321'); // => 2054353 ``` -Modules [`es.number.epsilon`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.epsilon.js), [`es.number.is-finite`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.is-finite.js), [`es.number.is-integer`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.is-integer.js), [`es.number.is-nan`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.is-nan.js), [`es.number.is-safe-integer`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.is-safe-integer.js), [`es.number.max-safe-integer`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.max-safe-integer.js), [`es.number.min-safe-integer`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.min-safe-integer.js), [`es.number.parse-float`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.parse-float.js), [`es.number.parse-int`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.parse-int.js), [`es.number.to-fixed`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.to-fixed.js), [`es.number.to-precision`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.number.to-precision.js), [`es.parse-int`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.parse-int.js), [`es.parse-float`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.parse-float.js). -```js +Modules [`es.number.epsilon`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.epsilon.js), [`es.number.is-finite`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.is-finite.js), [`es.number.is-integer`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.is-integer.js), [`es.number.is-nan`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.is-nan.js), [`es.number.is-safe-integer`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.is-safe-integer.js), [`es.number.max-safe-integer`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.max-safe-integer.js), [`es.number.min-safe-integer`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.min-safe-integer.js), [`es.number.parse-float`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.parse-float.js), [`es.number.parse-int`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.parse-int.js), [`es.number.to-exponential`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.to-exponential.js), [`es.number.to-fixed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.to-fixed.js), [`es.number.to-precision`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.number.to-precision.js), [`es.parse-int`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.parse-int.js), [`es.parse-float`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.parse-float.js). +```ts class Number { constructor(value: any): number; + toExponential(digits: number): string; toFixed(digits: number): string; toPrecision(precision: number): string; static isFinite(number: any): boolean; @@ -837,25 +1174,26 @@ function parseInt(string: string, radix?: number = 10): number; ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/number -core-js/es|stable|features/number/constructor -core-js(-pure)/es|stable|features/number/is-finite -core-js(-pure)/es|stable|features/number/is-nan -core-js(-pure)/es|stable|features/number/is-integer -core-js(-pure)/es|stable|features/number/is-safe-integer -core-js(-pure)/es|stable|features/number/parse-float -core-js(-pure)/es|stable|features/number/parse-int -core-js(-pure)/es|stable|features/number/epsilon -core-js(-pure)/es|stable|features/number/max-safe-integer -core-js(-pure)/es|stable|features/number/min-safe-integer -core-js(-pure)/es|stable|features/number/to-fixed -core-js(-pure)/es|stable|features/number/to-precision -core-js(-pure)/es|stable|features/parse-float -core-js(-pure)/es|stable|features/parse-int -``` -#### ECMAScript: Math -Modules [`es.math.acosh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.acosh.js), [`es.math.asinh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.asinh.js), [`es.math.atanh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.atanh.js), [`es.math.cbrt`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.cbrt.js), [`es.math.clz32`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.clz32.js), [`es.math.cosh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.cosh.js), [`es.math.expm1`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.expm1.js), [`es.math.fround`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.fround.js), [`es.math.hypot`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.hypot.js), [`es.math.imul`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.imul.js), [`es.math.log10`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.log10.js), [`es.math.log1p`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.log1p.js), [`es.math.log2`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.log2.js), [`es.math.sign`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.sign.js), [`es.math.sinh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.sinh.js), [`es.math.tanh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.tanh.js), [`es.math.trunc`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.trunc.js). -```js +core-js(-pure)/es|stable|actual|full/number +core-js(-pure)/es|stable|actual|full/number/constructor +core-js(-pure)/es|stable|actual|full/number/is-finite +core-js(-pure)/es|stable|actual|full/number/is-nan +core-js(-pure)/es|stable|actual|full/number/is-integer +core-js(-pure)/es|stable|actual|full/number/is-safe-integer +core-js(-pure)/es|stable|actual|full/number/parse-float +core-js(-pure)/es|stable|actual|full/number/parse-int +core-js(-pure)/es|stable|actual|full/number/epsilon +core-js(-pure)/es|stable|actual|full/number/max-safe-integer +core-js(-pure)/es|stable|actual|full/number/min-safe-integer +core-js(-pure)/es|stable|actual|full/number(/virtual)/to-exponential +core-js(-pure)/es|stable|actual|full/number(/virtual)/to-fixed +core-js(-pure)/es|stable|actual|full/number(/virtual)/to-precision +core-js(-pure)/es|stable|actual|full/parse-float +core-js(-pure)/es|stable|actual|full/parse-int +``` +#### ECMAScript: Math[⬆](#index) +Modules [`es.math.acosh`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.acosh.js), [`es.math.asinh`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.asinh.js), [`es.math.atanh`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.atanh.js), [`es.math.cbrt`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.cbrt.js), [`es.math.clz32`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.clz32.js), [`es.math.cosh`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.cosh.js), [`es.math.expm1`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.expm1.js), [`es.math.fround`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.fround.js), [`es.math.f16round`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.f16round.js), [`es.math.hypot`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.hypot.js), [`es.math.imul`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.imul.js), [`es.math.log10`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.log10.js), [`es.math.log1p`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.log1p.js), [`es.math.log2`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.log2.js), [`es.math.sign`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.sign.js), [`es.math.sinh`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.sinh.js), [`esnext.math.sum-precise`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.math.sum-precise.js), [`es.math.tanh`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.tanh.js), [`es.math.trunc`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.trunc.js). +```ts namespace Math { acosh(number: number): number; asinh(number: number): number; @@ -865,6 +1203,7 @@ namespace Math { cosh(number: number): number; expm1(number: number): number; fround(number: number): number; + f16round(number: any): number; hypot(...args: Array): number; imul(number1: number, number2: number): number; log1p(number: number): number; @@ -872,35 +1211,49 @@ namespace Math { log2(number: number): number; sign(number: number): 1 | -1 | 0 | -0 | NaN; sinh(number: number): number; + sumPrecise(items: Iterable): Number; tanh(number: number): number; trunc(number: number): number; } ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/math -core-js(-pure)/es|stable|features/math/acosh -core-js(-pure)/es|stable|features/math/asinh -core-js(-pure)/es|stable|features/math/atanh -core-js(-pure)/es|stable|features/math/cbrt -core-js(-pure)/es|stable|features/math/clz32 -core-js(-pure)/es|stable|features/math/cosh -core-js(-pure)/es|stable|features/math/expm1 -core-js(-pure)/es|stable|features/math/fround -core-js(-pure)/es|stable|features/math/hypot -core-js(-pure)/es|stable|features/math/imul -core-js(-pure)/es|stable|features/math/log1p -core-js(-pure)/es|stable|features/math/log10 -core-js(-pure)/es|stable|features/math/log2 -core-js(-pure)/es|stable|features/math/sign -core-js(-pure)/es|stable|features/math/sinh -core-js(-pure)/es|stable|features/math/tanh -core-js(-pure)/es|stable|features/math/trunc -``` -#### ECMAScript: Date -Modules [`es.date.to-string`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.date.to-string.js), ES5 features with fixes: [`es.date.now`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.date.now.js), [`es.date.to-iso-string`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.date.to-iso-string.js), [`es.date.to-json`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.date.to-json.js) and [`es.date.to-primitive`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.date.to-primitive.js). -```js +core-js(-pure)/es|stable|actual|full/math +core-js(-pure)/es|stable|actual|full/math/acosh +core-js(-pure)/es|stable|actual|full/math/asinh +core-js(-pure)/es|stable|actual|full/math/atanh +core-js(-pure)/es|stable|actual|full/math/cbrt +core-js(-pure)/es|stable|actual|full/math/clz32 +core-js(-pure)/es|stable|actual|full/math/cosh +core-js(-pure)/es|stable|actual|full/math/expm1 +core-js(-pure)/es|stable|actual|full/math/fround +core-js(-pure)/es|stable|actual|full/math/f16round +core-js(-pure)/es|stable|actual|full/math/hypot +core-js(-pure)/es|stable|actual|full/math/imul +core-js(-pure)/es|stable|actual|full/math/log1p +core-js(-pure)/es|stable|actual|full/math/log10 +core-js(-pure)/es|stable|actual|full/math/log2 +core-js(-pure)/es|stable|actual|full/math/sign +core-js(-pure)/es|stable|actual|full/math/sinh +core-js(-pure)/es|stable|actual|full/math/sum-precise +core-js(-pure)/es|stable|actual|full/math/tanh +core-js(-pure)/es|stable|actual|full/math/trunc +``` +[*Examples*](https://tinyurl.com/2bd3nako): +```js +1e20 + 0.1 + -1e20; // => 0 +Math.sumPrecise([1e20, 0.1, -1e20]); // => 0.1 +``` + +#### ECMAScript: Date[⬆](#index) +Modules [`es.date.to-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.date.to-string.js), ES5 features with fixes: [`es.date.now`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.date.now.js), [`es.date.to-iso-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.date.to-iso-string.js), [`es.date.to-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.date.to-json.js) and [`es.date.to-primitive`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.date.to-primitive.js). + +Annex B methods. Modules [`es.date.get-year`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.date.get-year.js), [`es.date.set-year`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.date.set-year.js) and [`es.date.to-gmt-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.date.to-gmt-string.js). +```ts class Date { + getYear(): int; + setYear(year: int): number; + toGMTString(): string; toISOString(): string; toJSON(): string; toString(): string; @@ -910,41 +1263,51 @@ class Date { ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js/es|stable|features/date -core-js/es|stable|features/date/to-string -core-js(-pure)/es|stable|features/date/now -core-js(-pure)/es|stable|features/date/to-iso-string -core-js(-pure)/es|stable|features/date/to-json -core-js(-pure)/es|stable|features/date/to-primitive +core-js/es|stable|actual|full/date +core-js/es|stable|actual|full/date/to-string +core-js(-pure)/es|stable|actual|full/date/now +core-js(-pure)/es|stable|actual|full/date/get-year +core-js(-pure)/es|stable|actual|full/date/set-year +core-js(-pure)/es|stable|actual|full/date/to-gmt-string +core-js(-pure)/es|stable|actual|full/date/to-iso-string +core-js(-pure)/es|stable|actual|full/date/to-json +core-js(-pure)/es|stable|actual|full/date/to-primitive ``` -[*Example*](http://goo.gl/haeHLR): +[*Example*](https://tinyurl.com/2cngq74c): ```js new Date(NaN).toString(); // => 'Invalid Date' ``` -#### ECMAScript: Promise -Modules [`es.promise`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.promise.js), [`es.promise.all-settled`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.promise.all-settled.js) and [`es.promise.finally`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.promise.finally.js). -```js +#### ECMAScript: Promise[⬆](#index) +Modules [`es.promise`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.js), [`es.promise.all-settled`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.all-settled.js), [`es.promise.any`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.any.js), [`es.promise.finally`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.finally.js), [`es.promise.try`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.try.js) and [`es.promise.with-resolvers`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.promise.with-resolvers.js). +```ts class Promise { constructor(executor: (resolve: Function, reject: Function) => void): Promise; then(onFulfilled: Function, onRejected: Function): Promise; catch(onRejected: Function): Promise; finally(onFinally: Function): Promise; - static resolve(x: any): Promise; - static reject(r: any): Promise; static all(iterable: Iterable): Promise; static allSettled(iterable: Iterable): Promise; + static any(promises: Iterable): Promise; static race(iterable: Iterable): Promise; + static reject(r: any): Promise; + static resolve(x: any): Promise; + static try(callbackfn: Function, ...args?: Array): Promise; + static withResolvers(): { promise: Promise, resolve: function, reject: function }; } ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/promise -core-js(-pure)/es|stable|features/promise/all-settled -core-js(-pure)/es|stable|features/promise/finally +core-js(-pure)/es|stable|actual|full/promise +core-js(-pure)/es|stable|actual|full/promise/all-settled +core-js(-pure)/es|stable|actual|full/promise/any +core-js(-pure)/es|stable|actual|full/promise/finally +core-js(-pure)/es|stable|actual|full/promise/try +core-js(-pure)/es|stable|actual|full/promise/with-resolvers ``` -Basic [*example*](http://goo.gl/vGrtUC): +Basic [*example*](https://tinyurl.com/23bhbhbu): ```js +/* eslint-disable promise/prefer-await-to-callbacks -- example */ function sleepRandom(time) { return new Promise((resolve, reject) => { setTimeout(resolve, time * 1e3, 0 | Math.random() * 1e3); @@ -959,45 +1322,47 @@ sleepRandom(5).then(result => { console.log(result); // => 202, after 10 sec. }).then(() => { console.log('immediately after'); // => immediately after - throw Error('Irror!'); + throw new Error('Irror!'); }).then(() => { console.log('will not be displayed'); -}).catch(x => console.log(x)); // => => Error: Irror! +}).catch(error => console.log(error)); // => => Error: Irror! ``` -`Promise.resolve` and `Promise.reject` [*example*](http://goo.gl/vr8TN3): +`Promise.resolve` and `Promise.reject` [*example*](https://tinyurl.com/28nq4agd): ```js -Promise.resolve(42).then(x => console.log(x)); // => 42 -Promise.reject(42).catch(x => console.log(x)); // => 42 +/* eslint-disable promise/prefer-await-to-callbacks -- example */ +Promise.resolve(42).then(x => console.log(x)); // => 42 +Promise.reject(42).catch(error => console.log(error)); // => 42 Promise.resolve($.getJSON('/data.json')); // => ES promise ``` -`Promise#finally` [*example*](https://goo.gl/AhyBbJ): +`Promise#finally` [*example*](https://tinyurl.com/2ywzmz72): ```js Promise.resolve(42).finally(() => console.log('You will see it anyway')); Promise.reject(42).finally(() => console.log('You will see it anyway')); ``` -`Promise.all` [*example*](http://goo.gl/RdoDBZ): +`Promise.all` [*example*](https://tinyurl.com/23nc596a): ```js Promise.all([ 'foo', sleepRandom(5), sleepRandom(15), - sleepRandom(10) // after 15 sec: + sleepRandom(10), // after 15 sec: ]).then(x => console.log(x)); // => ['foo', 956, 85, 382] ``` -`Promise.race` [*example*](http://goo.gl/L8ovkJ): +`Promise.race` [*example*](https://tinyurl.com/2degj8ux): ```js +/* eslint-disable promise/prefer-await-to-callbacks -- example */ function timeLimit(promise, time) { return Promise.race([promise, new Promise((resolve, reject) => { - setTimeout(reject, time * 1e3, Error('Await > ' + time + ' sec')); + setTimeout(reject, time * 1e3, new Error(`Await > ${ time } sec`)); })]); } -timeLimit(sleepRandom(5), 10).then(x => console.log(x)); // => 853, after 5 sec. -timeLimit(sleepRandom(15), 10).catch(x => console.log(x)); // Error: Await > 10 sec +timeLimit(sleepRandom(5), 10).then(x => console.log(x)); // => 853, after 5 sec. +timeLimit(sleepRandom(15), 10).catch(error => console.log(error)); // Error: Await > 10 sec ``` -`Promise.allSettled` [*example*](https://goo.gl/PXXLNJ): +`Promise.allSettled` [*example*](https://tinyurl.com/2akj7c2u): ```js Promise.allSettled([ Promise.resolve(1), @@ -1005,10 +1370,42 @@ Promise.allSettled([ Promise.resolve(3), ]).then(console.log); // => [{ value: 1, status: 'fulfilled' }, { reason: 2, status: 'rejected' }, { value: 3, status: 'fulfilled' }] ``` +`Promise.any` [*example*](https://tinyurl.com/23u59v6g): +```js +Promise.any([ + Promise.resolve(1), + Promise.reject(2), + Promise.resolve(3), +]).then(console.log); // => 1 + +Promise.any([ + Promise.reject(1), + Promise.reject(2), + Promise.reject(3), +]).catch(({ errors }) => console.log(errors)); // => [1, 2, 3] +``` +`Promise.try` [*examples*](https://tinyurl.com/2p48ojau): +```js +/* eslint-disable promise/prefer-await-to-callbacks -- example */ +Promise.try(() => 42).then(it => console.log(`Promise, resolved as ${ it }`)); -[Example](http://goo.gl/wnQS4j) with async functions: +Promise.try(() => { throw new Error('42'); }).catch(error => console.log(`Promise, rejected as ${ error }`)); + +Promise.try(async () => 42).then(it => console.log(`Promise, resolved as ${ it }`)); + +Promise.try(async () => { throw new Error('42'); }).catch(error => console.log(`Promise, rejected as ${ error }`)); + +Promise.try(it => it, 42).then(it => console.log(`Promise, resolved as ${ it }`)); +``` +`Promise.withResolvers` [*examples*](https://tinyurl.com/2gx4t3xu): ```js -let delay = time => new Promise(resolve => setTimeout(resolve, time)) +const d = Promise.withResolvers(); +d.resolve(42); +d.promise.then(console.log); // => 42 +``` +[Example](https://tinyurl.com/bde6am73) with async functions: +```js +let delay = time => new Promise(resolve => setTimeout(resolve, time)); async function sleepRandom(time) { await delay(time * 1e3); @@ -1017,7 +1414,7 @@ async function sleepRandom(time) { async function sleepError(time, msg) { await delay(time * 1e3); - throw Error(msg); + throw new Error(msg); } (async () => { @@ -1027,52 +1424,56 @@ async function sleepError(time, msg) { let [a, b, c] = await Promise.all([ sleepRandom(5), sleepRandom(15), - sleepRandom(10) + sleepRandom(10), ]); console.log(a, b, c); // => 210 445 71, after 15 sec. await sleepError(5, 'Error!'); console.log('Will not be displayed'); - } catch (e) { - console.log(e); // => Error: 'Error!', after 5 sec. + } catch (error) { + console.log(error); // => Error: 'Error!', after 5 sec. } })(); ``` -##### Unhandled rejection tracking +##### Unhandled rejection tracking[⬆](#index) In Node.js, like in native implementation, available events [`unhandledRejection`](https://nodejs.org/api/process.html#process_event_unhandledrejection) and [`rejectionHandled`](https://nodejs.org/api/process.html#process_event_rejectionhandled): ```js process.on('unhandledRejection', (reason, promise) => console.log('unhandled', reason, promise)); -process.on('rejectionHandled', (promise) => console.log('handled', promise)); +process.on('rejectionHandled', promise => console.log('handled', promise)); let promise = Promise.reject(42); // unhandled 42 [object Promise] -setTimeout(() => promise.catch(() => {}), 1e3); +// eslint-disable-next-line promise/prefer-await-to-then -- example +setTimeout(() => promise.catch(() => { /* empty */ }), 1e3); // handled [object Promise] ``` -In a browser on rejection, by default, you will see notify in the console, or you can add a custom handler and a handler on handling unhandled, [*example*](http://goo.gl/Wozskl): +In a browser on rejection, by default, you will see notify in the console, or you can add a custom handler and a handler on handling unhandled, [*example*](https://tinyurl.com/5n6nj2e8): ```js -window.addEventListener('unhandledrejection', e => console.log('unhandled', e.reason, e.promise)); -window.addEventListener('rejectionhandled', e => console.log('handled', e.reason, e.promise)); +globalThis.addEventListener('unhandledrejection', e => console.log('unhandled', e.reason, e.promise)); +globalThis.addEventListener('rejectionhandled', e => console.log('handled', e.reason, e.promise)); // or -window.onunhandledrejection = e => console.log('unhandled', e.reason, e.promise); -window.onrejectionhandled = e => console.log('handled', e.reason, e.promise); +globalThis.onunhandledrejection = e => console.log('unhandled', e.reason, e.promise); +globalThis.onrejectionhandled = e => console.log('handled', e.reason, e.promise); let promise = Promise.reject(42); // => unhandled 42 [object Promise] -setTimeout(() => promise.catch(() => {}), 1e3); +// eslint-disable-next-line promise/prefer-await-to-then -- example +setTimeout(() => promise.catch(() => { /* empty */ }), 1e3); // => handled 42 [object Promise] ``` -#### ECMAScript: Symbol -Modules [`es.symbol`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.js), [`es.symbol.async-iterator`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.async-iterator.js), [`es.symbol.description`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.description.js), [`es.symbol.has-instance`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.has-instance.js), [`es.symbol.is-concat-spreadable`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.is-concat-spreadable.js), [`es.symbol.iterator`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.iterator.js), [`es.symbol.match`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.match.js), [`es.symbol.replace`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.replace.js), [`es.symbol.search`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.search.js), [`es.symbol.species`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.species.js), [`es.symbol.split`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.split.js), [`es.symbol.to-primitive`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.to-primitive.js), [`es.symbol.to-string-tag`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.to-string-tag.js), [`es.symbol.unscopables`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.symbol.unscopables.js), [`es.math.to-string-tag`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.math.to-string-tag.js), [`es.json.to-string-tag`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.json.to-string-tag.js). -```js +#### ECMAScript: Symbol[⬆](#index) +Modules [`es.symbol`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.js), [`es.symbol.async-dispose`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.async-dispose.js), [`es.symbol.async-iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.async-iterator.js), [`es.symbol.description`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.description.js), [`es.symbol.dispose`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.dispose.js), [`es.symbol.has-instance`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.has-instance.js), [`es.symbol.is-concat-spreadable`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.is-concat-spreadable.js), [`es.symbol.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.iterator.js), [`es.symbol.match`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.match.js), [`es.symbol.replace`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.replace.js), [`es.symbol.search`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.search.js), [`es.symbol.species`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.species.js), [`es.symbol.split`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.split.js), [`es.symbol.to-primitive`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.to-primitive.js), [`es.symbol.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.to-string-tag.js), [`es.symbol.unscopables`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.symbol.unscopables.js), [`es.math.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.math.to-string-tag.js). +```ts class Symbol { constructor(description?): symbol; readonly attribute description: string | void; + static asyncDispose: @@asyncDispose; static asyncIterator: @@asyncIterator; + static dispose: @@dispose; static hasInstance: @@hasInstance; static isConcatSpreadable: @@isConcatSpreadable; static iterator: @@iterator; @@ -1095,7 +1496,7 @@ class Object { } ``` Also wrapped some methods for correct work with `Symbol` polyfill. -```js +```ts class Object { static create(prototype: Object | null, properties?: { [property: PropertyKey]: PropertyDescriptor }): Object; static defineProperties(object: Object, properties: { [property: PropertyKey]: PropertyDescriptor })): Object; @@ -1104,34 +1505,31 @@ class Object { static getOwnPropertyNames(object: any): Array; propertyIsEnumerable(key: PropertyKey): boolean; } - -namespace JSON { - stringify(target: any, replacer?: Function | Array, space?: string | number): string | void; -} ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/symbol -core-js(-pure)/es|stable|features/symbol/async-iterator -core-js/es|stable|features/symbol/description -core-js(-pure)/es|stable|features/symbol/has-instance -core-js(-pure)/es|stable|features/symbol/is-concat-spreadable -core-js(-pure)/es|stable|features/symbol/iterator -core-js(-pure)/es|stable|features/symbol/match -core-js(-pure)/es|stable|features/symbol/replace -core-js(-pure)/es|stable|features/symbol/search -core-js(-pure)/es|stable|features/symbol/species -core-js(-pure)/es|stable|features/symbol/split -core-js(-pure)/es|stable|features/symbol/to-primitive -core-js(-pure)/es|stable|features/symbol/to-string-tag -core-js(-pure)/es|stable|features/symbol/unscopables -core-js(-pure)/es|stable|features/symbol/for -core-js(-pure)/es|stable|features/symbol/key-for -core-js(-pure)/es|stable|features/object/get-own-property-symbols -core-js(-pure)/es|stable|features/math/to-string-tag -core-js(-pure)/es|stable|features/json/to-string-tag -``` -[*Basic example*](http://goo.gl/BbvWFc): +core-js(-pure)/es|stable|actual|full/symbol +core-js(-pure)/es|stable|actual|full/symbol/async-dispose +core-js(-pure)/es|stable|actual|full/symbol/async-iterator +core-js/es|stable|actual|full/symbol/description +core-js(-pure)/es|stable|actual|full/symbol/dispose +core-js(-pure)/es|stable|actual|full/symbol/has-instance +core-js(-pure)/es|stable|actual|full/symbol/is-concat-spreadable +core-js(-pure)/es|stable|actual|full/symbol/iterator +core-js(-pure)/es|stable|actual|full/symbol/match +core-js(-pure)/es|stable|actual|full/symbol/replace +core-js(-pure)/es|stable|actual|full/symbol/search +core-js(-pure)/es|stable|actual|full/symbol/species +core-js(-pure)/es|stable|actual|full/symbol/split +core-js(-pure)/es|stable|actual|full/symbol/to-primitive +core-js(-pure)/es|stable|actual|full/symbol/to-string-tag +core-js(-pure)/es|stable|actual|full/symbol/unscopables +core-js(-pure)/es|stable|actual|full/symbol/for +core-js(-pure)/es|stable|actual|full/symbol/key-for +core-js(-pure)/es|stable|actual|full/object/get-own-property-symbols +core-js(-pure)/es|stable|actual|full/math/to-string-tag +``` +[*Basic example*](https://tinyurl.com/2b2zfvrs): ```js let Person = (() => { let NAME = Symbol('name'); @@ -1142,22 +1540,22 @@ let Person = (() => { getName() { return this[NAME]; } - } + }; })(); let person = new Person('Vasya'); console.log(person.getName()); // => 'Vasya' -console.log(person['name']); // => undefined +console.log(person.name); // => undefined console.log(person[Symbol('name')]); // => undefined, symbols are uniq for (let key in person) console.log(key); // => nothing, symbols are not enumerable ``` -`Symbol.for` & `Symbol.keyFor` [*example*](http://goo.gl/0pdJjX): +`Symbol.for` & `Symbol.keyFor` [*example*](https://tinyurl.com/29u2q3jb): ```js let symbol = Symbol.for('key'); symbol === Symbol.for('key'); // true Symbol.keyFor(symbol); // 'key' ``` -[*Example*](http://goo.gl/mKVOQJ) with methods for getting own object keys: +[*Example*](https://tinyurl.com/2297e9bg) with methods for getting own object keys: ```js let object = { a: 1 }; Object.defineProperty(object, 'b', { value: 2 }); @@ -1168,39 +1566,36 @@ Object.getOwnPropertySymbols(object); // => [Symbol(c)] Reflect.ownKeys(object); // => ['a', 'b', Symbol(c)] ``` -[*Symbol#description getter*](https://goo.gl/MWizfc): +[*Symbol#description getter*](https://tinyurl.com/25s4664f): ```js Symbol('foo').description; // => 'foo' +// eslint-disable-next-line symbol-description -- example Symbol().description; // => undefined ``` -##### Caveats when using `Symbol` polyfill: +##### Caveats when using `Symbol` polyfill:[⬆](#index) -* We can't add new primitive type, `Symbol` returns object. -* `Symbol.for` and `Symbol.keyFor` can't be shimmed cross-realm. -* By default, to hide the keys, `Symbol` polyfill defines setter in `Object.prototype`. For this reason, uncontrolled creation of symbols can cause memory leak and the `in` operator is not working correctly with `Symbol` polyfill: `Symbol() in {} // => true`. +- We can't add a new primitive type, `Symbol` returns an object. +- `Symbol.for` and `Symbol.keyFor` can't be polyfilled cross-realm. +- By default, to hide the keys, `Symbol` polyfill defines a setter in `Object.prototype`. For this reason, an uncontrolled creation of symbols can cause a memory leak and the `in` operator is not working correctly with `Symbol` polyfill: `Symbol() in {} // => true`. -You can disable defining setters in `Object.prototype`. [Example](http://goo.gl/N5UD7J): +You can disable defining setters in `Object.prototype`. [Example](https://tinyurl.com/2blse6aa): ```js Symbol.useSimple(); -let symbol1 = Symbol('symbol1'); -let object1 = {}; -object1[symbol1] = true; +let object1 = { [Symbol('symbol1')]: true }; for (let key in object1) console.log(key); // => 'Symbol(symbol1)_t.qamkg9f3q', w/o native Symbol Symbol.useSetter(); -let symbol2 = Symbol('symbol2'); -let object2 = {}; -object2[symbol2] = true; +let object2 = { [Symbol('symbol2')]: true }; for (let key in object2) console.log(key); // nothing ``` -* Currently, `core-js` not adds setters to `Object.prototype` for well-known symbols for correct work something like `Symbol.iterator in foo`. It can cause problems with their enumerability. -* Some problems possible with environment exotic objects (for example, IE `localStorage`). +- Currently, `core-js` does not add setters to `Object.prototype` for well-known symbols for correct work something like `Symbol.iterator in foo`. It can cause problems with their enumerability. +- Some problems are possible with environment exotic objects (for example, IE `localStorage`). -#### ECMAScript: Collections -`core-js` uses native collections in most case, just fixes methods / constructor, if it's required, and in old environment uses fast polyfill (O(1) lookup). -#### Map -Module [`es.map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.map.js). -```js +#### ECMAScript: Collections[⬆](#index) +`core-js` uses native collections in most cases, just fixes methods / constructor, if it's required, and in the old environment uses fast polyfill (O(1) lookup). +#### Map[⬆](#index) +Modules [`es.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.map.js) and [`es.map.group-by`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.map.group-by.js). +```ts class Map { constructor(iterable?: Iterable<[key, value]>): Map; clear(): void; @@ -1214,13 +1609,15 @@ class Map { entries(): Iterator<[key, value]>; @@iterator(): Iterator<[key, value]>; readonly attribute size: number; + static groupBy(items: Iterable, callbackfn: (value: any, index: number) => key): Map>; } ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/map +core-js(-pure)/es|stable|actual|full/map +core-js(-pure)/es|stable|actual|full/map/group-by ``` -[*Examples*](http://goo.gl/GWR7NI): +[*Examples*](https://tinyurl.com/yn2w5s8v): ```js let array = [1]; @@ -1240,7 +1637,7 @@ console.log(map.size); // => 3 console.log(map.get(array)); // => undefined console.log(Array.from(map)); // => [['a', 1], [42, 2], [true, 4]] -let map = new Map([['a', 1], ['b', 2], ['c', 3]]); +map = new Map([['a', 1], ['b', 2], ['c', 3]]); for (let [key, value] of map) { console.log(key); // => 'a', 'b', 'c' @@ -1252,10 +1649,14 @@ for (let [key, value] of map.entries()) { console.log(key); // => 'a', 'b', 'c' console.log(value); // => 1, 2, 3 } + +map = Map.groupBy([1, 2, 3, 4, 5], it => it % 2); +map.get(1); // => [1, 3, 5] +map.get(0); // => [2, 4] ``` -#### Set -Module [`es.set`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.set.js). -```js +#### Set[⬆](#index) +Modules [`es.set`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.set.js), [`es.set.difference.v2`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.set.difference.v2.js), [`es.set.intersection.v2`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.set.intersection.v2.js), [`es.set.is-disjoint-from.v2`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.set.is-disjoint-from.v2.js), [`es.set.is-subset-of.v2`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.set.is-subset-of.v2.js), [`es.set.is-superset-of.v2`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.set.is-superset-of.v2.js), [`es.set.symmetric-difference.v2`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.set.symmetric-difference.v2.js), [`es.set.union.v2`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.set.union.v2.js) +```ts class Set { constructor(iterable?: Iterable): Set; add(key: any): this; @@ -1266,15 +1667,29 @@ class Set { values(): Iterator; keys(): Iterator; entries(): Iterator<[value, value]>; + difference(other: SetLike): Set; + intersection(other: SetLike): Set; + isDisjointFrom(other: SetLike): boolean; + isSubsetOf(other: SetLike): boolean; + isSupersetOf(other: SetLike): boolean; + symmetricDifference(other: SetLike): Set; + union(other: SetLike): Set; @@iterator(): Iterator; readonly attribute size: number; } ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/set +core-js(-pure)/es|stable|actual|full/set +core-js(-pure)/es|stable|actual|full/set/difference +core-js(-pure)/es|stable|actual|full/set/intersection +core-js(-pure)/es|stable|actual|full/set/is-disjoint-from +core-js(-pure)/es|stable|actual|full/set/is-subset-of +core-js(-pure)/es|stable|actual|full/set/is-superset-of +core-js(-pure)/es|stable|actual|full/set/symmetric-difference +core-js(-pure)/es|stable|actual|full/set/union ``` -[*Examples*](http://goo.gl/bmhLwg): +[*Examples*](https://tinyurl.com/2dy5t9ey): ```js let set = new Set(['a', 'b', 'a', 'c']); set.add('d').add('b').add('e'); @@ -1288,7 +1703,7 @@ console.log(set.size); // => 4 console.log(set.has('b')); // => false console.log(Array.from(set)); // => ['a', 'c', 'd', 'e'] -let set = new Set([1, 2, 3, 2, 1]); +set = new Set([1, 2, 3, 2, 1]); for (let value of set) console.log(value); // => 1, 2, 3 for (let value of set.values()) console.log(value); // => 1, 2, 3 @@ -1297,10 +1712,18 @@ for (let [key, value] of set.entries()) { console.log(key); // => 1, 2, 3 console.log(value); // => 1, 2, 3 } + +new Set([1, 2, 3]).union(new Set([3, 4, 5])); // => Set {1, 2, 3, 4, 5} +new Set([1, 2, 3]).intersection(new Set([3, 4, 5])); // => Set {3} +new Set([1, 2, 3]).difference(new Set([3, 4, 5])); // => Set {1, 2} +new Set([1, 2, 3]).symmetricDifference(new Set([3, 4, 5])); // => Set {1, 2, 4, 5} +new Set([1, 2, 3]).isDisjointFrom(new Set([4, 5, 6])); // => true +new Set([1, 2, 3]).isSubsetOf(new Set([5, 4, 3, 2, 1])); // => true +new Set([5, 4, 3, 2, 1]).isSupersetOf(new Set([1, 2, 3])); // => true ``` -#### WeakMap -Module [`es.weak-map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.weak-map.js). -```js +#### WeakMap[⬆](#index) +Module [`es.weak-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.weak-map.js). +```ts class WeakMap { constructor(iterable?: Iterable<[key, value]>): WeakMap; delete(key: Object): boolean; @@ -1311,9 +1734,9 @@ class WeakMap { ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/weak-map +core-js(-pure)/es|stable|actual|full/weak-map ``` -[*Examples*](http://goo.gl/SILXyw): +[*Examples*](https://tinyurl.com/2yws9shh): ```js let a = [1]; let b = [2]; @@ -1329,7 +1752,7 @@ console.log(weakmap.get(a)); // => undefined // Private properties store: let Person = (() => { - let names = new WeakMap; + let names = new WeakMap(); return class { constructor(name) { names.set(this, name); @@ -1337,16 +1760,16 @@ let Person = (() => { getName() { return names.get(this); } - } + }; })(); let person = new Person('Vasya'); console.log(person.getName()); // => 'Vasya' for (let key in person) console.log(key); // => only 'getName' ``` -#### WeakSet -Module [`es.weak-set`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.weak-set.js). -```js +#### WeakSet[⬆](#index) +Module [`es.weak-set`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.weak-set.js). +```ts class WeakSet { constructor(iterable?: Iterable): WeakSet; add(key: Object): this; @@ -1356,9 +1779,9 @@ class WeakSet { ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/weak-set +core-js(-pure)/es|stable|actual|full/weak-set ``` -[*Examples*](http://goo.gl/TdFbEx): +[*Examples*](https://tinyurl.com/2ceoza3j): ```js let a = [1]; let b = [2]; @@ -1371,19 +1794,80 @@ console.log(weakset.has([2])); // => false weakset.delete(b); console.log(weakset.has(b)); // => false ``` -##### Caveats when using collections polyfill: -* Weak-collections polyfill stores values as hidden properties of keys. It works correct and not leak in most cases. However, it is desirable to store a collection longer than its keys. +> [!WARNING] +> - Weak-collections polyfill stores values as hidden properties of keys. It works correctly and does not leak in most cases. However, it is desirable to store a collection longer than its keys. +> - Native symbols as `WeakMap` keys can't be properly polyfilled without memory leaks. + +#### ECMAScript: Explicit Resource Management[⬆](#index) +> [!NOTE] +> This is only built-ins for this Explicit Resource Management, `using` syntax support requires [transpiler support](https://babeljs.io/docs/babel-plugin-syntax-explicit-resource-management). + +Modules [`es.disposable-stack.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.disposable-stack.constructor.js), [`es.iterator.dispose`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.iterator.dispose.js), [`es.async-disposable-stack.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.async-disposable-stack.constructor.js), [`es.async-iterator.async-dispose`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.async-dispose.js). +```ts +class Symbol { + static asyncDispose: @@asyncDispose; + static dispose: @@dispose; +} + +class DisposableStack { + constructor(): DisposableStack; + dispose(): undefined; + use(value: Disposable): value; + adopt(value: object, onDispose: Function): value; + defer(onDispose: Function): undefined; + move(): DisposableStack; + @@dispose(): undefined; + @@toStringTag: 'DisposableStack'; +} + +class AsyncDisposableStack { + constructor(): AsyncDisposableStack; + disposeAsync(): Promise; + use(value: AsyncDisposable | Disposable): value; + adopt(value: object, onDispose: Function): value; + defer(onDispose: Function): undefined; + move(): AsyncDisposableStack; + @@asyncDispose(): Promise; + @@toStringTag: 'AsyncDisposableStack'; +} + +class SuppressedError extends Error { + constructor(error: any, suppressed: any, message?: string): SuppressedError; + error: any; + suppressed: any; + message: string; + cause: any; +} + +class Iterator { + @@dispose(): undefined; +} + +class AsyncIterator { + @@asyncDispose(): Promise; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/es|stable|actual|full/disposable-stack +core-js(-pure)/es|stable|actual|full/async-disposable-stack +core-js(-pure)/es|stable|actual|full/iterator/dispose +core-js(-pure)/es|stable|actual|full/async-iterator/async-dispose +``` -#### ECMAScript: Typed Arrays +#### ECMAScript: Typed Arrays[⬆](#index) Implementations and fixes for `ArrayBuffer`, `DataView`, Typed Arrays constructors, static and prototype methods. Typed arrays work only in environments with support descriptors (IE9+), `ArrayBuffer` and `DataView` should work anywhere. -Modules [`es.array-buffer.constructor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array-buffer.constructor.js), [`es.array-buffer.is-view`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array-buffer.is-view.js), [`es.array-buffer.slice`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.array-buffer.slice.js), [`es.data-view`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.data-view.js), [`es.typed-array.int8-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.int8-array.js), [`es.typed-array.uint8-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.uint8-array.js), [`es.typed-array.uint8-clamped-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.uint8-clamped-array.js), [`es.typed-array.int16-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.int16-array.js), [`es.typed-array.uint16-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.uint16-array.js), [`es.typed-array.int32-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed.int32-array.js), [`es.typed-array.uint32-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.uint32-array.js), [`es.typed-array.float32-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.float32-array.js), [`es.typed-array.float64-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.float64-array.js), [`es.typed-array.copy-within`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.copy-within.js), [`es.typed-array.every`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.every.js), [`es.typed-array.fill`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.fill.js), [`es.typed-array.filter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.filter.js), [`es.typed-array.find`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.find.js), [`es.typed-array.find-index`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.find-index.js), [`es.typed-array.for-each`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.for-each.js), [`es.typed-array.from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.from.js), [`es.typed-array.includes`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.includes.js), [`es.typed-array.index-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.index-of.js), [`es.typed-array.iterator`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.iterator.js), [`es.typed-array.last-index-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.last-index-of.js), [`es.typed-array.map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.map.js), [`es.typed-array.of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.of.js), [`es.typed-array.reduce`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.reduce.js), [`es.typed-array.reduce-right`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.reduce-right.js), [`es.typed-array.reverse`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.reverse.js), [`es.typed-array.set`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.set.js), [`es.typed-array.slice`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.slice.js), [`es.typed-array.some`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.some.js), [`es.typed-array.sort`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.sort.js), [`es.typed-array.subarray`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.subarray.js), [`es.typed-array.to-locale-string`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.to-locale-string.js) and [`es.typed-array.to-string`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.typed-array.to-string.js). -```js +Modules [`es.array-buffer.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array-buffer.constructor.js), [`es.array-buffer.is-view`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array-buffer.is-view.js), [`esnext.array-buffer.detached`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array-buffer.detached.js), [`es.array-buffer.slice`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.array-buffer.slice.js), [`esnext.array-buffer.transfer`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array-buffer.transfer.js), [`esnext.array-buffer.transfer-to-fixed-length`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array-buffer.transfer-to-fixed-length.js) [`es.data-view`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.data-view.js), [`es.data-view.get-float16`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.data-view.get-float16.js), [`es.data-view.set-float16`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.data-view.set-float16.js), [`es.typed-array.int8-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.int8-array.js), [`es.typed-array.uint8-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.uint8-array.js), [`es.typed-array.uint8-clamped-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.uint8-clamped-array.js), [`es.typed-array.int16-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.int16-array.js), [`es.typed-array.uint16-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.uint16-array.js), [`es.typed-array.int32-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.int32-array.js), [`es.typed-array.uint32-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.uint32-array.js), [`es.typed-array.float32-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.float32-array.js), [`es.typed-array.float64-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.float64-array.js), [`es.typed-array.copy-within`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.copy-within.js), [`es.typed-array.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.every.js), [`es.typed-array.fill`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.fill.js), [`es.typed-array.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.filter.js), [`es.typed-array.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.find.js), [`es.typed-array.find-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.find-index.js), [`es.typed-array.find-last`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.find-last.js), [`es.typed-array.find-last-index`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.find-last-index.js), [`es.typed-array.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.for-each.js), [`es.typed-array.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.from.js), [`es.typed-array.includes`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.includes.js), [`es.typed-array.index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.index-of.js), [`es.typed-array.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.iterator.js), [`es.typed-array.last-index-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.last-index-of.js), [`es.typed-array.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.map.js), [`es.typed-array.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.of.js), [`es.typed-array.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.reduce.js), [`es.typed-array.reduce-right`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.reduce-right.js), [`es.typed-array.reverse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.reverse.js), [`es.typed-array.set`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.set.js), [`es.typed-array.slice`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.slice.js), [`es.typed-array.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.some.js), [`es.typed-array.sort`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.sort.js), [`es.typed-array.subarray`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.subarray.js), [`es.typed-array.to-locale-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.to-locale-string.js), [`es.typed-array.to-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.to-string.js), [`es.typed-array.at`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.at.js), [`es.typed-array.to-reversed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.to-reversed.js), [`es.typed-array.to-sorted`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.to-sorted.js), [`es.typed-array.with`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.typed-array.with.js), [`es.uint8-array.from-base64`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.uint8-array.from-base64.js), [`es.uint8-array.from-hex`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.uint8-array.from-hex.js), [`es.uint8-array.set-from-hex`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.uint8-array.set-from-hex.js), [`es.uint8-array.to-base64`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.uint8-array.to-base64.js), [`es.uint8-array.to-hex`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.uint8-array.to-hex.js). +```ts class ArrayBuffer { constructor(length: any): ArrayBuffer; - slice(start: any, end: any): ArrayBuffer; readonly attribute byteLength: number; + readonly attribute detached: boolean; + slice(start: any, end: any): ArrayBuffer; + transfer(newLength?: number): ArrayBuffer; + transferToFixedLength(newLength?: number): ArrayBuffer; static isView(arg: any): boolean; } @@ -1395,6 +1879,7 @@ class DataView { getUint16(offset: any, littleEndian?: boolean = false): uint16; getInt32(offset: any, littleEndian?: boolean = false): int32; getUint32(offset: any, littleEndian?: boolean = false): uint32; + getFloat16(offset: any, littleEndian?: boolean = false): float16 getFloat32(offset: any, littleEndian?: boolean = false): float32; getFloat64(offset: any, littleEndian?: boolean = false): float64; setInt8(offset: any, value: any): void; @@ -1403,6 +1888,7 @@ class DataView { setUint16(offset: any, value: any, littleEndian?: boolean = false): void; setInt32(offset: any, value: any, littleEndian?: boolean = false): void; setUint32(offset: any, value: any, littleEndian?: boolean = false): void; + setFloat16(offset: any, value: any, littleEndian?: boolean = false): void; setFloat32(offset: any, value: any, littleEndian?: boolean = false): void; setFloat64(offset: any, value: any, littleEndian?: boolean = false): void; readonly attribute buffer: ArrayBuffer; @@ -1420,35 +1906,44 @@ class [ Uint32Array, Float32Array, Float64Array, -] { +] extends %TypedArray% { constructor(length: number): %TypedArray%; constructor(object: %TypedArray% | Iterable | ArrayLike): %TypedArray%; - constructor(buffer: ArrayBuffer, byteOffset?: number, length?: number): %TypedArray%; + constructor(buffer: ArrayBuffer, byteOffset?: number, length?: number): %TypedArray% +} + +class %TypedArray% { + at(index: int): number; copyWithin(target: number, start: number, end?: number): this; - every(callbackfn: (value: number, index: number, target: any) => boolean, thisArg?: any): boolean; + entries(): Iterator<[index, value]>; + every(callbackfn: (value: number, index: number, target: %TypedArray%) => boolean, thisArg?: any): boolean; fill(value: number, start?: number, end?: number): this; - filter(callbackfn: (value: number, index: number, target: any) => boolean, thisArg?: any): %TypedArray%; - find(callbackfn: (value: number, index: number, target: any) => boolean), thisArg?: any): any; - findIndex(callbackfn: (value: number, index: number, target: any) => boolean, thisArg?: any): number; - forEach(callbackfn: (value: number, index: number, target: any) => void, thisArg?: any): void; + filter(callbackfn: (value: number, index: number, target: %TypedArray%) => boolean, thisArg?: any): %TypedArray%; + find(callbackfn: (value: number, index: number, target: %TypedArray%) => boolean), thisArg?: any): any; + findIndex(callbackfn: (value: number, index: number, target: %TypedArray%) => boolean, thisArg?: any): uint; + findLast(callbackfn: (value: any, index: number, target: %TypedArray%) => boolean, thisArg?: any): any; + findLastIndex(callbackfn: (value: any, index: number, target: %TypedArray%) => boolean, thisArg?: any): uint; + forEach(callbackfn: (value: number, index: number, target: %TypedArray%) => void, thisArg?: any): void; includes(searchElement: any, from?: number): boolean; indexOf(searchElement: any, from?: number): number; join(separator: string = ','): string; + keys(): Iterator; lastIndexOf(searchElement: any, from?: number): number; - map(mapFn: (value: number, index: number, target: any) => number, thisArg?: any): %TypedArray%; - reduce(callbackfn: (memo: any, value: number, index: number, target: any) => any, initialValue?: any): any; - reduceRight(callbackfn: (memo: any, value: number, index: number, target: any) => any, initialValue?: any): any; + map(mapFn: (value: number, index: number, target: %TypedArray%) => number, thisArg?: any): %TypedArray%; + reduce(callbackfn: (memo: any, value: number, index: number, target: %TypedArray%) => any, initialValue?: any): any; + reduceRight(callbackfn: (memo: any, value: number, index: number, target: %TypedArray%) => any, initialValue?: any): any; reverse(): this; set(array: ArrayLike, offset?: number): void; slice(start?: number, end?: number): %TypedArray%; - some(callbackfn: (value: number, index: number, target: any) => boolean, thisArg?: any): boolean; - sort(comparefn?: (a: number, b: number) => number): this; + some(callbackfn: (value: number, index: number, target: %TypedArray%) => boolean, thisArg?: any): boolean; + sort(comparefn?: (a: number, b: number) => number): this; // with modern behavior like stable sort subarray(begin?: number, end?: number): %TypedArray%; + toReversed(): %TypedArray%; + toSorted(comparefn?: (a: any, b: any) => number): %TypedArray%; toString(): string; toLocaleString(): string; values(): Iterator; - keys(): Iterator; - entries(): Iterator<[index, value]>; + with(index: includes, value: any): %TypedArray%; @@iterator(): Iterator; readonly attribute buffer: ArrayBuffer; readonly attribute byteLength: number; @@ -1459,61 +1954,87 @@ class [ static of(...args: Array): %TypedArray%; static BYTES_PER_ELEMENT: number; } + +class Uint8Array { + static fromBase64(string: string, options?: { alphabet?: 'base64' | 'base64url', lastChunkHandling?: 'loose' | 'strict' | 'stop-before-partial' }): Uint8Array; + static fromHex(string: string): Uint8Array; + setFromBase64(string: string, options?: { alphabet?: 'base64' | 'base64url', lastChunkHandling?: 'loose' | 'strict' | 'stop-before-partial' }): { read: uint, written: uint }; + setFromHex(string: string): { read: uint, written: uint }; + toBase64(options?: { alphabet?: 'base64' | 'base64url', omitPadding?: boolean }): string; + toHex(): string; +} ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js/es|stable|features/array-buffer -core-js/es|stable|features/array-buffer/constructor -core-js/es|stable|features/array-buffer/is-view -core-js/es|stable|features/array-buffer/slice -core-js/es|stable|features/data-view -core-js/es|stable|features/typed-array -core-js/es|stable|features/typed-array/int8-array -core-js/es|stable|features/typed-array/uint8-array -core-js/es|stable|features/typed-array/uint8-clamped-array -core-js/es|stable|features/typed-array/int16-array -core-js/es|stable|features/typed-array/uint16-array -core-js/es|stable|features/typed-array/int32-array -core-js/es|stable|features/typed-array/uint32-array -core-js/es|stable|features/typed-array/float32-array -core-js/es|stable|features/typed-array/float64-array -core-js/es|stable|features/typed-array/copy-within -core-js/es|stable|features/typed-array/entries -core-js/es|stable|features/typed-array/every -core-js/es|stable|features/typed-array/fill -core-js/es|stable|features/typed-array/filter -core-js/es|stable|features/typed-array/find -core-js/es|stable|features/typed-array/find-index -core-js/es|stable|features/typed-array/for-each -core-js/es|stable|features/typed-array/from -core-js/es|stable|features/typed-array/includes -core-js/es|stable|features/typed-array/index-of -core-js/es|stable|features/typed-array/iterator -core-js/es|stable|features/typed-array/join -core-js/es|stable|features/typed-array/keys -core-js/es|stable|features/typed-array/last-index-of -core-js/es|stable|features/typed-array/map -core-js/es|stable|features/typed-array/of -core-js/es|stable|features/typed-array/reduce -core-js/es|stable|features/typed-array/reduce-right -core-js/es|stable|features/typed-array/reverse -core-js/es|stable|features/typed-array/set -core-js/es|stable|features/typed-array/slice -core-js/es|stable|features/typed-array/some -core-js/es|stable|features/typed-array/sort -core-js/es|stable|features/typed-array/subarray -core-js/es|stable|features/typed-array/to-locale-string -core-js/es|stable|features/typed-array/to-string -core-js/es|stable|features/typed-array/values -``` -[*Examples*](http://goo.gl/yla75z): +core-js/es|stable|actual|full/array-buffer +core-js/es|stable|actual|full/array-buffer/constructor +core-js/es|stable|actual|full/array-buffer/is-view +core-js/es|stable|actual|full/array-buffer/detached +core-js/es|stable|actual|full/array-buffer/slice +core-js/es|stable|actual|full/array-buffer/transfer +core-js/es|stable|actual|full/array-buffer/transfer-to-fixed-length +core-js/es|stable|actual|full/data-view +core-js/es|stable|actual|full/dataview/get-float16 +core-js/es|stable|actual|full/dataview/set-float16 +core-js/es|stable|actual|full/typed-array +core-js/es|stable|actual|full/typed-array/int8-array +core-js/es|stable|actual|full/typed-array/uint8-array +core-js/es|stable|actual|full/typed-array/uint8-clamped-array +core-js/es|stable|actual|full/typed-array/int16-array +core-js/es|stable|actual|full/typed-array/uint16-array +core-js/es|stable|actual|full/typed-array/int32-array +core-js/es|stable|actual|full/typed-array/uint32-array +core-js/es|stable|actual|full/typed-array/float32-array +core-js/es|stable|actual|full/typed-array/float64-array +core-js/es|stable|actual|full/typed-array/at +core-js/es|stable|actual|full/typed-array/copy-within +core-js/es|stable|actual|full/typed-array/entries +core-js/es|stable|actual|full/typed-array/every +core-js/es|stable|actual|full/typed-array/fill +core-js/es|stable|actual|full/typed-array/filter +core-js/es|stable|actual|full/typed-array/find +core-js/es|stable|actual|full/typed-array/find-index +core-js/es|stable|actual|full/typed-array/find-last +core-js/es|stable|actual|full/typed-array/find-last-index +core-js/es|stable|actual|full/typed-array/for-each +core-js/es|stable|actual|full/typed-array/from +core-js/es|stable|actual|full/typed-array/from-base64 +core-js/es|stable|actual|full/typed-array/from-hex +core-js/es|stable|actual|full/typed-array/includes +core-js/es|stable|actual|full/typed-array/index-of +core-js/es|stable|actual|full/typed-array/iterator +core-js/es|stable|actual|full/typed-array/join +core-js/es|stable|actual|full/typed-array/keys +core-js/es|stable|actual|full/typed-array/last-index-of +core-js/es|stable|actual|full/typed-array/map +core-js/es|stable|actual|full/typed-array/of +core-js/es|stable|actual|full/typed-array/reduce +core-js/es|stable|actual|full/typed-array/reduce-right +core-js/es|stable|actual|full/typed-array/reverse +core-js/es|stable|actual|full/typed-array/set +core-js/es|stable|actual|full/typed-array/set-from-base64 +core-js/es|stable|actual|full/typed-array/set-from-hex +core-js/es|stable|actual|full/typed-array/slice +core-js/es|stable|actual|full/typed-array/some +core-js/es|stable|actual|full/typed-array/sort +core-js/es|stable|actual|full/typed-array/subarray +core-js/es|stable|actual|full/typed-array/to-base64 +core-js/es|stable|actual|full/typed-array/to-hex +core-js/es|stable|actual|full/typed-array/to-locale-string +core-js/es|stable|actual|full/typed-array/to-reversed +core-js/es|stable|actual|full/typed-array/to-sorted +core-js/es|stable|actual|full/typed-array/to-string +core-js/es|stable|actual|full/typed-array/values +core-js/es|stable|actual|full/typed-array/with +``` +[*Examples*](https://tinyurl.com/23cdt8rk): ```js new Int32Array(4); // => [0, 0, 0, 0] new Uint8ClampedArray([1, 2, 3, 666]); // => [1, 2, 3, 255] new Float32Array(new Set([1, 2, 3, 2, 1])); // => [1, 2, 3] let buffer = new ArrayBuffer(8); -let view = new DataView(buffer); +let view = new DataView(buffer); view.setFloat64(0, 123.456, true); new Uint8Array(buffer.slice(4)); // => [47, 221, 94, 64] @@ -1537,14 +2058,38 @@ for (let [key, value] of typed.entries()) { console.log(key); // => 0, 1, 2 console.log(value); // => 1, 2, 3 } -``` -##### Caveats when using typed arrays polyfills: -* Polyfills of Typed Arrays constructors work completely how should work by the spec, but because of internal usage of getters / setters on each instance, are slow and consumes significant memory. However, polyfills of Typed Arrays constructors required mainly for old IE, all modern engines have native Typed Arrays constructors and require only fixes of constructors and polyfills of methods. +new Int32Array([1, 2, 3]).at(1); // => 2 +new Int32Array([1, 2, 3]).at(-1); // => 3 + +buffer = Int8Array.of(1, 2, 3, 4, 5, 6, 7, 8).buffer; +console.log(buffer.byteLength); // => 8 +console.log(buffer.detached); // => false +const newBuffer = buffer.transfer(4); +console.log(buffer.byteLength); // => 0 +console.log(buffer.detached); // => true +console.log(newBuffer.byteLength); // => 4 +console.log(newBuffer.detached); // => false +console.log([...new Int8Array(newBuffer)]); // => [1, 2, 3, 4] +``` -#### ECMAScript: Reflect -Modules [`es.reflect.apply`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.apply.js), [`es.reflect.construct`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.construct.js), [`es.reflect.define-property`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.define-property.js), [`es.reflect.delete-property`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.delete-property.js), [`es.reflect.get`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.get.js), [`es.reflect.get-own-property-descriptor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.get-own-property-descriptor.js), [`es.reflect.get-prototype-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.get-prototype-of.js), [`es.reflect.has`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.has.js), [`es.reflect.is-extensible`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.is-extensible.js), [`es.reflect.own-keys`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.own-keys.js), [`es.reflect.prevent-extensions`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.prevent-extensions.js), [`es.reflect.set`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.set.js), [`es.reflect.set-prototype-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/es.reflect.set-prototype-of.js). +*Base64 / Hex examples*: ```js +let arr = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); +console.log(arr.toBase64()); // => 'SGVsbG8gV29ybGQ=' +console.log(arr.toBase64({ omitPadding: true })); // => 'SGVsbG8gV29ybGQ' +console.log(arr.toHex()); // => '48656c6c6f20576f726c64' +console.log(Uint8Array.fromBase64('SGVsbG8gV29ybGQ=')); // => Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]) +console.log(Uint8Array.fromHex('48656c6c6f20576f726c64')); // => Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]) +``` + +> [!WARNING] +> - Polyfills of Typed Arrays constructors work completely how they should work by the spec. Still, because of the internal usage of getters / setters on each instance, they are slow and consume significant memory. However, polyfills of Typed Arrays constructors are required mainly for old IE, all modern engines have native Typed Arrays constructors and require only fixes of constructors and polyfills of methods. +> - `ArrayBuffer.prototype.{ transfer, transferToFixedLength }` polyfilled only in runtime with native `structuredClone` with `ArrayBuffer` transfer or `MessageChannel` support. + +#### ECMAScript: Reflect[⬆](#index) +Modules [`es.reflect.apply`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.apply.js), [`es.reflect.construct`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.construct.js), [`es.reflect.define-property`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.define-property.js), [`es.reflect.delete-property`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.delete-property.js), [`es.reflect.get`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.get.js), [`es.reflect.get-own-property-descriptor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.get-own-property-descriptor.js), [`es.reflect.get-prototype-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.get-prototype-of.js), [`es.reflect.has`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.has.js), [`es.reflect.is-extensible`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.is-extensible.js), [`es.reflect.own-keys`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.own-keys.js), [`es.reflect.prevent-extensions`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.prevent-extensions.js), [`es.reflect.set`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.set.js), [`es.reflect.set-prototype-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.reflect.set-prototype-of.js). +```ts namespace Reflect { apply(target: Function, thisArgument: any, argumentsList: Array): any; construct(target: Function, argumentsList: Array, newTarget?: Function): Object; @@ -1563,22 +2108,22 @@ namespace Reflect { ``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/es|stable|features/reflect -core-js(-pure)/es|stable|features/reflect/apply -core-js(-pure)/es|stable|features/reflect/construct -core-js(-pure)/es|stable|features/reflect/define-property -core-js(-pure)/es|stable|features/reflect/delete-property -core-js(-pure)/es|stable|features/reflect/get -core-js(-pure)/es|stable|features/reflect/get-own-property-descriptor -core-js(-pure)/es|stable|features/reflect/get-prototype-of -core-js(-pure)/es|stable|features/reflect/has -core-js(-pure)/es|stable|features/reflect/is-extensible -core-js(-pure)/es|stable|features/reflect/own-keys -core-js(-pure)/es|stable|features/reflect/prevent-extensions -core-js(-pure)/es|stable|features/reflect/set -core-js(-pure)/es|stable|features/reflect/set-prototype-of -``` -[*Examples*](http://goo.gl/gVT0cH): +core-js(-pure)/es|stable|actual|full/reflect +core-js(-pure)/es|stable|actual|full/reflect/apply +core-js(-pure)/es|stable|actual|full/reflect/construct +core-js(-pure)/es|stable|actual|full/reflect/define-property +core-js(-pure)/es|stable|actual|full/reflect/delete-property +core-js(-pure)/es|stable|actual|full/reflect/get +core-js(-pure)/es|stable|actual|full/reflect/get-own-property-descriptor +core-js(-pure)/es|stable|actual|full/reflect/get-prototype-of +core-js(-pure)/es|stable|actual|full/reflect/has +core-js(-pure)/es|stable|actual|full/reflect/is-extensible +core-js(-pure)/es|stable|actual|full/reflect/own-keys +core-js(-pure)/es|stable|actual|full/reflect/prevent-extensions +core-js(-pure)/es|stable|actual|full/reflect/set +core-js(-pure)/es|stable|actual|full/reflect/set-prototype-of +``` +[*Examples*](https://tinyurl.com/27leplqz): ```js let object = { a: 1 }; Object.defineProperty(object, 'b', { value: 2 }); @@ -1593,62 +2138,475 @@ let instance = Reflect.construct(C, [20, 22]); instance.c; // => 42 ``` -### ECMAScript proposals -[The TC39 process.](https://tc39.github.io/process-document/) -`core-js/stage/4` entry point contains only stage 4 proposals, `core-js/stage/3` - stage 3 and stage 4, etc. -#### Stage 4 proposals +#### ECMAScript: JSON[⬆](#index) +Since `JSON` object is missed only in very old engines like IE7-, `core-js` does not provide a full `JSON.{ parse, stringify }` polyfill, however, fix already existing implementations by the current standard. -Stage 4 proposals already marked in `core-js` as stable ECMAScript, they will be removed from proposals namespace in the next major `core-js` version. -[*CommonJS entry points:*](#commonjs-api) -```js -core-js(-pure)/stage/4 -``` -##### [`globalThis`](https://github.com/tc39/proposal-global) -Module [`esnext.global-this`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.global-this.js). -```js -let globalThis: Object; +Modules [`es.json.is-raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.is-raw-json.js), [`es.json.parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.parse.js), [`es.json.raw-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.raw-json.js), [`es.json.stringify`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.stringify.js) and [`es.json.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.json.to-string-tag.js) . +```ts +namespace JSON { + isRawJSON(O: any): boolean; + parse(text: string, reviver?: (this: any, key: string, value: any, context: { source?: string }) => any): any; + rawJSON(text: any): RawJSON; + stringify(value: any, replacer?: Array | (this: any, key: string, value: any) => any, space?: string | number): string | void; + @@toStringTag: 'JSON'; +} ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/global-this -core-js(-pure)/features/global-this ``` -[*Examples*](https://goo.gl/LAifsc): -```js -globalThis.Array === Array; // => true +core-js(-pure)/es|stable|actual|full/json/is-raw-json +core-js(-pure)/es|stable|actual|full/json/parse +core-js(-pure)/es|stable|actual|full/json/raw-json +core-js(-pure)/es|stable|actual|full/json/stringify +core-js(-pure)/es|stable|actual|full/json/stringify +core-js(-pure)/es|stable|actual|full/json/to-string-tag ``` -##### [`String#matchAll`](https://github.com/tc39/proposal-string-matchall) -Module [`esnext.string.match-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.string.match-all.js). - +[*Examples*](https://tinyurl.com/34ctm7cn): ```js -class String { - matchAll(regexp: RegExp): Iterator; +JSON.stringify({ '𠮷': ['\uDF06\uD834'] }); // => '{"𠮷":["\\udf06\\ud834"]}' + +function digitsToBigInt(key, val, { source }) { + return /^\d+$/.test(source) ? BigInt(source) : val; } + +function bigIntToRawJSON(key, val) { + return typeof val === 'bigint' ? JSON.rawJSON(String(val)) : val; +} + +const tooBigForNumber = BigInt(Number.MAX_SAFE_INTEGER) + 2n; +JSON.parse(String(tooBigForNumber), digitsToBigInt) === tooBigForNumber; // true + +const wayTooBig = BigInt(`1${ '0'.repeat(1000) }`); +JSON.parse(String(wayTooBig), digitsToBigInt) === wayTooBig; // true + +const embedded = JSON.stringify({ tooBigForNumber }, bigIntToRawJSON); +embedded === '{"tooBigForNumber":9007199254740993}'; // true +``` + +#### ECMAScript: globalThis[⬆](#index) +Module [`es.global-this`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/es.global-this.js). +```ts +let globalThis: GlobalThisValue; ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/string-match-all ``` -##### [`Promise.allSettled`](https://github.com/tc39/proposal-promise-allSettled) -Module [`esnext.promise.all-settled`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.promise.all-settled.js) -```js -class Promise { - static allSettled(iterable: Iterable): Promise; -} +core-js(-pure)/es|stable|actual|full/global-this ``` -[*CommonJS entry points:*](#commonjs-api) +[*Examples*](https://tinyurl.com/25ajyfuk): ```js -core-js/proposals/promise-all-settled +globalThis.Array === Array; // => true ``` -#### Stage 3 proposals +### ECMAScript proposals[⬆](#index) +[The TC39 process.](https://tc39.github.io/process-document/) + +`core-js/stage/3` entry point contains only stage 3 proposals, `core-js/stage/2.7` - stage 2.7 and stage 3, etc. + +#### Finished proposals[⬆](#index) + +Finished (stage 4) proposals already marked in `core-js` as stable ECMAScript, they are available in `core-js/stable` and `core-js/es` namespace, you can find them in related sections of the README. However, even for finished proposals, `core-js` provides a way to include only features for a specific proposal like `core-js/proposals/proposal-name`. + +##### [`globalThis`](https://github.com/tc39/proposal-global)[⬆](#index) +```ts +let globalThis: GlobalThisValue; +``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js(-pure)/stage/3 ``` -##### [`Promise.any`](https://github.com/tc39/proposal-promise-any) -Modules [`esnext.promise.any`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.promise.any.js) and [`esnext.aggregate-error`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.aggregate-error.js) -```js +core-js/proposals/global-this +``` +##### [Relative indexing method](https://github.com/tc39/proposal-relative-indexing-method)[⬆](#index) +```ts +class Array { + at(index: int): any; +} + +class String { + at(index: int): string; +} + +class %TypedArray% { + at(index: int): number; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/relative-indexing-method +``` +##### [`Array.prototype.includes`](https://github.com/tc39/proposal-Array.prototype.includes)[⬆](#index) +```ts +class Array { + includes(searchElement: any, from?: number): boolean; +} + +class %TypedArray% { + includes(searchElement: any, from?: number): boolean; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/array-includes +``` +##### [`Array.prototype.flat` / `Array.prototype.flatMap`](https://github.com/tc39/proposal-flatMap)[⬆](#index) +```ts +class Array { + flat(depthArg?: number = 1): Array; + flatMap(mapFn: (value: any, index: number, target: any) => any, thisArg: any): Array; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/array-flat-map +``` +##### [Array find from last](https://github.com/tc39/proposal-array-find-from-last)[⬆](#index) +```ts +class Array { + findLast(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): any; + findLastIndex(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): uint; +} + +class %TypedArray% { + findLast(callbackfn: (value: any, index: number, target: %TypedArray%) => boolean, thisArg?: any): any; + findLastIndex(callbackfn: (value: any, index: number, target: %TypedArray%) => boolean, thisArg?: any): uint; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/array-find-from-last +``` +##### [Change `Array` by copy](https://github.com/tc39/proposal-change-array-by-copy)[⬆](#index) +```ts +class Array { + toReversed(): Array; + toSpliced(start?: number, deleteCount?: number, ...items: Array): Array; + toSorted(comparefn?: (a: any, b: any) => number): Array; + with(index: includes, value: any): Array; +} + +class %TypedArray% { + toReversed(): %TypedArray%; + toSorted(comparefn?: (a: any, b: any) => number): %TypedArray%; + with(index: includes, value: any): %TypedArray%; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/change-array-by-copy-stage-4 +core-js(-pure)/es|stable|actual|full/array(/virtual)/to-reversed +core-js(-pure)/es|stable|actual|full/array(/virtual)/to-sorted +core-js(-pure)/es|stable|actual|full/array(/virtual)/to-spliced +core-js(-pure)/es|stable|actual|full/array(/virtual)/with +core-js/es|stable|actual|full/typed-array/to-reversed +core-js/es|stable|actual|full/typed-array/to-sorted +core-js/es|stable|actual|full/typed-array/with +``` +##### [`Array` grouping](https://github.com/tc39/proposal-array-grouping)[⬆](#index) +```ts +class Object { + static groupBy(items: Iterable, callbackfn: (value: any, index: number) => key): { [key]: Array }; +} + +class Map { + static groupBy(items: Iterable, callbackfn: (value: any, index: number) => key): Map>; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/array-grouping-v2 +``` + +##### [`Array.fromAsync`](https://github.com/tc39/proposal-array-from-async)[⬆](#index) +```ts +class Array { + static fromAsync(asyncItems: AsyncIterable | Iterable | ArrayLike, mapfn?: (value: any, index: number) => any, thisArg?: any): Array; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/array-from-async-stage-2 +``` + +##### [`ArrayBuffer.prototype.transfer` and friends](https://github.com/tc39/proposal-arraybuffer-transfer)[⬆](#index) +```ts +class ArrayBuffer { + readonly attribute detached: boolean; + transfer(newLength?: number): ArrayBuffer; + transferToFixedLength(newLength?: number): ArrayBuffer; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/array-buffer-transfer +``` + +##### [`Uint8Array` to / from base64 and hex](https://github.com/tc39/proposal-arraybuffer-base64)[⬆](#index) +```ts +class Uint8Array { + static fromBase64(string: string, options?: { alphabet?: 'base64' | 'base64url', lastChunkHandling?: 'loose' | 'strict' | 'stop-before-partial' }): Uint8Array; + static fromHex(string: string): Uint8Array; + setFromBase64(string: string, options?: { alphabet?: 'base64' | 'base64url', lastChunkHandling?: 'loose' | 'strict' | 'stop-before-partial' }): { read: uint, written: uint }; + setFromHex(string: string): { read: uint, written: uint }; + toBase64(options?: { alphabet?: 'base64' | 'base64url', omitPadding?: boolean }): string; + toHex(): string; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/array-buffer-base64 +``` + +##### [`Error.isError`](https://github.com/tc39/proposal-is-error)[⬆](#index) +```ts +class Error { + static isError(value: any): boolean; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/is-error +``` + +> [!WARNING] +> We have no bulletproof way to polyfill this `Error.isError` / check if the object is an error, so it's an enough naive implementation. + + +##### [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management)[⬆](#index) +> [!NOTE] +> This is only built-ins for this Explicit Resource Management, `using` syntax support requires [transpiler support](https://babeljs.io/docs/babel-plugin-syntax-explicit-resource-management). +```ts +class Symbol { + static asyncDispose: @@asyncDispose; + static dispose: @@dispose; +} + +class DisposableStack { + constructor(): DisposableStack; + dispose(): undefined; + use(value: Disposable): value; + adopt(value: object, onDispose: Function): value; + defer(onDispose: Function): undefined; + move(): DisposableStack; + @@dispose(): undefined; + @@toStringTag: 'DisposableStack'; +} + +class AsyncDisposableStack { + constructor(): AsyncDisposableStack; + disposeAsync(): Promise; + use(value: AsyncDisposable | Disposable): value; + adopt(value: object, onDispose: Function): value; + defer(onDispose: Function): undefined; + move(): AsyncDisposableStack; + @@asyncDispose(): Promise; + @@toStringTag: 'AsyncDisposableStack'; +} + +class SuppressedError extends Error { + constructor(error: any, suppressed: any, message?: string): SuppressedError; + error: any; + suppressed: any; + message: string; + cause: any; +} + +class Iterator { + @@dispose(): undefined; +} + +class AsyncIterator { + @@asyncDispose(): Promise; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/explicit-resource-management +``` + +##### [`Float16` methods](https://github.com/tc39/proposal-float16array)[⬆](#index) +```ts +class DataView { + getFloat16(offset: any, littleEndian?: boolean = false): float16 + setFloat16(offset: any, value: any, littleEndian?: boolean = false): void; +} + +namespace Math { + fround(number: any): number; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/float16 +``` + +##### [`Iterator` helpers](https://github.com/tc39/proposal-iterator-helpers)[⬆](#index) +```ts +class Iterator { + static from(iterable: Iterable | Iterator): Iterator; + drop(limit: uint): Iterator; + every(callbackfn: (value: any, counter: uint) => boolean): boolean; + filter(callbackfn: (value: any, counter: uint) => boolean): Iterator; + find(callbackfn: (value: any, counter: uint) => boolean)): any; + flatMap(callbackfn: (value: any, counter: uint) => Iterable | Iterator): Iterator; + forEach(callbackfn: (value: any, counter: uint) => void): void; + map(callbackfn: (value: any, counter: uint) => any): Iterator; + reduce(callbackfn: (memo: any, value: any, counter: uint) => any, initialValue: any): any; + some(callbackfn: (value: any, counter: uint) => boolean): boolean; + take(limit: uint): Iterator; + toArray(): Array; + @@toStringTag: 'Iterator' +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/iterator-helpers-stage-3-2 +``` + +##### [`Iterator` sequencing](https://github.com/tc39/proposal-iterator-sequencing)[⬆](#index) +```ts +class Iterator { + static concat(...items: Array): Iterator; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/iterator-sequencing +``` + +##### [`Object.values` / `Object.entries`](https://github.com/tc39/proposal-object-values-entries)[⬆](#index) +```ts +class Object { + static entries(object: Object): Array<[string, mixed]>; + static values(object: any): Array; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/object-values-entries +``` +##### [`Object.fromEntries`](https://github.com/tc39/proposal-object-from-entries)[⬆](#index) +```ts +class Object { + static fromEntries(iterable: Iterable<[key, value]>): Object; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/object-from-entries +``` +##### [`Object.getOwnPropertyDescriptors`](https://github.com/tc39/proposal-object-getownpropertydescriptors)[⬆](#index) +```ts +class Object { + static getOwnPropertyDescriptors(object: any): { [property: PropertyKey]: PropertyDescriptor }; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/object-getownpropertydescriptors +``` +##### [Accessible `Object.prototype.hasOwnProperty`](https://github.com/tc39/proposal-accessible-object-hasownproperty)[⬆](#index) +```ts +class Object { + static hasOwn(object: object, key: PropertyKey): boolean; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/accessible-object-hasownproperty +``` +##### [`String` padding](https://github.com/tc39/proposal-string-pad-start-end)[⬆](#index) +```ts +class String { + padStart(length: number, fillStr?: string = ' '): string; + padEnd(length: number, fillStr?: string = ' '): string; +} + +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/string-padding +``` +##### [`String#matchAll`](https://github.com/tc39/proposal-string-matchall)[⬆](#index). +```ts +class String { + matchAll(regexp: RegExp): Iterator; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/string-match-all +``` +##### [`String#replaceAll`](https://github.com/tc39/proposal-string-replace-all)[⬆](#index) +```ts +class String { + replaceAll(searchValue: string | RegExp, replaceString: string | (searchValue, index, this) => string): string; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/string-replace-all-stage-4 +``` +##### [`String.prototype.trimStart` / `String.prototype.trimEnd`](https://github.com/tc39/proposal-string-left-right-trim)[⬆](#index) +```ts +class String { + trimLeft(): string; + trimRight(): string; + trimStart(): string; + trimEnd(): string; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/string-left-right-trim +``` +##### [`RegExp` `s` (`dotAll`) flag](https://github.com/tc39/proposal-regexp-dotall-flag)[⬆](#index) +```ts +// patched for support `RegExp` dotAll (`s`) flag: +class RegExp { + constructor(pattern: RegExp | string, flags?: string): RegExp; + exec(): Array | null; + readonly attribute dotAll: boolean; + readonly attribute flags: string; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/regexp-dotall-flag +``` +##### [`RegExp` named capture groups](https://github.com/tc39/proposal-regexp-named-groups)[⬆](#index) +```ts +// patched for support `RegExp` named capture groups: +class RegExp { + constructor(pattern: RegExp | string, flags?: string): RegExp; + exec(): Array | null; + @@replace(string: string, replaceValue: Function | string): string; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/regexp-named-groups +``` + +##### [`RegExp` escaping](https://github.com/tc39/proposal-regex-escaping)[⬆](#index) +```ts +class RegExp { + static escape(value: string): string +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/regexp-escaping +``` + +##### [`Promise.allSettled`](https://github.com/tc39/proposal-promise-allSettled)[⬆](#index) +```ts +class Promise { + static allSettled(iterable: Iterable): Promise; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/promise-all-settled +``` +##### [`Promise.any`](https://github.com/tc39/proposal-promise-any)[⬆](#index) +```ts class AggregateError { constructor(errors: Iterable, message: string): AggregateError; errors: Array; @@ -1660,297 +2618,520 @@ class Promise { } ``` [*CommonJS entry points:*](#commonjs-api) -```js +``` core-js/proposals/promise-any -core-js(-pure)/features/promise/any -core-js(-pure)/features/aggregate-error ``` -[*Examples*](https://goo.gl/iErvmp): -```js -Promise.any([ - Promise.resolve(1), - Promise.reject(2), - Promise.resolve(3), -]).then(console.log); // => 1 +##### [`Promise.prototype.finally`](https://github.com/tc39/proposal-promise-finally)[⬆](#index) +```ts +class Promise { + finally(onFinally: Function): Promise; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/promise-finally +``` -Promise.any([ - Promise.reject(1), - Promise.reject(2), - Promise.reject(3), -]).catch(({ errors }) => console.log(errors)); // => [1, 2, 3] +##### [`Promise.try`](https://github.com/tc39/proposal-promise-try) +```ts +class Promise { + static try(callbackfn: Function, ...args?: Array): Promise; +} ``` -##### [`String#replaceAll`](https://github.com/tc39/proposal-string-replace-all) -Module [`esnext.string.replace-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.string.replace-all.js) -```js +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/promise-try +``` + +##### [`Promise.withResolvers`](https://github.com/tc39/proposal-promise-with-resolvers)[⬆](#index) +```ts +class Promise { + static withResolvers(): { promise: Promise, resolve: function, reject: function }; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/promise-with-resolvers +``` +##### [`Symbol.asyncIterator` for asynchronous iteration](https://github.com/tc39/proposal-async-iteration)[⬆](#index) +```ts +class Symbol { + static asyncIterator: @@asyncIterator; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/async-iteration +``` +##### [`Symbol.prototype.description`](https://github.com/tc39/proposal-Symbol-description)[⬆](#index) +```ts +class Symbol { + readonly attribute description: string | void; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/symbol-description +``` + +##### [`JSON.parse` source text access](https://github.com/tc39/proposal-json-parse-with-source)[⬆](#index) +```ts +namespace JSON { + isRawJSON(O: any): boolean; + // patched for source support + parse(text: string, reviver?: (this: any, key: string, value: any, context: { source?: string }) => any): any; + rawJSON(text: any): RawJSON; + // patched for `JSON.rawJSON` support + stringify(value: any, replacer?: Array | (this: any, key: string, value: any) => any, space?: string | number): string | void; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/json-parse-with-source +``` + +##### [Well-formed `JSON.stringify`](https://github.com/tc39/proposal-well-formed-stringify)[⬆](#index) +```ts +namespace JSON { + stringify(target: any, replacer?: Function | Array, space?: string | number): string | void; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/well-formed-stringify +``` +##### [Well-formed unicode strings](https://github.com/tc39/proposal-is-usv-string)[⬆](#index) +```ts class String { - replaceAll(searchValue: string | RegExp, replaceString: string | (searchValue, index, this) => string): string; + isWellFormed(): boolean; + toWellFormed(): string; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/string-replace-all -core-js/features/string/replace-all ``` -[*Examples*](https://goo.gl/wUXNXN): -```js -'Test abc test test abc test.'.replaceAll('abc', 'foo'); // -> 'Test foo test test foo test.' +core-js/proposals/well-formed-unicode-strings +``` +##### [New `Set` methods](https://github.com/tc39/proposal-set-methods)[⬆](#index) +```ts +class Set { + difference(other: SetLike): Set; + intersection(other: SetLike): Set; + isDisjointFrom(other: SetLike): boolean; + isSubsetOf(other: SetLike): boolean; + isSupersetOf(other: SetLike): boolean; + symmetricDifference(other: SetLike): Set; + union(other: SetLike): Set; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/set-methods-v2 ``` -#### Stage 2 proposals +##### [`Math.sumPrecise`](https://github.com/tc39/proposal-math-sum) +```ts +namespace Math { + sumPrecise(items: Iterable): Number; +} +``` [*CommonJS entry points:*](#commonjs-api) ``` -core-js(-pure)/stage/2 +core-js/proposals/math-sum +``` + +#### Stage 3 proposals[⬆](#index) + +[*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/stage/3 +``` + +##### [Joint iteration](https://github.com/tc39/proposal-joint-iteration)[⬆](#index) +Modules [esnext.iterator.zip](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.zip.js), [esnext.iterator.zip-keyed](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.zip-keyed.js) +```ts +class Iterator { + zip[]>( + iterables: T, + options?: { + mode?: 'shortest' | 'longest' | 'strict'; + padding?: { [K in keyof T]?: T[K] extends Iterable ? U : never }; + } + ): IterableIterator<{ [K in keyof T]: T[K] extends Iterable ? U : never }>; + zipKeyed>>( + iterables: V, + options?: { + mode?: 'shortest' | 'longest' | 'strict'; + padding?: { [P in keyof V]?: V[P] extends Iterable ? U : never }; + } + ): IterableIterator<{ [P in keyof V]: V[P] extends Iterable ? U : never }>; +} +``` +[*CommonJS entry points:*](#commonjs-api) ``` -##### [New `Set` methods](https://github.com/tc39/proposal-set-methods) -Modules [`esnext.set.difference`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.difference.js), [`esnext.set.intersection`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.intersection.js), [`esnext.set.is-disjoint-from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.is-disjoint-from.js), [`esnext.set.is-subset-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.is-subset-of.js), [`esnext.set.is-superset-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.is-superset-of.js), [`esnext.set.symmetric-difference`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.symmetric-difference.js), [`esnext.set.union`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.union.js) +core-js/proposals/joint-iteration +core-js(-pure)/actual|full/iterator/zip +core-js(-pure)/actual|full/iterator/zip-keyed +``` +[*Example*](https://tinyurl.com/vutnf2nu): +```js +Iterator.zip([ + [0, 1, 2], + [3, 4, 5], +]).toArray(); // => [[0, 3], [1, 4], [2, 5]] + +Iterator.zipKeyed({ + a: [0, 1, 2], + b: [3, 4, 5, 6], + c: [7, 8, 9], +}, { + mode: 'longest', + padding: { c: 10 }, +}).toArray(); +/* +[ + { a: 0, b: 3, c: 7 }, + { a: 1, b: 4, c: 8 }, + { a: 2, b: 5, c: 9 }, + { a: undefined, b: 6, c: 10 }, +]; + */ +``` + +##### [`Map` upsert](https://github.com/thumbsupep/proposal-upsert)[⬆](#index) +Modules [`esnext.map.get-or-insert`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.get-or-insert.js), [`esnext.map.get-or-insert-computed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.get-or-insert-computed.js), [`esnext.weak-map.get-or-insert`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-map.get-or-insert.js) and [`esnext.weak-map.get-or-insert-computed`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-map.get-or-insert-computed.js) +```ts +class Map { + getOrInsert(key: any, value: any): any; + getOrInsertComputed(key: any, (key: any) => value: any): any; +} + +class WeakMap { + getOrInsert(key: any, value: any): any; + getOrInsertComputed(key: any, (key: any) => value: any): any; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/map-upsert-v4 +core-js(-pure)/actual|full/map/get-or-insert +core-js(-pure)/actual|full/map/get-or-insert-computed +core-js(-pure)/actual|full/weak-map/get-or-insert +core-js(-pure)/actual|full/weak-map/get-or-insert-computed +``` +[*Examples*](https://tinyurl.com/2a54u5ux): ```js -class Set { - difference(iterable: Iterable): Set; - intersection(iterable: Iterable): Set; - isDisjointFrom(iterable: Iterable): boolean; - isSubsetOf(iterable: Iterable): boolean; - isSupersetOf(iterable: Iterable): boolean; - symmetricDifference(iterable: Iterable): Set; - union(iterable: Iterable): Set; +const map = new Map([['a', 1]]); + +map.getOrInsert('a', 2); // => 1 + +map.getOrInsert('b', 3); // => 3 + +map.getOrInsertComputed('a', key => key); // => 1 + +map.getOrInsertComputed('c', key => key); // => 'c' + +console.log(map); // => Map { 'a': 1, 'b': 3, 'c': 'c' } +``` + +##### [`Symbol.metadata` for decorators metadata proposal](https://github.com/tc39/proposal-decorator-metadata)[⬆](#index) +Modules [`esnext.symbol.metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.metadata.js) and [`esnext.function.metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.function.metadata.js). +```ts +class Symbol { + static metadata: @@metadata; +} + +class Function { + @@metadata: null; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/set-methods -core-js(-pure)/features/set/difference -core-js(-pure)/features/set/intersection -core-js(-pure)/features/set/is-disjoint-from -core-js(-pure)/features/set/is-subset-of -core-js(-pure)/features/set/is-superset-of -core-js(-pure)/features/set/symmetric-difference -core-js(-pure)/features/set/union ``` -[*Examples*](https://goo.gl/QMQdaJ): -```js -new Set([1, 2, 3]).union([3, 4, 5]); // => Set {1, 2, 3, 4, 5} -new Set([1, 2, 3]).intersection([3, 4, 5]); // => Set {3} -new Set([1, 2, 3]).difference([3, 4, 5]); // => Set {1, 2} -new Set([1, 2, 3]).symmetricDifference([3, 4, 5]); // => Set {1, 2, 4, 5} +core-js/proposals/decorator-metadata-v2 +core-js(-pure)/actual|full/symbol/metadata +core-js(-pure)/actual|full/function/metadata +``` -new Set([1, 2, 3]).isDisjointFrom([4, 5, 6]); // => true -new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2, 1]); // => true -new Set([5, 4, 3, 2, 1]).isSupersetOf([1, 2, 3]); // => true +#### Stage 2.7 proposals[⬆](#index) +[*CommonJS entry points:*](#commonjs-api) ``` -##### [`Symbol.{ asyncDispose, dispose }` for `using` statement](https://github.com/tc39/proposal-using-statement) -Modules [`esnext.symbol.dispose`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.symbol.dispose.js) and [`esnext.symbol.async-dispose`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.symbol.async-dispose.js). -```js -class Symbol { - static asyncDispose: @@asyncDispose; - static dispose: @@dispose; +core-js(-pure)/stage/2.7 +``` + +##### [`Iterator` chunking](https://github.com/tc39/proposal-iterator-chunking)[⬆](#index) +Modules [`esnext.iterator.chunks`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.chunks.js) +and [`esnext.iterator.windows`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.windows.js) +```ts +class Iterator { + chunks(chunkSize: number): Iterator; + windows(windowSize: number, undersized?: 'only-full' | 'allow-partial' | undefined): Iterator; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/using-statement -core-js(-pure)/features/symbol/async-dispose -core-js(-pure)/features/symbol/dispose ``` -##### [`Array.isTemplateObject`](https://github.com/tc39/proposal-array-is-template-object) -Module [`esnext.array.is-template-object`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.array.is-template-object.js) +core-js/proposals/iterator-chunking-v2 +core-js(-pure)/full/iterator/chunks +core-js(-pure)/full/iterator/windows +``` +[*Examples*](https://tinyurl.com/24xnkcnn) ```js -class Array { - static isTemplateObject(value: any): boolean -} +const digits = () => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].values(); + +let chunks = Array.from(digits().chunks(2)); // [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]] + +let windows = Array.from(digits().windows(2)); // [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9]] + +let windowsPartial = Array.from([0, 1].values().windows(3, 'allow-partial')); // [[0, 1]] + +let windowsFull = Array.from([0, 1].values().windows(3)); // [] ``` + +#### Stage 2 proposals[⬆](#index) [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/array-is-template-object -core-js(-pure)/features/array/is-template-object ``` -*Example*: -```js -console.log(Array.isTemplateObject((it => it)`qwe${ 123 }asd`)); // => true +core-js(-pure)/stage/2 ``` -##### [Iterator helpers](https://github.com/tc39/proposal-iterator-helpers) -Modules [`esnext.async-iterator.constructor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.constructor.js), [`esnext.async-iterator.as-indexed-pairs`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.as-indexed-pairs.js), [`esnext.async-iterator.drop`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.drop.js), [`esnext.async-iterator.every`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.every.js), [`esnext.async-iterator.filter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.filter.js), [`esnext.async-iterator.find`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.find.js), [`esnext.async-iterator.flat-map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.flat-map.js), [`esnext.async-iterator.for-each`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.for-each.js), [`esnext.async-iterator.from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.from.js), [`esnext.async-iterator.map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.map.js), [`esnext.async-iterator.reduce`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.reduce.js), [`esnext.async-iterator.some`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.some.js), [`esnext.async-iterator.take`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.take.js), [`esnext.async-iterator.to-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.async-iterator.to-array.js), [`esnext.iterator.constructor`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.constructor.js), [`esnext.iterator.as-indexed-pairs`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.as-indexed-pairs.js), [`esnext.iterator.drop`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.drop.js), [`esnext.iterator.every`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.every.js), [`esnext.iterator.filter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.filter.js), [`esnext.iterator.find`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.find.js), [`esnext.iterator.flat-map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.flat-map.js), [`esnext.iterator.for-each`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.for-each.js), [`esnext.iterator.from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.from.js), [`esnext.iterator.map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.map.js), [`esnext.iterator.reduce`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.reduce.js), [`esnext.iterator.some`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.some.js), [`esnext.iterator.take`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.take.js) and [`esnext.iterator.to-array`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.iterator.to-array.js) -```js +##### [`AsyncIterator` helpers](https://github.com/tc39/proposal-async-iterator-helpers)[⬆](#index) +Modules [`esnext.async-iterator.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.constructor.js), [`esnext.async-iterator.drop`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.drop.js), [`esnext.async-iterator.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.every.js), [`esnext.async-iterator.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.filter.js), [`esnext.async-iterator.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.find.js), [`esnext.async-iterator.flat-map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.flat-map.js), [`esnext.async-iterator.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.for-each.js), [`esnext.async-iterator.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.from.js), [`esnext.async-iterator.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.map.js), [`esnext.async-iterator.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.reduce.js), [`esnext.async-iterator.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.some.js), [`esnext.async-iterator.take`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.take.js), [`esnext.async-iterator.to-array`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.async-iterator.to-array.js), , [`esnext.iterator.to-async`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.to-async.js) +```ts class Iterator { - static from(iterable: Iterable): Iterator; - asIndexedPairs(): Iterator<[index, any]>; - drop(limit: uint): Iterator; - every(callbackfn: value: any => boolean): boolean; - filter(callbackfn: value: any => boolean): Iterator; - find(callbackfn: value: any => boolean)): any; - flatMap(callbackfn: value => any): Iterator; - forEach(callbackfn: value => void): void; - map(callbackfn: value => any): Iterator; - reduce(callbackfn: (memo: any, value: any) => any, initialValue: any): any; - some(callbackfn: value: any => boolean): boolean; - take(limit: uint): Iterator; - toArray(): Array; - @@toStringTag: 'Iterator' + toAsync(): AsyncIterator; } class AsyncIterator { - static from(iterable: Iterable): AsyncIterator; - asIndexedPairs(): AsyncIterator<[index, any]>; + static from(iterable: AsyncIterable | Iterable | AsyncIterator): AsyncIterator; drop(limit: uint): AsyncIterator; - every(async callbackfn: value: any => boolean): boolean; - filter(async callbackfn: value: any => boolean): AsyncIterator; - find(async callbackfn: value: any => boolean)): any; - flatMap(async callbackfn: value => any): AsyncIterator; - forEach(async callbackfn: value => void): Promise; - map(async callbackfn: value => any): AsyncIterator; - reduce(async callbackfn: (memo: any, value: any) => any, initialValue: any): Promise; - some(async callbackfn: value: any => boolean): boolean; + every(async callbackfn: (value: any, counter: uint) => boolean): Promise; + filter(async callbackfn: (value: any, counter: uint) => boolean): AsyncIterator; + find(async callbackfn: (value: any, counter: uint) => boolean)): Promise; + flatMap(async callbackfn: (value: any, counter: uint) => AsyncIterable | Iterable | AsyncIterator): AsyncIterator; + forEach(async callbackfn: (value: any, counter: uint) => void): Promise; + map(async callbackfn: (value: any, counter: uint) => any): AsyncIterator; + reduce(async callbackfn: (memo: any, value: any, counter: uint) => any, initialValue: any): Promise; + some(async callbackfn: (value: any, counter: uint) => boolean): Promise; take(limit: uint): AsyncIterator; toArray(): Promise; @@toStringTag: 'AsyncIterator' } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/iterator-helpers -core-js(-pure)/features/async-iterator -core-js(-pure)/features/async-iterator/as-indexed-pairs -core-js(-pure)/features/async-iterator/drop -core-js(-pure)/features/async-iterator/every -core-js(-pure)/features/async-iterator/filter -core-js(-pure)/features/async-iterator/find -core-js(-pure)/features/async-iterator/flat-map -core-js(-pure)/features/async-iterator/for-each -core-js(-pure)/features/async-iterator/from -core-js(-pure)/features/async-iterator/map -core-js(-pure)/features/async-iterator/reduce -core-js(-pure)/features/async-iterator/some -core-js(-pure)/features/async-iterator/take -core-js(-pure)/features/async-iterator/to-array -core-js(-pure)/features/iterator -core-js(-pure)/features/iterator/as-indexed-pairs -core-js(-pure)/features/iterator/drop -core-js(-pure)/features/iterator/every -core-js(-pure)/features/iterator/filter -core-js(-pure)/features/iterator/find -core-js(-pure)/features/iterator/flat-map -core-js(-pure)/features/iterator/for-each -core-js(-pure)/features/iterator/from -core-js(-pure)/features/iterator/map -core-js(-pure)/features/iterator/reduce -core-js(-pure)/features/iterator/some -core-js(-pure)/features/iterator/take -core-js(-pure)/features/iterator/to-array -``` -[Examples](http://es6.zloirock.ru/#log(%5B1%2C%202%2C%203%2C%204%2C%205%2C%206%2C%207%5D.values()%0A%20%20.drop(1)%0A%20%20.take(5)%0A%20%20.filter(it%20%3D%3E%20it%20%25%202)%0A%20%20.map(it%20%3D%3E%20it%20**%202)%0A%20%20.toArray())%3B%20%2F%2F%20%3D%3E%20%5B9%2C%2025%5D%0A%0Alog(Iterator.from(%7B%0A%20%20next%3A%20()%20%3D%3E%20(%7B%20done%3A%20Math.random()%20%3E%20.9%2C%20value%3A%20Math.random()%20*%2010%20%7C%200%20%7D)%0A%7D).toArray())%3B%20%2F%2F%20%3D%3E%20%5B7%2C%206%2C%203%2C%200%2C%202%2C%208%5D%0A%0AAsyncIterator.from(%5B1%2C%202%2C%203%2C%204%2C%205%2C%206%2C%207%5D)%0A%20%20.drop(1)%0A%20%20.take(5)%0A%20%20.filter(it%20%3D%3E%20it%20%25%202)%0A%20%20.map(it%20%3D%3E%20it%20**%202)%0A%20%20.toArray()%0A%20%20.then(log)%3B%20%2F%2F%20%3D%3E%20%5B9%2C%2025%5D): -```js -[1, 2, 3, 4, 5, 6, 7].values() +``` +core-js/proposals/async-iterator-helpers +core-js(-pure)/actual|full/async-iterator +core-js(-pure)/actual|full/async-iterator/drop +core-js(-pure)/actual|full/async-iterator/every +core-js(-pure)/actual|full/async-iterator/filter +core-js(-pure)/actual|full/async-iterator/find +core-js(-pure)/actual|full/async-iterator/flat-map +core-js(-pure)/actual|full/async-iterator/for-each +core-js(-pure)/actual|full/async-iterator/from +core-js(-pure)/actual|full/async-iterator/map +core-js(-pure)/actual|full/async-iterator/reduce +core-js(-pure)/actual|full/async-iterator/some +core-js(-pure)/actual|full/async-iterator/take +core-js(-pure)/actual|full/async-iterator/to-array +core-js(-pure)/actual|full/iterator/to-async +``` +[Examples](https://tinyurl.com/28tet4ek): +```js +await AsyncIterator.from([1, 2, 3, 4, 5, 6, 7]) .drop(1) .take(5) .filter(it => it % 2) .map(it => it ** 2) .toArray(); // => [9, 25] -Iterator.from({ - next: () => ({ done: Math.random() > .9, value: Math.random() * 10 | 0 }) -}).toArray(); // => [7, 6, 3, 0, 2, 8] - -AsyncIterator.from([1, 2, 3, 4, 5, 6, 7]) - .drop(1) - .take(5) - .filter(it => it % 2) - .map(it => it ** 2) - .toArray() - .then(console.log); // => [9, 25] +await [1, 2, 3].values().toAsync().map(async it => it ** 2).toArray(); // => [1, 4, 9] ``` -###### Caveats: -- For preventing prototypes pollution, in the `pure` version, new `%IteratorPrototype%` methods are not added to the real `%IteratorPrototype%`, they available only on wrappers - instead of `[].values().map(fn)` use `Iterator.from([]).map(fn)`. -- Now, we have access to the real `%AsyncIteratorPrototype%` only with usage async generators syntax. So, for compatibility the library with old browsers, we should use `Function` constructor. However, that breaks compatibility with CSP. So, if you wanna use the real `%AsyncIteratorPrototype%`, you should set `USE_FUNCTION_CONSTRUCTOR` option in the `core-js/configurator` to `true`: + +###### Caveats:[⬆](#index) +- For preventing prototypes pollution, in the `pure` version, new `%AsyncIteratorPrototype%` methods are not added to the real `%AsyncIteratorPrototype%`, they available only on wrappers - instead of `[].values().toAsync().map(fn)` use `AsyncIterator.from([]).map(fn)`. +- Now, we have access to the real `%AsyncIteratorPrototype%` only with usage async generators syntax. So, for compatibility of the library with old browsers, we should use `Function` constructor. However, that breaks compatibility with CSP. So, if you wanna use the real `%AsyncIteratorPrototype%`, you should set `USE_FUNCTION_CONSTRUCTOR` option in the `core-js/configurator` to `true`: ```js const configurator = require('core-js/configurator'); configurator({ USE_FUNCTION_CONSTRUCTOR: true }); -require('core-js'); +require('core-js/actual/async-iterator'); (async function * () { /* empty */ })() instanceof AsyncIterator; // => true ``` -##### [`Map#upsert`](https://github.com/thumbsupep/proposal-upsert) -Modules [`esnext.map.upsert`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.upsert.js), [`esnext.map.update-or-insert`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.update-or-insert.js) and [`esnext.weak-map.update-or-insert`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.weak-map.update-or-insert.js) +- As an alternative, you could pass to the `core-js/configurator` an object that will be considered as `%AsyncIteratorPrototype%`: ```js -class Map { - updateOrInsert(key: any, onUpdate: (value: any) => updated: any, onInsert: () => value: any): updated | value; (obsolete in favor `.upsert`) - upsert(key: any, onUpdate: (value: any) => updated: any, onInsert: () => value: any): updated | value; -} +const configurator = require('core-js/configurator'); -class WeakMap { - upsert(key: Object, onUpdate: (value: any) => updated: any, onInsert: () => value: any): updated | value; +const { getPrototypeOf } = Object; + +configurator({ AsyncIteratorPrototype: getPrototypeOf(getPrototypeOf(getPrototypeOf(async function * () { /* empty */ }()))) }); + +require('core-js/actual/async-iterator'); + +(async function * () { /* empty */ })() instanceof AsyncIterator; // => true +``` + +##### [`Iterator.range`](https://github.com/tc39/proposal-Number.range)[⬆](#index) +Module [`esnext.iterator.range`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.iterator.range.js) +```ts +class Iterator { + range(start: number, end: number, options: { step: number = 1, inclusive: boolean = false } | step: number = 1): NumericRangeIterator; + range(start: bigint, end: bigint | Infinity | -Infinity, options: { step: bigint = 1n, inclusive: boolean = false } | step: bigint = 1n): NumericRangeIterator; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/map-upsert -core-js(-pure)/features/map/update-or-insert -core-js(-pure)/features/map/upsert -core-js(-pure)/features/weak-map/upsert ``` -[*Examples*](http://es6.zloirock.ru/#const%20map%20%3D%20new%20Map(%5B%5B'a'%2C%202%5D%5D)%3B%0A%0Amap.upsert('a'%2C%20it%20%3D%3E%20it%20**%202%2C%20()%20%3D%3E%203)%3B%20%2F%2F%20%3D%3E%204%0A%0Amap.upsert('b'%2C%20it%20%3D%3E%20it%20**%202%2C%20()%20%3D%3E%203)%3B%20%2F%2F%20%3D%3E%203%0A%0Alog(map)%3B%20%2F%2F%20%3D%3E%20%7B%20'a'%3A%204%2C%20'b'%3A%203%20%7D): +core-js/proposals/number-range +core-js(-pure)/full/iterator/range +``` +[*Example*](https://tinyurl.com/2gobe777): ```js -const map = new Map([['a', 2]]); - -map.upsert('a', it => it ** 2, () => 3); // => 4 - -map.upsert('b', it => it ** 2, () => 3); // => 3 +for (const i of Iterator.range(1, 10)) { + console.log(i); // => 1, 2, 3, 4, 5, 6, 7, 8, 9 +} -console.log(map); // => Map { 'a': 4, 'b': 3 } +for (const i of Iterator.range(1, 10, { step: 3, inclusive: true })) { + console.log(i); // => 1, 4, 7, 10 +} ``` -#### Stage 1 proposals +##### [`Array.isTemplateObject`](https://github.com/tc39/proposal-array-is-template-object)[⬆](#index) +Module [`esnext.array.is-template-object`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array.is-template-object.js) +```ts +class Array { + static isTemplateObject(value: any): boolean +} +``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js(-pure)/stage/1 ``` -##### [Getting last item from `Array`](https://github.com/keithamus/proposal-array-last) -Modules [`esnext.array.last-item`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.array.last-item.js) and [`esnext.array.last-index`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.array.last-index.js) +core-js/proposals/array-is-template-object +core-js(-pure)/full/array/is-template-object +``` +*Example*: ```js -class Array { - attribute lastItem: any; - readonly attribute lastIndex: uint; +console.log(Array.isTemplateObject((it => it)`qwe${ 123 }asd`)); // => true +``` + +##### [`Number.prototype.clamp`](https://github.com/tc39/proposal-math-clamp)[⬆](#index) +Module [`esnext.number.clamp`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.number.clamp.js) +```ts +class Number { + clamp(min: number, max: number): number; } ``` [*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/math-clamp-v2 +core-js(-pure)/full/number/clamp +``` +[*Example*](https://tinyurl.com/yeyv7nxz): ```js -core-js/proposals/array-last -core-js/features/array/last-item -core-js/features/array/last-index +5.0.clamp(0, 10); // => 5 +-5.0.clamp(0, 10); // => 0 +15.0.clamp(0, 10); // => 10 +```` + +##### [`String.dedent`](https://github.com/tc39/proposal-string-dedent)[⬆](#index) +Module [`esnext.string.dedent`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.string.dedent.js) +```ts +class String { + static dedent(templateOrTag: { raw: Array } | function, ...substitutions: Array): string | function; +} ``` -[*Examples*](https://goo.gl/2TmcMT): +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/string-dedent +core-js(-pure)/full/string/dedent +``` +[*Example*](https://tinyurl.com/2lbnofgo): ```js -[1, 2, 3].lastItem; // => 3 -[1, 2, 3].lastIndex; // => 2 +const message = 42; -const array = [1, 2, 3]; -array.lastItem = 4; +console.log(String.dedent` + print('${ message }') +`); // => print('42') -array; // => [1, 2, 4] +String.dedent(console.log)` + print('${ message }') +`; // => ["print('", "')", raw: Array(2)], 42 ``` -##### [`Promise.try`](https://github.com/tc39/proposal-promise-try) -Module [`esnext.promise.try`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.promise.try.js) -```js -class Promise { - static try(callbackfn: Function): promise; + +##### [`Symbol` predicates](https://github.com/tc39/proposal-symbol-predicates)[⬆](#index) +Modules [`esnext.symbol.is-registered-symbol`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.is-registered-symbol.js), [`esnext.symbol.is-well-known-symbol`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.is-well-known-symbol.js). +```ts +class Symbol { + static isRegisteredSymbol(value: any): boolean; + static isWellKnownSymbol(value: any): boolean; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/promise-try -core-js(-pure)/features/promise/try ``` -[*Examples*](https://goo.gl/k5GGRo): +core-js/proposals/symbol-predicates-v2 +core-js(-pure)/full/symbol/is-registered-symbol +core-js(-pure)/full/symbol/is-well-known-symbol +``` +[*Example*](https://tinyurl.com/2oqoaq7t): ```js -Promise.try(() => 42).then(it => console.log(`Promise, resolved as ${it}`)); +Symbol.isRegisteredSymbol(Symbol.for('key')); // => true +Symbol.isRegisteredSymbol(Symbol('key')); // => false + +Symbol.isWellKnownSymbol(Symbol.iterator); // => true +Symbol.isWellKnownSymbol(Symbol('key')); // => false +``` + +##### [`Symbol.customMatcher` for extractors](https://github.com/tc39/proposal-extractors)[⬆](#index) +Module [`esnext.symbol.custom-matcher`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.custom-matcher.js). +```ts +class Symbol { + static customMatcher: @@customMatcher; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/pattern-extractors +core-js(-pure)/full/symbol/custom-matcher +``` + +#### Stage 1 proposals[⬆](#index) +[*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/stage/1 +``` +##### [`Observable`](https://github.com/zenparsing/es-observable)[⬆](#index) +Modules [`esnext.observable`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.observable.js) and [`esnext.symbol.observable`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.observable.js) +```ts +class Observable { + constructor(subscriber: Function): Observable; + subscribe(observer: Function | { next?: Function, error?: Function, complete?: Function }): Subscription; + @@observable(): this; + static of(...items: Array): Observable; + static from(x: Observable | Iterable): Observable; + static readonly attribute @@species: this; +} -Promise.try(() => { throw 42; }).catch(it => console.log(`Promise, rejected as ${it}`)); +class Symbol { + static observable: @@observable; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/observable +core-js(-pure)/full/observable +core-js(-pure)/full/symbol/observable ``` -#### New collections methods: -##### [New `Set` and `Map` methods](https://github.com/tc39/proposal-collection-methods) -Modules [`esnext.set.add-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.add-all.js), [`esnext.set.delete-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.delete-all.js), [`esnext.set.every`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.every.js), [`esnext.set.filter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.filter.js), [`esnext.set.find`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.find.js), [`esnext.set.join`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.join.js), [`esnext.set.map`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.map.js), [`esnext.set.reduce`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.reduce.js), [`esnext.set.some`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.some.js), [`esnext.map.delete-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.delete-all.js), [`esnext.map.every`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.every.js), [`esnext.map.filter`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.filter.js), [`esnext.map.find`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.find.js), [`esnext.map.find-key`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.find-key.js), [`esnext.map.group-by`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.group-by.js), [`esnext.map.includes`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.includes.js), [`esnext.map.key-by`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.key-by.js), [`esnext.map.key-of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.key-of.js), [`esnext.map.map-keys`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.map-keys.js), [`esnext.map.map-values`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.map-values.js), [`esnext.map.merge`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.merge.js), [`esnext.map.reduce`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.reduce.js), [`esnext.map.some`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.some.js), [`esnext.map.update`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.update.js), [`esnext.weak-set.add-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.weak-set.add-all.js), [`esnext.weak-set.delete-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.weak-set.delete-all.js), [`esnext.weak-map.delete-all`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.weak-map.delete-all.js) -##### [`.of` and `.from` methods on collection constructors](https://github.com/tc39/proposal-setmap-offrom) -Modules [`esnext.set.of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.of.js), [`esnext.set.from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.set.from.js), [`esnext.map.of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.of.js), [`esnext.map.from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.map.from.js), [`esnext.weak-set.of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.weak-set.of.js), [`esnext.weak-set.from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.weak-set.from.js), [`esnext.weak-map.of`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.weak-map.of.js), [`esnext.weak-map.from`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.weak-map.from.js) +*Example*: ```js +new Observable(observer => { + observer.next('hello'); + observer.next('world'); + observer.complete(); +}).subscribe({ + next(it) { console.log(it); }, + complete() { console.log('!'); }, +}); +``` +##### [New collections methods](https://github.com/tc39/proposal-collection-methods)[⬆](#index) +Modules [`esnext.set.add-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.add-all.js), [`esnext.set.delete-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.delete-all.js), [`esnext.set.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.every.js), [`esnext.set.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.filter.js), [`esnext.set.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.find.js), [`esnext.set.join`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.join.js), [`esnext.set.map`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.map.js), [`esnext.set.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.reduce.js), [`esnext.set.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.some.js), [`esnext.map.delete-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.delete-all.js), [`esnext.map.every`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.every.js), [`esnext.map.filter`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.filter.js), [`esnext.map.find`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.find.js), [`esnext.map.find-key`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.find-key.js), [`esnext.map.includes`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.includes.js), [`esnext.map.key-by`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.key-by.js), [`esnext.map.key-of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.key-of.js), [`esnext.map.map-keys`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.map-keys.js), [`esnext.map.map-values`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.map-values.js), [`esnext.map.merge`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.merge.js), [`esnext.map.reduce`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.reduce.js), [`esnext.map.some`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.some.js), [`esnext.map.update`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.update.js), [`esnext.weak-set.add-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-set.add-all.js), [`esnext.weak-set.delete-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-set.delete-all.js), [`esnext.weak-map.delete-all`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-map.delete-all.js) +##### [`.of` and `.from` methods on collection constructors](https://github.com/tc39/proposal-setmap-offrom)[⬆](#index) +Modules [`esnext.set.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.of.js), [`esnext.set.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.set.from.js), [`esnext.map.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.of.js), [`esnext.map.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.map.from.js), [`esnext.weak-set.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-set.of.js), [`esnext.weak-set.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-set.from.js), [`esnext.weak-map.of`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-map.of.js), [`esnext.weak-map.from`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.weak-map.from.js) +```ts class Set { static of(...args: Array): Set; static from(iterable: Iterable, mapFn?: (value: any, index: number) => any, thisArg?: any): Set; @@ -1966,7 +3147,6 @@ class Set { } class Map { - static groupBy(iterable: Iterable, callbackfn?: (value: any) => any): Map; static of(...args: Array<[key, value]>): Map; static from(iterable: Iterable, mapFn?: (value: any, index: number) => [key: any, value: any], thisArg?: any): Map; static keyBy(iterable: Iterable, callbackfn?: (value: any) => any): Map; @@ -1999,64 +3179,63 @@ class WeakMap { } ``` [*CommonJS entry points:*](#commonjs-api) -```js +``` core-js/proposals/collection-methods core-js/proposals/collection-of-from -core-js(-pure)/features/set/add-all -core-js(-pure)/features/set/delete-all -core-js(-pure)/features/set/every -core-js(-pure)/features/set/filter -core-js(-pure)/features/set/find -core-js(-pure)/features/set/from -core-js(-pure)/features/set/join -core-js(-pure)/features/set/map -core-js(-pure)/features/set/of -core-js(-pure)/features/set/reduce -core-js(-pure)/features/set/some -core-js(-pure)/features/map/delete-all -core-js(-pure)/features/map/every -core-js(-pure)/features/map/filter -core-js(-pure)/features/map/find -core-js(-pure)/features/map/find-key -core-js(-pure)/features/map/from -core-js(-pure)/features/map/group-by -core-js(-pure)/features/map/includes -core-js(-pure)/features/map/key-by -core-js(-pure)/features/map/key-of -core-js(-pure)/features/map/map-keys -core-js(-pure)/features/map/map-values -core-js(-pure)/features/map/merge -core-js(-pure)/features/map/of -core-js(-pure)/features/map/reduce -core-js(-pure)/features/map/some -core-js(-pure)/features/map/update -core-js(-pure)/features/weak-set/add-all -core-js(-pure)/features/weak-set/delete-all -core-js(-pure)/features/weak-set/of -core-js(-pure)/features/weak-set/from -core-js(-pure)/features/weak-map/delete-all -core-js(-pure)/features/weak-map/of -core-js(-pure)/features/weak-map/from -``` -`.of` / `.from` [*examples*](https://goo.gl/mSC7eU): +core-js(-pure)/full/set/add-all +core-js(-pure)/full/set/delete-all +core-js(-pure)/full/set/every +core-js(-pure)/full/set/filter +core-js(-pure)/full/set/find +core-js(-pure)/full/set/from +core-js(-pure)/full/set/join +core-js(-pure)/full/set/map +core-js(-pure)/full/set/of +core-js(-pure)/full/set/reduce +core-js(-pure)/full/set/some +core-js(-pure)/full/map/delete-all +core-js(-pure)/full/map/every +core-js(-pure)/full/map/filter +core-js(-pure)/full/map/find +core-js(-pure)/full/map/find-key +core-js(-pure)/full/map/from +core-js(-pure)/full/map/includes +core-js(-pure)/full/map/key-by +core-js(-pure)/full/map/key-of +core-js(-pure)/full/map/map-keys +core-js(-pure)/full/map/map-values +core-js(-pure)/full/map/merge +core-js(-pure)/full/map/of +core-js(-pure)/full/map/reduce +core-js(-pure)/full/map/some +core-js(-pure)/full/map/update +core-js(-pure)/full/weak-set/add-all +core-js(-pure)/full/weak-set/delete-all +core-js(-pure)/full/weak-set/of +core-js(-pure)/full/weak-set/from +core-js(-pure)/full/weak-map/delete-all +core-js(-pure)/full/weak-map/of +core-js(-pure)/full/weak-map/from +``` +`.of` / `.from` [*examples*](https://tinyurl.com/27fktwtw): ```js Set.of(1, 2, 3, 2, 1); // => Set {1, 2, 3} Map.from([[1, 2], [3, 4]], ([key, value]) => [key ** 2, value ** 2]); // => Map { 1: 4, 9: 16 } ``` -##### [`compositeKey` and `compositeSymbol` methods](https://github.com/tc39/proposal-richer-keys/tree/master/compositeKey) -Modules [`esnext.composite-key`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.composite-key.js) and [`esnext.composite-symbol`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.composite-symbol.js) -```js +##### [`compositeKey` and `compositeSymbol`](https://github.com/tc39/proposal-richer-keys/tree/master/compositeKey)[⬆](#index) +Modules [`esnext.composite-key`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.composite-key.js) and [`esnext.composite-symbol`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.composite-symbol.js) +```ts function compositeKey(...args: Array): object; function compositeSymbol(...args: Array): symbol; ``` [*CommonJS entry points:*](#commonjs-api) -```js +``` core-js/proposals/keys-composition -core-js(-pure)/features/composite-key -core-js(-pure)/features/composite-symbol +core-js(-pure)/full/composite-key +core-js(-pure)/full/composite-symbol ``` -[*Examples*](https://goo.gl/2oPAH7): +[*Examples*](https://tinyurl.com/2c8pczur): ```js // returns a symbol const symbol = compositeSymbol({}); @@ -2073,6 +3252,7 @@ const a = ['a']; const b = ['b']; const c = ['c']; +/* eslint-disable no-self-compare -- example */ console.log(compositeSymbol(a) === compositeSymbol(a)); // => true console.log(compositeSymbol(a) !== compositeSymbol(['a'])); // => true console.log(compositeSymbol(a, 1) === compositeSymbol(a, 1)); // => true @@ -2082,198 +3262,207 @@ console.log(compositeSymbol(1, a) === compositeSymbol(1, a)); // => true console.log(compositeSymbol(1, a, 2, b) === compositeSymbol(1, a, 2, b)); // => true console.log(compositeSymbol(a, a) === compositeSymbol(a, a)); // => true ``` -##### [`Observable`](https://github.com/zenparsing/es-observable) -Modules [`esnext.observable`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.observable.js) and [`esnext.symbol.observable`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.symbol.observable.js) -```js -class Observable { - constructor(subscriber: Function): Observable; - subscribe(observer: Function | { next?: Function, error?: Function, complete?: Function }): Subscription; - @@observable(): this; - static of(...items: Aray): Observable; - static from(x: Observable | Iterable): Observable; - static readonly attribute @@species: this; +##### [Array filtering](https://github.com/tc39/proposal-array-filtering)[⬆](#index) +Modules [`esnext.array.filter-reject`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array.filter-reject.js) and [`esnext.typed-array.filter-reject`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.typed-array.filter-reject.js). +```ts +class Array { + filterReject(callbackfn: (value: any, index: number, target: any) => boolean, thisArg?: any): Array; } -class Symbol { - static observable: @@observable; +class %TypedArray% { + filterReject(callbackfn: (value: number, index: number, target: %TypedArray%) => boolean, thisArg?: any): %TypedArray%; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/observable -core-js(-pure)/features/observable -core-js(-pure)/features/symbol/observable ``` -[*Examples*](http://goo.gl/1LDywi): -```js -new Observable(observer => { - observer.next('hello'); - observer.next('world'); - observer.complete(); -}).subscribe({ - next(it) { console.log(it); }, - complete() { console.log('!'); } -}); +core-js/proposals/array-filtering-stage-1 +core-js(-pure)/full/array(/virtual)/filter-reject +core-js/full/typed-array/filter-reject ``` -##### [`Math` extensions](https://github.com/rwaldron/proposal-math-extensions) -Modules [`esnext.math.clamp`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.clamp.js), [`esnext.math.deg-per-rad`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.deg-per-rad.js), [`esnext.math.degrees`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.degrees.js), [`esnext.math.fscale`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.fscale.js), [`esnext.math.rad-per-deg`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.rad-per-deg.js), [`esnext.math.radians`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.radians.js) and [`esnext.math.scale`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.scale.js) +[*Examples*](https://is.gd/jJcoWw): ```js -namespace Math { - DEG_PER_RAD: number; - RAD_PER_DEG: number; - clamp(x: number, lower: number, upper: number): number; - degrees(radians: number): number; - fscale(x: number, inLow: number, inHigh: number, outLow: number, outHigh: number): number; - radians(degrees: number): number; - scale(x: number, inLow: number, inHigh: number, outLow: number, outHigh: number): number; +[1, 2, 3, 4, 5].filterReject(it => it % 2); // => [2, 4] +``` +##### [Array deduplication](https://github.com/tc39/proposal-array-unique)[⬆](#index) +Modules [`esnext.array.unique-by`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.array.unique-by.js) and [`esnext.typed-array.unique-by`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.typed-array.unique-by.js) +```ts +class Array { + uniqueBy(resolver?: (item: any) => any): Array; +} + +class %TypedArray% { + uniqueBy(resolver?: (item: any) => any): %TypedArray%;; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/math-extensions -core-js(-pure)/features/math/clamp -core-js(-pure)/features/math/deg-per-rad -core-js(-pure)/features/math/degrees -core-js(-pure)/features/math/fscale -core-js(-pure)/features/math/rad-per-deg -core-js(-pure)/features/math/radians -core-js(-pure)/features/math/scale ``` -##### [`Math.signbit`](https://github.com/tc39/proposal-Math.signbit) -Module [`esnext.math.signbit`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.signbit.js) +core-js/proposals/array-unique +core-js(-pure)/full/array(/virtual)/unique-by +core-js/full/typed-array/unique-by +``` +[*Examples*](https://is.gd/lilNPu): ```js -namespace Math { - signbit(x: number): boolean; +[1, 2, 3, 2, 1].uniqueBy(); // [1, 2, 3] + +[ + { id: 1, uid: 10000 }, + { id: 2, uid: 10000 }, + { id: 3, uid: 10001 }, +].uniqueBy(it => it.uid); // => [{ id: 1, uid: 10000 }, { id: 3, uid: 10001 }] +``` + +##### [`DataView` get / set `Uint8Clamped` methods](https://github.com/tc39/proposal-dataview-get-set-uint8clamped)[⬆](#index) +Modules [`esnext.data-view.get-uint8-clamped`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.data-view.get-uint8-clamped.js) and [`esnext.data-view.set-uint8-clamped`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.data-view.set-uint8-clamped.js) +```ts +class DataView { + getUint8Clamped(offset: any): uint8 + setUint8Clamped(offset: any, value: any): void; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/math-signbit -core-js(-pure)/features/math/signbit ``` -[*Examples*](https://goo.gl/rPWbzZ): -```js -Math.signbit(NaN); // => NaN -Math.signbit(1); // => true -Math.signbit(-1); // => false -Math.signbit(0); // => true -Math.signbit(-0); // => false +core-js/proposals/data-view-get-set-uint8-clamped +core-js/full/dataview/get-uint8-clamped +core-js/full/dataview/set-uint8-clamped ``` -##### [`Number.fromString`](https://github.com/tc39/proposal-number-fromstring) -Module [`esnext.number.from-string`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.number.from-string.js) +[Examples](https://tinyurl.com/2h4zv8sw): ```js +const view = new DataView(new ArrayBuffer(1)); +view.setUint8Clamped(0, 100500); +console.log(view.getUint8Clamped(0)); // => 255 +``` + +##### [`Number.fromString`](https://github.com/tc39/proposal-number-fromstring)[⬆](#index) +Module [`esnext.number.from-string`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.number.from-string.js) +```ts class Number { fromString(string: string, radix: number): number; } ``` [*CommonJS entry points:*](#commonjs-api) -```js +``` core-js/proposals/number-from-string -core-js(-pure)/features/number/from-string +core-js(-pure)/full/number/from-string ``` -##### [`String#codePoints`](https://github.com/tc39/proposal-string-prototype-codepoints) -Module [`esnext.string.code-points`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.string.code-points.js) -```js + +##### [`String.cooked`](https://github.com/tc39/proposal-string-cooked)[⬆](#index) +Module [`esnext.string.cooked`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.string.cooked.js) +```ts class String { - codePoints(): Iterator<{ codePoint, position }>; + static cooked(template: Array, ...substitutions: Array): string; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/string-code-points -core-js(-pure)/features/string/code-points ``` -[*Example*](https://goo.gl/Jt7SsD): +core-js/proposals/string-cooked +core-js(-pure)/full/string/cooked +``` +[*Example*](https://is.gd/7QPnss): ```js -for (let { codePoint, position } of 'qwe'.codePoints()) { - console.log(codePoint); // => 113, 119, 101 - console.log(position); // => 0, 1, 2 +function safePath(strings, ...subs) { + return String.cooked(strings, ...subs.map(sub => encodeURIComponent(sub))); } + +let id = 'spottie?'; + +safePath`/cats/${ id }`; // => /cats/spottie%3F ``` -##### [Seeded pseudo-random numbers](https://github.com/tc39/proposal-seeded-random) -Module [`esnext.math.seeded-prng`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.seeded-prng.js) -```js -class Math { - seededPRNG({ seed: number }): Iterator; +##### [`String.prototype.codePoints`](https://github.com/tc39/proposal-string-prototype-codepoints)[⬆](#index) +Module [`esnext.string.code-points`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.string.code-points.js) +```ts +class String { + codePoints(): Iterator<{ codePoint, position }>; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/seeded-random -core-js(-pure)/features/math/seeded-prng ``` -[*Example*](https://goo.gl/oj3WgQ): +core-js/proposals/string-code-points +core-js(-pure)/full/string/code-points +``` +[*Example*](https://tinyurl.com/2bt9bhwn): ```js -for (let x of Math.seededPRNG({ seed: 42 })) { - console.log(x); // => 0.16461519912315087, 0.2203933906000046, 0.8249682894209105 - if (x > .8) break; +for (let { codePoint, position } of 'qwe'.codePoints()) { + console.log(codePoint); // => 113, 119, 101 + console.log(position); // => 0, 1, 2 } ``` -##### [`Symbol.patternMatch` for pattern matching](https://github.com/tc39/proposal-pattern-matching) -Module [`esnext.symbol.pattern-match`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.symbol.pattern-match.js). -```js + +##### [`Symbol.customMatcher` for pattern matching](https://github.com/tc39/proposal-pattern-matching)[⬆](#index) +Module [`esnext.symbol.custom-matcher`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.symbol.custom-matcher.js). +```ts class Symbol { - static patternMatch: @@patternMatch; + static customMatcher: @@customMatcher; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/pattern-matching -core-js(-pure)/features/symbol/pattern-match +``` +core-js/proposals/pattern-matching-v2 +core-js(-pure)/full/symbol/custom-matcher ``` -#### Stage 0 proposals +#### Stage 0 proposals[⬆](#index) [*CommonJS entry points:*](#commonjs-api) -```js +``` core-js(-pure)/stage/0 ``` -##### [`URL`](https://github.com/jasnell/proposal-url) -See more info [in web standards namespace](#url-and-urlsearchparams) -##### [`String#at`](https://github.com/mathiasbynens/String.prototype.at) -Module [`esnext.string.at`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.string.at.js) -```js -class String { - at(index: number): string; +##### [`Function.prototype.demethodize`](https://github.com/js-choi/proposal-function-demethodize)[⬆](#index) +Module [`esnext.function.demethodize`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.function.demethodize.js) +```ts +class Function { + demethodize(): Function; } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/proposals/string-at -core-js(-pure)/features/string/at -core-js(-pure)/features/string/virtual/at ``` -[*Examples*](http://goo.gl/XluXI8): -```js -'a𠮷b'.at(1); // => '𠮷' -'a𠮷b'.at(1).length; // => 2 +core-js/proposals/function-demethodize +core-js(-pure)/full/function/demethodize +core-js(-pure)/full/function/virtual/demethodize ``` -##### [Efficient 64 bit arithmetic](https://gist.github.com/BrendanEich/4294d5c212a6d2254703) -Modules [`esnext.math.iaddh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.iaddh.js), [`esnext.math.isubh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.isubh.js), [`esnext.math.imulh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.imulh.js) and [`esnext.math.umulh`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.math.umulh.js) +[*Examples*](https://tinyurl.com/2ltmohgl): ```js -namespace Math { - iaddh(lo0: number, hi0: number, lo1: number, hi1: number): number; - isubh(lo0: number, hi0: number, lo1: number, hi1: number): number; - imulh(a: number, b: number): number; - umulh(a: number, b: number): number; +const slice = Array.prototype.slice.demethodize(); + +slice([1, 2, 3], 1); // => [2, 3] +``` +##### [`Function.{ isCallable, isConstructor }`](https://github.com/caitp/TC39-Proposals/blob/trunk/tc39-reflect-isconstructor-iscallable.md)[⬆](#index) + +Modules [`esnext.function.is-callable`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.function.is-callable.js), [`esnext.function.is-constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.function.is-constructor.js) +```ts +class Function { + static isCallable(value: any): boolean; + static isConstructor(value: any): boolean; } ``` [*CommonJS entry points:*](#commonjs-api) +``` +core-js/proposals/function-is-callable-is-constructor +core-js(-pure)/full/function/is-callable +core-js(-pure)/full/function/is-constructor +``` +[*Examples*](https://is.gd/Kof1he): ```js -core-js/proposals/efficient-64-bit-arithmetic -core-js(-pure)/features/math/iaddh -core-js(-pure)/features/math/isubh -core-js(-pure)/features/math/imulh -core-js(-pure)/features/math/umulh +/* eslint-disable prefer-arrow-callback -- example */ +Function.isCallable(null); // => false +Function.isCallable({}); // => false +Function.isCallable(function () { /* empty */ }); // => true +Function.isCallable(() => { /* empty */ }); // => true +Function.isCallable(class { /* empty */ }); // => false + +Function.isConstructor(null); // => false +Function.isConstructor({}); // => false +Function.isConstructor(function () { /* empty */ }); // => true +Function.isConstructor(() => { /* empty */ }); // => false +Function.isConstructor(class { /* empty */ }); // => true ``` -#### Pre-stage 0 proposals +#### Pre-stage 0 proposals[⬆](#index) [*CommonJS entry points:*](#commonjs-api) -```js +``` core-js(-pure)/stage/pre ``` -##### [`Reflect` metadata](https://github.com/rbuckton/reflect-metadata) -Modules [`esnext.reflect.define-metadata`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.define-metadata.js), [`esnext.reflect.delete-metadata`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.delete-metadata.js), [`esnext.reflect.get-metadata`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.get-metadata.js), [`esnext.reflect.get-metadata-keys`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.get-metadata-keys.js), [`esnext.reflect.get-own-metadata`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.get-own-metadata.js), [`esnext.reflect.get-own-metadata-keys`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.get-own-metadata-keys.js), [`esnext.reflect.has-metadata`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.has-metadata.js), [`esnext.reflect.has-own-metadata`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.has-own-metadata.js) and [`esnext.reflect.metadata`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/esnext.reflect.metadata.js). -```js +##### [`Reflect` metadata](https://github.com/rbuckton/reflect-metadata)[⬆](#index) +Modules [`esnext.reflect.define-metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.define-metadata.js), [`esnext.reflect.delete-metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.delete-metadata.js), [`esnext.reflect.get-metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.get-metadata.js), [`esnext.reflect.get-metadata-keys`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.get-metadata-keys.js), [`esnext.reflect.get-own-metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.get-own-metadata.js), [`esnext.reflect.get-own-metadata-keys`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.get-own-metadata-keys.js), [`esnext.reflect.has-metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.has-metadata.js), [`esnext.reflect.has-own-metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.has-own-metadata.js) and [`esnext.reflect.metadata`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/esnext.reflect.metadata.js). +```ts namespace Reflect { defineMetadata(metadataKey: any, metadataValue: any, target: Object, propertyKey?: PropertyKey): void; getMetadata(metadataKey: any, target: Object, propertyKey?: PropertyKey): any; @@ -2287,19 +3476,19 @@ namespace Reflect { } ``` [*CommonJS entry points:*](#commonjs-api) -```js +``` core-js/proposals/reflect-metadata -core-js(-pure)/features/reflect/define-metadata -core-js(-pure)/features/reflect/delete-metadata -core-js(-pure)/features/reflect/get-metadata -core-js(-pure)/features/reflect/get-metadata-keys -core-js(-pure)/features/reflect/get-own-metadata -core-js(-pure)/features/reflect/get-own-metadata-keys -core-js(-pure)/features/reflect/has-metadata -core-js(-pure)/features/reflect/has-own-metadata -core-js(-pure)/features/reflect/metadata -``` -[*Examples*](http://goo.gl/KCo3PS): +core-js(-pure)/full/reflect/define-metadata +core-js(-pure)/full/reflect/delete-metadata +core-js(-pure)/full/reflect/get-metadata +core-js(-pure)/full/reflect/get-metadata-keys +core-js(-pure)/full/reflect/get-own-metadata +core-js(-pure)/full/reflect/get-own-metadata-keys +core-js(-pure)/full/reflect/has-metadata +core-js(-pure)/full/reflect/has-own-metadata +core-js(-pure)/full/reflect/metadata +``` +[*Examples*](https://tinyurl.com/27t6a5ya): ```js let object = {}; Reflect.defineMetadata('foo', 'bar', object); @@ -2308,22 +3497,92 @@ Reflect.getOwnMetadataKeys(object); // => ['foo'] Reflect.getOwnMetadata('foo', object); // => 'bar' ``` -### Web standards +### Web standards[⬆](#index) +#### `self`[⬆](#index) +[Spec](https://html.spec.whatwg.org/multipage/window-object.html#dom-self), module [`web.self`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.self.js) +```ts +getter self: GlobalThisValue; +``` [*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/stable|actual|full/self +``` +[*Examples*](https://tinyurl.com/27nghouh): ```js -core-js(-pure)/web +// eslint-disable-next-line no-restricted-globals -- example +self.Array === Array; // => true +``` + +#### `structuredClone`[⬆](#index) +[Spec](https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone), module [`web.structured-clone`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.structured-clone.js) +```ts +function structuredClone(value: Serializable, { transfer?: Sequence }): any; +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/stable|actual|full/structured-clone +``` +[*Examples*](https://is.gd/RhK7TW): +```js +const structured = [{ a: 42 }]; +const sclone = structuredClone(structured); +console.log(sclone); // => [{ a: 42 }] +console.log(structured !== sclone); // => true +console.log(structured[0] !== sclone[0]); // => true + +const circular = {}; +circular.circular = circular; +const cclone = structuredClone(circular); +console.log(cclone.circular === cclone); // => true + +structuredClone(42); // => 42 +structuredClone({ x: 42 }); // => { x: 42 } +structuredClone([1, 2, 3]); // => [1, 2, 3] +structuredClone(new Set([1, 2, 3])); // => Set{ 1, 2, 3 } +structuredClone(new Map([['a', 1], ['b', 2]])); // => Map{ a: 1, b: 2 } +structuredClone(new Int8Array([1, 2, 3])); // => new Int8Array([1, 2, 3]) +structuredClone(new AggregateError([1, 2, 3], 'message')); // => new AggregateError([1, 2, 3], 'message')) +structuredClone(new TypeError('message', { cause: 42 })); // => new TypeError('message', { cause: 42 }) +structuredClone(new DOMException('message', 'DataCloneError')); // => new DOMException('message', 'DataCloneError') +structuredClone(document.getElementById('myfileinput')); // => new FileList +structuredClone(new DOMPoint(1, 2, 3, 4)); // => new DOMPoint(1, 2, 3, 4) +structuredClone(new Blob(['test'])); // => new Blob(['test']) +structuredClone(new ImageData(8, 8)); // => new ImageData(8, 8) +// etc. + +structuredClone(new WeakMap()); // => DataCloneError on non-serializable types +``` +> [!WARNING] +> - Many platform types cannot be transferred in most engines since we have no way to polyfill this behavior, however `.transfer` option works for some platform types. I recommend avoiding this option. +> - Some specific platform types can't be cloned in old engines. Mainly it's very specific types or very old engines, but here are some exceptions. For example, we have no sync way to clone `ImageBitmap` in Safari 14.0- or Firefox 83-, so it's recommended to look to the [polyfill source](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.structured-clone.js) if you wanna clone something specific. + +#### Base64 utility methods[⬆](#index) +[Specification](https://html.spec.whatwg.org/multipage/webappapis.html#atob), [MDN](https://developer.mozilla.org/en-US/docs/Glossary/Base64). Modules [`web.atob`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.atob.js), [`web.btoa`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.btoa.js). +```ts +function atob(data: string): string; +function btoa(data: string): string; +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/stable|actual|full/atob +core-js(-pure)/stable|actual|full/btoa ``` -#### `setTimeout` and `setInterval` -Module [`web.timers`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/web.timers.js). Additional arguments fix for IE9-. +[*Examples*](https://is.gd/4Nxmzn): ```js +btoa('hi, core-js'); // => 'aGksIGNvcmUtanM=' +atob('aGksIGNvcmUtanM='); // => 'hi, core-js' +``` + +#### `setTimeout` and `setInterval`[⬆](#index) +Module [`web.timers`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.timers.js). Additional arguments fix for IE9-. +```ts function setTimeout(callback: any, time: any, ...args: Array): number; function setInterval(callback: any, time: any, ...args: Array): number; ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js(-pure)/web/timers -core-js(-pure)/stable|features/set-timeout -core-js(-pure)/stable|features/set-interval +``` +core-js(-pure)/stable|actual|full/set-timeout +core-js(-pure)/stable|actual|full/set-interval ``` ```js // Before: @@ -2331,19 +3590,18 @@ setTimeout(log.bind(null, 42), 1000); // After: setTimeout(log, 1000, 42); ``` -#### `setImmediate` -Module [`web.immediate`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/web.immediate.js). [`setImmediate`](http://w3c.github.io/setImmediate/) polyfill. -```js +#### `setImmediate`[⬆](#index) +Module [`web.immediate`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.immediate.js). [`setImmediate`](https://w3c.github.io/setImmediate/) polyfill. +```ts function setImmediate(callback: any, ...args: Array): number; function clearImmediate(id: number): void; ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js(-pure)/web/immediate -core-js(-pure)/stable|features/set-immediate -core-js(-pure)/stable|features/clear-immediate ``` -[*Examples*](http://goo.gl/6nXGrx): +core-js(-pure)/stable|actual|full/set-immediate +core-js(-pure)/stable|actual|full/clear-immediate +``` +[*Examples*](https://tinyurl.com/25u8y8ks): ```js setImmediate((arg1, arg2) => { console.log(arg1, arg2); // => Message will be displayed with minimum delay @@ -2354,24 +3612,23 @@ clearImmediate(setImmediate(() => { })); ``` -#### `queueMicrotask` -[Spec](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-queuemicrotask), module [`web.queue-microtask`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/web.queue-microtask.js) -```js +#### `queueMicrotask`[⬆](#index) +[Spec](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-queuemicrotask), module [`web.queue-microtask`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.queue-microtask.js) +```ts function queueMicrotask(fn: Function): void; ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js/web/queue-microtask -core-js(-pure)/stable|features/queue-microtask ``` -[*Examples*](https://goo.gl/nsW8P9): +core-js(-pure)/stable|actual|full/queue-microtask +``` +[*Examples*](https://tinyurl.com/2dk9f3zm): ```js queueMicrotask(() => console.log('called as microtask')); ``` -#### `URL` and `URLSearchParams` -[`URL` standard](https://url.spec.whatwg.org/) implementation. Modules [`web.url`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/web.url.js), [`web.url.to-json`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/web.url.to-json.js), [`web.url-search-params`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/web.url-search-params.js). -```js +#### `URL` and `URLSearchParams`[⬆](#index) +[`URL` standard](https://url.spec.whatwg.org/) implementation. Modules [`web.url`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.js), [`web.url.can-parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.can-parse.js), [`web.url.parse`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.parse.js), [`web.url.to-json`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url.to-json.js), [`web.url-search-params`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.js), [`web.url-search-params.delete`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.delete.js), [`web.url-search-params.has`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.has.js), [`web.url-search-params.size`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.url-search-params.size.js). +```ts class URL { constructor(url: string, base?: string); attribute href: string; @@ -2388,15 +3645,17 @@ class URL { attribute hash: string; toJSON(): string; toString(): string; + static canParse(url: string, base?: string): boolean; + static parse(url: string, base?: string): URL | null; } class URLSearchParams { constructor(params?: string | Iterable<[key, value]> | Object); append(name: string, value: string): void; - delete(name: string): void; + delete(name: string, value?: string): void; get(name: string): string | void; getAll(name: string): Array; - has(name: string): boolean; + has(name: string, value?: string): boolean; set(name: string, value: string): void; sort(): void; toString(): string; @@ -2405,25 +3664,30 @@ class URLSearchParams { keys(): Iterator; values(): Iterator; @@iterator(): Iterator<[key, value]>; + readonly attribute size: number; } ``` [*CommonJS entry points:*](#commonjs-api) -```js +``` core-js/proposals/url -core-js(-pure)/web/url -core-js(-pure)/web/url-search-params -core-js(-pure)/stable|features/url -core-js/stable|features/url/to-json -core-js(-pure)/stable|features/url-search-params -core-js/stable|features/url-search-params/sort +core-js(-pure)/stable|actual|full/url +core-js(-pure)/stable|actual|full/url/can-parse +core-js/stable|actual|full/url/to-json +core-js(-pure)/stable|actual|full/url-search-params ``` -[*Examples*](https://goo.gl/kksjwV): +[*Examples*](https://tinyurl.com/2yz45vol): ```js -const url = new URL('http://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment'); +URL.canParse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); // => true +URL.canParse('https'); // => false -console.log(url.href); // => 'http://login:password@example.com:8080/foo/bar?a=1&b=2#fragment' -console.log(url.origin); // => 'http://example.com:8080/' -console.log(url.protocol); // => 'http:' +URL.parse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); // => url +URL.parse('https'); // => null + +const url = new URL('https://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment'); + +console.log(url.href); // => 'https://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment' +console.log(url.origin); // => 'https://example.com:8080/' +console.log(url.protocol); // => 'https:' console.log(url.username); // => 'login' console.log(url.password); // => 'password' console.log(url.host); // => 'example.com:8080' @@ -2432,42 +3696,80 @@ console.log(url.port); // => '8080' console.log(url.pathname); // => '/foo/bar' console.log(url.search); // => '?a=1&b=2&a=3' console.log(url.hash); // => '#fragment' -console.log(url.toJSON()); // => 'http://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment' -console.log(url.toString()); // => 'http://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment' +console.log(url.toJSON()); // => 'https://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment' +console.log(url.toString()); // => 'https://login:password@example.com:8080/foo/bar?a=1&b=2&a=3#fragment' for (let [key, value] of url.searchParams) { - console.log(key); // => 'a', 'b' - console.log(value); // => '1', '2' + console.log(key); // => 'a', 'b', 'a' + console.log(value); // => '1', '2', '3' } url.pathname = ''; -url.searchParams.append('c', 3); +url.searchParams.append('c', 4); -console.log(url.search); // => '?a=1&b=2&c=3' -console.log(url.href); // => 'http://login:password@example.com:8080/?a=1&a=3&b=2&c=4#fragment' +console.log(url.search); // => '?a=1&b=2&a=3&c=4' +console.log(url.href); // => 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment' const params = new URLSearchParams('?a=1&b=2&a=3'); params.append('c', 4); params.append('a', 2); +params.delete('a', 1); params.sort(); +console.log(params.size); // => 4 + for (let [key, value] of params) { - console.log(key); // => 'a', 'a', 'a', 'b', 'c' - console.log(value); // => '1', '3', '2', '2', '4' + console.log(key); // => 'a', 'a', 'b', 'c' + console.log(value); // => '3', '2', '2', '4' } -console.log(params.toString()); // => 'a=1&a=3&a=2&b=2&c=4' +console.log(params.has('a')); // => true +console.log(params.has('a', 3)); // => true +console.log(params.has('a', 4)); // => false + +console.log(params.toString()); // => 'a=3&a=2&b=2&c=4' ``` -##### Caveats when using `URL` and `URLSearchParams`: -- IE8 does not support setters, so they do not work on `URL` instances. However, `URL` constructor can be used for basic `URL` parsing. -- Legacy encodings in a search query are not supported. Also, `core-js` implementation has some other encoding-related issues. -- `URL` implementations from all of the popular browsers have much more problems than `core-js`, however, replacing all of them does not looks like a good idea. You can customize the aggressiveness of polyfill [by your requirements](#configurable-level-of-aggressiveness). +> [!WARNING] +> - IE8 does not support setters, so they do not work on `URL` instances. However, `URL` constructor can be used for basic `URL` parsing. +> - Legacy encodings in a search query are not supported. Also, `core-js` implementation has some other encoding-related issues. +> - `URL` implementations from all of the popular browsers have significantly more problems than `core-js`, however, replacing all of them does not look like a good idea. You can customize the aggressiveness of polyfill [by your requirements](#configurable-level-of-aggressiveness). -#### Iterable DOM collections -Some DOM collections should have [iterable interface](https://heycam.github.io/webidl/#idl-iterable) or should be [inherited from `Array`](https://heycam.github.io/webidl/#LegacyArrayClass). That means they should have `forEach`, `keys`, `values`, `entries` and `@@iterator` methods for iteration. So add them. Modules [`web.dom-collections.iterator`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/web.dom-collections.iterator.js) and [`web.dom-collections.for-each`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/web.dom-collections.for-each.js). +##### `DOMException`:[⬆](#index) +[The specification.](https://webidl.spec.whatwg.org/#idl-DOMException) Modules [`web.dom-exception.constructor`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-exception.constructor.js), [`web.dom-exception.stack`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-exception.stack.js), [`web.dom-exception.to-string-tag`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-exception.to-string-tag.js). +```ts +class DOMException { + constructor(message: string, name?: string); + readonly attribute name: string; + readonly attribute message: string; + readonly attribute code: string; + attribute stack: string; // in engines that should have it + @@toStringTag: 'DOMException'; +} +``` +[*CommonJS entry points:*](#commonjs-api) +``` +core-js(-pure)/stable|actual|full/dom-exception +core-js(-pure)/stable|actual|full/dom-exception/constructor +core-js/stable|actual|full/dom-exception/to-string-tag +``` +[*Examples*](https://is.gd/pI6oTN): ```js +const exception = new DOMException('error', 'DataCloneError'); +console.log(exception.name); // => 'DataCloneError' +console.log(exception.message); // => 'error' +console.log(exception.code); // => 25 +console.log(typeof exception.stack); // => 'string' +console.log(exception instanceof DOMException); // => true +console.log(exception instanceof Error); // => true +console.log(exception.toString()); // => 'DataCloneError: error' +console.log(Object.prototype.toString.call(exception)); // => '[object DOMException]' +``` + +#### Iterable DOM collections[⬆](#index) +Some DOM collections should have [iterable interface](https://heycam.github.io/webidl/#idl-iterable) or should be [inherited from `Array`](https://heycam.github.io/webidl/#LegacyArrayClass). That means they should have `forEach`, `keys`, `values`, `entries` and `@@iterator` methods for iteration. So add them. Modules [`web.dom-collections.iterator`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-collections.iterator.js) and [`web.dom-collections.for-each`](https://github.com/zloirock/core-js/blob/master/packages/core-js/modules/web.dom-collections.for-each.js). +```ts class [ CSSRuleList, CSSStyleDeclaration, @@ -2511,12 +3813,11 @@ class [DOMTokenList, NodeList] { } ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js(-pure)/web/dom-collections -core-js(-pure)/stable|features/dom-collections/iterator -core-js/stable|features/dom-collections/for-each ``` -[*Examples*](http://goo.gl/lfXVFl): +core-js(-pure)/stable|actual|full/dom-collections/iterator +core-js/stable|actual|full/dom-collections/for-each +``` +[*Examples*](https://tinyurl.com/25rcspv4): ```js for (let { id } of document.querySelectorAll('*')) { if (id) console.log(id); @@ -2528,26 +3829,27 @@ for (let [index, { id }] of document.querySelectorAll('*').entries()) { document.querySelectorAll('*').forEach(it => console.log(it.id)); ``` -### Iteration helpers -Modules [`core.is-iterable`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/core.is-iterable.js), [`core.get-iterator`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/core.get-iterator.js), [`core.get-iterator-method`](https://github.com/zloirock/core-js/blob/v3.3.4/packages/core-js/modules/core.get-iterator-method.js) - helpers for check iterability / get iterator in the `pure` version or, for example, for `arguments` object: -```js +### Iteration helpers[⬆](#index) +Helpers for checking iterability / get iterator in the `pure` version or, for example, for `arguments` object: +```ts function isIterable(value: any): boolean; function getIterator(value: any): Object; function getIteratorMethod(value: any): Function | void; ``` [*CommonJS entry points:*](#commonjs-api) -```js -core-js-pure/features/is-iterable -core-js-pure/features/get-iterator -core-js-pure/features/get-iterator-method ``` -[*Examples*](http://goo.gl/SXsM6D): +core-js-pure/es|stable|actual|full/is-iterable +core-js-pure/es|stable|actual|full/get-iterator +core-js-pure/es|stable|actual|full/get-iterator-method +``` +*Examples*: ```js -import isIterable from 'core-js-pure/features/is-iterable'; -import getIterator from 'core-js-pure/features/get-iterator'; -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; +import isIterable from 'core-js-pure/actual/is-iterable'; +import getIterator from 'core-js-pure/actual/get-iterator'; +import getIteratorMethod from 'core-js-pure/actual/get-iterator-method'; let list = (function () { + // eslint-disable-next-line prefer-rest-params -- example return arguments; })(1, 2, 3); @@ -2559,11 +3861,11 @@ console.log(iterator.next().value); // 2 console.log(iterator.next().value); // 3 console.log(iterator.next().value); // undefined -getIterator({}); // TypeError: [object Object] is not iterable! +getIterator({}); // TypeError: [object Object] is not iterable! let method = getIteratorMethod(list); console.log(typeof method); // 'function' -let iterator = method.call(list); +iterator = method.call(list); console.log(iterator.next().value); // 1 console.log(iterator.next().value); // 2 console.log(iterator.next().value); // 3 @@ -2572,8 +3874,9 @@ console.log(iterator.next().value); // undefined console.log(getIteratorMethod({})); // undefined ``` -## Missing polyfills +## Missing polyfills[⬆](#index) +- ES `BigInt` can't be polyfilled since it requires changes in the behavior of operators, you can find more info [here](https://github.com/zloirock/core-js/issues/381). You could try to use [`JSBI`](https://github.com/GoogleChromeLabs/jsbi). +- ES `Proxy` can't be polyfilled, you can try to use [`proxy-polyfill`](https://github.com/GoogleChrome/proxy-polyfill) which provides a very small subset of features. - ES `String#normalize` is not a very useful feature, but this polyfill will be very large. If you need it, you can use [unorm](https://github.com/walling/unorm/). -- ES `Proxy` can't be polyfilled, but for Node.js / Chromium with additional flags, you can try [harmony-reflect](https://github.com/tvcutsem/harmony-reflect) for adapt old style `Proxy` API to final ES2015 version. +- ECMA-402 `Intl` is missed because of the size. You can use [those polyfills](https://formatjs.io/docs/polyfills). - `window.fetch` is not a cross-platform feature, in some environments, it makes no sense. For this reason, I don't think it should be in `core-js`. Looking at a large number of requests it *might be* added in the future. Now you can use, for example, [this polyfill](https://github.com/github/fetch). -- ECMA-402 `Intl` is missed because of the size. You can use [this polyfill](https://github.com/andyearnshaw/Intl.js/). diff --git a/SECURITY.md b/SECURITY.md index 7029b7679001..4c01330466fd 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,14 +2,7 @@ ## Supported Versions -This is the list of versions of `core-js` which are -currently being supported with security updates. - -| Version | Supported | -| -------- | ------------------ | -| 3.x | :white_check_mark: | -| 2.6.x | :white_check_mark: | -| < 2.6.0 | :x: | +The [latest released version](https://github.com/zloirock/core-js/releases) of `core-js` is supported. ## Reporting a Vulnerability diff --git a/babel.config.js b/babel.config.js index 7bf7672a6625..aee2952dfa35 100644 --- a/babel.config.js +++ b/babel.config.js @@ -2,23 +2,60 @@ module.exports = { // use transforms which does not use ES5+ builtins plugins: [ - ['@babel/proposal-optional-catch-binding'], ['@babel/transform-member-expression-literals'], ['@babel/transform-property-literals'], ['@babel/transform-arrow-functions'], ['@babel/transform-block-scoped-functions'], ['@babel/transform-block-scoping'], + // it seems `setClassMethods` unlike `loose` does not work ['@babel/transform-classes', { loose: true }], - ['@babel/transform-computed-properties', { loose: true }], - ['@babel/transform-destructuring', { loose: true }], + // private instance props in IE8- only with polyfills + ['@babel/transform-class-properties'], + ['@babel/transform-class-static-block'], + ['@babel/transform-computed-properties'], + ['@babel/transform-destructuring'], + ['@babel/transform-duplicate-named-capturing-groups-regex'], + ['@babel/transform-explicit-resource-management'], + ['@babel/transform-exponentiation-operator'], + ['@babel/transform-for-of'], ['@babel/transform-literals'], + ['@babel/transform-logical-assignment-operators'], + ['@babel/transform-new-target'], + ['@babel/transform-nullish-coalescing-operator'], + ['@babel/transform-numeric-separator'], + ['@babel/transform-object-rest-spread'], + ['@babel/transform-object-super'], + ['@babel/transform-optional-catch-binding'], + ['@babel/transform-optional-chaining'], ['@babel/transform-parameters'], + ['@babel/transform-private-methods'], + ['@babel/transform-private-property-in-object'], + ['@babel/transform-regexp-modifiers'], + ['@babel/transform-reserved-words'], ['@babel/transform-shorthand-properties'], - ['@babel/transform-spread', { loose: true }], - ['@babel/transform-template-literals', { loose: true, spec: true }], - ['@babel/transform-exponentiation-operator'], - ['transform-for-of-as-array'], + ['@babel/transform-spread'], + ['@babel/transform-template-literals'], + ['@babel/transform-unicode-regex'], // use it instead of webpack es modules for support engines without descriptors - ['transform-es2015-modules-simple-commonjs'], + ['@babel/transform-modules-commonjs'], ], + assumptions: { + constantReexports: true, + constantSuper: true, + enumerableModuleMeta: true, + iterableIsArray: true, + mutableTemplateObject: false, + noClassCalls: true, + noDocumentAll: true, + noIncompleteNsImportDetection: true, + noNewArrows: true, + objectRestNoSymbols: true, + privateFieldsAsProperties: true, + setClassMethods: true, + setComputedProperties: true, + setPublicClassFields: true, + setSpreadProperties: true, + skipForOfIteratorClosing: true, + superIsCallableConstructor: true, + }, }; diff --git a/deno/corejs/LICENSE b/deno/corejs/LICENSE new file mode 100644 index 000000000000..5cc1d065c701 --- /dev/null +++ b/deno/corejs/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014-2025 Denis Pushkarev, 2025 CoreJS Company + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/deno/corejs/README.md b/deno/corejs/README.md new file mode 100644 index 000000000000..4cc17e7e89b8 --- /dev/null +++ b/deno/corejs/README.md @@ -0,0 +1,53 @@ +![logo](https://user-images.githubusercontent.com/2213682/146607186-8e13ddef-26a4-4ebf-befd-5aac9d77c090.png) + +
+ +[![fundraising](https://opencollective.com/core-js/all/badge.svg?label=fundraising)](https://opencollective.com/core-js) [![PRs welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/zloirock/core-js/blob/master/CONTRIBUTING.md) [![version](https://img.shields.io/npm/v/core-js.svg)](https://www.npmjs.com/package/core-js) [![core-js downloads](https://img.shields.io/npm/dm/core-js.svg?label=npm%20i%20core-js)](https://npm-stat.com/charts.html?package=core-js&package=core-js-pure&package=core-js-compat&from=2014-11-18) [![core-js-pure downloads](https://img.shields.io/npm/dm/core-js-pure.svg?label=npm%20i%20core-js-pure)](https://npm-stat.com/charts.html?package=core-js&package=core-js-pure&package=core-js-compat&from=2014-11-18) [![jsDelivr](https://data.jsdelivr.com/v1/package/npm/core-js-bundle/badge?style=rounded)](https://www.jsdelivr.com/package/npm/core-js-bundle) + +
+ +**I highly recommend reading this: [So, what's next?](https://github.com/zloirock/core-js/blob/master/docs/2023-02-14-so-whats-next.md)** +--- + +> Modular standard library for JavaScript. Includes polyfills for [ECMAScript up to 2021](https://github.com/zloirock/core-js#ecmascript): [promises](https://github.com/zloirock/core-js#ecmascript-promise), [symbols](https://github.com/zloirock/core-js#ecmascript-symbol), [collections](https://github.com/zloirock/core-js#ecmascript-collections), iterators, [typed arrays](https://github.com/zloirock/core-js#ecmascript-typed-arrays), many other features, [ECMAScript proposals](https://github.com/zloirock/core-js#ecmascript-proposals), [some cross-platform WHATWG / W3C features and proposals](#web-standards) like [`URL`](https://github.com/zloirock/core-js#url-and-urlsearchparams). You can load only required features or use it without global namespace pollution. + +## [core-js@3, babel and a look into the future](https://github.com/zloirock/core-js/tree/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md) + +## Raising funds + +`core-js` isn't backed by a company, so the future of this project depends on you. Become a sponsor or a backer if you are interested in `core-js`: [**Open Collective**](https://opencollective.com/core-js), [**Patreon**](https://patreon.com/zloirock), [**Boosty**](https://boosty.to/zloirock), **Bitcoin ( bc1qlea7544qtsmj2rayg0lthvza9fau63ux0fstcz )**, [**Alipay**](https://user-images.githubusercontent.com/2213682/219464783-c17ad329-17ce-4795-82a7-f609493345ed.png). + +--- + + + +--- + + + +--- + +*Example*: +```js +import 'https://deno.land/x/corejs@v3.47.0/index.js'; // <- at the top of your entry point + +Object.hasOwn({ foo: 42 }, 'foo'); // => true + +[1, 2, 3, 4, 5, 6, 7].at(-3); // => 5 + +[1, 2, 3, 4, 5].group(it => it % 2); // => { 1: [1, 3, 5], 0: [2, 4] } + +Promise.any([ + Promise.resolve(1), + Promise.reject(2), + Promise.resolve(3), +]).then(console.log); // => 1 + +(function * (i) { while (true) yield i++; })(1) + .drop(1).take(5) + .filter(it => it % 2) + .map(it => it ** 2) + .toArray(); // => [9, 25] +``` + +**It's a bundled global version for Deno 1.0+, for more info see [`core-js` documentation](https://github.com/zloirock/core-js/blob/master/README.md).** diff --git a/deno/corejs/index.js b/deno/corejs/index.js new file mode 100644 index 000000000000..29d7d18efba8 --- /dev/null +++ b/deno/corejs/index.js @@ -0,0 +1,17746 @@ +/** + * core-js 3.47.0 + * © 2014-2025 Denis Pushkarev (zloirock.ru) + * license: https://github.com/zloirock/core-js/blob/v3.47.0/LICENSE + * source: https://github.com/zloirock/core-js + */ +!function (undefined) { 'use strict'; /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ var __webpack_require__ = function (moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports, __webpack_require__) { + +__webpack_require__(1); +__webpack_require__(47); +__webpack_require__(48); +__webpack_require__(88); +__webpack_require__(89); +__webpack_require__(105); +__webpack_require__(106); +__webpack_require__(107); +__webpack_require__(109); +__webpack_require__(111); +__webpack_require__(112); +__webpack_require__(116); +__webpack_require__(118); +__webpack_require__(121); +__webpack_require__(122); +__webpack_require__(124); +__webpack_require__(125); +__webpack_require__(130); +__webpack_require__(135); +__webpack_require__(143); +__webpack_require__(144); +__webpack_require__(148); +__webpack_require__(151); +__webpack_require__(155); +__webpack_require__(156); +__webpack_require__(162); +__webpack_require__(163); +__webpack_require__(165); +__webpack_require__(166); +__webpack_require__(168); +__webpack_require__(169); +__webpack_require__(170); +__webpack_require__(171); +__webpack_require__(172); +__webpack_require__(173); +__webpack_require__(174); +__webpack_require__(175); +__webpack_require__(178); +__webpack_require__(180); +__webpack_require__(182); +__webpack_require__(184); +__webpack_require__(186); +__webpack_require__(189); +__webpack_require__(190); +__webpack_require__(191); +__webpack_require__(192); +__webpack_require__(193); +__webpack_require__(221); +__webpack_require__(222); +__webpack_require__(223); +__webpack_require__(224); +__webpack_require__(225); +__webpack_require__(226); +__webpack_require__(233); +__webpack_require__(234); +__webpack_require__(235); +__webpack_require__(236); +__webpack_require__(241); +__webpack_require__(244); +__webpack_require__(254); +__webpack_require__(256); +__webpack_require__(258); +__webpack_require__(260); +__webpack_require__(262); +__webpack_require__(265); +__webpack_require__(267); +__webpack_require__(268); +__webpack_require__(269); +__webpack_require__(273); +__webpack_require__(274); +__webpack_require__(276); +__webpack_require__(277); +__webpack_require__(278); +__webpack_require__(280); +__webpack_require__(281); +__webpack_require__(282); +__webpack_require__(285); +__webpack_require__(290); +__webpack_require__(292); +__webpack_require__(294); +__webpack_require__(295); +__webpack_require__(296); +__webpack_require__(297); +__webpack_require__(301); +__webpack_require__(303); +__webpack_require__(305); +__webpack_require__(307); +__webpack_require__(308); +__webpack_require__(309); +__webpack_require__(310); +__webpack_require__(311); +__webpack_require__(314); +__webpack_require__(315); +__webpack_require__(319); +__webpack_require__(320); +__webpack_require__(321); +__webpack_require__(322); +__webpack_require__(323); +__webpack_require__(325); +__webpack_require__(326); +__webpack_require__(328); +__webpack_require__(329); +__webpack_require__(330); +__webpack_require__(331); +__webpack_require__(332); +__webpack_require__(333); +__webpack_require__(334); +__webpack_require__(337); +__webpack_require__(351); +__webpack_require__(352); +__webpack_require__(353); +__webpack_require__(355); +__webpack_require__(357); +__webpack_require__(358); +__webpack_require__(359); +__webpack_require__(360); +__webpack_require__(361); +__webpack_require__(363); +__webpack_require__(364); +__webpack_require__(365); +__webpack_require__(366); +__webpack_require__(368); +__webpack_require__(369); +__webpack_require__(370); +__webpack_require__(374); +__webpack_require__(375); +__webpack_require__(377); +__webpack_require__(378); +__webpack_require__(379); +__webpack_require__(380); +__webpack_require__(381); +__webpack_require__(382); +__webpack_require__(384); +__webpack_require__(385); +__webpack_require__(386); +__webpack_require__(388); +__webpack_require__(389); +__webpack_require__(390); +__webpack_require__(391); +__webpack_require__(392); +__webpack_require__(393); +__webpack_require__(395); +__webpack_require__(396); +__webpack_require__(397); +__webpack_require__(398); +__webpack_require__(401); +__webpack_require__(402); +__webpack_require__(403); +__webpack_require__(406); +__webpack_require__(407); +__webpack_require__(408); +__webpack_require__(409); +__webpack_require__(410); +__webpack_require__(412); +__webpack_require__(413); +__webpack_require__(414); +__webpack_require__(418); +__webpack_require__(420); +__webpack_require__(421); +__webpack_require__(422); +__webpack_require__(423); +__webpack_require__(424); +__webpack_require__(425); +__webpack_require__(426); +__webpack_require__(427); +__webpack_require__(428); +__webpack_require__(429); +__webpack_require__(430); +__webpack_require__(433); +__webpack_require__(434); +__webpack_require__(435); +__webpack_require__(436); +__webpack_require__(437); +__webpack_require__(438); +__webpack_require__(439); +__webpack_require__(440); +__webpack_require__(441); +__webpack_require__(442); +__webpack_require__(443); +__webpack_require__(444); +__webpack_require__(445); +__webpack_require__(446); +__webpack_require__(447); +__webpack_require__(448); +__webpack_require__(450); +__webpack_require__(452); +__webpack_require__(455); +__webpack_require__(456); +__webpack_require__(458); +__webpack_require__(459); +__webpack_require__(461); +__webpack_require__(462); +__webpack_require__(463); +__webpack_require__(464); +__webpack_require__(465); +__webpack_require__(466); +__webpack_require__(467); +__webpack_require__(469); +__webpack_require__(470); +__webpack_require__(471); +__webpack_require__(472); +__webpack_require__(474); +__webpack_require__(475); +__webpack_require__(476); +__webpack_require__(477); +__webpack_require__(478); +__webpack_require__(480); +__webpack_require__(483); +__webpack_require__(484); +__webpack_require__(485); +__webpack_require__(486); +__webpack_require__(489); +__webpack_require__(490); +__webpack_require__(491); +__webpack_require__(495); +__webpack_require__(496); +__webpack_require__(497); +__webpack_require__(499); +__webpack_require__(500); +__webpack_require__(501); +module.exports = __webpack_require__(502); + + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var defineWellKnownSymbol = __webpack_require__(3); +var defineProperty = __webpack_require__(23).f; +var getOwnPropertyDescriptor = __webpack_require__(41).f; + +var Symbol = globalThis.Symbol; + +// `Symbol.asyncDispose` well-known symbol +// https://github.com/tc39/proposal-async-explicit-resource-management +defineWellKnownSymbol('asyncDispose'); + +if (Symbol) { + var descriptor = getOwnPropertyDescriptor(Symbol, 'asyncDispose'); + // workaround of NodeJS 20.4 bug + // https://github.com/nodejs/node/issues/48699 + // and incorrect descriptor from some transpilers and userland helpers + if (descriptor.enumerable && descriptor.configurable && descriptor.writable) { + defineProperty(Symbol, 'asyncDispose', { value: descriptor.value, enumerable: false, configurable: false, writable: false }); + } +} + + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var check = function (it) { + return it && it.Math === Math && it; +}; + +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +module.exports = + // eslint-disable-next-line es/no-global-this -- safe + check(typeof globalThis == 'object' && globalThis) || + check(typeof window == 'object' && window) || + // eslint-disable-next-line no-restricted-globals -- safe + check(typeof self == 'object' && self) || + check(typeof global == 'object' && global) || + check(typeof this == 'object' && this) || + // eslint-disable-next-line no-new-func -- fallback + (function () { return this; })() || Function('return this')(); + + +/***/ }), +/* 3 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var path = __webpack_require__(4); +var hasOwn = __webpack_require__(5); +var wrappedWellKnownSymbolModule = __webpack_require__(12); +var defineProperty = __webpack_require__(23).f; + +module.exports = function (NAME) { + var Symbol = path.Symbol || (path.Symbol = {}); + if (!hasOwn(Symbol, NAME)) defineProperty(Symbol, NAME, { + value: wrappedWellKnownSymbolModule.f(NAME) + }); +}; + + +/***/ }), +/* 4 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); + +module.exports = globalThis; + + +/***/ }), +/* 5 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var toObject = __webpack_require__(9); + +var hasOwnProperty = uncurryThis({}.hasOwnProperty); + +// `HasOwnProperty` abstract operation +// https://tc39.es/ecma262/#sec-hasownproperty +// eslint-disable-next-line es/no-object-hasown -- safe +module.exports = Object.hasOwn || function hasOwn(it, key) { + return hasOwnProperty(toObject(it), key); +}; + + +/***/ }), +/* 6 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(7); + +var FunctionPrototype = Function.prototype; +var call = FunctionPrototype.call; +// eslint-disable-next-line es/no-function-prototype-bind -- safe +var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call); + +module.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) { + return function () { + return call.apply(fn, arguments); + }; +}; + + +/***/ }), +/* 7 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); + +module.exports = !fails(function () { + // eslint-disable-next-line es/no-function-prototype-bind -- safe + var test = (function () { /* empty */ }).bind(); + // eslint-disable-next-line no-prototype-builtins -- safe + return typeof test != 'function' || test.hasOwnProperty('prototype'); +}); + + +/***/ }), +/* 8 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = function (exec) { + try { + return !!exec(); + } catch (error) { + return true; + } +}; + + +/***/ }), +/* 9 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var requireObjectCoercible = __webpack_require__(10); + +var $Object = Object; + +// `ToObject` abstract operation +// https://tc39.es/ecma262/#sec-toobject +module.exports = function (argument) { + return $Object(requireObjectCoercible(argument)); +}; + + +/***/ }), +/* 10 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isNullOrUndefined = __webpack_require__(11); + +var $TypeError = TypeError; + +// `RequireObjectCoercible` abstract operation +// https://tc39.es/ecma262/#sec-requireobjectcoercible +module.exports = function (it) { + if (isNullOrUndefined(it)) throw new $TypeError("Can't call method on " + it); + return it; +}; + + +/***/ }), +/* 11 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// we can't use just `it == null` since of `document.all` special case +// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec +module.exports = function (it) { + return it === null || it === undefined; +}; + + +/***/ }), +/* 12 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var wellKnownSymbol = __webpack_require__(13); + +exports.f = wellKnownSymbol; + + +/***/ }), +/* 13 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var shared = __webpack_require__(14); +var hasOwn = __webpack_require__(5); +var uid = __webpack_require__(18); +var NATIVE_SYMBOL = __webpack_require__(19); +var USE_SYMBOL_AS_UID = __webpack_require__(22); + +var Symbol = globalThis.Symbol; +var WellKnownSymbolsStore = shared('wks'); +var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid; + +module.exports = function (name) { + if (!hasOwn(WellKnownSymbolsStore, name)) { + WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name) + ? Symbol[name] + : createWellKnownSymbol('Symbol.' + name); + } return WellKnownSymbolsStore[name]; +}; + + +/***/ }), +/* 14 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var store = __webpack_require__(15); + +module.exports = function (key, value) { + return store[key] || (store[key] = value || {}); +}; + + +/***/ }), +/* 15 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var IS_PURE = __webpack_require__(16); +var globalThis = __webpack_require__(2); +var defineGlobalProperty = __webpack_require__(17); + +var SHARED = '__core-js_shared__'; +var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {}); + +(store.versions || (store.versions = [])).push({ + version: '3.47.0', + mode: IS_PURE ? 'pure' : 'global', + copyright: '© 2014-2025 Denis Pushkarev (zloirock.ru), 2025 CoreJS Company (core-js.io)', + license: 'https://github.com/zloirock/core-js/blob/v3.47.0/LICENSE', + source: 'https://github.com/zloirock/core-js' +}); + + +/***/ }), +/* 16 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = false; + + +/***/ }), +/* 17 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); + +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; + +module.exports = function (key, value) { + try { + defineProperty(globalThis, key, { value: value, configurable: true, writable: true }); + } catch (error) { + globalThis[key] = value; + } return value; +}; + + +/***/ }), +/* 18 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +var id = 0; +var postfix = Math.random(); +var toString = uncurryThis(1.1.toString); + +module.exports = function (key) { + return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36); +}; + + +/***/ }), +/* 19 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable es/no-symbol -- required for testing */ +var V8_VERSION = __webpack_require__(20); +var fails = __webpack_require__(8); +var globalThis = __webpack_require__(2); + +var $String = globalThis.String; + +// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing +module.exports = !!Object.getOwnPropertySymbols && !fails(function () { + var symbol = Symbol('symbol detection'); + // Chrome 38 Symbol has incorrect toString conversion + // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances + // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will, + // of course, fail. + return !$String(symbol) || !(Object(symbol) instanceof Symbol) || + // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances + !Symbol.sham && V8_VERSION && V8_VERSION < 41; +}); + + +/***/ }), +/* 20 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var userAgent = __webpack_require__(21); + +var process = globalThis.process; +var Deno = globalThis.Deno; +var versions = process && process.versions || Deno && Deno.version; +var v8 = versions && versions.v8; +var match, version; + +if (v8) { + match = v8.split('.'); + // in old Chrome, versions of V8 isn't V8 = Chrome / 10 + // but their correct versions are not interesting for us + version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); +} + +// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` +// so check `userAgent` even if `.v8` exists, but 0 +if (!version && userAgent) { + match = userAgent.match(/Edge\/(\d+)/); + if (!match || match[1] >= 74) { + match = userAgent.match(/Chrome\/(\d+)/); + if (match) version = +match[1]; + } +} + +module.exports = version; + + +/***/ }), +/* 21 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); + +var navigator = globalThis.navigator; +var userAgent = navigator && navigator.userAgent; + +module.exports = userAgent ? String(userAgent) : ''; + + +/***/ }), +/* 22 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable es/no-symbol -- required for testing */ +var NATIVE_SYMBOL = __webpack_require__(19); + +module.exports = NATIVE_SYMBOL && + !Symbol.sham && + typeof Symbol.iterator == 'symbol'; + + +/***/ }), +/* 23 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var IE8_DOM_DEFINE = __webpack_require__(25); +var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(29); +var anObject = __webpack_require__(30); +var toPropertyKey = __webpack_require__(31); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var $defineProperty = Object.defineProperty; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; +var ENUMERABLE = 'enumerable'; +var CONFIGURABLE = 'configurable'; +var WRITABLE = 'writable'; + +// `Object.defineProperty` method +// https://tc39.es/ecma262/#sec-object.defineproperty +exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) { + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { + var current = $getOwnPropertyDescriptor(O, P); + if (current && current[WRITABLE]) { + O[P] = Attributes.value; + Attributes = { + configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE], + enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], + writable: false + }; + } + } return $defineProperty(O, P, Attributes); +} : $defineProperty : function defineProperty(O, P, Attributes) { + anObject(O); + P = toPropertyKey(P); + anObject(Attributes); + if (IE8_DOM_DEFINE) try { + return $defineProperty(O, P, Attributes); + } catch (error) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; +}; + + +/***/ }), +/* 24 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); + +// Detect IE8's incomplete defineProperty implementation +module.exports = !fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7; +}); + + +/***/ }), +/* 25 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var fails = __webpack_require__(8); +var createElement = __webpack_require__(26); + +// Thanks to IE8 for its funny defineProperty +module.exports = !DESCRIPTORS && !fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty(createElement('div'), 'a', { + get: function () { return 7; } + }).a !== 7; +}); + + +/***/ }), +/* 26 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var isObject = __webpack_require__(27); + +var document = globalThis.document; +// typeof document.createElement is 'object' in old IE +var EXISTS = isObject(document) && isObject(document.createElement); + +module.exports = function (it) { + return EXISTS ? document.createElement(it) : {}; +}; + + +/***/ }), +/* 27 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isCallable = __webpack_require__(28); + +module.exports = function (it) { + return typeof it == 'object' ? it !== null : isCallable(it); +}; + + +/***/ }), +/* 28 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot +var documentAll = typeof document == 'object' && document.all; + +// `IsCallable` abstract operation +// https://tc39.es/ecma262/#sec-iscallable +// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing +module.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) { + return typeof argument == 'function' || argument === documentAll; +} : function (argument) { + return typeof argument == 'function'; +}; + + +/***/ }), +/* 29 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var fails = __webpack_require__(8); + +// V8 ~ Chrome 36- +// https://bugs.chromium.org/p/v8/issues/detail?id=3334 +module.exports = DESCRIPTORS && fails(function () { + // eslint-disable-next-line es/no-object-defineproperty -- required for testing + return Object.defineProperty(function () { /* empty */ }, 'prototype', { + value: 42, + writable: false + }).prototype !== 42; +}); + + +/***/ }), +/* 30 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isObject = __webpack_require__(27); + +var $String = String; +var $TypeError = TypeError; + +// `Assert: Type(argument) is Object` +module.exports = function (argument) { + if (isObject(argument)) return argument; + throw new $TypeError($String(argument) + ' is not an object'); +}; + + +/***/ }), +/* 31 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toPrimitive = __webpack_require__(32); +var isSymbol = __webpack_require__(34); + +// `ToPropertyKey` abstract operation +// https://tc39.es/ecma262/#sec-topropertykey +module.exports = function (argument) { + var key = toPrimitive(argument, 'string'); + return isSymbol(key) ? key : key + ''; +}; + + +/***/ }), +/* 32 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var isObject = __webpack_require__(27); +var isSymbol = __webpack_require__(34); +var getMethod = __webpack_require__(37); +var ordinaryToPrimitive = __webpack_require__(40); +var wellKnownSymbol = __webpack_require__(13); + +var $TypeError = TypeError; +var TO_PRIMITIVE = wellKnownSymbol('toPrimitive'); + +// `ToPrimitive` abstract operation +// https://tc39.es/ecma262/#sec-toprimitive +module.exports = function (input, pref) { + if (!isObject(input) || isSymbol(input)) return input; + var exoticToPrim = getMethod(input, TO_PRIMITIVE); + var result; + if (exoticToPrim) { + if (pref === undefined) pref = 'default'; + result = call(exoticToPrim, input, pref); + if (!isObject(result) || isSymbol(result)) return result; + throw new $TypeError("Can't convert object to primitive value"); + } + if (pref === undefined) pref = 'number'; + return ordinaryToPrimitive(input, pref); +}; + + +/***/ }), +/* 33 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(7); + +var call = Function.prototype.call; +// eslint-disable-next-line es/no-function-prototype-bind -- safe +module.exports = NATIVE_BIND ? call.bind(call) : function () { + return call.apply(call, arguments); +}; + + +/***/ }), +/* 34 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); +var isCallable = __webpack_require__(28); +var isPrototypeOf = __webpack_require__(36); +var USE_SYMBOL_AS_UID = __webpack_require__(22); + +var $Object = Object; + +module.exports = USE_SYMBOL_AS_UID ? function (it) { + return typeof it == 'symbol'; +} : function (it) { + var $Symbol = getBuiltIn('Symbol'); + return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it)); +}; + + +/***/ }), +/* 35 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var isCallable = __webpack_require__(28); + +var aFunction = function (argument) { + return isCallable(argument) ? argument : undefined; +}; + +module.exports = function (namespace, method) { + return arguments.length < 2 ? aFunction(globalThis[namespace]) : globalThis[namespace] && globalThis[namespace][method]; +}; + + +/***/ }), +/* 36 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +module.exports = uncurryThis({}.isPrototypeOf); + + +/***/ }), +/* 37 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aCallable = __webpack_require__(38); +var isNullOrUndefined = __webpack_require__(11); + +// `GetMethod` abstract operation +// https://tc39.es/ecma262/#sec-getmethod +module.exports = function (V, P) { + var func = V[P]; + return isNullOrUndefined(func) ? undefined : aCallable(func); +}; + + +/***/ }), +/* 38 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isCallable = __webpack_require__(28); +var tryToString = __webpack_require__(39); + +var $TypeError = TypeError; + +// `Assert: IsCallable(argument) is true` +module.exports = function (argument) { + if (isCallable(argument)) return argument; + throw new $TypeError(tryToString(argument) + ' is not a function'); +}; + + +/***/ }), +/* 39 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $String = String; + +module.exports = function (argument) { + try { + return $String(argument); + } catch (error) { + return 'Object'; + } +}; + + +/***/ }), +/* 40 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var isCallable = __webpack_require__(28); +var isObject = __webpack_require__(27); + +var $TypeError = TypeError; + +// `OrdinaryToPrimitive` abstract operation +// https://tc39.es/ecma262/#sec-ordinarytoprimitive +module.exports = function (input, pref) { + var fn, val; + if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; + if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val; + if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val; + throw new $TypeError("Can't convert object to primitive value"); +}; + + +/***/ }), +/* 41 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var call = __webpack_require__(33); +var propertyIsEnumerableModule = __webpack_require__(42); +var createPropertyDescriptor = __webpack_require__(43); +var toIndexedObject = __webpack_require__(44); +var toPropertyKey = __webpack_require__(31); +var hasOwn = __webpack_require__(5); +var IE8_DOM_DEFINE = __webpack_require__(25); + +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// `Object.getOwnPropertyDescriptor` method +// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor +exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) { + O = toIndexedObject(O); + P = toPropertyKey(P); + if (IE8_DOM_DEFINE) try { + return $getOwnPropertyDescriptor(O, P); + } catch (error) { /* empty */ } + if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]); +}; + + +/***/ }), +/* 42 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $propertyIsEnumerable = {}.propertyIsEnumerable; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Nashorn ~ JDK8 bug +var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1); + +// `Object.prototype.propertyIsEnumerable` method implementation +// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable +exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) { + var descriptor = getOwnPropertyDescriptor(this, V); + return !!descriptor && descriptor.enumerable; +} : $propertyIsEnumerable; + + +/***/ }), +/* 43 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; +}; + + +/***/ }), +/* 44 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// toObject with fallback for non-array-like ES3 strings +var IndexedObject = __webpack_require__(45); +var requireObjectCoercible = __webpack_require__(10); + +module.exports = function (it) { + return IndexedObject(requireObjectCoercible(it)); +}; + + +/***/ }), +/* 45 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var fails = __webpack_require__(8); +var classof = __webpack_require__(46); + +var $Object = Object; +var split = uncurryThis(''.split); + +// fallback for non-array-like ES3 and non-enumerable old V8 strings +module.exports = fails(function () { + // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346 + // eslint-disable-next-line no-prototype-builtins -- safe + return !$Object('z').propertyIsEnumerable(0); +}) ? function (it) { + return classof(it) === 'String' ? split(it, '') : $Object(it); +} : $Object; + + +/***/ }), +/* 46 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +var toString = uncurryThis({}.toString); +var stringSlice = uncurryThis(''.slice); + +module.exports = function (it) { + return stringSlice(toString(it), 8, -1); +}; + + +/***/ }), +/* 47 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var defineWellKnownSymbol = __webpack_require__(3); +var defineProperty = __webpack_require__(23).f; +var getOwnPropertyDescriptor = __webpack_require__(41).f; + +var Symbol = globalThis.Symbol; + +// `Symbol.dispose` well-known symbol +// https://github.com/tc39/proposal-explicit-resource-management +defineWellKnownSymbol('dispose'); + +if (Symbol) { + var descriptor = getOwnPropertyDescriptor(Symbol, 'dispose'); + // workaround of NodeJS 20.4 bug + // https://github.com/nodejs/node/issues/48699 + // and incorrect descriptor from some transpilers and userland helpers + if (descriptor.enumerable && descriptor.configurable && descriptor.writable) { + defineProperty(Symbol, 'dispose', { value: descriptor.value, enumerable: false, configurable: false, writable: false }); + } +} + + +/***/ }), +/* 48 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable no-unused-vars -- required for functions `.length` */ +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var apply = __webpack_require__(72); +var wrapErrorConstructorWithCause = __webpack_require__(73); + +var WEB_ASSEMBLY = 'WebAssembly'; +var WebAssembly = globalThis[WEB_ASSEMBLY]; + +// eslint-disable-next-line es/no-error-cause -- feature detection +var FORCED = new Error('e', { cause: 7 }).cause !== 7; + +var exportGlobalErrorCauseWrapper = function (ERROR_NAME, wrapper) { + var O = {}; + // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation + O[ERROR_NAME] = wrapErrorConstructorWithCause(ERROR_NAME, wrapper, FORCED); + $({ global: true, constructor: true, arity: 1, forced: FORCED }, O); +}; + +var exportWebAssemblyErrorCauseWrapper = function (ERROR_NAME, wrapper) { + if (WebAssembly && WebAssembly[ERROR_NAME]) { + var O = {}; + // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation + O[ERROR_NAME] = wrapErrorConstructorWithCause(WEB_ASSEMBLY + '.' + ERROR_NAME, wrapper, FORCED); + $({ target: WEB_ASSEMBLY, stat: true, constructor: true, arity: 1, forced: FORCED }, O); + } +}; + +// https://tc39.es/ecma262/#sec-nativeerror +exportGlobalErrorCauseWrapper('Error', function (init) { + return function Error(message) { return apply(init, this, arguments); }; +}); +exportGlobalErrorCauseWrapper('EvalError', function (init) { + return function EvalError(message) { return apply(init, this, arguments); }; +}); +exportGlobalErrorCauseWrapper('RangeError', function (init) { + return function RangeError(message) { return apply(init, this, arguments); }; +}); +exportGlobalErrorCauseWrapper('ReferenceError', function (init) { + return function ReferenceError(message) { return apply(init, this, arguments); }; +}); +exportGlobalErrorCauseWrapper('SyntaxError', function (init) { + return function SyntaxError(message) { return apply(init, this, arguments); }; +}); +exportGlobalErrorCauseWrapper('TypeError', function (init) { + return function TypeError(message) { return apply(init, this, arguments); }; +}); +exportGlobalErrorCauseWrapper('URIError', function (init) { + return function URIError(message) { return apply(init, this, arguments); }; +}); +exportWebAssemblyErrorCauseWrapper('CompileError', function (init) { + return function CompileError(message) { return apply(init, this, arguments); }; +}); +exportWebAssemblyErrorCauseWrapper('LinkError', function (init) { + return function LinkError(message) { return apply(init, this, arguments); }; +}); +exportWebAssemblyErrorCauseWrapper('RuntimeError', function (init) { + return function RuntimeError(message) { return apply(init, this, arguments); }; +}); + + +/***/ }), +/* 49 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var getOwnPropertyDescriptor = __webpack_require__(41).f; +var createNonEnumerableProperty = __webpack_require__(50); +var defineBuiltIn = __webpack_require__(51); +var defineGlobalProperty = __webpack_require__(17); +var copyConstructorProperties = __webpack_require__(59); +var isForced = __webpack_require__(71); + +/* + options.target - name of the target object + options.global - target is the global object + options.stat - export as static methods of target + options.proto - export as prototype methods of target + options.real - real prototype method for the `pure` version + options.forced - export even if the native feature is available + options.bind - bind methods to the target, required for the `pure` version + options.wrap - wrap constructors to preventing global pollution, required for the `pure` version + options.unsafe - use the simple assignment of property instead of delete + defineProperty + options.sham - add a flag to not completely full polyfills + options.enumerable - export as enumerable property + options.dontCallGetSet - prevent calling a getter on target + options.name - the .name of the function if it does not match the key +*/ +module.exports = function (options, source) { + var TARGET = options.target; + var GLOBAL = options.global; + var STATIC = options.stat; + var FORCED, target, key, targetProperty, sourceProperty, descriptor; + if (GLOBAL) { + target = globalThis; + } else if (STATIC) { + target = globalThis[TARGET] || defineGlobalProperty(TARGET, {}); + } else { + target = globalThis[TARGET] && globalThis[TARGET].prototype; + } + if (target) for (key in source) { + sourceProperty = source[key]; + if (options.dontCallGetSet) { + descriptor = getOwnPropertyDescriptor(target, key); + targetProperty = descriptor && descriptor.value; + } else targetProperty = target[key]; + FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced); + // contained in target + if (!FORCED && targetProperty !== undefined) { + if (typeof sourceProperty == typeof targetProperty) continue; + copyConstructorProperties(sourceProperty, targetProperty); + } + // add a flag to not completely full polyfills + if (options.sham || (targetProperty && targetProperty.sham)) { + createNonEnumerableProperty(sourceProperty, 'sham', true); + } + defineBuiltIn(target, key, sourceProperty, options); + } +}; + + +/***/ }), +/* 50 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var definePropertyModule = __webpack_require__(23); +var createPropertyDescriptor = __webpack_require__(43); + +module.exports = DESCRIPTORS ? function (object, key, value) { + return definePropertyModule.f(object, key, createPropertyDescriptor(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; + + +/***/ }), +/* 51 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isCallable = __webpack_require__(28); +var definePropertyModule = __webpack_require__(23); +var makeBuiltIn = __webpack_require__(52); +var defineGlobalProperty = __webpack_require__(17); + +module.exports = function (O, key, value, options) { + if (!options) options = {}; + var simple = options.enumerable; + var name = options.name !== undefined ? options.name : key; + if (isCallable(value)) makeBuiltIn(value, name, options); + if (options.global) { + if (simple) O[key] = value; + else defineGlobalProperty(key, value); + } else { + try { + if (!options.unsafe) delete O[key]; + else if (O[key]) simple = true; + } catch (error) { /* empty */ } + if (simple) O[key] = value; + else definePropertyModule.f(O, key, { + value: value, + enumerable: false, + configurable: !options.nonConfigurable, + writable: !options.nonWritable + }); + } return O; +}; + + +/***/ }), +/* 52 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var fails = __webpack_require__(8); +var isCallable = __webpack_require__(28); +var hasOwn = __webpack_require__(5); +var DESCRIPTORS = __webpack_require__(24); +var CONFIGURABLE_FUNCTION_NAME = __webpack_require__(53).CONFIGURABLE; +var inspectSource = __webpack_require__(54); +var InternalStateModule = __webpack_require__(55); + +var enforceInternalState = InternalStateModule.enforce; +var getInternalState = InternalStateModule.get; +var $String = String; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; +var stringSlice = uncurryThis(''.slice); +var replace = uncurryThis(''.replace); +var join = uncurryThis([].join); + +var CONFIGURABLE_LENGTH = DESCRIPTORS && !fails(function () { + return defineProperty(function () { /* empty */ }, 'length', { value: 8 }).length !== 8; +}); + +var TEMPLATE = String(String).split('String'); + +var makeBuiltIn = module.exports = function (value, name, options) { + if (stringSlice($String(name), 0, 7) === 'Symbol(') { + name = '[' + replace($String(name), /^Symbol\(([^)]*)\).*$/, '$1') + ']'; + } + if (options && options.getter) name = 'get ' + name; + if (options && options.setter) name = 'set ' + name; + if (!hasOwn(value, 'name') || (CONFIGURABLE_FUNCTION_NAME && value.name !== name)) { + if (DESCRIPTORS) defineProperty(value, 'name', { value: name, configurable: true }); + else value.name = name; + } + if (CONFIGURABLE_LENGTH && options && hasOwn(options, 'arity') && value.length !== options.arity) { + defineProperty(value, 'length', { value: options.arity }); + } + try { + if (options && hasOwn(options, 'constructor') && options.constructor) { + if (DESCRIPTORS) defineProperty(value, 'prototype', { writable: false }); + // in V8 ~ Chrome 53, prototypes of some methods, like `Array.prototype.values`, are non-writable + } else if (value.prototype) value.prototype = undefined; + } catch (error) { /* empty */ } + var state = enforceInternalState(value); + if (!hasOwn(state, 'source')) { + state.source = join(TEMPLATE, typeof name == 'string' ? name : ''); + } return value; +}; + +// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative +// eslint-disable-next-line no-extend-native -- required +Function.prototype.toString = makeBuiltIn(function toString() { + return isCallable(this) && getInternalState(this).source || inspectSource(this); +}, 'toString'); + + +/***/ }), +/* 53 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var hasOwn = __webpack_require__(5); + +var FunctionPrototype = Function.prototype; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor; + +var EXISTS = hasOwn(FunctionPrototype, 'name'); +// additional protection from minified / mangled / dropped function names +var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something'; +var CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable)); + +module.exports = { + EXISTS: EXISTS, + PROPER: PROPER, + CONFIGURABLE: CONFIGURABLE +}; + + +/***/ }), +/* 54 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var isCallable = __webpack_require__(28); +var store = __webpack_require__(15); + +var functionToString = uncurryThis(Function.toString); + +// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper +if (!isCallable(store.inspectSource)) { + store.inspectSource = function (it) { + return functionToString(it); + }; +} + +module.exports = store.inspectSource; + + +/***/ }), +/* 55 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var NATIVE_WEAK_MAP = __webpack_require__(56); +var globalThis = __webpack_require__(2); +var isObject = __webpack_require__(27); +var createNonEnumerableProperty = __webpack_require__(50); +var hasOwn = __webpack_require__(5); +var shared = __webpack_require__(15); +var sharedKey = __webpack_require__(57); +var hiddenKeys = __webpack_require__(58); + +var OBJECT_ALREADY_INITIALIZED = 'Object already initialized'; +var TypeError = globalThis.TypeError; +var WeakMap = globalThis.WeakMap; +var set, get, has; + +var enforce = function (it) { + return has(it) ? get(it) : set(it, {}); +}; + +var getterFor = function (TYPE) { + return function (it) { + var state; + if (!isObject(it) || (state = get(it)).type !== TYPE) { + throw new TypeError('Incompatible receiver, ' + TYPE + ' required'); + } return state; + }; +}; + +if (NATIVE_WEAK_MAP || shared.state) { + var store = shared.state || (shared.state = new WeakMap()); + /* eslint-disable no-self-assign -- prototype methods protection */ + store.get = store.get; + store.has = store.has; + store.set = store.set; + /* eslint-enable no-self-assign -- prototype methods protection */ + set = function (it, metadata) { + if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + store.set(it, metadata); + return metadata; + }; + get = function (it) { + return store.get(it) || {}; + }; + has = function (it) { + return store.has(it); + }; +} else { + var STATE = sharedKey('state'); + hiddenKeys[STATE] = true; + set = function (it, metadata) { + if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + createNonEnumerableProperty(it, STATE, metadata); + return metadata; + }; + get = function (it) { + return hasOwn(it, STATE) ? it[STATE] : {}; + }; + has = function (it) { + return hasOwn(it, STATE); + }; +} + +module.exports = { + set: set, + get: get, + has: has, + enforce: enforce, + getterFor: getterFor +}; + + +/***/ }), +/* 56 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var isCallable = __webpack_require__(28); + +var WeakMap = globalThis.WeakMap; + +module.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap)); + + +/***/ }), +/* 57 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var shared = __webpack_require__(14); +var uid = __webpack_require__(18); + +var keys = shared('keys'); + +module.exports = function (key) { + return keys[key] || (keys[key] = uid(key)); +}; + + +/***/ }), +/* 58 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = {}; + + +/***/ }), +/* 59 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var hasOwn = __webpack_require__(5); +var ownKeys = __webpack_require__(60); +var getOwnPropertyDescriptorModule = __webpack_require__(41); +var definePropertyModule = __webpack_require__(23); + +module.exports = function (target, source, exceptions) { + var keys = ownKeys(source); + var defineProperty = definePropertyModule.f; + var getOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (!hasOwn(target, key) && !(exceptions && hasOwn(exceptions, key))) { + defineProperty(target, key, getOwnPropertyDescriptor(source, key)); + } + } +}; + + +/***/ }), +/* 60 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); +var getOwnPropertyNamesModule = __webpack_require__(61); +var getOwnPropertySymbolsModule = __webpack_require__(70); +var anObject = __webpack_require__(30); + +var concat = uncurryThis([].concat); + +// all object keys, includes non-enumerable and symbols +module.exports = getBuiltIn('Reflect', 'ownKeys') || function ownKeys(it) { + var keys = getOwnPropertyNamesModule.f(anObject(it)); + var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; + return getOwnPropertySymbols ? concat(keys, getOwnPropertySymbols(it)) : keys; +}; + + +/***/ }), +/* 61 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var internalObjectKeys = __webpack_require__(62); +var enumBugKeys = __webpack_require__(69); + +var hiddenKeys = enumBugKeys.concat('length', 'prototype'); + +// `Object.getOwnPropertyNames` method +// https://tc39.es/ecma262/#sec-object.getownpropertynames +// eslint-disable-next-line es/no-object-getownpropertynames -- safe +exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { + return internalObjectKeys(O, hiddenKeys); +}; + + +/***/ }), +/* 62 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var hasOwn = __webpack_require__(5); +var toIndexedObject = __webpack_require__(44); +var indexOf = __webpack_require__(63).indexOf; +var hiddenKeys = __webpack_require__(58); + +var push = uncurryThis([].push); + +module.exports = function (object, names) { + var O = toIndexedObject(object); + var i = 0; + var result = []; + var key; + for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key); + // Don't enum bug & hidden keys + while (names.length > i) if (hasOwn(O, key = names[i++])) { + ~indexOf(result, key) || push(result, key); + } + return result; +}; + + +/***/ }), +/* 63 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toIndexedObject = __webpack_require__(44); +var toAbsoluteIndex = __webpack_require__(64); +var lengthOfArrayLike = __webpack_require__(67); + +// `Array.prototype.{ indexOf, includes }` methods implementation +var createMethod = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = toIndexedObject($this); + var length = lengthOfArrayLike(O); + if (length === 0) return !IS_INCLUDES && -1; + var index = toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare -- NaN check + if (IS_INCLUDES && el !== el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare -- NaN check + if (value !== value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) { + if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; + +module.exports = { + // `Array.prototype.includes` method + // https://tc39.es/ecma262/#sec-array.prototype.includes + includes: createMethod(true), + // `Array.prototype.indexOf` method + // https://tc39.es/ecma262/#sec-array.prototype.indexof + indexOf: createMethod(false) +}; + + +/***/ }), +/* 64 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(65); + +var max = Math.max; +var min = Math.min; + +// Helper for a popular repeating case of the spec: +// Let integer be ? ToInteger(index). +// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length). +module.exports = function (index, length) { + var integer = toIntegerOrInfinity(index); + return integer < 0 ? max(integer + length, 0) : min(integer, length); +}; + + +/***/ }), +/* 65 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var trunc = __webpack_require__(66); + +// `ToIntegerOrInfinity` abstract operation +// https://tc39.es/ecma262/#sec-tointegerorinfinity +module.exports = function (argument) { + var number = +argument; + // eslint-disable-next-line no-self-compare -- NaN check + return number !== number || number === 0 ? 0 : trunc(number); +}; + + +/***/ }), +/* 66 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ceil = Math.ceil; +var floor = Math.floor; + +// `Math.trunc` method +// https://tc39.es/ecma262/#sec-math.trunc +// eslint-disable-next-line es/no-math-trunc -- safe +module.exports = Math.trunc || function trunc(x) { + var n = +x; + return (n > 0 ? floor : ceil)(n); +}; + + +/***/ }), +/* 67 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toLength = __webpack_require__(68); + +// `LengthOfArrayLike` abstract operation +// https://tc39.es/ecma262/#sec-lengthofarraylike +module.exports = function (obj) { + return toLength(obj.length); +}; + + +/***/ }), +/* 68 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(65); + +var min = Math.min; + +// `ToLength` abstract operation +// https://tc39.es/ecma262/#sec-tolength +module.exports = function (argument) { + var len = toIntegerOrInfinity(argument); + return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991 +}; + + +/***/ }), +/* 69 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// IE8- don't enum bug keys +module.exports = [ + 'constructor', + 'hasOwnProperty', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toLocaleString', + 'toString', + 'valueOf' +]; + + +/***/ }), +/* 70 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe +exports.f = Object.getOwnPropertySymbols; + + +/***/ }), +/* 71 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); +var isCallable = __webpack_require__(28); + +var replacement = /#|\.prototype\./; + +var isForced = function (feature, detection) { + var value = data[normalize(feature)]; + return value === POLYFILL ? true + : value === NATIVE ? false + : isCallable(detection) ? fails(detection) + : !!detection; +}; + +var normalize = isForced.normalize = function (string) { + return String(string).replace(replacement, '.').toLowerCase(); +}; + +var data = isForced.data = {}; +var NATIVE = isForced.NATIVE = 'N'; +var POLYFILL = isForced.POLYFILL = 'P'; + +module.exports = isForced; + + +/***/ }), +/* 72 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var NATIVE_BIND = __webpack_require__(7); + +var FunctionPrototype = Function.prototype; +var apply = FunctionPrototype.apply; +var call = FunctionPrototype.call; + +// eslint-disable-next-line es/no-function-prototype-bind, es/no-reflect -- safe +module.exports = typeof Reflect == 'object' && Reflect.apply || (NATIVE_BIND ? call.bind(apply) : function () { + return call.apply(apply, arguments); +}); + + +/***/ }), +/* 73 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); +var hasOwn = __webpack_require__(5); +var createNonEnumerableProperty = __webpack_require__(50); +var isPrototypeOf = __webpack_require__(36); +var setPrototypeOf = __webpack_require__(74); +var copyConstructorProperties = __webpack_require__(59); +var proxyAccessor = __webpack_require__(78); +var inheritIfRequired = __webpack_require__(79); +var normalizeStringArgument = __webpack_require__(80); +var installErrorCause = __webpack_require__(84); +var installErrorStack = __webpack_require__(85); +var DESCRIPTORS = __webpack_require__(24); +var IS_PURE = __webpack_require__(16); + +module.exports = function (FULL_NAME, wrapper, FORCED, IS_AGGREGATE_ERROR) { + var STACK_TRACE_LIMIT = 'stackTraceLimit'; + var OPTIONS_POSITION = IS_AGGREGATE_ERROR ? 2 : 1; + var path = FULL_NAME.split('.'); + var ERROR_NAME = path[path.length - 1]; + var OriginalError = getBuiltIn.apply(null, path); + + if (!OriginalError) return; + + var OriginalErrorPrototype = OriginalError.prototype; + + // V8 9.3- bug https://bugs.chromium.org/p/v8/issues/detail?id=12006 + if (!IS_PURE && hasOwn(OriginalErrorPrototype, 'cause')) delete OriginalErrorPrototype.cause; + + if (!FORCED) return OriginalError; + + var BaseError = getBuiltIn('Error'); + + var WrappedError = wrapper(function (a, b) { + var message = normalizeStringArgument(IS_AGGREGATE_ERROR ? b : a, undefined); + var result = IS_AGGREGATE_ERROR ? new OriginalError(a) : new OriginalError(); + if (message !== undefined) createNonEnumerableProperty(result, 'message', message); + installErrorStack(result, WrappedError, result.stack, 2); + if (this && isPrototypeOf(OriginalErrorPrototype, this)) inheritIfRequired(result, this, WrappedError); + if (arguments.length > OPTIONS_POSITION) installErrorCause(result, arguments[OPTIONS_POSITION]); + return result; + }); + + WrappedError.prototype = OriginalErrorPrototype; + + if (ERROR_NAME !== 'Error') { + if (setPrototypeOf) setPrototypeOf(WrappedError, BaseError); + else copyConstructorProperties(WrappedError, BaseError, { name: true }); + } else if (DESCRIPTORS && STACK_TRACE_LIMIT in OriginalError) { + proxyAccessor(WrappedError, OriginalError, STACK_TRACE_LIMIT); + proxyAccessor(WrappedError, OriginalError, 'prepareStackTrace'); + } + + copyConstructorProperties(WrappedError, OriginalError); + + if (!IS_PURE) try { + // Safari 13- bug: WebAssembly errors does not have a proper `.name` + if (OriginalErrorPrototype.name !== ERROR_NAME) { + createNonEnumerableProperty(OriginalErrorPrototype, 'name', ERROR_NAME); + } + OriginalErrorPrototype.constructor = WrappedError; + } catch (error) { /* empty */ } + + return WrappedError; +}; + + +/***/ }), +/* 74 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable no-proto -- safe */ +var uncurryThisAccessor = __webpack_require__(75); +var isObject = __webpack_require__(27); +var requireObjectCoercible = __webpack_require__(10); +var aPossiblePrototype = __webpack_require__(76); + +// `Object.setPrototypeOf` method +// https://tc39.es/ecma262/#sec-object.setprototypeof +// Works with __proto__ only. Old v8 can't work with null proto objects. +// eslint-disable-next-line es/no-object-setprototypeof -- safe +module.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () { + var CORRECT_SETTER = false; + var test = {}; + var setter; + try { + setter = uncurryThisAccessor(Object.prototype, '__proto__', 'set'); + setter(test, []); + CORRECT_SETTER = test instanceof Array; + } catch (error) { /* empty */ } + return function setPrototypeOf(O, proto) { + requireObjectCoercible(O); + aPossiblePrototype(proto); + if (!isObject(O)) return O; + if (CORRECT_SETTER) setter(O, proto); + else O.__proto__ = proto; + return O; + }; +}() : undefined); + + +/***/ }), +/* 75 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var aCallable = __webpack_require__(38); + +module.exports = function (object, key, method) { + try { + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + return uncurryThis(aCallable(Object.getOwnPropertyDescriptor(object, key)[method])); + } catch (error) { /* empty */ } +}; + + +/***/ }), +/* 76 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isPossiblePrototype = __webpack_require__(77); + +var $String = String; +var $TypeError = TypeError; + +module.exports = function (argument) { + if (isPossiblePrototype(argument)) return argument; + throw new $TypeError("Can't set " + $String(argument) + ' as a prototype'); +}; + + +/***/ }), +/* 77 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isObject = __webpack_require__(27); + +module.exports = function (argument) { + return isObject(argument) || argument === null; +}; + + +/***/ }), +/* 78 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineProperty = __webpack_require__(23).f; + +module.exports = function (Target, Source, key) { + key in Target || defineProperty(Target, key, { + configurable: true, + get: function () { return Source[key]; }, + set: function (it) { Source[key] = it; } + }); +}; + + +/***/ }), +/* 79 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isCallable = __webpack_require__(28); +var isObject = __webpack_require__(27); +var setPrototypeOf = __webpack_require__(74); + +// makes subclassing work correct for wrapped built-ins +module.exports = function ($this, dummy, Wrapper) { + var NewTarget, NewTargetPrototype; + if ( + // it can work only with native `setPrototypeOf` + setPrototypeOf && + // we haven't completely correct pre-ES6 way for getting `new.target`, so use this + isCallable(NewTarget = dummy.constructor) && + NewTarget !== Wrapper && + isObject(NewTargetPrototype = NewTarget.prototype) && + NewTargetPrototype !== Wrapper.prototype + ) setPrototypeOf($this, NewTargetPrototype); + return $this; +}; + + +/***/ }), +/* 80 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toString = __webpack_require__(81); + +module.exports = function (argument, $default) { + return argument === undefined ? arguments.length < 2 ? '' : $default : toString(argument); +}; + + +/***/ }), +/* 81 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var classof = __webpack_require__(82); + +var $String = String; + +module.exports = function (argument) { + if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string'); + return $String(argument); +}; + + +/***/ }), +/* 82 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var TO_STRING_TAG_SUPPORT = __webpack_require__(83); +var isCallable = __webpack_require__(28); +var classofRaw = __webpack_require__(46); +var wellKnownSymbol = __webpack_require__(13); + +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); +var $Object = Object; + +// ES3 wrong here +var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments'; + +// fallback for IE11 Script Access Denied error +var tryGet = function (it, key) { + try { + return it[key]; + } catch (error) { /* empty */ } +}; + +// getting tag from ES6+ `Object.prototype.toString` +module.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) { + var O, tag, result; + return it === undefined ? 'Undefined' : it === null ? 'Null' + // @@toStringTag case + : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag + // builtinTag case + : CORRECT_ARGUMENTS ? classofRaw(O) + // ES3 arguments fallback + : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result; +}; + + +/***/ }), +/* 83 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var wellKnownSymbol = __webpack_require__(13); + +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); +var test = {}; +// eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation +test[TO_STRING_TAG] = 'z'; + +module.exports = String(test) === '[object z]'; + + +/***/ }), +/* 84 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isObject = __webpack_require__(27); +var createNonEnumerableProperty = __webpack_require__(50); + +// `InstallErrorCause` abstract operation +// https://tc39.es/ecma262/#sec-installerrorcause +module.exports = function (O, options) { + if (isObject(options) && 'cause' in options) { + createNonEnumerableProperty(O, 'cause', options.cause); + } +}; + + +/***/ }), +/* 85 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var createNonEnumerableProperty = __webpack_require__(50); +var clearErrorStack = __webpack_require__(86); +var ERROR_STACK_INSTALLABLE = __webpack_require__(87); + +// non-standard V8 +// eslint-disable-next-line es/no-nonstandard-error-properties -- safe +var captureStackTrace = Error.captureStackTrace; + +module.exports = function (error, C, stack, dropEntries) { + if (ERROR_STACK_INSTALLABLE) { + if (captureStackTrace) captureStackTrace(error, C); + else createNonEnumerableProperty(error, 'stack', clearErrorStack(stack, dropEntries)); + } +}; + + +/***/ }), +/* 86 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +var $Error = Error; +var replace = uncurryThis(''.replace); + +var TEST = (function (arg) { return String(new $Error(arg).stack); })('zxcasd'); +// eslint-disable-next-line redos/no-vulnerable, sonarjs/slow-regex -- safe +var V8_OR_CHAKRA_STACK_ENTRY = /\n\s*at [^:]*:[^\n]*/; +var IS_V8_OR_CHAKRA_STACK = V8_OR_CHAKRA_STACK_ENTRY.test(TEST); + +module.exports = function (stack, dropEntries) { + if (IS_V8_OR_CHAKRA_STACK && typeof stack == 'string' && !$Error.prepareStackTrace) { + while (dropEntries--) stack = replace(stack, V8_OR_CHAKRA_STACK_ENTRY, ''); + } return stack; +}; + + +/***/ }), +/* 87 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); +var createPropertyDescriptor = __webpack_require__(43); + +module.exports = !fails(function () { + var error = new Error('a'); + if (!('stack' in error)) return true; + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty(error, 'stack', createPropertyDescriptor(1, 7)); + return error.stack !== 7; +}); + + +/***/ }), +/* 88 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var isObject = __webpack_require__(27); +var classof = __webpack_require__(82); +var fails = __webpack_require__(8); + +var ERROR = 'Error'; +var DOM_EXCEPTION = 'DOMException'; +// eslint-disable-next-line es/no-object-setprototypeof, no-proto -- safe +var PROTOTYPE_SETTING_AVAILABLE = Object.setPrototypeOf || ({}).__proto__; + +var DOMException = getBuiltIn(DOM_EXCEPTION); +var $Error = Error; +// eslint-disable-next-line es/no-error-iserror -- safe +var $isError = $Error.isError; + +var FORCED = !$isError || !PROTOTYPE_SETTING_AVAILABLE || fails(function () { + // Bun, isNativeError-based implementations, some buggy structuredClone-based implementations, etc. + // https://github.com/oven-sh/bun/issues/15821 + return (DOMException && !$isError(new DOMException(DOM_EXCEPTION))) || + // structuredClone-based implementations + // eslint-disable-next-line es/no-error-cause -- detection + !$isError(new $Error(ERROR, { cause: function () { /* empty */ } })) || + // instanceof-based and FF Error#stack-based implementations + $isError(getBuiltIn('Object', 'create')($Error.prototype)); +}); + +// `Error.isError` method +// https://tc39.es/ecma262/#sec-error.iserror +$({ target: 'Error', stat: true, sham: true, forced: FORCED }, { + isError: function isError(arg) { + if (!isObject(arg)) return false; + var tag = classof(arg); + return tag === ERROR || tag === DOM_EXCEPTION; + } +}); + + +/***/ }), +/* 89 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove this module from `core-js@4` since it's replaced to module below +__webpack_require__(90); + + +/***/ }), +/* 90 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isPrototypeOf = __webpack_require__(36); +var getPrototypeOf = __webpack_require__(91); +var setPrototypeOf = __webpack_require__(74); +var copyConstructorProperties = __webpack_require__(59); +var create = __webpack_require__(93); +var createNonEnumerableProperty = __webpack_require__(50); +var createPropertyDescriptor = __webpack_require__(43); +var installErrorCause = __webpack_require__(84); +var installErrorStack = __webpack_require__(85); +var iterate = __webpack_require__(97); +var normalizeStringArgument = __webpack_require__(80); +var wellKnownSymbol = __webpack_require__(13); + +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); +var $Error = Error; +var push = [].push; + +var $AggregateError = function AggregateError(errors, message /* , options */) { + var isInstance = isPrototypeOf(AggregateErrorPrototype, this); + var that; + if (setPrototypeOf) { + that = setPrototypeOf(new $Error(), isInstance ? getPrototypeOf(this) : AggregateErrorPrototype); + } else { + that = isInstance ? this : create(AggregateErrorPrototype); + createNonEnumerableProperty(that, TO_STRING_TAG, 'Error'); + } + if (message !== undefined) createNonEnumerableProperty(that, 'message', normalizeStringArgument(message)); + installErrorStack(that, $AggregateError, that.stack, 1); + if (arguments.length > 2) installErrorCause(that, arguments[2]); + var errorsArray = []; + iterate(errors, push, { that: errorsArray }); + createNonEnumerableProperty(that, 'errors', errorsArray); + return that; +}; + +if (setPrototypeOf) setPrototypeOf($AggregateError, $Error); +else copyConstructorProperties($AggregateError, $Error, { name: true }); + +var AggregateErrorPrototype = $AggregateError.prototype = create($Error.prototype, { + constructor: createPropertyDescriptor(1, $AggregateError), + message: createPropertyDescriptor(1, ''), + name: createPropertyDescriptor(1, 'AggregateError') +}); + +// `AggregateError` constructor +// https://tc39.es/ecma262/#sec-aggregate-error-constructor +$({ global: true, constructor: true, arity: 2 }, { + AggregateError: $AggregateError +}); + + +/***/ }), +/* 91 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var hasOwn = __webpack_require__(5); +var isCallable = __webpack_require__(28); +var toObject = __webpack_require__(9); +var sharedKey = __webpack_require__(57); +var CORRECT_PROTOTYPE_GETTER = __webpack_require__(92); + +var IE_PROTO = sharedKey('IE_PROTO'); +var $Object = Object; +var ObjectPrototype = $Object.prototype; + +// `Object.getPrototypeOf` method +// https://tc39.es/ecma262/#sec-object.getprototypeof +// eslint-disable-next-line es/no-object-getprototypeof -- safe +module.exports = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : function (O) { + var object = toObject(O); + if (hasOwn(object, IE_PROTO)) return object[IE_PROTO]; + var constructor = object.constructor; + if (isCallable(constructor) && object instanceof constructor) { + return constructor.prototype; + } return object instanceof $Object ? ObjectPrototype : null; +}; + + +/***/ }), +/* 92 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); + +module.exports = !fails(function () { + function F() { /* empty */ } + F.prototype.constructor = null; + // eslint-disable-next-line es/no-object-getprototypeof -- required for testing + return Object.getPrototypeOf(new F()) !== F.prototype; +}); + + +/***/ }), +/* 93 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* global ActiveXObject -- old IE, WSH */ +var anObject = __webpack_require__(30); +var definePropertiesModule = __webpack_require__(94); +var enumBugKeys = __webpack_require__(69); +var hiddenKeys = __webpack_require__(58); +var html = __webpack_require__(96); +var documentCreateElement = __webpack_require__(26); +var sharedKey = __webpack_require__(57); + +var GT = '>'; +var LT = '<'; +var PROTOTYPE = 'prototype'; +var SCRIPT = 'script'; +var IE_PROTO = sharedKey('IE_PROTO'); + +var EmptyConstructor = function () { /* empty */ }; + +var scriptTag = function (content) { + return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT; +}; + +// Create object with fake `null` prototype: use ActiveX Object with cleared prototype +var NullProtoObjectViaActiveX = function (activeXDocument) { + activeXDocument.write(scriptTag('')); + activeXDocument.close(); + var temp = activeXDocument.parentWindow.Object; + // eslint-disable-next-line no-useless-assignment -- avoid memory leak + activeXDocument = null; + return temp; +}; + +// Create object with fake `null` prototype: use iframe Object with cleared prototype +var NullProtoObjectViaIFrame = function () { + // Thrash, waste and sodomy: IE GC bug + var iframe = documentCreateElement('iframe'); + var JS = 'java' + SCRIPT + ':'; + var iframeDocument; + iframe.style.display = 'none'; + html.appendChild(iframe); + // https://github.com/zloirock/core-js/issues/475 + iframe.src = String(JS); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(scriptTag('document.F=Object')); + iframeDocument.close(); + return iframeDocument.F; +}; + +// Check for document.domain and active x support +// No need to use active x approach when document.domain is not set +// see https://github.com/es-shims/es5-shim/issues/150 +// variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346 +// avoid IE GC bug +var activeXDocument; +var NullProtoObject = function () { + try { + activeXDocument = new ActiveXObject('htmlfile'); + } catch (error) { /* ignore */ } + NullProtoObject = typeof document != 'undefined' + ? document.domain && activeXDocument + ? NullProtoObjectViaActiveX(activeXDocument) // old IE + : NullProtoObjectViaIFrame() + : NullProtoObjectViaActiveX(activeXDocument); // WSH + var length = enumBugKeys.length; + while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]]; + return NullProtoObject(); +}; + +hiddenKeys[IE_PROTO] = true; + +// `Object.create` method +// https://tc39.es/ecma262/#sec-object.create +// eslint-disable-next-line es/no-object-create -- safe +module.exports = Object.create || function create(O, Properties) { + var result; + if (O !== null) { + EmptyConstructor[PROTOTYPE] = anObject(O); + result = new EmptyConstructor(); + EmptyConstructor[PROTOTYPE] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO] = O; + } else result = NullProtoObject(); + return Properties === undefined ? result : definePropertiesModule.f(result, Properties); +}; + + +/***/ }), +/* 94 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(29); +var definePropertyModule = __webpack_require__(23); +var anObject = __webpack_require__(30); +var toIndexedObject = __webpack_require__(44); +var objectKeys = __webpack_require__(95); + +// `Object.defineProperties` method +// https://tc39.es/ecma262/#sec-object.defineproperties +// eslint-disable-next-line es/no-object-defineproperties -- safe +exports.f = DESCRIPTORS && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O, Properties) { + anObject(O); + var props = toIndexedObject(Properties); + var keys = objectKeys(Properties); + var length = keys.length; + var index = 0; + var key; + while (length > index) definePropertyModule.f(O, key = keys[index++], props[key]); + return O; +}; + + +/***/ }), +/* 95 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var internalObjectKeys = __webpack_require__(62); +var enumBugKeys = __webpack_require__(69); + +// `Object.keys` method +// https://tc39.es/ecma262/#sec-object.keys +// eslint-disable-next-line es/no-object-keys -- safe +module.exports = Object.keys || function keys(O) { + return internalObjectKeys(O, enumBugKeys); +}; + + +/***/ }), +/* 96 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); + +module.exports = getBuiltIn('document', 'documentElement'); + + +/***/ }), +/* 97 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var bind = __webpack_require__(98); +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var tryToString = __webpack_require__(39); +var isArrayIteratorMethod = __webpack_require__(100); +var lengthOfArrayLike = __webpack_require__(67); +var isPrototypeOf = __webpack_require__(36); +var getIterator = __webpack_require__(102); +var getIteratorMethod = __webpack_require__(103); +var iteratorClose = __webpack_require__(104); + +var $TypeError = TypeError; + +var Result = function (stopped, result) { + this.stopped = stopped; + this.result = result; +}; + +var ResultPrototype = Result.prototype; + +module.exports = function (iterable, unboundFunction, options) { + var that = options && options.that; + var AS_ENTRIES = !!(options && options.AS_ENTRIES); + var IS_RECORD = !!(options && options.IS_RECORD); + var IS_ITERATOR = !!(options && options.IS_ITERATOR); + var INTERRUPTED = !!(options && options.INTERRUPTED); + var fn = bind(unboundFunction, that); + var iterator, iterFn, index, length, result, next, step; + + var stop = function (condition) { + if (iterator) iteratorClose(iterator, 'normal'); + return new Result(true, condition); + }; + + var callFn = function (value) { + if (AS_ENTRIES) { + anObject(value); + return INTERRUPTED ? fn(value[0], value[1], stop) : fn(value[0], value[1]); + } return INTERRUPTED ? fn(value, stop) : fn(value); + }; + + if (IS_RECORD) { + iterator = iterable.iterator; + } else if (IS_ITERATOR) { + iterator = iterable; + } else { + iterFn = getIteratorMethod(iterable); + if (!iterFn) throw new $TypeError(tryToString(iterable) + ' is not iterable'); + // optimisation for array iterators + if (isArrayIteratorMethod(iterFn)) { + for (index = 0, length = lengthOfArrayLike(iterable); length > index; index++) { + result = callFn(iterable[index]); + if (result && isPrototypeOf(ResultPrototype, result)) return result; + } return new Result(false); + } + iterator = getIterator(iterable, iterFn); + } + + next = IS_RECORD ? iterable.next : iterator.next; + while (!(step = call(next, iterator)).done) { + try { + result = callFn(step.value); + } catch (error) { + iteratorClose(iterator, 'throw', error); + } + if (typeof result == 'object' && result && isPrototypeOf(ResultPrototype, result)) return result; + } return new Result(false); +}; + + +/***/ }), +/* 98 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(99); +var aCallable = __webpack_require__(38); +var NATIVE_BIND = __webpack_require__(7); + +var bind = uncurryThis(uncurryThis.bind); + +// optional / simple context binding +module.exports = function (fn, that) { + aCallable(fn); + return that === undefined ? fn : NATIVE_BIND ? bind(fn, that) : function (/* ...args */) { + return fn.apply(that, arguments); + }; +}; + + +/***/ }), +/* 99 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var classofRaw = __webpack_require__(46); +var uncurryThis = __webpack_require__(6); + +module.exports = function (fn) { + // Nashorn bug: + // https://github.com/zloirock/core-js/issues/1128 + // https://github.com/zloirock/core-js/issues/1130 + if (classofRaw(fn) === 'Function') return uncurryThis(fn); +}; + + +/***/ }), +/* 100 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var wellKnownSymbol = __webpack_require__(13); +var Iterators = __webpack_require__(101); + +var ITERATOR = wellKnownSymbol('iterator'); +var ArrayPrototype = Array.prototype; + +// check on default Array iterator +module.exports = function (it) { + return it !== undefined && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it); +}; + + +/***/ }), +/* 101 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = {}; + + +/***/ }), +/* 102 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var tryToString = __webpack_require__(39); +var getIteratorMethod = __webpack_require__(103); + +var $TypeError = TypeError; + +module.exports = function (argument, usingIterator) { + var iteratorMethod = arguments.length < 2 ? getIteratorMethod(argument) : usingIterator; + if (aCallable(iteratorMethod)) return anObject(call(iteratorMethod, argument)); + throw new $TypeError(tryToString(argument) + ' is not iterable'); +}; + + +/***/ }), +/* 103 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var classof = __webpack_require__(82); +var getMethod = __webpack_require__(37); +var isNullOrUndefined = __webpack_require__(11); +var Iterators = __webpack_require__(101); +var wellKnownSymbol = __webpack_require__(13); + +var ITERATOR = wellKnownSymbol('iterator'); + +module.exports = function (it) { + if (!isNullOrUndefined(it)) return getMethod(it, ITERATOR) + || getMethod(it, '@@iterator') + || Iterators[classof(it)]; +}; + + +/***/ }), +/* 104 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var getMethod = __webpack_require__(37); + +module.exports = function (iterator, kind, value) { + var innerResult, innerError; + anObject(iterator); + try { + innerResult = getMethod(iterator, 'return'); + if (!innerResult) { + if (kind === 'throw') throw value; + return value; + } + innerResult = call(innerResult, iterator); + } catch (error) { + innerError = true; + innerResult = error; + } + if (kind === 'throw') throw value; + if (innerError) throw innerResult; + anObject(innerResult); + return value; +}; + + +/***/ }), +/* 105 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var apply = __webpack_require__(72); +var fails = __webpack_require__(8); +var wrapErrorConstructorWithCause = __webpack_require__(73); + +var AGGREGATE_ERROR = 'AggregateError'; +var $AggregateError = getBuiltIn(AGGREGATE_ERROR); + +var FORCED = !fails(function () { + return $AggregateError([1]).errors[0] !== 1; +}) && fails(function () { + return $AggregateError([1], AGGREGATE_ERROR, { cause: 7 }).cause !== 7; +}); + +// https://tc39.es/ecma262/#sec-aggregate-error +$({ global: true, constructor: true, arity: 2, forced: FORCED }, { + AggregateError: wrapErrorConstructorWithCause(AGGREGATE_ERROR, function (init) { + // eslint-disable-next-line no-unused-vars -- required for functions `.length` + return function AggregateError(errors, message) { return apply(init, this, arguments); }; + }, FORCED, true) +}); + + +/***/ }), +/* 106 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var isPrototypeOf = __webpack_require__(36); +var getPrototypeOf = __webpack_require__(91); +var setPrototypeOf = __webpack_require__(74); +var copyConstructorProperties = __webpack_require__(59); +var create = __webpack_require__(93); +var createNonEnumerableProperty = __webpack_require__(50); +var createPropertyDescriptor = __webpack_require__(43); +var installErrorStack = __webpack_require__(85); +var normalizeStringArgument = __webpack_require__(80); +var wellKnownSymbol = __webpack_require__(13); +var fails = __webpack_require__(8); +var IS_PURE = __webpack_require__(16); + +var NativeSuppressedError = globalThis.SuppressedError; +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); +var $Error = Error; + +// https://github.com/oven-sh/bun/issues/9282 +var WRONG_ARITY = !!NativeSuppressedError && NativeSuppressedError.length !== 3; + +// https://github.com/oven-sh/bun/issues/9283 +var EXTRA_ARGS_SUPPORT = !!NativeSuppressedError && fails(function () { + return new NativeSuppressedError(1, 2, 3, { cause: 4 }).cause === 4; +}); + +var PATCH = WRONG_ARITY || EXTRA_ARGS_SUPPORT; + +var $SuppressedError = function SuppressedError(error, suppressed, message) { + var isInstance = isPrototypeOf(SuppressedErrorPrototype, this); + var that; + if (setPrototypeOf) { + that = PATCH && (!isInstance || getPrototypeOf(this) === SuppressedErrorPrototype) + ? new NativeSuppressedError() + : setPrototypeOf(new $Error(), isInstance ? getPrototypeOf(this) : SuppressedErrorPrototype); + } else { + that = isInstance ? this : create(SuppressedErrorPrototype); + createNonEnumerableProperty(that, TO_STRING_TAG, 'Error'); + } + if (message !== undefined) createNonEnumerableProperty(that, 'message', normalizeStringArgument(message)); + installErrorStack(that, $SuppressedError, that.stack, 1); + createNonEnumerableProperty(that, 'error', error); + createNonEnumerableProperty(that, 'suppressed', suppressed); + return that; +}; + +if (setPrototypeOf) setPrototypeOf($SuppressedError, $Error); +else copyConstructorProperties($SuppressedError, $Error, { name: true }); + +var SuppressedErrorPrototype = $SuppressedError.prototype = PATCH ? NativeSuppressedError.prototype : create($Error.prototype, { + constructor: createPropertyDescriptor(1, $SuppressedError), + message: createPropertyDescriptor(1, ''), + name: createPropertyDescriptor(1, 'SuppressedError') +}); + +if (PATCH && !IS_PURE) SuppressedErrorPrototype.constructor = $SuppressedError; + +// `SuppressedError` constructor +// https://github.com/tc39/proposal-explicit-resource-management +$({ global: true, constructor: true, arity: 3, forced: PATCH }, { + SuppressedError: $SuppressedError +}); + + +/***/ }), +/* 107 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var toObject = __webpack_require__(9); +var lengthOfArrayLike = __webpack_require__(67); +var toIntegerOrInfinity = __webpack_require__(65); +var addToUnscopables = __webpack_require__(108); + +// `Array.prototype.at` method +// https://tc39.es/ecma262/#sec-array.prototype.at +$({ target: 'Array', proto: true }, { + at: function at(index) { + var O = toObject(this); + var len = lengthOfArrayLike(O); + var relativeIndex = toIntegerOrInfinity(index); + var k = relativeIndex >= 0 ? relativeIndex : len + relativeIndex; + return (k < 0 || k >= len) ? undefined : O[k]; + } +}); + +addToUnscopables('at'); + + +/***/ }), +/* 108 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var wellKnownSymbol = __webpack_require__(13); +var create = __webpack_require__(93); +var defineProperty = __webpack_require__(23).f; + +var UNSCOPABLES = wellKnownSymbol('unscopables'); +var ArrayPrototype = Array.prototype; + +// Array.prototype[@@unscopables] +// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables +if (ArrayPrototype[UNSCOPABLES] === undefined) { + defineProperty(ArrayPrototype, UNSCOPABLES, { + configurable: true, + value: create(null) + }); +} + +// add a key to Array.prototype[@@unscopables] +module.exports = function (key) { + ArrayPrototype[UNSCOPABLES][key] = true; +}; + + +/***/ }), +/* 109 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $findLast = __webpack_require__(110).findLast; +var addToUnscopables = __webpack_require__(108); + +// `Array.prototype.findLast` method +// https://tc39.es/ecma262/#sec-array.prototype.findlast +$({ target: 'Array', proto: true }, { + findLast: function findLast(callbackfn /* , that = undefined */) { + return $findLast(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); + +addToUnscopables('findLast'); + + +/***/ }), +/* 110 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var bind = __webpack_require__(98); +var IndexedObject = __webpack_require__(45); +var toObject = __webpack_require__(9); +var lengthOfArrayLike = __webpack_require__(67); + +// `Array.prototype.{ findLast, findLastIndex }` methods implementation +var createMethod = function (TYPE) { + var IS_FIND_LAST_INDEX = TYPE === 1; + return function ($this, callbackfn, that) { + var O = toObject($this); + var self = IndexedObject(O); + var index = lengthOfArrayLike(self); + var boundFunction = bind(callbackfn, that); + var value, result; + while (index-- > 0) { + value = self[index]; + result = boundFunction(value, index, O); + if (result) switch (TYPE) { + case 0: return value; // findLast + case 1: return index; // findLastIndex + } + } + return IS_FIND_LAST_INDEX ? -1 : undefined; + }; +}; + +module.exports = { + // `Array.prototype.findLast` method + // https://github.com/tc39/proposal-array-find-from-last + findLast: createMethod(0), + // `Array.prototype.findLastIndex` method + // https://github.com/tc39/proposal-array-find-from-last + findLastIndex: createMethod(1) +}; + + +/***/ }), +/* 111 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $findLastIndex = __webpack_require__(110).findLastIndex; +var addToUnscopables = __webpack_require__(108); + +// `Array.prototype.findLastIndex` method +// https://tc39.es/ecma262/#sec-array.prototype.findlastindex +$({ target: 'Array', proto: true }, { + findLastIndex: function findLastIndex(callbackfn /* , that = undefined */) { + return $findLastIndex(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); + +addToUnscopables('findLastIndex'); + + +/***/ }), +/* 112 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var toObject = __webpack_require__(9); +var lengthOfArrayLike = __webpack_require__(67); +var setArrayLength = __webpack_require__(113); +var doesNotExceedSafeInteger = __webpack_require__(115); +var fails = __webpack_require__(8); + +var INCORRECT_TO_LENGTH = fails(function () { + return [].push.call({ length: 0x100000000 }, 1) !== 4294967297; +}); + +// V8 <= 121 and Safari <= 15.4; FF < 23 throws InternalError +// https://bugs.chromium.org/p/v8/issues/detail?id=12681 +var properErrorOnNonWritableLength = function () { + try { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty([], 'length', { writable: false }).push(); + } catch (error) { + return error instanceof TypeError; + } +}; + +var FORCED = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength(); + +// `Array.prototype.push` method +// https://tc39.es/ecma262/#sec-array.prototype.push +$({ target: 'Array', proto: true, arity: 1, forced: FORCED }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + push: function push(item) { + var O = toObject(this); + var len = lengthOfArrayLike(O); + var argCount = arguments.length; + doesNotExceedSafeInteger(len + argCount); + for (var i = 0; i < argCount; i++) { + O[len] = arguments[i]; + len++; + } + setArrayLength(O, len); + return len; + } +}); + + +/***/ }), +/* 113 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var isArray = __webpack_require__(114); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Safari < 13 does not throw an error in this case +var SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS && !function () { + // makes no sense without proper strict mode support + if (this !== undefined) return true; + try { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty([], 'length', { writable: false }).length = 1; + } catch (error) { + return error instanceof TypeError; + } +}(); + +module.exports = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) { + if (isArray(O) && !getOwnPropertyDescriptor(O, 'length').writable) { + throw new $TypeError('Cannot set read only .length'); + } return O.length = length; +} : function (O, length) { + return O.length = length; +}; + + +/***/ }), +/* 114 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var classof = __webpack_require__(46); + +// `IsArray` abstract operation +// https://tc39.es/ecma262/#sec-isarray +// eslint-disable-next-line es/no-array-isarray -- safe +module.exports = Array.isArray || function isArray(argument) { + return classof(argument) === 'Array'; +}; + + +/***/ }), +/* 115 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $TypeError = TypeError; +var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991 + +module.exports = function (it) { + if (it > MAX_SAFE_INTEGER) throw $TypeError('Maximum allowed index exceeded'); + return it; +}; + + +/***/ }), +/* 116 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var arrayToReversed = __webpack_require__(117); +var toIndexedObject = __webpack_require__(44); +var addToUnscopables = __webpack_require__(108); + +var $Array = Array; + +// `Array.prototype.toReversed` method +// https://tc39.es/ecma262/#sec-array.prototype.toreversed +$({ target: 'Array', proto: true }, { + toReversed: function toReversed() { + return arrayToReversed(toIndexedObject(this), $Array); + } +}); + +addToUnscopables('toReversed'); + + +/***/ }), +/* 117 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var lengthOfArrayLike = __webpack_require__(67); + +// https://tc39.es/ecma262/#sec-array.prototype.toreversed +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.toreversed +module.exports = function (O, C) { + var len = lengthOfArrayLike(O); + var A = new C(len); + var k = 0; + for (; k < len; k++) A[k] = O[len - k - 1]; + return A; +}; + + +/***/ }), +/* 118 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var aCallable = __webpack_require__(38); +var toIndexedObject = __webpack_require__(44); +var arrayFromConstructorAndList = __webpack_require__(119); +var getBuiltInPrototypeMethod = __webpack_require__(120); +var addToUnscopables = __webpack_require__(108); + +var $Array = Array; +var sort = uncurryThis(getBuiltInPrototypeMethod('Array', 'sort')); + +// `Array.prototype.toSorted` method +// https://tc39.es/ecma262/#sec-array.prototype.tosorted +$({ target: 'Array', proto: true }, { + toSorted: function toSorted(compareFn) { + if (compareFn !== undefined) aCallable(compareFn); + var O = toIndexedObject(this); + var A = arrayFromConstructorAndList($Array, O); + return sort(A, compareFn); + } +}); + +addToUnscopables('toSorted'); + + +/***/ }), +/* 119 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var lengthOfArrayLike = __webpack_require__(67); + +module.exports = function (Constructor, list, $length) { + var index = 0; + var length = arguments.length > 2 ? $length : lengthOfArrayLike(list); + var result = new Constructor(length); + while (length > index) result[index] = list[index++]; + return result; +}; + + +/***/ }), +/* 120 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); + +module.exports = function (CONSTRUCTOR, METHOD) { + var Constructor = globalThis[CONSTRUCTOR]; + var Prototype = Constructor && Constructor.prototype; + return Prototype && Prototype[METHOD]; +}; + + +/***/ }), +/* 121 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var addToUnscopables = __webpack_require__(108); +var doesNotExceedSafeInteger = __webpack_require__(115); +var lengthOfArrayLike = __webpack_require__(67); +var toAbsoluteIndex = __webpack_require__(64); +var toIndexedObject = __webpack_require__(44); +var toIntegerOrInfinity = __webpack_require__(65); + +var $Array = Array; +var max = Math.max; +var min = Math.min; + +// `Array.prototype.toSpliced` method +// https://tc39.es/ecma262/#sec-array.prototype.tospliced +$({ target: 'Array', proto: true }, { + toSpliced: function toSpliced(start, deleteCount /* , ...items */) { + var O = toIndexedObject(this); + var len = lengthOfArrayLike(O); + var actualStart = toAbsoluteIndex(start, len); + var argumentsLength = arguments.length; + var k = 0; + var insertCount, actualDeleteCount, newLen, A; + if (argumentsLength === 0) { + insertCount = actualDeleteCount = 0; + } else if (argumentsLength === 1) { + insertCount = 0; + actualDeleteCount = len - actualStart; + } else { + insertCount = argumentsLength - 2; + actualDeleteCount = min(max(toIntegerOrInfinity(deleteCount), 0), len - actualStart); + } + newLen = doesNotExceedSafeInteger(len + insertCount - actualDeleteCount); + A = $Array(newLen); + + for (; k < actualStart; k++) A[k] = O[k]; + for (; k < actualStart + insertCount; k++) A[k] = arguments[k - actualStart + 2]; + for (; k < newLen; k++) A[k] = O[k + actualDeleteCount - insertCount]; + + return A; + } +}); + +addToUnscopables('toSpliced'); + + +/***/ }), +/* 122 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var arrayWith = __webpack_require__(123); +var toIndexedObject = __webpack_require__(44); + +var $Array = Array; + +// Firefox bug +var INCORRECT_EXCEPTION_ON_COERCION_FAIL = (function () { + try { + // eslint-disable-next-line es/no-array-prototype-with, no-throw-literal -- needed for testing + []['with']({ valueOf: function () { throw 4; } }, null); + } catch (error) { + return error !== 4; + } +})(); + +// `Array.prototype.with` method +// https://tc39.es/ecma262/#sec-array.prototype.with +$({ target: 'Array', proto: true, forced: INCORRECT_EXCEPTION_ON_COERCION_FAIL }, { + 'with': function (index, value) { + return arrayWith(toIndexedObject(this), $Array, index, value); + } +}); + + +/***/ }), +/* 123 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var lengthOfArrayLike = __webpack_require__(67); +var toIntegerOrInfinity = __webpack_require__(65); + +var $RangeError = RangeError; + +// https://tc39.es/ecma262/#sec-array.prototype.with +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.with +module.exports = function (O, C, index, value) { + var len = lengthOfArrayLike(O); + var relativeIndex = toIntegerOrInfinity(index); + var actualIndex = relativeIndex < 0 ? len + relativeIndex : relativeIndex; + if (actualIndex >= len || actualIndex < 0) throw new $RangeError('Incorrect index'); + var A = new C(len); + var k = 0; + for (; k < len; k++) A[k] = k === actualIndex ? value : O[k]; + return A; +}; + + +/***/ }), +/* 124 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); + +var pow = Math.pow; + +var EXP_MASK16 = 31; // 2 ** 5 - 1 +var SIGNIFICAND_MASK16 = 1023; // 2 ** 10 - 1 +var MIN_SUBNORMAL16 = pow(2, -24); // 2 ** -10 * 2 ** -14 +var SIGNIFICAND_DENOM16 = 0.0009765625; // 2 ** -10 + +var unpackFloat16 = function (bytes) { + var sign = bytes >>> 15; + var exponent = bytes >>> 10 & EXP_MASK16; + var significand = bytes & SIGNIFICAND_MASK16; + if (exponent === EXP_MASK16) return significand === 0 ? (sign === 0 ? Infinity : -Infinity) : NaN; + if (exponent === 0) return significand * (sign === 0 ? MIN_SUBNORMAL16 : -MIN_SUBNORMAL16); + return pow(2, exponent - 15) * (sign === 0 ? 1 + significand * SIGNIFICAND_DENOM16 : -1 - significand * SIGNIFICAND_DENOM16); +}; + +// eslint-disable-next-line es/no-typed-arrays -- safe +var getUint16 = uncurryThis(DataView.prototype.getUint16); + +// `DataView.prototype.getFloat16` method +// https://tc39.es/ecma262/#sec-dataview.prototype.getfloat16 +$({ target: 'DataView', proto: true }, { + getFloat16: function getFloat16(byteOffset /* , littleEndian */) { + return unpackFloat16(getUint16(this, byteOffset, arguments.length > 1 ? arguments[1] : false)); + } +}); + + +/***/ }), +/* 125 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var aDataView = __webpack_require__(126); +var toIndex = __webpack_require__(127); +// TODO: Replace with module dependency in `core-js@4` +var log2 = __webpack_require__(128); +var roundTiesToEven = __webpack_require__(129); + +var pow = Math.pow; + +var MIN_INFINITY16 = 65520; // (2 - 2 ** -11) * 2 ** 15 +var MIN_NORMAL16 = 0.000061005353927612305; // (1 - 2 ** -11) * 2 ** -14 +var REC_MIN_SUBNORMAL16 = 16777216; // 2 ** 10 * 2 ** 14 +var REC_SIGNIFICAND_DENOM16 = 1024; // 2 ** 10; + +var packFloat16 = function (value) { + // eslint-disable-next-line no-self-compare -- NaN check + if (value !== value) return 0x7E00; // NaN + if (value === 0) return (1 / value === -Infinity) << 15; // +0 or -0 + + var neg = value < 0; + if (neg) value = -value; + if (value >= MIN_INFINITY16) return neg << 15 | 0x7C00; // Infinity + if (value < MIN_NORMAL16) return neg << 15 | roundTiesToEven(value * REC_MIN_SUBNORMAL16); // subnormal + + // normal + var exponent = log2(value) | 0; + if (exponent === -15) { + // we round from a value between 2 ** -15 * (1 + 1022/1024) (the largest subnormal) and 2 ** -14 * (1 + 0/1024) (the smallest normal) + // to the latter (former impossible because of the subnormal check above) + return neg << 15 | REC_SIGNIFICAND_DENOM16; + } + var significand = roundTiesToEven((value * pow(2, -exponent) - 1) * REC_SIGNIFICAND_DENOM16); + if (significand === REC_SIGNIFICAND_DENOM16) { + // we round from a value between 2 ** n * (1 + 1023/1024) and 2 ** (n + 1) * (1 + 0/1024) to the latter + return neg << 15 | exponent + 16 << 10; + } + return neg << 15 | exponent + 15 << 10 | significand; +}; + +// eslint-disable-next-line es/no-typed-arrays -- safe +var setUint16 = uncurryThis(DataView.prototype.setUint16); + +// `DataView.prototype.setFloat16` method +// https://tc39.es/ecma262/#sec-dataview.prototype.setfloat16 +$({ target: 'DataView', proto: true }, { + setFloat16: function setFloat16(byteOffset, value /* , littleEndian */) { + setUint16( + aDataView(this), + toIndex(byteOffset), + packFloat16(+value), + arguments.length > 2 ? arguments[2] : false + ); + } +}); + + +/***/ }), +/* 126 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var classof = __webpack_require__(82); + +var $TypeError = TypeError; + +module.exports = function (argument) { + if (classof(argument) === 'DataView') return argument; + throw new $TypeError('Argument is not a DataView'); +}; + + +/***/ }), +/* 127 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(65); +var toLength = __webpack_require__(68); + +var $RangeError = RangeError; + +// `ToIndex` abstract operation +// https://tc39.es/ecma262/#sec-toindex +module.exports = function (it) { + if (it === undefined) return 0; + var number = toIntegerOrInfinity(it); + var length = toLength(number); + if (number !== length) throw new $RangeError('Wrong length or index'); + return length; +}; + + +/***/ }), +/* 128 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var log = Math.log; +var LN2 = Math.LN2; + +// `Math.log2` method +// https://tc39.es/ecma262/#sec-math.log2 +// eslint-disable-next-line es/no-math-log2 -- safe +module.exports = Math.log2 || function log2(x) { + return log(x) / LN2; +}; + + +/***/ }), +/* 129 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var EPSILON = 2.220446049250313e-16; // Number.EPSILON +var INVERSE_EPSILON = 1 / EPSILON; + +module.exports = function (n) { + return n + INVERSE_EPSILON - INVERSE_EPSILON; +}; + + +/***/ }), +/* 130 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var defineBuiltInAccessor = __webpack_require__(131); +var isDetached = __webpack_require__(132); + +var ArrayBufferPrototype = ArrayBuffer.prototype; + +// `ArrayBuffer.prototype.detached` getter +// https://tc39.es/ecma262/#sec-get-arraybuffer.prototype.detached +if (DESCRIPTORS && !('detached' in ArrayBufferPrototype)) { + defineBuiltInAccessor(ArrayBufferPrototype, 'detached', { + configurable: true, + get: function detached() { + return isDetached(this); + } + }); +} + + +/***/ }), +/* 131 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var makeBuiltIn = __webpack_require__(52); +var defineProperty = __webpack_require__(23); + +module.exports = function (target, name, descriptor) { + if (descriptor.get) makeBuiltIn(descriptor.get, name, { getter: true }); + if (descriptor.set) makeBuiltIn(descriptor.set, name, { setter: true }); + return defineProperty.f(target, name, descriptor); +}; + + +/***/ }), +/* 132 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var NATIVE_ARRAY_BUFFER = __webpack_require__(133); +var arrayBufferByteLength = __webpack_require__(134); + +var DataView = globalThis.DataView; + +module.exports = function (O) { + if (!NATIVE_ARRAY_BUFFER || arrayBufferByteLength(O) !== 0) return false; + try { + // eslint-disable-next-line no-new -- thrower + new DataView(O); + return false; + } catch (error) { + return true; + } +}; + + +/***/ }), +/* 133 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// eslint-disable-next-line es/no-typed-arrays -- safe +module.exports = typeof ArrayBuffer != 'undefined' && typeof DataView != 'undefined'; + + +/***/ }), +/* 134 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var uncurryThisAccessor = __webpack_require__(75); +var classof = __webpack_require__(46); + +var ArrayBuffer = globalThis.ArrayBuffer; +var TypeError = globalThis.TypeError; + +// Includes +// - Perform ? RequireInternalSlot(O, [[ArrayBufferData]]). +// - If IsSharedArrayBuffer(O) is true, throw a TypeError exception. +module.exports = ArrayBuffer && uncurryThisAccessor(ArrayBuffer.prototype, 'byteLength', 'get') || function (O) { + if (classof(O) !== 'ArrayBuffer') throw new TypeError('ArrayBuffer expected'); + return O.byteLength; +}; + + +/***/ }), +/* 135 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $transfer = __webpack_require__(136); + +// `ArrayBuffer.prototype.transfer` method +// https://tc39.es/ecma262/#sec-arraybuffer.prototype.transfer +if ($transfer) $({ target: 'ArrayBuffer', proto: true }, { + transfer: function transfer() { + return $transfer(this, arguments.length ? arguments[0] : undefined, true); + } +}); + + +/***/ }), +/* 136 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var uncurryThis = __webpack_require__(6); +var uncurryThisAccessor = __webpack_require__(75); +var toIndex = __webpack_require__(127); +var notDetached = __webpack_require__(137); +var arrayBufferByteLength = __webpack_require__(134); +var detachTransferable = __webpack_require__(138); +var PROPER_STRUCTURED_CLONE_TRANSFER = __webpack_require__(142); + +var structuredClone = globalThis.structuredClone; +var ArrayBuffer = globalThis.ArrayBuffer; +var DataView = globalThis.DataView; +var min = Math.min; +var ArrayBufferPrototype = ArrayBuffer.prototype; +var DataViewPrototype = DataView.prototype; +var slice = uncurryThis(ArrayBufferPrototype.slice); +var isResizable = uncurryThisAccessor(ArrayBufferPrototype, 'resizable', 'get'); +var maxByteLength = uncurryThisAccessor(ArrayBufferPrototype, 'maxByteLength', 'get'); +var getInt8 = uncurryThis(DataViewPrototype.getInt8); +var setInt8 = uncurryThis(DataViewPrototype.setInt8); + +module.exports = (PROPER_STRUCTURED_CLONE_TRANSFER || detachTransferable) && function (arrayBuffer, newLength, preserveResizability) { + var byteLength = arrayBufferByteLength(arrayBuffer); + var newByteLength = newLength === undefined ? byteLength : toIndex(newLength); + var fixedLength = !isResizable || !isResizable(arrayBuffer); + var newBuffer; + notDetached(arrayBuffer); + if (PROPER_STRUCTURED_CLONE_TRANSFER) { + arrayBuffer = structuredClone(arrayBuffer, { transfer: [arrayBuffer] }); + if (byteLength === newByteLength && (preserveResizability || fixedLength)) return arrayBuffer; + } + if (byteLength >= newByteLength && (!preserveResizability || fixedLength)) { + newBuffer = slice(arrayBuffer, 0, newByteLength); + } else { + var options = preserveResizability && !fixedLength && maxByteLength ? { maxByteLength: maxByteLength(arrayBuffer) } : undefined; + newBuffer = new ArrayBuffer(newByteLength, options); + var a = new DataView(arrayBuffer); + var b = new DataView(newBuffer); + var copyLength = min(newByteLength, byteLength); + for (var i = 0; i < copyLength; i++) setInt8(b, i, getInt8(a, i)); + } + if (!PROPER_STRUCTURED_CLONE_TRANSFER) detachTransferable(arrayBuffer); + return newBuffer; +}; + + +/***/ }), +/* 137 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isDetached = __webpack_require__(132); + +var $TypeError = TypeError; + +module.exports = function (it) { + if (isDetached(it)) throw new $TypeError('ArrayBuffer is detached'); + return it; +}; + + +/***/ }), +/* 138 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var getBuiltInNodeModule = __webpack_require__(139); +var PROPER_STRUCTURED_CLONE_TRANSFER = __webpack_require__(142); + +var structuredClone = globalThis.structuredClone; +var $ArrayBuffer = globalThis.ArrayBuffer; +var $MessageChannel = globalThis.MessageChannel; +var detach = false; +var WorkerThreads, channel, buffer, $detach; + +if (PROPER_STRUCTURED_CLONE_TRANSFER) { + detach = function (transferable) { + structuredClone(transferable, { transfer: [transferable] }); + }; +} else if ($ArrayBuffer) try { + if (!$MessageChannel) { + WorkerThreads = getBuiltInNodeModule('worker_threads'); + if (WorkerThreads) $MessageChannel = WorkerThreads.MessageChannel; + } + + if ($MessageChannel) { + channel = new $MessageChannel(); + buffer = new $ArrayBuffer(2); + + $detach = function (transferable) { + channel.port1.postMessage(null, [transferable]); + }; + + if (buffer.byteLength === 2) { + $detach(buffer); + if (buffer.byteLength === 0) detach = $detach; + } + } +} catch (error) { /* empty */ } + +module.exports = detach; + + +/***/ }), +/* 139 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var IS_NODE = __webpack_require__(140); + +module.exports = function (name) { + if (IS_NODE) { + try { + return globalThis.process.getBuiltinModule(name); + } catch (error) { /* empty */ } + try { + // eslint-disable-next-line no-new-func -- safe + return Function('return require("' + name + '")')(); + } catch (error) { /* empty */ } + } +}; + + +/***/ }), +/* 140 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ENVIRONMENT = __webpack_require__(141); + +module.exports = ENVIRONMENT === 'NODE'; + + +/***/ }), +/* 141 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* global Bun, Deno -- detection */ +var globalThis = __webpack_require__(2); +var userAgent = __webpack_require__(21); +var classof = __webpack_require__(46); + +var userAgentStartsWith = function (string) { + return userAgent.slice(0, string.length) === string; +}; + +module.exports = (function () { + if (userAgentStartsWith('Bun/')) return 'BUN'; + if (userAgentStartsWith('Cloudflare-Workers')) return 'CLOUDFLARE'; + if (userAgentStartsWith('Deno/')) return 'DENO'; + if (userAgentStartsWith('Node.js/')) return 'NODE'; + if (globalThis.Bun && typeof Bun.version == 'string') return 'BUN'; + if (globalThis.Deno && typeof Deno.version == 'object') return 'DENO'; + if (classof(globalThis.process) === 'process') return 'NODE'; + if (globalThis.window && globalThis.document) return 'BROWSER'; + return 'REST'; +})(); + + +/***/ }), +/* 142 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var fails = __webpack_require__(8); +var V8 = __webpack_require__(20); +var ENVIRONMENT = __webpack_require__(141); + +var structuredClone = globalThis.structuredClone; + +module.exports = !!structuredClone && !fails(function () { + // prevent V8 ArrayBufferDetaching protector cell invalidation and performance degradation + // https://github.com/zloirock/core-js/issues/679 + if ((ENVIRONMENT === 'DENO' && V8 > 92) || (ENVIRONMENT === 'NODE' && V8 > 94) || (ENVIRONMENT === 'BROWSER' && V8 > 97)) return false; + var buffer = new ArrayBuffer(8); + var clone = structuredClone(buffer, { transfer: [buffer] }); + return buffer.byteLength !== 0 || clone.byteLength !== 8; +}); + + +/***/ }), +/* 143 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $transfer = __webpack_require__(136); + +// `ArrayBuffer.prototype.transferToFixedLength` method +// https://tc39.es/ecma262/#sec-arraybuffer.prototype.transfertofixedlength +if ($transfer) $({ target: 'ArrayBuffer', proto: true }, { + transferToFixedLength: function transferToFixedLength() { + return $transfer(this, arguments.length ? arguments[0] : undefined, false); + } +}); + + +/***/ }), +/* 144 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// https://github.com/tc39/proposal-explicit-resource-management +var $ = __webpack_require__(49); +var DESCRIPTORS = __webpack_require__(24); +var getBuiltIn = __webpack_require__(35); +var aCallable = __webpack_require__(38); +var anInstance = __webpack_require__(145); +var defineBuiltIn = __webpack_require__(51); +var defineBuiltIns = __webpack_require__(146); +var defineBuiltInAccessor = __webpack_require__(131); +var wellKnownSymbol = __webpack_require__(13); +var InternalStateModule = __webpack_require__(55); +var addDisposableResource = __webpack_require__(147); + +var SuppressedError = getBuiltIn('SuppressedError'); +var $ReferenceError = ReferenceError; + +var DISPOSE = wellKnownSymbol('dispose'); +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); + +var DISPOSABLE_STACK = 'DisposableStack'; +var setInternalState = InternalStateModule.set; +var getDisposableStackInternalState = InternalStateModule.getterFor(DISPOSABLE_STACK); + +var HINT = 'sync-dispose'; +var DISPOSED = 'disposed'; +var PENDING = 'pending'; + +var getPendingDisposableStackInternalState = function (stack) { + var internalState = getDisposableStackInternalState(stack); + if (internalState.state === DISPOSED) throw new $ReferenceError(DISPOSABLE_STACK + ' already disposed'); + return internalState; +}; + +var $DisposableStack = function DisposableStack() { + setInternalState(anInstance(this, DisposableStackPrototype), { + type: DISPOSABLE_STACK, + state: PENDING, + stack: [] + }); + + if (!DESCRIPTORS) this.disposed = false; +}; + +var DisposableStackPrototype = $DisposableStack.prototype; + +defineBuiltIns(DisposableStackPrototype, { + dispose: function dispose() { + var internalState = getDisposableStackInternalState(this); + if (internalState.state === DISPOSED) return; + internalState.state = DISPOSED; + if (!DESCRIPTORS) this.disposed = true; + var stack = internalState.stack; + var i = stack.length; + var thrown = false; + var suppressed; + while (i) { + var disposeMethod = stack[--i]; + stack[i] = null; + try { + disposeMethod(); + } catch (errorResult) { + if (thrown) { + suppressed = new SuppressedError(errorResult, suppressed); + } else { + thrown = true; + suppressed = errorResult; + } + } + } + internalState.stack = null; + if (thrown) throw suppressed; + }, + use: function use(value) { + addDisposableResource(getPendingDisposableStackInternalState(this), value, HINT); + return value; + }, + adopt: function adopt(value, onDispose) { + var internalState = getPendingDisposableStackInternalState(this); + aCallable(onDispose); + addDisposableResource(internalState, undefined, HINT, function () { + onDispose(value); + }); + return value; + }, + defer: function defer(onDispose) { + var internalState = getPendingDisposableStackInternalState(this); + aCallable(onDispose); + addDisposableResource(internalState, undefined, HINT, onDispose); + }, + move: function move() { + var internalState = getPendingDisposableStackInternalState(this); + var newDisposableStack = new $DisposableStack(); + getDisposableStackInternalState(newDisposableStack).stack = internalState.stack; + internalState.stack = []; + internalState.state = DISPOSED; + if (!DESCRIPTORS) this.disposed = true; + return newDisposableStack; + } +}); + +if (DESCRIPTORS) defineBuiltInAccessor(DisposableStackPrototype, 'disposed', { + configurable: true, + get: function disposed() { + return getDisposableStackInternalState(this).state === DISPOSED; + } +}); + +defineBuiltIn(DisposableStackPrototype, DISPOSE, DisposableStackPrototype.dispose, { name: 'dispose' }); +defineBuiltIn(DisposableStackPrototype, TO_STRING_TAG, DISPOSABLE_STACK, { nonWritable: true }); + +$({ global: true, constructor: true }, { + DisposableStack: $DisposableStack +}); + + +/***/ }), +/* 145 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isPrototypeOf = __webpack_require__(36); + +var $TypeError = TypeError; + +module.exports = function (it, Prototype) { + if (isPrototypeOf(Prototype, it)) return it; + throw new $TypeError('Incorrect invocation'); +}; + + +/***/ }), +/* 146 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineBuiltIn = __webpack_require__(51); + +module.exports = function (target, src, options) { + for (var key in src) defineBuiltIn(target, key, src[key], options); + return target; +}; + + +/***/ }), +/* 147 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); +var call = __webpack_require__(33); +var uncurryThis = __webpack_require__(6); +var bind = __webpack_require__(98); +var anObject = __webpack_require__(30); +var aCallable = __webpack_require__(38); +var isNullOrUndefined = __webpack_require__(11); +var getMethod = __webpack_require__(37); +var wellKnownSymbol = __webpack_require__(13); + +var ASYNC_DISPOSE = wellKnownSymbol('asyncDispose'); +var DISPOSE = wellKnownSymbol('dispose'); + +var push = uncurryThis([].push); + +// `GetDisposeMethod` abstract operation +// https://tc39.es/proposal-explicit-resource-management/#sec-getdisposemethod +var getDisposeMethod = function (V, hint) { + if (hint === 'async-dispose') { + var method = getMethod(V, ASYNC_DISPOSE); + if (method !== undefined) return method; + method = getMethod(V, DISPOSE); + if (method === undefined) return method; + return function () { + var O = this; + var Promise = getBuiltIn('Promise'); + return new Promise(function (resolve) { + call(method, O); + resolve(undefined); + }); + }; + } return getMethod(V, DISPOSE); +}; + +// `CreateDisposableResource` abstract operation +// https://tc39.es/proposal-explicit-resource-management/#sec-createdisposableresource +var createDisposableResource = function (V, hint, method) { + if (arguments.length < 3 && !isNullOrUndefined(V)) { + method = aCallable(getDisposeMethod(anObject(V), hint)); + } + + return method === undefined ? function () { + return undefined; + } : bind(method, V); +}; + +// `AddDisposableResource` abstract operation +// https://tc39.es/proposal-explicit-resource-management/#sec-adddisposableresource +module.exports = function (disposable, V, hint, method) { + var resource; + if (arguments.length < 4) { + // When `V`` is either `null` or `undefined` and hint is `async-dispose`, + // we record that the resource was evaluated to ensure we will still perform an `Await` when resources are later disposed. + if (isNullOrUndefined(V) && hint === 'sync-dispose') return; + resource = createDisposableResource(V, hint); + } else { + resource = createDisposableResource(undefined, hint, method); + } + + push(disposable.stack, resource); +}; + + +/***/ }), +/* 148 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var anInstance = __webpack_require__(145); +var anObject = __webpack_require__(30); +var isCallable = __webpack_require__(28); +var getPrototypeOf = __webpack_require__(91); +var defineBuiltInAccessor = __webpack_require__(131); +var createProperty = __webpack_require__(149); +var fails = __webpack_require__(8); +var hasOwn = __webpack_require__(5); +var wellKnownSymbol = __webpack_require__(13); +var IteratorPrototype = __webpack_require__(150).IteratorPrototype; +var DESCRIPTORS = __webpack_require__(24); +var IS_PURE = __webpack_require__(16); + +var CONSTRUCTOR = 'constructor'; +var ITERATOR = 'Iterator'; +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); + +var $TypeError = TypeError; +var NativeIterator = globalThis[ITERATOR]; + +// FF56- have non-standard global helper `Iterator` +var FORCED = IS_PURE + || !isCallable(NativeIterator) + || NativeIterator.prototype !== IteratorPrototype + // FF44- non-standard `Iterator` passes previous tests + || !fails(function () { NativeIterator({}); }); + +var IteratorConstructor = function Iterator() { + anInstance(this, IteratorPrototype); + if (getPrototypeOf(this) === IteratorPrototype) throw new $TypeError('Abstract class Iterator not directly constructable'); +}; + +var defineIteratorPrototypeAccessor = function (key, value) { + if (DESCRIPTORS) { + defineBuiltInAccessor(IteratorPrototype, key, { + configurable: true, + get: function () { + return value; + }, + set: function (replacement) { + anObject(this); + if (this === IteratorPrototype) throw new $TypeError("You can't redefine this property"); + if (hasOwn(this, key)) this[key] = replacement; + else createProperty(this, key, replacement); + } + }); + } else IteratorPrototype[key] = value; +}; + +if (!hasOwn(IteratorPrototype, TO_STRING_TAG)) defineIteratorPrototypeAccessor(TO_STRING_TAG, ITERATOR); + +if (FORCED || !hasOwn(IteratorPrototype, CONSTRUCTOR) || IteratorPrototype[CONSTRUCTOR] === Object) { + defineIteratorPrototypeAccessor(CONSTRUCTOR, IteratorConstructor); +} + +IteratorConstructor.prototype = IteratorPrototype; + +// `Iterator` constructor +// https://tc39.es/ecma262/#sec-iterator +$({ global: true, constructor: true, forced: FORCED }, { + Iterator: IteratorConstructor +}); + + +/***/ }), +/* 149 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var definePropertyModule = __webpack_require__(23); +var createPropertyDescriptor = __webpack_require__(43); + +module.exports = function (object, key, value) { + if (DESCRIPTORS) definePropertyModule.f(object, key, createPropertyDescriptor(0, value)); + else object[key] = value; +}; + + +/***/ }), +/* 150 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); +var isCallable = __webpack_require__(28); +var isObject = __webpack_require__(27); +var create = __webpack_require__(93); +var getPrototypeOf = __webpack_require__(91); +var defineBuiltIn = __webpack_require__(51); +var wellKnownSymbol = __webpack_require__(13); +var IS_PURE = __webpack_require__(16); + +var ITERATOR = wellKnownSymbol('iterator'); +var BUGGY_SAFARI_ITERATORS = false; + +// `%IteratorPrototype%` object +// https://tc39.es/ecma262/#sec-%iteratorprototype%-object +var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator; + +/* eslint-disable es/no-array-prototype-keys -- safe */ +if ([].keys) { + arrayIterator = [].keys(); + // Safari 8 has buggy iterators w/o `next` + if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true; + else { + PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator)); + if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype; + } +} + +var NEW_ITERATOR_PROTOTYPE = !isObject(IteratorPrototype) || fails(function () { + var test = {}; + // FF44- legacy iterators case + return IteratorPrototype[ITERATOR].call(test) !== test; +}); + +if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype = {}; +else if (IS_PURE) IteratorPrototype = create(IteratorPrototype); + +// `%IteratorPrototype%[@@iterator]()` method +// https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator +if (!isCallable(IteratorPrototype[ITERATOR])) { + defineBuiltIn(IteratorPrototype, ITERATOR, function () { + return this; + }); +} + +module.exports = { + IteratorPrototype: IteratorPrototype, + BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS +}; + + +/***/ }), +/* 151 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorMethod = __webpack_require__(103); +var createIteratorProxy = __webpack_require__(152); + +var $Array = Array; + +var IteratorProxy = createIteratorProxy(function () { + while (true) { + var iterator = this.iterator; + if (!iterator) { + var iterableIndex = this.nextIterableIndex++; + var iterables = this.iterables; + if (iterableIndex >= iterables.length) { + this.done = true; + return; + } + var entry = iterables[iterableIndex]; + this.iterables[iterableIndex] = null; + iterator = this.iterator = call(entry.method, entry.iterable); + this.next = iterator.next; + } + var result = anObject(call(this.next, iterator)); + if (result.done) { + this.iterator = null; + this.next = null; + continue; + } + return result.value; + } +}); + +// `Iterator.concat` method +// https://github.com/tc39/proposal-iterator-sequencing +$({ target: 'Iterator', stat: true }, { + concat: function concat() { + var length = arguments.length; + var iterables = $Array(length); + for (var index = 0; index < length; index++) { + var item = anObject(arguments[index]); + iterables[index] = { + iterable: item, + method: aCallable(getIteratorMethod(item)) + }; + } + return new IteratorProxy({ + iterables: iterables, + nextIterableIndex: 0, + iterator: null, + next: null + }); + } +}); + + +/***/ }), +/* 152 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var create = __webpack_require__(93); +var createNonEnumerableProperty = __webpack_require__(50); +var defineBuiltIns = __webpack_require__(146); +var wellKnownSymbol = __webpack_require__(13); +var InternalStateModule = __webpack_require__(55); +var getMethod = __webpack_require__(37); +var IteratorPrototype = __webpack_require__(150).IteratorPrototype; +var createIterResultObject = __webpack_require__(153); +var iteratorClose = __webpack_require__(104); +var iteratorCloseAll = __webpack_require__(154); + +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); +var ITERATOR_HELPER = 'IteratorHelper'; +var WRAP_FOR_VALID_ITERATOR = 'WrapForValidIterator'; +var NORMAL = 'normal'; +var THROW = 'throw'; +var setInternalState = InternalStateModule.set; + +var createIteratorProxyPrototype = function (IS_ITERATOR) { + var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER); + + return defineBuiltIns(create(IteratorPrototype), { + next: function next() { + var state = getInternalState(this); + // for simplification: + // for `%WrapForValidIteratorPrototype%.next` or with `state.returnHandlerResult` our `nextHandler` returns `IterResultObject` + // for `%IteratorHelperPrototype%.next` - just a value + if (IS_ITERATOR) return state.nextHandler(); + if (state.done) return createIterResultObject(undefined, true); + try { + var result = state.nextHandler(); + return state.returnHandlerResult ? result : createIterResultObject(result, state.done); + } catch (error) { + state.done = true; + throw error; + } + }, + 'return': function () { + var state = getInternalState(this); + var iterator = state.iterator; + state.done = true; + if (IS_ITERATOR) { + var returnMethod = getMethod(iterator, 'return'); + return returnMethod ? call(returnMethod, iterator) : createIterResultObject(undefined, true); + } + if (state.inner) try { + iteratorClose(state.inner.iterator, NORMAL); + } catch (error) { + return iteratorClose(iterator, THROW, error); + } + if (state.openIters) try { + iteratorCloseAll(state.openIters, NORMAL); + } catch (error) { + return iteratorClose(iterator, THROW, error); + } + if (iterator) iteratorClose(iterator, NORMAL); + return createIterResultObject(undefined, true); + } + }); +}; + +var WrapForValidIteratorPrototype = createIteratorProxyPrototype(true); +var IteratorHelperPrototype = createIteratorProxyPrototype(false); + +createNonEnumerableProperty(IteratorHelperPrototype, TO_STRING_TAG, 'Iterator Helper'); + +module.exports = function (nextHandler, IS_ITERATOR, RETURN_HANDLER_RESULT) { + var IteratorProxy = function Iterator(record, state) { + if (state) { + state.iterator = record.iterator; + state.next = record.next; + } else state = record; + state.type = IS_ITERATOR ? WRAP_FOR_VALID_ITERATOR : ITERATOR_HELPER; + state.returnHandlerResult = !!RETURN_HANDLER_RESULT; + state.nextHandler = nextHandler; + state.counter = 0; + state.done = false; + setInternalState(this, state); + }; + + IteratorProxy.prototype = IS_ITERATOR ? WrapForValidIteratorPrototype : IteratorHelperPrototype; + + return IteratorProxy; +}; + + +/***/ }), +/* 153 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// `CreateIterResultObject` abstract operation +// https://tc39.es/ecma262/#sec-createiterresultobject +module.exports = function (value, done) { + return { value: value, done: done }; +}; + + +/***/ }), +/* 154 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var iteratorClose = __webpack_require__(104); + +module.exports = function (iters, kind, value) { + for (var i = iters.length - 1; i >= 0; i--) { + if (iters[i] === undefined) continue; + try { + value = iteratorClose(iters[i].iterator, kind, value); + } catch (error) { + kind = 'throw'; + value = error; + } + } + if (kind === 'throw') throw value; + return value; +}; + + +/***/ }), +/* 155 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// https://github.com/tc39/proposal-explicit-resource-management +var call = __webpack_require__(33); +var defineBuiltIn = __webpack_require__(51); +var getMethod = __webpack_require__(37); +var hasOwn = __webpack_require__(5); +var wellKnownSymbol = __webpack_require__(13); +var IteratorPrototype = __webpack_require__(150).IteratorPrototype; + +var DISPOSE = wellKnownSymbol('dispose'); + +if (!hasOwn(IteratorPrototype, DISPOSE)) { + defineBuiltIn(IteratorPrototype, DISPOSE, function () { + var $return = getMethod(this, 'return'); + if ($return) call($return, this); + }); +} + + +/***/ }), +/* 156 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var notANaN = __webpack_require__(158); +var toPositiveInteger = __webpack_require__(159); +var iteratorClose = __webpack_require__(104); +var createIteratorProxy = __webpack_require__(152); +var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(160); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); +var IS_PURE = __webpack_require__(16); + +var DROP_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !iteratorHelperThrowsOnInvalidIterator('drop', 0); +var dropWithoutClosingOnEarlyError = !IS_PURE && !DROP_WITHOUT_THROWING_ON_INVALID_ITERATOR + && iteratorHelperWithoutClosingOnEarlyError('drop', RangeError); + +var FORCED = IS_PURE || DROP_WITHOUT_THROWING_ON_INVALID_ITERATOR || dropWithoutClosingOnEarlyError; + +var IteratorProxy = createIteratorProxy(function () { + var iterator = this.iterator; + var next = this.next; + var result, done; + while (this.remaining) { + this.remaining--; + result = anObject(call(next, iterator)); + done = this.done = !!result.done; + if (done) return; + } + result = anObject(call(next, iterator)); + done = this.done = !!result.done; + if (!done) return result.value; +}); + +// `Iterator.prototype.drop` method +// https://tc39.es/ecma262/#sec-iterator.prototype.drop +$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { + drop: function drop(limit) { + anObject(this); + var remaining; + try { + remaining = toPositiveInteger(notANaN(+limit)); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (dropWithoutClosingOnEarlyError) return call(dropWithoutClosingOnEarlyError, this, remaining); + + return new IteratorProxy(getIteratorDirect(this), { + remaining: remaining + }); + } +}); + + +/***/ }), +/* 157 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// `GetIteratorDirect(obj)` abstract operation +// https://tc39.es/ecma262/#sec-getiteratordirect +module.exports = function (obj) { + return { + iterator: obj, + next: obj.next, + done: false + }; +}; + + +/***/ }), +/* 158 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $RangeError = RangeError; + +module.exports = function (it) { + // eslint-disable-next-line no-self-compare -- NaN check + if (it === it) return it; + throw new $RangeError('NaN is not allowed'); +}; + + +/***/ }), +/* 159 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(65); + +var $RangeError = RangeError; + +module.exports = function (it) { + var result = toIntegerOrInfinity(it); + if (result < 0) throw new $RangeError("The argument can't be less than 0"); + return result; +}; + + +/***/ }), +/* 160 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// Should throw an error on invalid iterator +// https://issues.chromium.org/issues/336839115 +module.exports = function (methodName, argument) { + // eslint-disable-next-line es/no-iterator -- required for testing + var method = typeof Iterator == 'function' && Iterator.prototype[methodName]; + if (method) try { + method.call({ next: null }, argument).next(); + } catch (error) { + return true; + } +}; + + +/***/ }), +/* 161 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); + +// https://github.com/tc39/ecma262/pull/3467 +module.exports = function (METHOD_NAME, ExpectedError) { + var Iterator = globalThis.Iterator; + var IteratorPrototype = Iterator && Iterator.prototype; + var method = IteratorPrototype && IteratorPrototype[METHOD_NAME]; + + var CLOSED = false; + + if (method) try { + method.call({ + next: function () { return { done: true }; }, + 'return': function () { CLOSED = true; } + }, -1); + } catch (error) { + // https://bugs.webkit.org/show_bug.cgi?id=291195 + if (!(error instanceof ExpectedError)) CLOSED = false; + } + + if (!CLOSED) return method; +}; + + +/***/ }), +/* 162 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var iterate = __webpack_require__(97); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var iteratorClose = __webpack_require__(104); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); + +var everyWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('every', TypeError); + +// `Iterator.prototype.every` method +// https://tc39.es/ecma262/#sec-iterator.prototype.every +$({ target: 'Iterator', proto: true, real: true, forced: everyWithoutClosingOnEarlyError }, { + every: function every(predicate) { + anObject(this); + try { + aCallable(predicate); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (everyWithoutClosingOnEarlyError) return call(everyWithoutClosingOnEarlyError, this, predicate); + + var record = getIteratorDirect(this); + var counter = 0; + return !iterate(record, function (value, stop) { + if (!predicate(value, counter++)) return stop(); + }, { IS_RECORD: true, INTERRUPTED: true }).stopped; + } +}); + + +/***/ }), +/* 163 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var createIteratorProxy = __webpack_require__(152); +var callWithSafeIterationClosing = __webpack_require__(164); +var IS_PURE = __webpack_require__(16); +var iteratorClose = __webpack_require__(104); +var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(160); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); + +var FILTER_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !iteratorHelperThrowsOnInvalidIterator('filter', function () { /* empty */ }); +var filterWithoutClosingOnEarlyError = !IS_PURE && !FILTER_WITHOUT_THROWING_ON_INVALID_ITERATOR + && iteratorHelperWithoutClosingOnEarlyError('filter', TypeError); + +var FORCED = IS_PURE || FILTER_WITHOUT_THROWING_ON_INVALID_ITERATOR || filterWithoutClosingOnEarlyError; + +var IteratorProxy = createIteratorProxy(function () { + var iterator = this.iterator; + var predicate = this.predicate; + var next = this.next; + var result, done, value; + while (true) { + result = anObject(call(next, iterator)); + done = this.done = !!result.done; + if (done) return; + value = result.value; + if (callWithSafeIterationClosing(iterator, predicate, [value, this.counter++], true)) return value; + } +}); + +// `Iterator.prototype.filter` method +// https://tc39.es/ecma262/#sec-iterator.prototype.filter +$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { + filter: function filter(predicate) { + anObject(this); + try { + aCallable(predicate); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (filterWithoutClosingOnEarlyError) return call(filterWithoutClosingOnEarlyError, this, predicate); + + return new IteratorProxy(getIteratorDirect(this), { + predicate: predicate + }); + } +}); + + +/***/ }), +/* 164 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var anObject = __webpack_require__(30); +var iteratorClose = __webpack_require__(104); + +// call something on iterator step with safe closing on error +module.exports = function (iterator, fn, value, ENTRIES) { + try { + return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value); + } catch (error) { + iteratorClose(iterator, 'throw', error); + } +}; + + +/***/ }), +/* 165 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var iterate = __webpack_require__(97); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var iteratorClose = __webpack_require__(104); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); + +var findWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('find', TypeError); + +// `Iterator.prototype.find` method +// https://tc39.es/ecma262/#sec-iterator.prototype.find +$({ target: 'Iterator', proto: true, real: true, forced: findWithoutClosingOnEarlyError }, { + find: function find(predicate) { + anObject(this); + try { + aCallable(predicate); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (findWithoutClosingOnEarlyError) return call(findWithoutClosingOnEarlyError, this, predicate); + + var record = getIteratorDirect(this); + var counter = 0; + return iterate(record, function (value, stop) { + if (predicate(value, counter++)) return stop(value); + }, { IS_RECORD: true, INTERRUPTED: true }).result; + } +}); + + +/***/ }), +/* 166 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var getIteratorFlattenable = __webpack_require__(167); +var createIteratorProxy = __webpack_require__(152); +var iteratorClose = __webpack_require__(104); +var IS_PURE = __webpack_require__(16); +var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(160); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); + +var FLAT_MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE + && !iteratorHelperThrowsOnInvalidIterator('flatMap', function () { /* empty */ }); +var flatMapWithoutClosingOnEarlyError = !IS_PURE && !FLAT_MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR + && iteratorHelperWithoutClosingOnEarlyError('flatMap', TypeError); + +var FORCED = IS_PURE || FLAT_MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR || flatMapWithoutClosingOnEarlyError; + +var IteratorProxy = createIteratorProxy(function () { + var iterator = this.iterator; + var mapper = this.mapper; + var result, inner; + + while (true) { + if (inner = this.inner) try { + result = anObject(call(inner.next, inner.iterator)); + if (!result.done) return result.value; + this.inner = null; + } catch (error) { iteratorClose(iterator, 'throw', error); } + + result = anObject(call(this.next, iterator)); + + if (this.done = !!result.done) return; + + try { + this.inner = getIteratorFlattenable(mapper(result.value, this.counter++), false); + } catch (error) { iteratorClose(iterator, 'throw', error); } + } +}); + +// `Iterator.prototype.flatMap` method +// https://tc39.es/ecma262/#sec-iterator.prototype.flatmap +$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { + flatMap: function flatMap(mapper) { + anObject(this); + try { + aCallable(mapper); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (flatMapWithoutClosingOnEarlyError) return call(flatMapWithoutClosingOnEarlyError, this, mapper); + + return new IteratorProxy(getIteratorDirect(this), { + mapper: mapper, + inner: null + }); + } +}); + + +/***/ }), +/* 167 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var getIteratorMethod = __webpack_require__(103); + +module.exports = function (obj, stringHandling) { + if (!stringHandling || typeof obj !== 'string') anObject(obj); + var method = getIteratorMethod(obj); + return getIteratorDirect(anObject(method !== undefined ? call(method, obj) : obj)); +}; + + +/***/ }), +/* 168 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var iterate = __webpack_require__(97); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var iteratorClose = __webpack_require__(104); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); + +var forEachWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('forEach', TypeError); + +// `Iterator.prototype.forEach` method +// https://tc39.es/ecma262/#sec-iterator.prototype.foreach +$({ target: 'Iterator', proto: true, real: true, forced: forEachWithoutClosingOnEarlyError }, { + forEach: function forEach(fn) { + anObject(this); + try { + aCallable(fn); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (forEachWithoutClosingOnEarlyError) return call(forEachWithoutClosingOnEarlyError, this, fn); + + var record = getIteratorDirect(this); + var counter = 0; + iterate(record, function (value) { + fn(value, counter++); + }, { IS_RECORD: true }); + } +}); + + +/***/ }), +/* 169 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var toObject = __webpack_require__(9); +var isPrototypeOf = __webpack_require__(36); +var IteratorPrototype = __webpack_require__(150).IteratorPrototype; +var createIteratorProxy = __webpack_require__(152); +var getIteratorFlattenable = __webpack_require__(167); +var IS_PURE = __webpack_require__(16); + +var FORCED = IS_PURE || function () { + // Should not throw when an underlying iterator's `return` method is null + // https://bugs.webkit.org/show_bug.cgi?id=288714 + try { + // eslint-disable-next-line es/no-iterator -- required for testing + Iterator.from({ 'return': null })['return'](); + } catch (error) { + return true; + } +}(); + +var IteratorProxy = createIteratorProxy(function () { + return call(this.next, this.iterator); +}, true); + +// `Iterator.from` method +// https://tc39.es/ecma262/#sec-iterator.from +$({ target: 'Iterator', stat: true, forced: FORCED }, { + from: function from(O) { + var iteratorRecord = getIteratorFlattenable(typeof O == 'string' ? toObject(O) : O, true); + return isPrototypeOf(IteratorPrototype, iteratorRecord.iterator) + ? iteratorRecord.iterator + : new IteratorProxy(iteratorRecord); + } +}); + + +/***/ }), +/* 170 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var createIteratorProxy = __webpack_require__(152); +var callWithSafeIterationClosing = __webpack_require__(164); +var iteratorClose = __webpack_require__(104); +var iteratorHelperThrowsOnInvalidIterator = __webpack_require__(160); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); +var IS_PURE = __webpack_require__(16); + +var MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR = !IS_PURE && !iteratorHelperThrowsOnInvalidIterator('map', function () { /* empty */ }); +var mapWithoutClosingOnEarlyError = !IS_PURE && !MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR + && iteratorHelperWithoutClosingOnEarlyError('map', TypeError); + +var FORCED = IS_PURE || MAP_WITHOUT_THROWING_ON_INVALID_ITERATOR || mapWithoutClosingOnEarlyError; + +var IteratorProxy = createIteratorProxy(function () { + var iterator = this.iterator; + var result = anObject(call(this.next, iterator)); + var done = this.done = !!result.done; + if (!done) return callWithSafeIterationClosing(iterator, this.mapper, [result.value, this.counter++], true); +}); + +// `Iterator.prototype.map` method +// https://tc39.es/ecma262/#sec-iterator.prototype.map +$({ target: 'Iterator', proto: true, real: true, forced: FORCED }, { + map: function map(mapper) { + anObject(this); + try { + aCallable(mapper); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (mapWithoutClosingOnEarlyError) return call(mapWithoutClosingOnEarlyError, this, mapper); + + return new IteratorProxy(getIteratorDirect(this), { + mapper: mapper + }); + } +}); + + +/***/ }), +/* 171 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var iterate = __webpack_require__(97); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var iteratorClose = __webpack_require__(104); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); +var apply = __webpack_require__(72); +var fails = __webpack_require__(8); + +var $TypeError = TypeError; + +// https://bugs.webkit.org/show_bug.cgi?id=291651 +var FAILS_ON_INITIAL_UNDEFINED = fails(function () { + // eslint-disable-next-line es/no-iterator-prototype-reduce, es/no-array-prototype-keys, array-callback-return -- required for testing + [].keys().reduce(function () { /* empty */ }, undefined); +}); + +var reduceWithoutClosingOnEarlyError = !FAILS_ON_INITIAL_UNDEFINED && iteratorHelperWithoutClosingOnEarlyError('reduce', $TypeError); + +// `Iterator.prototype.reduce` method +// https://tc39.es/ecma262/#sec-iterator.prototype.reduce +$({ target: 'Iterator', proto: true, real: true, forced: FAILS_ON_INITIAL_UNDEFINED || reduceWithoutClosingOnEarlyError }, { + reduce: function reduce(reducer /* , initialValue */) { + anObject(this); + try { + aCallable(reducer); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + var noInitial = arguments.length < 2; + var accumulator = noInitial ? undefined : arguments[1]; + if (reduceWithoutClosingOnEarlyError) { + return apply(reduceWithoutClosingOnEarlyError, this, noInitial ? [reducer] : [reducer, accumulator]); + } + var record = getIteratorDirect(this); + var counter = 0; + iterate(record, function (value) { + if (noInitial) { + noInitial = false; + accumulator = value; + } else { + accumulator = reducer(accumulator, value, counter); + } + counter++; + }, { IS_RECORD: true }); + if (noInitial) throw new $TypeError('Reduce of empty iterator with no initial value'); + return accumulator; + } +}); + + +/***/ }), +/* 172 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var iterate = __webpack_require__(97); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var iteratorClose = __webpack_require__(104); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); + +var someWithoutClosingOnEarlyError = iteratorHelperWithoutClosingOnEarlyError('some', TypeError); + +// `Iterator.prototype.some` method +// https://tc39.es/ecma262/#sec-iterator.prototype.some +$({ target: 'Iterator', proto: true, real: true, forced: someWithoutClosingOnEarlyError }, { + some: function some(predicate) { + anObject(this); + try { + aCallable(predicate); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (someWithoutClosingOnEarlyError) return call(someWithoutClosingOnEarlyError, this, predicate); + + var record = getIteratorDirect(this); + var counter = 0; + return iterate(record, function (value, stop) { + if (predicate(value, counter++)) return stop(); + }, { IS_RECORD: true, INTERRUPTED: true }).stopped; + } +}); + + +/***/ }), +/* 173 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var notANaN = __webpack_require__(158); +var toPositiveInteger = __webpack_require__(159); +var createIteratorProxy = __webpack_require__(152); +var iteratorClose = __webpack_require__(104); +var iteratorHelperWithoutClosingOnEarlyError = __webpack_require__(161); +var IS_PURE = __webpack_require__(16); + +var takeWithoutClosingOnEarlyError = !IS_PURE && iteratorHelperWithoutClosingOnEarlyError('take', RangeError); + +var IteratorProxy = createIteratorProxy(function () { + var iterator = this.iterator; + if (!this.remaining--) { + this.done = true; + return iteratorClose(iterator, 'normal', undefined); + } + var result = anObject(call(this.next, iterator)); + var done = this.done = !!result.done; + if (!done) return result.value; +}); + +// `Iterator.prototype.take` method +// https://tc39.es/ecma262/#sec-iterator.prototype.take +$({ target: 'Iterator', proto: true, real: true, forced: IS_PURE || takeWithoutClosingOnEarlyError }, { + take: function take(limit) { + anObject(this); + var remaining; + try { + remaining = toPositiveInteger(notANaN(+limit)); + } catch (error) { + iteratorClose(this, 'throw', error); + } + + if (takeWithoutClosingOnEarlyError) return call(takeWithoutClosingOnEarlyError, this, remaining); + + return new IteratorProxy(getIteratorDirect(this), { + remaining: remaining + }); + } +}); + + +/***/ }), +/* 174 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var anObject = __webpack_require__(30); +var iterate = __webpack_require__(97); +var getIteratorDirect = __webpack_require__(157); + +var push = [].push; + +// `Iterator.prototype.toArray` method +// https://tc39.es/ecma262/#sec-iterator.prototype.toarray +$({ target: 'Iterator', proto: true, real: true }, { + toArray: function toArray() { + var result = []; + iterate(getIteratorDirect(anObject(this)), push, { that: result, IS_RECORD: true }); + return result; + } +}); + + +/***/ }), +/* 175 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var NATIVE_RAW_JSON = __webpack_require__(176); +var isRawJSON = __webpack_require__(177); + +// `JSON.isRawJSON` method +// https://tc39.es/proposal-json-parse-with-source/#sec-json.israwjson +// https://github.com/tc39/proposal-json-parse-with-source +$({ target: 'JSON', stat: true, forced: !NATIVE_RAW_JSON }, { + isRawJSON: isRawJSON +}); + + +/***/ }), +/* 176 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable es/no-json -- safe */ +var fails = __webpack_require__(8); + +module.exports = !fails(function () { + var unsafeInt = '9007199254740993'; + // eslint-disable-next-line es/no-nonstandard-json-properties -- feature detection + var raw = JSON.rawJSON(unsafeInt); + // eslint-disable-next-line es/no-nonstandard-json-properties -- feature detection + return !JSON.isRawJSON(raw) || JSON.stringify(raw) !== unsafeInt; +}); + + +/***/ }), +/* 177 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isObject = __webpack_require__(27); +var getInternalState = __webpack_require__(55).get; + +module.exports = function isRawJSON(O) { + if (!isObject(O)) return false; + var state = getInternalState(O); + return !!state && state.type === 'RawJSON'; +}; + + +/***/ }), +/* 178 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var DESCRIPTORS = __webpack_require__(24); +var globalThis = __webpack_require__(2); +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); +var call = __webpack_require__(33); +var isCallable = __webpack_require__(28); +var isObject = __webpack_require__(27); +var isArray = __webpack_require__(114); +var hasOwn = __webpack_require__(5); +var toString = __webpack_require__(81); +var lengthOfArrayLike = __webpack_require__(67); +var createProperty = __webpack_require__(149); +var fails = __webpack_require__(8); +var parseJSONString = __webpack_require__(179); +var NATIVE_SYMBOL = __webpack_require__(19); + +var JSON = globalThis.JSON; +var Number = globalThis.Number; +var SyntaxError = globalThis.SyntaxError; +var nativeParse = JSON && JSON.parse; +var enumerableOwnProperties = getBuiltIn('Object', 'keys'); +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; +var at = uncurryThis(''.charAt); +var slice = uncurryThis(''.slice); +var exec = uncurryThis(/./.exec); +var push = uncurryThis([].push); + +var IS_DIGIT = /^\d$/; +var IS_NON_ZERO_DIGIT = /^[1-9]$/; +var IS_NUMBER_START = /^[\d-]$/; +var IS_WHITESPACE = /^[\t\n\r ]$/; + +var PRIMITIVE = 0; +var OBJECT = 1; + +var $parse = function (source, reviver) { + source = toString(source); + var context = new Context(source, 0, ''); + var root = context.parse(); + var value = root.value; + var endIndex = context.skip(IS_WHITESPACE, root.end); + if (endIndex < source.length) { + throw new SyntaxError('Unexpected extra character: "' + at(source, endIndex) + '" after the parsed data at: ' + endIndex); + } + return isCallable(reviver) ? internalize({ '': value }, '', reviver, root) : value; +}; + +var internalize = function (holder, name, reviver, node) { + var val = holder[name]; + var unmodified = node && val === node.value; + var context = unmodified && typeof node.source == 'string' ? { source: node.source } : {}; + var elementRecordsLen, keys, len, i, P; + if (isObject(val)) { + var nodeIsArray = isArray(val); + var nodes = unmodified ? node.nodes : nodeIsArray ? [] : {}; + if (nodeIsArray) { + elementRecordsLen = nodes.length; + len = lengthOfArrayLike(val); + for (i = 0; i < len; i++) { + internalizeProperty(val, i, internalize(val, '' + i, reviver, i < elementRecordsLen ? nodes[i] : undefined)); + } + } else { + keys = enumerableOwnProperties(val); + len = lengthOfArrayLike(keys); + for (i = 0; i < len; i++) { + P = keys[i]; + internalizeProperty(val, P, internalize(val, P, reviver, hasOwn(nodes, P) ? nodes[P] : undefined)); + } + } + } + return call(reviver, holder, name, val, context); +}; + +var internalizeProperty = function (object, key, value) { + if (DESCRIPTORS) { + var descriptor = getOwnPropertyDescriptor(object, key); + if (descriptor && !descriptor.configurable) return; + } + if (value === undefined) delete object[key]; + else createProperty(object, key, value); +}; + +var Node = function (value, end, source, nodes) { + this.value = value; + this.end = end; + this.source = source; + this.nodes = nodes; +}; + +var Context = function (source, index) { + this.source = source; + this.index = index; +}; + +// https://www.json.org/json-en.html +Context.prototype = { + fork: function (nextIndex) { + return new Context(this.source, nextIndex); + }, + parse: function () { + var source = this.source; + var i = this.skip(IS_WHITESPACE, this.index); + var fork = this.fork(i); + var chr = at(source, i); + if (exec(IS_NUMBER_START, chr)) return fork.number(); + switch (chr) { + case '{': + return fork.object(); + case '[': + return fork.array(); + case '"': + return fork.string(); + case 't': + return fork.keyword(true); + case 'f': + return fork.keyword(false); + case 'n': + return fork.keyword(null); + } throw new SyntaxError('Unexpected character: "' + chr + '" at: ' + i); + }, + node: function (type, value, start, end, nodes) { + return new Node(value, end, type ? null : slice(this.source, start, end), nodes); + }, + object: function () { + var source = this.source; + var i = this.index + 1; + var expectKeypair = false; + var object = {}; + var nodes = {}; + while (i < source.length) { + i = this.until(['"', '}'], i); + if (at(source, i) === '}' && !expectKeypair) { + i++; + break; + } + // Parsing the key + var result = this.fork(i).string(); + var key = result.value; + i = result.end; + i = this.until([':'], i) + 1; + // Parsing value + i = this.skip(IS_WHITESPACE, i); + result = this.fork(i).parse(); + createProperty(nodes, key, result); + createProperty(object, key, result.value); + i = this.until([',', '}'], result.end); + var chr = at(source, i); + if (chr === ',') { + expectKeypair = true; + i++; + } else if (chr === '}') { + i++; + break; + } + } + return this.node(OBJECT, object, this.index, i, nodes); + }, + array: function () { + var source = this.source; + var i = this.index + 1; + var expectElement = false; + var array = []; + var nodes = []; + while (i < source.length) { + i = this.skip(IS_WHITESPACE, i); + if (at(source, i) === ']' && !expectElement) { + i++; + break; + } + var result = this.fork(i).parse(); + push(nodes, result); + push(array, result.value); + i = this.until([',', ']'], result.end); + if (at(source, i) === ',') { + expectElement = true; + i++; + } else if (at(source, i) === ']') { + i++; + break; + } + } + return this.node(OBJECT, array, this.index, i, nodes); + }, + string: function () { + var index = this.index; + var parsed = parseJSONString(this.source, this.index + 1); + return this.node(PRIMITIVE, parsed.value, index, parsed.end); + }, + number: function () { + var source = this.source; + var startIndex = this.index; + var i = startIndex; + if (at(source, i) === '-') i++; + if (at(source, i) === '0') i++; + else if (exec(IS_NON_ZERO_DIGIT, at(source, i))) i = this.skip(IS_DIGIT, i + 1); + else throw new SyntaxError('Failed to parse number at: ' + i); + if (at(source, i) === '.') i = this.skip(IS_DIGIT, i + 1); + if (at(source, i) === 'e' || at(source, i) === 'E') { + i++; + if (at(source, i) === '+' || at(source, i) === '-') i++; + var exponentStartIndex = i; + i = this.skip(IS_DIGIT, i); + if (exponentStartIndex === i) throw new SyntaxError("Failed to parse number's exponent value at: " + i); + } + return this.node(PRIMITIVE, Number(slice(source, startIndex, i)), startIndex, i); + }, + keyword: function (value) { + var keyword = '' + value; + var index = this.index; + var endIndex = index + keyword.length; + if (slice(this.source, index, endIndex) !== keyword) throw new SyntaxError('Failed to parse value at: ' + index); + return this.node(PRIMITIVE, value, index, endIndex); + }, + skip: function (regex, i) { + var source = this.source; + for (; i < source.length; i++) if (!exec(regex, at(source, i))) break; + return i; + }, + until: function (array, i) { + i = this.skip(IS_WHITESPACE, i); + var chr = at(this.source, i); + for (var j = 0; j < array.length; j++) if (array[j] === chr) return i; + throw new SyntaxError('Unexpected character: "' + chr + '" at: ' + i); + } +}; + +var NO_SOURCE_SUPPORT = fails(function () { + var unsafeInt = '9007199254740993'; + var source; + nativeParse(unsafeInt, function (key, value, context) { + source = context.source; + }); + return source !== unsafeInt; +}); + +var PROPER_BASE_PARSE = NATIVE_SYMBOL && !fails(function () { + // Safari 9 bug + return 1 / nativeParse('-0 \t') !== -Infinity; +}); + +// `JSON.parse` method +// https://tc39.es/ecma262/#sec-json.parse +// https://github.com/tc39/proposal-json-parse-with-source +$({ target: 'JSON', stat: true, forced: NO_SOURCE_SUPPORT }, { + parse: function parse(text, reviver) { + return PROPER_BASE_PARSE && !isCallable(reviver) ? nativeParse(text) : $parse(text, reviver); + } +}); + + +/***/ }), +/* 179 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var hasOwn = __webpack_require__(5); + +var $SyntaxError = SyntaxError; +var $parseInt = parseInt; +var fromCharCode = String.fromCharCode; +var at = uncurryThis(''.charAt); +var slice = uncurryThis(''.slice); +var exec = uncurryThis(/./.exec); + +var codePoints = { + '\\"': '"', + '\\\\': '\\', + '\\/': '/', + '\\b': '\b', + '\\f': '\f', + '\\n': '\n', + '\\r': '\r', + '\\t': '\t' +}; + +var IS_4_HEX_DIGITS = /^[\da-f]{4}$/i; +// eslint-disable-next-line regexp/no-control-character -- safe +var IS_C0_CONTROL_CODE = /^[\u0000-\u001F]$/; + +module.exports = function (source, i) { + var unterminated = true; + var value = ''; + while (i < source.length) { + var chr = at(source, i); + if (chr === '\\') { + var twoChars = slice(source, i, i + 2); + if (hasOwn(codePoints, twoChars)) { + value += codePoints[twoChars]; + i += 2; + } else if (twoChars === '\\u') { + i += 2; + var fourHexDigits = slice(source, i, i + 4); + if (!exec(IS_4_HEX_DIGITS, fourHexDigits)) throw new $SyntaxError('Bad Unicode escape at: ' + i); + value += fromCharCode($parseInt(fourHexDigits, 16)); + i += 4; + } else throw new $SyntaxError('Unknown escape sequence: "' + twoChars + '"'); + } else if (chr === '"') { + unterminated = false; + i++; + break; + } else { + if (exec(IS_C0_CONTROL_CODE, chr)) throw new $SyntaxError('Bad control character in string literal at: ' + i); + value += chr; + i++; + } + } + if (unterminated) throw new $SyntaxError('Unterminated string at: ' + i); + return { value: value, end: i }; +}; + + +/***/ }), +/* 180 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var FREEZING = __webpack_require__(181); +var NATIVE_RAW_JSON = __webpack_require__(176); +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); +var toString = __webpack_require__(81); +var createProperty = __webpack_require__(149); +var setInternalState = __webpack_require__(55).set; + +var $SyntaxError = SyntaxError; +var parse = getBuiltIn('JSON', 'parse'); +var create = getBuiltIn('Object', 'create'); +var freeze = getBuiltIn('Object', 'freeze'); +var at = uncurryThis(''.charAt); + +var ERROR_MESSAGE = 'Unacceptable as raw JSON'; + +var isWhitespace = function (it) { + return it === ' ' || it === '\t' || it === '\n' || it === '\r'; +}; + +// `JSON.rawJSON` method +// https://tc39.es/proposal-json-parse-with-source/#sec-json.rawjson +// https://github.com/tc39/proposal-json-parse-with-source +$({ target: 'JSON', stat: true, forced: !NATIVE_RAW_JSON }, { + rawJSON: function rawJSON(text) { + var jsonString = toString(text); + if (jsonString === '' || isWhitespace(at(jsonString, 0)) || isWhitespace(at(jsonString, jsonString.length - 1))) { + throw new $SyntaxError(ERROR_MESSAGE); + } + var parsed = parse(jsonString); + if (typeof parsed == 'object' && parsed !== null) throw new $SyntaxError(ERROR_MESSAGE); + var obj = create(null); + setInternalState(obj, { type: 'RawJSON' }); + createProperty(obj, 'rawJSON', jsonString); + return FREEZING ? freeze(obj) : obj; + } +}); + + +/***/ }), +/* 181 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); + +module.exports = !fails(function () { + // eslint-disable-next-line es/no-object-isextensible, es/no-object-preventextensions -- required for testing + return Object.isExtensible(Object.preventExtensions({})); +}); + + +/***/ }), +/* 182 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var apply = __webpack_require__(72); +var call = __webpack_require__(33); +var uncurryThis = __webpack_require__(6); +var fails = __webpack_require__(8); +var isArray = __webpack_require__(114); +var isCallable = __webpack_require__(28); +var isRawJSON = __webpack_require__(177); +var isSymbol = __webpack_require__(34); +var classof = __webpack_require__(46); +var toString = __webpack_require__(81); +var arraySlice = __webpack_require__(183); +var parseJSONString = __webpack_require__(179); +var uid = __webpack_require__(18); +var NATIVE_SYMBOL = __webpack_require__(19); +var NATIVE_RAW_JSON = __webpack_require__(176); + +var $String = String; +var $stringify = getBuiltIn('JSON', 'stringify'); +var exec = uncurryThis(/./.exec); +var charAt = uncurryThis(''.charAt); +var charCodeAt = uncurryThis(''.charCodeAt); +var replace = uncurryThis(''.replace); +var slice = uncurryThis(''.slice); +var push = uncurryThis([].push); +var numberToString = uncurryThis(1.1.toString); + +var surrogates = /[\uD800-\uDFFF]/g; +var lowSurrogates = /^[\uD800-\uDBFF]$/; +var hiSurrogates = /^[\uDC00-\uDFFF]$/; + +var MARK = uid(); +var MARK_LENGTH = MARK.length; + +var WRONG_SYMBOLS_CONVERSION = !NATIVE_SYMBOL || fails(function () { + var symbol = getBuiltIn('Symbol')('stringify detection'); + // MS Edge converts symbol values to JSON as {} + return $stringify([symbol]) !== '[null]' + // WebKit converts symbol values to JSON as null + || $stringify({ a: symbol }) !== '{}' + // V8 throws on boxed symbols + || $stringify(Object(symbol)) !== '{}'; +}); + +// https://github.com/tc39/proposal-well-formed-stringify +var ILL_FORMED_UNICODE = fails(function () { + return $stringify('\uDF06\uD834') !== '"\\udf06\\ud834"' + || $stringify('\uDEAD') !== '"\\udead"'; +}); + +var stringifyWithProperSymbolsConversion = WRONG_SYMBOLS_CONVERSION ? function (it, replacer) { + var args = arraySlice(arguments); + var $replacer = getReplacerFunction(replacer); + if (!isCallable($replacer) && (it === undefined || isSymbol(it))) return; // IE8 returns string on undefined + args[1] = function (key, value) { + // some old implementations (like WebKit) could pass numbers as keys + if (isCallable($replacer)) value = call($replacer, this, $String(key), value); + if (!isSymbol(value)) return value; + }; + return apply($stringify, null, args); +} : $stringify; + +var fixIllFormedJSON = function (match, offset, string) { + var prev = charAt(string, offset - 1); + var next = charAt(string, offset + 1); + if ((exec(lowSurrogates, match) && !exec(hiSurrogates, next)) || (exec(hiSurrogates, match) && !exec(lowSurrogates, prev))) { + return '\\u' + numberToString(charCodeAt(match, 0), 16); + } return match; +}; + +var getReplacerFunction = function (replacer) { + if (isCallable(replacer)) return replacer; + if (!isArray(replacer)) return; + var rawLength = replacer.length; + var keys = []; + for (var i = 0; i < rawLength; i++) { + var element = replacer[i]; + if (typeof element == 'string') push(keys, element); + else if (typeof element == 'number' || classof(element) === 'Number' || classof(element) === 'String') push(keys, toString(element)); + } + var keysLength = keys.length; + var root = true; + return function (key, value) { + if (root) { + root = false; + return value; + } + if (isArray(this)) return value; + for (var j = 0; j < keysLength; j++) if (keys[j] === key) return value; + }; +}; + +// `JSON.stringify` method +// https://tc39.es/ecma262/#sec-json.stringify +// https://github.com/tc39/proposal-json-parse-with-source +if ($stringify) $({ target: 'JSON', stat: true, arity: 3, forced: WRONG_SYMBOLS_CONVERSION || ILL_FORMED_UNICODE || !NATIVE_RAW_JSON }, { + stringify: function stringify(text, replacer, space) { + var replacerFunction = getReplacerFunction(replacer); + var rawStrings = []; + + var json = stringifyWithProperSymbolsConversion(text, function (key, value) { + // some old implementations (like WebKit) could pass numbers as keys + var v = isCallable(replacerFunction) ? call(replacerFunction, this, $String(key), value) : value; + return !NATIVE_RAW_JSON && isRawJSON(v) ? MARK + (push(rawStrings, v.rawJSON) - 1) : v; + }, space); + + if (typeof json != 'string') return json; + + if (ILL_FORMED_UNICODE) json = replace(json, surrogates, fixIllFormedJSON); + + if (NATIVE_RAW_JSON) return json; + + var result = ''; + var length = json.length; + + for (var i = 0; i < length; i++) { + var chr = charAt(json, i); + if (chr === '"') { + var end = parseJSONString(json, ++i).end - 1; + var string = slice(json, i, end); + result += slice(string, 0, MARK_LENGTH) === MARK + ? rawStrings[slice(string, MARK_LENGTH)] + : '"' + string + '"'; + i = end; + } else result += chr; + } + + return result; + } +}); + + +/***/ }), +/* 183 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +module.exports = uncurryThis([].slice); + + +/***/ }), +/* 184 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var aCallable = __webpack_require__(38); +var requireObjectCoercible = __webpack_require__(10); +var iterate = __webpack_require__(97); +var MapHelpers = __webpack_require__(185); +var IS_PURE = __webpack_require__(16); +var fails = __webpack_require__(8); + +var Map = MapHelpers.Map; +var has = MapHelpers.has; +var get = MapHelpers.get; +var set = MapHelpers.set; +var push = uncurryThis([].push); + +// https://bugs.webkit.org/show_bug.cgi?id=271524 +var DOES_NOT_WORK_WITH_PRIMITIVES = IS_PURE || fails(function () { + return Map.groupBy('ab', function (it) { + return it; + }).get('a').length !== 1; +}); + +// `Map.groupBy` method +// https://tc39.es/ecma262/#sec-map.groupby +$({ target: 'Map', stat: true, forced: IS_PURE || DOES_NOT_WORK_WITH_PRIMITIVES }, { + groupBy: function groupBy(items, callbackfn) { + requireObjectCoercible(items); + aCallable(callbackfn); + var map = new Map(); + var k = 0; + iterate(items, function (value) { + var key = callbackfn(value, k++); + if (!has(map, key)) set(map, key, [value]); + else push(get(map, key), value); + }); + return map; + } +}); + + +/***/ }), +/* 185 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +// eslint-disable-next-line es/no-map -- safe +var MapPrototype = Map.prototype; + +module.exports = { + // eslint-disable-next-line es/no-map -- safe + Map: Map, + set: uncurryThis(MapPrototype.set), + get: uncurryThis(MapPrototype.get), + has: uncurryThis(MapPrototype.has), + remove: uncurryThis(MapPrototype['delete']), + proto: MapPrototype +}; + + +/***/ }), +/* 186 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var floatRound = __webpack_require__(187); + +var FLOAT16_EPSILON = 0.0009765625; +var FLOAT16_MAX_VALUE = 65504; +var FLOAT16_MIN_VALUE = 6.103515625e-05; + +// `Math.f16round` method +// https://tc39.es/ecma262/#sec-math.f16round +$({ target: 'Math', stat: true }, { + f16round: function f16round(x) { + return floatRound(x, FLOAT16_EPSILON, FLOAT16_MAX_VALUE, FLOAT16_MIN_VALUE); + } +}); + + +/***/ }), +/* 187 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var sign = __webpack_require__(188); +var roundTiesToEven = __webpack_require__(129); + +var abs = Math.abs; + +var EPSILON = 2.220446049250313e-16; // Number.EPSILON + +module.exports = function (x, FLOAT_EPSILON, FLOAT_MAX_VALUE, FLOAT_MIN_VALUE) { + var n = +x; + var absolute = abs(n); + var s = sign(n); + if (absolute < FLOAT_MIN_VALUE) return s * roundTiesToEven(absolute / FLOAT_MIN_VALUE / FLOAT_EPSILON) * FLOAT_MIN_VALUE * FLOAT_EPSILON; + var a = (1 + FLOAT_EPSILON / EPSILON) * absolute; + var result = a - (a - absolute); + // eslint-disable-next-line no-self-compare -- NaN check + if (result > FLOAT_MAX_VALUE || result !== result) return s * Infinity; + return s * result; +}; + + +/***/ }), +/* 188 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// `Math.sign` method implementation +// https://tc39.es/ecma262/#sec-math.sign +// eslint-disable-next-line es/no-math-sign -- safe +module.exports = Math.sign || function sign(x) { + var n = +x; + // eslint-disable-next-line no-self-compare -- NaN check + return n === 0 || n !== n ? n : n < 0 ? -1 : 1; +}; + + +/***/ }), +/* 189 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// based on Shewchuk's algorithm for exactly floating point addition +// adapted from https://github.com/tc39/proposal-math-sum/blob/3513d58323a1ae25560e8700aa5294500c6c9287/polyfill/polyfill.mjs +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var iterate = __webpack_require__(97); + +var $RangeError = RangeError; +var $TypeError = TypeError; +var $Infinity = Infinity; +var $NaN = NaN; +var abs = Math.abs; +var pow = Math.pow; +var push = uncurryThis([].push); + +var POW_2_1023 = pow(2, 1023); +var MAX_SAFE_INTEGER = pow(2, 53) - 1; // 2 ** 53 - 1 === 9007199254740992 +var MAX_DOUBLE = Number.MAX_VALUE; // 2 ** 1024 - 2 ** (1023 - 52) === 1.79769313486231570815e+308 +var MAX_ULP = pow(2, 971); // 2 ** (1023 - 52) === 1.99584030953471981166e+292 + +var NOT_A_NUMBER = {}; +var MINUS_INFINITY = {}; +var PLUS_INFINITY = {}; +var MINUS_ZERO = {}; +var FINITE = {}; + +// prerequisite: abs(x) >= abs(y) +var twosum = function (x, y) { + var hi = x + y; + var lo = y - (hi - x); + return { hi: hi, lo: lo }; +}; + +// `Math.sumPrecise` method +// https://github.com/tc39/proposal-math-sum +$({ target: 'Math', stat: true }, { + // eslint-disable-next-line max-statements -- ok + sumPrecise: function sumPrecise(items) { + var numbers = []; + var count = 0; + var state = MINUS_ZERO; + + iterate(items, function (n) { + if (++count >= MAX_SAFE_INTEGER) throw new $RangeError('Maximum allowed index exceeded'); + if (typeof n != 'number') throw new $TypeError('Value is not a number'); + if (state !== NOT_A_NUMBER) { + // eslint-disable-next-line no-self-compare -- NaN check + if (n !== n) state = NOT_A_NUMBER; + else if (n === $Infinity) state = state === MINUS_INFINITY ? NOT_A_NUMBER : PLUS_INFINITY; + else if (n === -$Infinity) state = state === PLUS_INFINITY ? NOT_A_NUMBER : MINUS_INFINITY; + else if ((n !== 0 || (1 / n) === $Infinity) && (state === MINUS_ZERO || state === FINITE)) { + state = FINITE; + push(numbers, n); + } + } + }); + + switch (state) { + case NOT_A_NUMBER: return $NaN; + case MINUS_INFINITY: return -$Infinity; + case PLUS_INFINITY: return $Infinity; + case MINUS_ZERO: return -0; + } + + var partials = []; + var overflow = 0; // conceptually 2 ** 1024 times this value; the final partial is biased by this amount + var x, y, sum, hi, lo, tmp; + + for (var i = 0; i < numbers.length; i++) { + x = numbers[i]; + var actuallyUsedPartials = 0; + for (var j = 0; j < partials.length; j++) { + y = partials[j]; + if (abs(x) < abs(y)) { + tmp = x; + x = y; + y = tmp; + } + sum = twosum(x, y); + hi = sum.hi; + lo = sum.lo; + if (abs(hi) === $Infinity) { + var sign = hi === $Infinity ? 1 : -1; + overflow += sign; + + x = (x - (sign * POW_2_1023)) - (sign * POW_2_1023); + if (abs(x) < abs(y)) { + tmp = x; + x = y; + y = tmp; + } + sum = twosum(x, y); + hi = sum.hi; + lo = sum.lo; + } + if (lo !== 0) partials[actuallyUsedPartials++] = lo; + x = hi; + } + partials.length = actuallyUsedPartials; + if (x !== 0) push(partials, x); + } + + // compute the exact sum of partials, stopping once we lose precision + var n = partials.length - 1; + hi = 0; + lo = 0; + + if (overflow !== 0) { + var next = n >= 0 ? partials[n] : 0; + n--; + if (abs(overflow) > 1 || (overflow > 0 && next > 0) || (overflow < 0 && next < 0)) { + return overflow > 0 ? $Infinity : -$Infinity; + } + // here we actually have to do the arithmetic + // drop a factor of 2 so we can do it without overflow + // assert(abs(overflow) === 1) + sum = twosum(overflow * POW_2_1023, next / 2); + hi = sum.hi; + lo = sum.lo; + lo *= 2; + if (abs(2 * hi) === $Infinity) { + // rounding to the maximum value + if (hi > 0) { + return (hi === POW_2_1023 && lo === -(MAX_ULP / 2) && n >= 0 && partials[n] < 0) ? MAX_DOUBLE : $Infinity; + } return (hi === -POW_2_1023 && lo === (MAX_ULP / 2) && n >= 0 && partials[n] > 0) ? -MAX_DOUBLE : -$Infinity; + } + + if (lo !== 0) { + partials[++n] = lo; + lo = 0; + } + + hi *= 2; + } + + while (n >= 0) { + sum = twosum(hi, partials[n--]); + hi = sum.hi; + lo = sum.lo; + if (lo !== 0) break; + } + + if (n >= 0 && ((lo < 0 && partials[n] < 0) || (lo > 0 && partials[n] > 0))) { + y = lo * 2; + x = hi + y; + if (y === x - hi) hi = x; + } + + return hi; + } +}); + + +/***/ }), +/* 190 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var createProperty = __webpack_require__(149); +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); +var aCallable = __webpack_require__(38); +var requireObjectCoercible = __webpack_require__(10); +var toPropertyKey = __webpack_require__(31); +var iterate = __webpack_require__(97); +var fails = __webpack_require__(8); + +// eslint-disable-next-line es/no-object-groupby -- testing +var nativeGroupBy = Object.groupBy; +var create = getBuiltIn('Object', 'create'); +var push = uncurryThis([].push); + +// https://bugs.webkit.org/show_bug.cgi?id=271524 +var DOES_NOT_WORK_WITH_PRIMITIVES = !nativeGroupBy || fails(function () { + return nativeGroupBy('ab', function (it) { + return it; + }).a.length !== 1; +}); + +// `Object.groupBy` method +// https://tc39.es/ecma262/#sec-object.groupby +$({ target: 'Object', stat: true, forced: DOES_NOT_WORK_WITH_PRIMITIVES }, { + groupBy: function groupBy(items, callbackfn) { + requireObjectCoercible(items); + aCallable(callbackfn); + var obj = create(null); + var k = 0; + iterate(items, function (value) { + var key = toPropertyKey(callbackfn(value, k++)); + // in some IE versions, `hasOwnProperty` returns incorrect result on integer keys + // but since it's a `null` prototype object, we can safely use `in` + if (key in obj) push(obj[key], value); + else createProperty(obj, key, [value]); + }); + return obj; + } +}); + + +/***/ }), +/* 191 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var hasOwn = __webpack_require__(5); + +// `Object.hasOwn` method +// https://tc39.es/ecma262/#sec-object.hasown +$({ target: 'Object', stat: true }, { + hasOwn: hasOwn +}); + + +/***/ }), +/* 192 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var defineBuiltInAccessor = __webpack_require__(131); +var isObject = __webpack_require__(27); +var isPossiblePrototype = __webpack_require__(77); +var toObject = __webpack_require__(9); +var requireObjectCoercible = __webpack_require__(10); + +// eslint-disable-next-line es/no-object-getprototypeof -- safe +var getPrototypeOf = Object.getPrototypeOf; +// eslint-disable-next-line es/no-object-setprototypeof -- safe +var setPrototypeOf = Object.setPrototypeOf; +var ObjectPrototype = Object.prototype; +var PROTO = '__proto__'; + +// `Object.prototype.__proto__` accessor +// https://tc39.es/ecma262/#sec-object.prototype.__proto__ +if (DESCRIPTORS && getPrototypeOf && setPrototypeOf && !(PROTO in ObjectPrototype)) try { + defineBuiltInAccessor(ObjectPrototype, PROTO, { + configurable: true, + get: function __proto__() { + return getPrototypeOf(toObject(this)); + }, + set: function __proto__(proto) { + var O = requireObjectCoercible(this); + if (isPossiblePrototype(proto) && isObject(O)) { + setPrototypeOf(O, proto); + } + } + }); +} catch (error) { /* empty */ } + + +/***/ }), +/* 193 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove this module from `core-js@4` since it's split to modules listed below +__webpack_require__(194); +__webpack_require__(213); +__webpack_require__(216); +__webpack_require__(217); +__webpack_require__(218); +__webpack_require__(219); + + +/***/ }), +/* 194 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var IS_PURE = __webpack_require__(16); +var IS_NODE = __webpack_require__(140); +var globalThis = __webpack_require__(2); +var path = __webpack_require__(4); +var call = __webpack_require__(33); +var defineBuiltIn = __webpack_require__(51); +var setPrototypeOf = __webpack_require__(74); +var setToStringTag = __webpack_require__(195); +var setSpecies = __webpack_require__(196); +var aCallable = __webpack_require__(38); +var isCallable = __webpack_require__(28); +var isObject = __webpack_require__(27); +var anInstance = __webpack_require__(145); +var speciesConstructor = __webpack_require__(197); +var task = __webpack_require__(200).set; +var microtask = __webpack_require__(203); +var hostReportErrors = __webpack_require__(208); +var perform = __webpack_require__(209); +var Queue = __webpack_require__(205); +var InternalStateModule = __webpack_require__(55); +var NativePromiseConstructor = __webpack_require__(210); +var PromiseConstructorDetection = __webpack_require__(211); +var newPromiseCapabilityModule = __webpack_require__(212); + +var PROMISE = 'Promise'; +var FORCED_PROMISE_CONSTRUCTOR = PromiseConstructorDetection.CONSTRUCTOR; +var NATIVE_PROMISE_REJECTION_EVENT = PromiseConstructorDetection.REJECTION_EVENT; +var NATIVE_PROMISE_SUBCLASSING = PromiseConstructorDetection.SUBCLASSING; +var getInternalPromiseState = InternalStateModule.getterFor(PROMISE); +var setInternalState = InternalStateModule.set; +var NativePromisePrototype = NativePromiseConstructor && NativePromiseConstructor.prototype; +var PromiseConstructor = NativePromiseConstructor; +var PromisePrototype = NativePromisePrototype; +var TypeError = globalThis.TypeError; +var document = globalThis.document; +var process = globalThis.process; +var newPromiseCapability = newPromiseCapabilityModule.f; +var newGenericPromiseCapability = newPromiseCapability; + +var DISPATCH_EVENT = !!(document && document.createEvent && globalThis.dispatchEvent); +var UNHANDLED_REJECTION = 'unhandledrejection'; +var REJECTION_HANDLED = 'rejectionhandled'; +var PENDING = 0; +var FULFILLED = 1; +var REJECTED = 2; +var HANDLED = 1; +var UNHANDLED = 2; + +var Internal, OwnPromiseCapability, PromiseWrapper, nativeThen; + +// helpers +var isThenable = function (it) { + var then; + return isObject(it) && isCallable(then = it.then) ? then : false; +}; + +var callReaction = function (reaction, state) { + var value = state.value; + var ok = state.state === FULFILLED; + var handler = ok ? reaction.ok : reaction.fail; + var resolve = reaction.resolve; + var reject = reaction.reject; + var domain = reaction.domain; + var result, then, exited; + try { + if (handler) { + if (!ok) { + if (state.rejection === UNHANDLED) onHandleUnhandled(state); + state.rejection = HANDLED; + } + if (handler === true) result = value; + else { + if (domain) domain.enter(); + result = handler(value); // can throw + if (domain) { + domain.exit(); + exited = true; + } + } + if (result === reaction.promise) { + reject(new TypeError('Promise-chain cycle')); + } else if (then = isThenable(result)) { + call(then, result, resolve, reject); + } else resolve(result); + } else reject(value); + } catch (error) { + if (domain && !exited) domain.exit(); + reject(error); + } +}; + +var notify = function (state, isReject) { + if (state.notified) return; + state.notified = true; + microtask(function () { + var reactions = state.reactions; + var reaction; + while (reaction = reactions.get()) { + callReaction(reaction, state); + } + state.notified = false; + if (isReject && !state.rejection) onUnhandled(state); + }); +}; + +var dispatchEvent = function (name, promise, reason) { + var event, handler; + if (DISPATCH_EVENT) { + event = document.createEvent('Event'); + event.promise = promise; + event.reason = reason; + event.initEvent(name, false, true); + globalThis.dispatchEvent(event); + } else event = { promise: promise, reason: reason }; + if (!NATIVE_PROMISE_REJECTION_EVENT && (handler = globalThis['on' + name])) handler(event); + else if (name === UNHANDLED_REJECTION) hostReportErrors('Unhandled promise rejection', reason); +}; + +var onUnhandled = function (state) { + call(task, globalThis, function () { + var promise = state.facade; + var value = state.value; + var IS_UNHANDLED = isUnhandled(state); + var result; + if (IS_UNHANDLED) { + result = perform(function () { + if (IS_NODE) { + process.emit('unhandledRejection', value, promise); + } else dispatchEvent(UNHANDLED_REJECTION, promise, value); + }); + // Browsers should not trigger `rejectionHandled` event if it was handled here, NodeJS - should + state.rejection = IS_NODE || isUnhandled(state) ? UNHANDLED : HANDLED; + if (result.error) throw result.value; + } + }); +}; + +var isUnhandled = function (state) { + return state.rejection !== HANDLED && !state.parent; +}; + +var onHandleUnhandled = function (state) { + call(task, globalThis, function () { + var promise = state.facade; + if (IS_NODE) { + process.emit('rejectionHandled', promise); + } else dispatchEvent(REJECTION_HANDLED, promise, state.value); + }); +}; + +var bind = function (fn, state, unwrap) { + return function (value) { + fn(state, value, unwrap); + }; +}; + +var internalReject = function (state, value, unwrap) { + if (state.done) return; + state.done = true; + if (unwrap) state = unwrap; + state.value = value; + state.state = REJECTED; + notify(state, true); +}; + +var internalResolve = function (state, value, unwrap) { + if (state.done) return; + state.done = true; + if (unwrap) state = unwrap; + try { + if (state.facade === value) throw new TypeError("Promise can't be resolved itself"); + var then = isThenable(value); + if (then) { + microtask(function () { + var wrapper = { done: false }; + try { + call(then, value, + bind(internalResolve, wrapper, state), + bind(internalReject, wrapper, state) + ); + } catch (error) { + internalReject(wrapper, error, state); + } + }); + } else { + state.value = value; + state.state = FULFILLED; + notify(state, false); + } + } catch (error) { + internalReject({ done: false }, error, state); + } +}; + +// constructor polyfill +if (FORCED_PROMISE_CONSTRUCTOR) { + // 25.4.3.1 Promise(executor) + PromiseConstructor = function Promise(executor) { + anInstance(this, PromisePrototype); + aCallable(executor); + call(Internal, this); + var state = getInternalPromiseState(this); + try { + executor(bind(internalResolve, state), bind(internalReject, state)); + } catch (error) { + internalReject(state, error); + } + }; + + PromisePrototype = PromiseConstructor.prototype; + + // eslint-disable-next-line no-unused-vars -- required for `.length` + Internal = function Promise(executor) { + setInternalState(this, { + type: PROMISE, + done: false, + notified: false, + parent: false, + reactions: new Queue(), + rejection: false, + state: PENDING, + value: null + }); + }; + + // `Promise.prototype.then` method + // https://tc39.es/ecma262/#sec-promise.prototype.then + Internal.prototype = defineBuiltIn(PromisePrototype, 'then', function then(onFulfilled, onRejected) { + var state = getInternalPromiseState(this); + var reaction = newPromiseCapability(speciesConstructor(this, PromiseConstructor)); + state.parent = true; + reaction.ok = isCallable(onFulfilled) ? onFulfilled : true; + reaction.fail = isCallable(onRejected) && onRejected; + reaction.domain = IS_NODE ? process.domain : undefined; + if (state.state === PENDING) state.reactions.add(reaction); + else microtask(function () { + callReaction(reaction, state); + }); + return reaction.promise; + }); + + OwnPromiseCapability = function () { + var promise = new Internal(); + var state = getInternalPromiseState(promise); + this.promise = promise; + this.resolve = bind(internalResolve, state); + this.reject = bind(internalReject, state); + }; + + newPromiseCapabilityModule.f = newPromiseCapability = function (C) { + return C === PromiseConstructor || C === PromiseWrapper + ? new OwnPromiseCapability(C) + : newGenericPromiseCapability(C); + }; + + if (!IS_PURE && isCallable(NativePromiseConstructor) && NativePromisePrototype !== Object.prototype) { + nativeThen = NativePromisePrototype.then; + + if (!NATIVE_PROMISE_SUBCLASSING) { + // make `Promise#then` return a polyfilled `Promise` for native promise-based APIs + defineBuiltIn(NativePromisePrototype, 'then', function then(onFulfilled, onRejected) { + var that = this; + return new PromiseConstructor(function (resolve, reject) { + call(nativeThen, that, resolve, reject); + }).then(onFulfilled, onRejected); + // https://github.com/zloirock/core-js/issues/640 + }, { unsafe: true }); + } + + // make `.constructor === Promise` work for native promise-based APIs + try { + delete NativePromisePrototype.constructor; + } catch (error) { /* empty */ } + + // make `instanceof Promise` work for native promise-based APIs + if (setPrototypeOf) { + setPrototypeOf(NativePromisePrototype, PromisePrototype); + } + } +} + +// `Promise` constructor +// https://tc39.es/ecma262/#sec-promise-executor +$({ global: true, constructor: true, wrap: true, forced: FORCED_PROMISE_CONSTRUCTOR }, { + Promise: PromiseConstructor +}); + +PromiseWrapper = path.Promise; + +setToStringTag(PromiseConstructor, PROMISE, false, true); +setSpecies(PROMISE); + + +/***/ }), +/* 195 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineProperty = __webpack_require__(23).f; +var hasOwn = __webpack_require__(5); +var wellKnownSymbol = __webpack_require__(13); + +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); + +module.exports = function (target, TAG, STATIC) { + if (target && !STATIC) target = target.prototype; + if (target && !hasOwn(target, TO_STRING_TAG)) { + defineProperty(target, TO_STRING_TAG, { configurable: true, value: TAG }); + } +}; + + +/***/ }), +/* 196 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); +var defineBuiltInAccessor = __webpack_require__(131); +var wellKnownSymbol = __webpack_require__(13); +var DESCRIPTORS = __webpack_require__(24); + +var SPECIES = wellKnownSymbol('species'); + +module.exports = function (CONSTRUCTOR_NAME) { + var Constructor = getBuiltIn(CONSTRUCTOR_NAME); + + if (DESCRIPTORS && Constructor && !Constructor[SPECIES]) { + defineBuiltInAccessor(Constructor, SPECIES, { + configurable: true, + get: function () { return this; } + }); + } +}; + + +/***/ }), +/* 197 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var anObject = __webpack_require__(30); +var aConstructor = __webpack_require__(198); +var isNullOrUndefined = __webpack_require__(11); +var wellKnownSymbol = __webpack_require__(13); + +var SPECIES = wellKnownSymbol('species'); + +// `SpeciesConstructor` abstract operation +// https://tc39.es/ecma262/#sec-speciesconstructor +module.exports = function (O, defaultConstructor) { + var C = anObject(O).constructor; + var S; + return C === undefined || isNullOrUndefined(S = anObject(C)[SPECIES]) ? defaultConstructor : aConstructor(S); +}; + + +/***/ }), +/* 198 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isConstructor = __webpack_require__(199); +var tryToString = __webpack_require__(39); + +var $TypeError = TypeError; + +// `Assert: IsConstructor(argument) is true` +module.exports = function (argument) { + if (isConstructor(argument)) return argument; + throw new $TypeError(tryToString(argument) + ' is not a constructor'); +}; + + +/***/ }), +/* 199 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var fails = __webpack_require__(8); +var isCallable = __webpack_require__(28); +var classof = __webpack_require__(82); +var getBuiltIn = __webpack_require__(35); +var inspectSource = __webpack_require__(54); + +var noop = function () { /* empty */ }; +var construct = getBuiltIn('Reflect', 'construct'); +var constructorRegExp = /^\s*(?:class|function)\b/; +var exec = uncurryThis(constructorRegExp.exec); +var INCORRECT_TO_STRING = !constructorRegExp.test(noop); + +var isConstructorModern = function isConstructor(argument) { + if (!isCallable(argument)) return false; + try { + construct(noop, [], argument); + return true; + } catch (error) { + return false; + } +}; + +var isConstructorLegacy = function isConstructor(argument) { + if (!isCallable(argument)) return false; + switch (classof(argument)) { + case 'AsyncFunction': + case 'GeneratorFunction': + case 'AsyncGeneratorFunction': return false; + } + try { + // we can't check .prototype since constructors produced by .bind haven't it + // `Function#toString` throws on some built-it function in some legacy engines + // (for example, `DOMQuad` and similar in FF41-) + return INCORRECT_TO_STRING || !!exec(constructorRegExp, inspectSource(argument)); + } catch (error) { + return true; + } +}; + +isConstructorLegacy.sham = true; + +// `IsConstructor` abstract operation +// https://tc39.es/ecma262/#sec-isconstructor +module.exports = !construct || fails(function () { + var called; + return isConstructorModern(isConstructorModern.call) + || !isConstructorModern(Object) + || !isConstructorModern(function () { called = true; }) + || called; +}) ? isConstructorLegacy : isConstructorModern; + + +/***/ }), +/* 200 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var apply = __webpack_require__(72); +var bind = __webpack_require__(98); +var isCallable = __webpack_require__(28); +var hasOwn = __webpack_require__(5); +var fails = __webpack_require__(8); +var html = __webpack_require__(96); +var arraySlice = __webpack_require__(183); +var createElement = __webpack_require__(26); +var validateArgumentsLength = __webpack_require__(201); +var IS_IOS = __webpack_require__(202); +var IS_NODE = __webpack_require__(140); + +var set = globalThis.setImmediate; +var clear = globalThis.clearImmediate; +var process = globalThis.process; +var Dispatch = globalThis.Dispatch; +var Function = globalThis.Function; +var MessageChannel = globalThis.MessageChannel; +var String = globalThis.String; +var counter = 0; +var queue = {}; +var ONREADYSTATECHANGE = 'onreadystatechange'; +var $location, defer, channel, port; + +fails(function () { + // Deno throws a ReferenceError on `location` access without `--location` flag + $location = globalThis.location; +}); + +var run = function (id) { + if (hasOwn(queue, id)) { + var fn = queue[id]; + delete queue[id]; + fn(); + } +}; + +var runner = function (id) { + return function () { + run(id); + }; +}; + +var eventListener = function (event) { + run(event.data); +}; + +var globalPostMessageDefer = function (id) { + // old engines have not location.origin + globalThis.postMessage(String(id), $location.protocol + '//' + $location.host); +}; + +// Node.js 0.9+ & IE10+ has setImmediate, otherwise: +if (!set || !clear) { + set = function setImmediate(handler) { + validateArgumentsLength(arguments.length, 1); + var fn = isCallable(handler) ? handler : Function(handler); + var args = arraySlice(arguments, 1); + queue[++counter] = function () { + apply(fn, undefined, args); + }; + defer(counter); + return counter; + }; + clear = function clearImmediate(id) { + delete queue[id]; + }; + // Node.js 0.8- + if (IS_NODE) { + defer = function (id) { + process.nextTick(runner(id)); + }; + // Sphere (JS game engine) Dispatch API + } else if (Dispatch && Dispatch.now) { + defer = function (id) { + Dispatch.now(runner(id)); + }; + // Browsers with MessageChannel, includes WebWorkers + // except iOS - https://github.com/zloirock/core-js/issues/624 + } else if (MessageChannel && !IS_IOS) { + channel = new MessageChannel(); + port = channel.port2; + channel.port1.onmessage = eventListener; + defer = bind(port.postMessage, port); + // Browsers with postMessage, skip WebWorkers + // IE8 has postMessage, but it's sync & typeof its postMessage is 'object' + } else if ( + globalThis.addEventListener && + isCallable(globalThis.postMessage) && + !globalThis.importScripts && + $location && $location.protocol !== 'file:' && + !fails(globalPostMessageDefer) + ) { + defer = globalPostMessageDefer; + globalThis.addEventListener('message', eventListener, false); + // IE8- + } else if (ONREADYSTATECHANGE in createElement('script')) { + defer = function (id) { + html.appendChild(createElement('script'))[ONREADYSTATECHANGE] = function () { + html.removeChild(this); + run(id); + }; + }; + // Rest old browsers + } else { + defer = function (id) { + setTimeout(runner(id), 0); + }; + } +} + +module.exports = { + set: set, + clear: clear +}; + + +/***/ }), +/* 201 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $TypeError = TypeError; + +module.exports = function (passed, required) { + if (passed < required) throw new $TypeError('Not enough arguments'); + return passed; +}; + + +/***/ }), +/* 202 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var userAgent = __webpack_require__(21); + +// eslint-disable-next-line redos/no-vulnerable -- safe +module.exports = /(?:ipad|iphone|ipod).*applewebkit/i.test(userAgent); + + +/***/ }), +/* 203 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var safeGetBuiltIn = __webpack_require__(204); +var bind = __webpack_require__(98); +var macrotask = __webpack_require__(200).set; +var Queue = __webpack_require__(205); +var IS_IOS = __webpack_require__(202); +var IS_IOS_PEBBLE = __webpack_require__(206); +var IS_WEBOS_WEBKIT = __webpack_require__(207); +var IS_NODE = __webpack_require__(140); + +var MutationObserver = globalThis.MutationObserver || globalThis.WebKitMutationObserver; +var document = globalThis.document; +var process = globalThis.process; +var Promise = globalThis.Promise; +var microtask = safeGetBuiltIn('queueMicrotask'); +var notify, toggle, node, promise, then; + +// modern engines have queueMicrotask method +if (!microtask) { + var queue = new Queue(); + + var flush = function () { + var parent, fn; + if (IS_NODE && (parent = process.domain)) parent.exit(); + while (fn = queue.get()) try { + fn(); + } catch (error) { + if (queue.head) notify(); + throw error; + } + if (parent) parent.enter(); + }; + + // browsers with MutationObserver, except iOS - https://github.com/zloirock/core-js/issues/339 + // also except WebOS Webkit https://github.com/zloirock/core-js/issues/898 + if (!IS_IOS && !IS_NODE && !IS_WEBOS_WEBKIT && MutationObserver && document) { + toggle = true; + node = document.createTextNode(''); + new MutationObserver(flush).observe(node, { characterData: true }); + notify = function () { + node.data = toggle = !toggle; + }; + // environments with maybe non-completely correct, but existent Promise + } else if (!IS_IOS_PEBBLE && Promise && Promise.resolve) { + // Promise.resolve without an argument throws an error in LG WebOS 2 + promise = Promise.resolve(undefined); + // workaround of WebKit ~ iOS Safari 10.1 bug + promise.constructor = Promise; + then = bind(promise.then, promise); + notify = function () { + then(flush); + }; + // Node.js without promises + } else if (IS_NODE) { + notify = function () { + process.nextTick(flush); + }; + // for other environments - macrotask based on: + // - setImmediate + // - MessageChannel + // - window.postMessage + // - onreadystatechange + // - setTimeout + } else { + // `webpack` dev server bug on IE global methods - use bind(fn, global) + macrotask = bind(macrotask, globalThis); + notify = function () { + macrotask(flush); + }; + } + + microtask = function (fn) { + if (!queue.head) notify(); + queue.add(fn); + }; +} + +module.exports = microtask; + + +/***/ }), +/* 204 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var DESCRIPTORS = __webpack_require__(24); + +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; + +// Avoid NodeJS experimental warning +module.exports = function (name) { + if (!DESCRIPTORS) return globalThis[name]; + var descriptor = getOwnPropertyDescriptor(globalThis, name); + return descriptor && descriptor.value; +}; + + +/***/ }), +/* 205 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var Queue = function () { + this.head = null; + this.tail = null; +}; + +Queue.prototype = { + add: function (item) { + var entry = { item: item, next: null }; + var tail = this.tail; + if (tail) tail.next = entry; + else this.head = entry; + this.tail = entry; + }, + get: function () { + var entry = this.head; + if (entry) { + var next = this.head = entry.next; + if (next === null) this.tail = null; + return entry.item; + } + } +}; + +module.exports = Queue; + + +/***/ }), +/* 206 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var userAgent = __webpack_require__(21); + +module.exports = /ipad|iphone|ipod/i.test(userAgent) && typeof Pebble != 'undefined'; + + +/***/ }), +/* 207 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var userAgent = __webpack_require__(21); + +module.exports = /web0s(?!.*chrome)/i.test(userAgent); + + +/***/ }), +/* 208 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = function (a, b) { + try { + // eslint-disable-next-line no-console -- safe + arguments.length === 1 ? console.error(a) : console.error(a, b); + } catch (error) { /* empty */ } +}; + + +/***/ }), +/* 209 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = function (exec) { + try { + return { error: false, value: exec() }; + } catch (error) { + return { error: true, value: error }; + } +}; + + +/***/ }), +/* 210 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); + +module.exports = globalThis.Promise; + + +/***/ }), +/* 211 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var NativePromiseConstructor = __webpack_require__(210); +var isCallable = __webpack_require__(28); +var isForced = __webpack_require__(71); +var inspectSource = __webpack_require__(54); +var wellKnownSymbol = __webpack_require__(13); +var ENVIRONMENT = __webpack_require__(141); +var IS_PURE = __webpack_require__(16); +var V8_VERSION = __webpack_require__(20); + +var NativePromisePrototype = NativePromiseConstructor && NativePromiseConstructor.prototype; +var SPECIES = wellKnownSymbol('species'); +var SUBCLASSING = false; +var NATIVE_PROMISE_REJECTION_EVENT = isCallable(globalThis.PromiseRejectionEvent); + +var FORCED_PROMISE_CONSTRUCTOR = isForced('Promise', function () { + var PROMISE_CONSTRUCTOR_SOURCE = inspectSource(NativePromiseConstructor); + var GLOBAL_CORE_JS_PROMISE = PROMISE_CONSTRUCTOR_SOURCE !== String(NativePromiseConstructor); + // V8 6.6 (Node 10 and Chrome 66) have a bug with resolving custom thenables + // https://bugs.chromium.org/p/chromium/issues/detail?id=830565 + // We can't detect it synchronously, so just check versions + if (!GLOBAL_CORE_JS_PROMISE && V8_VERSION === 66) return true; + // We need Promise#{ catch, finally } in the pure version for preventing prototype pollution + if (IS_PURE && !(NativePromisePrototype['catch'] && NativePromisePrototype['finally'])) return true; + // We can't use @@species feature detection in V8 since it causes + // deoptimization and performance degradation + // https://github.com/zloirock/core-js/issues/679 + if (!V8_VERSION || V8_VERSION < 51 || !/native code/.test(PROMISE_CONSTRUCTOR_SOURCE)) { + // Detect correctness of subclassing with @@species support + var promise = new NativePromiseConstructor(function (resolve) { resolve(1); }); + var FakePromise = function (exec) { + exec(function () { /* empty */ }, function () { /* empty */ }); + }; + var constructor = promise.constructor = {}; + constructor[SPECIES] = FakePromise; + SUBCLASSING = promise.then(function () { /* empty */ }) instanceof FakePromise; + if (!SUBCLASSING) return true; + // Unhandled rejections tracking support, NodeJS Promise without it fails @@species test + } return !GLOBAL_CORE_JS_PROMISE && (ENVIRONMENT === 'BROWSER' || ENVIRONMENT === 'DENO') && !NATIVE_PROMISE_REJECTION_EVENT; +}); + +module.exports = { + CONSTRUCTOR: FORCED_PROMISE_CONSTRUCTOR, + REJECTION_EVENT: NATIVE_PROMISE_REJECTION_EVENT, + SUBCLASSING: SUBCLASSING +}; + + +/***/ }), +/* 212 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aCallable = __webpack_require__(38); + +var $TypeError = TypeError; + +var PromiseCapability = function (C) { + var resolve, reject; + this.promise = new C(function ($$resolve, $$reject) { + if (resolve !== undefined || reject !== undefined) throw new $TypeError('Bad Promise constructor'); + resolve = $$resolve; + reject = $$reject; + }); + this.resolve = aCallable(resolve); + this.reject = aCallable(reject); +}; + +// `NewPromiseCapability` abstract operation +// https://tc39.es/ecma262/#sec-newpromisecapability +module.exports.f = function (C) { + return new PromiseCapability(C); +}; + + +/***/ }), +/* 213 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var newPromiseCapabilityModule = __webpack_require__(212); +var perform = __webpack_require__(209); +var iterate = __webpack_require__(97); +var PROMISE_STATICS_INCORRECT_ITERATION = __webpack_require__(214); + +// `Promise.all` method +// https://tc39.es/ecma262/#sec-promise.all +$({ target: 'Promise', stat: true, forced: PROMISE_STATICS_INCORRECT_ITERATION }, { + all: function all(iterable) { + var C = this; + var capability = newPromiseCapabilityModule.f(C); + var resolve = capability.resolve; + var reject = capability.reject; + var result = perform(function () { + var $promiseResolve = aCallable(C.resolve); + var values = []; + var counter = 0; + var remaining = 1; + iterate(iterable, function (promise) { + var index = counter++; + var alreadyCalled = false; + remaining++; + call($promiseResolve, C, promise).then(function (value) { + if (alreadyCalled) return; + alreadyCalled = true; + values[index] = value; + --remaining || resolve(values); + }, reject); + }); + --remaining || resolve(values); + }); + if (result.error) reject(result.value); + return capability.promise; + } +}); + + +/***/ }), +/* 214 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var NativePromiseConstructor = __webpack_require__(210); +var checkCorrectnessOfIteration = __webpack_require__(215); +var FORCED_PROMISE_CONSTRUCTOR = __webpack_require__(211).CONSTRUCTOR; + +module.exports = FORCED_PROMISE_CONSTRUCTOR || !checkCorrectnessOfIteration(function (iterable) { + NativePromiseConstructor.all(iterable).then(undefined, function () { /* empty */ }); +}); + + +/***/ }), +/* 215 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var wellKnownSymbol = __webpack_require__(13); + +var ITERATOR = wellKnownSymbol('iterator'); +var SAFE_CLOSING = false; + +try { + var called = 0; + var iteratorWithReturn = { + next: function () { + return { done: !!called++ }; + }, + 'return': function () { + SAFE_CLOSING = true; + } + }; + // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation + iteratorWithReturn[ITERATOR] = function () { + return this; + }; + // eslint-disable-next-line es/no-array-from, no-throw-literal -- required for testing + Array.from(iteratorWithReturn, function () { throw 2; }); +} catch (error) { /* empty */ } + +module.exports = function (exec, SKIP_CLOSING) { + try { + if (!SKIP_CLOSING && !SAFE_CLOSING) return false; + } catch (error) { return false; } // workaround of old WebKit + `eval` bug + var ITERATION_SUPPORT = false; + try { + var object = {}; + // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation + object[ITERATOR] = function () { + return { + next: function () { + return { done: ITERATION_SUPPORT = true }; + } + }; + }; + exec(object); + } catch (error) { /* empty */ } + return ITERATION_SUPPORT; +}; + + +/***/ }), +/* 216 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var IS_PURE = __webpack_require__(16); +var FORCED_PROMISE_CONSTRUCTOR = __webpack_require__(211).CONSTRUCTOR; +var NativePromiseConstructor = __webpack_require__(210); +var getBuiltIn = __webpack_require__(35); +var isCallable = __webpack_require__(28); +var defineBuiltIn = __webpack_require__(51); + +var NativePromisePrototype = NativePromiseConstructor && NativePromiseConstructor.prototype; + +// `Promise.prototype.catch` method +// https://tc39.es/ecma262/#sec-promise.prototype.catch +$({ target: 'Promise', proto: true, forced: FORCED_PROMISE_CONSTRUCTOR, real: true }, { + 'catch': function (onRejected) { + return this.then(undefined, onRejected); + } +}); + +// makes sure that native promise-based APIs `Promise#catch` properly works with patched `Promise#then` +if (!IS_PURE && isCallable(NativePromiseConstructor)) { + var method = getBuiltIn('Promise').prototype['catch']; + if (NativePromisePrototype['catch'] !== method) { + defineBuiltIn(NativePromisePrototype, 'catch', method, { unsafe: true }); + } +} + + +/***/ }), +/* 217 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var newPromiseCapabilityModule = __webpack_require__(212); +var perform = __webpack_require__(209); +var iterate = __webpack_require__(97); +var PROMISE_STATICS_INCORRECT_ITERATION = __webpack_require__(214); + +// `Promise.race` method +// https://tc39.es/ecma262/#sec-promise.race +$({ target: 'Promise', stat: true, forced: PROMISE_STATICS_INCORRECT_ITERATION }, { + race: function race(iterable) { + var C = this; + var capability = newPromiseCapabilityModule.f(C); + var reject = capability.reject; + var result = perform(function () { + var $promiseResolve = aCallable(C.resolve); + iterate(iterable, function (promise) { + call($promiseResolve, C, promise).then(capability.resolve, reject); + }); + }); + if (result.error) reject(result.value); + return capability.promise; + } +}); + + +/***/ }), +/* 218 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var newPromiseCapabilityModule = __webpack_require__(212); +var FORCED_PROMISE_CONSTRUCTOR = __webpack_require__(211).CONSTRUCTOR; + +// `Promise.reject` method +// https://tc39.es/ecma262/#sec-promise.reject +$({ target: 'Promise', stat: true, forced: FORCED_PROMISE_CONSTRUCTOR }, { + reject: function reject(r) { + var capability = newPromiseCapabilityModule.f(this); + var capabilityReject = capability.reject; + capabilityReject(r); + return capability.promise; + } +}); + + +/***/ }), +/* 219 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var IS_PURE = __webpack_require__(16); +var NativePromiseConstructor = __webpack_require__(210); +var FORCED_PROMISE_CONSTRUCTOR = __webpack_require__(211).CONSTRUCTOR; +var promiseResolve = __webpack_require__(220); + +var PromiseConstructorWrapper = getBuiltIn('Promise'); +var CHECK_WRAPPER = IS_PURE && !FORCED_PROMISE_CONSTRUCTOR; + +// `Promise.resolve` method +// https://tc39.es/ecma262/#sec-promise.resolve +$({ target: 'Promise', stat: true, forced: IS_PURE || FORCED_PROMISE_CONSTRUCTOR }, { + resolve: function resolve(x) { + return promiseResolve(CHECK_WRAPPER && this === PromiseConstructorWrapper ? NativePromiseConstructor : this, x); + } +}); + + +/***/ }), +/* 220 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var anObject = __webpack_require__(30); +var isObject = __webpack_require__(27); +var newPromiseCapability = __webpack_require__(212); + +module.exports = function (C, x) { + anObject(C); + if (isObject(x) && x.constructor === C) return x; + var promiseCapability = newPromiseCapability.f(C); + var resolve = promiseCapability.resolve; + resolve(x); + return promiseCapability.promise; +}; + + +/***/ }), +/* 221 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var newPromiseCapabilityModule = __webpack_require__(212); +var perform = __webpack_require__(209); +var iterate = __webpack_require__(97); +var PROMISE_STATICS_INCORRECT_ITERATION = __webpack_require__(214); + +// `Promise.allSettled` method +// https://tc39.es/ecma262/#sec-promise.allsettled +$({ target: 'Promise', stat: true, forced: PROMISE_STATICS_INCORRECT_ITERATION }, { + allSettled: function allSettled(iterable) { + var C = this; + var capability = newPromiseCapabilityModule.f(C); + var resolve = capability.resolve; + var reject = capability.reject; + var result = perform(function () { + var promiseResolve = aCallable(C.resolve); + var values = []; + var counter = 0; + var remaining = 1; + iterate(iterable, function (promise) { + var index = counter++; + var alreadyCalled = false; + remaining++; + call(promiseResolve, C, promise).then(function (value) { + if (alreadyCalled) return; + alreadyCalled = true; + values[index] = { status: 'fulfilled', value: value }; + --remaining || resolve(values); + }, function (error) { + if (alreadyCalled) return; + alreadyCalled = true; + values[index] = { status: 'rejected', reason: error }; + --remaining || resolve(values); + }); + }); + --remaining || resolve(values); + }); + if (result.error) reject(result.value); + return capability.promise; + } +}); + + +/***/ }), +/* 222 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var getBuiltIn = __webpack_require__(35); +var newPromiseCapabilityModule = __webpack_require__(212); +var perform = __webpack_require__(209); +var iterate = __webpack_require__(97); +var PROMISE_STATICS_INCORRECT_ITERATION = __webpack_require__(214); + +var PROMISE_ANY_ERROR = 'No one promise resolved'; + +// `Promise.any` method +// https://tc39.es/ecma262/#sec-promise.any +$({ target: 'Promise', stat: true, forced: PROMISE_STATICS_INCORRECT_ITERATION }, { + any: function any(iterable) { + var C = this; + var AggregateError = getBuiltIn('AggregateError'); + var capability = newPromiseCapabilityModule.f(C); + var resolve = capability.resolve; + var reject = capability.reject; + var result = perform(function () { + var promiseResolve = aCallable(C.resolve); + var errors = []; + var counter = 0; + var remaining = 1; + var alreadyResolved = false; + iterate(iterable, function (promise) { + var index = counter++; + var alreadyRejected = false; + remaining++; + call(promiseResolve, C, promise).then(function (value) { + if (alreadyRejected || alreadyResolved) return; + alreadyResolved = true; + resolve(value); + }, function (error) { + if (alreadyRejected || alreadyResolved) return; + alreadyRejected = true; + errors[index] = error; + --remaining || reject(new AggregateError(errors, PROMISE_ANY_ERROR)); + }); + }); + --remaining || reject(new AggregateError(errors, PROMISE_ANY_ERROR)); + }); + if (result.error) reject(result.value); + return capability.promise; + } +}); + + +/***/ }), +/* 223 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var IS_PURE = __webpack_require__(16); +var NativePromiseConstructor = __webpack_require__(210); +var fails = __webpack_require__(8); +var getBuiltIn = __webpack_require__(35); +var isCallable = __webpack_require__(28); +var speciesConstructor = __webpack_require__(197); +var promiseResolve = __webpack_require__(220); +var defineBuiltIn = __webpack_require__(51); + +var NativePromisePrototype = NativePromiseConstructor && NativePromiseConstructor.prototype; + +// Safari bug https://bugs.webkit.org/show_bug.cgi?id=200829 +var NON_GENERIC = !!NativePromiseConstructor && fails(function () { + // eslint-disable-next-line unicorn/no-thenable -- required for testing + NativePromisePrototype['finally'].call({ then: function () { /* empty */ } }, function () { /* empty */ }); +}); + +// `Promise.prototype.finally` method +// https://tc39.es/ecma262/#sec-promise.prototype.finally +$({ target: 'Promise', proto: true, real: true, forced: NON_GENERIC }, { + 'finally': function (onFinally) { + var C = speciesConstructor(this, getBuiltIn('Promise')); + var isFunction = isCallable(onFinally); + return this.then( + isFunction ? function (x) { + return promiseResolve(C, onFinally()).then(function () { return x; }); + } : onFinally, + isFunction ? function (e) { + return promiseResolve(C, onFinally()).then(function () { throw e; }); + } : onFinally + ); + } +}); + +// makes sure that native promise-based APIs `Promise#finally` properly works with patched `Promise#then` +if (!IS_PURE && isCallable(NativePromiseConstructor)) { + var method = getBuiltIn('Promise').prototype['finally']; + if (NativePromisePrototype['finally'] !== method) { + defineBuiltIn(NativePromisePrototype, 'finally', method, { unsafe: true }); + } +} + + +/***/ }), +/* 224 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var apply = __webpack_require__(72); +var slice = __webpack_require__(183); +var newPromiseCapabilityModule = __webpack_require__(212); +var aCallable = __webpack_require__(38); +var perform = __webpack_require__(209); + +var Promise = globalThis.Promise; + +var ACCEPT_ARGUMENTS = false; +// Avoiding the use of polyfills of the previous iteration of this proposal +// that does not accept arguments of the callback +var FORCED = !Promise || !Promise['try'] || perform(function () { + Promise['try'](function (argument) { + ACCEPT_ARGUMENTS = argument === 8; + }, 8); +}).error || !ACCEPT_ARGUMENTS; + +// `Promise.try` method +// https://tc39.es/ecma262/#sec-promise.try +$({ target: 'Promise', stat: true, forced: FORCED }, { + 'try': function (callbackfn /* , ...args */) { + var args = arguments.length > 1 ? slice(arguments, 1) : []; + var promiseCapability = newPromiseCapabilityModule.f(this); + var result = perform(function () { + return apply(aCallable(callbackfn), undefined, args); + }); + (result.error ? promiseCapability.reject : promiseCapability.resolve)(result.value); + return promiseCapability.promise; + } +}); + + +/***/ }), +/* 225 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var newPromiseCapabilityModule = __webpack_require__(212); + +// `Promise.withResolvers` method +// https://tc39.es/ecma262/#sec-promise.withResolvers +$({ target: 'Promise', stat: true }, { + withResolvers: function withResolvers() { + var promiseCapability = newPromiseCapabilityModule.f(this); + return { + promise: promiseCapability.promise, + resolve: promiseCapability.resolve, + reject: promiseCapability.reject + }; + } +}); + + +/***/ }), +/* 226 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var fromAsync = __webpack_require__(227); +var fails = __webpack_require__(8); + +// eslint-disable-next-line es/no-array-fromasync -- safe +var nativeFromAsync = Array.fromAsync; +// https://bugs.webkit.org/show_bug.cgi?id=271703 +var INCORRECT_CONSTRUCTURING = !nativeFromAsync || fails(function () { + var counter = 0; + nativeFromAsync.call(function () { + counter++; + return []; + }, { length: 0 }); + return counter !== 1; +}); + +// `Array.fromAsync` method +// https://github.com/tc39/proposal-array-from-async +$({ target: 'Array', stat: true, forced: INCORRECT_CONSTRUCTURING }, { + fromAsync: fromAsync +}); + + +/***/ }), +/* 227 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var bind = __webpack_require__(98); +var uncurryThis = __webpack_require__(6); +var toObject = __webpack_require__(9); +var isConstructor = __webpack_require__(199); +var getAsyncIterator = __webpack_require__(228); +var getIterator = __webpack_require__(102); +var getIteratorDirect = __webpack_require__(157); +var getIteratorMethod = __webpack_require__(103); +var getMethod = __webpack_require__(37); +var getBuiltIn = __webpack_require__(35); +var getBuiltInPrototypeMethod = __webpack_require__(120); +var wellKnownSymbol = __webpack_require__(13); +var AsyncFromSyncIterator = __webpack_require__(229); +var toArray = __webpack_require__(231).toArray; + +var ASYNC_ITERATOR = wellKnownSymbol('asyncIterator'); +var arrayIterator = uncurryThis(getBuiltInPrototypeMethod('Array', 'values')); +var arrayIteratorNext = uncurryThis(arrayIterator([]).next); + +var safeArrayIterator = function () { + return new SafeArrayIterator(this); +}; + +var SafeArrayIterator = function (O) { + this.iterator = arrayIterator(O); +}; + +SafeArrayIterator.prototype.next = function () { + return arrayIteratorNext(this.iterator); +}; + +// `Array.fromAsync` method implementation +// https://github.com/tc39/proposal-array-from-async +module.exports = function fromAsync(asyncItems /* , mapfn = undefined, thisArg = undefined */) { + var C = this; + var argumentsLength = arguments.length; + var mapfn = argumentsLength > 1 ? arguments[1] : undefined; + var thisArg = argumentsLength > 2 ? arguments[2] : undefined; + return new (getBuiltIn('Promise'))(function (resolve) { + var O = toObject(asyncItems); + if (mapfn !== undefined) mapfn = bind(mapfn, thisArg); + var usingAsyncIterator = getMethod(O, ASYNC_ITERATOR); + var usingSyncIterator = usingAsyncIterator ? undefined : getIteratorMethod(O) || safeArrayIterator; + var A = isConstructor(C) ? new C() : []; + var iterator = usingAsyncIterator + ? getAsyncIterator(O, usingAsyncIterator) + : new AsyncFromSyncIterator(getIteratorDirect(getIterator(O, usingSyncIterator))); + resolve(toArray(iterator, mapfn, A)); + }); +}; + + +/***/ }), +/* 228 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var AsyncFromSyncIterator = __webpack_require__(229); +var anObject = __webpack_require__(30); +var getIterator = __webpack_require__(102); +var getIteratorDirect = __webpack_require__(157); +var getMethod = __webpack_require__(37); +var wellKnownSymbol = __webpack_require__(13); + +var ASYNC_ITERATOR = wellKnownSymbol('asyncIterator'); + +module.exports = function (it, usingIterator) { + var method = arguments.length < 2 ? getMethod(it, ASYNC_ITERATOR) : usingIterator; + return method ? anObject(call(method, it)) : new AsyncFromSyncIterator(getIteratorDirect(getIterator(it))); +}; + + +/***/ }), +/* 229 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var create = __webpack_require__(93); +var getMethod = __webpack_require__(37); +var defineBuiltIns = __webpack_require__(146); +var InternalStateModule = __webpack_require__(55); +var iteratorClose = __webpack_require__(104); +var getBuiltIn = __webpack_require__(35); +var AsyncIteratorPrototype = __webpack_require__(230); +var createIterResultObject = __webpack_require__(153); + +var Promise = getBuiltIn('Promise'); + +var ASYNC_FROM_SYNC_ITERATOR = 'AsyncFromSyncIterator'; +var setInternalState = InternalStateModule.set; +var getInternalState = InternalStateModule.getterFor(ASYNC_FROM_SYNC_ITERATOR); + +var asyncFromSyncIteratorContinuation = function (result, resolve, reject, syncIterator, closeOnRejection) { + var done = result.done; + Promise.resolve(result.value).then(function (value) { + resolve(createIterResultObject(value, done)); + }, function (error) { + if (!done && closeOnRejection) { + try { + iteratorClose(syncIterator, 'throw', error); + } catch (error2) { + error = error2; + } + } + + reject(error); + }); +}; + +var AsyncFromSyncIterator = function AsyncIterator(iteratorRecord) { + iteratorRecord.type = ASYNC_FROM_SYNC_ITERATOR; + setInternalState(this, iteratorRecord); +}; + +AsyncFromSyncIterator.prototype = defineBuiltIns(create(AsyncIteratorPrototype), { + next: function next() { + var state = getInternalState(this); + return new Promise(function (resolve, reject) { + var result = anObject(call(state.next, state.iterator)); + asyncFromSyncIteratorContinuation(result, resolve, reject, state.iterator, true); + }); + }, + 'return': function () { + var iterator = getInternalState(this).iterator; + return new Promise(function (resolve, reject) { + var $return = getMethod(iterator, 'return'); + if ($return === undefined) return resolve(createIterResultObject(undefined, true)); + var result = anObject(call($return, iterator)); + asyncFromSyncIteratorContinuation(result, resolve, reject, iterator); + }); + } +}); + +module.exports = AsyncFromSyncIterator; + + +/***/ }), +/* 230 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var shared = __webpack_require__(15); +var isCallable = __webpack_require__(28); +var create = __webpack_require__(93); +var getPrototypeOf = __webpack_require__(91); +var defineBuiltIn = __webpack_require__(51); +var wellKnownSymbol = __webpack_require__(13); +var IS_PURE = __webpack_require__(16); + +var USE_FUNCTION_CONSTRUCTOR = 'USE_FUNCTION_CONSTRUCTOR'; +var ASYNC_ITERATOR = wellKnownSymbol('asyncIterator'); +var AsyncIterator = globalThis.AsyncIterator; +var PassedAsyncIteratorPrototype = shared.AsyncIteratorPrototype; +var AsyncIteratorPrototype, prototype; + +if (PassedAsyncIteratorPrototype) { + AsyncIteratorPrototype = PassedAsyncIteratorPrototype; +} else if (isCallable(AsyncIterator)) { + AsyncIteratorPrototype = AsyncIterator.prototype; +} else if (shared[USE_FUNCTION_CONSTRUCTOR] || globalThis[USE_FUNCTION_CONSTRUCTOR]) { + try { + // eslint-disable-next-line no-new-func -- we have no alternatives without usage of modern syntax + prototype = getPrototypeOf(getPrototypeOf(getPrototypeOf(Function('return async function*(){}()')()))); + if (getPrototypeOf(prototype) === Object.prototype) AsyncIteratorPrototype = prototype; + } catch (error) { /* empty */ } +} + +if (!AsyncIteratorPrototype) AsyncIteratorPrototype = {}; +else if (IS_PURE) AsyncIteratorPrototype = create(AsyncIteratorPrototype); + +if (!isCallable(AsyncIteratorPrototype[ASYNC_ITERATOR])) { + defineBuiltIn(AsyncIteratorPrototype, ASYNC_ITERATOR, function () { + return this; + }); +} + +module.exports = AsyncIteratorPrototype; + + +/***/ }), +/* 231 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// https://github.com/tc39/proposal-async-iterator-helpers +// https://github.com/tc39/proposal-array-from-async +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var isObject = __webpack_require__(27); +var doesNotExceedSafeInteger = __webpack_require__(115); +var getBuiltIn = __webpack_require__(35); +var getIteratorDirect = __webpack_require__(157); +var closeAsyncIteration = __webpack_require__(232); + +var createMethod = function (TYPE) { + var IS_TO_ARRAY = TYPE === 0; + var IS_FOR_EACH = TYPE === 1; + var IS_EVERY = TYPE === 2; + var IS_SOME = TYPE === 3; + return function (object, fn, target) { + anObject(object); + var MAPPING = fn !== undefined; + if (MAPPING || !IS_TO_ARRAY) aCallable(fn); + var record = getIteratorDirect(object); + var Promise = getBuiltIn('Promise'); + var iterator = record.iterator; + var next = record.next; + var counter = 0; + + return new Promise(function (resolve, reject) { + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, reject, error, reject); + }; + + var loop = function () { + try { + if (MAPPING) try { + doesNotExceedSafeInteger(counter); + } catch (error5) { ifAbruptCloseAsyncIterator(error5); } + Promise.resolve(anObject(call(next, iterator))).then(function (step) { + try { + if (anObject(step).done) { + if (IS_TO_ARRAY) { + target.length = counter; + resolve(target); + } else resolve(IS_SOME ? false : IS_EVERY || undefined); + } else { + var value = step.value; + try { + if (MAPPING) { + var result = fn(value, counter); + + var handler = function ($result) { + if (IS_FOR_EACH) { + loop(); + } else if (IS_EVERY) { + $result ? loop() : closeAsyncIteration(iterator, resolve, false, reject); + } else if (IS_TO_ARRAY) { + try { + target[counter++] = $result; + loop(); + } catch (error4) { ifAbruptCloseAsyncIterator(error4); } + } else { + $result ? closeAsyncIteration(iterator, resolve, IS_SOME || value, reject) : loop(); + } + }; + + if (isObject(result)) Promise.resolve(result).then(handler, ifAbruptCloseAsyncIterator); + else handler(result); + } else { + target[counter++] = value; + loop(); + } + } catch (error3) { ifAbruptCloseAsyncIterator(error3); } + } + } catch (error2) { reject(error2); } + }, reject); + } catch (error) { reject(error); } + }; + + loop(); + }); + }; +}; + +module.exports = { + // `AsyncIterator.prototype.toArray` / `Array.fromAsync` methods + toArray: createMethod(0), + // `AsyncIterator.prototype.forEach` method + forEach: createMethod(1), + // `AsyncIterator.prototype.every` method + every: createMethod(2), + // `AsyncIterator.prototype.some` method + some: createMethod(3), + // `AsyncIterator.prototype.find` method + find: createMethod(4) +}; + + +/***/ }), +/* 232 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var getBuiltIn = __webpack_require__(35); +var getMethod = __webpack_require__(37); + +module.exports = function (iterator, method, argument, reject) { + try { + var returnMethod = getMethod(iterator, 'return'); + if (returnMethod) { + return getBuiltIn('Promise').resolve(call(returnMethod, iterator)).then(function () { + method(argument); + }, function (error) { + reject(error); + }); + } + } catch (error2) { + return reject(error2); + } method(argument); +}; + + +/***/ }), +/* 233 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// https://github.com/tc39/proposal-async-explicit-resource-management +var $ = __webpack_require__(49); +var DESCRIPTORS = __webpack_require__(24); +var getBuiltIn = __webpack_require__(35); +var aCallable = __webpack_require__(38); +var anInstance = __webpack_require__(145); +var defineBuiltIn = __webpack_require__(51); +var defineBuiltIns = __webpack_require__(146); +var defineBuiltInAccessor = __webpack_require__(131); +var wellKnownSymbol = __webpack_require__(13); +var InternalStateModule = __webpack_require__(55); +var addDisposableResource = __webpack_require__(147); +var V8_VERSION = __webpack_require__(20); + +var Promise = getBuiltIn('Promise'); +var SuppressedError = getBuiltIn('SuppressedError'); +var $ReferenceError = ReferenceError; + +var ASYNC_DISPOSE = wellKnownSymbol('asyncDispose'); +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); + +var ASYNC_DISPOSABLE_STACK = 'AsyncDisposableStack'; +var setInternalState = InternalStateModule.set; +var getAsyncDisposableStackInternalState = InternalStateModule.getterFor(ASYNC_DISPOSABLE_STACK); + +var HINT = 'async-dispose'; +var DISPOSED = 'disposed'; +var PENDING = 'pending'; + +var getPendingAsyncDisposableStackInternalState = function (stack) { + var internalState = getAsyncDisposableStackInternalState(stack); + if (internalState.state === DISPOSED) throw new $ReferenceError(ASYNC_DISPOSABLE_STACK + ' already disposed'); + return internalState; +}; + +var $AsyncDisposableStack = function AsyncDisposableStack() { + setInternalState(anInstance(this, AsyncDisposableStackPrototype), { + type: ASYNC_DISPOSABLE_STACK, + state: PENDING, + stack: [] + }); + + if (!DESCRIPTORS) this.disposed = false; +}; + +var AsyncDisposableStackPrototype = $AsyncDisposableStack.prototype; + +defineBuiltIns(AsyncDisposableStackPrototype, { + disposeAsync: function disposeAsync() { + var asyncDisposableStack = this; + return new Promise(function (resolve, reject) { + var internalState = getAsyncDisposableStackInternalState(asyncDisposableStack); + if (internalState.state === DISPOSED) return resolve(undefined); + internalState.state = DISPOSED; + if (!DESCRIPTORS) asyncDisposableStack.disposed = true; + var stack = internalState.stack; + var i = stack.length; + var thrown = false; + var suppressed; + + var handleError = function (result) { + if (thrown) { + suppressed = new SuppressedError(result, suppressed); + } else { + thrown = true; + suppressed = result; + } + + loop(); + }; + + var loop = function () { + if (i) { + var disposeMethod = stack[--i]; + stack[i] = null; + try { + Promise.resolve(disposeMethod()).then(loop, handleError); + } catch (error) { + handleError(error); + } + } else { + internalState.stack = null; + thrown ? reject(suppressed) : resolve(undefined); + } + }; + + loop(); + }); + }, + use: function use(value) { + addDisposableResource(getPendingAsyncDisposableStackInternalState(this), value, HINT); + return value; + }, + adopt: function adopt(value, onDispose) { + var internalState = getPendingAsyncDisposableStackInternalState(this); + aCallable(onDispose); + addDisposableResource(internalState, undefined, HINT, function () { + return onDispose(value); + }); + return value; + }, + defer: function defer(onDispose) { + var internalState = getPendingAsyncDisposableStackInternalState(this); + aCallable(onDispose); + addDisposableResource(internalState, undefined, HINT, onDispose); + }, + move: function move() { + var internalState = getPendingAsyncDisposableStackInternalState(this); + var newAsyncDisposableStack = new $AsyncDisposableStack(); + getAsyncDisposableStackInternalState(newAsyncDisposableStack).stack = internalState.stack; + internalState.stack = []; + internalState.state = DISPOSED; + if (!DESCRIPTORS) this.disposed = true; + return newAsyncDisposableStack; + } +}); + +if (DESCRIPTORS) defineBuiltInAccessor(AsyncDisposableStackPrototype, 'disposed', { + configurable: true, + get: function disposed() { + return getAsyncDisposableStackInternalState(this).state === DISPOSED; + } +}); + +defineBuiltIn(AsyncDisposableStackPrototype, ASYNC_DISPOSE, AsyncDisposableStackPrototype.disposeAsync, { name: 'disposeAsync' }); +defineBuiltIn(AsyncDisposableStackPrototype, TO_STRING_TAG, ASYNC_DISPOSABLE_STACK, { nonWritable: true }); + +// https://github.com/tc39/proposal-explicit-resource-management/issues/256 +// can't be detected synchronously +var SYNC_DISPOSE_RETURNING_PROMISE_RESOLUTION_BUG = V8_VERSION && V8_VERSION < 136; + +$({ global: true, constructor: true, forced: SYNC_DISPOSE_RETURNING_PROMISE_RESOLUTION_BUG }, { + AsyncDisposableStack: $AsyncDisposableStack +}); + + +/***/ }), +/* 234 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// https://github.com/tc39/proposal-async-explicit-resource-management +var call = __webpack_require__(33); +var defineBuiltIn = __webpack_require__(51); +var getBuiltIn = __webpack_require__(35); +var getMethod = __webpack_require__(37); +var hasOwn = __webpack_require__(5); +var wellKnownSymbol = __webpack_require__(13); +var AsyncIteratorPrototype = __webpack_require__(230); + +var ASYNC_DISPOSE = wellKnownSymbol('asyncDispose'); +var Promise = getBuiltIn('Promise'); + +if (!hasOwn(AsyncIteratorPrototype, ASYNC_DISPOSE)) { + defineBuiltIn(AsyncIteratorPrototype, ASYNC_DISPOSE, function () { + var O = this; + return new Promise(function (resolve, reject) { + var $return = getMethod(O, 'return'); + if ($return) { + Promise.resolve(call($return, O)).then(function () { + resolve(undefined); + }, reject); + } else resolve(undefined); + }); + }); +} + + +/***/ }), +/* 235 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var setToStringTag = __webpack_require__(195); + +$({ global: true }, { Reflect: {} }); + +// Reflect[@@toStringTag] property +// https://tc39.es/ecma262/#sec-reflect-@@tostringtag +setToStringTag(globalThis.Reflect, 'Reflect', true); + + +/***/ }), +/* 236 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var aString = __webpack_require__(237); +var hasOwn = __webpack_require__(5); +var padStart = __webpack_require__(238).start; +var WHITESPACES = __webpack_require__(240); + +var $Array = Array; +var $escape = RegExp.escape; +var charAt = uncurryThis(''.charAt); +var charCodeAt = uncurryThis(''.charCodeAt); +var numberToString = uncurryThis(1.1.toString); +var join = uncurryThis([].join); +var FIRST_DIGIT_OR_ASCII = /^[0-9a-z]/i; +var SYNTAX_SOLIDUS = /^[$()*+./?[\\\]^{|}]/; +var OTHER_PUNCTUATORS_AND_WHITESPACES = RegExp('^[!"#%&\',\\-:;<=>@`~' + WHITESPACES + ']'); +var exec = uncurryThis(FIRST_DIGIT_OR_ASCII.exec); + +var ControlEscape = { + '\u0009': 't', + '\u000A': 'n', + '\u000B': 'v', + '\u000C': 'f', + '\u000D': 'r' +}; + +var escapeChar = function (chr) { + var hex = numberToString(charCodeAt(chr, 0), 16); + return hex.length < 3 ? '\\x' + padStart(hex, 2, '0') : '\\u' + padStart(hex, 4, '0'); +}; + +// Avoiding the use of polyfills of the previous iteration of this proposal +var FORCED = !$escape || $escape('ab') !== '\\x61b'; + +// `RegExp.escape` method +// https://tc39.es/ecma262/#sec-regexp.escape +$({ target: 'RegExp', stat: true, forced: FORCED }, { + escape: function escape(S) { + aString(S); + var length = S.length; + var result = $Array(length); + + for (var i = 0; i < length; i++) { + var chr = charAt(S, i); + if (i === 0 && exec(FIRST_DIGIT_OR_ASCII, chr)) { + result[i] = escapeChar(chr); + } else if (hasOwn(ControlEscape, chr)) { + result[i] = '\\' + ControlEscape[chr]; + } else if (exec(SYNTAX_SOLIDUS, chr)) { + result[i] = '\\' + chr; + } else if (exec(OTHER_PUNCTUATORS_AND_WHITESPACES, chr)) { + result[i] = escapeChar(chr); + } else { + var charCode = charCodeAt(chr, 0); + // single UTF-16 code unit + if ((charCode & 0xF800) !== 0xD800) result[i] = chr; + // unpaired surrogate + else if (charCode >= 0xDC00 || i + 1 >= length || (charCodeAt(S, i + 1) & 0xFC00) !== 0xDC00) result[i] = escapeChar(chr); + // surrogate pair + else { + result[i] = chr; + result[++i] = charAt(S, i); + } + } + } + + return join(result, ''); + } +}); + + +/***/ }), +/* 237 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $TypeError = TypeError; + +module.exports = function (argument) { + if (typeof argument == 'string') return argument; + throw new $TypeError('Argument is not a string'); +}; + + +/***/ }), +/* 238 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var toLength = __webpack_require__(68); +var toString = __webpack_require__(81); +var $repeat = __webpack_require__(239); +var requireObjectCoercible = __webpack_require__(10); + +var repeat = uncurryThis($repeat); +var stringSlice = uncurryThis(''.slice); +var ceil = Math.ceil; + +// `String.prototype.{ padStart, padEnd }` methods implementation +var createMethod = function (IS_END) { + return function ($this, maxLength, fillString) { + var S = toString(requireObjectCoercible($this)); + var intMaxLength = toLength(maxLength); + var stringLength = S.length; + var fillStr = fillString === undefined ? ' ' : toString(fillString); + var fillLen, stringFiller; + if (intMaxLength <= stringLength || fillStr === '') return S; + fillLen = intMaxLength - stringLength; + stringFiller = repeat(fillStr, ceil(fillLen / fillStr.length)); + if (stringFiller.length > fillLen) stringFiller = stringSlice(stringFiller, 0, fillLen); + return IS_END ? S + stringFiller : stringFiller + S; + }; +}; + +module.exports = { + // `String.prototype.padStart` method + // https://tc39.es/ecma262/#sec-string.prototype.padstart + start: createMethod(false), + // `String.prototype.padEnd` method + // https://tc39.es/ecma262/#sec-string.prototype.padend + end: createMethod(true) +}; + + +/***/ }), +/* 239 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toIntegerOrInfinity = __webpack_require__(65); +var toString = __webpack_require__(81); +var requireObjectCoercible = __webpack_require__(10); + +var $RangeError = RangeError; + +// `String.prototype.repeat` method implementation +// https://tc39.es/ecma262/#sec-string.prototype.repeat +module.exports = function repeat(count) { + var str = toString(requireObjectCoercible(this)); + var result = ''; + var n = toIntegerOrInfinity(count); + if (n < 0 || n === Infinity) throw new $RangeError('Wrong number of repetitions'); + for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) result += str; + return result; +}; + + +/***/ }), +/* 240 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// a string of all valid unicode whitespaces +module.exports = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' + + '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; + + +/***/ }), +/* 241 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var defineBuiltInAccessor = __webpack_require__(131); +var regExpFlagsDetection = __webpack_require__(242); +var regExpFlagsGetterImplementation = __webpack_require__(243); + +// `RegExp.prototype.flags` getter +// https://tc39.es/ecma262/#sec-get-regexp.prototype.flags +if (DESCRIPTORS && !regExpFlagsDetection.correct) { + defineBuiltInAccessor(RegExp.prototype, 'flags', { + configurable: true, + get: regExpFlagsGetterImplementation + }); + + regExpFlagsDetection.correct = true; +} + + +/***/ }), +/* 242 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var fails = __webpack_require__(8); + +// babel-minify and Closure Compiler transpiles RegExp('.', 'd') -> /./d and it causes SyntaxError +var RegExp = globalThis.RegExp; + +var FLAGS_GETTER_IS_CORRECT = !fails(function () { + var INDICES_SUPPORT = true; + try { + RegExp('.', 'd'); + } catch (error) { + INDICES_SUPPORT = false; + } + + var O = {}; + // modern V8 bug + var calls = ''; + var expected = INDICES_SUPPORT ? 'dgimsy' : 'gimsy'; + + var addGetter = function (key, chr) { + // eslint-disable-next-line es/no-object-defineproperty -- safe + Object.defineProperty(O, key, { get: function () { + calls += chr; + return true; + } }); + }; + + var pairs = { + dotAll: 's', + global: 'g', + ignoreCase: 'i', + multiline: 'm', + sticky: 'y' + }; + + if (INDICES_SUPPORT) pairs.hasIndices = 'd'; + + for (var key in pairs) addGetter(key, pairs[key]); + + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + var result = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call(O); + + return result !== expected || calls !== expected; +}); + +module.exports = { correct: FLAGS_GETTER_IS_CORRECT }; + + +/***/ }), +/* 243 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var anObject = __webpack_require__(30); + +// `RegExp.prototype.flags` getter implementation +// https://tc39.es/ecma262/#sec-get-regexp.prototype.flags +module.exports = function () { + var that = anObject(this); + var result = ''; + if (that.hasIndices) result += 'd'; + if (that.global) result += 'g'; + if (that.ignoreCase) result += 'i'; + if (that.multiline) result += 'm'; + if (that.dotAll) result += 's'; + if (that.unicode) result += 'u'; + if (that.unicodeSets) result += 'v'; + if (that.sticky) result += 'y'; + return result; +}; + + +/***/ }), +/* 244 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var difference = __webpack_require__(245); +var fails = __webpack_require__(8); +var setMethodAcceptSetLike = __webpack_require__(253); + +var SET_LIKE_INCORRECT_BEHAVIOR = !setMethodAcceptSetLike('difference', function (result) { + return result.size === 0; +}); + +var FORCED = SET_LIKE_INCORRECT_BEHAVIOR || fails(function () { + // https://bugs.webkit.org/show_bug.cgi?id=288595 + var setLike = { + size: 1, + has: function () { return true; }, + keys: function () { + var index = 0; + return { + next: function () { + var done = index++ > 1; + if (baseSet.has(1)) baseSet.clear(); + return { done: done, value: 2 }; + } + }; + } + }; + // eslint-disable-next-line es/no-set -- testing + var baseSet = new Set([1, 2, 3, 4]); + // eslint-disable-next-line es/no-set-prototype-difference -- testing + return baseSet.difference(setLike).size !== 3; +}); + +// `Set.prototype.difference` method +// https://tc39.es/ecma262/#sec-set.prototype.difference +$({ target: 'Set', proto: true, real: true, forced: FORCED }, { + difference: difference +}); + + +/***/ }), +/* 245 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aSet = __webpack_require__(246); +var SetHelpers = __webpack_require__(247); +var clone = __webpack_require__(248); +var size = __webpack_require__(251); +var getSetRecord = __webpack_require__(252); +var iterateSet = __webpack_require__(249); +var iterateSimple = __webpack_require__(250); + +var has = SetHelpers.has; +var remove = SetHelpers.remove; + +// `Set.prototype.difference` method +// https://tc39.es/ecma262/#sec-set.prototype.difference +module.exports = function difference(other) { + var O = aSet(this); + var otherRec = getSetRecord(other); + var result = clone(O); + if (size(O) <= otherRec.size) iterateSet(O, function (e) { + if (otherRec.includes(e)) remove(result, e); + }); + else iterateSimple(otherRec.getIterator(), function (e) { + if (has(result, e)) remove(result, e); + }); + return result; +}; + + +/***/ }), +/* 246 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var has = __webpack_require__(247).has; + +// Perform ? RequireInternalSlot(M, [[SetData]]) +module.exports = function (it) { + has(it); + return it; +}; + + +/***/ }), +/* 247 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +// eslint-disable-next-line es/no-set -- safe +var SetPrototype = Set.prototype; + +module.exports = { + // eslint-disable-next-line es/no-set -- safe + Set: Set, + add: uncurryThis(SetPrototype.add), + has: uncurryThis(SetPrototype.has), + remove: uncurryThis(SetPrototype['delete']), + proto: SetPrototype +}; + + +/***/ }), +/* 248 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var SetHelpers = __webpack_require__(247); +var iterate = __webpack_require__(249); + +var Set = SetHelpers.Set; +var add = SetHelpers.add; + +module.exports = function (set) { + var result = new Set(); + iterate(set, function (it) { + add(result, it); + }); + return result; +}; + + +/***/ }), +/* 249 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var iterateSimple = __webpack_require__(250); +var SetHelpers = __webpack_require__(247); + +var Set = SetHelpers.Set; +var SetPrototype = SetHelpers.proto; +var forEach = uncurryThis(SetPrototype.forEach); +var keys = uncurryThis(SetPrototype.keys); +var next = keys(new Set()).next; + +module.exports = function (set, fn, interruptible) { + return interruptible ? iterateSimple({ iterator: keys(set), next: next }, fn) : forEach(set, fn); +}; + + +/***/ }), +/* 250 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); + +module.exports = function (record, fn, ITERATOR_INSTEAD_OF_RECORD) { + var iterator = ITERATOR_INSTEAD_OF_RECORD ? record : record.iterator; + var next = record.next; + var step, result; + while (!(step = call(next, iterator)).done) { + result = fn(step.value); + if (result !== undefined) return result; + } +}; + + +/***/ }), +/* 251 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThisAccessor = __webpack_require__(75); +var SetHelpers = __webpack_require__(247); + +module.exports = uncurryThisAccessor(SetHelpers.proto, 'size', 'get') || function (set) { + return set.size; +}; + + +/***/ }), +/* 252 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var call = __webpack_require__(33); +var toIntegerOrInfinity = __webpack_require__(65); +var getIteratorDirect = __webpack_require__(157); + +var INVALID_SIZE = 'Invalid size'; +var $RangeError = RangeError; +var $TypeError = TypeError; +var max = Math.max; + +var SetRecord = function (set, intSize) { + this.set = set; + this.size = max(intSize, 0); + this.has = aCallable(set.has); + this.keys = aCallable(set.keys); +}; + +SetRecord.prototype = { + getIterator: function () { + return getIteratorDirect(anObject(call(this.keys, this.set))); + }, + includes: function (it) { + return call(this.has, this.set, it); + } +}; + +// `GetSetRecord` abstract operation +// https://tc39.es/proposal-set-methods/#sec-getsetrecord +module.exports = function (obj) { + anObject(obj); + var numSize = +obj.size; + // NOTE: If size is undefined, then numSize will be NaN + // eslint-disable-next-line no-self-compare -- NaN check + if (numSize !== numSize) throw new $TypeError(INVALID_SIZE); + var intSize = toIntegerOrInfinity(numSize); + if (intSize < 0) throw new $RangeError(INVALID_SIZE); + return new SetRecord(obj, intSize); +}; + + +/***/ }), +/* 253 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); + +var createSetLike = function (size) { + return { + size: size, + has: function () { + return false; + }, + keys: function () { + return { + next: function () { + return { done: true }; + } + }; + } + }; +}; + +var createSetLikeWithInfinitySize = function (size) { + return { + size: size, + has: function () { + return true; + }, + keys: function () { + throw new Error('e'); + } + }; +}; + +module.exports = function (name, callback) { + var Set = getBuiltIn('Set'); + try { + new Set()[name](createSetLike(0)); + try { + // late spec change, early WebKit ~ Safari 17 implementation does not pass it + // https://github.com/tc39/proposal-set-methods/pull/88 + // also covered engines with + // https://bugs.webkit.org/show_bug.cgi?id=272679 + new Set()[name](createSetLike(-1)); + return false; + } catch (error2) { + if (!callback) return true; + // early V8 implementation bug + // https://issues.chromium.org/issues/351332634 + try { + new Set()[name](createSetLikeWithInfinitySize(-Infinity)); + return false; + } catch (error) { + var set = new Set([1, 2]); + return callback(set[name](createSetLikeWithInfinitySize(Infinity))); + } + } + } catch (error) { + return false; + } +}; + + +/***/ }), +/* 254 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var fails = __webpack_require__(8); +var intersection = __webpack_require__(255); +var setMethodAcceptSetLike = __webpack_require__(253); + +var INCORRECT = !setMethodAcceptSetLike('intersection', function (result) { + return result.size === 2 && result.has(1) && result.has(2); +}) || fails(function () { + // eslint-disable-next-line es/no-array-from, es/no-set, es/no-set-prototype-intersection -- testing + return String(Array.from(new Set([1, 2, 3]).intersection(new Set([3, 2])))) !== '3,2'; +}); + +// `Set.prototype.intersection` method +// https://tc39.es/ecma262/#sec-set.prototype.intersection +$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, { + intersection: intersection +}); + + +/***/ }), +/* 255 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aSet = __webpack_require__(246); +var SetHelpers = __webpack_require__(247); +var size = __webpack_require__(251); +var getSetRecord = __webpack_require__(252); +var iterateSet = __webpack_require__(249); +var iterateSimple = __webpack_require__(250); + +var Set = SetHelpers.Set; +var add = SetHelpers.add; +var has = SetHelpers.has; + +// `Set.prototype.intersection` method +// https://tc39.es/ecma262/#sec-set.prototype.intersection +module.exports = function intersection(other) { + var O = aSet(this); + var otherRec = getSetRecord(other); + var result = new Set(); + + if (size(O) > otherRec.size) { + iterateSimple(otherRec.getIterator(), function (e) { + if (has(O, e)) add(result, e); + }); + } else { + iterateSet(O, function (e) { + if (otherRec.includes(e)) add(result, e); + }); + } + + return result; +}; + + +/***/ }), +/* 256 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isDisjointFrom = __webpack_require__(257); +var setMethodAcceptSetLike = __webpack_require__(253); + +var INCORRECT = !setMethodAcceptSetLike('isDisjointFrom', function (result) { + return !result; +}); + +// `Set.prototype.isDisjointFrom` method +// https://tc39.es/ecma262/#sec-set.prototype.isdisjointfrom +$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, { + isDisjointFrom: isDisjointFrom +}); + + +/***/ }), +/* 257 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aSet = __webpack_require__(246); +var has = __webpack_require__(247).has; +var size = __webpack_require__(251); +var getSetRecord = __webpack_require__(252); +var iterateSet = __webpack_require__(249); +var iterateSimple = __webpack_require__(250); +var iteratorClose = __webpack_require__(104); + +// `Set.prototype.isDisjointFrom` method +// https://tc39.es/ecma262/#sec-set.prototype.isdisjointfrom +module.exports = function isDisjointFrom(other) { + var O = aSet(this); + var otherRec = getSetRecord(other); + if (size(O) <= otherRec.size) return iterateSet(O, function (e) { + if (otherRec.includes(e)) return false; + }, true) !== false; + var iterator = otherRec.getIterator(); + return iterateSimple(iterator, function (e) { + if (has(O, e)) return iteratorClose(iterator, 'normal', false); + }) !== false; +}; + + +/***/ }), +/* 258 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isSubsetOf = __webpack_require__(259); +var setMethodAcceptSetLike = __webpack_require__(253); + +var INCORRECT = !setMethodAcceptSetLike('isSubsetOf', function (result) { + return result; +}); + +// `Set.prototype.isSubsetOf` method +// https://tc39.es/ecma262/#sec-set.prototype.issubsetof +$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, { + isSubsetOf: isSubsetOf +}); + + +/***/ }), +/* 259 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aSet = __webpack_require__(246); +var size = __webpack_require__(251); +var iterate = __webpack_require__(249); +var getSetRecord = __webpack_require__(252); + +// `Set.prototype.isSubsetOf` method +// https://tc39.es/ecma262/#sec-set.prototype.issubsetof +module.exports = function isSubsetOf(other) { + var O = aSet(this); + var otherRec = getSetRecord(other); + if (size(O) > otherRec.size) return false; + return iterate(O, function (e) { + if (!otherRec.includes(e)) return false; + }, true) !== false; +}; + + +/***/ }), +/* 260 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isSupersetOf = __webpack_require__(261); +var setMethodAcceptSetLike = __webpack_require__(253); + +var INCORRECT = !setMethodAcceptSetLike('isSupersetOf', function (result) { + return !result; +}); + +// `Set.prototype.isSupersetOf` method +// https://tc39.es/ecma262/#sec-set.prototype.issupersetof +$({ target: 'Set', proto: true, real: true, forced: INCORRECT }, { + isSupersetOf: isSupersetOf +}); + + +/***/ }), +/* 261 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aSet = __webpack_require__(246); +var has = __webpack_require__(247).has; +var size = __webpack_require__(251); +var getSetRecord = __webpack_require__(252); +var iterateSimple = __webpack_require__(250); +var iteratorClose = __webpack_require__(104); + +// `Set.prototype.isSupersetOf` method +// https://tc39.es/ecma262/#sec-set.prototype.issupersetof +module.exports = function isSupersetOf(other) { + var O = aSet(this); + var otherRec = getSetRecord(other); + if (size(O) < otherRec.size) return false; + var iterator = otherRec.getIterator(); + return iterateSimple(iterator, function (e) { + if (!has(O, e)) return iteratorClose(iterator, 'normal', false); + }) !== false; +}; + + +/***/ }), +/* 262 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var symmetricDifference = __webpack_require__(263); +var setMethodGetKeysBeforeCloning = __webpack_require__(264); +var setMethodAcceptSetLike = __webpack_require__(253); + +var FORCED = !setMethodAcceptSetLike('symmetricDifference') || !setMethodGetKeysBeforeCloning('symmetricDifference'); + +// `Set.prototype.symmetricDifference` method +// https://tc39.es/ecma262/#sec-set.prototype.symmetricdifference +$({ target: 'Set', proto: true, real: true, forced: FORCED }, { + symmetricDifference: symmetricDifference +}); + + +/***/ }), +/* 263 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aSet = __webpack_require__(246); +var SetHelpers = __webpack_require__(247); +var clone = __webpack_require__(248); +var getSetRecord = __webpack_require__(252); +var iterateSimple = __webpack_require__(250); + +var add = SetHelpers.add; +var has = SetHelpers.has; +var remove = SetHelpers.remove; + +// `Set.prototype.symmetricDifference` method +// https://tc39.es/ecma262/#sec-set.prototype.symmetricdifference +module.exports = function symmetricDifference(other) { + var O = aSet(this); + var keysIter = getSetRecord(other).getIterator(); + var result = clone(O); + iterateSimple(keysIter, function (e) { + if (has(O, e)) remove(result, e); + else add(result, e); + }); + return result; +}; + + +/***/ }), +/* 264 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// Should get iterator record of a set-like object before cloning this +// https://bugs.webkit.org/show_bug.cgi?id=289430 +module.exports = function (METHOD_NAME) { + try { + // eslint-disable-next-line es/no-set -- needed for test + var baseSet = new Set(); + var setLike = { + size: 0, + has: function () { return true; }, + keys: function () { + // eslint-disable-next-line es/no-object-defineproperty -- needed for test + return Object.defineProperty({}, 'next', { + get: function () { + baseSet.clear(); + baseSet.add(4); + return function () { + return { done: true }; + }; + } + }); + } + }; + var result = baseSet[METHOD_NAME](setLike); + + return result.size === 1 && result.values().next().value === 4; + } catch (error) { + return false; + } +}; + + +/***/ }), +/* 265 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var union = __webpack_require__(266); +var setMethodGetKeysBeforeCloning = __webpack_require__(264); +var setMethodAcceptSetLike = __webpack_require__(253); + +var FORCED = !setMethodAcceptSetLike('union') || !setMethodGetKeysBeforeCloning('union'); + +// `Set.prototype.union` method +// https://tc39.es/ecma262/#sec-set.prototype.union +$({ target: 'Set', proto: true, real: true, forced: FORCED }, { + union: union +}); + + +/***/ }), +/* 266 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aSet = __webpack_require__(246); +var add = __webpack_require__(247).add; +var clone = __webpack_require__(248); +var getSetRecord = __webpack_require__(252); +var iterateSimple = __webpack_require__(250); + +// `Set.prototype.union` method +// https://tc39.es/ecma262/#sec-set.prototype.union +module.exports = function union(other) { + var O = aSet(this); + var keysIter = getSetRecord(other).getIterator(); + var result = clone(O); + iterateSimple(keysIter, function (it) { + add(result, it); + }); + return result; +}; + + +/***/ }), +/* 267 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var requireObjectCoercible = __webpack_require__(10); +var toIntegerOrInfinity = __webpack_require__(65); +var toString = __webpack_require__(81); +var fails = __webpack_require__(8); + +var charAt = uncurryThis(''.charAt); + +var FORCED = fails(function () { + // eslint-disable-next-line es/no-string-prototype-at -- safe + return '𠮷'.at(-2) !== '\uD842'; +}); + +// `String.prototype.at` method +// https://tc39.es/ecma262/#sec-string.prototype.at +$({ target: 'String', proto: true, forced: FORCED }, { + at: function at(index) { + var S = toString(requireObjectCoercible(this)); + var len = S.length; + var relativeIndex = toIntegerOrInfinity(index); + var k = relativeIndex >= 0 ? relativeIndex : len + relativeIndex; + return (k < 0 || k >= len) ? undefined : charAt(S, k); + } +}); + + +/***/ }), +/* 268 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var requireObjectCoercible = __webpack_require__(10); +var toString = __webpack_require__(81); + +var charCodeAt = uncurryThis(''.charCodeAt); + +// `String.prototype.isWellFormed` method +// https://tc39.es/ecma262/#sec-string.prototype.iswellformed +$({ target: 'String', proto: true }, { + isWellFormed: function isWellFormed() { + var S = toString(requireObjectCoercible(this)); + var length = S.length; + for (var i = 0; i < length; i++) { + var charCode = charCodeAt(S, i); + // single UTF-16 code unit + if ((charCode & 0xF800) !== 0xD800) continue; + // unpaired surrogate + if (charCode >= 0xDC00 || ++i >= length || (charCodeAt(S, i) & 0xFC00) !== 0xDC00) return false; + } return true; + } +}); + + +/***/ }), +/* 269 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var uncurryThis = __webpack_require__(6); +var requireObjectCoercible = __webpack_require__(10); +var isCallable = __webpack_require__(28); +var isObject = __webpack_require__(27); +var isRegExp = __webpack_require__(270); +var toString = __webpack_require__(81); +var getMethod = __webpack_require__(37); +var getRegExpFlags = __webpack_require__(271); +var getSubstitution = __webpack_require__(272); +var wellKnownSymbol = __webpack_require__(13); +var IS_PURE = __webpack_require__(16); + +var REPLACE = wellKnownSymbol('replace'); +var $TypeError = TypeError; +var indexOf = uncurryThis(''.indexOf); +var replace = uncurryThis(''.replace); +var stringSlice = uncurryThis(''.slice); +var max = Math.max; + +// `String.prototype.replaceAll` method +// https://tc39.es/ecma262/#sec-string.prototype.replaceall +$({ target: 'String', proto: true }, { + replaceAll: function replaceAll(searchValue, replaceValue) { + var O = requireObjectCoercible(this); + var IS_REG_EXP, flags, replacer, string, searchString, functionalReplace, searchLength, advanceBy, position, replacement; + var endOfLastMatch = 0; + var result = ''; + if (isObject(searchValue)) { + IS_REG_EXP = isRegExp(searchValue); + if (IS_REG_EXP) { + flags = toString(requireObjectCoercible(getRegExpFlags(searchValue))); + if (!~indexOf(flags, 'g')) throw new $TypeError('`.replaceAll` does not allow non-global regexes'); + } + replacer = getMethod(searchValue, REPLACE); + if (replacer) return call(replacer, searchValue, O, replaceValue); + if (IS_PURE && IS_REG_EXP) return replace(toString(O), searchValue, replaceValue); + } + string = toString(O); + searchString = toString(searchValue); + functionalReplace = isCallable(replaceValue); + if (!functionalReplace) replaceValue = toString(replaceValue); + searchLength = searchString.length; + advanceBy = max(1, searchLength); + position = indexOf(string, searchString); + while (position !== -1) { + replacement = functionalReplace + ? toString(replaceValue(searchString, position, string)) + : getSubstitution(searchString, string, position, [], undefined, replaceValue); + result += stringSlice(string, endOfLastMatch, position) + replacement; + endOfLastMatch = position + searchLength; + position = position + advanceBy > string.length ? -1 : indexOf(string, searchString, position + advanceBy); + } + if (endOfLastMatch < string.length) { + result += stringSlice(string, endOfLastMatch); + } + return result; + } +}); + + +/***/ }), +/* 270 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isObject = __webpack_require__(27); +var classof = __webpack_require__(46); +var wellKnownSymbol = __webpack_require__(13); + +var MATCH = wellKnownSymbol('match'); + +// `IsRegExp` abstract operation +// https://tc39.es/ecma262/#sec-isregexp +module.exports = function (it) { + var isRegExp; + return isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : classof(it) === 'RegExp'); +}; + + +/***/ }), +/* 271 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var hasOwn = __webpack_require__(5); +var isPrototypeOf = __webpack_require__(36); +var regExpFlagsDetection = __webpack_require__(242); +var regExpFlagsGetterImplementation = __webpack_require__(243); + +var RegExpPrototype = RegExp.prototype; + +module.exports = regExpFlagsDetection.correct ? function (it) { + return it.flags; +} : function (it) { + return (!regExpFlagsDetection.correct && isPrototypeOf(RegExpPrototype, it) && !hasOwn(it, 'flags')) + ? call(regExpFlagsGetterImplementation, it) + : it.flags; +}; + + +/***/ }), +/* 272 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var toObject = __webpack_require__(9); + +var floor = Math.floor; +var charAt = uncurryThis(''.charAt); +var replace = uncurryThis(''.replace); +var stringSlice = uncurryThis(''.slice); +// eslint-disable-next-line redos/no-vulnerable -- safe +var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g; +var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g; + +// `GetSubstitution` abstract operation +// https://tc39.es/ecma262/#sec-getsubstitution +module.exports = function (matched, str, position, captures, namedCaptures, replacement) { + var tailPos = position + matched.length; + var m = captures.length; + var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED; + if (namedCaptures !== undefined) { + namedCaptures = toObject(namedCaptures); + symbols = SUBSTITUTION_SYMBOLS; + } + return replace(replacement, symbols, function (match, ch) { + var capture; + switch (charAt(ch, 0)) { + case '$': return '$'; + case '&': return matched; + case '`': return stringSlice(str, 0, position); + case "'": return stringSlice(str, tailPos); + case '<': + capture = namedCaptures[stringSlice(ch, 1, -1)]; + break; + default: // \d\d? + var n = +ch; + if (n === 0) return match; + if (n > m) { + var f = floor(n / 10); + if (f === 0) return match; + if (f <= m) return captures[f - 1] === undefined ? charAt(ch, 1) : captures[f - 1] + charAt(ch, 1); + return match; + } + capture = captures[n - 1]; + } + return capture === undefined ? '' : capture; + }); +}; + + +/***/ }), +/* 273 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var uncurryThis = __webpack_require__(6); +var requireObjectCoercible = __webpack_require__(10); +var toString = __webpack_require__(81); +var fails = __webpack_require__(8); + +var $Array = Array; +var charAt = uncurryThis(''.charAt); +var charCodeAt = uncurryThis(''.charCodeAt); +var join = uncurryThis([].join); +// eslint-disable-next-line es/no-string-prototype-towellformed -- safe +var $toWellFormed = ''.toWellFormed; +var REPLACEMENT_CHARACTER = '\uFFFD'; + +// Safari bug +var TO_STRING_CONVERSION_BUG = $toWellFormed && fails(function () { + return call($toWellFormed, 1) !== '1'; +}); + +// `String.prototype.toWellFormed` method +// https://tc39.es/ecma262/#sec-string.prototype.towellformed +$({ target: 'String', proto: true, forced: TO_STRING_CONVERSION_BUG }, { + toWellFormed: function toWellFormed() { + var S = toString(requireObjectCoercible(this)); + if (TO_STRING_CONVERSION_BUG) return call($toWellFormed, S); + var length = S.length; + var result = $Array(length); + for (var i = 0; i < length; i++) { + var charCode = charCodeAt(S, i); + // single UTF-16 code unit + if ((charCode & 0xF800) !== 0xD800) result[i] = charAt(S, i); + // unpaired surrogate + else if (charCode >= 0xDC00 || i + 1 >= length || (charCodeAt(S, i + 1) & 0xFC00) !== 0xDC00) result[i] = REPLACEMENT_CHARACTER; + // surrogate pair + else { + result[i] = charAt(S, i); + result[++i] = charAt(S, i); + } + } return join(result, ''); + } +}); + + +/***/ }), +/* 274 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ArrayBufferViewCore = __webpack_require__(275); +var lengthOfArrayLike = __webpack_require__(67); +var toIntegerOrInfinity = __webpack_require__(65); + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; + +// `%TypedArray%.prototype.at` method +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.at +exportTypedArrayMethod('at', function at(index) { + var O = aTypedArray(this); + var len = lengthOfArrayLike(O); + var relativeIndex = toIntegerOrInfinity(index); + var k = relativeIndex >= 0 ? relativeIndex : len + relativeIndex; + return (k < 0 || k >= len) ? undefined : O[k]; +}); + + +/***/ }), +/* 275 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var NATIVE_ARRAY_BUFFER = __webpack_require__(133); +var DESCRIPTORS = __webpack_require__(24); +var globalThis = __webpack_require__(2); +var isCallable = __webpack_require__(28); +var isObject = __webpack_require__(27); +var hasOwn = __webpack_require__(5); +var classof = __webpack_require__(82); +var tryToString = __webpack_require__(39); +var createNonEnumerableProperty = __webpack_require__(50); +var defineBuiltIn = __webpack_require__(51); +var defineBuiltInAccessor = __webpack_require__(131); +var isPrototypeOf = __webpack_require__(36); +var getPrototypeOf = __webpack_require__(91); +var setPrototypeOf = __webpack_require__(74); +var wellKnownSymbol = __webpack_require__(13); +var uid = __webpack_require__(18); +var InternalStateModule = __webpack_require__(55); + +var enforceInternalState = InternalStateModule.enforce; +var getInternalState = InternalStateModule.get; +var Int8Array = globalThis.Int8Array; +var Int8ArrayPrototype = Int8Array && Int8Array.prototype; +var Uint8ClampedArray = globalThis.Uint8ClampedArray; +var Uint8ClampedArrayPrototype = Uint8ClampedArray && Uint8ClampedArray.prototype; +var TypedArray = Int8Array && getPrototypeOf(Int8Array); +var TypedArrayPrototype = Int8ArrayPrototype && getPrototypeOf(Int8ArrayPrototype); +var ObjectPrototype = Object.prototype; +var TypeError = globalThis.TypeError; + +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); +var TYPED_ARRAY_TAG = uid('TYPED_ARRAY_TAG'); +var TYPED_ARRAY_CONSTRUCTOR = 'TypedArrayConstructor'; +// Fixing native typed arrays in Opera Presto crashes the browser, see #595 +var NATIVE_ARRAY_BUFFER_VIEWS = NATIVE_ARRAY_BUFFER && !!setPrototypeOf && classof(globalThis.opera) !== 'Opera'; +var TYPED_ARRAY_TAG_REQUIRED = false; +var NAME, Constructor, Prototype; + +var TypedArrayConstructorsList = { + Int8Array: 1, + Uint8Array: 1, + Uint8ClampedArray: 1, + Int16Array: 2, + Uint16Array: 2, + Int32Array: 4, + Uint32Array: 4, + Float32Array: 4, + Float64Array: 8 +}; + +var BigIntArrayConstructorsList = { + BigInt64Array: 8, + BigUint64Array: 8 +}; + +var isView = function isView(it) { + if (!isObject(it)) return false; + var klass = classof(it); + return klass === 'DataView' + || hasOwn(TypedArrayConstructorsList, klass) + || hasOwn(BigIntArrayConstructorsList, klass); +}; + +var getTypedArrayConstructor = function (it) { + var proto = getPrototypeOf(it); + if (!isObject(proto)) return; + var state = getInternalState(proto); + return (state && hasOwn(state, TYPED_ARRAY_CONSTRUCTOR)) ? state[TYPED_ARRAY_CONSTRUCTOR] : getTypedArrayConstructor(proto); +}; + +var isTypedArray = function (it) { + if (!isObject(it)) return false; + var klass = classof(it); + return hasOwn(TypedArrayConstructorsList, klass) + || hasOwn(BigIntArrayConstructorsList, klass); +}; + +var aTypedArray = function (it) { + if (isTypedArray(it)) return it; + throw new TypeError('Target is not a typed array'); +}; + +var aTypedArrayConstructor = function (C) { + if (isCallable(C) && (!setPrototypeOf || isPrototypeOf(TypedArray, C))) return C; + throw new TypeError(tryToString(C) + ' is not a typed array constructor'); +}; + +var exportTypedArrayMethod = function (KEY, property, forced, options) { + if (!DESCRIPTORS) return; + if (forced) for (var ARRAY in TypedArrayConstructorsList) { + var TypedArrayConstructor = globalThis[ARRAY]; + if (TypedArrayConstructor && hasOwn(TypedArrayConstructor.prototype, KEY)) try { + delete TypedArrayConstructor.prototype[KEY]; + } catch (error) { + // old WebKit bug - some methods are non-configurable + try { + TypedArrayConstructor.prototype[KEY] = property; + } catch (error2) { /* empty */ } + } + } + if (!TypedArrayPrototype[KEY] || forced) { + defineBuiltIn(TypedArrayPrototype, KEY, forced ? property + : NATIVE_ARRAY_BUFFER_VIEWS && Int8ArrayPrototype[KEY] || property, options); + } +}; + +var exportTypedArrayStaticMethod = function (KEY, property, forced) { + var ARRAY, TypedArrayConstructor; + if (!DESCRIPTORS) return; + if (setPrototypeOf) { + if (forced) for (ARRAY in TypedArrayConstructorsList) { + TypedArrayConstructor = globalThis[ARRAY]; + if (TypedArrayConstructor && hasOwn(TypedArrayConstructor, KEY)) try { + delete TypedArrayConstructor[KEY]; + } catch (error) { /* empty */ } + } + if (!TypedArray[KEY] || forced) { + // V8 ~ Chrome 49-50 `%TypedArray%` methods are non-writable non-configurable + try { + return defineBuiltIn(TypedArray, KEY, forced ? property : NATIVE_ARRAY_BUFFER_VIEWS && TypedArray[KEY] || property); + } catch (error) { /* empty */ } + } else return; + } + for (ARRAY in TypedArrayConstructorsList) { + TypedArrayConstructor = globalThis[ARRAY]; + if (TypedArrayConstructor && (!TypedArrayConstructor[KEY] || forced)) { + defineBuiltIn(TypedArrayConstructor, KEY, property); + } + } +}; + +for (NAME in TypedArrayConstructorsList) { + Constructor = globalThis[NAME]; + Prototype = Constructor && Constructor.prototype; + if (Prototype) enforceInternalState(Prototype)[TYPED_ARRAY_CONSTRUCTOR] = Constructor; + else NATIVE_ARRAY_BUFFER_VIEWS = false; +} + +for (NAME in BigIntArrayConstructorsList) { + Constructor = globalThis[NAME]; + Prototype = Constructor && Constructor.prototype; + if (Prototype) enforceInternalState(Prototype)[TYPED_ARRAY_CONSTRUCTOR] = Constructor; +} + +// WebKit bug - typed arrays constructors prototype is Object.prototype +if (!NATIVE_ARRAY_BUFFER_VIEWS || !isCallable(TypedArray) || TypedArray === Function.prototype) { + // eslint-disable-next-line no-shadow -- safe + TypedArray = function TypedArray() { + throw new TypeError('Incorrect invocation'); + }; + if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) { + if (globalThis[NAME]) setPrototypeOf(globalThis[NAME], TypedArray); + } +} + +if (!NATIVE_ARRAY_BUFFER_VIEWS || !TypedArrayPrototype || TypedArrayPrototype === ObjectPrototype) { + TypedArrayPrototype = TypedArray.prototype; + if (NATIVE_ARRAY_BUFFER_VIEWS) for (NAME in TypedArrayConstructorsList) { + if (globalThis[NAME]) setPrototypeOf(globalThis[NAME].prototype, TypedArrayPrototype); + } +} + +// WebKit bug - one more object in Uint8ClampedArray prototype chain +if (NATIVE_ARRAY_BUFFER_VIEWS && getPrototypeOf(Uint8ClampedArrayPrototype) !== TypedArrayPrototype) { + setPrototypeOf(Uint8ClampedArrayPrototype, TypedArrayPrototype); +} + +if (DESCRIPTORS && !hasOwn(TypedArrayPrototype, TO_STRING_TAG)) { + TYPED_ARRAY_TAG_REQUIRED = true; + defineBuiltInAccessor(TypedArrayPrototype, TO_STRING_TAG, { + configurable: true, + get: function () { + return isObject(this) ? this[TYPED_ARRAY_TAG] : undefined; + } + }); + for (NAME in TypedArrayConstructorsList) if (globalThis[NAME]) { + createNonEnumerableProperty(globalThis[NAME], TYPED_ARRAY_TAG, NAME); + } +} + +module.exports = { + NATIVE_ARRAY_BUFFER_VIEWS: NATIVE_ARRAY_BUFFER_VIEWS, + TYPED_ARRAY_TAG: TYPED_ARRAY_TAG_REQUIRED && TYPED_ARRAY_TAG, + aTypedArray: aTypedArray, + aTypedArrayConstructor: aTypedArrayConstructor, + exportTypedArrayMethod: exportTypedArrayMethod, + exportTypedArrayStaticMethod: exportTypedArrayStaticMethod, + getTypedArrayConstructor: getTypedArrayConstructor, + isView: isView, + isTypedArray: isTypedArray, + TypedArray: TypedArray, + TypedArrayPrototype: TypedArrayPrototype +}; + + +/***/ }), +/* 276 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ArrayBufferViewCore = __webpack_require__(275); +var $findLast = __webpack_require__(110).findLast; + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; + +// `%TypedArray%.prototype.findLast` method +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.findlast +exportTypedArrayMethod('findLast', function findLast(predicate /* , thisArg */) { + return $findLast(aTypedArray(this), predicate, arguments.length > 1 ? arguments[1] : undefined); +}); + + +/***/ }), +/* 277 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ArrayBufferViewCore = __webpack_require__(275); +var $findLastIndex = __webpack_require__(110).findLastIndex; + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; + +// `%TypedArray%.prototype.findLastIndex` method +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.findlastindex +exportTypedArrayMethod('findLastIndex', function findLastIndex(predicate /* , thisArg */) { + return $findLastIndex(aTypedArray(this), predicate, arguments.length > 1 ? arguments[1] : undefined); +}); + + +/***/ }), +/* 278 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var call = __webpack_require__(33); +var ArrayBufferViewCore = __webpack_require__(275); +var lengthOfArrayLike = __webpack_require__(67); +var toOffset = __webpack_require__(279); +var toIndexedObject = __webpack_require__(9); +var fails = __webpack_require__(8); + +var RangeError = globalThis.RangeError; +var Int8Array = globalThis.Int8Array; +var Int8ArrayPrototype = Int8Array && Int8Array.prototype; +var $set = Int8ArrayPrototype && Int8ArrayPrototype.set; +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; + +var WORKS_WITH_OBJECTS_AND_GENERIC_ON_TYPED_ARRAYS = !fails(function () { + // eslint-disable-next-line es/no-typed-arrays -- required for testing + var array = new Uint8ClampedArray(2); + call($set, array, { length: 1, 0: 3 }, 1); + return array[1] !== 3; +}); + +// https://bugs.chromium.org/p/v8/issues/detail?id=11294 and other +var TO_OBJECT_BUG = WORKS_WITH_OBJECTS_AND_GENERIC_ON_TYPED_ARRAYS && ArrayBufferViewCore.NATIVE_ARRAY_BUFFER_VIEWS && fails(function () { + var array = new Int8Array(2); + array.set(1); + array.set('2', 1); + return array[0] !== 0 || array[1] !== 2; +}); + +// `%TypedArray%.prototype.set` method +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.set +exportTypedArrayMethod('set', function set(arrayLike /* , offset */) { + aTypedArray(this); + var offset = toOffset(arguments.length > 1 ? arguments[1] : undefined, 1); + var src = toIndexedObject(arrayLike); + if (WORKS_WITH_OBJECTS_AND_GENERIC_ON_TYPED_ARRAYS) return call($set, this, src, offset); + var length = this.length; + var len = lengthOfArrayLike(src); + var index = 0; + if (len + offset > length) throw new RangeError('Wrong length'); + while (index < len) this[offset + index] = src[index++]; +}, !WORKS_WITH_OBJECTS_AND_GENERIC_ON_TYPED_ARRAYS || TO_OBJECT_BUG); + + +/***/ }), +/* 279 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toPositiveInteger = __webpack_require__(159); + +var $RangeError = RangeError; + +module.exports = function (it, BYTES) { + var offset = toPositiveInteger(it); + if (offset % BYTES) throw new $RangeError('Wrong offset'); + return offset; +}; + + +/***/ }), +/* 280 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var arrayToReversed = __webpack_require__(117); +var ArrayBufferViewCore = __webpack_require__(275); + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; +var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor; + +// `%TypedArray%.prototype.toReversed` method +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.toreversed +exportTypedArrayMethod('toReversed', function toReversed() { + return arrayToReversed(aTypedArray(this), getTypedArrayConstructor(this)); +}); + + +/***/ }), +/* 281 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ArrayBufferViewCore = __webpack_require__(275); +var uncurryThis = __webpack_require__(6); +var aCallable = __webpack_require__(38); +var arrayFromConstructorAndList = __webpack_require__(119); + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; +var sort = uncurryThis(ArrayBufferViewCore.TypedArrayPrototype.sort); + +// `%TypedArray%.prototype.toSorted` method +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.tosorted +exportTypedArrayMethod('toSorted', function toSorted(compareFn) { + if (compareFn !== undefined) aCallable(compareFn); + var O = aTypedArray(this); + var A = arrayFromConstructorAndList(getTypedArrayConstructor(O), O); + return sort(A, compareFn); +}); + + +/***/ }), +/* 282 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var arrayWith = __webpack_require__(123); +var ArrayBufferViewCore = __webpack_require__(275); +var isBigIntArray = __webpack_require__(283); +var toIntegerOrInfinity = __webpack_require__(65); +var toBigInt = __webpack_require__(284); + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; + +var PROPER_ORDER = function () { + try { + // eslint-disable-next-line no-throw-literal, es/no-typed-arrays, es/no-array-prototype-with -- required for testing + new Int8Array(1)['with'](2, { valueOf: function () { throw 8; } }); + } catch (error) { + // some early implementations, like WebKit, does not follow the final semantic + // https://github.com/tc39/proposal-change-array-by-copy/pull/86 + return error === 8; + } +}(); + +// Bug in WebKit. It should truncate a negative fractional index to zero, but instead throws an error +var THROW_ON_NEGATIVE_FRACTIONAL_INDEX = PROPER_ORDER && function () { + try { + // eslint-disable-next-line es/no-typed-arrays, es/no-array-prototype-with -- required for testing + new Int8Array(1)['with'](-0.5, 1); + } catch (error) { + return true; + } +}(); + +// `%TypedArray%.prototype.with` method +// https://tc39.es/ecma262/#sec-%typedarray%.prototype.with +exportTypedArrayMethod('with', { 'with': function (index, value) { + var O = aTypedArray(this); + var relativeIndex = toIntegerOrInfinity(index); + var actualValue = isBigIntArray(O) ? toBigInt(value) : +value; + return arrayWith(O, getTypedArrayConstructor(O), relativeIndex, actualValue); +} }['with'], !PROPER_ORDER || THROW_ON_NEGATIVE_FRACTIONAL_INDEX); + + +/***/ }), +/* 283 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var classof = __webpack_require__(82); + +module.exports = function (it) { + var klass = classof(it); + return klass === 'BigInt64Array' || klass === 'BigUint64Array'; +}; + + +/***/ }), +/* 284 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var toPrimitive = __webpack_require__(32); + +var $TypeError = TypeError; + +// `ToBigInt` abstract operation +// https://tc39.es/ecma262/#sec-tobigint +module.exports = function (argument) { + var prim = toPrimitive(argument, 'number'); + if (typeof prim == 'number') throw new $TypeError("Can't convert number to bigint"); + // eslint-disable-next-line es/no-bigint -- safe + return BigInt(prim); +}; + + +/***/ }), +/* 285 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var arrayFromConstructorAndList = __webpack_require__(119); +var $fromBase64 = __webpack_require__(286); + +var Uint8Array = globalThis.Uint8Array; + +var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array || !Uint8Array.fromBase64 || !function () { + // Webkit not throw an error on odd length string + try { + Uint8Array.fromBase64('a'); + return; + } catch (error) { /* empty */ } + try { + Uint8Array.fromBase64('', null); + } catch (error) { + return true; + } +}(); + +// `Uint8Array.fromBase64` method +// https://github.com/tc39/proposal-arraybuffer-base64 +if (Uint8Array) $({ target: 'Uint8Array', stat: true, forced: INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS }, { + fromBase64: function fromBase64(string /* , options */) { + var result = $fromBase64(string, arguments.length > 1 ? arguments[1] : undefined, null, 0x1FFFFFFFFFFFFF); + return arrayFromConstructorAndList(Uint8Array, result.bytes); + } +}); + + +/***/ }), +/* 286 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var uncurryThis = __webpack_require__(6); +var anObjectOrUndefined = __webpack_require__(287); +var aString = __webpack_require__(237); +var hasOwn = __webpack_require__(5); +var base64Map = __webpack_require__(288); +var getAlphabetOption = __webpack_require__(289); +var notDetached = __webpack_require__(137); + +var base64Alphabet = base64Map.c2i; +var base64UrlAlphabet = base64Map.c2iUrl; + +var SyntaxError = globalThis.SyntaxError; +var TypeError = globalThis.TypeError; +var at = uncurryThis(''.charAt); + +var skipAsciiWhitespace = function (string, index) { + var length = string.length; + for (;index < length; index++) { + var chr = at(string, index); + if (chr !== ' ' && chr !== '\t' && chr !== '\n' && chr !== '\f' && chr !== '\r') break; + } return index; +}; + +var decodeBase64Chunk = function (chunk, alphabet, throwOnExtraBits) { + var chunkLength = chunk.length; + + if (chunkLength < 4) { + chunk += chunkLength === 2 ? 'AA' : 'A'; + } + + var triplet = (alphabet[at(chunk, 0)] << 18) + + (alphabet[at(chunk, 1)] << 12) + + (alphabet[at(chunk, 2)] << 6) + + alphabet[at(chunk, 3)]; + + var chunkBytes = [ + (triplet >> 16) & 255, + (triplet >> 8) & 255, + triplet & 255 + ]; + + if (chunkLength === 2) { + if (throwOnExtraBits && chunkBytes[1] !== 0) { + throw new SyntaxError('Extra bits'); + } + return [chunkBytes[0]]; + } + + if (chunkLength === 3) { + if (throwOnExtraBits && chunkBytes[2] !== 0) { + throw new SyntaxError('Extra bits'); + } + return [chunkBytes[0], chunkBytes[1]]; + } + + return chunkBytes; +}; + +var writeBytes = function (bytes, elements, written) { + var elementsLength = elements.length; + for (var index = 0; index < elementsLength; index++) { + bytes[written + index] = elements[index]; + } + return written + elementsLength; +}; + +/* eslint-disable max-statements, max-depth -- TODO */ +module.exports = function (string, options, into, maxLength) { + aString(string); + anObjectOrUndefined(options); + var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet; + var lastChunkHandling = options ? options.lastChunkHandling : undefined; + + if (lastChunkHandling === undefined) lastChunkHandling = 'loose'; + + if (lastChunkHandling !== 'loose' && lastChunkHandling !== 'strict' && lastChunkHandling !== 'stop-before-partial') { + throw new TypeError('Incorrect `lastChunkHandling` option'); + } + + if (into) notDetached(into.buffer); + + var stringLength = string.length; + var bytes = into || []; + var written = 0; + var read = 0; + var chunk = ''; + var index = 0; + + if (maxLength) while (true) { + index = skipAsciiWhitespace(string, index); + if (index === stringLength) { + if (chunk.length > 0) { + if (lastChunkHandling === 'stop-before-partial') { + break; + } + if (lastChunkHandling === 'loose') { + if (chunk.length === 1) { + throw new SyntaxError('Malformed padding: exactly one additional character'); + } + written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); + } else { + throw new SyntaxError('Missing padding'); + } + } + read = stringLength; + break; + } + var chr = at(string, index); + ++index; + if (chr === '=') { + if (chunk.length < 2) { + throw new SyntaxError('Padding is too early'); + } + index = skipAsciiWhitespace(string, index); + if (chunk.length === 2) { + if (index === stringLength) { + if (lastChunkHandling === 'stop-before-partial') { + break; + } + throw new SyntaxError('Malformed padding: only one ='); + } + if (at(string, index) === '=') { + ++index; + index = skipAsciiWhitespace(string, index); + } + } + if (index < stringLength) { + throw new SyntaxError('Unexpected character after padding'); + } + written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, lastChunkHandling === 'strict'), written); + read = stringLength; + break; + } + if (!hasOwn(alphabet, chr)) { + throw new SyntaxError('Unexpected character'); + } + var remainingBytes = maxLength - written; + if (remainingBytes === 1 && chunk.length === 2 || remainingBytes === 2 && chunk.length === 3) { + // special case: we can fit exactly the number of bytes currently represented by chunk, so we were just checking for `=` + break; + } + + chunk += chr; + if (chunk.length === 4) { + written = writeBytes(bytes, decodeBase64Chunk(chunk, alphabet, false), written); + chunk = ''; + read = index; + if (written === maxLength) { + break; + } + } + } + + return { bytes: bytes, read: read, written: written }; +}; + + +/***/ }), +/* 287 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isObject = __webpack_require__(27); + +var $String = String; +var $TypeError = TypeError; + +module.exports = function (argument) { + if (argument === undefined || isObject(argument)) return argument; + throw new $TypeError($String(argument) + ' is not an object or undefined'); +}; + + +/***/ }), +/* 288 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var commonAlphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; +var base64Alphabet = commonAlphabet + '+/'; +var base64UrlAlphabet = commonAlphabet + '-_'; + +var inverse = function (characters) { + // TODO: use `Object.create(null)` in `core-js@4` + var result = {}; + var index = 0; + for (; index < 64; index++) result[characters.charAt(index)] = index; + return result; +}; + +module.exports = { + i2c: base64Alphabet, + c2i: inverse(base64Alphabet), + i2cUrl: base64UrlAlphabet, + c2iUrl: inverse(base64UrlAlphabet) +}; + + +/***/ }), +/* 289 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $TypeError = TypeError; + +module.exports = function (options) { + var alphabet = options && options.alphabet; + if (alphabet === undefined || alphabet === 'base64' || alphabet === 'base64url') return alphabet || 'base64'; + throw new $TypeError('Incorrect `alphabet` option'); +}; + + +/***/ }), +/* 290 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var aString = __webpack_require__(237); +var $fromHex = __webpack_require__(291); + +// `Uint8Array.fromHex` method +// https://github.com/tc39/proposal-arraybuffer-base64 +if (globalThis.Uint8Array) $({ target: 'Uint8Array', stat: true }, { + fromHex: function fromHex(string) { + return $fromHex(aString(string)).bytes; + } +}); + + +/***/ }), +/* 291 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var uncurryThis = __webpack_require__(6); + +var Uint8Array = globalThis.Uint8Array; +var SyntaxError = globalThis.SyntaxError; +var parseInt = globalThis.parseInt; +var min = Math.min; +var NOT_HEX = /[^\da-f]/i; +var exec = uncurryThis(NOT_HEX.exec); +var stringSlice = uncurryThis(''.slice); + +module.exports = function (string, into) { + var stringLength = string.length; + if (stringLength % 2 !== 0) throw new SyntaxError('String should be an even number of characters'); + var maxLength = into ? min(into.length, stringLength / 2) : stringLength / 2; + var bytes = into || new Uint8Array(maxLength); + var read = 0; + var written = 0; + while (written < maxLength) { + var hexits = stringSlice(string, read, read += 2); + if (exec(NOT_HEX, hexits)) throw new SyntaxError('String should only contain hex characters'); + bytes[written++] = parseInt(hexits, 16); + } + return { bytes: bytes, read: read }; +}; + + +/***/ }), +/* 292 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var $fromBase64 = __webpack_require__(286); +var anUint8Array = __webpack_require__(293); + +var Uint8Array = globalThis.Uint8Array; + +var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array || !Uint8Array.prototype.setFromBase64 || !function () { + var target = new Uint8Array([255, 255, 255, 255, 255]); + try { + target.setFromBase64('', null); + return; + } catch (error) { /* empty */ } + // Webkit not throw an error on odd length string + try { + target.setFromBase64('a'); + return; + } catch (error) { /* empty */ } + try { + target.setFromBase64('MjYyZg==='); + } catch (error) { + return target[0] === 50 && target[1] === 54 && target[2] === 50 && target[3] === 255 && target[4] === 255; + } +}(); + +// `Uint8Array.prototype.setFromBase64` method +// https://github.com/tc39/proposal-arraybuffer-base64 +if (Uint8Array) $({ target: 'Uint8Array', proto: true, forced: INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS }, { + setFromBase64: function setFromBase64(string /* , options */) { + anUint8Array(this); + + var result = $fromBase64(string, arguments.length > 1 ? arguments[1] : undefined, this, this.length); + + return { read: result.read, written: result.written }; + } +}); + + +/***/ }), +/* 293 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var classof = __webpack_require__(82); + +var $TypeError = TypeError; + +// Perform ? RequireInternalSlot(argument, [[TypedArrayName]]) +// If argument.[[TypedArrayName]] is not "Uint8Array", throw a TypeError exception +module.exports = function (argument) { + if (classof(argument) === 'Uint8Array') return argument; + throw new $TypeError('Argument is not an Uint8Array'); +}; + + +/***/ }), +/* 294 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var aString = __webpack_require__(237); +var anUint8Array = __webpack_require__(293); +var notDetached = __webpack_require__(137); +var $fromHex = __webpack_require__(291); + +// `Uint8Array.prototype.setFromHex` method +// https://github.com/tc39/proposal-arraybuffer-base64 +if (globalThis.Uint8Array) $({ target: 'Uint8Array', proto: true }, { + setFromHex: function setFromHex(string) { + anUint8Array(this); + aString(string); + notDetached(this.buffer); + var read = $fromHex(string, this).read; + return { read: read, written: read / 2 }; + } +}); + + +/***/ }), +/* 295 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var uncurryThis = __webpack_require__(6); +var anObjectOrUndefined = __webpack_require__(287); +var anUint8Array = __webpack_require__(293); +var notDetached = __webpack_require__(137); +var base64Map = __webpack_require__(288); +var getAlphabetOption = __webpack_require__(289); + +var base64Alphabet = base64Map.i2c; +var base64UrlAlphabet = base64Map.i2cUrl; + +var charAt = uncurryThis(''.charAt); + +var Uint8Array = globalThis.Uint8Array; + +var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array || !Uint8Array.prototype.toBase64 || !function () { + try { + var target = new Uint8Array(); + target.toBase64(null); + } catch (error) { + return true; + } +}(); + +// `Uint8Array.prototype.toBase64` method +// https://github.com/tc39/proposal-arraybuffer-base64 +if (Uint8Array) $({ target: 'Uint8Array', proto: true, forced: INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS }, { + toBase64: function toBase64(/* options */) { + var array = anUint8Array(this); + var options = arguments.length ? anObjectOrUndefined(arguments[0]) : undefined; + var alphabet = getAlphabetOption(options) === 'base64' ? base64Alphabet : base64UrlAlphabet; + var omitPadding = !!options && !!options.omitPadding; + notDetached(this.buffer); + + var result = ''; + var i = 0; + var length = array.length; + var triplet; + + var at = function (shift) { + return charAt(alphabet, (triplet >> (6 * shift)) & 63); + }; + + for (; i + 2 < length; i += 3) { + triplet = (array[i] << 16) + (array[i + 1] << 8) + array[i + 2]; + result += at(3) + at(2) + at(1) + at(0); + } + if (i + 2 === length) { + triplet = (array[i] << 16) + (array[i + 1] << 8); + result += at(3) + at(2) + at(1) + (omitPadding ? '' : '='); + } else if (i + 1 === length) { + triplet = array[i] << 16; + result += at(3) + at(2) + (omitPadding ? '' : '=='); + } + + return result; + } +}); + + +/***/ }), +/* 296 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var uncurryThis = __webpack_require__(6); +var anUint8Array = __webpack_require__(293); +var notDetached = __webpack_require__(137); + +var numberToString = uncurryThis(1.1.toString); + +var Uint8Array = globalThis.Uint8Array; + +var INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS = !Uint8Array || !Uint8Array.prototype.toHex || !(function () { + try { + var target = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]); + return target.toHex() === 'ffffffffffffffff'; + } catch (error) { + return false; + } +})(); + +// `Uint8Array.prototype.toHex` method +// https://github.com/tc39/proposal-arraybuffer-base64 +if (Uint8Array) $({ target: 'Uint8Array', proto: true, forced: INCORRECT_BEHAVIOR_OR_DOESNT_EXISTS }, { + toHex: function toHex() { + anUint8Array(this); + notDetached(this.buffer); + var result = ''; + for (var i = 0, length = this.length; i < length; i++) { + var hex = numberToString(this[i], 16); + result += hex.length === 1 ? '0' + hex : hex; + } + return result; + } +}); + + +/***/ }), +/* 297 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $filterReject = __webpack_require__(298).filterReject; +var addToUnscopables = __webpack_require__(108); + +// `Array.prototype.filterReject` method +// https://github.com/tc39/proposal-array-filtering +$({ target: 'Array', proto: true, forced: true }, { + filterReject: function filterReject(callbackfn /* , thisArg */) { + return $filterReject(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); + +addToUnscopables('filterReject'); + + +/***/ }), +/* 298 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var bind = __webpack_require__(98); +var uncurryThis = __webpack_require__(6); +var IndexedObject = __webpack_require__(45); +var toObject = __webpack_require__(9); +var lengthOfArrayLike = __webpack_require__(67); +var arraySpeciesCreate = __webpack_require__(299); + +var push = uncurryThis([].push); + +// `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterReject }` methods implementation +var createMethod = function (TYPE) { + var IS_MAP = TYPE === 1; + var IS_FILTER = TYPE === 2; + var IS_SOME = TYPE === 3; + var IS_EVERY = TYPE === 4; + var IS_FIND_INDEX = TYPE === 6; + var IS_FILTER_REJECT = TYPE === 7; + var NO_HOLES = TYPE === 5 || IS_FIND_INDEX; + return function ($this, callbackfn, that, specificCreate) { + var O = toObject($this); + var self = IndexedObject(O); + var length = lengthOfArrayLike(self); + var boundFunction = bind(callbackfn, that); + var index = 0; + var create = specificCreate || arraySpeciesCreate; + var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined; + var value, result; + for (;length > index; index++) if (NO_HOLES || index in self) { + value = self[index]; + result = boundFunction(value, index, O); + if (TYPE) { + if (IS_MAP) target[index] = result; // map + else if (result) switch (TYPE) { + case 3: return true; // some + case 5: return value; // find + case 6: return index; // findIndex + case 2: push(target, value); // filter + } else switch (TYPE) { + case 4: return false; // every + case 7: push(target, value); // filterReject + } + } + } + return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target; + }; +}; + +module.exports = { + // `Array.prototype.forEach` method + // https://tc39.es/ecma262/#sec-array.prototype.foreach + forEach: createMethod(0), + // `Array.prototype.map` method + // https://tc39.es/ecma262/#sec-array.prototype.map + map: createMethod(1), + // `Array.prototype.filter` method + // https://tc39.es/ecma262/#sec-array.prototype.filter + filter: createMethod(2), + // `Array.prototype.some` method + // https://tc39.es/ecma262/#sec-array.prototype.some + some: createMethod(3), + // `Array.prototype.every` method + // https://tc39.es/ecma262/#sec-array.prototype.every + every: createMethod(4), + // `Array.prototype.find` method + // https://tc39.es/ecma262/#sec-array.prototype.find + find: createMethod(5), + // `Array.prototype.findIndex` method + // https://tc39.es/ecma262/#sec-array.prototype.findIndex + findIndex: createMethod(6), + // `Array.prototype.filterReject` method + // https://github.com/tc39/proposal-array-filtering + filterReject: createMethod(7) +}; + + +/***/ }), +/* 299 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var arraySpeciesConstructor = __webpack_require__(300); + +// `ArraySpeciesCreate` abstract operation +// https://tc39.es/ecma262/#sec-arrayspeciescreate +module.exports = function (originalArray, length) { + return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length); +}; + + +/***/ }), +/* 300 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var isArray = __webpack_require__(114); +var isConstructor = __webpack_require__(199); +var isObject = __webpack_require__(27); +var wellKnownSymbol = __webpack_require__(13); + +var SPECIES = wellKnownSymbol('species'); +var $Array = Array; + +// a part of `ArraySpeciesCreate` abstract operation +// https://tc39.es/ecma262/#sec-arrayspeciescreate +module.exports = function (originalArray) { + var C; + if (isArray(originalArray)) { + C = originalArray.constructor; + // cross-realm fallback + if (isConstructor(C) && (C === $Array || isArray(C.prototype))) C = undefined; + else if (isObject(C)) { + C = C[SPECIES]; + if (C === null) C = undefined; + } + } return C === undefined ? $Array : C; +}; + + +/***/ }), +/* 301 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $group = __webpack_require__(302); +var addToUnscopables = __webpack_require__(108); + +// `Array.prototype.group` method +// https://github.com/tc39/proposal-array-grouping +$({ target: 'Array', proto: true }, { + group: function group(callbackfn /* , thisArg */) { + var thisArg = arguments.length > 1 ? arguments[1] : undefined; + return $group(this, callbackfn, thisArg); + } +}); + +addToUnscopables('group'); + + +/***/ }), +/* 302 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var bind = __webpack_require__(98); +var uncurryThis = __webpack_require__(6); +var IndexedObject = __webpack_require__(45); +var toObject = __webpack_require__(9); +var toPropertyKey = __webpack_require__(31); +var lengthOfArrayLike = __webpack_require__(67); +var objectCreate = __webpack_require__(93); +var arrayFromConstructorAndList = __webpack_require__(119); + +var $Array = Array; +var push = uncurryThis([].push); + +module.exports = function ($this, callbackfn, that, specificConstructor) { + var O = toObject($this); + var self = IndexedObject(O); + var boundFunction = bind(callbackfn, that); + var target = objectCreate(null); + var length = lengthOfArrayLike(self); + var index = 0; + var Constructor, key, value; + for (;length > index; index++) { + value = self[index]; + key = toPropertyKey(boundFunction(value, index, O)); + // in some IE versions, `hasOwnProperty` returns incorrect result on integer keys + // but since it's a `null` prototype object, we can safely use `in` + if (key in target) push(target[key], value); + else target[key] = [value]; + } + // TODO: Remove this block from `core-js@4` + if (specificConstructor) { + Constructor = specificConstructor(O); + if (Constructor !== $Array) { + for (key in target) target[key] = arrayFromConstructorAndList(Constructor, target[key]); + } + } return target; +}; + + +/***/ }), +/* 303 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var $group = __webpack_require__(302); +var arrayMethodIsStrict = __webpack_require__(304); +var addToUnscopables = __webpack_require__(108); + +// `Array.prototype.groupBy` method +// https://github.com/tc39/proposal-array-grouping +// https://bugs.webkit.org/show_bug.cgi?id=236541 +$({ target: 'Array', proto: true, forced: !arrayMethodIsStrict('groupBy') }, { + groupBy: function groupBy(callbackfn /* , thisArg */) { + var thisArg = arguments.length > 1 ? arguments[1] : undefined; + return $group(this, callbackfn, thisArg); + } +}); + +addToUnscopables('groupBy'); + + +/***/ }), +/* 304 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); + +module.exports = function (METHOD_NAME, argument) { + var method = [][METHOD_NAME]; + return !!method && fails(function () { + // eslint-disable-next-line no-useless-call -- required for testing + method.call(null, argument || function () { return 1; }, 1); + }); +}; + + +/***/ }), +/* 305 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var arrayMethodIsStrict = __webpack_require__(304); +var addToUnscopables = __webpack_require__(108); +var $groupToMap = __webpack_require__(306); +var IS_PURE = __webpack_require__(16); + +// `Array.prototype.groupByToMap` method +// https://github.com/tc39/proposal-array-grouping +// https://bugs.webkit.org/show_bug.cgi?id=236541 +$({ target: 'Array', proto: true, name: 'groupToMap', forced: IS_PURE || !arrayMethodIsStrict('groupByToMap') }, { + groupByToMap: $groupToMap +}); + +addToUnscopables('groupByToMap'); + + +/***/ }), +/* 306 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var bind = __webpack_require__(98); +var uncurryThis = __webpack_require__(6); +var IndexedObject = __webpack_require__(45); +var toObject = __webpack_require__(9); +var lengthOfArrayLike = __webpack_require__(67); +var MapHelpers = __webpack_require__(185); + +var Map = MapHelpers.Map; +var mapGet = MapHelpers.get; +var mapHas = MapHelpers.has; +var mapSet = MapHelpers.set; +var push = uncurryThis([].push); + +// `Array.prototype.groupToMap` method +// https://github.com/tc39/proposal-array-grouping +module.exports = function groupToMap(callbackfn /* , thisArg */) { + var O = toObject(this); + var self = IndexedObject(O); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var map = new Map(); + var length = lengthOfArrayLike(self); + var index = 0; + var key, value; + for (;length > index; index++) { + value = self[index]; + key = boundFunction(value, index, O); + if (mapHas(map, key)) push(mapGet(map, key), value); + else mapSet(map, key, [value]); + } return map; +}; + + +/***/ }), +/* 307 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var addToUnscopables = __webpack_require__(108); +var $groupToMap = __webpack_require__(306); +var IS_PURE = __webpack_require__(16); + +// `Array.prototype.groupToMap` method +// https://github.com/tc39/proposal-array-grouping +$({ target: 'Array', proto: true, forced: IS_PURE }, { + groupToMap: $groupToMap +}); + +addToUnscopables('groupToMap'); + + +/***/ }), +/* 308 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isArray = __webpack_require__(114); + +// eslint-disable-next-line es/no-object-isfrozen -- safe +var isFrozen = Object.isFrozen; + +var isFrozenStringArray = function (array, allowUndefined) { + if (!isFrozen || !isArray(array) || !isFrozen(array)) return false; + var index = 0; + var length = array.length; + var element; + while (index < length) { + element = array[index++]; + if (!(typeof element == 'string' || (allowUndefined && element === undefined))) { + return false; + } + } return length !== 0; +}; + +// `Array.isTemplateObject` method +// https://github.com/tc39/proposal-array-is-template-object +$({ target: 'Array', stat: true, sham: true, forced: true }, { + isTemplateObject: function isTemplateObject(value) { + if (!isFrozenStringArray(value, true)) return false; + var raw = value.raw; + return raw.length === value.length && isFrozenStringArray(raw, false); + } +}); + + +/***/ }), +/* 309 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var DESCRIPTORS = __webpack_require__(24); +var addToUnscopables = __webpack_require__(108); +var toObject = __webpack_require__(9); +var lengthOfArrayLike = __webpack_require__(67); +var defineBuiltInAccessor = __webpack_require__(131); + +// `Array.prototype.lastIndex` getter +// https://github.com/tc39/proposal-array-last +if (DESCRIPTORS) { + defineBuiltInAccessor(Array.prototype, 'lastIndex', { + configurable: true, + get: function lastIndex() { + var O = toObject(this); + var len = lengthOfArrayLike(O); + return len === 0 ? 0 : len - 1; + } + }); + + addToUnscopables('lastIndex'); +} + + +/***/ }), +/* 310 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var DESCRIPTORS = __webpack_require__(24); +var addToUnscopables = __webpack_require__(108); +var toObject = __webpack_require__(9); +var lengthOfArrayLike = __webpack_require__(67); +var defineBuiltInAccessor = __webpack_require__(131); + +// `Array.prototype.lastIndex` accessor +// https://github.com/tc39/proposal-array-last +if (DESCRIPTORS) { + defineBuiltInAccessor(Array.prototype, 'lastItem', { + configurable: true, + get: function lastItem() { + var O = toObject(this); + var len = lengthOfArrayLike(O); + return len === 0 ? undefined : O[len - 1]; + }, + set: function lastItem(value) { + var O = toObject(this); + var len = lengthOfArrayLike(O); + return O[len === 0 ? 0 : len - 1] = value; + } + }); + + addToUnscopables('lastItem'); +} + + +/***/ }), +/* 311 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var addToUnscopables = __webpack_require__(108); +var uniqueBy = __webpack_require__(312); + +// `Array.prototype.uniqueBy` method +// https://github.com/tc39/proposal-array-unique +$({ target: 'Array', proto: true, forced: true }, { + uniqueBy: uniqueBy +}); + +addToUnscopables('uniqueBy'); + + +/***/ }), +/* 312 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var aCallable = __webpack_require__(38); +var isNullOrUndefined = __webpack_require__(11); +var lengthOfArrayLike = __webpack_require__(67); +var toObject = __webpack_require__(9); +var MapHelpers = __webpack_require__(185); +var iterate = __webpack_require__(313); + +var Map = MapHelpers.Map; +var mapHas = MapHelpers.has; +var mapSet = MapHelpers.set; +var push = uncurryThis([].push); + +// `Array.prototype.uniqueBy` method +// https://github.com/tc39/proposal-array-unique +module.exports = function uniqueBy(resolver) { + var that = toObject(this); + var length = lengthOfArrayLike(that); + var result = []; + var map = new Map(); + var resolverFunction = !isNullOrUndefined(resolver) ? aCallable(resolver) : function (value) { + return value; + }; + var index, item, key; + for (index = 0; index < length; index++) { + item = that[index]; + key = resolverFunction(item); + if (!mapHas(map, key)) mapSet(map, key, item); + } + iterate(map, function (value) { + push(result, value); + }); + return result; +}; + + +/***/ }), +/* 313 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var iterateSimple = __webpack_require__(250); +var MapHelpers = __webpack_require__(185); + +var Map = MapHelpers.Map; +var MapPrototype = MapHelpers.proto; +var forEach = uncurryThis(MapPrototype.forEach); +var entries = uncurryThis(MapPrototype.entries); +var next = entries(new Map()).next; + +module.exports = function (map, fn, interruptible) { + return interruptible ? iterateSimple({ iterator: entries(map), next: next }, function (entry) { + return fn(entry[1], entry[0]); + }) : forEach(map, fn); +}; + + +/***/ }), +/* 314 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var anInstance = __webpack_require__(145); +var getPrototypeOf = __webpack_require__(91); +var createNonEnumerableProperty = __webpack_require__(50); +var hasOwn = __webpack_require__(5); +var wellKnownSymbol = __webpack_require__(13); +var AsyncIteratorPrototype = __webpack_require__(230); +var IS_PURE = __webpack_require__(16); + +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); + +var $TypeError = TypeError; + +var AsyncIteratorConstructor = function AsyncIterator() { + anInstance(this, AsyncIteratorPrototype); + if (getPrototypeOf(this) === AsyncIteratorPrototype) throw new $TypeError('Abstract class AsyncIterator not directly constructable'); +}; + +AsyncIteratorConstructor.prototype = AsyncIteratorPrototype; + +if (!hasOwn(AsyncIteratorPrototype, TO_STRING_TAG)) { + createNonEnumerableProperty(AsyncIteratorPrototype, TO_STRING_TAG, 'AsyncIterator'); +} + +if (IS_PURE || !hasOwn(AsyncIteratorPrototype, 'constructor') || AsyncIteratorPrototype.constructor === Object) { + createNonEnumerableProperty(AsyncIteratorPrototype, 'constructor', AsyncIteratorConstructor); +} + +// `AsyncIterator` constructor +// https://github.com/tc39/proposal-async-iterator-helpers +$({ global: true, constructor: true, forced: IS_PURE }, { + AsyncIterator: AsyncIteratorConstructor +}); + + +/***/ }), +/* 315 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var indexed = __webpack_require__(316); + +// `AsyncIterator.prototype.asIndexedPairs` method +// https://github.com/tc39/proposal-iterator-helpers +$({ target: 'AsyncIterator', name: 'indexed', proto: true, real: true, forced: true }, { + asIndexedPairs: indexed +}); + + +/***/ }), +/* 316 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var map = __webpack_require__(317); + +var callback = function (value, counter) { + return [counter, value]; +}; + +// `AsyncIterator.prototype.indexed` method +// https://github.com/tc39/proposal-iterator-helpers +module.exports = function indexed() { + return call(map, this, callback); +}; + + +/***/ }), +/* 317 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var isObject = __webpack_require__(27); +var getIteratorDirect = __webpack_require__(157); +var createAsyncIteratorProxy = __webpack_require__(318); +var createIterResultObject = __webpack_require__(153); +var closeAsyncIteration = __webpack_require__(232); + +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { + var state = this; + var iterator = state.iterator; + var mapper = state.mapper; + + return new Promise(function (resolve, reject) { + var doneAndReject = function (error) { + state.done = true; + reject(error); + }; + + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, doneAndReject, error, doneAndReject); + }; + + Promise.resolve(anObject(call(state.next, iterator))).then(function (step) { + try { + if (anObject(step).done) { + state.done = true; + resolve(createIterResultObject(undefined, true)); + } else { + var value = step.value; + try { + var result = mapper(value, state.counter++); + + var handler = function (mapped) { + resolve(createIterResultObject(mapped, false)); + }; + + if (isObject(result)) Promise.resolve(result).then(handler, ifAbruptCloseAsyncIterator); + else handler(result); + } catch (error2) { ifAbruptCloseAsyncIterator(error2); } + } + } catch (error) { doneAndReject(error); } + }, doneAndReject); + }); +}); + +// `AsyncIterator.prototype.map` method +// https://github.com/tc39/proposal-async-iterator-helpers +module.exports = function map(mapper) { + anObject(this); + aCallable(mapper); + return new AsyncIteratorProxy(getIteratorDirect(this), { + mapper: mapper + }); +}; + + +/***/ }), +/* 318 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var perform = __webpack_require__(209); +var anObject = __webpack_require__(30); +var create = __webpack_require__(93); +var createNonEnumerableProperty = __webpack_require__(50); +var defineBuiltIns = __webpack_require__(146); +var wellKnownSymbol = __webpack_require__(13); +var InternalStateModule = __webpack_require__(55); +var getBuiltIn = __webpack_require__(35); +var getMethod = __webpack_require__(37); +var AsyncIteratorPrototype = __webpack_require__(230); +var createIterResultObject = __webpack_require__(153); +var iteratorClose = __webpack_require__(104); + +var Promise = getBuiltIn('Promise'); + +var TO_STRING_TAG = wellKnownSymbol('toStringTag'); +var ASYNC_ITERATOR_HELPER = 'AsyncIteratorHelper'; +var WRAP_FOR_VALID_ASYNC_ITERATOR = 'WrapForValidAsyncIterator'; +var setInternalState = InternalStateModule.set; + +var createAsyncIteratorProxyPrototype = function (IS_ITERATOR) { + var IS_GENERATOR = !IS_ITERATOR; + var getInternalState = InternalStateModule.getterFor(IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER); + + var getStateOrEarlyExit = function (that) { + var stateCompletion = perform(function () { + return getInternalState(that); + }); + + var stateError = stateCompletion.error; + var state = stateCompletion.value; + + if (stateError || (IS_GENERATOR && state.done)) { + return { exit: true, value: stateError ? Promise.reject(state) : Promise.resolve(createIterResultObject(undefined, true)) }; + } return { exit: false, value: state }; + }; + + return defineBuiltIns(create(AsyncIteratorPrototype), { + next: function next() { + var stateCompletion = getStateOrEarlyExit(this); + var state = stateCompletion.value; + if (stateCompletion.exit) return state; + var handlerCompletion = perform(function () { + return anObject(state.nextHandler(Promise)); + }); + var handlerError = handlerCompletion.error; + var value = handlerCompletion.value; + if (handlerError) state.done = true; + return handlerError ? Promise.reject(value) : Promise.resolve(value); + }, + 'return': function () { + var stateCompletion = getStateOrEarlyExit(this); + var state = stateCompletion.value; + if (stateCompletion.exit) return state; + state.done = true; + var iterator = state.iterator; + var returnMethod, result; + var completion = perform(function () { + if (state.inner) try { + iteratorClose(state.inner.iterator, 'normal'); + } catch (error) { + return iteratorClose(iterator, 'throw', error); + } + return getMethod(iterator, 'return'); + }); + returnMethod = result = completion.value; + if (completion.error) return Promise.reject(result); + if (returnMethod === undefined) return Promise.resolve(createIterResultObject(undefined, true)); + completion = perform(function () { + return call(returnMethod, iterator); + }); + result = completion.value; + if (completion.error) return Promise.reject(result); + return IS_ITERATOR ? Promise.resolve(result) : Promise.resolve(result).then(function (resolved) { + anObject(resolved); + return createIterResultObject(undefined, true); + }); + } + }); +}; + +var WrapForValidAsyncIteratorPrototype = createAsyncIteratorProxyPrototype(true); +var AsyncIteratorHelperPrototype = createAsyncIteratorProxyPrototype(false); + +createNonEnumerableProperty(AsyncIteratorHelperPrototype, TO_STRING_TAG, 'Async Iterator Helper'); + +module.exports = function (nextHandler, IS_ITERATOR) { + var AsyncIteratorProxy = function AsyncIterator(record, state) { + if (state) { + state.iterator = record.iterator; + state.next = record.next; + } else state = record; + state.type = IS_ITERATOR ? WRAP_FOR_VALID_ASYNC_ITERATOR : ASYNC_ITERATOR_HELPER; + state.nextHandler = nextHandler; + state.counter = 0; + state.done = false; + setInternalState(this, state); + }; + + AsyncIteratorProxy.prototype = IS_ITERATOR ? WrapForValidAsyncIteratorPrototype : AsyncIteratorHelperPrototype; + + return AsyncIteratorProxy; +}; + + +/***/ }), +/* 319 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var notANaN = __webpack_require__(158); +var toPositiveInteger = __webpack_require__(159); +var createAsyncIteratorProxy = __webpack_require__(318); +var createIterResultObject = __webpack_require__(153); + +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { + var state = this; + + return new Promise(function (resolve, reject) { + var doneAndReject = function (error) { + state.done = true; + reject(error); + }; + + var loop = function () { + try { + Promise.resolve(anObject(call(state.next, state.iterator))).then(function (step) { + try { + if (anObject(step).done) { + state.done = true; + resolve(createIterResultObject(undefined, true)); + } else if (state.remaining) { + state.remaining--; + loop(); + } else resolve(createIterResultObject(step.value, false)); + } catch (err) { doneAndReject(err); } + }, doneAndReject); + } catch (error) { doneAndReject(error); } + }; + + loop(); + }); +}); + +// `AsyncIterator.prototype.drop` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + drop: function drop(limit) { + anObject(this); + var remaining = toPositiveInteger(notANaN(+limit)); + return new AsyncIteratorProxy(getIteratorDirect(this), { + remaining: remaining + }); + } +}); + + +/***/ }), +/* 320 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $every = __webpack_require__(231).every; + +// `AsyncIterator.prototype.every` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + every: function every(predicate) { + return $every(this, predicate); + } +}); + + +/***/ }), +/* 321 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var isObject = __webpack_require__(27); +var getIteratorDirect = __webpack_require__(157); +var createAsyncIteratorProxy = __webpack_require__(318); +var createIterResultObject = __webpack_require__(153); +var closeAsyncIteration = __webpack_require__(232); + +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { + var state = this; + var iterator = state.iterator; + var predicate = state.predicate; + + return new Promise(function (resolve, reject) { + var doneAndReject = function (error) { + state.done = true; + reject(error); + }; + + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, doneAndReject, error, doneAndReject); + }; + + var loop = function () { + try { + Promise.resolve(anObject(call(state.next, iterator))).then(function (step) { + try { + if (anObject(step).done) { + state.done = true; + resolve(createIterResultObject(undefined, true)); + } else { + var value = step.value; + try { + var result = predicate(value, state.counter++); + + var handler = function (selected) { + selected ? resolve(createIterResultObject(value, false)) : loop(); + }; + + if (isObject(result)) Promise.resolve(result).then(handler, ifAbruptCloseAsyncIterator); + else handler(result); + } catch (error3) { ifAbruptCloseAsyncIterator(error3); } + } + } catch (error2) { doneAndReject(error2); } + }, doneAndReject); + } catch (error) { doneAndReject(error); } + }; + + loop(); + }); +}); + +// `AsyncIterator.prototype.filter` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + filter: function filter(predicate) { + anObject(this); + aCallable(predicate); + return new AsyncIteratorProxy(getIteratorDirect(this), { + predicate: predicate + }); + } +}); + + +/***/ }), +/* 322 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $find = __webpack_require__(231).find; + +// `AsyncIterator.prototype.find` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + find: function find(predicate) { + return $find(this, predicate); + } +}); + + +/***/ }), +/* 323 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var isObject = __webpack_require__(27); +var getIteratorDirect = __webpack_require__(157); +var createAsyncIteratorProxy = __webpack_require__(318); +var createIterResultObject = __webpack_require__(153); +var getAsyncIteratorFlattenable = __webpack_require__(324); +var closeAsyncIteration = __webpack_require__(232); + +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { + var state = this; + var iterator = state.iterator; + var mapper = state.mapper; + + return new Promise(function (resolve, reject) { + var doneAndReject = function (error) { + state.done = true; + reject(error); + }; + + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, doneAndReject, error, doneAndReject); + }; + + var outerLoop = function () { + try { + Promise.resolve(anObject(call(state.next, iterator))).then(function (step) { + try { + if (anObject(step).done) { + state.done = true; + resolve(createIterResultObject(undefined, true)); + } else { + var value = step.value; + try { + var result = mapper(value, state.counter++); + + var handler = function (mapped) { + try { + state.inner = getAsyncIteratorFlattenable(mapped); + innerLoop(); + } catch (error4) { ifAbruptCloseAsyncIterator(error4); } + }; + + if (isObject(result)) Promise.resolve(result).then(handler, ifAbruptCloseAsyncIterator); + else handler(result); + } catch (error3) { ifAbruptCloseAsyncIterator(error3); } + } + } catch (error2) { doneAndReject(error2); } + }, doneAndReject); + } catch (error) { doneAndReject(error); } + }; + + var innerLoop = function () { + var inner = state.inner; + if (inner) { + try { + Promise.resolve(anObject(call(inner.next, inner.iterator))).then(function (result) { + try { + if (anObject(result).done) { + state.inner = null; + outerLoop(); + } else resolve(createIterResultObject(result.value, false)); + } catch (error1) { ifAbruptCloseAsyncIterator(error1); } + }, ifAbruptCloseAsyncIterator); + } catch (error) { ifAbruptCloseAsyncIterator(error); } + } else outerLoop(); + }; + + innerLoop(); + }); +}); + +// `AsyncIterator.prototype.flatMap` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + flatMap: function flatMap(mapper) { + anObject(this); + aCallable(mapper); + return new AsyncIteratorProxy(getIteratorDirect(this), { + mapper: mapper, + inner: null + }); + } +}); + + +/***/ }), +/* 324 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var isCallable = __webpack_require__(28); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var getIteratorMethod = __webpack_require__(103); +var getMethod = __webpack_require__(37); +var wellKnownSymbol = __webpack_require__(13); +var AsyncFromSyncIterator = __webpack_require__(229); + +var ASYNC_ITERATOR = wellKnownSymbol('asyncIterator'); + +module.exports = function (obj) { + var object = anObject(obj); + var alreadyAsync = true; + var method = getMethod(object, ASYNC_ITERATOR); + var iterator; + if (!isCallable(method)) { + method = getIteratorMethod(object); + alreadyAsync = false; + } + if (method !== undefined) { + iterator = call(method, object); + } else { + iterator = object; + alreadyAsync = true; + } + anObject(iterator); + return getIteratorDirect(alreadyAsync ? iterator : new AsyncFromSyncIterator(getIteratorDirect(iterator))); +}; + + +/***/ }), +/* 325 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $forEach = __webpack_require__(231).forEach; + +// `AsyncIterator.prototype.forEach` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + forEach: function forEach(fn) { + return $forEach(this, fn); + } +}); + + +/***/ }), +/* 326 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var toObject = __webpack_require__(9); +var isPrototypeOf = __webpack_require__(36); +var getAsyncIteratorFlattenable = __webpack_require__(324); +var AsyncIteratorPrototype = __webpack_require__(230); +var WrapAsyncIterator = __webpack_require__(327); + +// `AsyncIterator.from` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', stat: true, forced: true }, { + from: function from(O) { + var iteratorRecord = getAsyncIteratorFlattenable(typeof O == 'string' ? toObject(O) : O); + return isPrototypeOf(AsyncIteratorPrototype, iteratorRecord.iterator) + ? iteratorRecord.iterator + : new WrapAsyncIterator(iteratorRecord); + } +}); + + +/***/ }), +/* 327 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var createAsyncIteratorProxy = __webpack_require__(318); + +module.exports = createAsyncIteratorProxy(function () { + return call(this.next, this.iterator); +}, true); + + +/***/ }), +/* 328 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var indexed = __webpack_require__(316); + +// `AsyncIterator.prototype.indexed` method +// https://github.com/tc39/proposal-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + indexed: indexed +}); + + +/***/ }), +/* 329 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var map = __webpack_require__(317); + +// `AsyncIterator.prototype.map` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + map: map +}); + + + +/***/ }), +/* 330 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var isObject = __webpack_require__(27); +var getBuiltIn = __webpack_require__(35); +var getIteratorDirect = __webpack_require__(157); +var closeAsyncIteration = __webpack_require__(232); + +var Promise = getBuiltIn('Promise'); +var $TypeError = TypeError; + +// `AsyncIterator.prototype.reduce` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + reduce: function reduce(reducer /* , initialValue */) { + anObject(this); + aCallable(reducer); + var record = getIteratorDirect(this); + var iterator = record.iterator; + var next = record.next; + var noInitial = arguments.length < 2; + var accumulator = noInitial ? undefined : arguments[1]; + var counter = 0; + + return new Promise(function (resolve, reject) { + var ifAbruptCloseAsyncIterator = function (error) { + closeAsyncIteration(iterator, reject, error, reject); + }; + + var loop = function () { + try { + Promise.resolve(anObject(call(next, iterator))).then(function (step) { + try { + if (anObject(step).done) { + noInitial ? reject(new $TypeError('Reduce of empty iterator with no initial value')) : resolve(accumulator); + } else { + var value = step.value; + if (noInitial) { + noInitial = false; + accumulator = value; + loop(); + } else try { + var result = reducer(accumulator, value, counter); + + var handler = function ($result) { + accumulator = $result; + loop(); + }; + + if (isObject(result)) Promise.resolve(result).then(handler, ifAbruptCloseAsyncIterator); + else handler(result); + } catch (error3) { ifAbruptCloseAsyncIterator(error3); } + } + counter++; + } catch (error2) { reject(error2); } + }, reject); + } catch (error) { reject(error); } + }; + + loop(); + }); + } +}); + + +/***/ }), +/* 331 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $some = __webpack_require__(231).some; + +// `AsyncIterator.prototype.some` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + some: function some(predicate) { + return $some(this, predicate); + } +}); + + +/***/ }), +/* 332 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var getIteratorDirect = __webpack_require__(157); +var notANaN = __webpack_require__(158); +var toPositiveInteger = __webpack_require__(159); +var createAsyncIteratorProxy = __webpack_require__(318); +var createIterResultObject = __webpack_require__(153); + +var AsyncIteratorProxy = createAsyncIteratorProxy(function (Promise) { + var state = this; + var iterator = state.iterator; + var returnMethod; + + if (!state.remaining--) { + var resultDone = createIterResultObject(undefined, true); + state.done = true; + returnMethod = iterator['return']; + if (returnMethod !== undefined) { + return Promise.resolve(call(returnMethod, iterator, undefined)).then(function () { + return resultDone; + }); + } + return resultDone; + } return Promise.resolve(call(state.next, iterator)).then(function (step) { + if (anObject(step).done) { + state.done = true; + return createIterResultObject(undefined, true); + } return createIterResultObject(step.value, false); + }).then(null, function (error) { + state.done = true; + throw error; + }); +}); + +// `AsyncIterator.prototype.take` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + take: function take(limit) { + anObject(this); + var remaining = toPositiveInteger(notANaN(+limit)); + return new AsyncIteratorProxy(getIteratorDirect(this), { + remaining: remaining + }); + } +}); + + +/***/ }), +/* 333 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $toArray = __webpack_require__(231).toArray; + +// `AsyncIterator.prototype.toArray` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'AsyncIterator', proto: true, real: true, forced: true }, { + toArray: function toArray() { + return $toArray(this, undefined, []); + } +}); + + +/***/ }), +/* 334 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable es/no-bigint -- safe */ +var $ = __webpack_require__(49); +var NumericRangeIterator = __webpack_require__(335); + +// `BigInt.range` method +// https://github.com/tc39/proposal-Number.range +// TODO: Remove from `core-js@4` +if (typeof BigInt == 'function') { + $({ target: 'BigInt', stat: true, forced: true }, { + range: function range(start, end, option) { + return new NumericRangeIterator(start, end, option, 'bigint', BigInt(0), BigInt(1)); + } + }); +} + + +/***/ }), +/* 335 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var InternalStateModule = __webpack_require__(55); +var createIteratorConstructor = __webpack_require__(336); +var createIterResultObject = __webpack_require__(153); +var isNullOrUndefined = __webpack_require__(11); +var isObject = __webpack_require__(27); +var defineBuiltInAccessor = __webpack_require__(131); +var DESCRIPTORS = __webpack_require__(24); + +var INCORRECT_RANGE = 'Incorrect Iterator.range arguments'; +var NUMERIC_RANGE_ITERATOR = 'NumericRangeIterator'; + +var setInternalState = InternalStateModule.set; +var getInternalState = InternalStateModule.getterFor(NUMERIC_RANGE_ITERATOR); + +var $RangeError = RangeError; +var $TypeError = TypeError; + +var $RangeIterator = createIteratorConstructor(function NumericRangeIterator(start, end, option, type, zero, one) { + // TODO: Drop the first `typeof` check after removing legacy methods in `core-js@4` + if (typeof start != type || (end !== Infinity && end !== -Infinity && typeof end != type)) { + throw new $TypeError(INCORRECT_RANGE); + } + if (start === Infinity || start === -Infinity) { + throw new $RangeError(INCORRECT_RANGE); + } + var ifIncrease = end > start; + var inclusiveEnd = false; + var step; + if (option === undefined) { + step = undefined; + } else if (isObject(option)) { + step = option.step; + inclusiveEnd = !!option.inclusive; + } else if (typeof option == type) { + step = option; + } else { + throw new $TypeError(INCORRECT_RANGE); + } + if (isNullOrUndefined(step)) { + step = ifIncrease ? one : -one; + } + if (typeof step != type) { + throw new $TypeError(INCORRECT_RANGE); + } + if (step === Infinity || step === -Infinity || (step === zero && start !== end)) { + throw new $RangeError(INCORRECT_RANGE); + } + // eslint-disable-next-line no-self-compare -- NaN check + var hitsEnd = start !== start || end !== end || step !== step || (end > start) !== (step > zero); + setInternalState(this, { + type: NUMERIC_RANGE_ITERATOR, + start: start, + end: end, + step: step, + inclusive: inclusiveEnd, + hitsEnd: hitsEnd, + currentCount: zero, + zero: zero + }); + if (!DESCRIPTORS) { + this.start = start; + this.end = end; + this.step = step; + this.inclusive = inclusiveEnd; + } +}, NUMERIC_RANGE_ITERATOR, function next() { + var state = getInternalState(this); + if (state.hitsEnd) return createIterResultObject(undefined, true); + var start = state.start; + var end = state.end; + var step = state.step; + var currentYieldingValue = start + (step * state.currentCount++); + if (currentYieldingValue === end) state.hitsEnd = true; + var inclusiveEnd = state.inclusive; + var endCondition; + if (end > start) { + endCondition = inclusiveEnd ? currentYieldingValue > end : currentYieldingValue >= end; + } else { + endCondition = inclusiveEnd ? end > currentYieldingValue : end >= currentYieldingValue; + } + if (endCondition) { + state.hitsEnd = true; + return createIterResultObject(undefined, true); + } return createIterResultObject(currentYieldingValue, false); +}); + +var addGetter = function (key) { + defineBuiltInAccessor($RangeIterator.prototype, key, { + get: function () { + return getInternalState(this)[key]; + }, + set: function () { /* empty */ }, + configurable: true, + enumerable: false + }); +}; + +if (DESCRIPTORS) { + addGetter('start'); + addGetter('end'); + addGetter('inclusive'); + addGetter('step'); +} + +module.exports = $RangeIterator; + + +/***/ }), +/* 336 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var IteratorPrototype = __webpack_require__(150).IteratorPrototype; +var create = __webpack_require__(93); +var createPropertyDescriptor = __webpack_require__(43); +var setToStringTag = __webpack_require__(195); +var Iterators = __webpack_require__(101); + +var returnThis = function () { return this; }; + +module.exports = function (IteratorConstructor, NAME, next, ENUMERABLE_NEXT) { + var TO_STRING_TAG = NAME + ' Iterator'; + IteratorConstructor.prototype = create(IteratorPrototype, { next: createPropertyDescriptor(+!ENUMERABLE_NEXT, next) }); + setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true); + Iterators[TO_STRING_TAG] = returnThis; + return IteratorConstructor; +}; + + +/***/ }), +/* 337 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var apply = __webpack_require__(72); +var getCompositeKeyNode = __webpack_require__(338); +var getBuiltIn = __webpack_require__(35); +var create = __webpack_require__(93); + +var $Object = Object; + +var initializer = function () { + var freeze = getBuiltIn('Object', 'freeze'); + return freeze ? freeze(create(null)) : create(null); +}; + +// https://github.com/tc39/proposal-richer-keys/tree/master/compositeKey +$({ global: true, forced: true }, { + compositeKey: function compositeKey() { + return apply(getCompositeKeyNode, $Object, arguments).get('object', initializer); + } +}); + + +/***/ }), +/* 338 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env` +__webpack_require__(339); +__webpack_require__(348); +var getBuiltIn = __webpack_require__(35); +var create = __webpack_require__(93); +var isObject = __webpack_require__(27); + +var $Object = Object; +var $TypeError = TypeError; +var Map = getBuiltIn('Map'); +var WeakMap = getBuiltIn('WeakMap'); + +var Node = function () { + // keys + this.object = null; + this.symbol = null; + // child nodes + this.primitives = null; + this.objectsByIndex = create(null); +}; + +Node.prototype.get = function (key, initializer) { + return this[key] || (this[key] = initializer()); +}; + +Node.prototype.next = function (i, it, IS_OBJECT) { + var store = IS_OBJECT + ? this.objectsByIndex[i] || (this.objectsByIndex[i] = new WeakMap()) + : this.primitives || (this.primitives = new Map()); + var entry = store.get(it); + if (!entry) store.set(it, entry = new Node()); + return entry; +}; + +var root = new Node(); + +module.exports = function () { + var active = root; + var length = arguments.length; + var i, it; + // for prevent leaking, start from objects + for (i = 0; i < length; i++) { + if (isObject(it = arguments[i])) active = active.next(i, it, true); + } + if (this === $Object && active === root) throw new $TypeError('Composite keys must contain a non-primitive component'); + for (i = 0; i < length; i++) { + if (!isObject(it = arguments[i])) active = active.next(i, it, false); + } return active; +}; + + +/***/ }), +/* 339 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove this module from `core-js@4` since it's replaced to module below +__webpack_require__(340); + + +/***/ }), +/* 340 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var collection = __webpack_require__(341); +var collectionStrong = __webpack_require__(346); + +// `Map` constructor +// https://tc39.es/ecma262/#sec-map-objects +collection('Map', function (init) { + return function Map() { return init(this, arguments.length ? arguments[0] : undefined); }; +}, collectionStrong); + + +/***/ }), +/* 341 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var uncurryThis = __webpack_require__(6); +var isForced = __webpack_require__(71); +var defineBuiltIn = __webpack_require__(51); +var InternalMetadataModule = __webpack_require__(342); +var iterate = __webpack_require__(97); +var anInstance = __webpack_require__(145); +var isCallable = __webpack_require__(28); +var isNullOrUndefined = __webpack_require__(11); +var isObject = __webpack_require__(27); +var fails = __webpack_require__(8); +var checkCorrectnessOfIteration = __webpack_require__(215); +var setToStringTag = __webpack_require__(195); +var inheritIfRequired = __webpack_require__(79); + +module.exports = function (CONSTRUCTOR_NAME, wrapper, common) { + var IS_MAP = CONSTRUCTOR_NAME.indexOf('Map') !== -1; + var IS_WEAK = CONSTRUCTOR_NAME.indexOf('Weak') !== -1; + var ADDER = IS_MAP ? 'set' : 'add'; + var NativeConstructor = globalThis[CONSTRUCTOR_NAME]; + var NativePrototype = NativeConstructor && NativeConstructor.prototype; + var Constructor = NativeConstructor; + var exported = {}; + + var fixMethod = function (KEY) { + var uncurriedNativeMethod = uncurryThis(NativePrototype[KEY]); + defineBuiltIn(NativePrototype, KEY, + KEY === 'add' ? function add(value) { + uncurriedNativeMethod(this, value === 0 ? 0 : value); + return this; + } : KEY === 'delete' ? function (key) { + return IS_WEAK && !isObject(key) ? false : uncurriedNativeMethod(this, key === 0 ? 0 : key); + } : KEY === 'get' ? function get(key) { + return IS_WEAK && !isObject(key) ? undefined : uncurriedNativeMethod(this, key === 0 ? 0 : key); + } : KEY === 'has' ? function has(key) { + return IS_WEAK && !isObject(key) ? false : uncurriedNativeMethod(this, key === 0 ? 0 : key); + } : function set(key, value) { + uncurriedNativeMethod(this, key === 0 ? 0 : key, value); + return this; + } + ); + }; + + var REPLACE = isForced( + CONSTRUCTOR_NAME, + !isCallable(NativeConstructor) || !(IS_WEAK || NativePrototype.forEach && !fails(function () { + new NativeConstructor().entries().next(); + })) + ); + + if (REPLACE) { + // create collection constructor + Constructor = common.getConstructor(wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER); + InternalMetadataModule.enable(); + } else if (isForced(CONSTRUCTOR_NAME, true)) { + var instance = new Constructor(); + // early implementations not supports chaining + var HASNT_CHAINING = instance[ADDER](IS_WEAK ? {} : -0, 1) !== instance; + // V8 ~ Chromium 40- weak-collections throws on primitives, but should return false + var THROWS_ON_PRIMITIVES = fails(function () { instance.has(1); }); + // most early implementations doesn't supports iterables, most modern - not close it correctly + // eslint-disable-next-line no-new -- required for testing + var ACCEPT_ITERABLES = checkCorrectnessOfIteration(function (iterable) { new NativeConstructor(iterable); }); + // for early implementations -0 and +0 not the same + var BUGGY_ZERO = !IS_WEAK && fails(function () { + // V8 ~ Chromium 42- fails only with 5+ elements + var $instance = new NativeConstructor(); + var index = 5; + while (index--) $instance[ADDER](index, index); + return !$instance.has(-0); + }); + + if (!ACCEPT_ITERABLES) { + Constructor = wrapper(function (dummy, iterable) { + anInstance(dummy, NativePrototype); + var that = inheritIfRequired(new NativeConstructor(), dummy, Constructor); + if (!isNullOrUndefined(iterable)) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); + return that; + }); + Constructor.prototype = NativePrototype; + NativePrototype.constructor = Constructor; + } + + if (THROWS_ON_PRIMITIVES || BUGGY_ZERO) { + fixMethod('delete'); + fixMethod('has'); + IS_MAP && fixMethod('get'); + } + + if (BUGGY_ZERO || HASNT_CHAINING) fixMethod(ADDER); + + // weak collections should not contains .clear method + if (IS_WEAK && NativePrototype.clear) delete NativePrototype.clear; + } + + exported[CONSTRUCTOR_NAME] = Constructor; + $({ global: true, constructor: true, forced: Constructor !== NativeConstructor }, exported); + + setToStringTag(Constructor, CONSTRUCTOR_NAME); + + if (!IS_WEAK) common.setStrong(Constructor, CONSTRUCTOR_NAME, IS_MAP); + + return Constructor; +}; + + +/***/ }), +/* 342 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var hiddenKeys = __webpack_require__(58); +var isObject = __webpack_require__(27); +var hasOwn = __webpack_require__(5); +var defineProperty = __webpack_require__(23).f; +var getOwnPropertyNamesModule = __webpack_require__(61); +var getOwnPropertyNamesExternalModule = __webpack_require__(343); +var isExtensible = __webpack_require__(344); +var uid = __webpack_require__(18); +var FREEZING = __webpack_require__(181); + +var REQUIRED = false; +var METADATA = uid('meta'); +var id = 0; + +var setMetadata = function (it) { + defineProperty(it, METADATA, { value: { + objectID: 'O' + id++, // object ID + weakData: {} // weak collections IDs + } }); +}; + +var fastKey = function (it, create) { + // return a primitive with prefix + if (!isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; + if (!hasOwn(it, METADATA)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return 'F'; + // not necessary to add metadata + if (!create) return 'E'; + // add missing metadata + setMetadata(it); + // return object ID + } return it[METADATA].objectID; +}; + +var getWeakData = function (it, create) { + if (!hasOwn(it, METADATA)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return true; + // not necessary to add metadata + if (!create) return false; + // add missing metadata + setMetadata(it); + // return the store of weak collections IDs + } return it[METADATA].weakData; +}; + +// add metadata on freeze-family methods calling +var onFreeze = function (it) { + if (FREEZING && REQUIRED && isExtensible(it) && !hasOwn(it, METADATA)) setMetadata(it); + return it; +}; + +var enable = function () { + meta.enable = function () { /* empty */ }; + REQUIRED = true; + var getOwnPropertyNames = getOwnPropertyNamesModule.f; + var splice = uncurryThis([].splice); + var test = {}; + // eslint-disable-next-line unicorn/no-immediate-mutation -- ES3 syntax limitation + test[METADATA] = 1; + + // prevent exposing of metadata key + if (getOwnPropertyNames(test).length) { + getOwnPropertyNamesModule.f = function (it) { + var result = getOwnPropertyNames(it); + for (var i = 0, length = result.length; i < length; i++) { + if (result[i] === METADATA) { + splice(result, i, 1); + break; + } + } return result; + }; + + $({ target: 'Object', stat: true, forced: true }, { + getOwnPropertyNames: getOwnPropertyNamesExternalModule.f + }); + } +}; + +var meta = module.exports = { + enable: enable, + fastKey: fastKey, + getWeakData: getWeakData, + onFreeze: onFreeze +}; + +hiddenKeys[METADATA] = true; + + +/***/ }), +/* 343 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable es/no-object-getownpropertynames -- safe */ +var classof = __webpack_require__(46); +var toIndexedObject = __webpack_require__(44); +var $getOwnPropertyNames = __webpack_require__(61).f; +var arraySlice = __webpack_require__(183); + +var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames + ? Object.getOwnPropertyNames(window) : []; + +var getWindowNames = function (it) { + try { + return $getOwnPropertyNames(it); + } catch (error) { + return arraySlice(windowNames); + } +}; + +// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window +module.exports.f = function getOwnPropertyNames(it) { + return windowNames && classof(it) === 'Window' + ? getWindowNames(it) + : $getOwnPropertyNames(toIndexedObject(it)); +}; + + +/***/ }), +/* 344 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); +var isObject = __webpack_require__(27); +var classof = __webpack_require__(46); +var ARRAY_BUFFER_NON_EXTENSIBLE = __webpack_require__(345); + +// eslint-disable-next-line es/no-object-isextensible -- safe +var $isExtensible = Object.isExtensible; +var FAILS_ON_PRIMITIVES = fails(function () { $isExtensible(1); }); + +// `Object.isExtensible` method +// https://tc39.es/ecma262/#sec-object.isextensible +module.exports = (FAILS_ON_PRIMITIVES || ARRAY_BUFFER_NON_EXTENSIBLE) ? function isExtensible(it) { + if (!isObject(it)) return false; + if (ARRAY_BUFFER_NON_EXTENSIBLE && classof(it) === 'ArrayBuffer') return false; + return $isExtensible ? $isExtensible(it) : true; +} : $isExtensible; + + +/***/ }), +/* 345 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// FF26- bug: ArrayBuffers are non-extensible, but Object.isExtensible does not report it +var fails = __webpack_require__(8); + +module.exports = fails(function () { + if (typeof ArrayBuffer == 'function') { + var buffer = new ArrayBuffer(8); + // eslint-disable-next-line es/no-object-isextensible, es/no-object-defineproperty -- safe + if (Object.isExtensible(buffer)) Object.defineProperty(buffer, 'a', { value: 8 }); + } +}); + + +/***/ }), +/* 346 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var create = __webpack_require__(93); +var defineBuiltInAccessor = __webpack_require__(131); +var defineBuiltIns = __webpack_require__(146); +var bind = __webpack_require__(98); +var anInstance = __webpack_require__(145); +var isNullOrUndefined = __webpack_require__(11); +var iterate = __webpack_require__(97); +var defineIterator = __webpack_require__(347); +var createIterResultObject = __webpack_require__(153); +var setSpecies = __webpack_require__(196); +var DESCRIPTORS = __webpack_require__(24); +var fastKey = __webpack_require__(342).fastKey; +var InternalStateModule = __webpack_require__(55); + +var setInternalState = InternalStateModule.set; +var internalStateGetterFor = InternalStateModule.getterFor; + +module.exports = { + getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) { + var Constructor = wrapper(function (that, iterable) { + anInstance(that, Prototype); + setInternalState(that, { + type: CONSTRUCTOR_NAME, + index: create(null), + first: null, + last: null, + size: 0 + }); + if (!DESCRIPTORS) that.size = 0; + if (!isNullOrUndefined(iterable)) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); + }); + + var Prototype = Constructor.prototype; + + var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME); + + var define = function (that, key, value) { + var state = getInternalState(that); + var entry = getEntry(that, key); + var previous, index; + // change existing entry + if (entry) { + entry.value = value; + // create new entry + } else { + state.last = entry = { + index: index = fastKey(key, true), + key: key, + value: value, + previous: previous = state.last, + next: null, + removed: false + }; + if (!state.first) state.first = entry; + if (previous) previous.next = entry; + if (DESCRIPTORS) state.size++; + else that.size++; + // add to index + if (index !== 'F') state.index[index] = entry; + } return that; + }; + + var getEntry = function (that, key) { + var state = getInternalState(that); + // fast case + var index = fastKey(key); + var entry; + if (index !== 'F') return state.index[index]; + // frozen object case + for (entry = state.first; entry; entry = entry.next) { + if (entry.key === key) return entry; + } + }; + + defineBuiltIns(Prototype, { + // `{ Map, Set }.prototype.clear()` methods + // https://tc39.es/ecma262/#sec-map.prototype.clear + // https://tc39.es/ecma262/#sec-set.prototype.clear + clear: function clear() { + var that = this; + var state = getInternalState(that); + var entry = state.first; + while (entry) { + entry.removed = true; + if (entry.previous) entry.previous = entry.previous.next = null; + entry = entry.next; + } + state.first = state.last = null; + state.index = create(null); + if (DESCRIPTORS) state.size = 0; + else that.size = 0; + }, + // `{ Map, Set }.prototype.delete(key)` methods + // https://tc39.es/ecma262/#sec-map.prototype.delete + // https://tc39.es/ecma262/#sec-set.prototype.delete + 'delete': function (key) { + var that = this; + var state = getInternalState(that); + var entry = getEntry(that, key); + if (entry) { + var next = entry.next; + var prev = entry.previous; + delete state.index[entry.index]; + entry.removed = true; + if (prev) prev.next = next; + if (next) next.previous = prev; + if (state.first === entry) state.first = next; + if (state.last === entry) state.last = prev; + if (DESCRIPTORS) state.size--; + else that.size--; + } return !!entry; + }, + // `{ Map, Set }.prototype.forEach(callbackfn, thisArg = undefined)` methods + // https://tc39.es/ecma262/#sec-map.prototype.foreach + // https://tc39.es/ecma262/#sec-set.prototype.foreach + forEach: function forEach(callbackfn /* , that = undefined */) { + var state = getInternalState(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var entry; + while (entry = entry ? entry.next : state.first) { + boundFunction(entry.value, entry.key, this); + // revert to the last existing entry + while (entry && entry.removed) entry = entry.previous; + } + }, + // `{ Map, Set}.prototype.has(key)` methods + // https://tc39.es/ecma262/#sec-map.prototype.has + // https://tc39.es/ecma262/#sec-set.prototype.has + has: function has(key) { + return !!getEntry(this, key); + } + }); + + defineBuiltIns(Prototype, IS_MAP ? { + // `Map.prototype.get(key)` method + // https://tc39.es/ecma262/#sec-map.prototype.get + get: function get(key) { + var entry = getEntry(this, key); + return entry && entry.value; + }, + // `Map.prototype.set(key, value)` method + // https://tc39.es/ecma262/#sec-map.prototype.set + set: function set(key, value) { + return define(this, key === 0 ? 0 : key, value); + } + } : { + // `Set.prototype.add(value)` method + // https://tc39.es/ecma262/#sec-set.prototype.add + add: function add(value) { + return define(this, value = value === 0 ? 0 : value, value); + } + }); + if (DESCRIPTORS) defineBuiltInAccessor(Prototype, 'size', { + configurable: true, + get: function () { + return getInternalState(this).size; + } + }); + return Constructor; + }, + setStrong: function (Constructor, CONSTRUCTOR_NAME, IS_MAP) { + var ITERATOR_NAME = CONSTRUCTOR_NAME + ' Iterator'; + var getInternalCollectionState = internalStateGetterFor(CONSTRUCTOR_NAME); + var getInternalIteratorState = internalStateGetterFor(ITERATOR_NAME); + // `{ Map, Set }.prototype.{ keys, values, entries, @@iterator }()` methods + // https://tc39.es/ecma262/#sec-map.prototype.entries + // https://tc39.es/ecma262/#sec-map.prototype.keys + // https://tc39.es/ecma262/#sec-map.prototype.values + // https://tc39.es/ecma262/#sec-map.prototype-@@iterator + // https://tc39.es/ecma262/#sec-set.prototype.entries + // https://tc39.es/ecma262/#sec-set.prototype.keys + // https://tc39.es/ecma262/#sec-set.prototype.values + // https://tc39.es/ecma262/#sec-set.prototype-@@iterator + defineIterator(Constructor, CONSTRUCTOR_NAME, function (iterated, kind) { + setInternalState(this, { + type: ITERATOR_NAME, + target: iterated, + state: getInternalCollectionState(iterated), + kind: kind, + last: null + }); + }, function () { + var state = getInternalIteratorState(this); + var kind = state.kind; + var entry = state.last; + // revert to the last existing entry + while (entry && entry.removed) entry = entry.previous; + // get next entry + if (!state.target || !(state.last = entry = entry ? entry.next : state.state.first)) { + // or finish the iteration + state.target = null; + return createIterResultObject(undefined, true); + } + // return step by kind + if (kind === 'keys') return createIterResultObject(entry.key, false); + if (kind === 'values') return createIterResultObject(entry.value, false); + return createIterResultObject([entry.key, entry.value], false); + }, IS_MAP ? 'entries' : 'values', !IS_MAP, true); + + // `{ Map, Set }.prototype[@@species]` accessors + // https://tc39.es/ecma262/#sec-get-map-@@species + // https://tc39.es/ecma262/#sec-get-set-@@species + setSpecies(CONSTRUCTOR_NAME); + } +}; + + +/***/ }), +/* 347 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var IS_PURE = __webpack_require__(16); +var FunctionName = __webpack_require__(53); +var isCallable = __webpack_require__(28); +var createIteratorConstructor = __webpack_require__(336); +var getPrototypeOf = __webpack_require__(91); +var setPrototypeOf = __webpack_require__(74); +var setToStringTag = __webpack_require__(195); +var createNonEnumerableProperty = __webpack_require__(50); +var defineBuiltIn = __webpack_require__(51); +var wellKnownSymbol = __webpack_require__(13); +var Iterators = __webpack_require__(101); +var IteratorsCore = __webpack_require__(150); + +var PROPER_FUNCTION_NAME = FunctionName.PROPER; +var CONFIGURABLE_FUNCTION_NAME = FunctionName.CONFIGURABLE; +var IteratorPrototype = IteratorsCore.IteratorPrototype; +var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS; +var ITERATOR = wellKnownSymbol('iterator'); +var KEYS = 'keys'; +var VALUES = 'values'; +var ENTRIES = 'entries'; + +var returnThis = function () { return this; }; + +module.exports = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) { + createIteratorConstructor(IteratorConstructor, NAME, next); + + var getIterationMethod = function (KIND) { + if (KIND === DEFAULT && defaultIterator) return defaultIterator; + if (!BUGGY_SAFARI_ITERATORS && KIND && KIND in IterablePrototype) return IterablePrototype[KIND]; + + switch (KIND) { + case KEYS: return function keys() { return new IteratorConstructor(this, KIND); }; + case VALUES: return function values() { return new IteratorConstructor(this, KIND); }; + case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); }; + } + + return function () { return new IteratorConstructor(this); }; + }; + + var TO_STRING_TAG = NAME + ' Iterator'; + var INCORRECT_VALUES_NAME = false; + var IterablePrototype = Iterable.prototype; + var nativeIterator = IterablePrototype[ITERATOR] + || IterablePrototype['@@iterator'] + || DEFAULT && IterablePrototype[DEFAULT]; + var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT); + var anyNativeIterator = NAME === 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator; + var CurrentIteratorPrototype, methods, KEY; + + // fix native + if (anyNativeIterator) { + CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable())); + if (CurrentIteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) { + if (!IS_PURE && getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) { + if (setPrototypeOf) { + setPrototypeOf(CurrentIteratorPrototype, IteratorPrototype); + } else if (!isCallable(CurrentIteratorPrototype[ITERATOR])) { + defineBuiltIn(CurrentIteratorPrototype, ITERATOR, returnThis); + } + } + // Set @@toStringTag to native iterators + setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true); + if (IS_PURE) Iterators[TO_STRING_TAG] = returnThis; + } + } + + // fix Array.prototype.{ values, @@iterator }.name in V8 / FF + if (PROPER_FUNCTION_NAME && DEFAULT === VALUES && nativeIterator && nativeIterator.name !== VALUES) { + if (!IS_PURE && CONFIGURABLE_FUNCTION_NAME) { + createNonEnumerableProperty(IterablePrototype, 'name', VALUES); + } else { + INCORRECT_VALUES_NAME = true; + defaultIterator = function values() { return call(nativeIterator, this); }; + } + } + + // export additional methods + if (DEFAULT) { + methods = { + values: getIterationMethod(VALUES), + keys: IS_SET ? defaultIterator : getIterationMethod(KEYS), + entries: getIterationMethod(ENTRIES) + }; + if (FORCED) for (KEY in methods) { + if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) { + defineBuiltIn(IterablePrototype, KEY, methods[KEY]); + } + } else $({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods); + } + + // define iterator + if ((!IS_PURE || FORCED) && IterablePrototype[ITERATOR] !== defaultIterator) { + defineBuiltIn(IterablePrototype, ITERATOR, defaultIterator, { name: DEFAULT }); + } + Iterators[NAME] = defaultIterator; + + return methods; +}; + + +/***/ }), +/* 348 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove this module from `core-js@4` since it's replaced to module below +__webpack_require__(349); + + +/***/ }), +/* 349 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var FREEZING = __webpack_require__(181); +var globalThis = __webpack_require__(2); +var uncurryThis = __webpack_require__(6); +var defineBuiltIns = __webpack_require__(146); +var InternalMetadataModule = __webpack_require__(342); +var collection = __webpack_require__(341); +var collectionWeak = __webpack_require__(350); +var isObject = __webpack_require__(27); +var enforceInternalState = __webpack_require__(55).enforce; +var fails = __webpack_require__(8); +var NATIVE_WEAK_MAP = __webpack_require__(56); + +var $Object = Object; +// eslint-disable-next-line es/no-array-isarray -- safe +var isArray = Array.isArray; +// eslint-disable-next-line es/no-object-isextensible -- safe +var isExtensible = $Object.isExtensible; +// eslint-disable-next-line es/no-object-isfrozen -- safe +var isFrozen = $Object.isFrozen; +// eslint-disable-next-line es/no-object-issealed -- safe +var isSealed = $Object.isSealed; +// eslint-disable-next-line es/no-object-freeze -- safe +var freeze = $Object.freeze; +// eslint-disable-next-line es/no-object-seal -- safe +var seal = $Object.seal; + +var IS_IE11 = !globalThis.ActiveXObject && 'ActiveXObject' in globalThis; +var InternalWeakMap; + +var wrapper = function (init) { + return function WeakMap() { + return init(this, arguments.length ? arguments[0] : undefined); + }; +}; + +// `WeakMap` constructor +// https://tc39.es/ecma262/#sec-weakmap-constructor +var $WeakMap = collection('WeakMap', wrapper, collectionWeak); +var WeakMapPrototype = $WeakMap.prototype; +var nativeSet = uncurryThis(WeakMapPrototype.set); + +// Chakra Edge bug: adding frozen arrays to WeakMap unfreeze them +var hasMSEdgeFreezingBug = function () { + return FREEZING && fails(function () { + var frozenArray = freeze([]); + nativeSet(new $WeakMap(), frozenArray, 1); + return !isFrozen(frozenArray); + }); +}; + +// IE11 WeakMap frozen keys fix +// We can't use feature detection because it crash some old IE builds +// https://github.com/zloirock/core-js/issues/485 +if (NATIVE_WEAK_MAP) if (IS_IE11) { + InternalWeakMap = collectionWeak.getConstructor(wrapper, 'WeakMap', true); + InternalMetadataModule.enable(); + var nativeDelete = uncurryThis(WeakMapPrototype['delete']); + var nativeHas = uncurryThis(WeakMapPrototype.has); + var nativeGet = uncurryThis(WeakMapPrototype.get); + defineBuiltIns(WeakMapPrototype, { + 'delete': function (key) { + if (isObject(key) && !isExtensible(key)) { + var state = enforceInternalState(this); + if (!state.frozen) state.frozen = new InternalWeakMap(); + return nativeDelete(this, key) || state.frozen['delete'](key); + } return nativeDelete(this, key); + }, + has: function has(key) { + if (isObject(key) && !isExtensible(key)) { + var state = enforceInternalState(this); + if (!state.frozen) state.frozen = new InternalWeakMap(); + return nativeHas(this, key) || state.frozen.has(key); + } return nativeHas(this, key); + }, + get: function get(key) { + if (isObject(key) && !isExtensible(key)) { + var state = enforceInternalState(this); + if (!state.frozen) state.frozen = new InternalWeakMap(); + return nativeHas(this, key) ? nativeGet(this, key) : state.frozen.get(key); + } return nativeGet(this, key); + }, + set: function set(key, value) { + if (isObject(key) && !isExtensible(key)) { + var state = enforceInternalState(this); + if (!state.frozen) state.frozen = new InternalWeakMap(); + nativeHas(this, key) ? nativeSet(this, key, value) : state.frozen.set(key, value); + } else nativeSet(this, key, value); + return this; + } + }); +// Chakra Edge frozen keys fix +} else if (hasMSEdgeFreezingBug()) { + defineBuiltIns(WeakMapPrototype, { + set: function set(key, value) { + var arrayIntegrityLevel; + if (isArray(key)) { + if (isFrozen(key)) arrayIntegrityLevel = freeze; + else if (isSealed(key)) arrayIntegrityLevel = seal; + } + nativeSet(this, key, value); + if (arrayIntegrityLevel) arrayIntegrityLevel(key); + return this; + } + }); +} + + +/***/ }), +/* 350 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var defineBuiltIns = __webpack_require__(146); +var getWeakData = __webpack_require__(342).getWeakData; +var anInstance = __webpack_require__(145); +var anObject = __webpack_require__(30); +var isNullOrUndefined = __webpack_require__(11); +var isObject = __webpack_require__(27); +var iterate = __webpack_require__(97); +var ArrayIterationModule = __webpack_require__(298); +var hasOwn = __webpack_require__(5); +var InternalStateModule = __webpack_require__(55); + +var setInternalState = InternalStateModule.set; +var internalStateGetterFor = InternalStateModule.getterFor; +var find = ArrayIterationModule.find; +var findIndex = ArrayIterationModule.findIndex; +var splice = uncurryThis([].splice); +var id = 0; + +// fallback for uncaught frozen keys +var uncaughtFrozenStore = function (state) { + return state.frozen || (state.frozen = new UncaughtFrozenStore()); +}; + +var UncaughtFrozenStore = function () { + this.entries = []; +}; + +var findUncaughtFrozen = function (store, key) { + return find(store.entries, function (it) { + return it[0] === key; + }); +}; + +UncaughtFrozenStore.prototype = { + get: function (key) { + var entry = findUncaughtFrozen(this, key); + if (entry) return entry[1]; + }, + has: function (key) { + return !!findUncaughtFrozen(this, key); + }, + set: function (key, value) { + var entry = findUncaughtFrozen(this, key); + if (entry) entry[1] = value; + else this.entries.push([key, value]); + }, + 'delete': function (key) { + var index = findIndex(this.entries, function (it) { + return it[0] === key; + }); + if (~index) splice(this.entries, index, 1); + return !!~index; + } +}; + +module.exports = { + getConstructor: function (wrapper, CONSTRUCTOR_NAME, IS_MAP, ADDER) { + var Constructor = wrapper(function (that, iterable) { + anInstance(that, Prototype); + setInternalState(that, { + type: CONSTRUCTOR_NAME, + id: id++, + frozen: null + }); + if (!isNullOrUndefined(iterable)) iterate(iterable, that[ADDER], { that: that, AS_ENTRIES: IS_MAP }); + }); + + var Prototype = Constructor.prototype; + + var getInternalState = internalStateGetterFor(CONSTRUCTOR_NAME); + + var define = function (that, key, value) { + var state = getInternalState(that); + var data = getWeakData(anObject(key), true); + if (data === true) uncaughtFrozenStore(state).set(key, value); + else data[state.id] = value; + return that; + }; + + defineBuiltIns(Prototype, { + // `{ WeakMap, WeakSet }.prototype.delete(key)` methods + // https://tc39.es/ecma262/#sec-weakmap.prototype.delete + // https://tc39.es/ecma262/#sec-weakset.prototype.delete + 'delete': function (key) { + var state = getInternalState(this); + if (!isObject(key)) return false; + var data = getWeakData(key); + if (data === true) return uncaughtFrozenStore(state)['delete'](key); + return data && hasOwn(data, state.id) && delete data[state.id]; + }, + // `{ WeakMap, WeakSet }.prototype.has(key)` methods + // https://tc39.es/ecma262/#sec-weakmap.prototype.has + // https://tc39.es/ecma262/#sec-weakset.prototype.has + has: function has(key) { + var state = getInternalState(this); + if (!isObject(key)) return false; + var data = getWeakData(key); + if (data === true) return uncaughtFrozenStore(state).has(key); + return data && hasOwn(data, state.id); + } + }); + + defineBuiltIns(Prototype, IS_MAP ? { + // `WeakMap.prototype.get(key)` method + // https://tc39.es/ecma262/#sec-weakmap.prototype.get + get: function get(key) { + var state = getInternalState(this); + if (isObject(key)) { + var data = getWeakData(key); + if (data === true) return uncaughtFrozenStore(state).get(key); + if (data) return data[state.id]; + } + }, + // `WeakMap.prototype.set(key, value)` method + // https://tc39.es/ecma262/#sec-weakmap.prototype.set + set: function set(key, value) { + return define(this, key, value); + } + } : { + // `WeakSet.prototype.add(value)` method + // https://tc39.es/ecma262/#sec-weakset.prototype.add + add: function add(value) { + return define(this, value, true); + } + }); + + return Constructor; + } +}; + + +/***/ }), +/* 351 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getCompositeKeyNode = __webpack_require__(338); +var getBuiltIn = __webpack_require__(35); +var apply = __webpack_require__(72); + +// https://github.com/tc39/proposal-richer-keys/tree/master/compositeKey +$({ global: true, forced: true }, { + compositeSymbol: function compositeSymbol() { + if (arguments.length === 1 && typeof arguments[0] == 'string') return getBuiltIn('Symbol')['for'](arguments[0]); + return apply(getCompositeKeyNode, null, arguments).get('symbol', getBuiltIn('Symbol')); + } +}); + + +/***/ }), +/* 352 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); + +// eslint-disable-next-line es/no-typed-arrays -- safe +var getUint8 = uncurryThis(DataView.prototype.getUint8); + +// `DataView.prototype.getUint8Clamped` method +// https://github.com/tc39/proposal-dataview-get-set-uint8clamped +$({ target: 'DataView', proto: true, forced: true }, { + getUint8Clamped: function getUint8Clamped(byteOffset) { + return getUint8(this, byteOffset); + } +}); + + +/***/ }), +/* 353 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var aDataView = __webpack_require__(126); +var toIndex = __webpack_require__(127); +var toUint8Clamped = __webpack_require__(354); + +// eslint-disable-next-line es/no-typed-arrays -- safe +var setUint8 = uncurryThis(DataView.prototype.setUint8); + +// `DataView.prototype.setUint8Clamped` method +// https://github.com/tc39/proposal-dataview-get-set-uint8clamped +$({ target: 'DataView', proto: true, forced: true }, { + setUint8Clamped: function setUint8Clamped(byteOffset, value) { + setUint8( + aDataView(this), + toIndex(byteOffset), + toUint8Clamped(value) + ); + } +}); + + +/***/ }), +/* 354 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var round = Math.round; + +module.exports = function (it) { + var value = round(it); + return value < 0 ? 0 : value > 0xFF ? 0xFF : value & 0xFF; +}; + + +/***/ }), +/* 355 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var demethodize = __webpack_require__(356); + +// `Function.prototype.demethodize` method +// https://github.com/js-choi/proposal-function-demethodize +$({ target: 'Function', proto: true, forced: true }, { + demethodize: demethodize +}); + + +/***/ }), +/* 356 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var aCallable = __webpack_require__(38); + +module.exports = function demethodize() { + return uncurryThis(aCallable(this)); +}; + + +/***/ }), +/* 357 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var $isCallable = __webpack_require__(28); +var inspectSource = __webpack_require__(54); +var hasOwn = __webpack_require__(5); +var DESCRIPTORS = __webpack_require__(24); + +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; +var classRegExp = /^\s*class\b/; +var exec = uncurryThis(classRegExp.exec); + +var isClassConstructor = function (argument) { + try { + // `Function#toString` throws on some built-it function in some legacy engines + // (for example, `DOMQuad` and similar in FF41-) + if (!DESCRIPTORS || !exec(classRegExp, inspectSource(argument))) return false; + } catch (error) { /* empty */ } + var prototype = getOwnPropertyDescriptor(argument, 'prototype'); + return !!prototype && hasOwn(prototype, 'writable') && !prototype.writable; +}; + +// `Function.isCallable` method +// https://github.com/caitp/TC39-Proposals/blob/trunk/tc39-reflect-isconstructor-iscallable.md +$({ target: 'Function', stat: true, sham: true, forced: true }, { + isCallable: function isCallable(argument) { + return $isCallable(argument) && !isClassConstructor(argument); + } +}); + + +/***/ }), +/* 358 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isConstructor = __webpack_require__(199); + +// `Function.isConstructor` method +// https://github.com/caitp/TC39-Proposals/blob/trunk/tc39-reflect-isconstructor-iscallable.md +$({ target: 'Function', stat: true, forced: true }, { + isConstructor: isConstructor +}); + + +/***/ }), +/* 359 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var wellKnownSymbol = __webpack_require__(13); +var defineProperty = __webpack_require__(23).f; + +var METADATA = wellKnownSymbol('metadata'); +var FunctionPrototype = Function.prototype; + +// Function.prototype[@@metadata] +// https://github.com/tc39/proposal-decorator-metadata +if (FunctionPrototype[METADATA] === undefined) { + defineProperty(FunctionPrototype, METADATA, { + value: null + }); +} + + +/***/ }), +/* 360 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var demethodize = __webpack_require__(356); + +// `Function.prototype.unThis` method +// https://github.com/js-choi/proposal-function-demethodize +// TODO: Remove from `core-js@4` +$({ target: 'Function', proto: true, forced: true, name: 'demethodize' }, { + unThis: demethodize +}); + + +/***/ }), +/* 361 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var indexed = __webpack_require__(362); + +// `Iterator.prototype.asIndexedPairs` method +// https://github.com/tc39/proposal-iterator-helpers +$({ target: 'Iterator', name: 'indexed', proto: true, real: true, forced: true }, { + asIndexedPairs: indexed +}); + + +/***/ }), +/* 362 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +__webpack_require__(170); +var call = __webpack_require__(33); +var map = __webpack_require__(150).IteratorPrototype.map; + +var callback = function (value, counter) { + return [counter, value]; +}; + +// `Iterator.prototype.indexed` method +// https://github.com/tc39/proposal-iterator-helpers +module.exports = function indexed() { + return call(map, this, callback); +}; + + +/***/ }), +/* 363 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var anObject = __webpack_require__(30); +var call = __webpack_require__(33); +var createIteratorProxy = __webpack_require__(152); +var getIteratorDirect = __webpack_require__(157); +var iteratorClose = __webpack_require__(104); +var uncurryThis = __webpack_require__(6); + +var $RangeError = RangeError; +var push = uncurryThis([].push); + +var IteratorProxy = createIteratorProxy(function () { + var iterator = this.iterator; + var next = this.next; + var chunkSize = this.chunkSize; + var buffer = []; + var result, done; + while (true) { + result = anObject(call(next, iterator)); + done = !!result.done; + if (done) { + if (buffer.length) return buffer; + this.done = true; + return; + } + push(buffer, result.value); + if (buffer.length === chunkSize) return buffer; + } +}); + +// `Iterator.prototype.chunks` method +// https://github.com/tc39/proposal-iterator-chunking +$({ target: 'Iterator', proto: true, real: true, forced: true }, { + chunks: function chunks(chunkSize) { + var O = anObject(this); + if (typeof chunkSize != 'number' || !chunkSize || chunkSize >>> 0 !== chunkSize) { + return iteratorClose(O, 'throw', new $RangeError('chunkSize must be integer in [1, 2^32-1]')); + } + return new IteratorProxy(getIteratorDirect(O), { + chunkSize: chunkSize + }); + } +}); + + +/***/ }), +/* 364 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var indexed = __webpack_require__(362); + +// `Iterator.prototype.indexed` method +// https://github.com/tc39/proposal-iterator-helpers +$({ target: 'Iterator', proto: true, real: true, forced: true }, { + indexed: indexed +}); + + +/***/ }), +/* 365 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +/* eslint-disable es/no-bigint -- safe */ +var $ = __webpack_require__(49); +var NumericRangeIterator = __webpack_require__(335); + +var $TypeError = TypeError; + +// `Iterator.range` method +// https://github.com/tc39/proposal-Number.range +$({ target: 'Iterator', stat: true, forced: true }, { + range: function range(start, end, option) { + if (typeof start == 'number') return new NumericRangeIterator(start, end, option, 'number', 0, 1); + if (typeof start == 'bigint') return new NumericRangeIterator(start, end, option, 'bigint', BigInt(0), BigInt(1)); + throw new $TypeError('Incorrect Iterator.range arguments'); + } +}); + + +/***/ }), +/* 366 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var iteratorWindow = __webpack_require__(367); + +// `Iterator.prototype.sliding` method +// https://github.com/tc39/proposal-iterator-chunking +$({ target: 'Iterator', proto: true, real: true, forced: true }, { + sliding: function sliding(windowSize) { + return iteratorWindow(this, windowSize, 'allow-partial'); + } +}); + + +/***/ }), +/* 367 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var anObject = __webpack_require__(30); +var call = __webpack_require__(33); +var createIteratorProxy = __webpack_require__(152); +var createIterResultObject = __webpack_require__(153); +var getIteratorDirect = __webpack_require__(157); +var iteratorClose = __webpack_require__(104); +var uncurryThis = __webpack_require__(6); + +var $RangeError = RangeError; +var $TypeError = TypeError; +var push = uncurryThis([].push); +var slice = uncurryThis([].slice); +var ALLOW_PARTIAL = 'allow-partial'; + +var IteratorProxy = createIteratorProxy(function () { + var iterator = this.iterator; + var next = this.next; + var buffer = this.buffer; + var windowSize = this.windowSize; + var allowPartial = this.allowPartial; + var result, done; + while (true) { + result = anObject(call(next, iterator)); + done = this.done = !!result.done; + if (allowPartial && done && buffer.length && buffer.length < windowSize) return createIterResultObject(buffer, false); + if (done) return createIterResultObject(undefined, true); + + if (buffer.length === windowSize) this.buffer = buffer = slice(buffer, 1); + push(buffer, result.value); + if (buffer.length === windowSize) return createIterResultObject(buffer, false); + } +}, false, true); + +// `Iterator.prototype.windows` and obsolete `Iterator.prototype.sliding` methods +// https://github.com/tc39/proposal-iterator-chunking +module.exports = function (O, windowSize, undersized) { + anObject(O); + if (typeof windowSize != 'number' || !windowSize || windowSize >>> 0 !== windowSize) { + return iteratorClose(O, 'throw', new $RangeError('`windowSize` must be integer in [1, 2^32-1]')); + } + if (undersized !== undefined && undersized !== 'only-full' && undersized !== ALLOW_PARTIAL) { + return iteratorClose(O, 'throw', new $TypeError('Incorrect `undersized` argument')); + } + return new IteratorProxy(getIteratorDirect(O), { + windowSize: windowSize, + buffer: [], + allowPartial: undersized === ALLOW_PARTIAL + }); +}; + + +/***/ }), +/* 368 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var anObject = __webpack_require__(30); +var AsyncFromSyncIterator = __webpack_require__(229); +var WrapAsyncIterator = __webpack_require__(327); +var getIteratorDirect = __webpack_require__(157); + +// `Iterator.prototype.toAsync` method +// https://github.com/tc39/proposal-async-iterator-helpers +$({ target: 'Iterator', proto: true, real: true, forced: true }, { + toAsync: function toAsync() { + return new WrapAsyncIterator(getIteratorDirect(new AsyncFromSyncIterator(getIteratorDirect(anObject(this))))); + } +}); + + +/***/ }), +/* 369 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var iteratorWindow = __webpack_require__(367); + +// `Iterator.prototype.windows` method +// https://github.com/tc39/proposal-iterator-chunking +$({ target: 'Iterator', proto: true, real: true, forced: true }, { + windows: function windows(windowSize /* , undersized */) { + return iteratorWindow(this, windowSize, arguments.length < 2 ? undefined : arguments[1]); + } +}); + + +/***/ }), +/* 370 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var anObject = __webpack_require__(30); +var anObjectOrUndefined = __webpack_require__(287); +var call = __webpack_require__(33); +var uncurryThis = __webpack_require__(6); +var getIteratorRecord = __webpack_require__(371); +var getIteratorFlattenable = __webpack_require__(167); +var getModeOption = __webpack_require__(372); +var iteratorClose = __webpack_require__(104); +var iteratorCloseAll = __webpack_require__(154); +var iteratorZip = __webpack_require__(373); + +var concat = uncurryThis([].concat); +var push = uncurryThis([].push); +var THROW = 'throw'; + +// `Iterator.zip` method +// https://github.com/tc39/proposal-joint-iteration +$({ target: 'Iterator', stat: true }, { + zip: function zip(iterables /* , options */) { + anObject(iterables); + var options = arguments.length > 1 ? anObjectOrUndefined(arguments[1]) : undefined; + var mode = getModeOption(options); + var paddingOption = mode === 'longest' ? anObjectOrUndefined(options && options.padding) : undefined; + + var iters = []; + var padding = []; + var inputIter = getIteratorRecord(iterables); + var iter, done, next; + while (!done) { + try { + next = anObject(call(inputIter.next, inputIter.iterator)); + done = next.done; + } catch (error) { + return iteratorCloseAll(iters, THROW, error); + } + if (!done) { + try { + iter = getIteratorFlattenable(next.value, true); + } catch (error) { + return iteratorCloseAll(concat([inputIter.iterator], iters), THROW, error); + } + push(iters, iter); + } + } + + var iterCount = iters.length; + var i, paddingDone, paddingIter; + if (mode === 'longest') { + if (paddingOption === undefined) { + for (i = 0; i < iterCount; i++) push(padding, undefined); + } else { + try { + paddingIter = getIteratorRecord(paddingOption); + } catch (error) { + return iteratorCloseAll(iters, THROW, error); + } + var usingIterator = true; + for (i = 0; i < iterCount; i++) { + if (usingIterator) { + try { + next = anObject(call(paddingIter.next, paddingIter.iterator)); + paddingDone = next.done; + next = next.value; + } catch (error) { + return iteratorCloseAll(iters, THROW, error); + } + if (paddingDone) { + usingIterator = false; + } else { + push(padding, next); + } + } else { + push(padding, undefined); + } + } + + if (usingIterator) { + try { + iteratorClose(paddingIter.iterator, 'normal'); + } catch (error) { + return iteratorCloseAll(iters, THROW, error); + } + } + } + } + + return iteratorZip(iters, mode, padding); + } +}); + + +/***/ }), +/* 371 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getIterator = __webpack_require__(102); +var getIteratorDirect = __webpack_require__(157); + +module.exports = function (argument) { + return getIteratorDirect(getIterator(argument)); +}; + + +/***/ }), +/* 372 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $TypeError = TypeError; + +module.exports = function (options) { + var mode = options && options.mode; + if (mode === undefined || mode === 'shortest' || mode === 'longest' || mode === 'strict') return mode || 'shortest'; + throw new $TypeError('Incorrect `mode` option'); +}; + + +/***/ }), +/* 373 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var call = __webpack_require__(33); +var uncurryThis = __webpack_require__(6); +var createIteratorProxy = __webpack_require__(152); +var iteratorCloseAll = __webpack_require__(154); + +var $TypeError = TypeError; +var slice = uncurryThis([].slice); +var push = uncurryThis([].push); +var ITERATOR_IS_EXHAUSTED = 'Iterator is exhausted'; +var THROW = 'throw'; + +// eslint-disable-next-line max-statements -- specification case +var IteratorProxy = createIteratorProxy(function () { + var iterCount = this.iterCount; + if (!iterCount) { + this.done = true; + return; + } + var openIters = this.openIters; + var iters = this.iters; + var padding = this.padding; + var mode = this.mode; + var finishResults = this.finishResults; + + var results = []; + var result, done; + for (var i = 0; i < iterCount; i++) { + var iter = iters[i]; + if (iter === null) { + result = padding[i]; + } else { + try { + result = call(iter.next, iter.iterator); + done = result.done; + result = result.value; + } catch (error) { + openIters[i] = undefined; + return iteratorCloseAll(openIters, THROW, error); + } + if (done) { + openIters[i] = undefined; + this.openItersCount--; + if (mode === 'shortest') { + this.done = true; + return iteratorCloseAll(openIters, 'normal', undefined); + } + if (mode === 'strict') { + if (i) { + return iteratorCloseAll(openIters, THROW, new $TypeError(ITERATOR_IS_EXHAUSTED)); + } + + var open, openDone; + for (var k = 1; k < iterCount; k++) { + // eslint-disable-next-line max-depth -- specification case + try { + open = call(iters[k].next, iters[k].iterator); + openDone = open.done; + open = open.value; + } catch (error) { + openIters[k] = undefined; + return iteratorCloseAll(openIters, THROW, open); + } + // eslint-disable-next-line max-depth -- specification case + if (openDone) { + openIters[k] = undefined; + this.openItersCount--; + } else { + return iteratorCloseAll(openIters, THROW, new $TypeError(ITERATOR_IS_EXHAUSTED)); + } + } + this.done = true; + return; + } + if (!this.openItersCount) { + this.done = true; + return; + } + iters[i] = null; + result = padding[i]; + } + } + push(results, result); + } + + return finishResults ? finishResults(results) : results; +}); + +module.exports = function (iters, mode, padding, finishResults) { + var iterCount = iters.length; + return new IteratorProxy({ + iters: iters, + iterCount: iterCount, + openIters: slice(iters, 0), + openItersCount: iterCount, + mode: mode, + padding: padding, + finishResults: finishResults + }); +}; + + +/***/ }), +/* 374 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var anObject = __webpack_require__(30); +var anObjectOrUndefined = __webpack_require__(287); +var createProperty = __webpack_require__(149); +var call = __webpack_require__(33); +var uncurryThis = __webpack_require__(6); +var getBuiltIn = __webpack_require__(35); +var propertyIsEnumerableModule = __webpack_require__(42); +var getIteratorFlattenable = __webpack_require__(167); +var getModeOption = __webpack_require__(372); +var iteratorCloseAll = __webpack_require__(154); +var iteratorZip = __webpack_require__(373); + +var create = getBuiltIn('Object', 'create'); +var ownKeys = getBuiltIn('Reflect', 'ownKeys'); +var push = uncurryThis([].push); +var THROW = 'throw'; + +// `Iterator.zipKeyed` method +// https://github.com/tc39/proposal-joint-iteration +$({ target: 'Iterator', stat: true }, { + zipKeyed: function zipKeyed(iterables /* , options */) { + anObject(iterables); + var options = arguments.length > 1 ? anObjectOrUndefined(arguments[1]) : undefined; + var mode = getModeOption(options); + var paddingOption = mode === 'longest' ? anObjectOrUndefined(options && options.padding) : undefined; + + var iters = []; + var padding = []; + var allKeys = ownKeys(iterables); + var keys = []; + var propertyIsEnumerable = propertyIsEnumerableModule.f; + var i, key, value; + for (i = 0; i < allKeys.length; i++) try { + key = allKeys[i]; + if (!call(propertyIsEnumerable, iterables, key)) continue; + value = iterables[key]; + if (value !== undefined) { + push(keys, key); + push(iters, getIteratorFlattenable(value, true)); + } + } catch (error) { + return iteratorCloseAll(iters, THROW, error); + } + + var iterCount = iters.length; + if (mode === 'longest') { + if (paddingOption === undefined) { + for (i = 0; i < iterCount; i++) push(padding, undefined); + } else { + for (i = 0; i < keys.length; i++) { + try { + value = paddingOption[keys[i]]; + } catch (error) { + return iteratorCloseAll(iters, THROW, error); + } + push(padding, value); + } + } + } + + return iteratorZip(iters, mode, padding, function (results) { + var obj = create(null); + for (var j = 0; j < iterCount; j++) { + createProperty(obj, keys[j], results[j]); + } + return obj; + }); + } +}); + + +/***/ }), +/* 375 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aMap = __webpack_require__(376); +var remove = __webpack_require__(185).remove; + +// `Map.prototype.deleteAll` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + deleteAll: function deleteAll(/* ...elements */) { + var collection = aMap(this); + var allDeleted = true; + var wasDeleted; + for (var k = 0, len = arguments.length; k < len; k++) { + wasDeleted = remove(collection, arguments[k]); + allDeleted = allDeleted && wasDeleted; + } return !!allDeleted; + } +}); + + +/***/ }), +/* 376 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var has = __webpack_require__(185).has; + +// Perform ? RequireInternalSlot(M, [[MapData]]) +module.exports = function (it) { + has(it); + return it; +}; + + +/***/ }), +/* 377 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aMap = __webpack_require__(376); +var MapHelpers = __webpack_require__(185); + +var get = MapHelpers.get; +var has = MapHelpers.has; +var set = MapHelpers.set; + +// `Map.prototype.emplace` method +// https://github.com/tc39/proposal-upsert +$({ target: 'Map', proto: true, real: true, forced: true }, { + emplace: function emplace(key, handler) { + var map = aMap(this); + var value, inserted; + if (has(map, key)) { + value = get(map, key); + if ('update' in handler) { + value = handler.update(value, key, map); + set(map, key, value); + } return value; + } + inserted = handler.insert(key, map); + set(map, key, inserted); + return inserted; + } +}); + + +/***/ }), +/* 378 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aMap = __webpack_require__(376); +var iterate = __webpack_require__(313); + +// `Map.prototype.every` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + every: function every(callbackfn /* , thisArg */) { + var map = aMap(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return iterate(map, function (value, key) { + if (!boundFunction(value, key, map)) return false; + }, true) !== false; + } +}); + + +/***/ }), +/* 379 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aMap = __webpack_require__(376); +var MapHelpers = __webpack_require__(185); +var iterate = __webpack_require__(313); + +var Map = MapHelpers.Map; +var set = MapHelpers.set; + +// `Map.prototype.filter` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + filter: function filter(callbackfn /* , thisArg */) { + var map = aMap(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var newMap = new Map(); + iterate(map, function (value, key) { + if (boundFunction(value, key, map)) set(newMap, key, value); + }); + return newMap; + } +}); + + +/***/ }), +/* 380 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aMap = __webpack_require__(376); +var iterate = __webpack_require__(313); + +// `Map.prototype.find` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + find: function find(callbackfn /* , thisArg */) { + var map = aMap(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var result = iterate(map, function (value, key) { + if (boundFunction(value, key, map)) return { value: value }; + }, true); + return result && result.value; + } +}); + + +/***/ }), +/* 381 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aMap = __webpack_require__(376); +var iterate = __webpack_require__(313); + +// `Map.prototype.findKey` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + findKey: function findKey(callbackfn /* , thisArg */) { + var map = aMap(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var result = iterate(map, function (value, key) { + if (boundFunction(value, key, map)) return { key: key }; + }, true); + return result && result.key; + } +}); + + +/***/ }), +/* 382 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var MapHelpers = __webpack_require__(185); +var createCollectionFrom = __webpack_require__(383); + +// `Map.from` method +// https://tc39.github.io/proposal-setmap-offrom/#sec-map.from +$({ target: 'Map', stat: true, forced: true }, { + from: createCollectionFrom(MapHelpers.Map, MapHelpers.set, true) +}); + + +/***/ }), +/* 383 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// https://tc39.github.io/proposal-setmap-offrom/ +var bind = __webpack_require__(98); +var anObject = __webpack_require__(30); +var toObject = __webpack_require__(9); +var iterate = __webpack_require__(97); + +module.exports = function (C, adder, ENTRY) { + return function from(source /* , mapFn, thisArg */) { + var O = toObject(source); + var length = arguments.length; + var mapFn = length > 1 ? arguments[1] : undefined; + var mapping = mapFn !== undefined; + var boundFunction = mapping ? bind(mapFn, length > 2 ? arguments[2] : undefined) : undefined; + var result = new C(); + var n = 0; + iterate(O, function (nextItem) { + var entry = mapping ? boundFunction(nextItem, n++) : nextItem; + if (ENTRY) adder(result, anObject(entry)[0], entry[1]); + else adder(result, entry); + }); + return result; + }; +}; + + +/***/ }), +/* 384 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aMap = __webpack_require__(376); +var MapHelpers = __webpack_require__(185); +var IS_PURE = __webpack_require__(16); + +var get = MapHelpers.get; +var has = MapHelpers.has; +var set = MapHelpers.set; + +// `Map.prototype.getOrInsert` method +// https://github.com/tc39/proposal-upsert +$({ target: 'Map', proto: true, real: true, forced: IS_PURE }, { + getOrInsert: function getOrInsert(key, value) { + if (has(aMap(this), key)) return get(this, key); + set(this, key, value); + return value; + } +}); + + +/***/ }), +/* 385 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aCallable = __webpack_require__(38); +var aMap = __webpack_require__(376); +var MapHelpers = __webpack_require__(185); +var IS_PURE = __webpack_require__(16); + +var get = MapHelpers.get; +var has = MapHelpers.has; +var set = MapHelpers.set; + +// `Map.prototype.getOrInsertComputed` method +// https://github.com/tc39/proposal-upsert +$({ target: 'Map', proto: true, real: true, forced: IS_PURE }, { + getOrInsertComputed: function getOrInsertComputed(key, callbackfn) { + aMap(this); + aCallable(callbackfn); + if (has(this, key)) return get(this, key); + // CanonicalizeKeyedCollectionKey + if (key === 0 && 1 / key === -Infinity) key = 0; + var value = callbackfn(key); + set(this, key, value); + return value; + } +}); + + +/***/ }), +/* 386 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var sameValueZero = __webpack_require__(387); +var aMap = __webpack_require__(376); +var iterate = __webpack_require__(313); + +// `Map.prototype.includes` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + includes: function includes(searchElement) { + return iterate(aMap(this), function (value) { + if (sameValueZero(value, searchElement)) return true; + }, true) === true; + } +}); + + +/***/ }), +/* 387 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// `SameValueZero` abstract operation +// https://tc39.es/ecma262/#sec-samevaluezero +module.exports = function (x, y) { + // eslint-disable-next-line no-self-compare -- NaN check + return x === y || x !== x && y !== y; +}; + + +/***/ }), +/* 388 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var iterate = __webpack_require__(97); +var isCallable = __webpack_require__(28); +var aCallable = __webpack_require__(38); +var Map = __webpack_require__(185).Map; + +// `Map.keyBy` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', stat: true, forced: true }, { + keyBy: function keyBy(iterable, keyDerivative) { + var C = isCallable(this) ? this : Map; + var newMap = new C(); + aCallable(keyDerivative); + var setter = aCallable(newMap.set); + iterate(iterable, function (element) { + call(setter, newMap, keyDerivative(element), element); + }); + return newMap; + } +}); + + +/***/ }), +/* 389 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aMap = __webpack_require__(376); +var iterate = __webpack_require__(313); + +// `Map.prototype.keyOf` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + keyOf: function keyOf(searchElement) { + var result = iterate(aMap(this), function (value, key) { + if (value === searchElement) return { key: key }; + }, true); + return result && result.key; + } +}); + + +/***/ }), +/* 390 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aMap = __webpack_require__(376); +var MapHelpers = __webpack_require__(185); +var iterate = __webpack_require__(313); + +var Map = MapHelpers.Map; +var set = MapHelpers.set; + +// `Map.prototype.mapKeys` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + mapKeys: function mapKeys(callbackfn /* , thisArg */) { + var map = aMap(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var newMap = new Map(); + iterate(map, function (value, key) { + set(newMap, boundFunction(value, key, map), value); + }); + return newMap; + } +}); + + +/***/ }), +/* 391 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aMap = __webpack_require__(376); +var MapHelpers = __webpack_require__(185); +var iterate = __webpack_require__(313); + +var Map = MapHelpers.Map; +var set = MapHelpers.set; + +// `Map.prototype.mapValues` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + mapValues: function mapValues(callbackfn /* , thisArg */) { + var map = aMap(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var newMap = new Map(); + iterate(map, function (value, key) { + set(newMap, key, boundFunction(value, key, map)); + }); + return newMap; + } +}); + + +/***/ }), +/* 392 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aMap = __webpack_require__(376); +var iterate = __webpack_require__(97); +var set = __webpack_require__(185).set; + +// `Map.prototype.merge` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, arity: 1, forced: true }, { + // eslint-disable-next-line no-unused-vars -- required for `.length` + merge: function merge(iterable /* ...iterables */) { + var map = aMap(this); + var argumentsLength = arguments.length; + var i = 0; + while (i < argumentsLength) { + iterate(arguments[i++], function (key, value) { + set(map, key, value); + }, { AS_ENTRIES: true }); + } + return map; + } +}); + + +/***/ }), +/* 393 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var MapHelpers = __webpack_require__(185); +var createCollectionOf = __webpack_require__(394); + +// `Map.of` method +// https://tc39.github.io/proposal-setmap-offrom/#sec-map.of +$({ target: 'Map', stat: true, forced: true }, { + of: createCollectionOf(MapHelpers.Map, MapHelpers.set, true) +}); + + +/***/ }), +/* 394 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var anObject = __webpack_require__(30); + +// https://tc39.github.io/proposal-setmap-offrom/ +module.exports = function (C, adder, ENTRY) { + return function of() { + var result = new C(); + var length = arguments.length; + for (var index = 0; index < length; index++) { + var entry = arguments[index]; + if (ENTRY) adder(result, anObject(entry)[0], entry[1]); + else adder(result, entry); + } return result; + }; +}; + + +/***/ }), +/* 395 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aCallable = __webpack_require__(38); +var aMap = __webpack_require__(376); +var iterate = __webpack_require__(313); + +var $TypeError = TypeError; + +// `Map.prototype.reduce` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + reduce: function reduce(callbackfn /* , initialValue */) { + var map = aMap(this); + var noInitial = arguments.length < 2; + var accumulator = noInitial ? undefined : arguments[1]; + aCallable(callbackfn); + iterate(map, function (value, key) { + if (noInitial) { + noInitial = false; + accumulator = value; + } else { + accumulator = callbackfn(accumulator, value, key, map); + } + }); + if (noInitial) throw new $TypeError('Reduce of empty map with no initial value'); + return accumulator; + } +}); + + +/***/ }), +/* 396 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aMap = __webpack_require__(376); +var iterate = __webpack_require__(313); + +// `Map.prototype.some` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + some: function some(callbackfn /* , thisArg */) { + var map = aMap(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return iterate(map, function (value, key) { + if (boundFunction(value, key, map)) return true; + }, true) === true; + } +}); + + +/***/ }), +/* 397 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aCallable = __webpack_require__(38); +var aMap = __webpack_require__(376); +var MapHelpers = __webpack_require__(185); + +var $TypeError = TypeError; +var get = MapHelpers.get; +var has = MapHelpers.has; +var set = MapHelpers.set; + +// `Map.prototype.update` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Map', proto: true, real: true, forced: true }, { + update: function update(key, callback /* , thunk */) { + var map = aMap(this); + var length = arguments.length; + aCallable(callback); + var isPresentInMap = has(map, key); + if (!isPresentInMap && length < 3) { + throw new $TypeError('Updating absent value'); + } + var value = isPresentInMap ? get(map, key) : aCallable(length > 2 ? arguments[2] : undefined)(key, map); + set(map, key, callback(value, key, map)); + return map; + } +}); + + +/***/ }), +/* 398 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var clamp = __webpack_require__(399); + +// TODO: Remove from `core-js@4` +// `Math.clamp` method +// https://github.com/tc39/proposal-math-clamp +$({ target: 'Math', stat: true, forced: true }, { + clamp: clamp +}); + + +/***/ }), +/* 399 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var aNumber = __webpack_require__(400); + +var $min = Math.min; +var $max = Math.max; + +module.exports = function clamp(value, min, max) { + return $min($max(aNumber(value), aNumber(min)), aNumber(max)); +}; + + +/***/ }), +/* 400 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $TypeError = TypeError; + +module.exports = function (argument) { + if (typeof argument == 'number') return argument; + throw new $TypeError('Argument is not a number'); +}; + + +/***/ }), +/* 401 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); + +// `Math.DEG_PER_RAD` constant +// https://rwaldron.github.io/proposal-math-extensions/ +$({ target: 'Math', stat: true, nonConfigurable: true, nonWritable: true }, { + DEG_PER_RAD: Math.PI / 180 +}); + + +/***/ }), +/* 402 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); + +var RAD_PER_DEG = 180 / Math.PI; + +// `Math.degrees` method +// https://rwaldron.github.io/proposal-math-extensions/ +$({ target: 'Math', stat: true, forced: true }, { + degrees: function degrees(radians) { + return radians * RAD_PER_DEG; + } +}); + + +/***/ }), +/* 403 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); + +var scale = __webpack_require__(404); +var fround = __webpack_require__(405); + +// `Math.fscale` method +// https://rwaldron.github.io/proposal-math-extensions/ +$({ target: 'Math', stat: true, forced: true }, { + fscale: function fscale(x, inLow, inHigh, outLow, outHigh) { + return fround(scale(x, inLow, inHigh, outLow, outHigh)); + } +}); + + +/***/ }), +/* 404 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// `Math.scale` method implementation +// https://rwaldron.github.io/proposal-math-extensions/ +module.exports = function scale(x, inLow, inHigh, outLow, outHigh) { + var nx = +x; + var nInLow = +inLow; + var nInHigh = +inHigh; + var nOutLow = +outLow; + var nOutHigh = +outHigh; + // eslint-disable-next-line no-self-compare -- NaN check + if (nx !== nx || nInLow !== nInLow || nInHigh !== nInHigh || nOutLow !== nOutLow || nOutHigh !== nOutHigh) return NaN; + if (nx === Infinity || nx === -Infinity) return nx; + return (nx - nInLow) * (nOutHigh - nOutLow) / (nInHigh - nInLow) + nOutLow; +}; + + +/***/ }), +/* 405 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var floatRound = __webpack_require__(187); + +var FLOAT32_EPSILON = 1.1920928955078125e-7; // 2 ** -23; +var FLOAT32_MAX_VALUE = 3.4028234663852886e+38; // 2 ** 128 - 2 ** 104 +var FLOAT32_MIN_VALUE = 1.1754943508222875e-38; // 2 ** -126; + +// `Math.fround` method implementation +// https://tc39.es/ecma262/#sec-math.fround +// eslint-disable-next-line es/no-math-fround -- safe +module.exports = Math.fround || function fround(x) { + return floatRound(x, FLOAT32_EPSILON, FLOAT32_MAX_VALUE, FLOAT32_MIN_VALUE); +}; + + +/***/ }), +/* 406 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); + +// `Math.RAD_PER_DEG` constant +// https://rwaldron.github.io/proposal-math-extensions/ +$({ target: 'Math', stat: true, nonConfigurable: true, nonWritable: true }, { + RAD_PER_DEG: 180 / Math.PI +}); + + +/***/ }), +/* 407 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); + +var DEG_PER_RAD = Math.PI / 180; + +// `Math.radians` method +// https://rwaldron.github.io/proposal-math-extensions/ +$({ target: 'Math', stat: true, forced: true }, { + radians: function radians(degrees) { + return degrees * DEG_PER_RAD; + } +}); + + +/***/ }), +/* 408 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var scale = __webpack_require__(404); + +// `Math.scale` method +// https://rwaldron.github.io/proposal-math-extensions/ +$({ target: 'Math', stat: true, forced: true }, { + scale: scale +}); + + +/***/ }), +/* 409 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); + +// `Math.signbit` method +// https://github.com/tc39/proposal-Math.signbit +$({ target: 'Math', stat: true, forced: true }, { + signbit: function signbit(x) { + var n = +x; + // eslint-disable-next-line no-self-compare -- NaN check + return n === n && n === 0 ? 1 / n === -Infinity : n < 0; + } +}); + + +/***/ }), +/* 410 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var $clamp = __webpack_require__(399); +var thisNumberValue = __webpack_require__(411); + +// `Number.prototype.clamp` method +// https://github.com/tc39/proposal-math-clamp +$({ target: 'Number', proto: true, forced: true }, { + clamp: function clamp(min, max) { + return $clamp(thisNumberValue(this), min, max); + } +}); + + +/***/ }), +/* 411 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +// `thisNumberValue` abstract operation +// https://tc39.es/ecma262/#sec-thisnumbervalue +module.exports = uncurryThis(1.1.valueOf); + + +/***/ }), +/* 412 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var toIntegerOrInfinity = __webpack_require__(65); + +var INVALID_NUMBER_REPRESENTATION = 'Invalid number representation'; +var INVALID_RADIX = 'Invalid radix'; +var $RangeError = RangeError; +var $SyntaxError = SyntaxError; +var $TypeError = TypeError; +var $parseInt = parseInt; +var pow = Math.pow; +var valid = /^[\d.a-z]+$/; +var charAt = uncurryThis(''.charAt); +var exec = uncurryThis(valid.exec); +var numberToString = uncurryThis(1.1.toString); +var stringSlice = uncurryThis(''.slice); +var split = uncurryThis(''.split); + +// `Number.fromString` method +// https://github.com/tc39/proposal-number-fromstring +$({ target: 'Number', stat: true, forced: true }, { + fromString: function fromString(string, radix) { + var sign = 1; + if (typeof string != 'string') throw new $TypeError(INVALID_NUMBER_REPRESENTATION); + if (!string.length) throw new $SyntaxError(INVALID_NUMBER_REPRESENTATION); + if (charAt(string, 0) === '-') { + sign = -1; + string = stringSlice(string, 1); + if (!string.length) throw new $SyntaxError(INVALID_NUMBER_REPRESENTATION); + } + var R = radix === undefined ? 10 : toIntegerOrInfinity(radix); + if (R < 2 || R > 36) throw new $RangeError(INVALID_RADIX); + if (!exec(valid, string)) throw new $SyntaxError(INVALID_NUMBER_REPRESENTATION); + var parts = split(string, '.'); + var mathNum = $parseInt(parts[0], R); + if (parts.length > 1) mathNum += $parseInt(parts[1], R) / pow(R, parts[1].length); + if (R === 10 && numberToString(mathNum, R) !== string) throw new $SyntaxError(INVALID_NUMBER_REPRESENTATION); + return sign * mathNum; + } +}); + + +/***/ }), +/* 413 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var NumericRangeIterator = __webpack_require__(335); + +// `Number.range` method +// https://github.com/tc39/proposal-Number.range +// TODO: Remove from `core-js@4` +$({ target: 'Number', stat: true, forced: true }, { + range: function range(start, end, option) { + return new NumericRangeIterator(start, end, option, 'number', 0, 1); + } +}); + + +/***/ }), +/* 414 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove this module from `core-js@4` since it's split to modules listed below +__webpack_require__(415); +__webpack_require__(416); +__webpack_require__(417); + + +/***/ }), +/* 415 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// https://github.com/tc39/proposal-observable +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var DESCRIPTORS = __webpack_require__(24); +var setSpecies = __webpack_require__(196); +var aCallable = __webpack_require__(38); +var anObject = __webpack_require__(30); +var anInstance = __webpack_require__(145); +var isCallable = __webpack_require__(28); +var isNullOrUndefined = __webpack_require__(11); +var isObject = __webpack_require__(27); +var getMethod = __webpack_require__(37); +var defineBuiltIn = __webpack_require__(51); +var defineBuiltIns = __webpack_require__(146); +var defineBuiltInAccessor = __webpack_require__(131); +var hostReportErrors = __webpack_require__(208); +var wellKnownSymbol = __webpack_require__(13); +var InternalStateModule = __webpack_require__(55); + +var $$OBSERVABLE = wellKnownSymbol('observable'); +var OBSERVABLE = 'Observable'; +var SUBSCRIPTION = 'Subscription'; +var SUBSCRIPTION_OBSERVER = 'SubscriptionObserver'; +var getterFor = InternalStateModule.getterFor; +var setInternalState = InternalStateModule.set; +var getObservableInternalState = getterFor(OBSERVABLE); +var getSubscriptionInternalState = getterFor(SUBSCRIPTION); +var getSubscriptionObserverInternalState = getterFor(SUBSCRIPTION_OBSERVER); + +var SubscriptionState = function (observer) { + this.observer = anObject(observer); + this.cleanup = null; + this.subscriptionObserver = null; +}; + +SubscriptionState.prototype = { + type: SUBSCRIPTION, + clean: function () { + var cleanup = this.cleanup; + if (cleanup) { + this.cleanup = null; + try { + cleanup(); + } catch (error) { + hostReportErrors(error); + } + } + }, + close: function () { + if (!DESCRIPTORS) { + var subscription = this.facade; + var subscriptionObserver = this.subscriptionObserver; + subscription.closed = true; + if (subscriptionObserver) subscriptionObserver.closed = true; + } this.observer = null; + }, + isClosed: function () { + return this.observer === null; + } +}; + +var Subscription = function (observer, subscriber) { + var subscriptionState = setInternalState(this, new SubscriptionState(observer)); + var start; + if (!DESCRIPTORS) this.closed = false; + try { + if (start = getMethod(observer, 'start')) call(start, observer, this); + } catch (error) { + hostReportErrors(error); + } + if (subscriptionState.isClosed()) return; + var subscriptionObserver = subscriptionState.subscriptionObserver = new SubscriptionObserver(subscriptionState); + try { + var cleanup = subscriber(subscriptionObserver); + var subscription = cleanup; + if (!isNullOrUndefined(cleanup)) subscriptionState.cleanup = isCallable(cleanup.unsubscribe) + ? function () { subscription.unsubscribe(); } + : aCallable(cleanup); + } catch (error) { + subscriptionObserver.error(error); + return; + } if (subscriptionState.isClosed()) subscriptionState.clean(); +}; + +Subscription.prototype = defineBuiltIns({}, { + unsubscribe: function unsubscribe() { + var subscriptionState = getSubscriptionInternalState(this); + if (!subscriptionState.isClosed()) { + subscriptionState.close(); + subscriptionState.clean(); + } + } +}); + +if (DESCRIPTORS) defineBuiltInAccessor(Subscription.prototype, 'closed', { + configurable: true, + get: function closed() { + return getSubscriptionInternalState(this).isClosed(); + } +}); + +var SubscriptionObserver = function (subscriptionState) { + setInternalState(this, { + type: SUBSCRIPTION_OBSERVER, + subscriptionState: subscriptionState + }); + if (!DESCRIPTORS) this.closed = false; +}; + +SubscriptionObserver.prototype = defineBuiltIns({}, { + next: function next(value) { + var subscriptionState = getSubscriptionObserverInternalState(this).subscriptionState; + if (!subscriptionState.isClosed()) { + var observer = subscriptionState.observer; + try { + var nextMethod = getMethod(observer, 'next'); + if (nextMethod) call(nextMethod, observer, value); + } catch (error) { + hostReportErrors(error); + } + } + }, + error: function error(value) { + var subscriptionState = getSubscriptionObserverInternalState(this).subscriptionState; + if (!subscriptionState.isClosed()) { + var observer = subscriptionState.observer; + subscriptionState.close(); + try { + var errorMethod = getMethod(observer, 'error'); + if (errorMethod) call(errorMethod, observer, value); + else hostReportErrors(value); + } catch (err) { + hostReportErrors(err); + } subscriptionState.clean(); + } + }, + complete: function complete() { + var subscriptionState = getSubscriptionObserverInternalState(this).subscriptionState; + if (!subscriptionState.isClosed()) { + var observer = subscriptionState.observer; + subscriptionState.close(); + try { + var completeMethod = getMethod(observer, 'complete'); + if (completeMethod) call(completeMethod, observer); + } catch (error) { + hostReportErrors(error); + } subscriptionState.clean(); + } + } +}); + +if (DESCRIPTORS) defineBuiltInAccessor(SubscriptionObserver.prototype, 'closed', { + configurable: true, + get: function closed() { + return getSubscriptionObserverInternalState(this).subscriptionState.isClosed(); + } +}); + +var $Observable = function Observable(subscriber) { + anInstance(this, ObservablePrototype); + setInternalState(this, { + type: OBSERVABLE, + subscriber: aCallable(subscriber) + }); +}; + +var ObservablePrototype = $Observable.prototype; + +defineBuiltIns(ObservablePrototype, { + subscribe: function subscribe(observer) { + var length = arguments.length; + return new Subscription(isCallable(observer) ? { + next: observer, + error: length > 1 ? arguments[1] : undefined, + complete: length > 2 ? arguments[2] : undefined + } : isObject(observer) ? observer : {}, getObservableInternalState(this).subscriber); + } +}); + +defineBuiltIn(ObservablePrototype, $$OBSERVABLE, function () { return this; }); + +$({ global: true, constructor: true, forced: true }, { + Observable: $Observable +}); + +setSpecies(OBSERVABLE); + + +/***/ }), +/* 416 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var call = __webpack_require__(33); +var anObject = __webpack_require__(30); +var isConstructor = __webpack_require__(199); +var getIterator = __webpack_require__(102); +var getMethod = __webpack_require__(37); +var iterate = __webpack_require__(97); +var wellKnownSymbol = __webpack_require__(13); + +var $$OBSERVABLE = wellKnownSymbol('observable'); + +// `Observable.from` method +// https://github.com/tc39/proposal-observable +$({ target: 'Observable', stat: true, forced: true }, { + from: function from(x) { + var C = isConstructor(this) ? this : getBuiltIn('Observable'); + var observableMethod = getMethod(anObject(x), $$OBSERVABLE); + if (observableMethod) { + var observable = anObject(call(observableMethod, x)); + return observable.constructor === C ? observable : new C(function (observer) { + return observable.subscribe(observer); + }); + } + var iterator = getIterator(x); + return new C(function (observer) { + iterate(iterator, function (it, stop) { + observer.next(it); + if (observer.closed) return stop(); + }, { IS_ITERATOR: true, INTERRUPTED: true }); + observer.complete(); + }); + } +}); + + +/***/ }), +/* 417 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var isConstructor = __webpack_require__(199); + +var Array = getBuiltIn('Array'); + +// `Observable.of` method +// https://github.com/tc39/proposal-observable +$({ target: 'Observable', stat: true, forced: true }, { + of: function of() { + var C = isConstructor(this) ? this : getBuiltIn('Observable'); + var length = arguments.length; + var items = Array(length); + var index = 0; + while (index < length) items[index] = arguments[index++]; + return new C(function (observer) { + for (var i = 0; i < length; i++) { + observer.next(items[i]); + if (observer.closed) return; + } observer.complete(); + }); + } +}); + + +/***/ }), +/* 418 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); + +var toMetadataKey = ReflectMetadataModule.toKey; +var ordinaryDefineOwnMetadata = ReflectMetadataModule.set; + +// `Reflect.defineMetadata` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + defineMetadata: function defineMetadata(metadataKey, metadataValue, target /* , targetKey */) { + var targetKey = arguments.length < 4 ? undefined : toMetadataKey(arguments[3]); + ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), targetKey); + } +}); + + +/***/ }), +/* 419 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: in core-js@4, move /modules/ dependencies to public entries for better optimization by tools like `preset-env` +__webpack_require__(339); +__webpack_require__(348); +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); +var shared = __webpack_require__(14); + +var Map = getBuiltIn('Map'); +var WeakMap = getBuiltIn('WeakMap'); +var push = uncurryThis([].push); + +var metadata = shared('metadata'); +var store = metadata.store || (metadata.store = new WeakMap()); + +var getOrCreateMetadataMap = function (target, targetKey, create) { + var targetMetadata = store.get(target); + if (!targetMetadata) { + if (!create) return; + store.set(target, targetMetadata = new Map()); + } + var keyMetadata = targetMetadata.get(targetKey); + if (!keyMetadata) { + if (!create) return; + targetMetadata.set(targetKey, keyMetadata = new Map()); + } return keyMetadata; +}; + +var ordinaryHasOwnMetadata = function (MetadataKey, O, P) { + var metadataMap = getOrCreateMetadataMap(O, P, false); + return metadataMap === undefined ? false : metadataMap.has(MetadataKey); +}; + +var ordinaryGetOwnMetadata = function (MetadataKey, O, P) { + var metadataMap = getOrCreateMetadataMap(O, P, false); + return metadataMap === undefined ? undefined : metadataMap.get(MetadataKey); +}; + +var ordinaryDefineOwnMetadata = function (MetadataKey, MetadataValue, O, P) { + getOrCreateMetadataMap(O, P, true).set(MetadataKey, MetadataValue); +}; + +var ordinaryOwnMetadataKeys = function (target, targetKey) { + var metadataMap = getOrCreateMetadataMap(target, targetKey, false); + var keys = []; + if (metadataMap) metadataMap.forEach(function (_, key) { push(keys, key); }); + return keys; +}; + +var toMetadataKey = function (it) { + return it === undefined || typeof it == 'symbol' ? it : String(it); +}; + +module.exports = { + store: store, + getMap: getOrCreateMetadataMap, + has: ordinaryHasOwnMetadata, + get: ordinaryGetOwnMetadata, + set: ordinaryDefineOwnMetadata, + keys: ordinaryOwnMetadataKeys, + toKey: toMetadataKey +}; + + +/***/ }), +/* 420 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); + +var toMetadataKey = ReflectMetadataModule.toKey; +var getOrCreateMetadataMap = ReflectMetadataModule.getMap; +var store = ReflectMetadataModule.store; + +// `Reflect.deleteMetadata` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + deleteMetadata: function deleteMetadata(metadataKey, target /* , targetKey */) { + var targetKey = arguments.length < 3 ? undefined : toMetadataKey(arguments[2]); + var metadataMap = getOrCreateMetadataMap(anObject(target), targetKey, false); + if (metadataMap === undefined || !metadataMap['delete'](metadataKey)) return false; + if (metadataMap.size) return true; + var targetMetadata = store.get(target); + targetMetadata['delete'](targetKey); + return !!targetMetadata.size || store['delete'](target); + } +}); + + +/***/ }), +/* 421 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); +var getPrototypeOf = __webpack_require__(91); + +var ordinaryHasOwnMetadata = ReflectMetadataModule.has; +var ordinaryGetOwnMetadata = ReflectMetadataModule.get; +var toMetadataKey = ReflectMetadataModule.toKey; + +var ordinaryGetMetadata = function (MetadataKey, O, P) { + var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P); + if (hasOwn) return ordinaryGetOwnMetadata(MetadataKey, O, P); + var parent = getPrototypeOf(O); + return parent !== null ? ordinaryGetMetadata(MetadataKey, parent, P) : undefined; +}; + +// `Reflect.getMetadata` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + getMetadata: function getMetadata(metadataKey, target /* , targetKey */) { + var targetKey = arguments.length < 3 ? undefined : toMetadataKey(arguments[2]); + return ordinaryGetMetadata(metadataKey, anObject(target), targetKey); + } +}); + + +/***/ }), +/* 422 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); +var getPrototypeOf = __webpack_require__(91); +var $arrayUniqueBy = __webpack_require__(312); + +var arrayUniqueBy = uncurryThis($arrayUniqueBy); +var concat = uncurryThis([].concat); +var ordinaryOwnMetadataKeys = ReflectMetadataModule.keys; +var toMetadataKey = ReflectMetadataModule.toKey; + +var ordinaryMetadataKeys = function (O, P) { + var oKeys = ordinaryOwnMetadataKeys(O, P); + var parent = getPrototypeOf(O); + if (parent === null) return oKeys; + var pKeys = ordinaryMetadataKeys(parent, P); + return pKeys.length ? oKeys.length ? arrayUniqueBy(concat(oKeys, pKeys)) : pKeys : oKeys; +}; + +// `Reflect.getMetadataKeys` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + getMetadataKeys: function getMetadataKeys(target /* , targetKey */) { + var targetKey = arguments.length < 2 ? undefined : toMetadataKey(arguments[1]); + return ordinaryMetadataKeys(anObject(target), targetKey); + } +}); + + +/***/ }), +/* 423 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); + +var ordinaryGetOwnMetadata = ReflectMetadataModule.get; +var toMetadataKey = ReflectMetadataModule.toKey; + +// `Reflect.getOwnMetadata` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + getOwnMetadata: function getOwnMetadata(metadataKey, target /* , targetKey */) { + var targetKey = arguments.length < 3 ? undefined : toMetadataKey(arguments[2]); + return ordinaryGetOwnMetadata(metadataKey, anObject(target), targetKey); + } +}); + + +/***/ }), +/* 424 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); + +var ordinaryOwnMetadataKeys = ReflectMetadataModule.keys; +var toMetadataKey = ReflectMetadataModule.toKey; + +// `Reflect.getOwnMetadataKeys` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + getOwnMetadataKeys: function getOwnMetadataKeys(target /* , targetKey */) { + var targetKey = arguments.length < 2 ? undefined : toMetadataKey(arguments[1]); + return ordinaryOwnMetadataKeys(anObject(target), targetKey); + } +}); + + +/***/ }), +/* 425 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); +var getPrototypeOf = __webpack_require__(91); + +var ordinaryHasOwnMetadata = ReflectMetadataModule.has; +var toMetadataKey = ReflectMetadataModule.toKey; + +var ordinaryHasMetadata = function (MetadataKey, O, P) { + var hasOwn = ordinaryHasOwnMetadata(MetadataKey, O, P); + if (hasOwn) return true; + var parent = getPrototypeOf(O); + return parent !== null ? ordinaryHasMetadata(MetadataKey, parent, P) : false; +}; + +// `Reflect.hasMetadata` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + hasMetadata: function hasMetadata(metadataKey, target /* , targetKey */) { + var targetKey = arguments.length < 3 ? undefined : toMetadataKey(arguments[2]); + return ordinaryHasMetadata(metadataKey, anObject(target), targetKey); + } +}); + + +/***/ }), +/* 426 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var $ = __webpack_require__(49); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); + +var ordinaryHasOwnMetadata = ReflectMetadataModule.has; +var toMetadataKey = ReflectMetadataModule.toKey; + +// `Reflect.hasOwnMetadata` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + hasOwnMetadata: function hasOwnMetadata(metadataKey, target /* , targetKey */) { + var targetKey = arguments.length < 3 ? undefined : toMetadataKey(arguments[2]); + return ordinaryHasOwnMetadata(metadataKey, anObject(target), targetKey); + } +}); + + +/***/ }), +/* 427 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var ReflectMetadataModule = __webpack_require__(419); +var anObject = __webpack_require__(30); + +var toMetadataKey = ReflectMetadataModule.toKey; +var ordinaryDefineOwnMetadata = ReflectMetadataModule.set; + +// `Reflect.metadata` method +// https://github.com/rbuckton/reflect-metadata +$({ target: 'Reflect', stat: true }, { + metadata: function metadata(metadataKey, metadataValue) { + return function decorator(target, key) { + ordinaryDefineOwnMetadata(metadataKey, metadataValue, anObject(target), toMetadataKey(key)); + }; + } +}); + + +/***/ }), +/* 428 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aSet = __webpack_require__(246); +var add = __webpack_require__(247).add; + +// `Set.prototype.addAll` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + addAll: function addAll(/* ...elements */) { + var set = aSet(this); + for (var k = 0, len = arguments.length; k < len; k++) { + add(set, arguments[k]); + } return set; + } +}); + + +/***/ }), +/* 429 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aSet = __webpack_require__(246); +var remove = __webpack_require__(247).remove; + +// `Set.prototype.deleteAll` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + deleteAll: function deleteAll(/* ...elements */) { + var collection = aSet(this); + var allDeleted = true; + var wasDeleted; + for (var k = 0, len = arguments.length; k < len; k++) { + wasDeleted = remove(collection, arguments[k]); + allDeleted = allDeleted && wasDeleted; + } return !!allDeleted; + } +}); + + +/***/ }), +/* 430 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var toSetLike = __webpack_require__(431); +var $difference = __webpack_require__(245); + +// `Set.prototype.difference` method +// https://github.com/tc39/proposal-set-methods +// TODO: Obsolete version, remove from `core-js@4` +$({ target: 'Set', proto: true, real: true, forced: true }, { + difference: function difference(other) { + return call($difference, this, toSetLike(other)); + } +}); + + +/***/ }), +/* 431 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); +var isCallable = __webpack_require__(28); +var isIterable = __webpack_require__(432); +var isObject = __webpack_require__(27); + +var Set = getBuiltIn('Set'); + +var isSetLike = function (it) { + return isObject(it) + && typeof it.size == 'number' + && isCallable(it.has) + && isCallable(it.keys); +}; + +// fallback old -> new set methods proposal arguments +module.exports = function (it) { + if (isSetLike(it)) return it; + return isIterable(it) ? new Set(it) : it; +}; + + +/***/ }), +/* 432 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var classof = __webpack_require__(82); +var hasOwn = __webpack_require__(5); +var isNullOrUndefined = __webpack_require__(11); +var wellKnownSymbol = __webpack_require__(13); +var Iterators = __webpack_require__(101); + +var ITERATOR = wellKnownSymbol('iterator'); +var $Object = Object; + +module.exports = function (it) { + if (isNullOrUndefined(it)) return false; + var O = $Object(it); + return O[ITERATOR] !== undefined + || '@@iterator' in O + || hasOwn(Iterators, classof(O)); +}; + + +/***/ }), +/* 433 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aSet = __webpack_require__(246); +var iterate = __webpack_require__(249); + +// `Set.prototype.every` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + every: function every(callbackfn /* , thisArg */) { + var set = aSet(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return iterate(set, function (value) { + if (!boundFunction(value, value, set)) return false; + }, true) !== false; + } +}); + + +/***/ }), +/* 434 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aSet = __webpack_require__(246); +var SetHelpers = __webpack_require__(247); +var iterate = __webpack_require__(249); + +var Set = SetHelpers.Set; +var add = SetHelpers.add; + +// `Set.prototype.filter` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + filter: function filter(callbackfn /* , thisArg */) { + var set = aSet(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var newSet = new Set(); + iterate(set, function (value) { + if (boundFunction(value, value, set)) add(newSet, value); + }); + return newSet; + } +}); + + +/***/ }), +/* 435 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aSet = __webpack_require__(246); +var iterate = __webpack_require__(249); + +// `Set.prototype.find` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + find: function find(callbackfn /* , thisArg */) { + var set = aSet(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var result = iterate(set, function (value) { + if (boundFunction(value, value, set)) return { value: value }; + }, true); + return result && result.value; + } +}); + + +/***/ }), +/* 436 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var SetHelpers = __webpack_require__(247); +var createCollectionFrom = __webpack_require__(383); + +// `Set.from` method +// https://tc39.github.io/proposal-setmap-offrom/#sec-set.from +$({ target: 'Set', stat: true, forced: true }, { + from: createCollectionFrom(SetHelpers.Set, SetHelpers.add, false) +}); + + +/***/ }), +/* 437 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var toSetLike = __webpack_require__(431); +var $intersection = __webpack_require__(255); + +// `Set.prototype.intersection` method +// https://github.com/tc39/proposal-set-methods +// TODO: Obsolete version, remove from `core-js@4` +$({ target: 'Set', proto: true, real: true, forced: true }, { + intersection: function intersection(other) { + return call($intersection, this, toSetLike(other)); + } +}); + + +/***/ }), +/* 438 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var toSetLike = __webpack_require__(431); +var $isDisjointFrom = __webpack_require__(257); + +// `Set.prototype.isDisjointFrom` method +// https://github.com/tc39/proposal-set-methods +// TODO: Obsolete version, remove from `core-js@4` +$({ target: 'Set', proto: true, real: true, forced: true }, { + isDisjointFrom: function isDisjointFrom(other) { + return call($isDisjointFrom, this, toSetLike(other)); + } +}); + + +/***/ }), +/* 439 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var toSetLike = __webpack_require__(431); +var $isSubsetOf = __webpack_require__(259); + +// `Set.prototype.isSubsetOf` method +// https://github.com/tc39/proposal-set-methods +// TODO: Obsolete version, remove from `core-js@4` +$({ target: 'Set', proto: true, real: true, forced: true }, { + isSubsetOf: function isSubsetOf(other) { + return call($isSubsetOf, this, toSetLike(other)); + } +}); + + +/***/ }), +/* 440 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var toSetLike = __webpack_require__(431); +var $isSupersetOf = __webpack_require__(261); + +// `Set.prototype.isSupersetOf` method +// https://github.com/tc39/proposal-set-methods +// TODO: Obsolete version, remove from `core-js@4` +$({ target: 'Set', proto: true, real: true, forced: true }, { + isSupersetOf: function isSupersetOf(other) { + return call($isSupersetOf, this, toSetLike(other)); + } +}); + + +/***/ }), +/* 441 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var uncurryThis = __webpack_require__(6); +var aSet = __webpack_require__(246); +var iterate = __webpack_require__(249); +var toString = __webpack_require__(81); + +var arrayJoin = uncurryThis([].join); +var push = uncurryThis([].push); + +// `Set.prototype.join` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + join: function join(separator) { + var set = aSet(this); + var sep = separator === undefined ? ',' : toString(separator); + var array = []; + iterate(set, function (value) { + push(array, value); + }); + return arrayJoin(array, sep); + } +}); + + +/***/ }), +/* 442 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aSet = __webpack_require__(246); +var SetHelpers = __webpack_require__(247); +var iterate = __webpack_require__(249); + +var Set = SetHelpers.Set; +var add = SetHelpers.add; + +// `Set.prototype.map` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + map: function map(callbackfn /* , thisArg */) { + var set = aSet(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + var newSet = new Set(); + iterate(set, function (value) { + add(newSet, boundFunction(value, value, set)); + }); + return newSet; + } +}); + + +/***/ }), +/* 443 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var SetHelpers = __webpack_require__(247); +var createCollectionOf = __webpack_require__(394); + +// `Set.of` method +// https://tc39.github.io/proposal-setmap-offrom/#sec-set.of +$({ target: 'Set', stat: true, forced: true }, { + of: createCollectionOf(SetHelpers.Set, SetHelpers.add, false) +}); + + +/***/ }), +/* 444 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aCallable = __webpack_require__(38); +var aSet = __webpack_require__(246); +var iterate = __webpack_require__(249); + +var $TypeError = TypeError; + +// `Set.prototype.reduce` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + reduce: function reduce(callbackfn /* , initialValue */) { + var set = aSet(this); + var noInitial = arguments.length < 2; + var accumulator = noInitial ? undefined : arguments[1]; + aCallable(callbackfn); + iterate(set, function (value) { + if (noInitial) { + noInitial = false; + accumulator = value; + } else { + accumulator = callbackfn(accumulator, value, value, set); + } + }); + if (noInitial) throw new $TypeError('Reduce of empty set with no initial value'); + return accumulator; + } +}); + + +/***/ }), +/* 445 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var bind = __webpack_require__(98); +var aSet = __webpack_require__(246); +var iterate = __webpack_require__(249); + +// `Set.prototype.some` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'Set', proto: true, real: true, forced: true }, { + some: function some(callbackfn /* , thisArg */) { + var set = aSet(this); + var boundFunction = bind(callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return iterate(set, function (value) { + if (boundFunction(value, value, set)) return true; + }, true) === true; + } +}); + + +/***/ }), +/* 446 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var toSetLike = __webpack_require__(431); +var $symmetricDifference = __webpack_require__(263); + +// `Set.prototype.symmetricDifference` method +// https://github.com/tc39/proposal-set-methods +// TODO: Obsolete version, remove from `core-js@4` +$({ target: 'Set', proto: true, real: true, forced: true }, { + symmetricDifference: function symmetricDifference(other) { + return call($symmetricDifference, this, toSetLike(other)); + } +}); + + +/***/ }), +/* 447 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var call = __webpack_require__(33); +var toSetLike = __webpack_require__(431); +var $union = __webpack_require__(266); + +// `Set.prototype.union` method +// https://github.com/tc39/proposal-set-methods +// TODO: Obsolete version, remove from `core-js@4` +$({ target: 'Set', proto: true, real: true, forced: true }, { + union: function union(other) { + return call($union, this, toSetLike(other)); + } +}); + + +/***/ }), +/* 448 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var cooked = __webpack_require__(449); + +// `String.cooked` method +// https://github.com/tc39/proposal-string-cooked +$({ target: 'String', stat: true, forced: true }, { + cooked: cooked +}); + + +/***/ }), +/* 449 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var toIndexedObject = __webpack_require__(44); +var toString = __webpack_require__(81); +var lengthOfArrayLike = __webpack_require__(67); + +var $TypeError = TypeError; +var push = uncurryThis([].push); +var join = uncurryThis([].join); + +// `String.cooked` method +// https://tc39.es/proposal-string-cooked/ +module.exports = function cooked(template /* , ...substitutions */) { + var cookedTemplate = toIndexedObject(template); + var literalSegments = lengthOfArrayLike(cookedTemplate); + if (!literalSegments) return ''; + var argumentsLength = arguments.length; + var elements = []; + var i = 0; + while (true) { + var nextVal = cookedTemplate[i++]; + if (nextVal === undefined) throw new $TypeError('Incorrect template'); + push(elements, toString(nextVal)); + if (i === literalSegments) return join(elements, ''); + if (i < argumentsLength) push(elements, toString(arguments[i])); + } +}; + + +/***/ }), +/* 450 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var createIteratorConstructor = __webpack_require__(336); +var createIterResultObject = __webpack_require__(153); +var requireObjectCoercible = __webpack_require__(10); +var toString = __webpack_require__(81); +var InternalStateModule = __webpack_require__(55); +var StringMultibyteModule = __webpack_require__(451); + +var codeAt = StringMultibyteModule.codeAt; +var charAt = StringMultibyteModule.charAt; +var STRING_ITERATOR = 'String Iterator'; +var setInternalState = InternalStateModule.set; +var getInternalState = InternalStateModule.getterFor(STRING_ITERATOR); + +// TODO: unify with String#@@iterator +var $StringIterator = createIteratorConstructor(function StringIterator(string) { + setInternalState(this, { + type: STRING_ITERATOR, + string: string, + index: 0 + }); +}, 'String', function next() { + var state = getInternalState(this); + var string = state.string; + var index = state.index; + var point; + if (index >= string.length) return createIterResultObject(undefined, true); + point = charAt(string, index); + state.index += point.length; + return createIterResultObject({ codePoint: codeAt(point, 0), position: index }, false); +}); + +// `String.prototype.codePoints` method +// https://github.com/tc39/proposal-string-prototype-codepoints +$({ target: 'String', proto: true, forced: true }, { + codePoints: function codePoints() { + return new $StringIterator(toString(requireObjectCoercible(this))); + } +}); + + +/***/ }), +/* 451 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var toIntegerOrInfinity = __webpack_require__(65); +var toString = __webpack_require__(81); +var requireObjectCoercible = __webpack_require__(10); + +var charAt = uncurryThis(''.charAt); +var charCodeAt = uncurryThis(''.charCodeAt); +var stringSlice = uncurryThis(''.slice); + +var createMethod = function (CONVERT_TO_STRING) { + return function ($this, pos) { + var S = toString(requireObjectCoercible($this)); + var position = toIntegerOrInfinity(pos); + var size = S.length; + var first, second; + if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined; + first = charCodeAt(S, position); + return first < 0xD800 || first > 0xDBFF || position + 1 === size + || (second = charCodeAt(S, position + 1)) < 0xDC00 || second > 0xDFFF + ? CONVERT_TO_STRING + ? charAt(S, position) + : first + : CONVERT_TO_STRING + ? stringSlice(S, position, position + 2) + : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000; + }; +}; + +module.exports = { + // `String.prototype.codePointAt` method + // https://tc39.es/ecma262/#sec-string.prototype.codepointat + codeAt: createMethod(false), + // `String.prototype.at` method + // https://github.com/mathiasbynens/String.prototype.at + charAt: createMethod(true) +}; + + +/***/ }), +/* 452 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var FREEZING = __webpack_require__(181); +var $ = __webpack_require__(49); +var makeBuiltIn = __webpack_require__(52); +var uncurryThis = __webpack_require__(6); +var apply = __webpack_require__(72); +var anObject = __webpack_require__(30); +var toObject = __webpack_require__(9); +var isCallable = __webpack_require__(28); +var lengthOfArrayLike = __webpack_require__(67); +var defineProperty = __webpack_require__(23).f; +var createArrayFromList = __webpack_require__(183); +var WeakMapHelpers = __webpack_require__(453); +var cooked = __webpack_require__(449); +var parse = __webpack_require__(454); +var whitespaces = __webpack_require__(240); + +var DedentMap = new WeakMapHelpers.WeakMap(); +var weakMapGet = WeakMapHelpers.get; +var weakMapHas = WeakMapHelpers.has; +var weakMapSet = WeakMapHelpers.set; + +var $Array = Array; +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-freeze -- safe +var freeze = Object.freeze || Object; +// eslint-disable-next-line es/no-object-isfrozen -- safe +var isFrozen = Object.isFrozen; +var min = Math.min; +var charAt = uncurryThis(''.charAt); +var stringSlice = uncurryThis(''.slice); +var split = uncurryThis(''.split); +var exec = uncurryThis(/./.exec); + +var NEW_LINE = /([\n\u2028\u2029]|\r\n?)/g; +var LEADING_WHITESPACE = RegExp('^[' + whitespaces + ']*'); +var NON_WHITESPACE = RegExp('[^' + whitespaces + ']'); +var INVALID_TAG = 'Invalid tag'; +var INVALID_OPENING_LINE = 'Invalid opening line'; +var INVALID_CLOSING_LINE = 'Invalid closing line'; + +var dedentTemplateStringsArray = function (template) { + var rawInput = template.raw; + // https://github.com/tc39/proposal-string-dedent/issues/75 + if (FREEZING && !isFrozen(rawInput)) throw new $TypeError('Raw template should be frozen'); + if (weakMapHas(DedentMap, rawInput)) return weakMapGet(DedentMap, rawInput); + var raw = dedentStringsArray(rawInput); + var cookedArr = cookStrings(raw); + defineProperty(cookedArr, 'raw', { + value: freeze(raw) + }); + freeze(cookedArr); + weakMapSet(DedentMap, rawInput, cookedArr); + return cookedArr; +}; + +var dedentStringsArray = function (template) { + var t = toObject(template); + var length = lengthOfArrayLike(t); + var blocks = $Array(length); + var dedented = $Array(length); + var i = 0; + var lines, common, quasi, k; + + if (!length) throw new $TypeError(INVALID_TAG); + + for (; i < length; i++) { + var element = t[i]; + if (typeof element == 'string') blocks[i] = split(element, NEW_LINE); + else throw new $TypeError(INVALID_TAG); + } + + for (i = 0; i < length; i++) { + var lastSplit = i + 1 === length; + lines = blocks[i]; + if (i === 0) { + if (lines.length === 1 || lines[0].length > 0) { + throw new $TypeError(INVALID_OPENING_LINE); + } + lines[1] = ''; + } + if (lastSplit) { + if (lines.length === 1 || exec(NON_WHITESPACE, lines[lines.length - 1])) { + throw new $TypeError(INVALID_CLOSING_LINE); + } + lines[lines.length - 2] = ''; + lines[lines.length - 1] = ''; + } + // eslint-disable-next-line sonarjs/no-redundant-assignments -- false positive, https://github.com/SonarSource/SonarJS/issues/4767 + for (var j = 2; j < lines.length; j += 2) { + var text = lines[j]; + var lineContainsTemplateExpression = j + 1 === lines.length && !lastSplit; + var leading = exec(LEADING_WHITESPACE, text)[0]; + if (!lineContainsTemplateExpression && leading.length === text.length) { + lines[j] = ''; + continue; + } + common = commonLeadingIndentation(leading, common); + } + } + + var count = common ? common.length : 0; + + for (i = 0; i < length; i++) { + lines = blocks[i]; + quasi = lines[0]; + k = 1; + for (; k < lines.length; k += 2) { + quasi += lines[k] + stringSlice(lines[k + 1], count); + } + dedented[i] = quasi; + } + + return dedented; +}; + +var commonLeadingIndentation = function (a, b) { + if (b === undefined || a === b) return a; + var i = 0; + for (var len = min(a.length, b.length); i < len; i++) { + if (charAt(a, i) !== charAt(b, i)) break; + } + return stringSlice(a, 0, i); +}; + +var cookStrings = function (raw) { + var i = 0; + var length = raw.length; + var result = $Array(length); + for (; i < length; i++) { + result[i] = parse(raw[i]); + } return result; +}; + +var makeDedentTag = function (tag) { + return makeBuiltIn(function (template /* , ...substitutions */) { + var args = createArrayFromList(arguments); + args[0] = dedentTemplateStringsArray(anObject(template)); + return apply(tag, this, args); + }, ''); +}; + +var cookedDedentTag = makeDedentTag(cooked); + +// `String.dedent` method +// https://github.com/tc39/proposal-string-dedent +$({ target: 'String', stat: true, forced: true }, { + dedent: function dedent(templateOrFn /* , ...substitutions */) { + anObject(templateOrFn); + if (isCallable(templateOrFn)) return makeDedentTag(templateOrFn); + return apply(cookedDedentTag, this, arguments); + } +}); + + +/***/ }), +/* 453 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +// eslint-disable-next-line es/no-weak-map -- safe +var WeakMapPrototype = WeakMap.prototype; + +module.exports = { + // eslint-disable-next-line es/no-weak-map -- safe + WeakMap: WeakMap, + set: uncurryThis(WeakMapPrototype.set), + get: uncurryThis(WeakMapPrototype.get), + has: uncurryThis(WeakMapPrototype.has), + remove: uncurryThis(WeakMapPrototype['delete']) +}; + + +/***/ }), +/* 454 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// adapted from https://github.com/jridgewell/string-dedent +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); + +var fromCharCode = String.fromCharCode; +var fromCodePoint = getBuiltIn('String', 'fromCodePoint'); +var charAt = uncurryThis(''.charAt); +var charCodeAt = uncurryThis(''.charCodeAt); +var stringIndexOf = uncurryThis(''.indexOf); +var stringSlice = uncurryThis(''.slice); + +var ZERO_CODE = 48; +var NINE_CODE = 57; +var LOWER_A_CODE = 97; +var LOWER_F_CODE = 102; +var UPPER_A_CODE = 65; +var UPPER_F_CODE = 70; + +var isDigit = function (str, index) { + var c = charCodeAt(str, index); + return c >= ZERO_CODE && c <= NINE_CODE; +}; + +var parseHex = function (str, index, end) { + if (end >= str.length) return -1; + var n = 0; + for (; index < end; index++) { + var c = hexToInt(charCodeAt(str, index)); + if (c === -1) return -1; + n = n * 16 + c; + } + return n; +}; + +var hexToInt = function (c) { + if (c >= ZERO_CODE && c <= NINE_CODE) return c - ZERO_CODE; + if (c >= LOWER_A_CODE && c <= LOWER_F_CODE) return c - LOWER_A_CODE + 10; + if (c >= UPPER_A_CODE && c <= UPPER_F_CODE) return c - UPPER_A_CODE + 10; + return -1; +}; + +module.exports = function (raw) { + var out = ''; + var start = 0; + // We need to find every backslash escape sequence, and cook the escape into a real char. + var i = 0; + var n; + while ((i = stringIndexOf(raw, '\\', i)) > -1) { + out += stringSlice(raw, start, i); + // If the backslash is the last char of the string, then it was an invalid sequence. + // This can't actually happen in a tagged template literal, but could happen if you manually + // invoked the tag with an array. + if (++i === raw.length) return; + var next = charAt(raw, i++); + switch (next) { + // Escaped control codes need to be individually processed. + case 'b': + out += '\b'; + break; + case 't': + out += '\t'; + break; + case 'n': + out += '\n'; + break; + case 'v': + out += '\v'; + break; + case 'f': + out += '\f'; + break; + case 'r': + out += '\r'; + break; + // Escaped line terminators just skip the char. + case '\r': + // Treat `\r\n` as a single terminator. + if (i < raw.length && charAt(raw, i) === '\n') ++i; + // break omitted + case '\n': + case '\u2028': + case '\u2029': + break; + // `\0` is a null control char, but `\0` followed by another digit is an illegal octal escape. + case '0': + if (isDigit(raw, i)) return; + out += '\0'; + break; + // Hex escapes must contain 2 hex chars. + case 'x': + n = parseHex(raw, i, i + 2); + if (n === -1) return; + i += 2; + out += fromCharCode(n); + break; + // Unicode escapes contain either 4 chars, or an unlimited number between `{` and `}`. + // The hex value must not overflow 0x10FFFF. + case 'u': + if (i < raw.length && charAt(raw, i) === '{') { + var end = stringIndexOf(raw, '}', ++i); + if (end === -1) return; + n = parseHex(raw, i, end); + i = end + 1; + } else { + n = parseHex(raw, i, i + 4); + i += 4; + } + if (n === -1 || n > 0x10FFFF) return; + out += fromCodePoint(n); + break; + default: + if (isDigit(next, 0)) return; + out += next; + } + start = i; + } + return out + stringSlice(raw, start); +}; + + +/***/ }), +/* 455 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineWellKnownSymbol = __webpack_require__(3); + +// `Symbol.customMatcher` well-known symbol +// https://github.com/tc39/proposal-pattern-matching +defineWellKnownSymbol('customMatcher'); + + +/***/ }), +/* 456 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isRegisteredSymbol = __webpack_require__(457); + +// `Symbol.isRegisteredSymbol` method +// https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol +$({ target: 'Symbol', stat: true }, { + isRegisteredSymbol: isRegisteredSymbol +}); + + +/***/ }), +/* 457 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); + +var Symbol = getBuiltIn('Symbol'); +var keyFor = Symbol.keyFor; +var thisSymbolValue = uncurryThis(Symbol.prototype.valueOf); + +// `Symbol.isRegisteredSymbol` method +// https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol +module.exports = Symbol.isRegisteredSymbol || function isRegisteredSymbol(value) { + try { + return keyFor(thisSymbolValue(value)) !== undefined; + } catch (error) { + return false; + } +}; + + +/***/ }), +/* 458 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isRegisteredSymbol = __webpack_require__(457); + +// `Symbol.isRegistered` method +// obsolete version of https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol +$({ target: 'Symbol', stat: true, name: 'isRegisteredSymbol' }, { + isRegistered: isRegisteredSymbol +}); + + +/***/ }), +/* 459 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isWellKnownSymbol = __webpack_require__(460); + +// `Symbol.isWellKnownSymbol` method +// https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol +// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected +$({ target: 'Symbol', stat: true, forced: true }, { + isWellKnownSymbol: isWellKnownSymbol +}); + + +/***/ }), +/* 460 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var shared = __webpack_require__(14); +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); +var isSymbol = __webpack_require__(34); +var wellKnownSymbol = __webpack_require__(13); + +var Symbol = getBuiltIn('Symbol'); +var $isWellKnownSymbol = Symbol.isWellKnownSymbol; +var getOwnPropertyNames = getBuiltIn('Object', 'getOwnPropertyNames'); +var thisSymbolValue = uncurryThis(Symbol.prototype.valueOf); +var WellKnownSymbolsStore = shared('wks'); + +for (var i = 0, symbolKeys = getOwnPropertyNames(Symbol), symbolKeysLength = symbolKeys.length; i < symbolKeysLength; i++) { + // some old engines throws on access to some keys like `arguments` or `caller` + try { + var symbolKey = symbolKeys[i]; + if (isSymbol(Symbol[symbolKey])) wellKnownSymbol(symbolKey); + } catch (error) { /* empty */ } +} + +// `Symbol.isWellKnownSymbol` method +// https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol +// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected +module.exports = function isWellKnownSymbol(value) { + if ($isWellKnownSymbol && $isWellKnownSymbol(value)) return true; + try { + var symbol = thisSymbolValue(value); + for (var j = 0, keys = getOwnPropertyNames(WellKnownSymbolsStore), keysLength = keys.length; j < keysLength; j++) { + // eslint-disable-next-line eqeqeq -- polyfilled symbols case + if (WellKnownSymbolsStore[keys[j]] == symbol) return true; + } + } catch (error) { /* empty */ } + return false; +}; + + +/***/ }), +/* 461 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var isWellKnownSymbol = __webpack_require__(460); + +// `Symbol.isWellKnown` method +// obsolete version of https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol +// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected +$({ target: 'Symbol', stat: true, name: 'isWellKnownSymbol', forced: true }, { + isWellKnown: isWellKnownSymbol +}); + + +/***/ }), +/* 462 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineWellKnownSymbol = __webpack_require__(3); + +// `Symbol.matcher` well-known symbol +// https://github.com/tc39/proposal-pattern-matching +defineWellKnownSymbol('matcher'); + + +/***/ }), +/* 463 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineWellKnownSymbol = __webpack_require__(3); + +// `Symbol.metadata` well-known symbol +// https://github.com/tc39/proposal-decorators +defineWellKnownSymbol('metadata'); + + +/***/ }), +/* 464 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var defineWellKnownSymbol = __webpack_require__(3); + +// `Symbol.metadataKey` well-known symbol +// https://github.com/tc39/proposal-decorator-metadata +defineWellKnownSymbol('metadataKey'); + + +/***/ }), +/* 465 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineWellKnownSymbol = __webpack_require__(3); + +// `Symbol.observable` well-known symbol +// https://github.com/tc39/proposal-observable +defineWellKnownSymbol('observable'); + + +/***/ }), +/* 466 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var getBuiltIn = __webpack_require__(35); +var aConstructor = __webpack_require__(198); +var arrayFromAsync = __webpack_require__(227); +var ArrayBufferViewCore = __webpack_require__(275); +var arrayFromConstructorAndList = __webpack_require__(119); + +var aTypedArrayConstructor = ArrayBufferViewCore.aTypedArrayConstructor; +var exportTypedArrayStaticMethod = ArrayBufferViewCore.exportTypedArrayStaticMethod; + +// `%TypedArray%.fromAsync` method +// https://github.com/tc39/proposal-array-from-async +exportTypedArrayStaticMethod('fromAsync', function fromAsync(asyncItems /* , mapfn = undefined, thisArg = undefined */) { + var C = this; + var argumentsLength = arguments.length; + var mapfn = argumentsLength > 1 ? arguments[1] : undefined; + var thisArg = argumentsLength > 2 ? arguments[2] : undefined; + return new (getBuiltIn('Promise'))(function (resolve) { + aConstructor(C); + resolve(arrayFromAsync(asyncItems, mapfn, thisArg)); + }).then(function (list) { + return arrayFromConstructorAndList(aTypedArrayConstructor(C), list); + }); +}, true); + + +/***/ }), +/* 467 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var ArrayBufferViewCore = __webpack_require__(275); +var $filterReject = __webpack_require__(298).filterReject; +var fromSameTypeAndList = __webpack_require__(468); + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; + +// `%TypedArray%.prototype.filterReject` method +// https://github.com/tc39/proposal-array-filtering +exportTypedArrayMethod('filterReject', function filterReject(callbackfn /* , thisArg */) { + var list = $filterReject(aTypedArray(this), callbackfn, arguments.length > 1 ? arguments[1] : undefined); + return fromSameTypeAndList(this, list); +}, true); + + +/***/ }), +/* 468 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var arrayFromConstructorAndList = __webpack_require__(119); +var getTypedArrayConstructor = __webpack_require__(275).getTypedArrayConstructor; + +module.exports = function (instance, list) { + return arrayFromConstructorAndList(getTypedArrayConstructor(instance), list); +}; + + +/***/ }), +/* 469 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var ArrayBufferViewCore = __webpack_require__(275); +var $group = __webpack_require__(302); + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; + +// `%TypedArray%.prototype.groupBy` method +// https://github.com/tc39/proposal-array-grouping +exportTypedArrayMethod('groupBy', function groupBy(callbackfn /* , thisArg */) { + var thisArg = arguments.length > 1 ? arguments[1] : undefined; + return $group(aTypedArray(this), callbackfn, thisArg, getTypedArrayConstructor); +}, true); + + +/***/ }), +/* 470 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove from `core-js@4` +var ArrayBufferViewCore = __webpack_require__(275); +var lengthOfArrayLike = __webpack_require__(67); +var isBigIntArray = __webpack_require__(283); +var toAbsoluteIndex = __webpack_require__(64); +var toBigInt = __webpack_require__(284); +var toIntegerOrInfinity = __webpack_require__(65); + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; +var max = Math.max; +var min = Math.min; + +// `%TypedArray%.prototype.toSpliced` method +// https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toSpliced +exportTypedArrayMethod('toSpliced', function toSpliced(start, deleteCount /* , ...items */) { + var O = aTypedArray(this); + var C = getTypedArrayConstructor(O); + var len = lengthOfArrayLike(O); + var actualStart = toAbsoluteIndex(start, len); + var argumentsLength = arguments.length; + var k = 0; + var insertCount, actualDeleteCount, thisIsBigIntArray, convertedItems, value, newLen, A; + if (argumentsLength === 0) { + insertCount = actualDeleteCount = 0; + } else if (argumentsLength === 1) { + insertCount = 0; + actualDeleteCount = len - actualStart; + } else { + actualDeleteCount = min(max(toIntegerOrInfinity(deleteCount), 0), len - actualStart); + insertCount = argumentsLength - 2; + if (insertCount) { + convertedItems = new C(insertCount); + thisIsBigIntArray = isBigIntArray(convertedItems); + for (var i = 2; i < argumentsLength; i++) { + value = arguments[i]; + // FF30- typed arrays doesn't properly convert objects to typed array values + convertedItems[i - 2] = thisIsBigIntArray ? toBigInt(value) : +value; + } + } + } + newLen = len + insertCount - actualDeleteCount; + A = new C(newLen); + + for (; k < actualStart; k++) A[k] = O[k]; + for (; k < actualStart + insertCount; k++) A[k] = convertedItems[k - actualStart]; + for (; k < newLen; k++) A[k] = O[k + actualDeleteCount - insertCount]; + + return A; +}, true); + + +/***/ }), +/* 471 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); +var ArrayBufferViewCore = __webpack_require__(275); +var arrayFromConstructorAndList = __webpack_require__(119); +var $arrayUniqueBy = __webpack_require__(312); + +var aTypedArray = ArrayBufferViewCore.aTypedArray; +var getTypedArrayConstructor = ArrayBufferViewCore.getTypedArrayConstructor; +var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; +var arrayUniqueBy = uncurryThis($arrayUniqueBy); + +// `%TypedArray%.prototype.uniqueBy` method +// https://github.com/tc39/proposal-array-unique +exportTypedArrayMethod('uniqueBy', function uniqueBy(resolver) { + aTypedArray(this); + return arrayFromConstructorAndList(getTypedArrayConstructor(this), arrayUniqueBy(this, resolver)); +}, true); + + +/***/ }), +/* 472 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aWeakMap = __webpack_require__(473); +var remove = __webpack_require__(453).remove; + +// `WeakMap.prototype.deleteAll` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'WeakMap', proto: true, real: true, forced: true }, { + deleteAll: function deleteAll(/* ...elements */) { + var collection = aWeakMap(this); + var allDeleted = true; + var wasDeleted; + for (var k = 0, len = arguments.length; k < len; k++) { + wasDeleted = remove(collection, arguments[k]); + allDeleted = allDeleted && wasDeleted; + } return !!allDeleted; + } +}); + + +/***/ }), +/* 473 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var has = __webpack_require__(453).has; + +// Perform ? RequireInternalSlot(M, [[WeakMapData]]) +module.exports = function (it) { + has(it); + return it; +}; + + +/***/ }), +/* 474 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var WeakMapHelpers = __webpack_require__(453); +var createCollectionFrom = __webpack_require__(383); + +// `WeakMap.from` method +// https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.from +$({ target: 'WeakMap', stat: true, forced: true }, { + from: createCollectionFrom(WeakMapHelpers.WeakMap, WeakMapHelpers.set, true) +}); + + +/***/ }), +/* 475 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var WeakMapHelpers = __webpack_require__(453); +var createCollectionOf = __webpack_require__(394); + +// `WeakMap.of` method +// https://tc39.github.io/proposal-setmap-offrom/#sec-weakmap.of +$({ target: 'WeakMap', stat: true, forced: true }, { + of: createCollectionOf(WeakMapHelpers.WeakMap, WeakMapHelpers.set, true) +}); + + +/***/ }), +/* 476 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aWeakMap = __webpack_require__(473); +var WeakMapHelpers = __webpack_require__(453); + +var get = WeakMapHelpers.get; +var has = WeakMapHelpers.has; +var set = WeakMapHelpers.set; + +// `WeakMap.prototype.emplace` method +// https://github.com/tc39/proposal-upsert +$({ target: 'WeakMap', proto: true, real: true, forced: true }, { + emplace: function emplace(key, handler) { + var map = aWeakMap(this); + var value, inserted; + if (has(map, key)) { + value = get(map, key); + if ('update' in handler) { + value = handler.update(value, key, map); + set(map, key, value); + } return value; + } + inserted = handler.insert(key, map); + set(map, key, inserted); + return inserted; + } +}); + + +/***/ }), +/* 477 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aWeakMap = __webpack_require__(473); +var WeakMapHelpers = __webpack_require__(453); +var IS_PURE = __webpack_require__(16); + +var get = WeakMapHelpers.get; +var has = WeakMapHelpers.has; +var set = WeakMapHelpers.set; + +// `WeakMap.prototype.getOrInsert` method +// https://github.com/tc39/proposal-upsert +$({ target: 'WeakMap', proto: true, real: true, forced: IS_PURE }, { + getOrInsert: function getOrInsert(key, value) { + if (has(aWeakMap(this), key)) return get(this, key); + set(this, key, value); + return value; + } +}); + + +/***/ }), +/* 478 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aCallable = __webpack_require__(38); +var aWeakMap = __webpack_require__(473); +var aWeakKey = __webpack_require__(479); +var WeakMapHelpers = __webpack_require__(453); +var IS_PURE = __webpack_require__(16); + +var get = WeakMapHelpers.get; +var has = WeakMapHelpers.has; +var set = WeakMapHelpers.set; + +var FORCED = IS_PURE || !function () { + try { + // eslint-disable-next-line es/no-weak-map, no-throw-literal -- testing + if (WeakMap.prototype.getOrInsertComputed) new WeakMap().getOrInsertComputed(1, function () { throw 1; }); + } catch (error) { + // FF144 Nightly - Beta 3 bug + // https://bugzilla.mozilla.org/show_bug.cgi?id=1988369 + return error instanceof TypeError; + } +}(); + +// `WeakMap.prototype.getOrInsertComputed` method +// https://github.com/tc39/proposal-upsert +$({ target: 'WeakMap', proto: true, real: true, forced: FORCED }, { + getOrInsertComputed: function getOrInsertComputed(key, callbackfn) { + aWeakMap(this); + aWeakKey(key); + aCallable(callbackfn); + if (has(this, key)) return get(this, key); + var value = callbackfn(key); + set(this, key, value); + return value; + } +}); + + +/***/ }), +/* 479 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var WeakMapHelpers = __webpack_require__(453); + +var weakmap = new WeakMapHelpers.WeakMap(); +var set = WeakMapHelpers.set; +var remove = WeakMapHelpers.remove; + +module.exports = function (key) { + set(weakmap, key, 1); + remove(weakmap, key); + return key; +}; + + +/***/ }), +/* 480 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aWeakSet = __webpack_require__(481); +var add = __webpack_require__(482).add; + +// `WeakSet.prototype.addAll` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'WeakSet', proto: true, real: true, forced: true }, { + addAll: function addAll(/* ...elements */) { + var set = aWeakSet(this); + for (var k = 0, len = arguments.length; k < len; k++) { + add(set, arguments[k]); + } return set; + } +}); + + +/***/ }), +/* 481 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var has = __webpack_require__(482).has; + +// Perform ? RequireInternalSlot(M, [[WeakSetData]]) +module.exports = function (it) { + has(it); + return it; +}; + + +/***/ }), +/* 482 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var uncurryThis = __webpack_require__(6); + +// eslint-disable-next-line es/no-weak-set -- safe +var WeakSetPrototype = WeakSet.prototype; + +module.exports = { + // eslint-disable-next-line es/no-weak-set -- safe + WeakSet: WeakSet, + add: uncurryThis(WeakSetPrototype.add), + has: uncurryThis(WeakSetPrototype.has), + remove: uncurryThis(WeakSetPrototype['delete']) +}; + + +/***/ }), +/* 483 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var aWeakSet = __webpack_require__(481); +var remove = __webpack_require__(482).remove; + +// `WeakSet.prototype.deleteAll` method +// https://github.com/tc39/proposal-collection-methods +$({ target: 'WeakSet', proto: true, real: true, forced: true }, { + deleteAll: function deleteAll(/* ...elements */) { + var collection = aWeakSet(this); + var allDeleted = true; + var wasDeleted; + for (var k = 0, len = arguments.length; k < len; k++) { + wasDeleted = remove(collection, arguments[k]); + allDeleted = allDeleted && wasDeleted; + } return !!allDeleted; + } +}); + + +/***/ }), +/* 484 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var WeakSetHelpers = __webpack_require__(482); +var createCollectionFrom = __webpack_require__(383); + +// `WeakSet.from` method +// https://tc39.github.io/proposal-setmap-offrom/#sec-weakset.from +$({ target: 'WeakSet', stat: true, forced: true }, { + from: createCollectionFrom(WeakSetHelpers.WeakSet, WeakSetHelpers.add, false) +}); + + +/***/ }), +/* 485 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var WeakSetHelpers = __webpack_require__(482); +var createCollectionOf = __webpack_require__(394); + +// `WeakSet.of` method +// https://tc39.github.io/proposal-setmap-offrom/#sec-weakset.of +$({ target: 'WeakSet', stat: true, forced: true }, { + of: createCollectionOf(WeakSetHelpers.WeakSet, WeakSetHelpers.add, false) +}); + + +/***/ }), +/* 486 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var getBuiltInNodeModule = __webpack_require__(139); +var fails = __webpack_require__(8); +var create = __webpack_require__(93); +var createPropertyDescriptor = __webpack_require__(43); +var defineProperty = __webpack_require__(23).f; +var defineBuiltIn = __webpack_require__(51); +var defineBuiltInAccessor = __webpack_require__(131); +var hasOwn = __webpack_require__(5); +var anInstance = __webpack_require__(145); +var anObject = __webpack_require__(30); +var errorToString = __webpack_require__(487); +var normalizeStringArgument = __webpack_require__(80); +var DOMExceptionConstants = __webpack_require__(488); +var clearErrorStack = __webpack_require__(86); +var InternalStateModule = __webpack_require__(55); +var DESCRIPTORS = __webpack_require__(24); +var IS_PURE = __webpack_require__(16); + +var DOM_EXCEPTION = 'DOMException'; +var DATA_CLONE_ERR = 'DATA_CLONE_ERR'; +var Error = getBuiltIn('Error'); +// NodeJS < 17.0 does not expose `DOMException` to global +var NativeDOMException = getBuiltIn(DOM_EXCEPTION) || (function () { + try { + // NodeJS < 15.0 does not expose `MessageChannel` to global + var MessageChannel = getBuiltIn('MessageChannel') || getBuiltInNodeModule('worker_threads').MessageChannel; + // eslint-disable-next-line es/no-weak-map, unicorn/require-post-message-target-origin -- safe + new MessageChannel().port1.postMessage(new WeakMap()); + } catch (error) { + if (error.name === DATA_CLONE_ERR && error.code === 25) return error.constructor; + } +})(); +var NativeDOMExceptionPrototype = NativeDOMException && NativeDOMException.prototype; +var ErrorPrototype = Error.prototype; +var setInternalState = InternalStateModule.set; +var getInternalState = InternalStateModule.getterFor(DOM_EXCEPTION); +var HAS_STACK = 'stack' in new Error(DOM_EXCEPTION); + +var codeFor = function (name) { + return hasOwn(DOMExceptionConstants, name) && DOMExceptionConstants[name].m ? DOMExceptionConstants[name].c : 0; +}; + +var $DOMException = function DOMException() { + anInstance(this, DOMExceptionPrototype); + var argumentsLength = arguments.length; + var message = normalizeStringArgument(argumentsLength < 1 ? undefined : arguments[0]); + var name = normalizeStringArgument(argumentsLength < 2 ? undefined : arguments[1], 'Error'); + var code = codeFor(name); + setInternalState(this, { + type: DOM_EXCEPTION, + name: name, + message: message, + code: code + }); + if (!DESCRIPTORS) { + this.name = name; + this.message = message; + this.code = code; + } + if (HAS_STACK) { + var error = new Error(message); + error.name = DOM_EXCEPTION; + defineProperty(this, 'stack', createPropertyDescriptor(1, clearErrorStack(error.stack, 1))); + } +}; + +var DOMExceptionPrototype = $DOMException.prototype = create(ErrorPrototype); + +var createGetterDescriptor = function (get) { + return { enumerable: true, configurable: true, get: get }; +}; + +var getterFor = function (key) { + return createGetterDescriptor(function () { + return getInternalState(this)[key]; + }); +}; + +if (DESCRIPTORS) { + // `DOMException.prototype.code` getter + defineBuiltInAccessor(DOMExceptionPrototype, 'code', getterFor('code')); + // `DOMException.prototype.message` getter + defineBuiltInAccessor(DOMExceptionPrototype, 'message', getterFor('message')); + // `DOMException.prototype.name` getter + defineBuiltInAccessor(DOMExceptionPrototype, 'name', getterFor('name')); +} + +defineProperty(DOMExceptionPrototype, 'constructor', createPropertyDescriptor(1, $DOMException)); + +// FF36- DOMException is a function, but can't be constructed +var INCORRECT_CONSTRUCTOR = fails(function () { + return !(new NativeDOMException() instanceof Error); +}); + +// Safari 10.1 / Chrome 32- / IE8- DOMException.prototype.toString bugs +var INCORRECT_TO_STRING = INCORRECT_CONSTRUCTOR || fails(function () { + return ErrorPrototype.toString !== errorToString || String(new NativeDOMException(1, 2)) !== '2: 1'; +}); + +// Deno 1.6.3- DOMException.prototype.code just missed +var INCORRECT_CODE = INCORRECT_CONSTRUCTOR || fails(function () { + return new NativeDOMException(1, 'DataCloneError').code !== 25; +}); + +// Deno 1.6.3- DOMException constants just missed +var MISSED_CONSTANTS = INCORRECT_CONSTRUCTOR + || NativeDOMException[DATA_CLONE_ERR] !== 25 + || NativeDOMExceptionPrototype[DATA_CLONE_ERR] !== 25; + +var FORCED_CONSTRUCTOR = IS_PURE ? INCORRECT_TO_STRING || INCORRECT_CODE || MISSED_CONSTANTS : INCORRECT_CONSTRUCTOR; + +// `DOMException` constructor +// https://webidl.spec.whatwg.org/#idl-DOMException +$({ global: true, constructor: true, forced: FORCED_CONSTRUCTOR }, { + DOMException: FORCED_CONSTRUCTOR ? $DOMException : NativeDOMException +}); + +var PolyfilledDOMException = getBuiltIn(DOM_EXCEPTION); +var PolyfilledDOMExceptionPrototype = PolyfilledDOMException.prototype; + +if (INCORRECT_TO_STRING && (IS_PURE || NativeDOMException === PolyfilledDOMException)) { + defineBuiltIn(PolyfilledDOMExceptionPrototype, 'toString', errorToString); +} + +if (INCORRECT_CODE && DESCRIPTORS && NativeDOMException === PolyfilledDOMException) { + defineBuiltInAccessor(PolyfilledDOMExceptionPrototype, 'code', createGetterDescriptor(function () { + return codeFor(anObject(this).name); + })); +} + +// `DOMException` constants +for (var key in DOMExceptionConstants) if (hasOwn(DOMExceptionConstants, key)) { + var constant = DOMExceptionConstants[key]; + var constantName = constant.s; + var descriptor = createPropertyDescriptor(6, constant.c); + if (!hasOwn(PolyfilledDOMException, constantName)) { + defineProperty(PolyfilledDOMException, constantName, descriptor); + } + if (!hasOwn(PolyfilledDOMExceptionPrototype, constantName)) { + defineProperty(PolyfilledDOMExceptionPrototype, constantName, descriptor); + } +} + + +/***/ }), +/* 487 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var fails = __webpack_require__(8); +var anObject = __webpack_require__(30); +var normalizeStringArgument = __webpack_require__(80); + +var nativeErrorToString = Error.prototype.toString; + +var INCORRECT_TO_STRING = fails(function () { + if (DESCRIPTORS) { + // Chrome 32- incorrectly call accessor + // eslint-disable-next-line es/no-object-create, es/no-object-defineproperty -- safe + var object = Object.create(Object.defineProperty({}, 'name', { get: function () { + return this === object; + } })); + if (nativeErrorToString.call(object) !== 'true') return true; + } + // FF10- does not properly handle non-strings + return nativeErrorToString.call({ message: 1, name: 2 }) !== '2: 1' + // IE8 does not properly handle defaults + || nativeErrorToString.call({}) !== 'Error'; +}); + +module.exports = INCORRECT_TO_STRING ? function toString() { + var O = anObject(this); + var name = normalizeStringArgument(O.name, 'Error'); + var message = normalizeStringArgument(O.message); + return !name ? message : !message ? name : name + ': ' + message; +} : nativeErrorToString; + + +/***/ }), +/* 488 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +module.exports = { + IndexSizeError: { s: 'INDEX_SIZE_ERR', c: 1, m: 1 }, + DOMStringSizeError: { s: 'DOMSTRING_SIZE_ERR', c: 2, m: 0 }, + HierarchyRequestError: { s: 'HIERARCHY_REQUEST_ERR', c: 3, m: 1 }, + WrongDocumentError: { s: 'WRONG_DOCUMENT_ERR', c: 4, m: 1 }, + InvalidCharacterError: { s: 'INVALID_CHARACTER_ERR', c: 5, m: 1 }, + NoDataAllowedError: { s: 'NO_DATA_ALLOWED_ERR', c: 6, m: 0 }, + NoModificationAllowedError: { s: 'NO_MODIFICATION_ALLOWED_ERR', c: 7, m: 1 }, + NotFoundError: { s: 'NOT_FOUND_ERR', c: 8, m: 1 }, + NotSupportedError: { s: 'NOT_SUPPORTED_ERR', c: 9, m: 1 }, + InUseAttributeError: { s: 'INUSE_ATTRIBUTE_ERR', c: 10, m: 1 }, + InvalidStateError: { s: 'INVALID_STATE_ERR', c: 11, m: 1 }, + SyntaxError: { s: 'SYNTAX_ERR', c: 12, m: 1 }, + InvalidModificationError: { s: 'INVALID_MODIFICATION_ERR', c: 13, m: 1 }, + NamespaceError: { s: 'NAMESPACE_ERR', c: 14, m: 1 }, + InvalidAccessError: { s: 'INVALID_ACCESS_ERR', c: 15, m: 1 }, + ValidationError: { s: 'VALIDATION_ERR', c: 16, m: 0 }, + TypeMismatchError: { s: 'TYPE_MISMATCH_ERR', c: 17, m: 1 }, + SecurityError: { s: 'SECURITY_ERR', c: 18, m: 1 }, + NetworkError: { s: 'NETWORK_ERR', c: 19, m: 1 }, + AbortError: { s: 'ABORT_ERR', c: 20, m: 1 }, + URLMismatchError: { s: 'URL_MISMATCH_ERR', c: 21, m: 1 }, + QuotaExceededError: { s: 'QUOTA_EXCEEDED_ERR', c: 22, m: 1 }, + TimeoutError: { s: 'TIMEOUT_ERR', c: 23, m: 1 }, + InvalidNodeTypeError: { s: 'INVALID_NODE_TYPE_ERR', c: 24, m: 1 }, + DataCloneError: { s: 'DATA_CLONE_ERR', c: 25, m: 1 } +}; + + +/***/ }), +/* 489 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var getBuiltIn = __webpack_require__(35); +var createPropertyDescriptor = __webpack_require__(43); +var defineProperty = __webpack_require__(23).f; +var hasOwn = __webpack_require__(5); +var anInstance = __webpack_require__(145); +var inheritIfRequired = __webpack_require__(79); +var normalizeStringArgument = __webpack_require__(80); +var DOMExceptionConstants = __webpack_require__(488); +var clearErrorStack = __webpack_require__(86); +var DESCRIPTORS = __webpack_require__(24); +var IS_PURE = __webpack_require__(16); + +var DOM_EXCEPTION = 'DOMException'; +var Error = getBuiltIn('Error'); +var NativeDOMException = getBuiltIn(DOM_EXCEPTION); + +var $DOMException = function DOMException() { + anInstance(this, DOMExceptionPrototype); + var argumentsLength = arguments.length; + var message = normalizeStringArgument(argumentsLength < 1 ? undefined : arguments[0]); + var name = normalizeStringArgument(argumentsLength < 2 ? undefined : arguments[1], 'Error'); + var that = new NativeDOMException(message, name); + var error = new Error(message); + error.name = DOM_EXCEPTION; + defineProperty(that, 'stack', createPropertyDescriptor(1, clearErrorStack(error.stack, 1))); + inheritIfRequired(that, this, $DOMException); + return that; +}; + +var DOMExceptionPrototype = $DOMException.prototype = NativeDOMException.prototype; + +var ERROR_HAS_STACK = 'stack' in new Error(DOM_EXCEPTION); +var DOM_EXCEPTION_HAS_STACK = 'stack' in new NativeDOMException(1, 2); + +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +var descriptor = NativeDOMException && DESCRIPTORS && Object.getOwnPropertyDescriptor(globalThis, DOM_EXCEPTION); + +// Bun ~ 0.1.1 DOMException have incorrect descriptor and we can't redefine it +// https://github.com/Jarred-Sumner/bun/issues/399 +var BUGGY_DESCRIPTOR = !!descriptor && !(descriptor.writable && descriptor.configurable); + +var FORCED_CONSTRUCTOR = ERROR_HAS_STACK && !BUGGY_DESCRIPTOR && !DOM_EXCEPTION_HAS_STACK; + +// `DOMException` constructor patch for `.stack` where it's required +// https://webidl.spec.whatwg.org/#es-DOMException-specialness +$({ global: true, constructor: true, forced: IS_PURE || FORCED_CONSTRUCTOR }, { // TODO: fix export logic + DOMException: FORCED_CONSTRUCTOR ? $DOMException : NativeDOMException +}); + +var PolyfilledDOMException = getBuiltIn(DOM_EXCEPTION); +var PolyfilledDOMExceptionPrototype = PolyfilledDOMException.prototype; + +if (PolyfilledDOMExceptionPrototype.constructor !== PolyfilledDOMException) { + if (!IS_PURE) { + defineProperty(PolyfilledDOMExceptionPrototype, 'constructor', createPropertyDescriptor(1, PolyfilledDOMException)); + } + + for (var key in DOMExceptionConstants) if (hasOwn(DOMExceptionConstants, key)) { + var constant = DOMExceptionConstants[key]; + var constantName = constant.s; + if (!hasOwn(PolyfilledDOMException, constantName)) { + defineProperty(PolyfilledDOMException, constantName, createPropertyDescriptor(6, constant.c)); + } + } +} + + +/***/ }), +/* 490 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var getBuiltIn = __webpack_require__(35); +var setToStringTag = __webpack_require__(195); + +var DOM_EXCEPTION = 'DOMException'; + +// `DOMException.prototype[@@toStringTag]` property +setToStringTag(getBuiltIn(DOM_EXCEPTION), DOM_EXCEPTION); + + +/***/ }), +/* 491 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +// TODO: Remove this module from `core-js@4` since it's split to modules listed below +__webpack_require__(492); +__webpack_require__(493); + + +/***/ }), +/* 492 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var clearImmediate = __webpack_require__(200).clear; + +// `clearImmediate` method +// http://w3c.github.io/setImmediate/#si-clearImmediate +$({ global: true, bind: true, enumerable: true, forced: globalThis.clearImmediate !== clearImmediate }, { + clearImmediate: clearImmediate +}); + + +/***/ }), +/* 493 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var setTask = __webpack_require__(200).set; +var schedulersFix = __webpack_require__(494); + +// https://github.com/oven-sh/bun/issues/1633 +var setImmediate = globalThis.setImmediate ? schedulersFix(setTask, false) : setTask; + +// `setImmediate` method +// http://w3c.github.io/setImmediate/#si-setImmediate +$({ global: true, bind: true, enumerable: true, forced: globalThis.setImmediate !== setImmediate }, { + setImmediate: setImmediate +}); + + +/***/ }), +/* 494 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var globalThis = __webpack_require__(2); +var apply = __webpack_require__(72); +var isCallable = __webpack_require__(28); +var ENVIRONMENT = __webpack_require__(141); +var USER_AGENT = __webpack_require__(21); +var arraySlice = __webpack_require__(183); +var validateArgumentsLength = __webpack_require__(201); + +var Function = globalThis.Function; +// dirty IE9- and Bun 0.3.0- checks +var WRAP = /MSIE .\./.test(USER_AGENT) || ENVIRONMENT === 'BUN' && (function () { + var version = globalThis.Bun.version.split('.'); + return version.length < 3 || version[0] === '0' && (version[1] < 3 || version[1] === '3' && version[2] === '0'); +})(); + +// IE9- / Bun 0.3.0- setTimeout / setInterval / setImmediate additional parameters fix +// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers +// https://github.com/oven-sh/bun/issues/1633 +module.exports = function (scheduler, hasTimeArg) { + var firstParamIndex = hasTimeArg ? 2 : 1; + return WRAP ? function (handler, timeout /* , ...arguments */) { + var boundArgs = validateArgumentsLength(arguments.length, 1) > firstParamIndex; + var fn = isCallable(handler) ? handler : Function(handler); + var params = boundArgs ? arraySlice(arguments, firstParamIndex) : []; + var callback = boundArgs ? function () { + apply(fn, this, params); + } : fn; + return hasTimeArg ? scheduler(callback, timeout) : scheduler(callback); + } : scheduler; +}; + + +/***/ }), +/* 495 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var defineBuiltInAccessor = __webpack_require__(131); +var DESCRIPTORS = __webpack_require__(24); + +var $TypeError = TypeError; +// eslint-disable-next-line es/no-object-defineproperty -- safe +var defineProperty = Object.defineProperty; +var INCORRECT_VALUE = globalThis.self !== globalThis; + +// `self` getter +// https://html.spec.whatwg.org/multipage/window-object.html#dom-self +try { + if (DESCRIPTORS) { + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + var descriptor = Object.getOwnPropertyDescriptor(globalThis, 'self'); + // some engines have `self`, but with incorrect descriptor + // https://github.com/denoland/deno/issues/15765 + if (INCORRECT_VALUE || !descriptor || !descriptor.get || !descriptor.enumerable) { + defineBuiltInAccessor(globalThis, 'self', { + get: function self() { + return globalThis; + }, + set: function self(value) { + if (this !== globalThis) throw new $TypeError('Illegal invocation'); + defineProperty(globalThis, 'self', { + value: value, + writable: true, + configurable: true, + enumerable: true + }); + }, + configurable: true, + enumerable: true + }); + } + } else $({ global: true, simple: true, forced: INCORRECT_VALUE }, { + self: globalThis + }); +} catch (error) { /* empty */ } + + +/***/ }), +/* 496 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var IS_PURE = __webpack_require__(16); +var $ = __webpack_require__(49); +var globalThis = __webpack_require__(2); +var getBuiltIn = __webpack_require__(35); +var uncurryThis = __webpack_require__(6); +var fails = __webpack_require__(8); +var uid = __webpack_require__(18); +var isCallable = __webpack_require__(28); +var isConstructor = __webpack_require__(199); +var isNullOrUndefined = __webpack_require__(11); +var isObject = __webpack_require__(27); +var isSymbol = __webpack_require__(34); +var iterate = __webpack_require__(97); +var anObject = __webpack_require__(30); +var classof = __webpack_require__(82); +var hasOwn = __webpack_require__(5); +var createProperty = __webpack_require__(149); +var createNonEnumerableProperty = __webpack_require__(50); +var lengthOfArrayLike = __webpack_require__(67); +var validateArgumentsLength = __webpack_require__(201); +var getRegExpFlags = __webpack_require__(271); +var MapHelpers = __webpack_require__(185); +var SetHelpers = __webpack_require__(247); +var setIterate = __webpack_require__(249); +var detachTransferable = __webpack_require__(138); +var ERROR_STACK_INSTALLABLE = __webpack_require__(87); +var PROPER_STRUCTURED_CLONE_TRANSFER = __webpack_require__(142); + +var Object = globalThis.Object; +var Array = globalThis.Array; +var Date = globalThis.Date; +var Error = globalThis.Error; +var TypeError = globalThis.TypeError; +var PerformanceMark = globalThis.PerformanceMark; +var DOMException = getBuiltIn('DOMException'); +var Map = MapHelpers.Map; +var mapHas = MapHelpers.has; +var mapGet = MapHelpers.get; +var mapSet = MapHelpers.set; +var Set = SetHelpers.Set; +var setAdd = SetHelpers.add; +var setHas = SetHelpers.has; +var objectKeys = getBuiltIn('Object', 'keys'); +var push = uncurryThis([].push); +var thisBooleanValue = uncurryThis(true.valueOf); +var thisNumberValue = uncurryThis(1.1.valueOf); +var thisStringValue = uncurryThis(''.valueOf); +var thisTimeValue = uncurryThis(Date.prototype.getTime); +var PERFORMANCE_MARK = uid('structuredClone'); +var DATA_CLONE_ERROR = 'DataCloneError'; +var TRANSFERRING = 'Transferring'; + +var checkBasicSemantic = function (structuredCloneImplementation) { + return !fails(function () { + var set1 = new globalThis.Set([7]); + var set2 = structuredCloneImplementation(set1); + var number = structuredCloneImplementation(Object(7)); + return set2 === set1 || !set2.has(7) || !isObject(number) || +number !== 7; + }) && structuredCloneImplementation; +}; + +var checkErrorsCloning = function (structuredCloneImplementation, $Error) { + return !fails(function () { + var error = new $Error(); + var test = structuredCloneImplementation({ a: error, b: error }); + return !(test && test.a === test.b && test.a instanceof $Error && test.a.stack === error.stack); + }); +}; + +// https://github.com/whatwg/html/pull/5749 +var checkNewErrorsCloningSemantic = function (structuredCloneImplementation) { + return !fails(function () { + var test = structuredCloneImplementation(new globalThis.AggregateError([1], PERFORMANCE_MARK, { cause: 3 })); + return test.name !== 'AggregateError' || test.errors[0] !== 1 || test.message !== PERFORMANCE_MARK || test.cause !== 3; + }); +}; + +// FF94+, Safari 15.4+, Chrome 98+, NodeJS 17.0+, Deno 1.13+ +// FF<103 and Safari implementations can't clone errors +// https://bugzilla.mozilla.org/show_bug.cgi?id=1556604 +// FF103 can clone errors, but `.stack` of clone is an empty string +// https://bugzilla.mozilla.org/show_bug.cgi?id=1778762 +// FF104+ fixed it on usual errors, but not on DOMExceptions +// https://bugzilla.mozilla.org/show_bug.cgi?id=1777321 +// Chrome <102 returns `null` if cloned object contains multiple references to one error +// https://bugs.chromium.org/p/v8/issues/detail?id=12542 +// NodeJS implementation can't clone DOMExceptions +// https://github.com/nodejs/node/issues/41038 +// only FF103+ supports new (html/5749) error cloning semantic +var nativeStructuredClone = globalThis.structuredClone; + +var FORCED_REPLACEMENT = IS_PURE + || !checkErrorsCloning(nativeStructuredClone, Error) + || !checkErrorsCloning(nativeStructuredClone, DOMException) + || !checkNewErrorsCloningSemantic(nativeStructuredClone); + +// Chrome 82+, Safari 14.1+, Deno 1.11+ +// Chrome 78-81 implementation swaps `.name` and `.message` of cloned `DOMException` +// Chrome returns `null` if cloned object contains multiple references to one error +// Safari 14.1 implementation doesn't clone some `RegExp` flags, so requires a workaround +// Safari implementation can't clone errors +// Deno 1.2-1.10 implementations too naive +// NodeJS 16.0+ does not have `PerformanceMark` constructor +// NodeJS <17.2 structured cloning implementation from `performance.mark` is too naive +// and can't clone, for example, `RegExp` or some boxed primitives +// https://github.com/nodejs/node/issues/40840 +// no one of those implementations supports new (html/5749) error cloning semantic +var structuredCloneFromMark = !nativeStructuredClone && checkBasicSemantic(function (value) { + return new PerformanceMark(PERFORMANCE_MARK, { detail: value }).detail; +}); + +var nativeRestrictedStructuredClone = checkBasicSemantic(nativeStructuredClone) || structuredCloneFromMark; + +var throwUncloneable = function (type) { + throw new DOMException('Uncloneable type: ' + type, DATA_CLONE_ERROR); +}; + +var throwUnpolyfillable = function (type, action) { + throw new DOMException((action || 'Cloning') + ' of ' + type + ' cannot be properly polyfilled in this engine', DATA_CLONE_ERROR); +}; + +var tryNativeRestrictedStructuredClone = function (value, type) { + if (!nativeRestrictedStructuredClone) throwUnpolyfillable(type); + return nativeRestrictedStructuredClone(value); +}; + +var createDataTransfer = function () { + var dataTransfer; + try { + dataTransfer = new globalThis.DataTransfer(); + } catch (error) { + try { + dataTransfer = new globalThis.ClipboardEvent('').clipboardData; + } catch (error2) { /* empty */ } + } + return dataTransfer && dataTransfer.items && dataTransfer.files ? dataTransfer : null; +}; + +var cloneBuffer = function (value, map, $type) { + if (mapHas(map, value)) return mapGet(map, value); + + var type = $type || classof(value); + var clone, length, options, source, target, i; + + if (type === 'SharedArrayBuffer') { + if (nativeRestrictedStructuredClone) clone = nativeRestrictedStructuredClone(value); + // SharedArrayBuffer should use shared memory, we can't polyfill it, so return the original + else clone = value; + } else { + var DataView = globalThis.DataView; + + // `ArrayBuffer#slice` is not available in IE10 + // `ArrayBuffer#slice` and `DataView` are not available in old FF + if (!DataView && !isCallable(value.slice)) throwUnpolyfillable('ArrayBuffer'); + // detached buffers throws in `DataView` and `.slice` + try { + if (isCallable(value.slice) && !value.resizable) { + clone = value.slice(0); + } else { + length = value.byteLength; + options = 'maxByteLength' in value ? { maxByteLength: value.maxByteLength } : undefined; + // eslint-disable-next-line es/no-resizable-and-growable-arraybuffers -- safe + clone = new ArrayBuffer(length, options); + source = new DataView(value); + target = new DataView(clone); + for (i = 0; i < length; i++) { + target.setUint8(i, source.getUint8(i)); + } + } + } catch (error) { + throw new DOMException('ArrayBuffer is detached', DATA_CLONE_ERROR); + } + } + + mapSet(map, value, clone); + + return clone; +}; + +var cloneView = function (value, type, offset, length, map) { + var C = globalThis[type]; + // in some old engines like Safari 9, typeof C is 'object' + // on Uint8ClampedArray or some other constructors + if (!isObject(C)) throwUnpolyfillable(type); + return new C(cloneBuffer(value.buffer, map), offset, length); +}; + +var structuredCloneInternal = function (value, map) { + if (isSymbol(value)) throwUncloneable('Symbol'); + if (!isObject(value)) return value; + // effectively preserves circular references + if (map) { + if (mapHas(map, value)) return mapGet(map, value); + } else map = new Map(); + + var type = classof(value); + var C, name, cloned, dataTransfer, i, length, keys, key; + + switch (type) { + case 'Array': + cloned = Array(lengthOfArrayLike(value)); + break; + case 'Object': + cloned = {}; + break; + case 'Map': + cloned = new Map(); + break; + case 'Set': + cloned = new Set(); + break; + case 'RegExp': + // in this block because of a Safari 14.1 bug + // old FF does not clone regexes passed to the constructor, so get the source and flags directly + cloned = new RegExp(value.source, getRegExpFlags(value)); + break; + case 'Error': + name = value.name; + switch (name) { + case 'AggregateError': + cloned = new (getBuiltIn(name))([]); + break; + case 'EvalError': + case 'RangeError': + case 'ReferenceError': + case 'SuppressedError': + case 'SyntaxError': + case 'TypeError': + case 'URIError': + cloned = new (getBuiltIn(name))(); + break; + case 'CompileError': + case 'LinkError': + case 'RuntimeError': + cloned = new (getBuiltIn('WebAssembly', name))(); + break; + default: + cloned = new Error(); + } + break; + case 'DOMException': + cloned = new DOMException(value.message, value.name); + break; + case 'ArrayBuffer': + case 'SharedArrayBuffer': + cloned = cloneBuffer(value, map, type); + break; + case 'DataView': + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float16Array': + case 'Float32Array': + case 'Float64Array': + case 'BigInt64Array': + case 'BigUint64Array': + length = type === 'DataView' ? value.byteLength : value.length; + cloned = cloneView(value, type, value.byteOffset, length, map); + break; + case 'DOMQuad': + try { + cloned = new DOMQuad( + structuredCloneInternal(value.p1, map), + structuredCloneInternal(value.p2, map), + structuredCloneInternal(value.p3, map), + structuredCloneInternal(value.p4, map) + ); + } catch (error) { + cloned = tryNativeRestrictedStructuredClone(value, type); + } + break; + case 'File': + if (nativeRestrictedStructuredClone) try { + cloned = nativeRestrictedStructuredClone(value); + // NodeJS 20.0.0 bug, https://github.com/nodejs/node/issues/47612 + if (classof(cloned) !== type) cloned = undefined; + } catch (error) { /* empty */ } + if (!cloned) try { + cloned = new File([value], value.name, value); + } catch (error) { /* empty */ } + if (!cloned) throwUnpolyfillable(type); + break; + case 'FileList': + dataTransfer = createDataTransfer(); + if (dataTransfer) { + for (i = 0, length = lengthOfArrayLike(value); i < length; i++) { + dataTransfer.items.add(structuredCloneInternal(value[i], map)); + } + cloned = dataTransfer.files; + } else cloned = tryNativeRestrictedStructuredClone(value, type); + break; + case 'ImageData': + // Safari 9 ImageData is a constructor, but typeof ImageData is 'object' + try { + cloned = new ImageData( + structuredCloneInternal(value.data, map), + value.width, + value.height, + { colorSpace: value.colorSpace } + ); + } catch (error) { + cloned = tryNativeRestrictedStructuredClone(value, type); + } break; + default: + if (nativeRestrictedStructuredClone) { + cloned = nativeRestrictedStructuredClone(value); + } else switch (type) { + case 'BigInt': + // can be a 3rd party polyfill + cloned = Object(value.valueOf()); + break; + case 'Boolean': + cloned = Object(thisBooleanValue(value)); + break; + case 'Number': + cloned = Object(thisNumberValue(value)); + break; + case 'String': + cloned = Object(thisStringValue(value)); + break; + case 'Date': + cloned = new Date(thisTimeValue(value)); + break; + case 'Blob': + try { + cloned = value.slice(0, value.size, value.type); + } catch (error) { + throwUnpolyfillable(type); + } break; + case 'DOMPoint': + case 'DOMPointReadOnly': + C = globalThis[type]; + try { + cloned = C.fromPoint + ? C.fromPoint(value) + : new C(value.x, value.y, value.z, value.w); + } catch (error) { + throwUnpolyfillable(type); + } break; + case 'DOMRect': + case 'DOMRectReadOnly': + C = globalThis[type]; + try { + cloned = C.fromRect + ? C.fromRect(value) + : new C(value.x, value.y, value.width, value.height); + } catch (error) { + throwUnpolyfillable(type); + } break; + case 'DOMMatrix': + case 'DOMMatrixReadOnly': + C = globalThis[type]; + try { + cloned = C.fromMatrix + ? C.fromMatrix(value) + : new C(value); + } catch (error) { + throwUnpolyfillable(type); + } break; + case 'AudioData': + case 'VideoFrame': + if (!isCallable(value.clone)) throwUnpolyfillable(type); + try { + cloned = value.clone(); + } catch (error) { + throwUncloneable(type); + } break; + case 'CropTarget': + case 'CryptoKey': + case 'FileSystemDirectoryHandle': + case 'FileSystemFileHandle': + case 'FileSystemHandle': + case 'GPUCompilationInfo': + case 'GPUCompilationMessage': + case 'ImageBitmap': + case 'RTCCertificate': + case 'WebAssembly.Module': + throwUnpolyfillable(type); + // break omitted + default: + throwUncloneable(type); + } + } + + mapSet(map, value, cloned); + + switch (type) { + case 'Array': + case 'Object': + keys = objectKeys(value); + for (i = 0, length = lengthOfArrayLike(keys); i < length; i++) { + key = keys[i]; + createProperty(cloned, key, structuredCloneInternal(value[key], map)); + } break; + case 'Map': + value.forEach(function (v, k) { + mapSet(cloned, structuredCloneInternal(k, map), structuredCloneInternal(v, map)); + }); + break; + case 'Set': + value.forEach(function (v) { + setAdd(cloned, structuredCloneInternal(v, map)); + }); + break; + case 'Error': + createNonEnumerableProperty(cloned, 'message', structuredCloneInternal(value.message, map)); + if (hasOwn(value, 'cause')) { + createNonEnumerableProperty(cloned, 'cause', structuredCloneInternal(value.cause, map)); + } + if (name === 'AggregateError') { + cloned.errors = structuredCloneInternal(value.errors, map); + } else if (name === 'SuppressedError') { + cloned.error = structuredCloneInternal(value.error, map); + cloned.suppressed = structuredCloneInternal(value.suppressed, map); + } // break omitted + case 'DOMException': + if (ERROR_STACK_INSTALLABLE) { + createNonEnumerableProperty(cloned, 'stack', structuredCloneInternal(value.stack, map)); + } + } + + return cloned; +}; + +var tryToTransfer = function (rawTransfer, map) { + if (!isObject(rawTransfer)) throw new TypeError('Transfer option cannot be converted to a sequence'); + + var transfer = []; + + iterate(rawTransfer, function (value) { + push(transfer, anObject(value)); + }); + + var i = 0; + var length = lengthOfArrayLike(transfer); + var buffers = new Set(); + var value, type, C, transferred, canvas, context; + + while (i < length) { + value = transfer[i++]; + + type = classof(value); + + if (type === 'ArrayBuffer' ? setHas(buffers, value) : mapHas(map, value)) { + throw new DOMException('Duplicate transferable', DATA_CLONE_ERROR); + } + + if (type === 'ArrayBuffer') { + setAdd(buffers, value); + continue; + } + + if (PROPER_STRUCTURED_CLONE_TRANSFER) { + transferred = nativeStructuredClone(value, { transfer: [value] }); + } else switch (type) { + case 'ImageBitmap': + C = globalThis.OffscreenCanvas; + if (!isConstructor(C)) throwUnpolyfillable(type, TRANSFERRING); + try { + canvas = new C(value.width, value.height); + context = canvas.getContext('bitmaprenderer'); + context.transferFromImageBitmap(value); + transferred = canvas.transferToImageBitmap(); + } catch (error) { /* empty */ } + break; + case 'AudioData': + case 'VideoFrame': + if (!isCallable(value.clone) || !isCallable(value.close)) throwUnpolyfillable(type, TRANSFERRING); + try { + transferred = value.clone(); + value.close(); + } catch (error) { /* empty */ } + break; + case 'MediaSourceHandle': + case 'MessagePort': + case 'MIDIAccess': + case 'OffscreenCanvas': + case 'ReadableStream': + case 'RTCDataChannel': + case 'TransformStream': + case 'WebTransportReceiveStream': + case 'WebTransportSendStream': + case 'WritableStream': + throwUnpolyfillable(type, TRANSFERRING); + } + + if (transferred === undefined) throw new DOMException('This object cannot be transferred: ' + type, DATA_CLONE_ERROR); + + mapSet(map, value, transferred); + } + + return buffers; +}; + +var detachBuffers = function (buffers) { + setIterate(buffers, function (buffer) { + if (PROPER_STRUCTURED_CLONE_TRANSFER) { + nativeRestrictedStructuredClone(buffer, { transfer: [buffer] }); + } else if (isCallable(buffer.transfer)) { + buffer.transfer(); + } else if (detachTransferable) { + detachTransferable(buffer); + } else { + throwUnpolyfillable('ArrayBuffer', TRANSFERRING); + } + }); +}; + +// `structuredClone` method +// https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone +$({ global: true, enumerable: true, sham: !PROPER_STRUCTURED_CLONE_TRANSFER, forced: FORCED_REPLACEMENT }, { + structuredClone: function structuredClone(value /* , { transfer } */) { + var options = validateArgumentsLength(arguments.length, 1) > 1 && !isNullOrUndefined(arguments[1]) ? anObject(arguments[1]) : undefined; + var transfer = options ? options.transfer : undefined; + var map, buffers; + + if (transfer !== undefined) { + map = new Map(); + buffers = tryToTransfer(transfer, map); + } + + var clone = structuredCloneInternal(value, map); + + // since of an issue with cloning views of transferred buffers, we a forced to detach them later + // https://github.com/zloirock/core-js/issues/1265 + if (buffers) detachBuffers(buffers); + + return clone; + } +}); + + +/***/ }), +/* 497 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var fails = __webpack_require__(8); +var validateArgumentsLength = __webpack_require__(201); +var toString = __webpack_require__(81); +var USE_NATIVE_URL = __webpack_require__(498); + +var URL = getBuiltIn('URL'); + +// https://github.com/nodejs/node/issues/47505 +// https://github.com/denoland/deno/issues/18893 +var THROWS_WITHOUT_ARGUMENTS = USE_NATIVE_URL && fails(function () { + URL.canParse(); +}); + +// Bun ~ 1.0.30 bug +// https://github.com/oven-sh/bun/issues/9250 +var WRONG_ARITY = fails(function () { + return URL.canParse.length !== 1; +}); + +// `URL.canParse` method +// https://url.spec.whatwg.org/#dom-url-canparse +$({ target: 'URL', stat: true, forced: !THROWS_WITHOUT_ARGUMENTS || WRONG_ARITY }, { + canParse: function canParse(url) { + var length = validateArgumentsLength(arguments.length, 1); + var urlString = toString(url); + var base = length < 2 || arguments[1] === undefined ? undefined : toString(arguments[1]); + try { + return !!new URL(urlString, base); + } catch (error) { + return false; + } + } +}); + + +/***/ }), +/* 498 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var fails = __webpack_require__(8); +var wellKnownSymbol = __webpack_require__(13); +var DESCRIPTORS = __webpack_require__(24); +var IS_PURE = __webpack_require__(16); + +var ITERATOR = wellKnownSymbol('iterator'); + +module.exports = !fails(function () { + // eslint-disable-next-line unicorn/relative-url-style -- required for testing + var url = new URL('b?a=1&b=2&c=3', 'https://a/'); + var params = url.searchParams; + var params2 = new URLSearchParams('a=1&a=2&b=3'); + var result = ''; + url.pathname = 'c%20d'; + params.forEach(function (value, key) { + params['delete']('b'); + result += key + value; + }); + params2['delete']('a', 2); + // `undefined` case is a Chromium 117 bug + // https://bugs.chromium.org/p/v8/issues/detail?id=14222 + params2['delete']('b', undefined); + return (IS_PURE && (!url.toJSON || !params2.has('a', 1) || params2.has('a', 2) || !params2.has('a', undefined) || params2.has('b'))) + || (!params.size && (IS_PURE || !DESCRIPTORS)) + || !params.sort + || url.href !== 'https://a/c%20d?a=1&c=3' + || params.get('c') !== '3' + || String(new URLSearchParams('?a=1')) !== 'a=1' + || !params[ITERATOR] + // throws in Edge + || new URL('https://a@b/').username !== 'a' + || new URLSearchParams(new URLSearchParams('a=b')).get('a') !== 'b' + // not punycoded in Edge + || new URL('https://xn--e1aybc/').host !== 'xn--e1aybc' + // not escaped in Chrome 62- + || new URL('https://a/#%D0%B1').hash !== '#%D0%B1' + // fails in Chrome 66- + || result !== 'a1c3' + // throws in Safari + || new URL('https://x/', undefined).host !== 'x'; +}); + + +/***/ }), +/* 499 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var $ = __webpack_require__(49); +var getBuiltIn = __webpack_require__(35); +var validateArgumentsLength = __webpack_require__(201); +var toString = __webpack_require__(81); +var USE_NATIVE_URL = __webpack_require__(498); + +var URL = getBuiltIn('URL'); + +// `URL.parse` method +// https://url.spec.whatwg.org/#dom-url-canparse +$({ target: 'URL', stat: true, forced: !USE_NATIVE_URL }, { + parse: function parse(url) { + var length = validateArgumentsLength(arguments.length, 1); + var urlString = toString(url); + var base = length < 2 || arguments[1] === undefined ? undefined : toString(arguments[1]); + try { + return new URL(urlString, base); + } catch (error) { + return null; + } + } +}); + + +/***/ }), +/* 500 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineBuiltIn = __webpack_require__(51); +var uncurryThis = __webpack_require__(6); +var toString = __webpack_require__(81); +var validateArgumentsLength = __webpack_require__(201); + +var $URLSearchParams = URLSearchParams; +var URLSearchParamsPrototype = $URLSearchParams.prototype; +var append = uncurryThis(URLSearchParamsPrototype.append); +var $delete = uncurryThis(URLSearchParamsPrototype['delete']); +var forEach = uncurryThis(URLSearchParamsPrototype.forEach); +var push = uncurryThis([].push); +var params = new $URLSearchParams('a=1&a=2&b=3'); + +params['delete']('a', 1); +// `undefined` case is a Chromium 117 bug +// https://bugs.chromium.org/p/v8/issues/detail?id=14222 +params['delete']('b', undefined); + +if (params + '' !== 'a=2') { + defineBuiltIn(URLSearchParamsPrototype, 'delete', function (name /* , value */) { + var length = arguments.length; + var $value = length < 2 ? undefined : arguments[1]; + if (length && $value === undefined) return $delete(this, name); + var entries = []; + forEach(this, function (v, k) { // also validates `this` + push(entries, { key: k, value: v }); + }); + validateArgumentsLength(length, 1); + var key = toString(name); + var value = toString($value); + var index = 0; + var dindex = 0; + var found = false; + var entriesLength = entries.length; + var entry; + while (index < entriesLength) { + entry = entries[index++]; + if (found || entry.key === key) { + found = true; + $delete(this, entry.key); + } else dindex++; + } + while (dindex < entriesLength) { + entry = entries[dindex++]; + if (!(entry.key === key && entry.value === value)) append(this, entry.key, entry.value); + } + }, { enumerable: true, unsafe: true }); +} + + +/***/ }), +/* 501 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var defineBuiltIn = __webpack_require__(51); +var uncurryThis = __webpack_require__(6); +var toString = __webpack_require__(81); +var validateArgumentsLength = __webpack_require__(201); + +var $URLSearchParams = URLSearchParams; +var URLSearchParamsPrototype = $URLSearchParams.prototype; +var getAll = uncurryThis(URLSearchParamsPrototype.getAll); +var $has = uncurryThis(URLSearchParamsPrototype.has); +var params = new $URLSearchParams('a=1'); + +// `undefined` case is a Chromium 117 bug +// https://bugs.chromium.org/p/v8/issues/detail?id=14222 +if (params.has('a', 2) || !params.has('a', undefined)) { + defineBuiltIn(URLSearchParamsPrototype, 'has', function has(name /* , value */) { + var length = arguments.length; + var $value = length < 2 ? undefined : arguments[1]; + if (length && $value === undefined) return $has(this, name); + var values = getAll(this, name); // also validates `this` + validateArgumentsLength(length, 1); + var value = toString($value); + var index = 0; + while (index < values.length) { + if (values[index++] === value) return true; + } return false; + }, { enumerable: true, unsafe: true }); +} + + +/***/ }), +/* 502 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +var DESCRIPTORS = __webpack_require__(24); +var uncurryThis = __webpack_require__(6); +var defineBuiltInAccessor = __webpack_require__(131); + +var URLSearchParamsPrototype = URLSearchParams.prototype; +var forEach = uncurryThis(URLSearchParamsPrototype.forEach); + +// `URLSearchParams.prototype.size` getter +// https://github.com/whatwg/url/pull/734 +if (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) { + defineBuiltInAccessor(URLSearchParamsPrototype, 'size', { + get: function size() { + var count = 0; + forEach(this, function () { count++; }); + return count; + }, + configurable: true, + enumerable: true + }); +} + + +/***/ }) +/******/ ]); }(); diff --git a/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md b/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md index bda380c66c00..b167e761ac76 100644 --- a/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md +++ b/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md @@ -1,7 +1,9 @@ -# core-js@3, babel and a look into the future - After more than 1.5 years of development, dozens of pre-releases, many sleepless nights, **[`core-js@3`](https://github.com/zloirock/core-js)** is finally released. It's the largest set of changes in `core-js` and polyfilling-related **[`babel`](https://babeljs.io)** features of all time. +--- + +# core-js@3, babel and a look into the future + What is `core-js`? - It is a polyfill of the JavaScript standard library, which supports: - The latest ECMAScript standard. @@ -11,17 +13,17 @@ What is `core-js`? - It can be used without polluting the global namespace. - It is [tightly integrated with `babel`](#Babel): this allows many optimizations of `core-js` import. -It's the most universal and [the most popular](https://www.npmtrends.com/core-js-vs-es5-shim-vs-es6-shim-vs-airbnb-js-shims-vs-polyfill-library-vs-polyfill-service-vs-js-polyfills) way to polyfill JavaScript standard library, but a big part of developers just don't know that they use `core-js` indirectly 🙂 +It's the most universal and [the most popular](https://npmtrends.com/airbnb-js-shims-vs-core-js-vs-es5-shim-vs-es6-shim-vs-js-polyfills-vs-polyfill-library-vs-polyfill-service) way to polyfill JavaScript standard library, but a big part of developers just don't know that they use `core-js` indirectly 🙂 ## Contributing `core-js` is my own hobby project and it does not bring me any profit. It takes too much time and it is really costly: to finish work on `core-js@3`, I had left my job some months ago. This project facilitates the life of many people and companies. For these reasons, it makes sense to start raising funds to support the maintenance of `core-js`. -If you interested in the `core-js` project or use it in your day-to-day work, you can become a sponsor on **[Open Collective](https://opencollective.com/core-js#sponsor)** or **[Patreon](https://www.patreon.com/zloirock)**. +If you are interested in the `core-js` project or use it in your day-to-day work, you can become a sponsor on **[Open Collective](https://opencollective.com/core-js#sponsor)** or **[Patreon](https://www.patreon.com/zloirock)**. You can propose [me](http://zloirock.ru/) a good job where I will be able to work on something related. -Or you can contribute in another way: you can help improving code, tests or documentation (currently, `core-js` documentation is terrible!). +Or you can contribute in another way: you can help improve code, tests or documentation (currently, `core-js` documentation is terrible!). ## What changed in `core-js@3`? @@ -106,15 +108,15 @@ Some proposals have been largely changed, and `core-js` was updated accordingly: #### Web standards -Many useful features have been added in this category. +Many useful features have been added to this category. -The most important one is support for [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) and [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams). It was [one of the most popular feature requests](https://github.com/zloirock/core-js/issues/117). Adding `URL` and `URLSearchParams`, making maximally spec compliant, supporting any environment keeping their source code small compact was [one of the hardest tasks](https://github.com/zloirock/core-js/pull/454/files) in the `core-js@3` development. +The most important one is support for [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) and [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams). It was [one of the most popular feature requests](https://github.com/zloirock/core-js/issues/117). Adding `URL` and `URLSearchParams`, making maximally spec-compliant, supporting any environment keeping their source code small compact was [one of the hardest tasks](https://github.com/zloirock/core-js/pull/454/files) in the `core-js@3` development. `core-js@3` includes *a standard* method to create microtasks in JavaScript: [`queueMicrotask`](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#microtask-queuing). `core-js@2` provided the `asap` function which did the same thing and was an old ECMAScript proposal. `queueMicrotask` is defined in the HTML standard and it is already available in modern engines like Chromium or NodeJS. Another popular feature request was support for the [`.forEach` method on DOM collection](https://developer.mozilla.org/en-US/docs/Web/API/NodeList/forEach). Since `core-js` already polyfilled iterators of DOM collections, why not add also `.forEach` to `NodeList` and `DOMTokenList`? -#### Removed obsolete featues: +#### Removed obsolete features: - `Reflect.enumerate` because it's removed from the spec - `System.global` and `global` since now they are replaced by `globalThis` @@ -132,7 +134,7 @@ Many years ago, I started writing a library which I needed as the core of my Jav ### Packages, entry points and modules names -A popular issue was the big size (~2MB) of the `core-js` package and duplication of many of its files. For this reason, `core-js` was split into three packages: +A popular issue was a big size (~2MB) of the `core-js` package and duplication of many of its files. For this reason, `core-js` was split into three packages: - [`core-js`](https://www.npmjs.com/package/core-js), which defines global polyfills. (~500KB, [40KB minified and gzipped](https://bundlephobia.com/result?p=core-js@3.0.0-beta.20)) - [`core-js-pure`](https://www.npmjs.com/package/core-js-pure), which provides polyfills without pollution the global environment. It's the equivalent of `core-js/library` from `core-js@2`. (~440KB) - [`core-js-bundle`](https://www.npmjs.com/package/core-js-bundle): a bundled version of `core-js` which defines global polyfills. @@ -176,13 +178,13 @@ import "core-js/stage/2"; ### Some other important changes -It's now possible to [configure the aggressiveness](https://github.com/zloirock/core-js/blob/master/README.md#configurable-level-of-aggressiveness) of `core-js` polyfills. If you think that `core-js` feature detection is too aggressive in some cases and that the native implementation is correct enough for your usecase, or if an incorrect implementation isn't detected by `core-js` as such, you can change the `core-js` default behavior. +It's now possible to [configure the aggressiveness](https://github.com/zloirock/core-js/blob/master/README.md#configurable-level-of-aggressiveness) of `core-js` polyfills. If you think that `core-js` feature detection is too aggressive in some cases and that the native implementation is correct enough for your use-case, or if an incorrect implementation isn't detected by `core-js` as such, you can change the `core-js` default behavior. -If a feature can't be implemented following the specification in every details, `core-js` adds a `.sham` property to the polyfill. For example, in IE11 `Symbol.sham` is `true`. +If a feature can't be implemented following the specification in every detail, `core-js` adds a `.sham` property to the polyfill. For example, in IE11 `Symbol.sham` is `true`. No more LiveScript! When I started the `core-js` project, I mainly used [LiveScript](http://livescript.net/); after some time, I rewrote all the polyfills in JavaScript. Tests and helper tools in `core-js@2` still used LiveScript: it is a very interesting CoffeeScript-like language with powerful syntax sugar which allows writing very compact code, but now it's almost dead. Other than that, it was an additional barrier for contributing to `core-js` because most `core-js` users do not know this language. `core-js@3` tests and tools use modern ES syntax: it could be a good moment to start contributing to `core-js` 🙂 -For almost all users, for optimization of `core-js` import, I recommend using [`babel`](#Babel). However, for some cases still useful [`core-js-builder`](http://npmjs.com/package/core-js-builder). Now it supports the `targets` argument which takes a [`browserslist`](https://github.com/browserslist/browserslist) query with target engines - you can create a bundle which contains only required for target engines polyfills. For cases like this, I made the [`core-js-compat`](http://npmjs.com/package/core-js-compat) package, more info about it you could find in [`@babel/preset-env` part of this article](#babelpreset-env). +For almost all users, for optimization of `core-js` import, I recommend using [`babel`](#Babel). However, [`core-js-builder`](https://npmjs.com/package/core-js-builder) is still useful in some cases. Now it supports the `targets` argument which takes a [`browserslist`](https://github.com/browserslist/browserslist) query with target engines - you can create a bundle which contains only required for target engines polyfills. For cases like this, I made the [`core-js-compat`](https://www.npmjs.com/package/core-js-compat) package, more info about it you could find in [`@babel/preset-env` part of this article](#babelpreset-env). --- @@ -225,16 +227,16 @@ To make it possible for Babel to support new `core-js` features introduced in fu One of the most important parts of `@babel/preset-env` was the source providing data about the features supported by different target engines, to understand whether something needs to be polyfilled by `core-js` or not. [`caniuse`](https://caniuse.com/), [`mdn`](https://developer.mozilla.org/en-US/) and [`compat-table`](http://kangax.github.io/compat-table/es6/) are good educational resources but aren't really meant to be used as data sources for developer tools: only the `compat-table` contains a good set of ES-related data and it is used by `@babel/preset-env`, but it has some limitations: - it contains data only about ECMAScript features and proposals, but not about web platform features like `setImmediate` or DOM collections iterators. So, up to now, `@babel/preset-env` added all web platform features from `core-js` even for targets where they are supported. - it does not contain any information about (even serious) bugs in engines: for example, already mentioned `Array#reverse` broken in Safari 12 but it isn't marked as unsupported by `compat-table`. On the other hand, `core-js` correctly fixes broken implementations, but with `compat-table` this capability wasn't taken advantage of. -- it contains only some basic and naive tests, which do not check that features work as they should in real-word cases. For example, old Safari has broken iterators without `.next` method, but `compat-table` shows them as supported because it just check that `typeof` of methods which should return iterators is `"function"`. Some features like typed arrays are almost completely not covered. +- it contains only some basic and naive tests, which do not check that features work as they should in real-world cases. For example, old Safari has broken iterators without `.next` method, but `compat-table` shows them as supported because it just checks that `typeof` of methods which should return iterators is `"function"`. Some features like typed arrays are almost completely not covered. - `compat-table` is not designed for providing data for tools. I'm one of the `compat-table` maintainers, but [some of the other maintainers are against maintaining this functionality](https://github.com/kangax/compat-table/pull/1312). -For this reason, I created the [`core-js-compat`](https://github.com/zloirock/core-js/tree/master/packages/core-js-compat) package: it provides data about the necessity of `core-js` modules for different target engines. When using `core-js@3`, `@babel/preset-env` will use that new package instead of `compat-table`. [Please help us testing and providing data and mappings for missing engines! 😊](https://github.com/zloirock/core-js/blob/master/CONTRIBUTING.md#updating-core-js-compat-data) +For this reason, I created the [`core-js-compat`](https://github.com/zloirock/core-js/tree/master/packages/core-js-compat) package: it provides data about the necessity of `core-js` modules for different target engines. When using `core-js@3`, `@babel/preset-env` will use that new package instead of `compat-table`. [Please help us with testing and providing data and mappings for missing engines! 😊](https://github.com/zloirock/core-js/blob/master/CONTRIBUTING.md#updating-core-js-compat-data) -Until Babel 7.3, `@babel/preset-env` had some problems related to the order polyfills were injected. Starting from version 7.4.0, `@babel/preset-env` will add the polyfills only when it know which of them required and in the recommended order. +Until Babel 7.3, `@babel/preset-env` had some problems related to the order polyfills were injected. Starting from version 7.4.0, `@babel/preset-env` will add the polyfills only when it knows which of them is required and in the recommended order. #### `useBuiltIns: entry` with `corejs: 3` -When using this option, `@babel/preset-env` replaces direct imports of `core-js` to imports of only the specific modules required for a target environment. +When using this option, `@babel/preset-env` replaces direct imports of `core-js` with imports of only the specific modules required for a target environment. Before those changes, `@babel/preset-env` replaced only `import '@babel/polyfill'` and `import 'core-js'`, they were synonyms and used for polyfilling all stable JavaScript features. @@ -259,7 +261,7 @@ when targeting `chrome 73` (which completely support ES2019 standard library), i import "core-js/modules/web.immediate"; ``` -Since now `@babel/polyfill` is deprecated in favor of separate `core-js` and `regenerator-runtime` inclusion, we can optimize `regenerator-runtime` import. For this reason, `regenerator-runtime` import will be removed from the source code when targeting browsers that supports generators natively. +Since now `@babel/polyfill` is deprecated in favor of separate `core-js` and `regenerator-runtime` inclusion, we can optimize `regenerator-runtime` import. For this reason, `regenerator-runtime` import will be removed from the source code when targeting browsers that support generators natively. Now, `@babel/preset-env` in `useBuiltIns: entry` mode transpile **all available** `core-js` entry points and their combinations. This means that you can customize it as much as you want, by using different `core-js` entry points, and it will be optimized for your target environment. @@ -321,7 +323,7 @@ Babel 7.4 supports injecting proposals polyfills. By default, `@babel/preset-env ### `@babel/runtime` -When used with `core-js@3`, [`@babel/transform-runtime`](https://babeljs.io/docs/en/next/babel-plugin-transform-runtime#corejs) now injects polyfills from `core-js-pure`: a version of `core-js` which doesn't pollute the global namespace. +When used with `core-js@3`, [`@babel/transform-runtime`](https://babeljs.io/docs/en/next/babel-plugin-transform-runtime#corejs) now injects polyfills from `core-js-pure`: a version of `core-js` that doesn't pollute the global namespace. `core-js@3` and `@babel/runtime` have been integrated together by adding a `corejs: 3` option to `@babel/transform-runtime` and creating the `@babel/runtime-corejs3` package. But what advantages did this bring? @@ -366,7 +368,7 @@ myArrayLikeObject[Symbol.iterator] = Array.prototype[Symbol.iterator]; ``` Although previous versions of `@babel/runtime` did not work with instance methods, iterables (both `[Symbol.iterator]()` calls and its presence) were supported using some custom helper functions. Extracting the `[Symbol.iterator]` method was not supported, but now it works. -As a cheap bonus, `@babel/runtime` now supports IE8-, with some limitations. For example, since IE8- does not support accessors, modules transform should be used in loose mode and `regenerator-runtime` (which internally use some ES5+ built-ins) needs to be transpiled by this plugin. +As a cheap bonus, `@babel/runtime` now supports IE8-, with some limitations. For example, since IE8- does not support accessors, modules transform should be used in loose mode and `regenerator-runtime` (which internally uses some ES5+ built-ins) needs to be transpiled by this plugin. ## Look into the future @@ -374,27 +376,27 @@ Much work has been done, but `core-js` is still far from perfect. How can the li ### Old engines support -At this moment, `core-js` tries to support all possible engines and platforms where we can test it: it even supports IE8- or, for example, early Firefox versions. While it is useful for some users, only for a small part of developers using `core-js` need it. For many other users, it can cause some problems like bigger bundle size or slower runtime execution. +At this moment, `core-js` tries to support all possible engines and platforms where we can test it: it even supports IE8- or, for example, early Firefox versions. While it is useful for some users, only a small part of developers using `core-js` need it. For many other users, it can cause some problems like bigger bundle size or slower runtime execution. -The main problem comes from supporting ES3 engines (above all, IE8-): most modern ES features based on ES5 features, which aren't available in those very old browsers. +The main problem comes from supporting ES3 engines (above all, IE8-): most modern ES features are based on ES5 features, which aren't available in those very old browsers. -The biggest missing important feature are property descriptors: when they aren't available, some features can't be polyfilled because they either are accessors (like `RegExp.prototype.flags` or `URL` properties setters) or are accessors-based (like typed arrays polyfill). In order to workaround this lack, we need to use different workarounds (for example, to keep `Set.prototype.size` updated). Maintenance of those workarounds sometimes is too painful, and removing them would highly simplify many polyfills. +The biggest missing important feature is property descriptors: when they aren't available, some features can't be polyfilled because they either are accessors (like `RegExp.prototype.flags` or `URL` properties setters) or are accessors-based (like typed arrays polyfill). In order to workaround this lack, we need to use different workarounds (for example, to keep `Set.prototype.size` updated). Maintenance of those workarounds sometimes is too painful, and removing them would highly simplify many polyfills. However, descriptors are just a part of this problem. The ES5 standard library contains many other features that can be considered as the basis of modern JavaScript: `Object.keys`, `Object.create`, `Object.getPrototypeOf`, `Array.prototype.forEach`, `Function.prototype.bind`, etc. Unlike the most modern features, `core-js` internally relies on them and [in order to implement even a simple modern function, `core-js` needs to load implementations of some of those "building blocks"](https://github.com/babel/babel/pull/7646#discussion_r179333093). It is a problem for users who want to create [a maximally minimalistic bundle](https://github.com/zloirock/core-js/issues/388) and only import just a few `core-js` polyfills. -In some countries IE8 still is quite popular, but browsers should disappear at some point to allow the web to move forward. IE8 was released 19-03-2009; today it is 19-03-2019: it's the 10th birthday of IE8. IE6 is about to turn 18: I stopped testing new `core-js` versions in IE6 some months ago. +In some countries, IE8 still is quite popular, but browsers should disappear at some point to allow the web to move forward. IE8 was released 19-03-2009; today it is 19-03-2019: it's the 10th birthday of IE8. IE6 is about to turn 18: I stopped testing new `core-js` versions in IE6 some months ago. We should drop IE8- and other engines without basic ES5 support in `core-js@4`. ### ECMAScript modules -`core-js` use `CommonJS` modules. It has the most popular JavaScript modules format for a long time, but now ECMAScript provides its own modules format. Many engines already support them; some bundlers (like `rollup`) are based on them, and some other bundlers provide them as an alternative to `CommonJS`. It would make sense to provide an alternative version of `core-js` which uses ECMAScript modules format. +`core-js` use `CommonJS` modules. It has been the most popular JavaScript modules format for a long time, but now ECMAScript provides its own modules format. Many engines already support them; some bundlers (like `rollup`) are based on them, and some other bundlers provide them as an alternative to `CommonJS`. It would make sense to provide an alternative version of `core-js` which uses ECMAScript modules format. ### Extended web standards support? `core-js` is currently focused on ECMAScript support, but it also supports a few web standards features which are available cross-platform and closely related to ECMAScript. Adding polyfills for web standards like `fetch` is a very popular feature request. -The main reason why `core-js` doesn’t include them was that it would have seriously increased bundles size and it would have forced `core-js` users to load features which might not have been needed. Now `core-js` is maximally modular, user can include only some choosen features, there are tools like `@babel/preset-env` and `@babel/runtime` which helps to get rid of unused or unnecessary polyfills. +The main reason why `core-js` doesn’t include them was that it would have seriously increased bundles size and it would have forced `core-js` users to load features which might not have been needed. Now `core-js` is maximally modular, user can include only some chosen features, there are tools like `@babel/preset-env` and `@babel/runtime` which helps to get rid of unused or unnecessary polyfills. Maybe it's time to revisit this old decision? @@ -410,9 +412,9 @@ As explained above, Babel plugins give us different ways of optimizing `core-js` `@babel/preset-env` with `useBuiltIns: usage` now should work much better than before, but it could still fail in some uncommon cases: when the code can't be statically analyzed. For that case, we need to find a way for library developers to specify which polyfills are required by their library instead of directly loading them: some kind of metadata, which will be used to inject polyfills when creating the final bundle. -Another issue of `useBuiltIns: usage` is the duplication of polyfills import. `useBuiltIns: usage` can inject dozens of `core-js` imports in each file. But what if in our project has thousands of files or even tenths of thousands? In this case, we will have more lines of code with `import "core-js/..."` than lines of code in `core-js` itself: we need a way to collect all imports to one file so that they can be deduplicated. +Another issue of `useBuiltIns: usage` is the duplication of polyfills import. `useBuiltIns: usage` can inject dozens of `core-js` imports in each file. But what if our project has thousands of files or even tenths of thousands? In this case, we will have more lines of code with `import "core-js/..."` than lines of code in `core-js` itself: we need a way to collect all imports to one file so that they can be deduplicated. -Almost every `@babel/preset-env` user which targets old engines like IE11 uses a single bundle for every browser. That means that even modern engines with full ES2019 support will be loading the unnecessary polyfills only required by IE11. Sure, we can create different bundles for different targets and use, for example, the `type=module` / `nomodules` attributes: one bundle for modern engines with modules support, another for legacy engines. Unfortunately it’s not a complete solution to this problem: a service which bundles polyfills for the required target based on the user agent would be really useful. And we already have one - [`polyfill-service`](https://github.com/Financial-Times/polyfill-service). Although it is an interesting and popular service, polyfills quality leaves much to be desired. It’s not as bad as it was some years ago: the team of this project is actively working to improve it, but I wouldn't recommend using polyfills from this project if you want them to match native implementations. Some years ago was an attempt to use `core-js` as a polyfills source for this project, but it hadn't been possible because `polyfill-service` relies on files concatenation instead of modules (like `core-js` in the first few months after it was published 😊). +Almost every `@babel/preset-env` user which targets old engines like IE11 uses a single bundle for every browser. That means that even modern engines with full ES2019 support will be loading the unnecessary polyfills only required by IE11. Sure, we can create different bundles for different targets and use, for example, the `type=module` / `nomodules` attributes: one bundle for modern engines with modules support, another for legacy engines. Unfortunately, it’s not a complete solution to this problem: a service that bundles polyfills for the required target based on the user agent would be really useful. And we already have one - [`polyfill-service`](https://github.com/Financial-Times/polyfill-service). Although it is an interesting and popular service, polyfills quality leaves much to be desired. It’s not as bad as it was some years ago: the team of this project is actively working to improve it, but I wouldn't recommend using polyfills from this project if you want them to match native implementations. Some years ago was an attempt to use `core-js` as a polyfills source for this project, but it hadn't been possible because `polyfill-service` relies on files concatenation instead of modules (like `core-js` in the first few months after it was published 😊). A service like this one integrated with a good polyfills source like `core-js`, which only loads the needed polyfills by statically analyzing the source like Babel's `useBuiltIns: usage` option does could cause a revolution in the way we think about polyfills. @@ -424,15 +426,15 @@ TC39 is working really hard to improve ECMAScript: you can see the progress by l At this moment, TC39 is considering adding to ECMAScript [built-in modules](https://github.com/tc39/proposal-javascript-standard-library): a modular standard library. It would be a great addition to JavaScript, and `core-js` is the best place where it could be polyfilled. With the techniques used in `@babel/preset-env` and `@babel/runtime`, we could theoretically inject polyfills for required built-in modules in a very simple way. However, the current version of this proposal causes some serious problems which don't make it as straightforward. -Polyfilling of built-in modules, [as stated by authors of the proposal](https://github.com/tc39/proposal-javascript-standard-library/issues/2), only means falling back to layered APIs or import maps. This means that if a native module will be missing, it will be possible to load a polyfill from a provided url. That's absolutely not what polyfills need, and it is incompatible with the architecture of `core-js` and every other popular polyfill projects. Import maps shouldn't be the only way to polyfill built-in modules. +Polyfilling of built-in modules, [as stated by the authors of the proposal](https://github.com/tc39/proposal-javascript-standard-library/issues/2), only means falling back to layered APIs or import maps. This means that if a native module will be missing, it will be possible to load a polyfill from a provided URL. That's absolutely not what polyfills need, and it is incompatible with the architecture of `core-js` and every other popular polyfill project. Import maps shouldn't be the only way to polyfill built-in modules. -We will be able to get a built-in module just by usage ES modules syntax with a special prefix. This syntax haven't any equal based on the previous version of the language - transpiled modules will not be able to interact with not transpiled in modern engines - it will cause problems for package distribution. +We will be able to get a built-in module just by using ES modules syntax with a special prefix. This syntax haven't any equal based on the previous version of the language - transpiled modules will not be able to interact with not transpiled in modern engines - it will cause problems for package distribution. More other, it will work asynchronously. It's a critical problem for feature detection - scripts will not wait when you'll detect a feature and load a polyfill - feature detection should be done synchronously. [The first implementation of built-in modules without a proper way of transpiling / polyfilling already available](https://developers.google.com/web/updates/2019/03/kv-storage). If it will not be revised, built-in modules will not be able to be polyfilled in the current `core-js` format. The proposed way of polyfilling will seriously complicate the lives of developers. -The issue with the standard library can be solved by adding a new global (maybe it will be the last one?): a registry of built-in modules which will allow getting and seting them synchronously, like +The issue with the standard library can be solved by adding a new global (maybe it will be the last one?): a registry of built-in modules which will allow getting and setting them synchronously, like ```js StandardLibraryRegistry.get(moduleName); StandardLibraryRegistry.set(moduleName, value); @@ -446,13 +448,13 @@ As a bonus point, it would simplify transpiling native modules import to old syn [In the new iteration](https://github.com/tc39/proposal-decorators) of this proposal, it has been seriously reworked. Decorator definitions aren't a syntax sugar anymore and, like with built-in modules, we will not be able to write a decorator in an old version of the language and use it as a native decorator. Other than that, decorators are not just usual identifiers - they live in a parallel lexical scope: this means that transpiled decorators can't interact with native decorators. -The proposal authors recommend distributing packages with untranspiled decorators and leave to the library consumers the choice to transpile their dependencies. However, it's not possible in different scenarios. This approach could prevent `core-js` from polyfilling new built-in decorators when they will be added to the JS standard library. +The proposal authors recommend distributing packages with untranspiled decorators and leaving to the library consumers the choice to transpile their dependencies. However, it's not possible in different scenarios. This approach could prevent `core-js` from polyfilling new built-in decorators when they will be added to the JS standard library. Decorators should be just an alternative way of applying functions on something, they should only be syntax sugar for wrappers. Why complicate things? --- -If a new language feature does not introduce to the language something fundamentally new, an alternative for what couldn't be implemented in a previous version of the language, we should be able to transpile and/or polyfill it, and transpiled/polyfilled code should be able to interact with native feature in engines which supports this feature natively. +If a new language feature does not introduce to the language something fundamentally new, an alternative for what couldn't be implemented in a previous version of the language, we should be able to transpile and/or polyfill it, and transpiled/polyfilled code should be able to interact with the native feature in engines which supports this feature natively. I hope for the wisdom of the authors of those proposals and of the committee, that these proposals will be adapted so that it will be possible to properly transpile or polyfill them. @@ -462,6 +464,6 @@ If you are interested in the `core-js` project or use it in your day-to-day work --- -**Feel free to add comments to this article [here](https://github.com/zloirock/core-js/issues/496).** +**Feel free to add comments to this article [here](https://github.com/zloirock/core-js/discussions/963).** **[Denis Pushkarev](https://github.com/zloirock)**, **19-03-2019**, *thanks [Nicolò Ribaudo](https://github.com/nicolo-ribaudo) for redaction* diff --git a/docs/2023-02-14-so-whats-next.md b/docs/2023-02-14-so-whats-next.md new file mode 100644 index 000000000000..b4908d8491aa --- /dev/null +++ b/docs/2023-02-14-so-whats-next.md @@ -0,0 +1,574 @@ +

core-js

+ +Hi. I am (**[@zloirock](https://github.com/zloirock)**), a full-time open-source developer. I don't like to write long posts, but it seems it is high time to do it. Initially, this post was supposed to be a post about the start of active development of the new major version of `core-js` and the roadmap (it was moved to [the second half](#roadmap)), however, due to recent events, it became a really long post about many different things... I'm fucking tired. Free open-source software is fundamentally broken. I could stop working on this silently, but I want to give open-source one last chance. + +--- + +# So, what's next? + +
+🔻 Click to see how you can help 🔻 + +If you or your company use `core-js` in one way or another and are interested in the quality of your supply chain, support the project: +- [**Open Collective**](https://opencollective.com/core-js) +- [**Patreon**](https://patreon.com/zloirock) +- [**Boosty**](https://boosty.to/zloirock) +- **Bitcoin ( bc1qlea7544qtsmj2rayg0lthvza9fau63ux0fstcz )** +- [**Alipay**](https://user-images.githubusercontent.com/2213682/219464783-c17ad329-17ce-4795-82a7-f609493345ed.png) + +**Write me if you want to offer a good job on Web-standards and open-source.** +
+ +## What is [`core-js`](https://github.com/zloirock/core-js)? + +- It is the most popular and the most universal polyfill of the JavaScript standard library, which provides support for the latest ECMAScript standard and proposals, from ancient ES5 features to bleeding edge features like [iterator helpers](https://github.com/tc39/proposal-iterator-helpers), and web platform features closely related to ECMAScript, like `structuredClone`. +- It is the most complex and comprehensive polyfill project. At the time of publishing this post, `core-js` contains about half a thousand polyfill modules with different levels of complexity — from `Object.hasOwn` or `Array.prototype.at` to `URL`, `Promise` or `Symbol` — that are designed to work together. With a different architecture, each of them could be a separate package — however, it is not as convenient. +- It is maximally modular — you can easily (or even automatically) choose to load only the features you will be using. It can be used without polluting the global namespace (someone calls such a use case "ponyfill"). +- It is designed for integration with tools and provides everything that's required for this — for example, `@babel/preset-env`, `@babel/transform-runtime`, and similar SWC features are based on `core-js`. +- It is one of the main reasons why developers could use modern ECMAScript features in their development process every day for many years, but most developers just don't know that they have this possibility because of `core-js` since they use `core-js` indirectly as it's provided by their transpilers / frameworks / intermediate packages like `babel-polyfill` / etc. +- It is not a framework or a library, whose usage requires the developer to know their API, periodically look at the documentation, or at least remember that he or she is using it. Even if developers use `core-js` directly — it's just some lines of import or some lines in the configuration (in most cases — with mistakes, since almost no one read the documentation), after that, they forget about `core-js` and just use features from web-standards provided by `core-js` — but sometimes this is the most of JS standard library that they use. + +[About 9 billion NPM downloads / 250 million NPM downloads for a month](https://npm-stat.com/charts.html?package=core-js&package=core-js-pure&package=core-js-bundle&from=2014-11-18), 19 million dependent GitHub repositories ([global](https://github.com/zloirock/core-js/network/dependents?package_id=UGFja2FnZS00ODk5NjgyNDU%3D) ⋃ [pure](https://github.com/zloirock/core-js/network/dependents?package_id=UGFja2FnZS00MjYyOTI0Ng%3D%3D)) — big numbers, however, they do not show the real spread of `core-js`. Let's check it. + +I wrote [a simple script](https://github.com/zloirock/core-js/blob/master/scripts/usage/usage.mjs) that checks the usage of `core-js` in the wild by the Alexa top websites list. We can detect obvious cases of `core-js` usage and used versions (only modern). + +

usage

+ +At this moment, this script running on the TOP 1000 websites **detects usage of `core-js` on [52%](https://gist.github.com/zloirock/7ad972bba4b21596a4037ea2d87616f6) of tested websites**. Depending on the phase of the moon (the list, websites, etc. are not constants), results may vary by a few percent. However, it's just a naive detection on websites' home pages using a modern browser that loses many cases, **manual check shows that it's additional dozens of percent**. For example, let's leave the home pages of some websites from the screenshot above where `core-js` was **not** found by this script, without repeating for each company (at first — MS that's already on the screenshot) websites (be patient, after the series of screenshots the number of pictures will decrease): + +

whatsapp

+ +--- +

linkedin

+ +--- +

netflix

+ +--- +

qq

+ +--- +

ebay

+ +--- +

apple

+ +--- +

fandom

+ +--- +

pornhub

+ +--- +

paypal

+ +--- +

binance

+ +--- +

spotify

+ +**With such a manual check, you can find `core-js` on about 75-80% of the top 100 websites** while the script found it on about 55-60%. On a larger sample the percentage, of course, decreases. + +[Wappalyzer](https://www.wappalyzer.com/technologies/javascript-libraries/) allows to detect used technologies, including `core-js`, with a browser plugin and has previously shown interesting results, but now on their website, all the most popular technologies' public results are limited to only about 5 million positives. Statistics based on Wappalyzer results are available [here](https://almanac.httparchive.org/en/2022/javascript#library-usage) and show `core-js` on 41% and 44% of 8 million mobile and 5 million desktop tested pages. [Built With at this moment shows `core-js` on 54% of TOP 10000 sites](https://trends.builtwith.com/javascript/core-js) (however, I'm not sure about the completeness of their detection and see the graph from another reality). + +Anyway, we can say with confidence that **`core-js` is used by most of the popular websites**. Even if `core-js` is not used on the main site of any large corporation, it's definitely used in some of their projects. + +What JS libraries are more widespread on websites? It's not [React](https://trends.builtwith.com/javascript/React), [Lodash](https://trends.builtwith.com/javascript/lodash), or any other most talked-about library or framework, I am pretty sure only about ["good old" jQuery](https://trends.builtwith.com/javascript/jQuery). + +And `core-js` is not only about a website's frontend — it's used almost everywhere where JavaScript is used — but I think that's more than enough statistics. + +

github

+ +However, for the above reasons, [**almost no one remembers that he or she uses `core-js`**](https://2022.stateofjs.com/en-US/other-tools). + +Why am I posting this? No, not to show how cool I am, but to show how bad everything is. Read on. + +--- + +## Let's start the next part with one popular `xkcd` picture + +[

xkcd

](https://xkcd.com/2347/) + +### Beginning + +I switched my development stack to full-stack JavaScript in 2012. It was a time when JavaScript still was too raw — IE still was more popular than anything else, ES3 era browsers still occupied a significant part of the web, the latest NodeJS version was 0.7 — it was just starting its way. JavaScript still was not adapted for writing of serious applications and developers solved the lack of required language syntax sugar with compilers from languages like CoffeeScript and the lack of proper standard library with libraries like Underscore. However, it wasn't a standard — over time, these languages and libraries became obsolete together with the projects that used them. So, I took all news of the upcoming ECMAScript ~~Harmony~~ 6 standard with great hope. + +Given the prevalence of old JavaScript engines and the fact that users were in no hurry and often did not have the opportunity to abandon them, even in the case of quick and problem-free adoption of the new ECMAScript standard, the ability to use it only through JavaScript engines was postponed for many and many years. But it was possible to try to get support features from this standard using some tools. Transpilers (this word was not as popular as it is now) should have to solve the problem with the syntax, and polyfills — with the standard library. However, at that time the necessary toolkit was only just beginning to emerge. + +It was a time when ECMAScript transpilers started to become popular and develop actively. However, at the same time, polyfills have barely evolved according to users' and real-life projects' needs. They were not modular. They could not be used without global namespace pollution — so they were not suitable for libraries. They weren't a single complex — it was required to use multiple different polyfill libraries from different authors and somehow make them work together — but in some cases, it was almost impossible. Too many necessary fundamental language features were just missing. + +To fix these problems, at the end of 2012, initially for my own projects, I started to work on a project that was later called `core-js`. I wanted to make the life of all JS developers easier and in November 2014, I published `core-js` as an open-source project. *Maybe it was the biggest mistake in my life.* + +Since I was not the only one who faced these issues, after a few months, `core-js` has already become the de facto standard of polyfill for JavaScript standard library features. `core-js` was integrated into Babel (`6to5` at that moment) which appeared a couple of months before `core-js` was published — some of the aforementioned issues were critical for that project too. `core-js` began to be distributed as `6to5/polyfill`; and after rebranding as `babel-polyfill`. After a few months of collaboration, a tool has appeared, which became `babel-runtime` after rebranding and evolution. A few months later `core-js` was integrated into the key frameworks. + +### Ensuring compatibility for the whole Web + +I didn't promote myself or the project. *This is the second mistake.* `core-js` didn't have a website or social media accounts, only GitHub. I did not show up at conferences to talk about it. I wrote almost no posts about it. I was just making a really useful and wanted part of the modern development stack, and I was happy about that. I gave developers a chance to use the most modern and really necessary JavaScript features without waiting for years until they are implemented in all required engines, without thinking about compatibility and bugs — and they started to use it. The spread of the project had grown exponentially — very soon it was already used on dozens of percent of popular websites. + +However, it was just the start of the required work. Many years of hard work followed. Almost every day I spent some hours on `core-js` and maintenance of related projects (mainly Babel and [`compat-table`](https://kangax.github.io/compat-table/es2016plus/)). + +![github](https://user-images.githubusercontent.com/2213682/218516268-6ec765a5-50df-4d45-971f-3c3fc4aba7a1.png) + +`core-js` is not a several lines library that you can write and forget about it. Unlike the vast majority of libraries, it's bound to the state of the Web. It should react to any change of JavaScript standards or proposals, to any new JS engine release, to any detection of a bug in JS engines, etc. ECMAScript ~~6~~ 2015 was followed by new proposals, new versions of ECMAScript, new non-ECMAScript web standards, new engines and tools, etc. The evolution, the improvement of the project, and the adaptation to the current state of the Web have never stopped — and almost all of this work remains not visible to the average user. + +The scale of required work was constantly growing. + +I tried to find other maintainers or at least constant contributors for `core-js` in different ways for a long time, but all attempts have failed. Almost every JS developer used `core-js` indirectly and knew, for example, `babel-polyfill`, `babel-runtime`, or that their framework polyfilled all required features, but almost no one knew `core-js`. In some posts about polyfilling where `core-js` was mentioned, it was called "a small library". It was not a trendy and widely discussed project, so why help maintain it if it works great anyway? Over time, I lost hope for it, but I felt a responsibility to the community, so I was forced to continue working alone. + +After a few years combining full-time work and FOSS became almost impossible — no one wanted to pay money for the working time devoted to FOSS, non-working hours were not enough, and sometimes `core-js` required complete immersion for weeks. I thought that proper polyfilling is required for the community and money was not my priority. + +I left a high-paying job and did not accept some very good options because in those positions I would not have had the opportunity to devote enough time to work on open-source. I started to work on open-source full-time. No one paid me for it. I hoped sooner or later to find a job where I could fully dedicate myself to open-source and web standards. Periodically, I earned the money required for living and work on FOSS, on short-term contracts. I returned to Russia, where it was possible to have a decent standard of living with relatively little money. *One more mistake — as you will see below, money matters.* + +--- + +Until April 2019, for about one and a half years as a whole and about a half-year full-time without distraction of any other work, I worked on [the `core-js@3` with a fundamental improvement of polyfilling-related Babel tools](https://github.com/zloirock/core-js/blob/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md), the foundation of the toolkit generation that now is used almost everywhere. + +### Accident + +Shit happened 3 weeks after the `core-js@3` release. One April night, at 3 AM, I was driving home. Two deadly drunk 18-years-old girls in dark clothes decided somehow *to crawl* across a poorly lit highway — one of them laid down on the road, another sat down and dragged the first, but not from the road — directly under my wheels. That's what the witnesses said. I had absolutely no chance to see them. One more witness said that before the accident they were just jokingly fighting on the road. Nothing unusual, it's Russia. One of them died and another girl went to the hospital. However, even in this case, according to Russian arbitrage practice, if the driver is not a son of a deputy or someone like that, he would almost always be found guilty — he has to see and anticipate everything, and a pedestrian owes nothing to anyone. I could end up in prison for a long time, IIRC later the prosecutor requested 7 years. + +The only way not to end up in prison was reconciliation with "victims" — a standard practice after such accidents — and a good lawyer. Within a few weeks after the accident, I received financial claims totaling about 80 thousand dollars at the exchange rate at that time from "victims'" relatives. A significant amount of money was also needed for a lawyer. + +Maybe it's not an inconceivable amount of money for a good software engineer, but, as I wrote just above, I worked full time on the `core-js@3` release for a long time. Of course, no one paid me for this work, and I completely exhausted all my financial reserves, so, sure, I didn't have that kind of money and I didn't have a chance to find the money required from available sources. The time I had was running out. + +### Fundraising + +By that time `core-js` already was used almost as widely as it is now. As I wrote above, I looked for contributors for `core-js` for a long time without any success. However, `core-js` is a project that should be actively maintained and it can't stay just frozen. My long-term imprisonment would have caused problems not only for me — but it would have also been the death of `core-js` and a problem for everyone who had been using it — for half of the Web. The notorious [bus factor](https://en.wikipedia.org/wiki/Bus_factor). + +Some months before that, I started raising funds to support the `core-js` development (mainly it was posted in READMEs on GitHub and NPM). The result was... \$57 / month. Fair pay for full-time work on ensuring compatibility for the whole web 😂 + +I decided to do a little experiment — to ask for help from the `core-js` users — those who will suffer if `core-js` will be left without maintenance. I added a message in `core-js` installation: + +![postinstall](https://user-images.githubusercontent.com/2213682/153024428-28b8102c-ce08-461c-af99-d0417dc7d2cd.png) + +I understood that I'd have hardly gotten all the required money from donations, however, every dollar mattered. I added a job search message to get a chance to earn the other part. I was thinking that a few lines in the NPM installation log asking to help, which can be hidden if needed, is an acceptable price for using `core-js`. The original plan was to delete this message in a few weeks, but everything went against the plan. How wrong I was about people... + +### Hate + +Of course, I expected that someone would not like to see a request for help in their console, but the continuous stream of hate that I began to receive went through the roof. It was hundreds of messages, posts, and comments every day. All of it can be reduced to something like: + +

get-rid

+ +This is far from the funniest thing I've seen — if I wanted to, I could collect a huge selection of statements in the style [collected here](https://github.com/samdark/opensource-hate) — but why? I already have enough negativity in my life. + +**Developers love to use free open-source software — it's free and works great, they are not interested in the fact that many and many thousands of hours of development, and real people with their own problems and needs are behind it. They consider any mention of this as an invasion of their personal space or even a personal affront. For them, these are just gears that should automatically change without any noise and their participation.** + +So, thousands of developers attacked me with insults and claimed that I have no right to ask them for any kind of help. My request for help offended them so much that they began to demand restricting my access to the repository and packages and move them to someone else like it was done with [`left-pad`](https://arstechnica.com/information-technology/2016/03/rage-quit-coder-unpublished-17-lines-of-javascript-and-broke-the-internet/). Almost none of them understood what `core-js` does, the scale of the project, and, of course, nobody wanted to maintain it — it should be done by "the community", someone else. Seeing all this hatred, in order to not be led by the haters, I did not delete the help-asking message, which was initially planned to be there only for a couple of weeks, just out of principle. + +**What about companies which `core-js` helped and is helping to make big money? It's almost every big company. Let's rephrase [this old tweet](https://twitter.com/AdamRackis/status/931195056479965185):** + +> Company: "We'd like to use SQL Server Enterprise" +> +> MS: "That'll be a quarter million dollars + $20K/month" +> +> Company: "Ok!" +> +> ... +> +> Company: "We'd like to use core-js" +> +> core-js: "Ok! npm i core-js" +> +> Company: "Cool" +> +> core-js: "Would you like to help contribute financially?" +> +> Company: "lol no" + +A few months later, tired of user complaints, NPM presented [`npm fund`](https://docs.npmjs.com/cli/v6/commands/npm-fund) — it was not a solution for the problem, it was just a way to get rid of those complaints. How often did you call `npm fund`? How often did you donate to someone who you saw in `npm fund`? Who did you see and support at first — `core-js` or someone who maintains a dozen of one-line libraries dependent on each other? It also provided NPM with a perfect justification for the future step (read below). + +Within 9 months many thousands of developers, including developers of projects fundamentally dependent on `core-js`, knew about the situation — but no one offered to maintain `core-js`. Within many months I talked with maintainers of some significant projects dependent on `core-js`, but without any success — they didn't have the necessary time resources. So I was forced to ask some of my friends who were not related to FOSS community (at first **[@slowcheetah](https://github.com/slowcheetah)**, thanks him for his help) to cover for me and at least try to fix significant issues until I get free. + +--- + +Few users and small companies supported the `core-js` — and I am very grateful to them. However, the amount of money raised in 9 months was only about 1/4 of the money that should have been collected within a couple of weeks to change something. + +During the same time, despite everything, the number of `core-js` downloads per day almost doubled. + +In January 2020 I ended up in prison. + +### Release + +I don't wanna say many words about prison and I have no great desire remembering this. It was slave labor at a chemical factory where my health was significantly ruined and where I 24/7 had a great time in a company of drug dealers, thieves, and killers (from other regimes), without access to the Internet and computers. + +After about 10 months, I was released early. + +--- + +I saw dozens of articles, hundreds of posts, and thousands of comments the essence of many of which can be expressed by this: + +

reddit

+ +What do you think I did? *Of course, I made the same mistake.* I saw some people who supported the development of `core-js`, many issues, questions, and messages — sure, not as many as angry comments. `core-js` became even more popular and was already used by almost the same percentage of websites as it is now. + +### Ensuring compatibility for the whole Web again + +I returned to `core-js` maintenance like it was before. Moreover, I completely stopped being distracted by contracts and any other work in favor of working on `core-js`. `core-js` had some money on funding platforms — not so much, many times less than I received before starting work on `core-js` full-time — but for me alone it was enough to live on. A kind of down-shifting, full-time Open-Source to make the world better... I didn't think about the tens of thousands of dollars in lawsuits left over from the accident. I didn't think about my future. I thought about a better future for the Web. And, of course, I was hoping that some company would offer me a position with the opportunity to work on web standards and would sponsor my work on polyfills and FOSS. + +[A lot has been accomplished](https://github.com/zloirock/core-js/compare/0943d43e98aca9ea7b23cdd23ab8b7f3901d04f1...master) over the next two years — in terms of work, almost as much as in the previous 8 years. This is still `core-js@3` — but much better. However, the changelog and even the previous diff reflect only a small percentage of the work done. Almost all of this work remains in the shadows, not visible to the average user. + +It is the fundamental work with standards and proposals. As a side effect of this work, taking into account the hard work that was done and changes after my feedback and suggestions, I consider many of the ECMAScript proposals — that have become part of the language — are my achievements as much as they are achievements of their champions. It is the work with engines and their bug trackers in searching for bugs. It is the constant automatic and (too often) manual testing in many hundreds of environments, many thousands of environments / builds / test suites combinations to ensure proper operation of the standard library everywhere and to collect compat data. From a raw prototype, made in a couple of days, `core-js` compat data became an exhaustive data set with proper external and internal tooling. It is the design and prototyping of many features that are yet to appear in the project. And also much, much more. + +--- + +As you can see above, `core-js` is present in most of the popular websites, provides an almost complete JavaScript standard library, and fixes improper implementations. The number of web page openings with `core-js` is greater than the number of web page openings in Safari and Firefox. Thus, from a certain point of view, `core-js` can be called one of the most popular JavaScript runtimes. + +When working on `core-js`, I am the first implementer of almost all modern and future JavaScript standard library features, almost all of them have my feedback and they have been fixed according to it. `core-js` is the best playground for experimentation with ECMAScript proposals. In too many cases, proposals receive feedback from other users after they play with experimental `core-js` implementations of these proposals. + +The best way forward for JavaScript would be for TC39 and `core-js` to work together on the future of JavaScript. For example, TC39 invites members of projects like Babel and others as experts. Except `core-js`. Instead, too often, I see the ignoring of my or `core-js`'s issues or even creation of roadblocks by TC39 members; and they don't even hide it: + +

shu

+ +--- + +

lj

+ +--- + +After a while, "support" came from NPM. In `npm@7`, which was released at the end of 2020, as a logical continuation of `npm fund`, the console output was disabled in post-install scripts. The result was expectable, because people stopped seeing the funding request and almost no one uses `npm fund`, the number of `core-js` backers began to decline. An excellent support for the project from those, who not only earn by distributing my work, but also use it themselves :-) + +

npm

+ +In addition, another factor came into play again. Higher quality — less support. Is the library well-maintained? There are practically almost no open bug reports, and when they happen, they are fixed almost instantly? Does the library already give us almost everything we want? Yes? So why should we support the maintenance of the library? The price at which this is done for the maintainers is not on the surface — for most developers and companies, it's still just "a small library". Many of those, who backed `core-js` before, stopped doing it. + +The `core-js` code contains my copyright. As you can see at the top of this post, it's present in about half of all websites. Regularly someone finds it in the source code of harmful sites / applications — but they don't know what `core-js` is and their tech level is not good enough even to find it out. When this happens, the police will call and threaten me, and someone even tried to blackmail me. Sometimes it's not funny at all. + +I have been contacted several times by American and Canadian journalists who discovered `core-js` on American news and government websites. They were very disappointed that I was not an evil Russian hacker who meddles in American elections. + +The endless stream of hatred decreased slightly over time but continues. However, most of it moved from something like GitHub issues or Twitter threads to my mail or IM. Today, one developer wrote me a message. He called me a parasite on the body of the developer community that makes a lot of money spamming and doing nothing useful. He called me the same murderer as [Hans Reiser](https://en.wikipedia.org/wiki/Hans_Reiser), but who bought the judge and escaped unpunished. He wished death for me and all my relatives. And there is nothing unusual here, I get several of such messages a month. Last year, one more thing was added that I am a "Russian fascist". + +### Some words about the war + +**Open-source should be out of politics.** + +I don't want to choose between two kinds of evil. I will not comment on this in more detail, since there are people close to me on both sides of the border who may suffer because of this. + +Let me remind you what I wrote about above: I returned to Russia because it was a place where it was possible to have a decent standard of living for relatively little money and to concentrate on FOSS instead of making money. Now I cannot leave Russia, because after the accident I have outstanding lawsuits in the amount of tens of thousands of dollars and I am forbidden to leave the country until they are paid off. + +### What do you think, how much money does `core-js` receive each month? + +When I started to maintain `core-js` full-time, without being distracted by contracts and any other work, **it was about \$2500 per month — it was about 4-5 times less than I usually had on full-time contracts**. Remember, a kind of down-shifting, to make the Web better. Temporarily. Reduce issues and bugs to zero, make the highest quality product, which is used by almost everyone... and the project will be sufficiently supported, right? Right? + +After a few months, the reoccurring monthly income **decreased to about \$1700** *(at least that's what I thought)*, \$1000 via Tidelift, \$600 via Open Collective, and \$100 via Patreon. In addition to the reoccurring monthly, one-time donations came periodically (on average it was maybe \$100 per month). + +Crypto? Adding a crypto wallet for donations was a very popular request. However, for all the time, only 2 transfers for a total amount of about \$200 have been received on crypto wallets, the last one was more than a year ago. GitHub sponsors? It's not available in Russia and never was. PayPal? It's banned for Russians. When it was available, `core-js` received about \$60 in all that time. Grants? I applied for a lot of grants — all applications were ignored. + +**The main part, \$400 per month, of those donations, `core-js` received from... [Bower](https://bower.io/), another FOSS community. I am also very grateful [to all other sponsors](https://opencollective.com/core-js#section-contributors): because of your donations, I'm still working on this project.** + +However, in this list there is not a single big corporation or at least a company from the top 1000 website list. Let's be honest, there are mainly individuals, and only a few small companies on the current list of backers and they pay a few dollars a month. + +If someone says that they don't know that `core-js` requires funding... Come on, I regularly see memes like [this](https://www.reddit.com/r/ProgrammerHumor/comments/fbfb2o/thank_you_for_using_corejs/): + +

sanders

+ +--- + +A year ago, Tidelift stopped sending me money. They said that because of the political situation, the Hyperwallet, that they used, is no longer available to Russians (but it was available to me till last month when I tried to update some personal data), and for safety, they will store my money on their side. Over the previous couple of months, I tried to get this money to a bank or a Hyperwallet account, but only received replies that they will try to do something (*sounds great, doesn't it?*). Since the end of the last year, they have just stopped responding to emails. And now, I've got this: + +![tidelift](https://user-images.githubusercontent.com/2213682/217650273-548d123d-4ee4-4beb-ad5b-631c55e612a6.png) + +**In such an amusing way, I found out that I will not receive the money for the previous year, and this year I worked not for \$1800, but for \$800 a month.** There were, of course, no replies to subsequent emails. However, their site indicated that I received and still receive money through them. + +

tidelift

+ +I wonder how the companies that support their dependencies chain through them will react to such a scam. + +--- + +On the same day, on OpenCollective I saw that the reoccurring monthly was reduced from about \$600 to about \$300. Apparently, the financial reserves of `Bower` have come to an end. This means that **for this month I'll get about \$400 total**. + +In the previous months, I measured how much time it takes to work on `core-js`. It turned out about... **250 hours a month** — significantly more than a full day without any days off, which makes it impossible to have a "real" (as many say) full-time work or work for any significant contracts. \$400 for 250 hours... It will be less than **\$2 per hour of work, for the year before a little more: \$4 per hour**. Yes, in some months, I did spend less time working on the project, but it does not change much. + +This is the current price for ensuring compatibility for the whole Web. And no insurance or social security. + +**Awesome earning growth and career, right?** + +I think you understand well how much senior software engineers in key IT companies get paid. I received a lot of comparable offers, however, they are not compatible with the proper work on `core-js`. + +--- + +Among the regular threats, accusations, demands, and insults, I often get something like "Stop begging and go to work, idler. Remove your beggarly messages immediately — I don't wanna see them." The funny thing is that at least some of these people get over $300,000 a year (which I know for sure because I talk to their colleagues), and (because of the nature of their work) `core-js` saves them many hours of work each month. + +### Everything changes + +When I started working on `core-js`, I was alone. Now I have a family. A little over a year ago, I became a father of my son. Now I have to provide him with a decent standard of living. + +![son](https://user-images.githubusercontent.com/2213682/208297825-7f98a8e2-088e-47d3-95a6-a853077296b3.png) + +I have a wife, and sometimes she wants some new shoes or a bag, a new iPhone or an Apple Watch. My parents are already at the age that I need to significantly support them. + +I think it is obvious that it is impossible to properly support a family with the money that I have or had from `core-js` maintenance. Financial reserves that I used, have finally come to the end. + +More and more often I hear reproaches like: "Give up your Open-Source, this is pampering. Go back to a normal job. `%USERNAME%` has been working as a programmer for just a year. He understands almost nothing about it, works a couple of hours a day, and already earns many times more than you do." + +# NO MORE + +I'm damn tired. I love working on open-source and `core-js`. But who or what am I doing this for? Let's summarize the above. + +- I have been ensuring zero compatibility issues and providing bleeding edge features of the web platform for most of the Web since 2014; and I've been working on it for most of the time for money, that now will not even be enough for food. +- Rather than any gratitude, all I see is the huge hatred from developers whose life I simplify. +- Companies that save and earn many millions of dollars on `core-js` usage just ignore `core-js` funding requests. +- Even in a critical situation, in response to a request for help, instead of help, most of them preferred to ignore or hate. +- Instead of working together with standards' and browsers' developers on a better future for JavaScript, I'm forced to struggle with roadblocks that they make. + +--- + +I don't care about the haters. Otherwise, I would have left open-source a long time ago. + +I can tolerate the lack of normal interaction with the standards developers. First of all, this means future problems for users and, when the Web will be broken, for standards developers themselves. + +**However, money matters.** I've had enough of sponsoring corporations at the expense of my and my family's well-being. I should be able to ensure a bright future for my family, for my son. + +The work on `core-js` occupies almost all of my time, more than a full working day. This work ensures the proper functioning of the most of the popular websites and this work should be paid properly. I'm not going to keep working for free or for \$2 per hour. I'm willing to continue working on a project for at least \$80 an hour. This is the rate that have, for example, [`eslint` team members per hour](https://eslint.org/blog/2022/02/paying-contributors-sponsoring-projects/#paying-team-members-per-hour). And, if the work on open-source requires it, I'm ready to pay off my lawsuits and leave Russia — however, it's not cheap. + +--- + +Regularly I see comments like this: + +

core-js approach

+ +Ok guys, if you want it — let's use such an approach. + +--- + +## Depending on your feedback, `core-js` will soon follow one of the following ways: + +- **Appropriate financial backing** + + I hope that, at least after reading this post, corporations, small companies, and developers will finally think about the sustainability of their development stack and will properly back `core-js` development. In this case, `core-js` will be appropriately maintained and I'll be able to focus on adding [a new level of functionality](#roadmap). + + The scale of the necessary work goes through the roof, a single me is no longer enough — I can't work more physically. Some work, for example, improving test coverage or documentation, is simple enough and takes a lot of time, but it's not the kind of work that volunteers want to do — I don't remember any PRs with improvements for test coverage of existent features. So it makes sense to attract at least one or two developers (at least students, better — higher level) on a paid basis. + + Taking into account the involvement of additional maintainers and other expenses, I think that at this moment about 30 thousand dollars a month could be enough. More money — better product and faster development. A couple times less — it makes sense to resume the work on `core-js` full-time alone — sure, not as productive as it could be with a team. + +- **I may be hired by a company where I will be able to work on Open-Source and Web standards** + + and that will give me the resources required for continuation of the work. + +- **`core-js` will become a commercial project** if it will not receive an appropriate support from users + + It's problematic to create a commercial infrastructure around the current `core-js` packages, so most likely the new `core-js` major release will change the license. The free version will be significantly limited. All extra functionality will be paid for. `core-js` will continue to evolve appropriately and, in the scope of this project, many new tools will be created to ensure web compatibility. Sure, it will significantly reduce the spread of `core-js` and will cause problems for many developers, however, even some paying customers could be enough and my family will have money to pay the bills. + +- A **slow death** in case I'll see that `core-js` is not required + + I have many ideas for commercial projects, I have a lot of good job offers — all this takes time, which now goes into `core-js` maintenance. It does not mean that I'll immediately completely stop maintaining `core-js`, I'll just maintain pro-rata donations. If they are at the current level, it will be only a few hours of maintenance a month instead of hundreds like now. The project will stop the upgrowth — maybe minor bugs will be fixed and compatibility data will be updated — this time is not enough for more. After a while, `core-js` will become just useless and will die. + +I still hope for the first outcome since `core-js` is one of the key components of the modern digital infrastructure, but, looking at the present and the past, I am mentally getting ready for other options. + +## I will answer some angry comments in advance that I see regularly and that will definitely come up after this post: + +- **"Not a problem, we will just pin the `core-js` dependency."** + + Unlike most projects, `core-js` should be on the bleeding edge since `core-js` allows you to be on the bleeding edge of JavaScript: use the most recent JavaScript features and don't think about engines compatibility and bugs. However, the library has a good safety margin for the future. Maybe for a year or a couple, you will not have serious problems. After that, they will appear — polyfills will become obsolete, but still will be present in your bundles and will become just a useless ballast. You will not be able to use new features of the language and will face new bugs in JS engines. + +- **"It's open-source, we will fork it, fuck off."** + + I see such comments regularly, someone even tries to scare me with a fork. I've said already too many times that **if someone will fork and properly maintain `core-js`, I'd be happy** — it makes no sense just to fork it without maintenance. Now I don't see anyone at all who tries to add something significant to `core-js` or at least contribute regularly. The project ought to follow up on each new JavaScript engine release to update compatibility data, fix or at least take into account each new (no matter how significant) bug from each engine, take a look and implement each new JavaScript feature possible, do it maximally properly, test and take into account the specifics of each version of each modern or legacy engine. It's a hard work, are you ready and have the required knowledge and time for that? For example, when I was in prison, Babel said that they are not: + +

babel

+ +- **"We don't need `core-js`, many alternative projects are available."** + + Nobody is holding you. But where are those alternatives in real life? Sure, `core-js` is not the only polyfill of the JavaScript standard library. But all other projects are [tens](https://npm-stat.com/charts.html?package=core-js&package=core-js-pure&package=es6-shim&from=2014-11-18) of [times](https://user-images.githubusercontent.com/2213682/205467964-2dfcce78-5cdf-4f4f-b0d6-e37c02e1bf01.png) less popular than `core-js`, and it's not unreasonable — all of them provide only a small part of `core-js` functionality, they are not proper and complex enough, the number of cases where they can be used is significantly limited, they can't be properly integrated into your project in such a simple way and have other significant problems. In the case if proper alternatives existed, I would have stopped working on `core-js` a long time ago. + +- **"We can drop IE support, so we no longer need polyfills."** + + As I wrote a just above, nobody is holding you. In some cases, polyfills are really not required and you can avoid them, but it's only a small part of all cases — almost the same as it was in the IE era. Of course, if you don't need IE support, polyfills will not expand your possibilities as much as it was with adding ES6 support to IE8. But even the most modern engines do not implement the most modern JavaScript features. Even the most modern engines contain bugs. Are you pretty sure that you and your team perfectly know all limitations of all engines that you support and can work around them? Even I sometimes may forget some quirks and missing features. + +- **"You are an asshole, we will expel you from the FOSS community."** + + Yes, you're right. I'm such an asshole that gives you a chance to use modern JavaScript features in the real life, have been solving your cross-engine compatibility issues for many years, and had sacrificed for this more than anyone else. I'm such an asshole that just wants his son to be well-fed, wants his family to have enough money to pay the bills, so they don't need anything. Some options above suppose my departure from FOSS in favor of commercial software, so we'll see. + +--- + +Now let's move away from the negative to the second half of this post where we will talk about things that would be nice to implement in `core-js` and the problems of polyfilling in general. + +## Roadmap + +JavaScript, browsers, and web development are evolving at an amazing speed. The time when almost all of the `core-js` modules were required for all browsers is gone. The latest browsers have good standards support and, in the common use cases, they need only some percentage of the `core-js` modules for the most recent language features and bug fixes. Some companies are already dropping support for IE11 which was recently "buried" once more. However, even without IE, old browsers will always be there, bugs will happen in modern browsers too, and new language features will appear regularly and they will appear in browsers with a delay anyway; so, if we want to use modern JS in development and minimize possible problems, polyfills stay with us for a long time, but they should continue to evolve. + +Here I will write (almost) nothing about adding new or improving existing specific polyfills (but, sure, it's one of the main parts of `core-js` development), let's talk about some other crucial moments without focusing on minor things. If it is decided to make a commercial project from `core-js`, the roadmap will be adapted to this outcome. + +I am trying to keep `core-js` as compact as possible, but one of the main conceptions that it should follow is to be maximally useful in the modern web — the client should not load any unnecessary polyfills and polyfills should be maximally compact and optimized. Currently, a maximal `core-js` bundle size with early-stage proposals [is about 220KB minified, 70KB gzipped](https://bundlephobia.com/package/core-js) — it's not a tiny package, it's big enough — it's like jQuery, LoDash, and Axios together — the reason is that the package covers almost the entire standard library of the language. The individual weight of each component is several times less than the weight of quite correct alternatives. It's possible to load only the `core-js` features that you use and in minimal cases, the bundle size can be reduced to some kilobytes. When `core-js` is used correctly, this is usually a couple of tens of kilobytes — however, there is something to strive for. [Most pages contain pictures larger](https://almanac.httparchive.org/en/2022/media#bytesizes) than the entire `core-js` bundle, most users have Internet speed in dozens of Mbps, so why is this concept so significant? + +I don't want to repeat old posts about [the cost of JavaScript](https://medium.com/dev-channel/the-cost-of-javascript-84009f51e99e) in detail where you can read why adding JS increases the time when the user can start interacting with the page much more than adding a similar size picture — it's not only downloading, it's also parsing, compiling, evaluating the script, it blocks the page rendering. + +In too many places the mobile Internet is not perfect and is still 3G or even 2G. In the case of 3G, the download of one full copy of `core-js` can take a couple of seconds. However, pages contain more than one copy of `core-js` and many other duplicated polyfills too often. Some (mainly mobile) Internet providers have very limited "unlimited" data plans and after a few gigabytes reduce the speed to a few Kbps. The connection speed is often limited for many other reasons too. + +The speed of the page load equals revenue. + +

conversion

+ +> Illustration is from a [random post](https://medium.com/@vikigreen/impact-of-slow-page-load-time-on-website-performance-40d5c9ce568a) by googling + +The size of `core-js` is constantly growing because of the addition of new or improvements to the existing polyfills. This issue also is a blocker for some big polyfills — the addition of `Intl`, `Temporal`, and some other features to `core-js` could increase the maximal bundle size by a dozen times up to a few megabytes. + +One of the main `core-js` killer features is that it can be optimized with the usage of Babel, SWC, or manually, however, current approaches solve only a part of the problem. To properly solve them, the modern web requires a new generation of the toolkit that could be simply integrated into the current development stack. And in some cases, as you will see below, this toolkit could help to make the size of your web pages even less than just without `core-js`. + +I already wrote about some of this in [**`core-js@3`, Babel and a look into the future** post](https://github.com/zloirock/core-js/blob/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md#look-into-the-future), but those were just raw ideas. Now they're in the stage of experimentation or even implementation. + +Since the future of the project is uncertain, it makes no sense to write any specific dates here, I do not promise that all of this will be done shortly, but this is what should be strived for. + +--- + +### New major version + +`core-js@3` was released about 4 years ago — it's been a long time. It's not a big problem for me to add some breaking changes (rather ensuring backward compatibility is often a challenge) and to mark a new version as a major release — it's a big problem for the users. + +At this moment, about 25% of `core-js` downloads are critically obsolete `core-js@2`. Many users wanna update it to `core-js@3`, but because their dependencies use `core-js@2` they still use the obsolete version to avoid multiple copies (I saw such issues on GitHub in too many projects). Too frequent major updates would worsen such cases even more. + +However, it's better not to get too obsessed with compatibility with older versions. The library contains too much that's not removed only for compatibility reasons. The absence of some long-needed breaking changes for someone will negatively affect the future. Judging by how the standards, the ecosystem, and the Web change, and how legacy accumulates, it's better to release a new major version each 2-3 years. + +The addition of all the new things that we would like to see in the new major version would take many years, which is unacceptable. However, `core-js` follows [SemVer](https://semver.org/) and it makes sense to release a new major release at first with breaking changes (some of them below), most of the new features can be added in minor releases. In this case, such a release can take just about 2-3 months of full-time work and it can be the first `core-js` version that reduced the size compared to the previous -) + +### `core-js` package directly + +### Drop critically obsolete engines support + +IE is dead. However, not for all — for many different reasons, someone is still forced to make or maintain websites that should work in IE. `core-js` is one of the main tools that makes life easier for them. + +At this moment, `core-js` tries to support all possible engines and platforms, even ES3 — IE8-. But only a small part of developers using `core-js` needs support of ES3 engines — at this moment, the IE8- segment of browsers is about 0.1%. For many other users, it causes problems — bigger bundle size and slower runtime execution. + +The main problem comes from supporting ES3 engines: most modern ES features are based on ES5 features, which aren't available in those old engines. Some features (like getters / setters) can't be polyfilled, so some polyfills (like typed arrays) can't work in IE8- at all. Some others require heavy workarounds. In cases where you need to polyfill only some simple features, the main part of the `core-js` size in the bundle is the implementation of ES5 methods (in the case of polyfilling a lot of features, it's only some percent, so this problem is related mainly to minimalistic bundles). + +Even the simple replacement of internal fallbacks of ES5 features to implementations to direct usage of those native features reduces minimalistic `core-js` bundle size by 2+ times. After reworking the architecture, it will be reduced even more. + +The IE9-10 segment of browsers already is also small — at this moment, the same 0.1%. But it makes no sense to consider dropping their support without dropping support of some other obsolete engines with similar or even greater restrictions, for example, Android 4.4.4 — in total, it's about 1%. Raising the lower bar higher than ES5 is a more difficult decision at least because of some non-browser engines. However, even dropping IE11 support in the future will not give as many benefits as dropping IE8- support would now. + +### ECMAScript modules and modern syntax + +At this moment, `core-js` uses CommonJS modules. For a long time, it was the most popular JavaScript modules format, but now ECMAScript provides its own modules format and it's already very popular and supported *almost* everywhere. For example, Deno, like browsers, doesn't support CommonJS, but supports ES modules. `core-js` should get an ECMAScript modules version in the near future. But, for example, on NodeJS, ECMAScript modules are supported only in the modern versions — but on NodeJS `core-js` should work without transpiling / bundling even in ancient versions, [Electron still does not support it](https://github.com/electron/electron/issues/21457), etc., so it's problematic to get rid of the CommonJS version immediately. + +The situation with the rest of modern syntax is not so obvious. At this moment, `core-js` uses ES3 syntax. Initially, it was for maximal optimization since it should be pre-transpiled to old syntax anyway. But it was true only initially. Now, `core-js` just can't be properly transpiled in userland and should be ignored in transpiler configs. Why? Let's take a look, for example, at Babel transforms: + +- A big part of transforms rely on modern built-ins, for example, transforms which use `@@iterator` protocol — yet `Symbol.iterator`, iterators, and all other related built-ins are implemented in `core-js` and absent before `core-js` loading. +- Another problem is transpiling `core-js` with transforms that inject `core-js` polyfills. Obviously, we can't inject polyfills into the place where they are implemented since it is circular dependencies. +- Some other transforms applied on `core-js` just break its internals — for example, [the `typeof` transform](https://babeljs.io/docs/en/babel-plugin-transform-typeof-symbol) (that should help with support of polyfilled symbols) breaks the `Symbol` polyfill. + +However, the usage of modern syntax in polyfills code could significantly improve the readability of the source code, reduce the size and in some cases improve performance if polyfill is bundled for a modern engine, so it's time to think about rewriting `core-js` to modern syntax, making it transpilable by getting around those problems and publishing versions with different syntax for different use cases. + +### Web standards polyfills + +I've been thinking about adding the most possible web standards (not only ECMAScript and closely related features) support to `core-js` for a long time. First of all, about the remaining features from the [Minimum Common Web Platform API](https://common-min-api.proposal.wintercg.org/#index) ([what is it?](https://blog.cloudflare.com/introducing-the-wintercg/)), but not only about them. It could be good to have one bulletproof polyfills project for all possible web development cases, not only for ECMAScript. At the moment, the situation with the support of web standards in browsers is much worse than with the support of modern ECMAScript features. + +One of the barriers preventing the addition of web standards polyfills to `core-js` was a significant increase of bundles' size, but I think that with current techniques of loading only the required polyfills and techniques which you can see below, we could add polyfills of web standards to `core-js`. + +But the main problem is that it should not be naive polyfills. As I wrote above, today the correctness of ECMAScript features is not in a very bad shape almost universally, but we can't say this about web platform features. For example, [a `structuredClone` polyfill](https://github.com/zloirock/core-js#structuredclone) was relatively recently added. When working on it, taking into account the dependencies, I faced **hundreds** of different JavaScript engines bugs — I don't remember when I saw something like that when I added new ECMAScript features — for this reason, the work on this simple method, that naively could be implemented within a couple hours, including resolving all issues and adding required features, lasted for several months. In the case of polyfills, better to do nothing than to do bad. The proper testing, polyfilling, and ensuring cross-platform compatibility web platform features require even more significant resources than what I spend on ECMAScript polyfills. So adding the maximum possible web standards support to `core-js` will be started only in case if I have such resources. + +--- + +### New approaches to tooling are more interesting + +Someone will ask why it's here. What do tools, like transpilers, have to do with the `core-js` project? `core-js` is just a polyfill, and those tools are written and maintained by other people. Once I also thought that it is enough to write a great project with a good API, explain its possibilities, and when it becomes popular, it will acquire an ecosystem with proper third-party tools. However, over the years, I realized that this will not happen if you do not do, or at least not control, it yourself. + +For example, for many years, instance methods were not able to be polyfilled through Babel `runtime`, but I explained how to do it too many times. Polyfilling via `preset-env` could not be used in real-life projects because of incomplete detection of required polyfills and a bad source of compatibility data, which I explained from the beginning. Because of such problems, I was forced [to almost completely rewrite those tools in 2018-2019, for the `core-js@3` release](https://github.com/babel/babel/pull/7646), after that we got the current state of statically analysis-based tools for polyfills injecting. + +I am sure that if the approaches below are not implemented in the scope of `core-js`, they will not be properly implemented at all. + +--- + +To avoid some questions related to the following text: `core-js` tools will be moved to scoped packages — tools like `core-js-builder` and `core-js-compat` will become `@core-js/builder` and `@core-js/compat` respectively. + +### Not only Babel: plugins for transpilers and module bundlers + +At this moment, some users are forced to use Babel only due to the need to automatically inject / optimize required polyfills. At this moment, Babel's [`preset-env`](https://babeljs.io/docs/en/babel-preset-env#usebuiltins) and [`runtime`](https://babeljs.io/docs/en/babel-plugin-transform-runtime#core-js-aliasing) are the only good enough and well-known ways to optimize usage of `core-js` with statical analysis. Historically, it happened because I helped Babel with polyfills. It does not mean that it's the only or the best place where it could be done. + +Babel is only one of many transpilers. TypeScript is another popular option. Other transpilers are gaining popularity now, for example, [SWC](https://swc.rs/) (that already contains [a tool for automatic polyfilling / `core-js` optimization](https://swc.rs/docs/configuration/supported-browsers), but it's still not perfect). However, why do we talk about the transpilers layer? The bundlers layer and tools like `webpack` or [`esbuild`](https://esbuild.github.io/) (that also contains an integrated transpiler) are more interesting for the optimization of polyfills. [Rome](https://rome.tools/) has been in development for several years and still is not ready, but its concept looks very promising. + +One of the main problems with statical analysis-based automatic polyfilling on the transpiler layer is that usually not all files from the bundle are transpiled — for example, dependencies. If some of your dependencies need a polyfill of a modern built-in feature, but you don't use this built-in in your userland code, this polyfill will not be added to the bundle. Unnecessary polyfills import also will not be removed from your dependencies (see below). Moving automatic polyfilling to the bundlers layer fixes this problem. + +Sure, writing or using such plugins in many places is difficult compared to Babel. For example, [now without some extra tools you can't use plugins for custom transforms in TypeScript](https://github.com/microsoft/TypeScript/issues/14419). However, where there's a will there's a way. + +Automatic polyfilling / optimization of `core-js` should be available not only in Babel. It's almost impossible to write and maintain plugins for all transpilers and bundlers in the scope of the `core-js` project, but it's possible to do those things: + +- Improve data provided by `core-js` (`@core-js/compat`) and tools for integration with third-party projects, they should be comprehensive. For example, "built-in definitions" are still on Babel's side that causing problems with their reuse in other projects. +- Since some tools already provide `core-js` integration, it makes sense to help them too, not just Babel. +- It makes sense to write and maintain plugins for some significant tools in the scope of the `core-js` project. Which? We will see. + +### Polyfills collector + +One of the problems of the statical analysis-based automatic polyfilling on the files layer (`usage` polyfilling mode of Babel `preset-env`) was explained above, but it's not the only problem. Let's talk about some others. + +Your dependencies could have their own `core-js` dependencies and they can be incompatible with the `core-js` version that you use at the root of your project, so injecting `core-js` imports to your dependencies directly could cause breakage. + +Projects often contain multiple entry points, multiple bundles, and, in some cases, the proper moving of all `core-js` modules to one chunk can be problematic and it could cause duplication of `core-js` in each bundle. + +I already posted [the `core-js` usage statistics](https://gist.github.com/zloirock/7331cec2a1ba74feae09e64584ec5d0e) above. In many cases, you could see the duplication of `core-js` — and it's only on the first loaded page of the application. Sometimes it's even like what we see on the Bloomberg website: + +

bloomberg

+ +[Some time ago this number was even higher.](https://user-images.githubusercontent.com/2213682/115339234-87e1f700-a1ce-11eb-853c-8b93b7fc5657.png) Of course, such a number of copies and various versions of `core-js` is not something typical, but a situation with several copies of `core-js` is too common as you saw above, affecting about half the websites with `core-js`. To prevent this **a new solution is required to collect all polyfills from all entry points, bundles and dependencies of the project in one place.** + +Let's call a tool for this `@core-js/collector`. This tool should take an entry point or a list of entry points and should use the same statical analysis that's used in `preset-env`, however, this tool should not transform code or inject anything, should check full dependencies trees and should return a full list of required `core-js` modules. As a requirement, it should be simple to integrate into the current development stack. One possible way can be a new polyfilling mode in plugins, let's call it `collected` — that will allow loading all collected polyfills of the application in one place and remove the unnecessary (see below). + +### Removing unnecessary third-party polyfills + +Now it's typical to see, for example, a dozen copies of `Promise` polyfills with the same functionality on a website — you load only one `Promise` polyfill from `core-js`, but some of your dependencies load `Promise` polyfills by themself — `Promise` polyfill from one more `core-js` copy, `es6-promise`, `promise-polyfill`, `es6-promise-polyfill`, `native-promise-only`, etc. But it's just ES6 `Promise` which is already completely covered by `core-js` — and available in most browsers without polyfills. Sometimes, due to this, the size of all polyfills in the bundle swells to several megabytes. + +It's not an ideal illustration for this issue, many other examples would have been better, but since above we started to talk about the Bloomberg website, let's take a look at this site one more time. We have no access to the source code, however, we have, for example, such an awesome tool as [`bundlescanner.com`](https://bundlescanner.com/website/bloomberg.com%2Feurope/all) (I hope that the Bloomberg team will fix it ASAP, so the result could be outdated). + +

bundlescanner

+ +As shown in the practice, since such analysis it's not a simple work, this tool detects only about half of libraries' code. However, in addition to 450 kilobytes of `core-js`, we see hundreds of kilobytes of other polyfills — many copies of `es6-promise`, `promise-polyfill`, `whatwg-fetch` ([for the above reason](#web-standards-polyfills), `core-js` *still* does not polyfill it), `string.prototype.codepointat`, `object-assign` (it's a *ponyfill* and the next section is about them), `array-find-index`, etc. + +But how many polyfills were not detected? What's the size of all polyfills that this website loads? It seems a couple of megabytes. However, even for *very* old browsers, at most a hundred kilobytes are more than be enough... And this situation is not something unique — it's a too common problem. + +Since many of those polyfills contain just a subset of `core-js` functionality, in the scope of `@core-js/compat`, we could collect data that will show if a module is an unnecessary third-party polyfill or not and, if this functionality is contained in `core-js`, a transpiler or bundler plugin will remove the import of this module or will replace it to the import of suitable `core-js` modules. + +The same approach could be applied to get rid of dependencies from old `core-js` versions. + +### Globalization of pure version polyfills / ponyfills + +One more popular and similar issue is a duplication of polyfills from global and pure `core-js` versions. The pure version of `core-js` / `babel-runtime` is intended for usage in libraries' code, so it's a normal situation if you use a global version of `core-js` and your dependencies also load some copies of `core-js` without global namespace pollution. They use different internals and it's problematic to share similar code between them. + +I'm thinking about resolving this issue on the transpiler or bundler plugins side similarly to the previous one (but, sure, a little more complex) — we could replace imports from the pure version with imports from the global version and remove polyfills unnecessary for the target engines. + +That also could be applied to third-party ponyfills or obsolete libraries that implement something already available in the JS standard library. For example, the usage of `has` package can be replaced by `Object.hasOwn`, `left-pad` by `String.prototype.padStart`, some `lodash` methods by related modern built-in JS methods, etc. + +### Service + +Loading the same polyfills, for example, in IE11, iOS Safari 14.8, and the latest Firefox is wrong — too much dead code will be loaded in modern browsers. At this moment, a popular pattern is the use of 2 bundles — for "modern" browsers that will be loaded if native modules are supported, ` diff --git a/tests/compat/metadata.json b/tests/compat/metadata.json new file mode 100644 index 000000000000..8efafd84ef56 --- /dev/null +++ b/tests/compat/metadata.json @@ -0,0 +1,10 @@ +{ + "segments": { + "0": [ + "./hermes-runner.js", + "./tests.js", + "./compat-data.js", + "./common-runner.js" + ] + } +} diff --git a/tests/compat/node-runner.js b/tests/compat/node-runner.js index df3672ec511f..4a5ae2548ce6 100644 --- a/tests/compat/node-runner.js +++ b/tests/compat/node-runner.js @@ -1,19 +1,10 @@ +'use strict'; +/* eslint-disable no-console -- output */ require('./tests'); -var tests = global.tests; -var result = {}; +require('./compat-data'); +require('./common-runner'); -for (var key in tests) { - var test = tests[key]; - try { - if (typeof test == 'function') { - result[key] = !!test(); - } else result[key] = test.reduce(function (accumulator, $test) { - return accumulator && !!$test(); - }, true); - } catch (error) { - result[key] = false; - } -} - -// eslint-disable-next-line no-console -console.log(JSON.stringify(result, null, ' ')); +if (process.argv.indexOf('json') !== -1) { + // eslint-disable-next-line es/no-json -- safe + console.log(JSON.stringify(global.results, null, ' ')); +} else global.showResults('node', console.log); diff --git a/tests/compat/rhino-adapter.mjs b/tests/compat/rhino-adapter.mjs new file mode 100644 index 000000000000..62eeee37c571 --- /dev/null +++ b/tests/compat/rhino-adapter.mjs @@ -0,0 +1,3 @@ +const [path] = argv._; + +await $`java -jar ${ path } -require tests/compat/rhino-runner.js`; diff --git a/tests/compat/rhino-runner.js b/tests/compat/rhino-runner.js new file mode 100644 index 000000000000..489e037b5e71 --- /dev/null +++ b/tests/compat/rhino-runner.js @@ -0,0 +1,7 @@ +'use strict'; +require('./tests'); +require('./compat-data'); +require('./common-runner'); + +/* eslint-disable-next-line no-restricted-globals -- output */ +global.showResults('rhino', print); diff --git a/tests/compat/tests.js b/tests/compat/tests.js index 39d49c5ece73..1f07066b8cf9 100644 --- a/tests/compat/tests.js +++ b/tests/compat/tests.js @@ -1,43 +1,99 @@ -/* eslint-disable no-new, radix */ -// eslint-disable-next-line no-new-func -var GLOBAL = Function('return this')(); -// eslint-disable-next-line max-len -var WHITESPACES = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; +'use strict'; +/* eslint-disable prefer-regex-literals, radix, unicorn/prefer-global-this -- required for testing */ +/* eslint-disable regexp/no-empty-capturing-group, regexp/no-lazy-ends, regexp/no-useless-quantifier -- required for testing */ +var GLOBAL = typeof global != 'undefined' ? global : Function('return this')(); +var WHITESPACES = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' + + '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; var NOT_WHITESPACES = '\u200B\u0085\u180E'; var USERAGENT = GLOBAL.navigator && GLOBAL.navigator.userAgent || ''; -// eslint-disable-next-line unicorn/no-unsafe-regex -var WEBKIT_STRING_PAD_BUG = /Version\/10\.\d+(\.\d+)?( Mobile\/\w+)? Safari\//.test(USERAGENT); +var process = GLOBAL.process; +var Bun = GLOBAL.Bun; +var Deno = GLOBAL.Deno; +var versions = process && process.versions || Deno && Deno.version; +var v8 = versions && versions.v8; + +var match, V8_VERSION; + +if (v8) { + match = v8.split('.'); + // in old Chrome, versions of V8 isn't V8 = Chrome / 10 + // but their correct versions are not interesting for us + V8_VERSION = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); +} + +// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0` +// so check `userAgent` even if `.v8` exists, but 0 +if (!V8_VERSION && USERAGENT) { + match = USERAGENT.match(/Edge\/(\d+)/); + if (!match || match[1] >= 74) { + match = USERAGENT.match(/Chrome\/(\d+)/); + if (match) V8_VERSION = +match[1]; + } +} + +var IS_BROWSER = typeof window == 'object' && typeof Deno != 'object'; +var IS_BUN = typeof Bun == 'function' && Bun && typeof Bun.version == 'string'; +var IS_DENO = typeof Deno == 'object' && Deno && typeof Deno.version == 'object'; + +// var IS_NODE = Object.prototype.toString.call(process) == '[object process]'; + +var WEBKIT_STRING_PAD_BUG = /Version\/10(?:\.\d+){1,2}(?: [\w./]+)?(?: Mobile\/\w+)? Safari\//.test(USERAGENT); var DESCRIPTORS_SUPPORT = function () { - return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a == 7; + return Object.defineProperty({}, 'a', { + get: function () { return 7; } + }).a === 7; }; -var PROMISES_SUPPORT = function () { - var process = GLOBAL.process; - var IS_NODE = Object.prototype.toString.call(process) == '[object process]'; - var v8 = process && process.versions && process.versions.v8 || ''; +var V8_PROTOTYPE_DEFINE_BUG = function () { + return Object.defineProperty(function () { /* empty */ }, 'prototype', { + value: 42, + writable: false + }).prototype === 42; +}; - var promise = Promise.resolve(1); +var PROMISES_SUPPORT = function () { + var promise = new Promise(function (resolve) { resolve(1); }); var empty = function () { /* empty */ }; var FakePromise = (promise.constructor = {})[Symbol.species] = function (exec) { exec(empty, empty); }; - return (IS_NODE || typeof PromiseRejectionEvent == 'function') - && promise.then(empty) instanceof FakePromise - && v8.indexOf('6.6') !== 0 - && USERAGENT.indexOf('Chrome/66') === -1; + return promise.then(empty) instanceof FakePromise + && V8_VERSION !== 66 + && (!(IS_BROWSER || IS_DENO) || typeof PromiseRejectionEvent == 'function'); +}; + +var PROMISE_STATICS_ITERATION = function () { + var ITERATION_SUPPORT = false; + try { + var object = {}; + object[Symbol.iterator] = function () { + return { + next: function () { + return { done: ITERATION_SUPPORT = true }; + } + }; + }; + Promise.all(object).then(undefined, function () { /* empty */ }); + } catch (error) { /* empty */ } + return ITERATION_SUPPORT; }; var SYMBOLS_SUPPORT = function () { - return String(Symbol()); + return Object.getOwnPropertySymbols && String(Symbol('symbol detection')) && !(V8_VERSION && V8_VERSION < 41); }; +var SYMBOL_REGISTRY = [SYMBOLS_SUPPORT, function () { + return Symbol['for'] && Symbol.keyFor; +}]; + var URL_AND_URL_SEARCH_PARAMS_SUPPORT = function () { - var url = new URL('b?a=1&b=2&c=3', 'http://a/'); + // eslint-disable-next-line unicorn/relative-url-style -- required for testing + var url = new URL('b?a=1&b=2&c=3', 'https://a/'); var searchParams = url.searchParams; var result = ''; url.pathname = 'c%20d'; @@ -46,18 +102,21 @@ var URL_AND_URL_SEARCH_PARAMS_SUPPORT = function () { result += key + value; }); return searchParams.sort - && url.href === 'http://a/c%20d?a=1&c=3' + && url.href === 'https://a/c%20d?a=1&c=3' && searchParams.get('c') === '3' && String(new URLSearchParams('?a=1')) === 'a=1' && searchParams[Symbol.iterator] && new URL('https://a@b/').username === 'a' && new URLSearchParams(new URLSearchParams('a=b')).get('a') === 'b' - && new URL('http://xn--e1aybc/').host === 'xn--e1aybc' - && new URL('http://a/#%D0%B1').hash === '#%D0%B1' + && new URL('https://xn--e1aybc/').host === 'xn--e1aybc' + && new URL('https://a/#%D0%B1').hash === '#%D0%B1' && result === 'a1c3' - && new URL('http://x/', undefined).host === 'x'; + && new URL('https://x/', undefined).host === 'x'; }; +// eslint-disable-next-line no-proto -- safe +var PROTOTYPE_SETTING_AVAILABLE = Object.setPrototypeOf || ({}).__proto__; + var OBJECT_PROTOTYPE_ACCESSORS_SUPPORT = function () { try { Object.prototype.__defineSetter__.call(null, Math.random(), function () { /* empty */ }); @@ -81,7 +140,7 @@ var SAFE_ITERATION_CLOSING_SUPPORT = function () { iteratorWithReturn[Symbol.iterator] = function () { return this; }; - Array.from(iteratorWithReturn, function () { throw Error('close'); }); + Array.from(iteratorWithReturn, function () { throw new Error('close'); }); } catch (error) { return SAFE_CLOSING; } @@ -129,20 +188,26 @@ var TYPED_ARRAY_CONSTRUCTORS_NOT_REQUIRES_WRAPPERS = function () { return this; }; - return new Int8Array(iterable)[0] == 1 - && new Int8Array(new ArrayBuffer(2), 1, undefined).length == 1; + return new Int8Array(iterable)[0] === 1 + && new Int8Array(new ArrayBuffer(2), 1, undefined).length === 1; }; +function NCG_SUPPORT() { + var re = RegExp('(?b)'); + return re.exec('b').groups.a === 'b' && + 'b'.replace(re, '$c') === 'bc'; +} + function createIsRegExpLogicTest(name) { return function () { var regexp = /./; try { '/./'[name](regexp); - } catch (e) { + } catch (error1) { try { regexp[Symbol.match] = false; return '/./'[name](regexp); - } catch (f) { /* empty */ } + } catch (error2) { /* empty */ } } return false; }; } @@ -150,7 +215,7 @@ function createIsRegExpLogicTest(name) { function createStringHTMLMethodTest(METHOD_NAME) { return function () { var test = ''[METHOD_NAME]('"'); - return test == test.toLowerCase() && test.split('"').length <= 3; + return test === test.toLowerCase() && test.split('"').length <= 3; }; } @@ -162,24 +227,163 @@ function createStringTrimMethodTest(METHOD_NAME) { }; } +function createSetLike(size) { + return { + size: size, + has: function () { + return false; + }, + keys: function () { + return { + next: function () { + return { done: true }; + } + }; + } + }; +} + +function createSetLikeWithInfinitySize(size) { + return { + size: size, + has: function () { + return true; + }, + keys: function () { + throw new Error('e'); + } + }; +} + +function createSetMethodTest(METHOD_NAME, callback) { + return function () { + try { + new Set()[METHOD_NAME](createSetLike(0)); + try { + // late spec change, early WebKit ~ Safari 17.0 beta implementation does not pass it + // https://github.com/tc39/proposal-set-methods/pull/88 + new Set()[METHOD_NAME](createSetLike(-1)); + return false; + } catch (error2) { + if (!callback) return true; + // early V8 implementation bug + // https://issues.chromium.org/issues/351332634 + try { + new Set()[METHOD_NAME](createSetLikeWithInfinitySize(-Infinity)); + return false; + } catch (error) { + var set = new Set([1, 2]); + return callback(set[METHOD_NAME](createSetLikeWithInfinitySize(Infinity))); + } + } + } catch (error) { + return false; + } + }; +} + +function createSetMethodTestShouldGetKeysBeforeCloning(METHOD_NAME) { + return function () { + var baseSet = new Set(); + var setLike = { + size: 0, + has: function () { return true; }, + keys: function () { + return Object.defineProperty({}, 'next', { + get: function () { + baseSet.clear(); + baseSet.add(4); + return function () { + return { done: true }; + }; + } + }); + } + }; + var result = baseSet[METHOD_NAME](setLike); + + return result.size === 1 && result.values().next().value === 4; + }; +} + +function NATIVE_RAW_JSON() { + var unsafeInt = '9007199254740993'; + var raw = JSON.rawJSON(unsafeInt); + return JSON.isRawJSON(raw) && JSON.stringify(raw) === unsafeInt; +} + +function IMMEDIATE() { + return setImmediate && clearImmediate && !(IS_BUN && (function () { + var version = Bun.version.split('.'); + return version.length < 3 || version[0] === '0' && (version[1] < 3 || version[1] === '3' && version[2] === '0'); + })()); +} + +function TIMERS() { + return !(/MSIE .\./.test(USERAGENT) || IS_BUN && (function () { + var version = Bun.version.split('.'); + return version.length < 3 || version[0] === '0' && (version[1] < 3 || version[1] === '3' && version[2] === '0'); + })()); +} + +// https://github.com/tc39/ecma262/pull/3467 +function checkIteratorClosingOnEarlyError(METHOD_NAME, ExpectedError) { + return function () { + var CLOSED = false; + try { + Iterator.prototype[METHOD_NAME].call({ + next: function () { return { done: true }; }, + 'return': function () { CLOSED = true; } + }, -1); + } catch (error) { + // https://bugs.webkit.org/show_bug.cgi?id=291195 + if (!(error instanceof ExpectedError)) return; + } + return CLOSED; + }; +} + +// https://issues.chromium.org/issues/336839115 +function iteratorHelperThrowsErrorOnInvalidIterator(methodName, argument) { + return function () { + if (typeof Iterator == 'function' && Iterator.prototype[methodName]) try { + Iterator.prototype[methodName].call({ next: null }, argument).next(); + } catch (error) { + return true; + } + }; +} + GLOBAL.tests = { + // TODO: Remove this module from `core-js@4` since it's split to modules listed below 'es.symbol': [SYMBOLS_SUPPORT, function () { - return Object.getOwnPropertySymbols - && Object.getOwnPropertySymbols('qwe') + var symbol = Symbol('stringify detection'); + return Object.getOwnPropertySymbols('qwe') && Symbol['for'] && Symbol.keyFor - && JSON.stringify([Symbol()]) == '[null]' - && JSON.stringify({ a: Symbol() }) == '{}' - && JSON.stringify(Object(Symbol())) == '{}' + && JSON.stringify([symbol]) === '[null]' + && JSON.stringify({ a: symbol }) === '{}' + && JSON.stringify(Object(symbol)) === '{}' && Symbol.prototype[Symbol.toPrimitive] && Symbol.prototype[Symbol.toStringTag]; }], + 'es.symbol.constructor': SYMBOLS_SUPPORT, 'es.symbol.description': function () { - return Symbol('foo').description == 'foo' && Symbol().description === undefined; + // eslint-disable-next-line symbol-description -- required for testing + return Symbol('description detection').description === 'description detection' && Symbol().description === undefined; + }, + 'es.symbol.async-dispose': function () { + var descriptor = Object.getOwnPropertyDescriptor(Symbol, 'asyncDispose'); + return descriptor.value && !descriptor.enumerable && !descriptor.configurable && !descriptor.writable; }, 'es.symbol.async-iterator': function () { return Symbol.asyncIterator; }, + 'es.symbol.dispose': function () { + var descriptor = Object.getOwnPropertyDescriptor(Symbol, 'dispose'); + return descriptor.value && !descriptor.enumerable && !descriptor.configurable && !descriptor.writable; + }, + 'es.symbol.for': SYMBOL_REGISTRY, 'es.symbol.has-instance': [SYMBOLS_SUPPORT, function () { return Symbol.hasInstance; }], @@ -189,6 +393,7 @@ GLOBAL.tests = { 'es.symbol.iterator': [SYMBOLS_SUPPORT, function () { return Symbol.iterator; }], + 'es.symbol.key-for': SYMBOL_REGISTRY, 'es.symbol.match': [SYMBOLS_SUPPORT, function () { return Symbol.match; }], @@ -208,14 +413,52 @@ GLOBAL.tests = { return Symbol.split; }], 'es.symbol.to-primitive': [SYMBOLS_SUPPORT, function () { - return Symbol.toPrimitive; + return Symbol.toPrimitive && Symbol.prototype[Symbol.toPrimitive]; }], 'es.symbol.to-string-tag': [SYMBOLS_SUPPORT, function () { - return Symbol.toStringTag; + return Symbol.toStringTag && Symbol.prototype[Symbol.toStringTag]; }], 'es.symbol.unscopables': [SYMBOLS_SUPPORT, function () { return Symbol.unscopables; }], + 'es.error.cause': function () { + return new Error('e', { cause: 7 }).cause === 7 + && !('cause' in Error.prototype); + }, + 'es.error.is-error': function () { + return PROTOTYPE_SETTING_AVAILABLE && + (typeof DOMException != 'function' || Error.isError(new DOMException('DOMException'))) && + Error.isError(new Error('Error', { cause: function () { /* empty */ } })) && + !Error.isError(Object.create(Error.prototype)); + }, + 'es.error.to-string': function () { + if (DESCRIPTORS_SUPPORT) { + // Chrome 32- incorrectly call accessor + var object = Object.create(Object.defineProperty({}, 'name', { get: function () { + return this === object; + } })); + if (Error.prototype.toString.call(object) !== 'true') return false; + } + // FF10- does not properly handle non-strings + return Error.prototype.toString.call({ message: 1, name: 2 }) === '2: 1' + // IE8 does not properly handle defaults + && Error.prototype.toString.call({}) === 'Error'; + }, + 'es.aggregate-error.constructor': function () { + return typeof AggregateError == 'function'; + }, + 'es.aggregate-error.cause': function () { + return new AggregateError([1], 'e', { cause: 7 }).cause === 7 + && !('cause' in AggregateError.prototype); + }, + 'es.suppressed-error.constructor': function () { + return typeof SuppressedError == 'function' + && SuppressedError.length === 3 + && new SuppressedError(1, 2, 3, { cause: 4 }).cause !== 4; + }, + 'es.array.at': function () { + return [].at; + }, 'es.array.concat': function () { var array1 = []; array1[Symbol.isConcatSpreadable] = false; @@ -226,6 +469,7 @@ GLOBAL.tests = { return { foo: 1 }; }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species return array1.concat()[0] === array1 && array2.concat().foo === 1; }, 'es.array.copy-within': function () { @@ -247,6 +491,7 @@ GLOBAL.tests = { constructor[Symbol.species] = function () { return { foo: 1 }; }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species return array.filter(Boolean).foo === 1; }, 'es.array.find': function () { @@ -259,6 +504,12 @@ GLOBAL.tests = { Array(1).findIndex(function () { return SKIPS_HOLES = false; }); return !SKIPS_HOLES && Array.prototype[Symbol.unscopables].findIndex; }, + 'es.array.find-last': function () { + return [].findLast; + }, + 'es.array.find-last-index': function () { + return [].findLastIndex; + }, 'es.array.flat': function () { return Array.prototype.flat; }, @@ -274,11 +525,12 @@ GLOBAL.tests = { }, 'es.array.from': SAFE_ITERATION_CLOSING_SUPPORT, 'es.array.includes': function () { - return Array.prototype.includes && Array.prototype[Symbol.unscopables].includes; + return Array(1).includes() + && Array.prototype[Symbol.unscopables].includes; }, 'es.array.index-of': function () { try { - Array.prototype.indexOf.call(null); + [].indexOf.call(null); } catch (error) { return 1 / [1].indexOf(1, -0) > 0; } @@ -302,14 +554,14 @@ GLOBAL.tests = { return false; } try { - Array.prototype.join.call(null); + Array.prototype.join.call(null, ''); return false; } catch (error) { /* empty */ } return true; }, 'es.array.last-index-of': function () { try { - Array.prototype.lastIndexOf.call(null); + [].lastIndexOf.call(null); } catch (error) { return 1 / [1].lastIndexOf(1, -0) > 0; } @@ -320,12 +572,21 @@ GLOBAL.tests = { constructor[Symbol.species] = function () { return { foo: 1 }; }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species return array.map(function () { return true; }).foo === 1; }, 'es.array.of': function () { function F() { /* empty */ } return Array.of.call(F) instanceof F; }, + 'es.array.push': function () { + if ([].push.call({ length: 0x100000000 }, 1) !== 4294967297) return false; + try { + Object.defineProperty([], 'length', { writable: false }).push(); + } catch (error) { + return error instanceof TypeError; + } + }, 'es.array.reduce': function () { try { Array.prototype.reduce.call(null, function () { /* empty */ }, 1); @@ -350,6 +611,7 @@ GLOBAL.tests = { constructor[Symbol.species] = function () { return { foo: 1 }; }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species return array.slice().foo === 1; }, 'es.array.some': function () { @@ -362,12 +624,38 @@ GLOBAL.tests = { 'es.array.sort': function () { try { Array.prototype.sort.call(null); - } catch (e) { + } catch (error1) { try { [1, 2, 3].sort(null); - } catch (f) { + } catch (error2) { [1, 2, 3].sort(undefined); - return true; + + // stable sort + var array = []; + var result = ''; + var code, chr, value, index; + + // generate an array with more 512 elements (Chakra and old V8 fails only in this case) + for (code = 65; code < 76; code++) { + chr = String.fromCharCode(code); + switch (code) { + case 66: case 69: case 70: case 72: value = 3; break; + case 68: case 71: value = 4; break; + default: value = 2; + } + for (index = 0; index < 47; index++) { + array.push({ k: chr + index, v: value }); + } + } + + array.sort(function (a, b) { return b.v - a.v; }); + + for (index = 0; index < array.length; index++) { + chr = array[index].k.charAt(0); + if (result.charAt(result.length - 1) !== chr) result += chr; + } + + return result === 'DGBEFHACIJK'; } } }, @@ -380,14 +668,40 @@ GLOBAL.tests = { constructor[Symbol.species] = function () { return { foo: 1 }; }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species return array.splice().foo === 1; }, + 'es.array.to-reversed': function () { + return [].toReversed; + }, + 'es.array.to-sorted': function () { + return [].toSorted; + }, + 'es.array.to-spliced': function () { + return [].toSpliced; + }, 'es.array.unscopables.flat': function () { return Array.prototype[Symbol.unscopables].flat; }, 'es.array.unscopables.flat-map': function () { return Array.prototype[Symbol.unscopables].flatMap; }, + 'es.array.unshift': function () { + if ([].unshift(0) !== 1) return false; + try { + Object.defineProperty([], 'length', { writable: false }).unshift(); + } catch (error) { + return error instanceof TypeError; + } + }, + 'es.array.with': function () { + // Incorrect exception thrown when index coercion fails in Firefox + try { + []['with']({ valueOf: function () { throw 4; } }, null); + } catch (error) { + return error === 4; + } + }, 'es.array-buffer.constructor': [ARRAY_BUFFER_SUPPORT, function () { try { return !ArrayBuffer(1); @@ -398,7 +712,7 @@ GLOBAL.tests = { new ArrayBuffer(); new ArrayBuffer(1.5); new ArrayBuffer(NaN); - return ArrayBuffer.name == 'ArrayBuffer'; + return ArrayBuffer.length === 1 && ArrayBuffer.name === 'ArrayBuffer'; }], 'es.array-buffer.is-view': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { return ArrayBuffer.isView; @@ -406,15 +720,40 @@ GLOBAL.tests = { 'es.array-buffer.slice': [ARRAY_BUFFER_SUPPORT, function () { return new ArrayBuffer(2).slice(1, undefined).byteLength; }], - 'es.data-view': ARRAY_BUFFER_SUPPORT, + 'es.array-buffer.detached': function () { + return 'detached' in ArrayBuffer.prototype; + }, + 'es.array-buffer.transfer': function () { + return ArrayBuffer.prototype.transfer; + }, + 'es.array-buffer.transfer-to-fixed-length': function () { + return ArrayBuffer.prototype.transferToFixedLength; + }, + 'es.data-view.constructor': ARRAY_BUFFER_SUPPORT, + 'es.data-view.get-float16': [ARRAY_BUFFER_SUPPORT, function () { + return DataView.prototype.getFloat16; + }], + 'es.data-view.set-float16': [ARRAY_BUFFER_SUPPORT, function () { + return DataView.prototype.setFloat16; + }], + 'es.date.get-year': function () { + return new Date(16e11).getYear() === 120; + }, + // TODO: Remove from `core-js@4` 'es.date.now': function () { return Date.now; }, + 'es.date.set-year': function () { + return Date.prototype.setYear; + }, + 'es.date.to-gmt-string': function () { + return Date.prototype.toGMTString; + }, 'es.date.to-iso-string': function () { try { new Date(NaN).toISOString(); } catch (error) { - return new Date(-5e13 - 1).toISOString() == '0385-07-25T07:06:39.999Z'; + return new Date(-5e13 - 1).toISOString() === '0385-07-25T07:06:39.999Z'; } }, 'es.date.to-json': function () { @@ -424,11 +763,20 @@ GLOBAL.tests = { 'es.date.to-primitive': [SYMBOLS_SUPPORT, function () { return Date.prototype[Symbol.toPrimitive]; }], + // TODO: Remove from `core-js@4` 'es.date.to-string': function () { - return new Date(NaN).toString() == 'Invalid Date'; + return new Date(NaN).toString() === 'Invalid Date'; + }, + 'es.disposable-stack.constructor': function () { + return typeof DisposableStack == 'function'; + }, + 'es.escape': function () { + return escape; }, 'es.function.bind': function () { - return Function.prototype.bind; + var test = (function () { /* empty */ }).bind(); + // eslint-disable-next-line no-prototype-builtins -- safe + return typeof test == 'function' && !test.hasOwnProperty('prototype'); }, 'es.function.has-instance': [SYMBOLS_SUPPORT, function () { return Symbol.hasInstance in Function.prototype; @@ -439,10 +787,76 @@ GLOBAL.tests = { 'es.global-this': function () { return globalThis; }, + 'es.iterator.constructor': function () { + try { + Iterator({}); + } catch (error) { + return typeof Iterator == 'function' + && Iterator.prototype === Object.getPrototypeOf(Object.getPrototypeOf([].values())); + } + }, + 'es.iterator.concat': function () { + return Iterator.concat; + }, + 'es.iterator.dispose': function () { + return [].keys()[Symbol.dispose]; + }, + 'es.iterator.drop': [ + iteratorHelperThrowsErrorOnInvalidIterator('drop', 0), + checkIteratorClosingOnEarlyError('drop', RangeError) + ], + 'es.iterator.every': checkIteratorClosingOnEarlyError('every', TypeError), + 'es.iterator.filter': [ + iteratorHelperThrowsErrorOnInvalidIterator('filter', function () { /* empty */ }), + checkIteratorClosingOnEarlyError('filter', TypeError) + ], + 'es.iterator.find': checkIteratorClosingOnEarlyError('find', TypeError), + 'es.iterator.flat-map': [ + iteratorHelperThrowsErrorOnInvalidIterator('flatMap', function () { /* empty */ }), + checkIteratorClosingOnEarlyError('flatMap', TypeError) + ], + 'es.iterator.for-each': checkIteratorClosingOnEarlyError('forEach', TypeError), + 'es.iterator.from': function () { + Iterator.from({ 'return': null })['return'](); + return true; + }, + 'es.iterator.map': [ + iteratorHelperThrowsErrorOnInvalidIterator('map', function () { /* empty */ }), + checkIteratorClosingOnEarlyError('map', TypeError) + ], + 'es.iterator.reduce': [checkIteratorClosingOnEarlyError('reduce', TypeError), function () { + // fails on undefined initial parameter + // https://bugs.webkit.org/show_bug.cgi?id=291651 + [].keys().reduce(function () { /* empty */ }, undefined); + return true; + }], + 'es.iterator.some': checkIteratorClosingOnEarlyError('some', TypeError), + 'es.iterator.take': checkIteratorClosingOnEarlyError('take', RangeError), + 'es.iterator.to-array': function () { + return Iterator.prototype.toArray; + }, + 'es.json.is-raw-json': NATIVE_RAW_JSON, + 'es.json.parse': function () { + var unsafeInt = '9007199254740993'; + var source; + JSON.parse(unsafeInt, function (key, value, context) { + source = context.source; + }); + return source === unsafeInt; + }, + 'es.json.raw-json': NATIVE_RAW_JSON, + 'es.json.stringify': [NATIVE_RAW_JSON, SYMBOLS_SUPPORT, function () { + var symbol = Symbol('stringify detection'); + return JSON.stringify([symbol]) === '[null]' + && JSON.stringify({ a: symbol }) === '{}' + && JSON.stringify(Object(symbol)) === '{}' + && JSON.stringify('\uDF06\uD834') === '"\\udf06\\ud834"' + && JSON.stringify('\uDEAD') === '"\\udead"'; + }], 'es.json.to-string-tag': [SYMBOLS_SUPPORT, function () { return JSON[Symbol.toStringTag]; }], - 'es.map': [SAFE_ITERATION_CLOSING_SUPPORT, function () { + 'es.map.constructor': [SAFE_ITERATION_CLOSING_SUPPORT, function () { var called = 0; var iterable = { next: function () { @@ -456,21 +870,30 @@ GLOBAL.tests = { var map = new Map(iterable); return map.forEach && map[Symbol.iterator]().next() - && map.get(1) == 2 - && map.set(-0, 3) == map + && map.get(1) === 2 + && map.set(-0, 3) === map && map.has(0) && map[Symbol.toStringTag]; }], + 'es.map.group-by': function () { + // https://bugs.webkit.org/show_bug.cgi?id=271524 + return Map.groupBy('ab', function (it) { + return it; + }).get('a').length === 1; + }, 'es.math.acosh': function () { // V8 bug: https://code.google.com/p/v8/issues/detail?id=3509 - return Math.floor(Math.acosh(Number.MAX_VALUE)) == 710 + return Math.floor(Math.acosh(Number.MAX_VALUE)) === 710 // Tor Browser bug: Math.acosh(Infinity) -> NaN - && Math.acosh(Infinity) == Infinity; + // eslint-disable-next-line math/no-static-infinity-calculations -- testing + && Math.acosh(Infinity) === Infinity; }, 'es.math.asinh': function () { + // eslint-disable-next-line math/no-static-infinity-calculations -- testing return 1 / Math.asinh(0) > 0; }, 'es.math.atanh': function () { + // eslint-disable-next-line math/no-static-infinity-calculations -- testing return 1 / Math.atanh(-0) < 0; }, 'es.math.cbrt': function () { @@ -484,18 +907,23 @@ GLOBAL.tests = { }, 'es.math.expm1': function () { // Old FF bug + // eslint-disable-next-line no-loss-of-precision -- required for old engines return Math.expm1(10) <= 22025.465794806719 && Math.expm1(10) >= 22025.4657948067165168 // Tor Browser bug - && Math.expm1(-2e-17) == -2e-17; + && Math.expm1(-2e-17) === -2e-17; }, 'es.math.fround': function () { return Math.fround; }, + 'es.math.f16round': function () { + return Math.f16round; + }, 'es.math.hypot': function () { + // eslint-disable-next-line math/no-static-infinity-calculations -- testing return Math.hypot && Math.hypot(Infinity, NaN) === Infinity; }, 'es.math.imul': function () { - return Math.imul(0xFFFFFFFF, 5) == -5 && Math.imul.length == 2; + return Math.imul(0xFFFFFFFF, 5) === -5 && Math.imul.length === 2; }, 'es.math.log10': function () { return Math.log10; @@ -510,7 +938,10 @@ GLOBAL.tests = { return Math.sign; }, 'es.math.sinh': function () { - return Math.sinh(-2e-17) == -2e-17; + return Math.sinh(-2e-17) === -2e-17; + }, + 'es.math.sum-precise': function () { + return Math.sumPrecise; }, 'es.math.tanh': function () { return Math.tanh; @@ -522,6 +953,7 @@ GLOBAL.tests = { return Math.trunc; }, 'es.number.constructor': function () { + // eslint-disable-next-line math/no-static-nan-calculations -- feature detection return Number(' 0o1') && Number('0b1') && !Number('+0x1'); }, 'es.number.epsilon': function () { @@ -546,13 +978,36 @@ GLOBAL.tests = { return Number.MIN_SAFE_INTEGER; }, 'es.number.parse-float': function () { - return Number.parseFloat === parseFloat - && 1 / Number.parseFloat(WHITESPACES + '-0') === -Infinity; + try { + parseFloat(Object(Symbol.iterator)); + } catch (error) { + return Number.parseFloat === parseFloat + && 1 / parseFloat(WHITESPACES + '-0') === -Infinity; + } }, 'es.number.parse-int': function () { - return Number.parseInt === parseInt - && Number.parseInt(WHITESPACES + '08') === 8 - && Number.parseInt(WHITESPACES + '0x16') === 22; + try { + parseInt(Object(Symbol.iterator)); + } catch (error) { + return Number.parseInt === parseInt + && parseInt(WHITESPACES + '08') === 8 + && parseInt(WHITESPACES + '0x16') === 22; + } + }, + 'es.number.to-exponential': function () { + try { + 1.0.toExponential(Infinity); + } catch (error) { + try { + 1.0.toExponential(-Infinity); + } catch (error2) { + Infinity.toExponential(Infinity); + NaN.toExponential(Infinity); + return (-6.9e-11).toExponential(4) === '-6.9000e-11' + && 1.255.toExponential(2) === '1.25e+0'; + // && 25.0.toExponential(0) === '3e+1'; + } + } }, 'es.number.to-fixed': function () { try { @@ -572,22 +1027,32 @@ GLOBAL.tests = { } }, 'es.object.assign': function () { + if (DESCRIPTORS_SUPPORT && Object.assign({ b: 1 }, Object.assign(Object.defineProperty({}, 'a', { + enumerable: true, + get: function () { + Object.defineProperty(this, 'b', { + value: 3, + enumerable: false + }); + } + }), { b: 2 })).b !== 1) return false; var A = {}; var B = {}; - var symbol = Symbol(); + var symbol = Symbol('assign detection'); var alphabet = 'abcdefghijklmnopqrst'; A[symbol] = 7; alphabet.split('').forEach(function (chr) { B[chr] = chr; }); - return Object.assign({}, A)[symbol] == 7 && Object.keys(Object.assign({}, B)).join('') == alphabet; + return Object.assign({}, A)[symbol] === 7 && Object.keys(Object.assign({}, B)).join('') === alphabet; }, + // TODO: Remove from `core-js@4` 'es.object.create': function () { return Object.create; }, 'es.object.define-getter': OBJECT_PROTOTYPE_ACCESSORS_SUPPORT, - 'es.object.define-properties': [DESCRIPTORS_SUPPORT, function () { + 'es.object.define-properties': [DESCRIPTORS_SUPPORT, V8_PROTOTYPE_DEFINE_BUG, function () { return Object.defineProperties; }], - 'es.object.define-property': DESCRIPTORS_SUPPORT, + 'es.object.define-property': [DESCRIPTORS_SUPPORT, V8_PROTOTYPE_DEFINE_BUG], 'es.object.define-setter': OBJECT_PROTOTYPE_ACCESSORS_SUPPORT, 'es.object.entries': function () { return Object.entries; @@ -607,9 +1072,21 @@ GLOBAL.tests = { 'es.object.get-own-property-names': function () { return Object.getOwnPropertyNames('qwe'); }, + 'es.object.get-own-property-symbols': [SYMBOLS_SUPPORT, function () { + return Object.getOwnPropertySymbols('qwe'); + }], 'es.object.get-prototype-of': function () { return Object.getPrototypeOf('qwe'); }, + 'es.object.group-by': function () { + // https://bugs.webkit.org/show_bug.cgi?id=271524 + return Object.groupBy('ab', function (it) { + return it; + }).a.length === 1; + }, + 'es.object.has-own': function () { + return Object.hasOwn; + }, 'es.object.is': function () { return Object.is; }, @@ -630,6 +1107,9 @@ GLOBAL.tests = { 'es.object.prevent-extensions': function () { return Object.preventExtensions(true); }, + 'es.object.proto': function () { + return '__proto__' in Object.prototype; + }, 'es.object.seal': function () { return Object.seal(true); }, @@ -645,19 +1125,70 @@ GLOBAL.tests = { return Object.values; }, 'es.parse-float': function () { - return 1 / parseFloat(WHITESPACES + '-0') === -Infinity; + try { + parseFloat(Object(Symbol.iterator)); + } catch (error) { + return 1 / parseFloat(WHITESPACES + '-0') === -Infinity; + } }, 'es.parse-int': function () { - return parseInt(WHITESPACES + '08') === 8 - && parseInt(WHITESPACES + '0x16') === 22; + try { + parseInt(Object(Symbol.iterator)); + } catch (error) { + return parseInt(WHITESPACES + '08') === 8 + && parseInt(WHITESPACES + '0x16') === 22; + } }, + // TODO: Remove this module from `core-js@4` since it's split to modules listed below 'es.promise': PROMISES_SUPPORT, - 'es.promise.all-settled': function () { + 'es.promise.constructor': PROMISES_SUPPORT, + 'es.promise.all': [PROMISES_SUPPORT, SAFE_ITERATION_CLOSING_SUPPORT, PROMISE_STATICS_ITERATION, function () { + return Promise.all; + }], + 'es.promise.all-settled': [PROMISES_SUPPORT, SAFE_ITERATION_CLOSING_SUPPORT, PROMISE_STATICS_ITERATION, function () { return Promise.allSettled; - }, + }], + 'es.promise.any': [PROMISES_SUPPORT, SAFE_ITERATION_CLOSING_SUPPORT, PROMISE_STATICS_ITERATION, function () { + return Promise.any; + }], + 'es.promise.catch': PROMISES_SUPPORT, 'es.promise.finally': [PROMISES_SUPPORT, function () { - return Promise.prototype['finally']; + // eslint-disable-next-line unicorn/no-thenable -- required for testing + return Promise.prototype['finally'].call({ then: function () { return this; } }, function () { /* empty */ }); + }], + 'es.promise.race': [PROMISES_SUPPORT, SAFE_ITERATION_CLOSING_SUPPORT, PROMISE_STATICS_ITERATION, function () { + return Promise.race; }], + 'es.promise.reject': PROMISES_SUPPORT, + 'es.promise.resolve': PROMISES_SUPPORT, + 'es.promise.try': [PROMISES_SUPPORT, function () { + var ACCEPT_ARGUMENTS = false; + Promise['try'](function (argument) { + ACCEPT_ARGUMENTS = argument === 8; + }, 8); + return ACCEPT_ARGUMENTS; + }], + 'es.promise.with-resolvers': [PROMISES_SUPPORT, function () { + return Promise.withResolvers; + }], + 'es.array.from-async': function () { + // https://bugs.webkit.org/show_bug.cgi?id=271703 + var counter = 0; + Array.fromAsync.call(function () { + counter++; + return []; + }, { length: 0 }); + return counter === 1; + }, + 'es.async-disposable-stack.constructor': function () { + // https://github.com/tc39/proposal-explicit-resource-management/issues/256 + // can't be detected synchronously + if (V8_VERSION && V8_VERSION < 136) return; + return typeof AsyncDisposableStack == 'function'; + }, + 'es.async-iterator.async-dispose': function () { + return AsyncIterator.prototype[Symbol.asyncDispose]; + }, 'es.reflect.apply': function () { try { return Reflect.apply(function () { @@ -704,37 +1235,105 @@ GLOBAL.tests = { return Reflect.preventExtensions; }, 'es.reflect.set': function () { - return Reflect.set; + var object = Object.defineProperty({}, 'a', { configurable: true }); + return Reflect.set(Object.getPrototypeOf(object), 'a', 1, object) === false; }, 'es.reflect.set-prototype-of': function () { return Reflect.setPrototypeOf; }, - 'es.regexp.constructor': function () { + 'es.reflect.to-string-tag': function () { + return Reflect[Symbol.toStringTag]; + }, + 'es.regexp.constructor': [NCG_SUPPORT, function () { var re1 = /a/g; var re2 = /a/g; re2[Symbol.match] = false; + // eslint-disable-next-line no-constant-binary-expression -- required for testing return new RegExp(re1) !== re1 && RegExp(re1) === re1 && RegExp(re2) !== re2 - && RegExp(re1, 'i') == '/a/i' + && String(RegExp(re1, 'i')) === '/a/i' + && new RegExp('a', 'y') // just check that it doesn't throw + && RegExp('.', 's').exec('\n') && RegExp[Symbol.species]; + }], + 'es.regexp.escape': function () { + return RegExp.escape('ab') === '\\x61b'; }, - 'es.regexp.exec': function () { + 'es.regexp.dot-all': function () { + return RegExp('.', 's').dotAll; + }, + 'es.regexp.exec': [NCG_SUPPORT, function () { var re1 = /a/; var re2 = /b*/g; + var reSticky = new RegExp('a', 'y'); + var reStickyAnchored = new RegExp('^a', 'y'); re1.exec('a'); re2.exec('a'); return re1.lastIndex === 0 && re2.lastIndex === 0 - && /()??/.exec('')[1] === undefined; - }, + // eslint-disable-next-line regexp/no-empty-group -- required for testing + && /()??/.exec('')[1] === undefined + && reSticky.exec('abc')[0] === 'a' + && reSticky.exec('abc') === null + && (reSticky.lastIndex = 1) + && reSticky.exec('bac')[0] === 'a' + && (reStickyAnchored.lastIndex = 2) + && reStickyAnchored.exec('cba') === null + && RegExp('.', 's').exec('\n'); + }], 'es.regexp.flags': function () { - return /./g.flags === 'g'; + var INDICES_SUPPORT = true; + try { + RegExp('.', 'd'); + } catch (error) { + INDICES_SUPPORT = false; + } + + var O = {}; + // modern V8 bug + var calls = ''; + var expected = INDICES_SUPPORT ? 'dgimsy' : 'gimsy'; + + var addGetter = function (key, chr) { + Object.defineProperty(O, key, { get: function () { + calls += chr; + return true; + } }); + }; + + var pairs = { + dotAll: 's', + global: 'g', + ignoreCase: 'i', + multiline: 'm', + sticky: 'y' + }; + + if (INDICES_SUPPORT) pairs.hasIndices = 'd'; + + for (var key in pairs) addGetter(key, pairs[key]); + + var result = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call(O); + + return result === expected && calls === expected; + }, + 'es.regexp.sticky': function () { + return new RegExp('a', 'y').sticky === true; + }, + 'es.regexp.test': function () { + var execCalled = false; + var re = /[ac]/; + re.exec = function () { + execCalled = true; + return /./.exec.apply(this, arguments); + }; + return re.test('abc') === true && execCalled; }, 'es.regexp.to-string': function () { return RegExp.prototype.toString.call({ source: 'a', flags: 'b' }) === '/a/b' && RegExp.prototype.toString.name === 'toString'; }, - 'es.set': [SAFE_ITERATION_CLOSING_SUPPORT, function () { + 'es.set.constructor': [SAFE_ITERATION_CLOSING_SUPPORT, function () { var called = 0; var iterable = { next: function () { @@ -749,10 +1348,59 @@ GLOBAL.tests = { return set.forEach && set[Symbol.iterator]().next() && set.has(1) - && set.add(-0) == set + && set.add(-0) === set && set.has(0) && set[Symbol.toStringTag]; }], + 'es.set.difference.v2': [createSetMethodTest('difference', function (result) { + return result.size === 0; + }), function () { + // A WebKit bug occurs when `this` is updated while Set.prototype.difference is being executed + // https://bugs.webkit.org/show_bug.cgi?id=288595 + var setLike = { + size: 1, + has: function () { return true; }, + keys: function () { + var index = 0; + return { + next: function () { + var done = index++ > 1; + if (baseSet.has(1)) baseSet.clear(); + return { done: done, value: 2 }; + } + }; + } + }; + + var baseSet = new Set([1, 2, 3, 4]); + + return baseSet.difference(setLike).size === 3; + }], + 'es.set.intersection.v2': [createSetMethodTest('intersection', function (result) { + return result.size === 2 && result.has(1) && result.has(2); + }), function () { + return String(Array.from(new Set([1, 2, 3]).intersection(new Set([3, 2])))) === '3,2'; + }], + 'es.set.is-disjoint-from.v2': createSetMethodTest('isDisjointFrom', function (result) { + return !result; + }), + 'es.set.is-subset-of.v2': createSetMethodTest('isSubsetOf', function (result) { + return result; + }), + 'es.set.is-superset-of.v2': createSetMethodTest('isSupersetOf', function (result) { + return !result; + }), + 'es.set.symmetric-difference.v2': [ + createSetMethodTest('symmetricDifference'), + createSetMethodTestShouldGetKeysBeforeCloning('symmetricDifference') + ], + 'es.set.union.v2': [ + createSetMethodTest('union'), + createSetMethodTestShouldGetKeysBeforeCloning('union') + ], + 'es.string.at-alternative': function () { + return '𠮷'.at(-2) === '\uD842'; + }, 'es.string.code-point-at': function () { return String.prototype.codePointAt; }, @@ -761,6 +1409,9 @@ GLOBAL.tests = { return String.fromCodePoint; }, 'es.string.includes': createIsRegExpLogicTest('includes'), + 'es.string.is-well-formed': function () { + return String.prototype.isWellFormed; + }, 'es.string.iterator': [SYMBOLS_SUPPORT, function () { return ''[Symbol.iterator]; }], @@ -770,13 +1421,18 @@ GLOBAL.tests = { var execCalled = false; var re = /a/; - re.exec = function () { execCalled = true; return null; }; + re.exec = function () { + execCalled = true; + return null; + }; re[Symbol.match](''); - return ''.match(O) == 7 && execCalled; + // eslint-disable-next-line regexp/prefer-regexp-exec -- required for testing + return ''.match(O) === 7 && execCalled; }, 'es.string.match-all': function () { try { + // eslint-disable-next-line regexp/no-missing-g-flag -- required for testing 'a'.matchAll(/./); } catch (error) { return 'a'.matchAll(/./g); @@ -800,7 +1456,10 @@ GLOBAL.tests = { var execCalled = false; var re = /a/; - re.exec = function () { execCalled = true; return null; }; + re.exec = function () { + execCalled = true; + return null; + }; re[Symbol.replace](''); var re2 = /./; @@ -810,7 +1469,16 @@ GLOBAL.tests = { return result; }; - return ''.replace(O) == 7 && execCalled && ''.replace(re2, '$') === '7'; + return ''.replace(O) === 7 + && execCalled + // eslint-disable-next-line regexp/no-useless-dollar-replacements -- false positive + && ''.replace(re2, '$') === '7' + // eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing + && 'a'.replace(/./, '$0') === '$0' + && /./[Symbol.replace]('a', '$0') === '$0'; + }, + 'es.string.replace-all': function () { + return String.prototype.replaceAll; }, 'es.string.search': function () { var O = {}; @@ -818,10 +1486,13 @@ GLOBAL.tests = { var execCalled = false; var re = /a/; - re.exec = function () { execCalled = true; return null; }; + re.exec = function () { + execCalled = true; + return null; + }; re[Symbol.search](''); - return ''.search(O) == 7 && execCalled; + return ''.search(O) === 7 && execCalled; }, 'es.string.split': function () { var O = {}; @@ -829,23 +1500,41 @@ GLOBAL.tests = { var execCalled = false; var re = /a/; - re.exec = function () { execCalled = true; return null; }; + re.exec = function () { + execCalled = true; + return null; + }; re.constructor = {}; re.constructor[Symbol.species] = function () { return re; }; re[Symbol.split](''); + // eslint-disable-next-line regexp/no-empty-group -- required for testing var re2 = /(?:)/; var originalExec = re2.exec; re2.exec = function () { return originalExec.apply(this, arguments); }; var result = 'ab'.split(re2); - return ''.split(O) == 7 && execCalled && result.length === 2 && result[0] === 'a' && result[1] === 'b'; + return ''.split(O) === 7 && execCalled && result.length === 2 && result[0] === 'a' && result[1] === 'b'; }, 'es.string.starts-with': createIsRegExpLogicTest('startsWith'), + 'es.string.substr': function () { + return 'ab'.substr(-1) === 'b'; + }, + 'es.string.to-well-formed': function () { + // Safari ToString conversion bug + // https://bugs.webkit.org/show_bug.cgi?id=251757 + return String.prototype.toWellFormed.call(1) === '1'; + }, 'es.string.trim': createStringTrimMethodTest('trim'), 'es.string.trim-end': [createStringTrimMethodTest('trimEnd'), function () { return String.prototype.trimRight === String.prototype.trimEnd; }], + 'es.string.trim-left': [createStringTrimMethodTest('trimStart'), function () { + return String.prototype.trimLeft === String.prototype.trimStart; + }], + 'es.string.trim-right': [createStringTrimMethodTest('trimEnd'), function () { + return String.prototype.trimRight === String.prototype.trimEnd; + }], 'es.string.trim-start': [createStringTrimMethodTest('trimStart'), function () { return String.prototype.trimLeft === String.prototype.trimStart; }], @@ -898,6 +1587,9 @@ GLOBAL.tests = { ARRAY_BUFFER_VIEWS_SUPPORT, TYPED_ARRAY_CONSTRUCTORS_NOT_REQUIRES_WRAPPERS ], + 'es.typed-array.at': function () { + return Int8Array.prototype.at; + }, 'es.typed-array.copy-within': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { return Int8Array.prototype.copyWithin; }], @@ -905,7 +1597,9 @@ GLOBAL.tests = { return Int8Array.prototype.every; }], 'es.typed-array.fill': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { - return Int8Array.prototype.fill; + var count = 0; + new Int8Array(2).fill({ valueOf: function () { return count++; } }); + return count === 1; }], 'es.typed-array.filter': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { return Int8Array.prototype.filter; @@ -916,6 +1610,12 @@ GLOBAL.tests = { 'es.typed-array.find-index': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { return Int8Array.prototype.findIndex; }], + 'es.typed-array.find-last': function () { + return Int8Array.prototype.findLast; + }, + 'es.typed-array.find-last-index': function () { + return Int8Array.prototype.findLastIndex; + }, 'es.typed-array.for-each': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { return Int8Array.prototype.forEach; }], @@ -933,10 +1633,14 @@ GLOBAL.tests = { return Int8Array.prototype.indexOf; }], 'es.typed-array.iterator': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { - return Int8Array.prototype[Symbol.iterator].name === 'values' - && Int8Array.prototype[Symbol.iterator] === Int8Array.prototype.values - && Int8Array.prototype.keys - && Int8Array.prototype.entries; + try { + Int8Array.prototype[Symbol.iterator].call([1]); + } catch (error) { + return Int8Array.prototype[Symbol.iterator].name === 'values' + && Int8Array.prototype[Symbol.iterator] === Int8Array.prototype.values + && Int8Array.prototype.keys + && Int8Array.prototype.entries; + } }], 'es.typed-array.join': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { return Int8Array.prototype.join; @@ -964,8 +1668,11 @@ GLOBAL.tests = { return Int8Array.prototype.reverse; }], 'es.typed-array.set': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { - new Int8Array(1).set({}); - return true; + var array = new Uint8ClampedArray(3); + array.set(1); + array.set('2', 1); + Int8Array.prototype.set.call(array, { length: 1, 0: 3 }, 2); + return array[0] === 0 && array[1] === 2 && array[2] === 3; }], 'es.typed-array.slice': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { return new Int8Array(1).slice(); @@ -974,7 +1681,29 @@ GLOBAL.tests = { return Int8Array.prototype.some; }], 'es.typed-array.sort': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { - return Int8Array.prototype.sort; + try { + new Uint16Array(1).sort(null); + new Uint16Array(1).sort({}); + return false; + } catch (error) { /* empty */ } + // stable sort + var array = new Uint16Array(516); + var expected = Array(516); + var index, mod; + + for (index = 0; index < 516; index++) { + mod = index % 4; + array[index] = 515 - index; + expected[index] = index - 2 * mod + 3; + } + + array.sort(function (a, b) { + return (a / 4 | 0) - (b / 4 | 0); + }); + + for (index = 0; index < 516; index++) { + if (array[index] !== expected[index]) return; + } return true; }], 'es.typed-array.subarray': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { return Int8Array.prototype.subarray; @@ -983,14 +1712,90 @@ GLOBAL.tests = { try { Int8Array.prototype.toLocaleString.call([1, 2]); } catch (error) { - return [1, 2].toLocaleString() == new Int8Array([1, 2]).toLocaleString(); + return [1, 2].toLocaleString() === new Int8Array([1, 2]).toLocaleString(); } }], 'es.typed-array.to-string': [ARRAY_BUFFER_VIEWS_SUPPORT, function () { - return Int8Array.prototype.toString == Array.prototype.toString; + return Int8Array.prototype.toString === Array.prototype.toString; + }], + 'es.typed-array.to-reversed': function () { + return Int8Array.prototype.toReversed; + }, + 'es.typed-array.to-sorted': function () { + return Int8Array.prototype.toSorted; + }, + 'es.typed-array.with': [function () { + try { + new Int8Array(1)['with'](2, { valueOf: function () { throw 8; } }); + } catch (error) { + return error === 8; + } + }, function () { + // WebKit doesn't handle this correctly. It should truncate a negative fractional index to zero, but instead throws an error + // Copyright (C) 2025 André Bargull. All rights reserved. + // This code is governed by the BSD license found in the LICENSE file. + // https://github.com/tc39/test262/pull/4477/commits/bd47071722d914036280cdd795a6ac6046d1c6f9 + var ta = new Int8Array(1); + var result = ta['with'](-0.5, 1); + return result[0] === 1; }], - 'es.weak-map': [SAFE_ITERATION_CLOSING_SUPPORT, function () { - var key = Object.freeze({}); + 'es.uint8-array.from-base64': function () { + try { + Uint8Array.fromBase64('a'); + return; + } catch (error) { /* empty */ } + if (!Uint8Array.fromBase64) return false; + try { + Uint8Array.fromBase64('', null); + } catch (error) { + return true; + } + }, + 'es.uint8-array.from-hex': function () { + return Uint8Array.fromHex; + }, + 'es.uint8-array.set-from-base64': function () { + var target = new Uint8Array([255, 255, 255, 255, 255]); + try { + target.setFromBase64('', null); + return false; + } catch (error) { /* empty */ } + try { + target.setFromBase64('a'); + return; + } catch (error) { /* empty */ } + try { + target.setFromBase64('MjYyZg==='); + } catch (error) { + return target[0] === 50 && target[1] === 54 && target[2] === 50 && target[3] === 255 && target[4] === 255; + } + }, + 'es.uint8-array.set-from-hex': function () { + return Uint8Array.prototype.setFromHex; + }, + 'es.uint8-array.to-base64': function () { + if (!Uint8Array.prototype.toBase64) return false; + try { + var target = new Uint8Array(); + target.toBase64(null); + } catch (error) { + return true; + } + }, + 'es.uint8-array.to-hex': function () { + if (!Uint8Array.prototype.toHex) return false; + try { + var target = new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]); + return target.toHex() === 'ffffffffffffffff'; + } catch (error) { + return false; + } + }, + 'es.unescape': function () { + return unescape; + }, + 'es.weak-map.constructor': [SAFE_ITERATION_CLOSING_SUPPORT, function () { + var key = Object.freeze([]); var called = 0; var iterable = { next: function () { @@ -1002,12 +1807,15 @@ GLOBAL.tests = { }; var map = new WeakMap(iterable); - return map.get(key) == 1 - && map.get(null) == undefined - && map.set({}, 2) == map - && map[Symbol.toStringTag]; + // MS IE bug + return map.get(key) === 1 + && map.get(null) === undefined + && map.set({}, 2) === map + && map[Symbol.toStringTag] + // MS Edge bug + && Object.isFrozen(key); }], - 'es.weak-set': [SAFE_ITERATION_CLOSING_SUPPORT, function () { + 'es.weak-set.constructor': [SAFE_ITERATION_CLOSING_SUPPORT, function () { var key = {}; var called = 0; var iterable = { @@ -1022,24 +1830,21 @@ GLOBAL.tests = { var set = new WeakSet(iterable); return set.has(key) && !set.has(null) - && set.add({}) == set + && set.add({}) === set && set[Symbol.toStringTag]; }], - 'esnext.aggregate-error': function () { - return typeof AggregateError === 'function'; + 'esnext.array.filter-reject': function () { + return [].filterReject; }, - 'esnext.array.last-index': function () { - return [1, 2, 3].lastIndex && Array.prototype[Symbol.unscopables].lastIndex; + 'esnext.array.is-template-object': function () { + return Array.isTemplateObject; }, - 'esnext.array.last-item': function () { - return [1, 2, 3].lastItem && Array.prototype[Symbol.unscopables].lastItem; + 'esnext.array.unique-by': function () { + return [].uniqueBy; }, 'esnext.async-iterator.constructor': function () { return typeof AsyncIterator == 'function'; }, - 'esnext.async-iterator.as-indexed-pairs': function () { - return AsyncIterator.prototype.asIndexedPairs; - }, 'esnext.async-iterator.drop': function () { return AsyncIterator.prototype.drop; }, @@ -1082,48 +1887,41 @@ GLOBAL.tests = { 'esnext.composite-symbol': function () { return compositeSymbol; }, - 'esnext.iterator.constructor': function () { - return typeof Iterator == 'function' - && Iterator.prototype === Object.getPrototypeOf(Object.getPrototypeOf([].values())); - }, - 'esnext.iterator.as-indexed-pairs': function () { - return Iterator.prototype.asIndexedPairs; - }, - 'esnext.iterator.drop': function () { - return Iterator.prototype.drop; - }, - 'esnext.iterator.every': function () { - return Iterator.prototype.every; - }, - 'esnext.iterator.filter': function () { - return Iterator.prototype.filter; + 'esnext.data-view.get-uint8-clamped': [ARRAY_BUFFER_SUPPORT, function () { + return DataView.prototype.getUint8Clamped; + }], + 'esnext.data-view.set-uint8-clamped': [ARRAY_BUFFER_SUPPORT, function () { + return DataView.prototype.setUint8Clamped; + }], + 'esnext.function.demethodize': function () { + return Function.prototype.demethodize; }, - 'esnext.iterator.find': function () { - return Iterator.prototype.find; + 'esnext.function.is-callable': function () { + return Function.isCallable; }, - 'esnext.iterator.flat-map': function () { - return Iterator.prototype.flatMap; + 'esnext.function.is-constructor': function () { + return Function.isConstructor; }, - 'esnext.iterator.for-each': function () { - return Iterator.prototype.forEach; + 'esnext.function.metadata': function () { + return Function.prototype[Symbol.metadata] === null; }, - 'esnext.iterator.from': function () { - return Iterator.from; + 'esnext.iterator.chunks': function () { + return Iterator.prototype.chunks; }, - 'esnext.iterator.map': function () { - return Iterator.prototype.map; + 'esnext.iterator.range': function () { + return Iterator.range; }, - 'esnext.iterator.reduce': function () { - return Iterator.prototype.reduce; + 'esnext.iterator.to-async': function () { + return Iterator.prototype.toAsync; }, - 'esnext.iterator.some': function () { - return Iterator.prototype.some; + 'esnext.iterator.windows': function () { + return Iterator.prototype.windows; }, - 'esnext.iterator.take': function () { - return Iterator.prototype.take; + 'esnext.iterator.zip': function () { + return Iterator.zip; }, - 'esnext.iterator.to-array': function () { - return Iterator.prototype.toArray; + 'esnext.iterator.zip-keyed': function () { + return Iterator.zipKeyed; }, 'esnext.map.delete-all': function () { return Map.prototype.deleteAll; @@ -1143,8 +1941,11 @@ GLOBAL.tests = { 'esnext.map.from': function () { return Map.from; }, - 'esnext.map.group-by': function () { - return Map.groupBy; + 'esnext.map.get-or-insert': function () { + return Map.prototype.getOrInsert; + }, + 'esnext.map.get-or-insert-computed': function () { + return Map.prototype.getOrInsertComputed; }, 'esnext.map.includes': function () { return Map.prototype.includes; @@ -1176,15 +1977,6 @@ GLOBAL.tests = { 'esnext.map.update': function () { return Map.prototype.update; }, - 'esnext.map.update-or-insert': function () { - return Map.prototype.updateOrInsert; - }, - 'esnext.map.upsert': function () { - return Map.prototype.upsert; - }, - 'esnext.math.clamp': function () { - return Math.clamp; - }, 'esnext.math.deg-per-rad': function () { return Math.DEG_PER_RAD; }, @@ -1194,15 +1986,6 @@ GLOBAL.tests = { 'esnext.math.fscale': function () { return Math.fscale; }, - 'esnext.math.iaddh': function () { - return Math.iaddh; - }, - 'esnext.math.imulh': function () { - return Math.imulh; - }, - 'esnext.math.isubh': function () { - return Math.isubh; - }, 'esnext.math.rad-per-deg': function () { return Math.RAD_PER_DEG; }, @@ -1212,63 +1995,21 @@ GLOBAL.tests = { 'esnext.math.scale': function () { return Math.scale; }, - 'esnext.math.seeded-prng': function () { - return Math.seededPRNG; - }, 'esnext.math.signbit': function () { return Math.signbit; }, - 'esnext.math.umulh': function () { - return Math.umulh; + 'esnext.number.clamp': function () { + return Number.prototype.clamp; }, 'esnext.number.from-string': function () { return Number.fromString; }, - 'esnext.observable': function () { - return Observable; - }, - 'esnext.promise.any': function () { - return Promise.any; - }, - 'esnext.promise.try': [PROMISES_SUPPORT, function () { - return Promise['try']; - }], - 'esnext.reflect.define-metadata': function () { - return Reflect.defineMetadata; - }, - 'esnext.reflect.delete-metadata': function () { - return Reflect.deleteMetadata; - }, - 'esnext.reflect.get-metadata': function () { - return Reflect.getMetadata; - }, - 'esnext.reflect.get-metadata-keys': function () { - return Reflect.getMetadataKeys; - }, - 'esnext.reflect.get-own-metadata': function () { - return Reflect.getOwnMetadata; - }, - 'esnext.reflect.get-own-metadata-keys': function () { - return Reflect.getOwnMetadataKeys; - }, - 'esnext.reflect.has-metadata': function () { - return Reflect.hasMetadata; - }, - 'esnext.reflect.has-own-metadata': function () { - return Reflect.hasOwnMetadata; - }, - 'esnext.reflect.metadata': function () { - return Reflect.metadata; - }, 'esnext.set.add-all': function () { return Set.prototype.addAll; }, 'esnext.set.delete-all': function () { return Set.prototype.deleteAll; }, - 'esnext.set.difference': function () { - return Set.prototype.difference; - }, 'esnext.set.every': function () { return Set.prototype.every; }, @@ -1281,18 +2022,6 @@ GLOBAL.tests = { 'esnext.set.from': function () { return Set.from; }, - 'esnext.set.intersection': function () { - return Set.prototype.intersection; - }, - 'esnext.set.is-disjoint-from': function () { - return Set.prototype.isDisjointFrom; - }, - 'esnext.set.is-subset-of': function () { - return Set.prototype.isSubsetOf; - }, - 'esnext.set.is-superset-of': function () { - return Set.prototype.isSupersetOf; - }, 'esnext.set.join': function () { return Set.prototype.join; }, @@ -1308,45 +2037,58 @@ GLOBAL.tests = { 'esnext.set.some': function () { return Set.prototype.some; }, - 'esnext.set.symmetric-difference': function () { - return Set.prototype.symmetricDifference; + 'esnext.string.code-points': function () { + return String.prototype.codePoints; + }, + 'esnext.string.cooked': function () { + return String.cooked; }, - 'esnext.set.union': function () { - return Set.prototype.union; + 'esnext.string.dedent': function () { + return String.dedent; }, - 'esnext.string.at': function () { - return String.prototype.at; + 'esnext.symbol.custom-matcher': function () { + return Symbol.customMatcher; }, - 'esnext.string.code-points': function () { - return String.prototype.codePoints; + 'esnext.symbol.is-registered-symbol': function () { + return Symbol.isRegisteredSymbol; }, - 'esnext.string.replace-all': function () { - return String.prototype.replaceAll; + 'esnext.symbol.is-well-known-symbol': function () { + return Symbol.isWellKnownSymbol; }, - 'esnext.symbol.dispose': function () { - return Symbol.dispose; + 'esnext.symbol.metadata': function () { + return Symbol.metadata; }, 'esnext.symbol.observable': function () { return Symbol.observable; }, - 'esnext.symbol.pattern-match': function () { - return Symbol.patternMatch; + 'esnext.typed-array.filter-reject': function () { + return Int8Array.prototype.filterReject; }, - 'esnext.symbol.replace-all': function () { - return Symbol.replaceAll; + 'esnext.typed-array.unique-by': function () { + return Int8Array.prototype.uniqueBy; }, 'esnext.weak-map.delete-all': function () { return WeakMap.prototype.deleteAll; }, + 'esnext.weak-map.get-or-insert': function () { + return WeakMap.prototype.getOrInsert; + }, + 'esnext.weak-map.get-or-insert-computed': function () { + if (!WeakMap.prototype.getOrInsertComputed) return; + try { + new WeakMap().getOrInsertComputed(1, function () { throw 1; }); + } catch (error) { + // FF144 Nightly - Beta 3 bug + // https://bugzilla.mozilla.org/show_bug.cgi?id=1988369 + return error instanceof TypeError; + } + }, 'esnext.weak-map.from': function () { return WeakMap.from; }, 'esnext.weak-map.of': function () { return WeakMap.of; }, - 'esnext.weak-map.upsert': function () { - return WeakMap.prototype.upsert; - }, 'esnext.weak-set.add-all': function () { return WeakSet.prototype.addAll; }, @@ -1359,6 +2101,27 @@ GLOBAL.tests = { 'esnext.weak-set.of': function () { return WeakSet.of; }, + 'web.atob': function () { + try { + atob(); + } catch (error1) { + try { + atob('a'); + } catch (error2) { + return atob(' ') === ''; + } + } + }, + 'web.btoa': function () { + try { + btoa(); + } catch (error) { + return typeof btoa == 'function'; + } + }, + 'web.clear-immediate': function () { + return setImmediate && clearImmediate; + }, 'web.dom-collections.for-each': function () { return (!GLOBAL.NodeList || (NodeList.prototype.forEach && NodeList.prototype.forEach === [].forEach)) && (!GLOBAL.DOMTokenList || (DOMTokenList.prototype.forEach && DOMTokenList.prototype.forEach === [].forEach)); @@ -1412,18 +2175,83 @@ GLOBAL.tests = { } return true; }, - 'web.immediate': function () { - return setImmediate && clearImmediate; + 'web.dom-exception.constructor': function () { + return new DOMException() instanceof Error + && new DOMException(1, 'DataCloneError').code === 25 + && String(new DOMException(1, 2)) === '2: 1' + && DOMException.DATA_CLONE_ERR === 25 + && DOMException.prototype.DATA_CLONE_ERR === 25; }, - 'web.queue-microtask': function () { - return Object.getOwnPropertyDescriptor(GLOBAL, 'queueMicrotask').value; + 'web.dom-exception.stack': function () { + return !('stack' in new Error('1')) || 'stack' in new DOMException(); }, - 'web.timers': function () { - return !/MSIE .\./.test(USERAGENT); + 'web.dom-exception.to-string-tag': function () { + return typeof DOMException == 'function' + && DOMException.prototype[Symbol.toStringTag] === 'DOMException'; }, - 'web.url': URL_AND_URL_SEARCH_PARAMS_SUPPORT, + // TODO: Remove this module from `core-js@4` since it's split to submodules + 'web.immediate': IMMEDIATE, + 'web.queue-microtask': function () { + return Object.getOwnPropertyDescriptor(GLOBAL, 'queueMicrotask').value.length === 1; + }, + 'web.self': function () { + // eslint-disable-next-line no-restricted-globals -- safe + if (self !== GLOBAL) return false; + if (!DESCRIPTORS_SUPPORT) return true; + var descriptor = Object.getOwnPropertyDescriptor(GLOBAL, 'self'); + return descriptor.get && descriptor.enumerable; + }, + 'web.set-immediate': IMMEDIATE, + 'web.set-interval': TIMERS, + 'web.set-timeout': TIMERS, + 'web.structured-clone': function () { + function checkErrorsCloning(structuredCloneImplementation, $Error) { + var error = new $Error(); + var test = structuredCloneImplementation({ a: error, b: error }); + return test && test.a === test.b && test.a instanceof $Error && test.a.stack === error.stack; + } + + function checkNewErrorsCloningSemantic(structuredCloneImplementation) { + var test = structuredCloneImplementation(new AggregateError([1], 'message', { cause: 3 })); + return test.name === 'AggregateError' && test.errors[0] === 1 && test.message === 'message' && test.cause === 3; + } + + return checkErrorsCloning(structuredClone, Error) + && checkErrorsCloning(structuredClone, DOMException) + && checkNewErrorsCloningSemantic(structuredClone); + }, + // TODO: Remove this module from `core-js@4` since it's split to submodules + 'web.timers': TIMERS, + 'web.url.constructor': URL_AND_URL_SEARCH_PARAMS_SUPPORT, + 'web.url.can-parse': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () { + try { + URL.canParse(); + } catch (error) { + return URL.canParse.length === 1; + } + }], + 'web.url.parse': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () { + return URL.parse; + }], 'web.url.to-json': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () { return URL.prototype.toJSON; }], - 'web.url-search-params': URL_AND_URL_SEARCH_PARAMS_SUPPORT + 'web.url-search-params.constructor': URL_AND_URL_SEARCH_PARAMS_SUPPORT, + 'web.url-search-params.delete': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () { + var params = new URLSearchParams('a=1&a=2&b=3'); + params['delete']('a', 1); + // `undefined` case is a Chromium 117 bug + // https://bugs.chromium.org/p/v8/issues/detail?id=14222 + params['delete']('b', undefined); + return params + '' === 'a=2'; + }], + 'web.url-search-params.has': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () { + var params = new URLSearchParams('a=1'); + // `undefined` case is a Chromium 117 bug + // https://bugs.chromium.org/p/v8/issues/detail?id=14222 + return params.has('a', 1) && !params.has('a', 2) && params.has('a', undefined); + }], + 'web.url-search-params.size': [URL_AND_URL_SEARCH_PARAMS_SUPPORT, function () { + return 'size' in URLSearchParams.prototype; + }] }; diff --git a/tests/entries/content.mjs b/tests/entries/content.mjs new file mode 100644 index 000000000000..1e343fde9d26 --- /dev/null +++ b/tests/entries/content.mjs @@ -0,0 +1,158 @@ +import { deepEqual, ok } from 'node:assert/strict'; +import konan from 'konan'; + +const allModules = await fs.readJson('packages/core-js-compat/modules.json'); +const entries = await fs.readJson('packages/core-js-compat/entries.json'); + +function filter(regexp) { + return allModules.filter(it => regexp.test(it)); +} + +function equal(name, required) { + const contains = new Set(entries[name]); + const shouldContain = new Set(Array.isArray(required) ? required : filter(required)); + deepEqual(contains, shouldContain); +} + +function superset(name, required) { + const contains = new Set(entries[name]); + const shouldContain = Array.isArray(required) ? required : filter(required); + for (const module of shouldContain) { + ok(contains.has(module), module); + } +} + +function subset(name, required) { + const contains = entries[name]; + const shouldContain = new Set(Array.isArray(required) ? required : filter(required)); + for (const module of contains) { + ok(shouldContain.has(module), module); + } +} + +equal('core-js', allModules); +equal('core-js/es', /^es\./); +superset('core-js/es/array', /^es\.array\./); +superset('core-js/es/array-buffer', /^es\.array-buffer\./); +superset('core-js/es/data-view', /^es\.data-view\./); +superset('core-js/es/date', /^es\.date\./); +superset('core-js/es/error', /^es\.error\./); +superset('core-js/es/function', /^es\.function\./); +superset('core-js/es/json', /^es\.json\./); +superset('core-js/es/map', /^es\.map/); +superset('core-js/es/math', /^es\.math\./); +superset('core-js/es/number', /^es\.number\./); +superset('core-js/es/object', /^es\.object\./); +superset('core-js/es/promise', /^es\.promise/); +superset('core-js/es/reflect', /^es\.reflect\./); +superset('core-js/es/regexp', /^es\.regexp\./); +superset('core-js/es/set', /^es\.set/); +superset('core-js/es/string', /^es\.string\./); +superset('core-js/es/symbol', /^es\.symbol/); +superset('core-js/es/typed-array', /^es\.typed-array\./); +superset('core-js/es/weak-map', /^es\.weak-map/); +superset('core-js/es/weak-set', /^es\.weak-set/); +equal('core-js/web', /^web\./); +equal('core-js/stable', /^(?:es|web)\./); +superset('core-js/stable/array', /^es\.array\./); +superset('core-js/stable/array-buffer', /^es\.array-buffer\./); +superset('core-js/stable/data-view', /^es\.data-view\./); +superset('core-js/stable/date', /^es\.date\./); +superset('core-js/stable/dom-collections', /^web\.dom-collections\./); +superset('core-js/stable/error', /^es\.error\./); +superset('core-js/stable/function', /^es\.function\./); +superset('core-js/stable/json', /^es\.json\./); +superset('core-js/stable/map', /^es\.map/); +superset('core-js/stable/math', /^es\.math\./); +superset('core-js/stable/number', /^es\.number\./); +superset('core-js/stable/object', /^es\.object\./); +superset('core-js/stable/promise', /^es\.promise/); +superset('core-js/stable/reflect', /^es\.reflect\./); +superset('core-js/stable/regexp', /^es\.regexp\./); +superset('core-js/stable/set', /^es\.set/); +superset('core-js/stable/string', /^es\.string\./); +superset('core-js/stable/symbol', /^es\.symbol/); +superset('core-js/stable/typed-array', /^es\.typed-array\./); +superset('core-js/stable/url', /^web\.url(http://github.com/?:\.|$)/); +superset('core-js/stable/url-search-params', /^web\.url-search-params/); +superset('core-js/stable/weak-map', /^es\.weak-map/); +superset('core-js/stable/weak-set', /^es\.weak-set/); +superset('core-js/actual', /^(?:es|web)\./); +superset('core-js/actual/array', /^es\.array\./); +superset('core-js/actual/array-buffer', /^es\.array-buffer\./); +superset('core-js/actual/data-view', /^es\.data-view\./); +superset('core-js/actual/date', /^es\.date\./); +superset('core-js/actual/dom-collections', /^web\.dom-collections\./); +superset('core-js/actual/function', /^es\.function\./); +superset('core-js/actual/json', /^es\.json\./); +superset('core-js/actual/map', /^es\.map/); +superset('core-js/actual/math', /^es\.math\./); +superset('core-js/actual/number', /^es\.number\./); +superset('core-js/actual/object', /^es\.object\./); +superset('core-js/actual/promise', /^es\.promise/); +superset('core-js/actual/reflect', /^es\.reflect\./); +superset('core-js/actual/regexp', /^es\.regexp\./); +superset('core-js/actual/set', /^es\.set/); +superset('core-js/actual/string', /^es\.string\./); +superset('core-js/actual/symbol', /^es\.symbol/); +superset('core-js/actual/typed-array', /^es\.typed-array\./); +superset('core-js/actual/url', /^web\.url(http://github.com/?:\.|$)/); +superset('core-js/actual/url-search-params', /^web\.url-search-params/); +superset('core-js/actual/weak-map', /^es\.weak-map/); +superset('core-js/actual/weak-set', /^es\.weak-set/); +equal('core-js/full', allModules); +superset('core-js/full/array', /^(?:es|esnext)\.array\./); +superset('core-js/full/array-buffer', /^(?:es|esnext)\.array-buffer\./); +superset('core-js/full/async-iterator', /^(?:es|esnext)\.async-iterator\./); +superset('core-js/full/bigint', /^(?:es|esnext)\.bigint\./); +superset('core-js/full/data-view', /^(?:es|esnext)\.data-view\./); +superset('core-js/full/date', /^(?:es|esnext)\.date\./); +superset('core-js/full/dom-collections', /^web\.dom-collections\./); +superset('core-js/full/error', /^es\.error\./); +superset('core-js/full/function', /^(?:es|esnext)\.function\./); +superset('core-js/full/iterator', /^(?:es|esnext)\.iterator\./); +superset('core-js/full/json', /^(?:es|esnext)\.json\./); +superset('core-js/full/map', /^(?:es|esnext)\.map/); +superset('core-js/full/math', /^(?:es|esnext)\.math\./); +superset('core-js/full/number', /^(?:es|esnext)\.number\./); +superset('core-js/full/object', /^(?:es|esnext)\.object\./); +superset('core-js/full/observable', /^(?:es|esnext)\.observable/); +superset('core-js/full/promise', /^(?:es|esnext)\.promise/); +superset('core-js/full/reflect', /^(?:es|esnext)\.reflect\./); +superset('core-js/full/regexp', /^(?:es|esnext)\.regexp\./); +superset('core-js/full/set', /^(?:es|esnext)\.set/); +superset('core-js/full/string', /^(?:es|esnext)\.string\./); +superset('core-js/full/symbol', /^(?:es|esnext)\.symbol/); +superset('core-js/full/typed-array', /^(?:es|esnext)\.typed-array\./); +superset('core-js/full/url', /^web\.url(http://github.com/?:\.|$)/); +superset('core-js/full/url-search-params', /^web\.url-search-params/); +superset('core-js/full/weak-map', /^(?:es|esnext)\.weak-map/); +superset('core-js/full/weak-set', /^(?:es|esnext)\.weak-set/); +subset('core-js/proposals', /^(?:es\.(?:map|string\.at)|esnext\.|web\.url)/); +subset('core-js/stage', /^(?:es\.(?:map|string\.at)|esnext\.|web\.url)/); +subset('core-js/stage/pre', /^(?:es\.(?:map|string\.at)|esnext\.|web\.url)/); +subset('core-js/stage/0', /^(?:es\.(?:map|string\.at)|esnext\.|web\.url)/); +subset('core-js/stage/1', /^(?:es\.(?:map|string\.at)|esnext\.|web\.url)/); +subset('core-js/stage/2', /^(?:es\.string\.at|esnext\.)/); +subset('core-js/stage/3', /^(?:es\.string\.at|esnext\.)/); +subset('core-js/stage/4', /^(?:es\.string\.at|esnext\.)/); + +async function unexpectedInnerNamespace(namespace, unexpected) { + const paths = await glob(`packages/core-js/${ namespace }/**/*.js`); + await Promise.all(paths.map(async path => { + for (const dependency of konan(String(await fs.readFile(path))).strings) { + if (unexpected.test(dependency)) { + echo(chalk.red(`${ chalk.cyan(path) }: found unexpected dependency: ${ chalk.cyan(dependency) }`)); + } + } + })); +} + +await Promise.all([ + unexpectedInnerNamespace('es', /\/(?:actual|full|stable)\//), + unexpectedInnerNamespace('stable', /\/(?:actual|full)\//), + unexpectedInnerNamespace('actual', /\/(?:es|full)\//), + unexpectedInnerNamespace('full', /\/(?:es|stable)\//), +]); + +echo(chalk.green('entry points content tested')); diff --git a/tests/entries/index.mjs b/tests/entries/index.mjs new file mode 100644 index 000000000000..a57a6ddd48ff --- /dev/null +++ b/tests/entries/index.mjs @@ -0,0 +1,2 @@ +await import('./content.mjs'); +await import('./unit.mjs'); diff --git a/tests/entries/unit.mjs b/tests/entries/unit.mjs new file mode 100644 index 000000000000..271b5d90ed43 --- /dev/null +++ b/tests/entries/unit.mjs @@ -0,0 +1,1127 @@ +/* eslint-disable import/no-dynamic-require, node/global-require -- required */ +import { ok } from 'node:assert/strict'; + +const entries = await fs.readJson('packages/core-js-compat/entries.json'); +const expected = new Set(Object.keys(entries)); +const tested = new Set(); +let PATH; + +function load(...components) { + const path = [PATH, ...components].join('/'); + tested.add(path); + expected.delete(path); + return require(path); +} + +for (PATH of ['core-js-pure', 'core-js']) { + for (const NS of ['es', 'stable', 'actual', 'full', 'features']) { + let O; + ok(load(NS, 'global-this').Math === Math); + ok(new (load(NS, 'aggregate-error'))([42]).errors[0] === 42); + ok(load(NS, 'object/assign')({ q: 1 }, { w: 2 }).w === 2); + ok(load(NS, 'object/create')(Array.prototype) instanceof Array); + ok(load(NS, 'object/define-property')({}, 'a', { value: 42 }).a === 42); + ok(load(NS, 'object/define-properties')({}, { a: { value: 42 } }).a === 42); + ok(load(NS, 'object/freeze')({})); + ok(load(NS, 'object/get-own-property-descriptor')({ q: 1 }, 'q').enumerable); + ok(load(NS, 'object/get-own-property-names')({ q: 42 })[0] === 'q'); + ok(load(NS, 'object/get-own-property-symbols')({ [Symbol('getOwnPropertySymbols test')]: 42 }).length === 1); + ok(load(NS, 'object/get-prototype-of')([]) === Array.prototype); + ok(load(NS, 'object/group-by')([1, 2, 3, 4, 5], it => it % 2 === 0 ? 'even' : 'odd').odd.length === 3); + ok(load(NS, 'object/has-own')({ foo: 42 }, 'foo')); + ok(load(NS, 'object/is')(NaN, NaN)); + ok(load(NS, 'object/is-extensible')({})); + ok(!load(NS, 'object/is-frozen')({})); + ok(!load(NS, 'object/is-sealed')({})); + ok(load(NS, 'object/keys')({ q: 0 })[0] === 'q'); + ok(load(NS, 'object/prevent-extensions')({})); + load(NS, 'object/proto'); + ok(load(NS, 'object/seal')({})); + ok(load(NS, 'object/set-prototype-of')({}, []) instanceof Array); + ok(load(NS, 'object/to-string')([]) === '[object Array]'); + ok(load(NS, 'object/entries')({ q: 2 })[0][0] === 'q'); + ok(load(NS, 'object/from-entries')([['a', 42]]).a === 42); + ok(load(NS, 'object/values')({ q: 2 })[0] === 2); + ok(load(NS, 'object/get-own-property-descriptors')({ q: 1 }).q.enumerable); + ok(typeof load(NS, 'object/define-getter') == 'function'); + ok(typeof load(NS, 'object/define-setter') == 'function'); + ok(typeof load(NS, 'object/lookup-getter') == 'function'); + ok(typeof load(NS, 'object/lookup-setter') == 'function'); + ok('values' in load(NS, 'object')); + ok(load(NS, 'function/bind')(function (a, b) { + return this + a + b; + }, 1, 2)(3) === 6); + ok(load(NS, 'function/virtual/bind').call(function (a, b) { + return this + a + b; + }, 1, 2)(3) === 6); + ok(load(NS, 'function/virtual').bind.call(function (a, b) { + return this + a + b; + }, 1, 2)(3) === 6); + load(NS, 'function/name'); + load(NS, 'function/has-instance'); + load(NS, 'function'); + ok(Array.isArray(load(NS, 'array/from')('qwe'))); + ok(typeof load(NS, 'array/from-async') == 'function'); + ok(load(NS, 'array/is-array')([])); + ok(Array.isArray(load(NS, 'array/of')('q', 'w', 'e'))); + ok(load(NS, 'array/at')([1, 2, 3], -2) === 2); + ok(load(NS, 'array/join')('qwe', 1) === 'q1w1e'); + ok(load(NS, 'array/slice')('qwe', 1)[1] === 'e'); + ok(load(NS, 'array/sort')([1, 3, 2])[1] === 2); + ok(typeof load(NS, 'array/for-each') == 'function'); + ok(typeof load(NS, 'array/map') == 'function'); + ok(typeof load(NS, 'array/filter') == 'function'); + ok(typeof load(NS, 'array/flat') == 'function'); + ok(typeof load(NS, 'array/flat-map') == 'function'); + ok(typeof load(NS, 'array/some') == 'function'); + ok(typeof load(NS, 'array/every') == 'function'); + ok(typeof load(NS, 'array/push') == 'function'); + ok(typeof load(NS, 'array/reduce') == 'function'); + ok(typeof load(NS, 'array/reduce-right') == 'function'); + ok(typeof load(NS, 'array/reverse') == 'function'); + ok(typeof load(NS, 'array/index-of') == 'function'); + ok(typeof load(NS, 'array/last-index-of') == 'function'); + ok(typeof load(NS, 'array/unshift') == 'function'); + ok(load(NS, 'array/concat')([1, 2, 3], [4, 5, 6]).length === 6); + ok(load(NS, 'array/copy-within')([1, 2, 3, 4, 5], 0, 3)[0] === 4); + ok('next' in load(NS, 'array/entries')([])); + ok(load(NS, 'array/fill')(Array(5), 2)[0] === 2); + ok(load(NS, 'array/find')([2, 3, 4], it => it % 2) === 3); + ok(load(NS, 'array/find-index')([2, 3, 4], it => it % 2) === 1); + ok(load(NS, 'array/find-last')([1, 2, 3], it => it % 2) === 3); + ok(load(NS, 'array/find-last-index')([1, 2, 3], it => it % 2) === 2); + ok('next' in load(NS, 'array/keys')([])); + ok('next' in load(NS, 'array/values')([])); + ok(load(NS, 'array/includes')([1, 2, 3], 2)); + ok('next' in load(NS, 'array/iterator')([])); + ok(load(NS, 'array/with')([1, 2, 3], 1, 4)); + ok(load(NS, 'array/to-reversed')([1, 2, 3])[0] === 3); + ok(load(NS, 'array/to-sorted')([3, 2, 1])[0] === 1); + ok(load(NS, 'array/to-spliced')([3, 2, 1], 1, 1, 4, 5).length === 4); + ok(load(NS, 'array/virtual/at').call([1, 2, 3], -2) === 2); + ok(load(NS, 'array/virtual/join').call('qwe', 1) === 'q1w1e'); + ok(load(NS, 'array/virtual/slice').call('qwe', 1)[1] === 'e'); + ok(load(NS, 'array/virtual/splice').call([1, 2, 3], 1, 2)[0] === 2); + ok(load(NS, 'array/virtual/sort').call([1, 3, 2])[1] === 2); + ok(typeof load(NS, 'array/virtual/for-each') == 'function'); + ok(typeof load(NS, 'array/virtual/map') == 'function'); + ok(typeof load(NS, 'array/virtual/filter') == 'function'); + ok(typeof load(NS, 'array/virtual/flat') == 'function'); + ok(typeof load(NS, 'array/virtual/flat-map') == 'function'); + ok(typeof load(NS, 'array/virtual/some') == 'function'); + ok(typeof load(NS, 'array/virtual/every') == 'function'); + ok(typeof load(NS, 'array/virtual/push') == 'function'); + ok(typeof load(NS, 'array/virtual/reduce') == 'function'); + ok(typeof load(NS, 'array/virtual/reduce-right') == 'function'); + ok(typeof load(NS, 'array/virtual/reverse') == 'function'); + ok(typeof load(NS, 'array/virtual/index-of') == 'function'); + ok(typeof load(NS, 'array/virtual/last-index-of') == 'function'); + ok(typeof load(NS, 'array/virtual/unshift') == 'function'); + ok(load(NS, 'array/virtual/concat').call([1, 2, 3], [4, 5, 6]).length === 6); + ok(load(NS, 'array/virtual/copy-within').call([1, 2, 3, 4, 5], 0, 3)[0] === 4); + ok('next' in load(NS, 'array/virtual/entries').call([])); + ok(load(NS, 'array/virtual/fill').call(Array(5), 2)[0] === 2); + ok(load(NS, 'array/virtual/find').call([2, 3, 4], it => it % 2) === 3); + ok(load(NS, 'array/virtual/find-index').call([2, 3, 4], it => it % 2) === 1); + ok(load(NS, 'array/virtual/find-last').call([1, 2, 3], it => it % 2) === 3); + ok(load(NS, 'array/virtual/find-last-index').call([1, 2, 3], it => it % 2) === 2); + ok('next' in load(NS, 'array/virtual/keys').call([])); + ok('next' in load(NS, 'array/virtual/values').call([])); + ok(load(NS, 'array/virtual/includes').call([1, 2, 3], 2)); + ok('next' in load(NS, 'array/virtual/iterator').call([])); + ok(load(NS, 'array/virtual/with').call([1, 2, 3], 1, 4)); + ok(load(NS, 'array/virtual/to-reversed').call([1, 2, 3])[0] === 3); + ok(load(NS, 'array/virtual/to-sorted').call([3, 2, 1])[0] === 1); + ok(load(NS, 'array/virtual/to-spliced').call([3, 2, 1], 1, 1, 4, 5).length === 4); + ok('map' in load(NS, 'array/virtual')); + ok('from' in load(NS, 'array')); + ok(load(NS, 'array/splice')([1, 2, 3], 1, 2)[0] === 2); + ok(new (load(NS, 'error/constructor').Error)(1, { cause: 7 }).cause === 7); + ok(load(NS, 'error/is-error')(new Error())); + ok(typeof load(NS, 'error/to-string') == 'function'); + ok(new (load(NS, 'error').Error)(1, { cause: 7 }).cause === 7); + ok(load(NS, 'math/acosh')(1) === 0); + ok(Object.is(load(NS, 'math/asinh')(-0), -0)); + ok(load(NS, 'math/atanh')(1) === Infinity); + ok(load(NS, 'math/cbrt')(-8) === -2); + ok(load(NS, 'math/clz32')(0) === 32); + ok(load(NS, 'math/cosh')(0) === 1); + ok(load(NS, 'math/expm1')(-Infinity) === -1); + ok(load(NS, 'math/fround')(0) === 0); + ok(load(NS, 'math/f16round')(1.337) === 1.3369140625); + ok(load(NS, 'math/hypot')(3, 4) === 5); + ok(load(NS, 'math/imul')(2, 2) === 4); + ok(load(NS, 'math/log10')(-0) === -Infinity); + ok(load(NS, 'math/log1p')(-1) === -Infinity); + ok(load(NS, 'math/log2')(1) === 0); + ok(load(NS, 'math/sign')(-2) === -1); + ok(Object.is(load(NS, 'math/sinh')(-0), -0)); + ok(load(NS, 'math/sum-precise')([1, 2, 3]) === 6); + ok(load(NS, 'math/tanh')(Infinity) === 1); + ok(load(NS, 'math/to-string-tag') === 'Math'); + ok(load(NS, 'math/trunc')(1.5) === 1); + ok('cbrt' in load(NS, 'math')); + ok(load(NS, 'number/constructor')('5') === 5); + ok(load(NS, 'number/epsilon') === 2 ** -52); + ok(load(NS, 'number/is-finite')(42.5)); + ok(load(NS, 'number/is-integer')(42.5) === false); + ok(load(NS, 'number/is-nan')(NaN)); + ok(load(NS, 'number/is-safe-integer')(42)); + ok(load(NS, 'number/max-safe-integer') === 0x1FFFFFFFFFFFFF); + ok(load(NS, 'number/min-safe-integer') === -0x1FFFFFFFFFFFFF); + ok(load(NS, 'number/parse-float')('1.5') === 1.5); + ok(load(NS, 'number/parse-int')('2.1') === 2); + ok(load(NS, 'number/to-exponential')(1, 1) === '1.0e+0'); + ok(load(NS, 'number/to-fixed')(1, 1) === '1.0'); + ok(load(NS, 'number/to-precision')(1) === '1'); + ok(load(NS, 'parse-float')('1.5') === 1.5); + ok(load(NS, 'parse-int')('2.1') === 2); + ok(load(NS, 'number/virtual/to-exponential').call(1, 1) === '1.0e+0'); + ok(load(NS, 'number/virtual/to-fixed').call(1, 1) === '1.0'); + ok(load(NS, 'number/virtual/to-precision').call(1) === '1'); + ok('toPrecision' in load(NS, 'number/virtual')); + ok('isNaN' in load(NS, 'number')); + ok(load(NS, 'reflect/apply')((a, b) => a + b, null, [1, 2]) === 3); + ok(load(NS, 'reflect/construct')(function () { + return this.a = 2; + }, []).a === 2); + load(NS, 'reflect/define-property')(O = {}, 'a', { value: 42 }); + ok(O.a === 42); + ok(load(NS, 'reflect/delete-property')({ q: 1 }, 'q')); + ok(load(NS, 'reflect/get')({ q: 1 }, 'q') === 1); + ok(load(NS, 'reflect/get-own-property-descriptor')({ q: 1 }, 'q').enumerable); + ok(load(NS, 'reflect/get-prototype-of')([]) === Array.prototype); + ok(load(NS, 'reflect/has')({ q: 1 }, 'q')); + ok(load(NS, 'reflect/is-extensible')({})); + ok(load(NS, 'reflect/own-keys')({ q: 1 })[0] === 'q'); + ok(load(NS, 'reflect/prevent-extensions')({})); + ok(load(NS, 'reflect/set')({}, 'a', 42)); + load(NS, 'reflect/set-prototype-of')(O = {}, []); + ok(load(NS, 'reflect/to-string-tag') === 'Reflect'); + ok(O instanceof Array); + ok('has' in load(NS, 'reflect')); + ok(load(NS, 'string/from-code-point')(97) === 'a'); + ok(load(NS, 'string/raw')({ raw: 'test' }, 0, 1, 2) === 't0e1s2t'); + ok(load(NS, 'string/at')('a', 0) === 'a'); + ok(load(NS, 'string/trim')(' ab ') === 'ab'); + ok(load(NS, 'string/trim-start')(' a ') === 'a '); + ok(load(NS, 'string/trim-end')(' a ') === ' a'); + ok(load(NS, 'string/trim-left')(' a ') === 'a '); + ok(load(NS, 'string/trim-right')(' a ') === ' a'); + ok(load(NS, 'string/code-point-at')('a', 0) === 97); + ok(load(NS, 'string/ends-with')('qwe', 'we')); + ok(load(NS, 'string/includes')('qwe', 'w')); + ok(load(NS, 'string/repeat')('q', 3) === 'qqq'); + ok(load(NS, 'string/starts-with')('qwe', 'qw')); + ok(typeof load(NS, 'string/anchor') == 'function'); + ok(typeof load(NS, 'string/big') == 'function'); + ok(typeof load(NS, 'string/blink') == 'function'); + ok(typeof load(NS, 'string/bold') == 'function'); + ok(typeof load(NS, 'string/fixed') == 'function'); + ok(typeof load(NS, 'string/fontcolor') == 'function'); + ok(typeof load(NS, 'string/fontsize') == 'function'); + ok(typeof load(NS, 'string/italics') == 'function'); + ok(typeof load(NS, 'string/link') == 'function'); + ok(typeof load(NS, 'string/small') == 'function'); + ok(typeof load(NS, 'string/strike') == 'function'); + ok(typeof load(NS, 'string/sub') == 'function'); + ok(load(NS, 'string/substr')('12345', 1, 3) === '234'); + ok(typeof load(NS, 'string/sup') == 'function'); + ok(typeof load(NS, 'string/replace-all') == 'function'); + ok(load(NS, 'string/pad-start')('a', 3) === ' a'); + ok(load(NS, 'string/pad-end')('a', 3) === 'a '); + ok(load(NS, 'string/is-well-formed')('a')); + ok(load(NS, 'string/to-well-formed')('a') === 'a'); + ok('next' in load(NS, 'string/iterator')('qwe')); + ok(load(NS, 'string/virtual/at').call('a', 0) === 'a'); + ok(load(NS, 'string/virtual/code-point-at').call('a', 0) === 97); + ok(load(NS, 'string/virtual/ends-with').call('qwe', 'we')); + ok(load(NS, 'string/virtual/includes').call('qwe', 'w')); + ok(typeof load(NS, 'string/virtual/match-all') == 'function'); + ok(typeof load(NS, 'string/virtual/replace-all') == 'function'); + ok(load(NS, 'string/virtual/repeat').call('q', 3) === 'qqq'); + ok(load(NS, 'string/virtual/starts-with').call('qwe', 'qw')); + ok(load(NS, 'string/virtual/trim').call(' ab ') === 'ab'); + ok(load(NS, 'string/virtual/trim-start').call(' a ') === 'a '); + ok(load(NS, 'string/virtual/trim-end').call(' a ') === ' a'); + ok(load(NS, 'string/virtual/trim-left').call(' a ') === 'a '); + ok(load(NS, 'string/virtual/trim-right').call(' a ') === ' a'); + ok(typeof load(NS, 'string/virtual/anchor') == 'function'); + ok(typeof load(NS, 'string/virtual/big') == 'function'); + ok(typeof load(NS, 'string/virtual/blink') == 'function'); + ok(typeof load(NS, 'string/virtual/bold') == 'function'); + ok(typeof load(NS, 'string/virtual/fixed') == 'function'); + ok(typeof load(NS, 'string/virtual/fontcolor') == 'function'); + ok(typeof load(NS, 'string/virtual/fontsize') == 'function'); + ok(typeof load(NS, 'string/virtual/italics') == 'function'); + ok(typeof load(NS, 'string/virtual/link') == 'function'); + ok(typeof load(NS, 'string/virtual/small') == 'function'); + ok(typeof load(NS, 'string/virtual/strike') == 'function'); + ok(typeof load(NS, 'string/virtual/sub') == 'function'); + ok(load(NS, 'string/virtual/substr').call('12345', 1, 3) === '234'); + ok(typeof load(NS, 'string/virtual/sup') == 'function'); + ok(load(NS, 'string/virtual/pad-start').call('a', 3) === ' a'); + ok(load(NS, 'string/virtual/pad-end').call('a', 3) === 'a '); + ok(load(NS, 'string/virtual/is-well-formed').call('a')); + ok(load(NS, 'string/virtual/to-well-formed').call('a') === 'a'); + ok('next' in load(NS, 'string/virtual/iterator').call('qwe')); + ok('padEnd' in load(NS, 'string/virtual')); + ok('raw' in load(NS, 'string')); + ok(String(load(NS, 'regexp/constructor')('a', 'g')) === '/a/g'); + ok(load(NS, 'regexp/escape')('10$') === '\\x310\\$'); + ok(load(NS, 'regexp/to-string')(/./g) === '/./g'); + ok(load(NS, 'regexp/flags')(/./g) === 'g'); + ok(typeof load(NS, 'regexp/match') == 'function'); + ok(typeof load(NS, 'regexp/replace') == 'function'); + ok(typeof load(NS, 'regexp/search') == 'function'); + ok(typeof load(NS, 'regexp/split') == 'function'); + ok(typeof load(NS, 'regexp/dot-all') == 'function'); + ok(typeof load(NS, 'regexp/sticky') == 'function'); + ok(typeof load(NS, 'regexp/test') == 'function'); + load(NS, 'regexp'); + ok(load(NS, 'escape')('!q2ф') === '%21q2%u0444'); + ok(load(NS, 'unescape')('%21q2%u0444') === '!q2ф'); + ok(load(NS, 'json').stringify([1]) === '[1]'); + ok(load(NS, 'json/is-raw-json')({}) === false); + ok(load(NS, 'json/parse')('[42]', (key, value, { source }) => typeof value == 'number' ? source + source : value)[0] === '4242'); + ok(typeof load(NS, 'json/raw-json')(42) == 'object'); + ok(load(NS, 'json/stringify')([1]) === '[1]'); + ok(load(NS, 'json/to-string-tag') === 'JSON'); + ok(typeof load(NS, 'date/now')(new Date()) === 'number'); + const date = new Date(); + ok(load(NS, 'date/get-year')(date) === date.getFullYear() - 1900); + load(NS, 'date/set-year')(date, 1); + ok(date.getFullYear() === 1901); + ok(typeof load(NS, 'date/to-string')(date) === 'string'); + ok(load(NS, 'date/to-gmt-string')(date) === date.toUTCString()); + ok(typeof load(NS, 'date/to-primitive')(new Date(), 'number') === 'number'); + ok(typeof load(NS, 'date/to-iso-string')(new Date()) === 'string'); + ok(load(NS, 'date/to-json')(Infinity) === null); + ok(load(NS, 'date')); + ok(typeof load(NS, 'symbol') == 'function'); + ok(typeof load(NS, 'symbol/for') == 'function'); + ok(typeof load(NS, 'symbol/key-for') == 'function'); + ok(Function[load(NS, 'symbol/has-instance')](it => it)); + ok(load(NS, 'symbol/is-concat-spreadable')); + ok(load(NS, 'symbol/iterator')); + ok(load(NS, 'symbol/match')); + ok(load(NS, 'symbol/match-all')); + ok(load(NS, 'symbol/replace')); + ok(load(NS, 'symbol/search')); + ok(load(NS, 'symbol/species')); + ok(load(NS, 'symbol/split')); + ok(load(NS, 'symbol/to-primitive')); + ok(load(NS, 'symbol/to-string-tag')); + ok(load(NS, 'symbol/unscopables')); + ok(load(NS, 'symbol/async-iterator')); + load(NS, 'symbol/description'); + const Map = load(NS, 'map'); + ok(load(NS, 'map/group-by')([], it => it) instanceof load(NS, 'map')); + const Set = load(NS, 'set'); + const WeakMap = load(NS, 'weak-map'); + const WeakSet = load(NS, 'weak-set'); + ok(new Map([[1, 2], [3, 4]]).size === 2); + ok(new Set([1, 2, 3, 2, 1]).size === 3); + ok(new WeakMap([[O = {}, 42]]).get(O) === 42); + ok(new WeakSet([O = {}]).has(O)); + ok(load(NS, 'set/difference')(new Set([1, 2, 3]), new Set([3, 4, 5])).size === 2); + ok(load(NS, 'set/intersection')(new Set([1, 2, 3]), new Set([1, 3, 4])).size === 2); + ok(load(NS, 'set/is-disjoint-from')(new Set([1, 2, 3]), new Set([4, 5, 6]))); + ok(load(NS, 'set/is-subset-of')(new Set([1, 2, 3]), new Set([1, 2, 3, 4]))); + ok(load(NS, 'set/is-superset-of')(new Set([1, 2, 3, 4]), new Set([1, 2, 3]))); + ok(load(NS, 'set/symmetric-difference')(new Set([1, 2, 3]), new Set([3, 4, 5])).size === 4); + ok(load(NS, 'set/union')(new Set([1, 2, 3]), new Set([3, 4, 5])).size === 5); + const Promise = load(NS, 'promise'); + ok('then' in Promise.prototype); + ok(load(NS, 'promise/all-settled')([1, 2, 3]) instanceof Promise); + ok(load(NS, 'promise/any')([1, 2, 3]) instanceof Promise); + ok(load(NS, 'promise/finally')(new Promise(resolve => resolve), it => it) instanceof Promise); + ok(load(NS, 'promise/try')(() => 42) instanceof Promise); + ok(load(NS, 'promise/with-resolvers')().promise instanceof load(NS, 'promise')); + ok(load(NS, 'is-iterable')([])); + ok(typeof load(NS, 'get-iterator-method')([]) == 'function'); + ok('next' in load(NS, 'get-iterator')([])); + ok('Map' in load(NS)); + ok(typeof load(NS, 'iterator') == 'function'); + ok(load(NS, 'iterator/concat')([2]).next().value === 2); + ok(typeof load(NS, 'iterator/drop') == 'function'); + ok(typeof load(NS, 'iterator/every') == 'function'); + ok(typeof load(NS, 'iterator/filter') == 'function'); + ok(typeof load(NS, 'iterator/find') == 'function'); + ok(typeof load(NS, 'iterator/flat-map') == 'function'); + ok(typeof load(NS, 'iterator/for-each') == 'function'); + ok(typeof load(NS, 'iterator/from') == 'function'); + ok(typeof load(NS, 'iterator/map') == 'function'); + ok(typeof load(NS, 'iterator/reduce') == 'function'); + ok(typeof load(NS, 'iterator/some') == 'function'); + ok(typeof load(NS, 'iterator/take') == 'function'); + ok(typeof load(NS, 'iterator/to-array') == 'function'); + ok(new (load(NS, 'suppressed-error'))(1, 2).suppressed === 2); + ok(typeof load(NS, 'disposable-stack') == 'function'); + ok(typeof load(NS, 'disposable-stack/constructor') == 'function'); + load(NS, 'iterator/dispose'); + ok(load(NS, 'symbol/async-dispose')); + ok(load(NS, 'symbol/dispose')); + load(NS, 'async-iterator'); + load(NS, 'async-iterator/async-dispose'); + ok(typeof load(NS, 'async-disposable-stack') == 'function'); + ok(typeof load(NS, 'async-disposable-stack/constructor') == 'function'); + + const instanceAt = load(NS, 'instance/at'); + ok(typeof instanceAt == 'function'); + ok(instanceAt({}) === undefined); + ok(typeof instanceAt([]) == 'function'); + ok(typeof instanceAt('') == 'function'); + ok(instanceAt([]).call([1, 2, 3], 2) === 3); + ok(instanceAt('').call('123', 2) === '3'); + + const instanceBind = load(NS, 'instance/bind'); + ok(typeof instanceBind == 'function'); + ok(instanceBind({}) === undefined); + ok(typeof instanceBind(it => it) == 'function'); + ok(instanceBind(it => it).call(it => it, 1, 2)() === 2); + + const instanceCodePointAt = load(NS, 'instance/code-point-at'); + ok(typeof instanceCodePointAt == 'function'); + ok(instanceCodePointAt({}) === undefined); + ok(typeof instanceCodePointAt('') == 'function'); + ok(instanceCodePointAt('').call('a', 0) === 97); + + const instanceConcat = load(NS, 'instance/concat'); + ok(typeof instanceConcat == 'function'); + ok(instanceConcat({}) === undefined); + ok(typeof instanceConcat([]) == 'function'); + ok(instanceConcat([]).call([1, 2, 3], [4, 5, 6]).length === 6); + + const instanceCopyWithin = load(NS, 'instance/copy-within'); + ok(typeof instanceCopyWithin == 'function'); + ok(instanceCopyWithin({}) === undefined); + ok(typeof instanceCopyWithin([]) == 'function'); + ok(instanceCopyWithin([]).call([1, 2, 3, 4, 5], 0, 3)[0] === 4); + + const instanceEndsWith = load(NS, 'instance/ends-with'); + ok(typeof instanceEndsWith == 'function'); + ok(instanceEndsWith({}) === undefined); + ok(typeof instanceEndsWith('') == 'function'); + ok(instanceEndsWith('').call('qwe', 'we')); + + const instanceEntries = load(NS, 'instance/entries'); + ok(typeof instanceEntries == 'function'); + ok(instanceEntries({}) === undefined); + ok(typeof instanceEntries([]) == 'function'); + ok(instanceEntries([]).call([1, 2, 3]).next().value[1] === 1); + + const instanceEvery = load(NS, 'instance/every'); + ok(typeof instanceEvery == 'function'); + ok(instanceEvery({}) === undefined); + ok(typeof instanceEvery([]) == 'function'); + ok(instanceEvery([]).call([1, 2, 3], it => typeof it == 'number')); + + const instanceFill = load(NS, 'instance/fill'); + ok(typeof instanceFill == 'function'); + ok(instanceFill({}) === undefined); + ok(typeof instanceFill([]) == 'function'); + ok(instanceFill([]).call(Array(5), 42)[3] === 42); + + const instanceFilter = load(NS, 'instance/filter'); + ok(typeof instanceFilter == 'function'); + ok(instanceFilter({}) === undefined); + ok(typeof instanceFilter([]) == 'function'); + ok(instanceFilter([]).call([1, 2, 3], it => it % 2).length === 2); + + const instanceFind = load(NS, 'instance/find'); + ok(typeof instanceFind == 'function'); + ok(instanceFind({}) === undefined); + ok(typeof instanceFind([]) == 'function'); + ok(instanceFind([]).call([1, 2, 3], it => it % 2) === 1); + + const instanceFindIndex = load(NS, 'instance/find-index'); + ok(typeof instanceFindIndex == 'function'); + ok(instanceFindIndex({}) === undefined); + ok(typeof instanceFindIndex([]) == 'function'); + ok(instanceFindIndex([]).call([1, 2, 3], it => it % 2) === 0); + + const instanceFindLast = load(NS, 'instance/find-last'); + ok(typeof instanceFindLast == 'function'); + ok(instanceFindLast({}) === undefined); + ok(typeof instanceFindLast([]) == 'function'); + ok(instanceFindLast([]).call([1, 2, 3], it => it % 2) === 3); + + const instanceFindLastIndex = load(NS, 'instance/find-last-index'); + ok(typeof instanceFindLastIndex == 'function'); + ok(instanceFindLastIndex({}) === undefined); + ok(typeof instanceFindLastIndex([]) == 'function'); + ok(instanceFindLastIndex([]).call([1, 2, 3], it => it % 2) === 2); + + const instanceFlags = load(NS, 'instance/flags'); + ok(typeof instanceFlags == 'function'); + ok(instanceFlags({}) === undefined); + ok(instanceFlags(/./g) === 'g'); + + const instanceFlatMap = load(NS, 'instance/flat-map'); + ok(typeof instanceFlatMap == 'function'); + ok(instanceFlatMap({}) === undefined); + ok(typeof instanceFlatMap([]) == 'function'); + ok(instanceFlatMap([]).call([1, 2, 3], (v, i) => [v, i]).length === 6); + + const instanceFlat = load(NS, 'instance/flat'); + ok(typeof instanceFlat == 'function'); + ok(instanceFlat({}) === undefined); + ok(typeof instanceFlat([]) == 'function'); + ok(instanceFlat([]).call([1, [2, 3], [4, [5, [6]]]]).length === 5); + + const instanceForEach = load(NS, 'instance/for-each'); + ok(typeof instanceForEach == 'function'); + ok(instanceForEach({}) === undefined); + ok(typeof instanceForEach([]) == 'function'); + + const instanceIncludes = load(NS, 'instance/includes'); + ok(typeof instanceIncludes == 'function'); + ok(instanceIncludes({}) === undefined); + ok(typeof instanceIncludes([]) == 'function'); + ok(typeof instanceIncludes('') == 'function'); + ok(instanceIncludes([]).call([1, 2, 3], 2)); + ok(instanceIncludes('').call('123', '2')); + + const instanceIndexOf = load(NS, 'instance/index-of'); + ok(typeof instanceIndexOf == 'function'); + ok(instanceIndexOf({}) === undefined); + ok(typeof instanceIndexOf([]) == 'function'); + ok(instanceIndexOf([]).call([1, 2, 3], 2) === 1); + + const instanceKeys = load(NS, 'instance/keys'); + ok(typeof instanceKeys == 'function'); + ok(instanceKeys({}) === undefined); + ok(typeof instanceKeys([]) == 'function'); + ok(instanceKeys([]).call([1, 2, 3]).next().value === 0); + + const instanceIsWellFormed = load(NS, 'instance/is-well-formed'); + ok(typeof instanceIsWellFormed == 'function'); + ok(instanceIsWellFormed({}) === undefined); + ok(typeof instanceIsWellFormed('') == 'function'); + ok(instanceIsWellFormed('').call('a')); + + const instanceLastIndexOf = load(NS, 'instance/last-index-of'); + ok(typeof instanceLastIndexOf == 'function'); + ok(instanceLastIndexOf({}) === undefined); + ok(typeof instanceLastIndexOf([]) == 'function'); + ok(instanceLastIndexOf([]).call([1, 2, 3], 2) === 1); + + const instanceMap = load(NS, 'instance/map'); + ok(typeof instanceMap == 'function'); + ok(instanceMap({}) === undefined); + ok(typeof instanceMap([]) == 'function'); + ok(instanceMap([]).call([1, 2, 3], it => it % 2)[1] === 0); + + const instanceMatchAll = load(NS, 'instance/match-all'); + ok(typeof instanceMatchAll == 'function'); + ok(instanceMatchAll({}) === undefined); + ok(typeof instanceMatchAll('') == 'function'); + ok(instanceMatchAll('').call('test1test2', /(?test\d)/g).next().value.groups.test === 'test1'); + + const instancePadEnd = load(NS, 'instance/pad-end'); + ok(typeof instancePadEnd == 'function'); + ok(instancePadEnd({}) === undefined); + ok(typeof instancePadEnd('') == 'function'); + ok(instancePadEnd('').call('a', 3, 'b') === 'abb'); + + const instancePadStart = load(NS, 'instance/pad-start'); + ok(typeof instancePadStart == 'function'); + ok(instancePadStart({}) === undefined); + ok(typeof instancePadStart('') == 'function'); + ok(instancePadStart('').call('a', 3, 'b') === 'bba'); + + const instancePush = load(NS, 'instance/push'); + ok(typeof instancePush == 'function'); + ok(instancePush({}) === undefined); + ok(typeof instancePush([]) == 'function'); + ok(instancePush([]).call([1], 8) === 2); + + const instanceReduceRight = load(NS, 'instance/reduce-right'); + ok(typeof instanceReduceRight == 'function'); + ok(instanceReduceRight({}) === undefined); + ok(typeof instanceReduceRight([]) == 'function'); + ok(instanceReduceRight([]).call([1, 2, 3], (memo, it) => it + memo, '') === '123'); + + const instanceReduce = load(NS, 'instance/reduce'); + ok(typeof instanceReduce == 'function'); + ok(instanceReduce({}) === undefined); + ok(typeof instanceReduce([]) == 'function'); + ok(instanceReduce([]).call([1, 2, 3], (memo, it) => it + memo, '') === '321'); + + const instanceRepeat = load(NS, 'instance/repeat'); + ok(typeof instanceRepeat == 'function'); + ok(instanceRepeat({}) === undefined); + ok(typeof instanceRepeat('') == 'function'); + ok(instanceRepeat('').call('a', 3) === 'aaa'); + + const instanceReplaceAll = load(NS, 'instance/replace-all'); + ok(typeof instanceReplaceAll == 'function'); + ok(instanceReplaceAll({}) === undefined); + ok(typeof instanceReplaceAll('') == 'function'); + ok(instanceReplaceAll('').call('aba', 'a', 'c') === 'cbc'); + + const instanceReverse = load(NS, 'instance/reverse'); + ok(typeof instanceReverse == 'function'); + ok(instanceReverse({}) === undefined); + ok(typeof instanceReverse([]) == 'function'); + + const instanceSlice = load(NS, 'instance/slice'); + ok(typeof instanceSlice == 'function'); + ok(instanceSlice({}) === undefined); + ok(typeof instanceSlice([]) == 'function'); + + const instanceSome = load(NS, 'instance/some'); + ok(typeof instanceSome == 'function'); + ok(instanceSome({}) === undefined); + ok(typeof instanceSome([]) == 'function'); + ok(instanceSome([]).call([1, 2, 3], it => typeof it == 'number')); + + const instanceSort = load(NS, 'instance/sort'); + ok(typeof instanceSort == 'function'); + ok(instanceSort({}) === undefined); + ok(typeof instanceSort([]) == 'function'); + + const instanceSplice = load(NS, 'instance/splice'); + ok(typeof instanceSplice == 'function'); + ok(instanceSplice({}) === undefined); + ok(typeof instanceSplice([]) == 'function'); + + const instanceStartsWith = load(NS, 'instance/starts-with'); + ok(typeof instanceStartsWith == 'function'); + ok(instanceStartsWith({}) === undefined); + ok(typeof instanceStartsWith('') == 'function'); + ok(instanceStartsWith('').call('qwe', 'qw')); + + const instanceToReversed = load(NS, 'instance/to-reversed'); + ok(typeof instanceToReversed == 'function'); + ok(instanceToReversed({}) === undefined); + ok(typeof instanceToReversed([]) == 'function'); + ok(instanceToReversed([]).call([1, 2, 3])[0] === 3); + + const instanceToSorted = load(NS, 'instance/to-sorted'); + ok(typeof instanceToSorted == 'function'); + ok(instanceToSorted({}) === undefined); + ok(typeof instanceToSorted([]) == 'function'); + ok(instanceToSorted([]).call([3, 2, 1])[0] === 1); + + const instanceToSpliced = load(NS, 'instance/to-spliced'); + ok(typeof instanceToSpliced == 'function'); + ok(instanceToSpliced({}) === undefined); + ok(typeof instanceToSpliced([]) == 'function'); + ok(instanceToSpliced([]).call([3, 2, 1], 1, 1, 4, 5).length === 4); + + const instanceToWellFormed = load(NS, 'instance/to-well-formed'); + ok(typeof instanceToWellFormed == 'function'); + ok(instanceToWellFormed({}) === undefined); + ok(typeof instanceToWellFormed('') == 'function'); + ok(instanceToWellFormed('').call('a') === 'a'); + + const instanceTrimEnd = load(NS, 'instance/trim-end'); + ok(typeof instanceTrimEnd == 'function'); + ok(instanceTrimEnd({}) === undefined); + ok(typeof instanceTrimEnd('') == 'function'); + ok(instanceTrimEnd('').call(' 1 ') === ' 1'); + + const instanceTrimLeft = load(NS, 'instance/trim-left'); + ok(typeof instanceTrimLeft == 'function'); + ok(instanceTrimLeft({}) === undefined); + ok(typeof instanceTrimLeft('') == 'function'); + ok(instanceTrimLeft('').call(' 1 ') === '1 '); + + const instanceTrimRight = load(NS, 'instance/trim-right'); + ok(typeof instanceTrimRight == 'function'); + ok(instanceTrimRight({}) === undefined); + ok(typeof instanceTrimRight('') == 'function'); + ok(instanceTrimRight('').call(' 1 ') === ' 1'); + + const instanceTrimStart = load(NS, 'instance/trim-start'); + ok(typeof instanceTrimStart == 'function'); + ok(instanceTrimStart({}) === undefined); + ok(typeof instanceTrimStart('') == 'function'); + ok(instanceTrimStart('').call(' 1 ') === '1 '); + + const instanceTrim = load(NS, 'instance/trim'); + ok(typeof instanceTrim == 'function'); + ok(instanceTrim({}) === undefined); + ok(typeof instanceTrim('') == 'function'); + ok(instanceTrim('').call(' 1 ') === '1'); + + const instanceUnshift = load(NS, 'instance/unshift'); + ok(typeof instanceUnshift == 'function'); + ok(instanceUnshift({}) === undefined); + ok(typeof instanceUnshift([]) == 'function'); + const instanceUnshiftTestArray = [1]; + ok(instanceUnshift([]).call(instanceUnshiftTestArray, 8)); + ok(instanceUnshiftTestArray[0] === 8); + + const instanceValues = load(NS, 'instance/values'); + ok(typeof instanceValues == 'function'); + ok(instanceValues({}) === undefined); + ok(typeof instanceValues([]) == 'function'); + ok(instanceValues([]).call([1, 2, 3]).next().value === 1); + + const instanceWith = load(NS, 'instance/with'); + ok(typeof instanceWith == 'function'); + ok(instanceWith({}) === undefined); + ok(typeof instanceWith([]) == 'function'); + ok(instanceWith([]).call([1, 2, 3], 1, 4)[1] === 4); + } + + for (const NS of ['stable', 'actual', 'full', 'features']) { + ok(load(NS, 'atob')('Zg==') === 'f'); + ok(load(NS, 'btoa')('f') === 'Zg=='); + ok(typeof load(NS, 'dom-exception/constructor') == 'function'); + ok(load(NS, 'dom-exception/to-string-tag') === 'DOMException'); + ok(typeof load(NS, 'dom-exception') == 'function'); + ok(typeof load(NS, 'dom-collections').iterator == 'function'); + ok(typeof load(NS, 'dom-collections/for-each') == 'function'); + ok(typeof load(NS, 'dom-collections/iterator') == 'function'); + ok(load(NS, 'self').Math === Math); + ok(typeof load(NS, 'set-timeout') == 'function'); + ok(typeof load(NS, 'set-interval') == 'function'); + ok(typeof load(NS, 'set-immediate') == 'function'); + ok(load(NS, 'structured-clone')(42) === 42); + ok(typeof load(NS, 'clear-immediate') == 'function'); + ok(typeof load(NS, 'queue-microtask') == 'function'); + ok(typeof load(NS, 'url') == 'function'); + ok(load(NS, 'url/can-parse')('a:b') === true); + ok(load(NS, 'url/parse')('a:b').href === 'a:b'); + load(NS, 'url/to-json'); + ok(typeof load(NS, 'url-search-params') == 'function'); + } + + for (const NS of ['actual', 'full', 'features']) { + ok(typeof load(NS, 'array/group') == 'function'); + ok(typeof load(NS, 'array/group-to-map') == 'function'); + ok(typeof load(NS, 'array/group-by') == 'function'); + ok(typeof load(NS, 'array/group-by-to-map') == 'function'); + ok(typeof load(NS, 'array/virtual/group') == 'function'); + ok(typeof load(NS, 'array/virtual/group-to-map') == 'function'); + ok(typeof load(NS, 'array/virtual/group-by') == 'function'); + ok(typeof load(NS, 'array/virtual/group-by-to-map') == 'function'); + ok(typeof load(NS, 'async-iterator') == 'function'); + ok(typeof load(NS, 'async-iterator/drop') == 'function'); + ok(typeof load(NS, 'async-iterator/every') == 'function'); + ok(typeof load(NS, 'async-iterator/filter') == 'function'); + ok(typeof load(NS, 'async-iterator/find') == 'function'); + ok(typeof load(NS, 'async-iterator/flat-map') == 'function'); + ok(typeof load(NS, 'async-iterator/for-each') == 'function'); + ok(typeof load(NS, 'async-iterator/from') == 'function'); + ok(typeof load(NS, 'async-iterator/map') == 'function'); + ok(typeof load(NS, 'async-iterator/reduce') == 'function'); + ok(typeof load(NS, 'async-iterator/some') == 'function'); + ok(typeof load(NS, 'async-iterator/take') == 'function'); + ok(typeof load(NS, 'async-iterator/to-array') == 'function'); + ok(load(NS, 'function/metadata') === null); + ok(typeof load(NS, 'iterator/to-async') == 'function'); + ok(typeof load(NS, 'iterator/zip') == 'function'); + ok(typeof load(NS, 'iterator/zip-keyed') == 'function'); + ok(load(NS, 'map/get-or-insert')(new Map([[1, 2]]), 1, 3) === 2); + ok(load(NS, 'map/get-or-insert-computed')(new Map([[1, 2]]), 1, key => key) === 2); + ok(load(NS, 'symbol/metadata')); + ok(load(NS, 'weak-map/get-or-insert')(new WeakMap([[{}, 2]]), {}, 3) === 3); + ok(load(NS, 'weak-map/get-or-insert-computed')(new WeakMap([[{}, 2]]), {}, () => 3) === 3); + + const instanceGroup = load(NS, 'instance/group'); + ok(typeof instanceGroup == 'function'); + ok(instanceGroup({}) === undefined); + ok(typeof instanceGroup([]) == 'function'); + ok(instanceGroup([]).call([1, 2, 3], it => it % 2)[1].length === 2); + + const instanceGroupToMap = load(NS, 'instance/group-to-map'); + ok(typeof instanceGroupToMap == 'function'); + ok(instanceGroupToMap({}) === undefined); + ok(typeof instanceGroupToMap([]) == 'function'); + ok(instanceGroupToMap([]).call([1, 2, 3], it => it % 2).get(1).length === 2); + + const instanceGroupBy = load(NS, 'instance/group-by'); + ok(typeof instanceGroupBy == 'function'); + ok(instanceGroupBy({}) === undefined); + ok(typeof instanceGroupBy([]) == 'function'); + ok(instanceGroupBy([]).call([1, 2, 3], it => it % 2)[1].length === 2); + + const instanceGroupByToMap = load(NS, 'instance/group-by-to-map'); + ok(typeof instanceGroupByToMap == 'function'); + ok(instanceGroupByToMap({}) === undefined); + ok(typeof instanceGroupByToMap([]) == 'function'); + ok(instanceGroupByToMap([]).call([1, 2, 3], it => it % 2).get(1).length === 2); + } + + for (const NS of ['full', 'features']) { + const Map = load(NS, 'map'); + const Set = load(NS, 'set'); + const WeakMap = load(NS, 'weak-map'); + const WeakSet = load(NS, 'weak-set'); + ok(typeof load(NS, 'array/filter-out') == 'function'); + ok(typeof load(NS, 'array/filter-reject') == 'function'); + ok(typeof load(NS, 'array/is-template-object') == 'function'); + load(NS, 'array/last-item'); + load(NS, 'array/last-index'); + ok(typeof load(NS, 'array/unique-by') == 'function'); + ok(typeof load(NS, 'array/virtual/filter-out') == 'function'); + ok(typeof load(NS, 'array/virtual/filter-reject') == 'function'); + ok(typeof load(NS, 'array/virtual/unique-by') == 'function'); + ok(typeof load(NS, 'async-iterator/as-indexed-pairs') == 'function'); + ok(typeof load(NS, 'async-iterator/indexed') == 'function'); + load(NS, 'bigint/range'); + load(NS, 'bigint'); + load(NS, 'data-view/get-uint8-clamped'); + load(NS, 'data-view/set-uint8-clamped'); + ok(typeof load(NS, 'composite-key')({}, 1, {}) === 'object'); + ok(typeof load(NS, 'composite-symbol')({}, 1, {}) === 'symbol'); + ok(load(NS, 'function/demethodize')([].slice)([1, 2, 3], 1)[0] === 2); + ok(load(NS, 'function/virtual/demethodize').call([].slice)([1, 2, 3], 1)[0] === 2); + ok(!load(NS, 'function/is-callable')(class { /* empty */ })); + ok(!load(NS, 'function/is-constructor')(it => it)); + ok(load(NS, 'function/un-this')([].slice)([1, 2, 3], 1)[0] === 2); + ok(load(NS, 'function/virtual/un-this').call([].slice)([1, 2, 3], 1)[0] === 2); + ok(typeof load(NS, 'iterator/as-indexed-pairs') == 'function'); + ok(typeof load(NS, 'iterator/indexed') == 'function'); + ok(load(NS, 'iterator/range')(1, 2).next().value === 1); + ok(typeof load(NS, 'iterator/chunks') == 'function'); + ok(typeof load(NS, 'iterator/sliding') == 'function'); + ok(typeof load(NS, 'iterator/windows') == 'function'); + ok(load(NS, 'map/delete-all')(new Map(), 1, 2) === false); + ok(load(NS, 'map/emplace')(new Map([[1, 2]]), 1, { update: it => it ** 2 }) === 4); + ok(load(NS, 'map/every')(new Map([[1, 2], [2, 3], [3, 4]]), it => it % 2) === false); + ok(load(NS, 'map/filter')(new Map([[1, 2], [2, 3], [3, 4]]), it => it % 2).size === 1); + ok(load(NS, 'map/find')(new Map([[1, 2], [2, 3], [3, 4]]), it => it % 2) === 3); + ok(load(NS, 'map/find-key')(new Map([[1, 2], [2, 3], [3, 4]]), it => it % 2) === 2); + ok(load(NS, 'map/from')([[1, 2], [3, 4]]) instanceof Map); + ok(load(NS, 'map/includes')(new Map([[1, 2]]), 2), true); + ok(load(NS, 'map/key-by')([], it => it) instanceof Map); + ok(load(NS, 'map/key-of')(new Map([[1, 2]]), 2), 1); + ok(load(NS, 'map/map-keys')(new Map([[1, 2], [2, 3], [3, 4]]), it => it).size === 3); + ok(load(NS, 'map/map-values')(new Map([[1, 2], [2, 3], [3, 4]]), it => it).size === 3); + ok(load(NS, 'map/merge')(new Map([[1, 2], [2, 3]]), [[2, 4], [4, 5]]).size === 3); + ok(load(NS, 'map/update-or-insert')(new Map([[1, 2]]), 1, it => it ** 2, () => 42) === 4); + ok(load(NS, 'map/upsert')(new Map([[1, 2]]), 1, it => it ** 2, () => 42) === 4); + ok(load(NS, 'math/clamp')(6, 2, 4) === 4); + ok(load(NS, 'math/deg-per-rad') === Math.PI / 180); + ok(load(NS, 'math/degrees')(Math.PI) === 180); + ok(load(NS, 'math/fscale')(3, 1, 2, 1, 2) === 3); + ok(load(NS, 'math/iaddh')(3, 2, 0xFFFFFFFF, 4) === 7); + ok(load(NS, 'math/isubh')(3, 4, 0xFFFFFFFF, 2) === 1); + ok(load(NS, 'math/imulh')(0xFFFFFFFF, 7) === -1); + ok(load(NS, 'math/rad-per-deg') === 180 / Math.PI); + ok(load(NS, 'math/radians')(180) === Math.PI); + ok(load(NS, 'math/scale')(3, 1, 2, 1, 2) === 3); + ok(typeof load(NS, 'math/seeded-prng')({ seed: 42 }).next().value === 'number'); + ok(load(NS, 'math/signbit')(-2) === true); + ok(load(NS, 'math/umulh')(0xFFFFFFFF, 7) === 6); + ok(load(NS, 'map/of')([1, 2], [3, 4]) instanceof Map); + ok(load(NS, 'map/reduce')(new Map([[1, 2], [2, 3], [3, 4]]), (a, b) => a + b) === 9); + ok(load(NS, 'map/some')(new Map([[1, 2], [2, 3], [3, 4]]), it => it % 2) === true); + ok(load(NS, 'map/update')(new Map([[1, 2]]), 1, it => it * 2).get(1) === 4); + ok(load(NS, 'number/clamp')(6, 2, 4) === 4); + ok(load(NS, 'number/virtual/clamp').call(6, 2, 4) === 4); + ok(load(NS, 'number/from-string')('12', 3) === 5); + ok(load(NS, 'number/range')(1, 2).next().value === 1); + ok(typeof load(NS, 'object/iterate-entries')({}).next == 'function'); + ok(typeof load(NS, 'object/iterate-keys')({}).next == 'function'); + ok(typeof load(NS, 'object/iterate-values')({}).next == 'function'); + ok('from' in load(NS, 'observable')); + ok(typeof load(NS, 'reflect/define-metadata') == 'function'); + ok(typeof load(NS, 'reflect/delete-metadata') == 'function'); + ok(typeof load(NS, 'reflect/get-metadata') == 'function'); + ok(typeof load(NS, 'reflect/get-metadata-keys') == 'function'); + ok(typeof load(NS, 'reflect/get-own-metadata') == 'function'); + ok(typeof load(NS, 'reflect/get-own-metadata-keys') == 'function'); + ok(typeof load(NS, 'reflect/has-metadata') == 'function'); + ok(typeof load(NS, 'reflect/has-own-metadata') == 'function'); + ok(typeof load(NS, 'reflect/metadata') == 'function'); + ok(load(NS, 'set/add-all')(new Set([1, 2, 3]), 4, 5).size === 5); + ok(load(NS, 'set/delete-all')(new Set([1, 2, 3]), 4, 5) === false); + ok(load(NS, 'set/every')(new Set([1, 2, 3]), it => typeof it == 'number')); + ok(load(NS, 'set/filter')(new Set([1, 2, 3]), it => it % 2).size === 2); + ok(load(NS, 'set/find')(new Set([2, 3, 4]), it => it % 2) === 3); + ok(load(NS, 'set/from')([1, 2, 3, 2, 1]) instanceof Set); + ok(load(NS, 'set/join')(new Set([1, 2, 3])) === '1,2,3'); + ok(load(NS, 'set/map')(new Set([1, 2, 3]), it => it % 2).size === 2); + ok(load(NS, 'set/of')(1, 2, 3, 2, 1) instanceof Set); + ok(load(NS, 'set/reduce')(new Set([1, 2, 3]), (it, v) => it + v) === 6); + ok(load(NS, 'set/some')(new Set([1, 2, 3]), it => typeof it == 'number')); + ok(load(NS, 'string/cooked')`a${ 1 }b` === 'a1b'); + ok(load(NS, 'string/dedent')` + a${ 1 }b + ` === 'a1b'); + ok('next' in load(NS, 'string/code-points')('a')); + ok('next' in load(NS, 'string/virtual/code-points').call('a')); + ok(load(NS, 'symbol/custom-matcher')); + ok(load(NS, 'symbol/is-registered-symbol')(1) === false); + ok(load(NS, 'symbol/is-well-known-symbol')(1) === false); + ok(load(NS, 'symbol/is-registered')(1) === false); + ok(load(NS, 'symbol/is-well-known')(1) === false); + ok(load(NS, 'symbol/matcher')); + ok(load(NS, 'symbol/metadata-key')); + ok(load(NS, 'symbol/observable')); + ok(load(NS, 'symbol/pattern-match')); + ok(load(NS, 'symbol/replace-all')); + ok(load(NS, 'weak-map/delete-all')(new WeakMap(), [], {}) === false); + ok(load(NS, 'weak-map/emplace')(new WeakMap(), {}, { insert: () => ({ a: 42 }) }).a === 42); + ok(load(NS, 'weak-map/upsert')(new WeakMap(), {}, null, () => 42) === 42); + ok(load(NS, 'weak-map/from')([[{}, 1], [[], 2]]) instanceof WeakMap); + ok(load(NS, 'weak-map/of')([{}, 1], [[], 2]) instanceof WeakMap); + ok(load(NS, 'weak-set/add-all')(new WeakSet(), [], {}) instanceof WeakSet); + ok(load(NS, 'weak-set/delete-all')(new WeakSet(), [], {}) === false); + ok(load(NS, 'weak-set/from')([{}, []]) instanceof WeakSet); + ok(load(NS, 'weak-set/of')({}, []) instanceof WeakSet); + + const instanceClamp = load(NS, 'instance/clamp'); + ok(typeof instanceClamp == 'function'); + ok(instanceClamp({}) === undefined); + ok(typeof instanceClamp(6) == 'function'); + ok(instanceClamp(6).call(6, 2, 4) === 4); + + const instanceCodePoints = load(NS, 'instance/code-points'); + ok(typeof instanceCodePoints == 'function'); + ok(instanceCodePoints({}) === undefined); + ok(typeof instanceCodePoints('') == 'function'); + ok(instanceCodePoints('').call('abc').next().value.codePoint === 97); + + const instanceDemethodize = load(NS, 'instance/demethodize'); + ok(typeof instanceDemethodize == 'function'); + ok(instanceDemethodize({}) === undefined); + ok(typeof instanceDemethodize([].slice) == 'function'); + ok(instanceDemethodize([].slice).call([].slice)([1, 2, 3], 1)[0] === 2); + + const instanceFilterOut = load(NS, 'instance/filter-out'); + ok(typeof instanceFilterOut == 'function'); + ok(instanceFilterOut({}) === undefined); + ok(typeof instanceFilterOut([]) == 'function'); + ok(instanceFilterOut([]).call([1, 2, 3], it => it % 2).length === 1); + + const instanceFilterReject = load(NS, 'instance/filter-reject'); + ok(typeof instanceFilterReject == 'function'); + ok(instanceFilterReject({}) === undefined); + ok(typeof instanceFilterReject([]) == 'function'); + ok(instanceFilterReject([]).call([1, 2, 3], it => it % 2).length === 1); + + const instanceUniqueBy = load(NS, 'instance/unique-by'); + ok(typeof instanceUniqueBy == 'function'); + ok(instanceUniqueBy({}) === undefined); + ok(typeof instanceUniqueBy([]) == 'function'); + ok(instanceUniqueBy([]).call([1, 2, 3, 2, 1]).length === 3); + + const instanceUnThis = load(NS, 'instance/un-this'); + ok(typeof instanceUnThis == 'function'); + ok(instanceUnThis({}) === undefined); + ok(typeof instanceUnThis([].slice) == 'function'); + ok(instanceUnThis([].slice).call([].slice)([1, 2, 3], 1)[0] === 2); + } + + load('proposals/accessible-object-hasownproperty'); + load('proposals/array-filtering'); + load('proposals/array-filtering-stage-1'); + load('proposals/array-find-from-last'); + load('proposals/array-flat-map'); + load('proposals/array-from-async'); + load('proposals/array-from-async-stage-2'); + load('proposals/array-grouping'); + load('proposals/array-grouping-stage-3'); + load('proposals/array-grouping-stage-3-2'); + load('proposals/array-grouping-v2'); + load('proposals/array-includes'); + load('proposals/array-is-template-object'); + load('proposals/array-last'); + load('proposals/array-unique'); + load('proposals/array-buffer-base64'); + load('proposals/array-buffer-transfer'); + load('proposals/async-explicit-resource-management'); + load('proposals/async-iteration'); + load('proposals/async-iterator-helpers'); + load('proposals/change-array-by-copy'); + load('proposals/change-array-by-copy-stage-4'); + load('proposals/collection-methods'); + load('proposals/collection-of-from'); + load('proposals/data-view-get-set-uint8-clamped'); + load('proposals/decorator-metadata'); + load('proposals/decorator-metadata-v2'); + load('proposals/decorators'); + load('proposals/efficient-64-bit-arithmetic'); + load('proposals/error-cause'); + load('proposals/explicit-resource-management'); + load('proposals/extractors'); + load('proposals/float16'); + load('proposals/function-demethodize'); + load('proposals/function-is-callable-is-constructor'); + load('proposals/function-un-this'); + load('proposals/global-this'); + load('proposals/is-error'); + load('proposals/iterator-helpers'); + load('proposals/iterator-helpers-stage-3'); + load('proposals/iterator-helpers-stage-3-2'); + load('proposals/iterator-range'); + load('proposals/iterator-sequencing'); + load('proposals/iterator-chunking'); + load('proposals/iterator-chunking-v2'); + load('proposals/joint-iteration'); + load('proposals/json-parse-with-source'); + load('proposals/keys-composition'); + load('proposals/map-update-or-insert'); + load('proposals/map-upsert'); + load('proposals/map-upsert-stage-2'); + load('proposals/map-upsert-v4'); + load('proposals/math-clamp'); + load('proposals/math-clamp-v2'); + load('proposals/math-extensions'); + load('proposals/math-signbit'); + load('proposals/math-sum'); + load('proposals/number-from-string'); + load('proposals/number-range'); + load('proposals/object-from-entries'); + load('proposals/object-iteration'); + load('proposals/object-getownpropertydescriptors'); + load('proposals/object-values-entries'); + load('proposals/observable'); + load('proposals/pattern-matching'); + load('proposals/pattern-matching-v2'); + load('proposals/promise-all-settled'); + load('proposals/promise-any'); + load('proposals/promise-finally'); + load('proposals/promise-try'); + load('proposals/promise-with-resolvers'); + load('proposals/reflect-metadata'); + load('proposals/regexp-dotall-flag'); + load('proposals/regexp-escaping'); + load('proposals/regexp-named-groups'); + load('proposals/relative-indexing-method'); + load('proposals/seeded-random'); + load('proposals/set-methods'); + load('proposals/set-methods-v2'); + load('proposals/string-at'); + load('proposals/string-cooked'); + load('proposals/string-code-points'); + load('proposals/string-dedent'); + load('proposals/string-left-right-trim'); + load('proposals/string-match-all'); + load('proposals/string-padding'); + load('proposals/string-replace-all'); + load('proposals/string-replace-all-stage-4'); + load('proposals/symbol-description'); + load('proposals/symbol-predicates'); + load('proposals/symbol-predicates-v2'); + load('proposals/url'); + load('proposals/using-statement'); + load('proposals/well-formed-stringify'); + load('proposals/well-formed-unicode-strings'); + load('proposals'); + + ok(load('stage/4')); + ok(load('stage/3')); + ok(load('stage/2.7')); + ok(load('stage/2')); + ok(load('stage/1')); + ok(load('stage/0')); + ok(load('stage/pre')); + ok(load('stage')); + + ok(load('web/dom-exception')); + ok(load('web/dom-collections')); + ok(load('web/immediate')); + ok(load('web/queue-microtask')); + ok(load('web/structured-clone')(42) === 42); + ok(load('web/timers')); + ok(load('web/url')); + ok(load('web/url-search-params')); + ok(load('web')); + + for (const key in entries) { + if (key.startsWith('core-js/modules/')) { + load('modules', key.slice(16)); + } + } + + ok(load()); +} + +for (const NS of ['es', 'stable', 'actual', 'full', 'features']) { + ok(typeof load(NS, 'string/match') == 'function'); + ok('next' in load(NS, 'string/match-all')('a', /./g)); + ok(typeof load(NS, 'string/replace') == 'function'); + ok(typeof load(NS, 'string/search') == 'function'); + ok(load(NS, 'string/split')('a s d', ' ').length === 3); + ok(typeof load(NS, 'array-buffer') == 'function'); + ok(typeof load(NS, 'array-buffer/constructor') == 'function'); + ok(typeof load(NS, 'array-buffer/is-view') == 'function'); + load(NS, 'array-buffer/slice'); + load(NS, 'array-buffer/detached'); + load(NS, 'array-buffer/transfer'); + load(NS, 'array-buffer/transfer-to-fixed-length'); + ok(typeof load(NS, 'data-view') == 'function'); + load(NS, 'data-view/get-float16'); + load(NS, 'data-view/set-float16'); + ok(typeof load(NS, 'typed-array/int8-array') == 'function'); + ok(typeof load(NS, 'typed-array/uint8-array') == 'function'); + ok(typeof load(NS, 'typed-array/uint8-clamped-array') == 'function'); + ok(typeof load(NS, 'typed-array/int16-array') == 'function'); + ok(typeof load(NS, 'typed-array/uint16-array') == 'function'); + ok(typeof load(NS, 'typed-array/int32-array') == 'function'); + ok(typeof load(NS, 'typed-array/uint32-array') == 'function'); + ok(typeof load(NS, 'typed-array/float32-array') == 'function'); + ok(typeof load(NS, 'typed-array/float64-array') == 'function'); + load(NS, 'typed-array/at'); + load(NS, 'typed-array/copy-within'); + load(NS, 'typed-array/entries'); + load(NS, 'typed-array/every'); + load(NS, 'typed-array/fill'); + load(NS, 'typed-array/filter'); + load(NS, 'typed-array/find'); + load(NS, 'typed-array/find-index'); + load(NS, 'typed-array/find-last'); + load(NS, 'typed-array/find-last-index'); + load(NS, 'typed-array/for-each'); + load(NS, 'typed-array/from'); + load(NS, 'typed-array/from-base64'); + load(NS, 'typed-array/from-hex'); + load(NS, 'typed-array/includes'); + load(NS, 'typed-array/index-of'); + load(NS, 'typed-array/iterator'); + load(NS, 'typed-array/join'); + load(NS, 'typed-array/keys'); + load(NS, 'typed-array/last-index-of'); + load(NS, 'typed-array/map'); + load(NS, 'typed-array/of'); + load(NS, 'typed-array/reduce'); + load(NS, 'typed-array/reduce-right'); + load(NS, 'typed-array/reverse'); + load(NS, 'typed-array/set'); + load(NS, 'typed-array/set-from-base64'); + load(NS, 'typed-array/set-from-hex'); + load(NS, 'typed-array/slice'); + load(NS, 'typed-array/some'); + load(NS, 'typed-array/sort'); + load(NS, 'typed-array/subarray'); + load(NS, 'typed-array/to-base64'); + load(NS, 'typed-array/to-hex'); + load(NS, 'typed-array/to-locale-string'); + load(NS, 'typed-array/to-reversed'); + load(NS, 'typed-array/to-sorted'); + load(NS, 'typed-array/to-string'); + load(NS, 'typed-array/values'); + load(NS, 'typed-array/with'); + load(NS, 'typed-array/methods'); + ok(typeof load(NS, 'typed-array').Uint32Array == 'function'); +} + +for (const NS of ['actual', 'full', 'features']) { + load(NS, 'typed-array/to-spliced'); +} + +for (const NS of ['full', 'features']) { + load(NS, 'typed-array/from-async'); + load(NS, 'typed-array/filter-out'); + load(NS, 'typed-array/filter-reject'); + load(NS, 'typed-array/group-by'); + load(NS, 'typed-array/unique-by'); +} + +load('modules/esnext.string.at-alternative'); + +echo(chalk.green(`tested ${ chalk.cyan(tested.size) } commonjs entry points`)); + +if (expected.size) { + echo(chalk.red('not tested entries:')); + expected.forEach(it => echo(chalk.cyan(it))); +} diff --git a/tests/eslint/eslint.config.js b/tests/eslint/eslint.config.js new file mode 100644 index 000000000000..afbf2c47dbd0 --- /dev/null +++ b/tests/eslint/eslint.config.js @@ -0,0 +1,2609 @@ +import globals from 'globals'; +import confusingBrowserGlobals from 'confusing-browser-globals'; +import parserJSONC from 'jsonc-eslint-parser'; +import pluginArrayFunc from 'eslint-plugin-array-func'; +import pluginASCII from 'eslint-plugin-ascii'; +import pluginDepend from 'eslint-plugin-depend'; +import pluginESX from 'eslint-plugin-es-x'; +import pluginESlintComments from '@eslint-community/eslint-plugin-eslint-comments'; +import pluginFilename from 'eslint-plugin-filename'; +import pluginImport from 'eslint-plugin-import-x'; +import pluginJSONC from 'eslint-plugin-jsonc'; +import pluginMarkdown from '@eslint/markdown'; +import pluginMath from 'eslint-plugin-math'; +import pluginN from 'eslint-plugin-n'; +import pluginNodeDependencies from 'eslint-plugin-node-dependencies'; +import * as pluginPackageJSON from 'eslint-plugin-package-json'; +import pluginPlaywright from 'eslint-plugin-playwright'; +import pluginPromise from 'eslint-plugin-promise'; +import pluginQUnit from 'eslint-plugin-qunit'; +import pluginReDoS from 'eslint-plugin-redos'; +import pluginRegExp from 'eslint-plugin-regexp'; +import pluginSonarJS from 'eslint-plugin-sonarjs'; +import pluginStylistic from '@stylistic/eslint-plugin'; +import pluginUnicorn from 'eslint-plugin-unicorn'; +import { yaml as pluginYaml } from 'eslint-yaml'; + +// https://github.com/benyasin/eslint-plugin-filename/issues/1 +pluginFilename.rules.match.meta.schema = false; + +const PACKAGES_NODE_VERSIONS = '8.9.0'; +const DEV_NODE_VERSIONS = '^18.12'; + +const ERROR = 'error'; +const OFF = 'off'; +const ALWAYS = 'always'; +const NEVER = 'never'; +const READONLY = 'readonly'; + +function disable(rules) { + return Object.fromEntries(Object.keys(rules).map(key => [key, OFF])); +} + +const base = { + // possible problems: + // enforces return statements in callbacks of array's methods + 'array-callback-return': ERROR, + // require `super()` calls in constructors + 'constructor-super': ERROR, + // enforce 'for' loop update clause moving the counter in the right direction + 'for-direction': ERROR, + // disallow using an async function as a `Promise` executor + 'no-async-promise-executor': ERROR, + // disallow reassigning class members + 'no-class-assign': ERROR, + // disallow comparing against -0 + 'no-compare-neg-zero': ERROR, + // disallow reassigning `const` variables + 'no-const-assign': ERROR, + // disallows expressions where the operation doesn't affect the value + 'no-constant-binary-expression': ERROR, + // disallow constant expressions in conditions + 'no-constant-condition': [ERROR, { checkLoops: false }], + // disallow returning value from constructor + 'no-constructor-return': ERROR, + // disallow use of debugger + 'no-debugger': ERROR, + // disallow duplicate arguments in functions + 'no-dupe-args': ERROR, + // disallow duplicate class members + 'no-dupe-class-members': ERROR, + // disallow duplicate conditions in if-else-if chains + 'no-dupe-else-if': ERROR, + // disallow duplicate keys when creating object literals + 'no-dupe-keys': ERROR, + // disallow a duplicate case label + 'no-duplicate-case': ERROR, + // disallow duplicate module imports + 'no-duplicate-imports': ERROR, + // disallow empty destructuring patterns + 'no-empty-pattern': ERROR, + // disallow assigning to the exception in a catch block + 'no-ex-assign': ERROR, + // disallow fallthrough of case statements + 'no-fallthrough': [ERROR, { commentPattern: 'break omitted' }], + // disallow overwriting functions written as function declarations + 'no-func-assign': ERROR, + // disallow assigning to imported bindings + 'no-import-assign': ERROR, + // disallow irregular whitespace outside of strings and comments + 'no-irregular-whitespace': ERROR, + // disallow literal numbers that lose precision + 'no-loss-of-precision': ERROR, + // disallow `new` operators with global non-constructor functions + 'no-new-native-nonconstructor': ERROR, + // disallow the use of object properties of the global object (Math and JSON) as functions + 'no-obj-calls': ERROR, + // disallow use of Object.prototypes builtins directly + 'no-prototype-builtins': ERROR, + // disallow self assignment + 'no-self-assign': ERROR, + // disallow comparisons where both sides are exactly the same + 'no-self-compare': ERROR, + // disallow sparse arrays + 'no-sparse-arrays': ERROR, + // disallow template literal placeholder syntax in regular strings + 'no-template-curly-in-string': ERROR, + // disallow `this` / `super` before calling `super()` in constructors + 'no-this-before-super': ERROR, + // disallow `let` or `var` variables that are read but never assigned + 'no-unassigned-vars': ERROR, + // disallow use of undeclared variables unless mentioned in a /*global */ block + 'no-undef': [ERROR, { typeof: false }], + // avoid code that looks like two expressions but is actually one + 'no-unexpected-multiline': ERROR, + // disallow unmodified loop conditions + 'no-unmodified-loop-condition': ERROR, + // disallow unreachable statements after a return, throw, continue, or break statement + 'no-unreachable': ERROR, + // disallow loops with a body that allows only one iteration + 'no-unreachable-loop': ERROR, + // disallow control flow statements in `finally` blocks + 'no-unsafe-finally': ERROR, + // disallow negation of the left operand of an in expression + 'no-unsafe-negation': ERROR, + // disallow use of optional chaining in contexts where the `undefined` value is not allowed + 'no-unsafe-optional-chaining': ERROR, + // disallow unused private class members + 'no-unused-private-class-members': ERROR, + // disallow declaration of variables that are not used in the code + 'no-unused-vars': [ERROR, { + vars: 'all', + args: 'after-used', + caughtErrors: 'none', + ignoreRestSiblings: true, + }], + // disallow variable assignments when the value is not used + 'no-useless-assignment': ERROR, + // require or disallow the Unicode Byte Order Mark + 'unicode-bom': [ERROR, NEVER], + // disallow comparisons with the value NaN + 'use-isnan': ERROR, + // ensure that the results of typeof are compared against a valid string + 'valid-typeof': ERROR, + + // suggestions: + // enforce the use of variables within the scope they are defined + 'block-scoped-var': ERROR, + // require camel case names + camelcase: [ERROR, { + properties: NEVER, + ignoreDestructuring: true, + ignoreImports: true, + ignoreGlobals: true, + }], + // enforce default clauses in switch statements to be last + 'default-case-last': ERROR, + // enforce default parameters to be last + 'default-param-last': ERROR, + // encourages use of dot notation whenever possible + 'dot-notation': [ERROR, { allowKeywords: true }], + // require the use of === and !== + eqeqeq: [ERROR, 'smart'], + // require grouped accessor pairs in object literals and classes + 'grouped-accessor-pairs': [ERROR, 'getBeforeSet'], + // require identifiers to match a specified regular expression + 'id-match': [ERROR, '^[$A-Za-z]|(?:[A-Z][A-Z\\d_]*[A-Z\\d])|(?:[$A-Za-z]\\w*[A-Za-z\\d])$', { + onlyDeclarations: true, + ignoreDestructuring: true, + }], + // require logical assignment operator shorthand + 'logical-assignment-operators': [ERROR, ALWAYS], + // enforce a maximum depth that blocks can be nested + 'max-depth': [ERROR, { max: 5 }], + // enforce a maximum depth that callbacks can be nested + 'max-nested-callbacks': [ERROR, { max: 4 }], + // specify the maximum number of statement allowed in a function + 'max-statements': [ERROR, { max: 50 }], + // require a capital letter for constructors + 'new-cap': [ERROR, { newIsCap: true, capIsNew: false }], + // disallow window alert / confirm / prompt calls + 'no-alert': ERROR, + // disallow use of arguments.caller or arguments.callee + 'no-caller': ERROR, + // disallow lexical declarations in case/default clauses + 'no-case-declarations': ERROR, + // disallow use of console + 'no-console': ERROR, + // disallow deletion of variables + 'no-delete-var': ERROR, + // disallow else after a return in an if + 'no-else-return': [ERROR, { allowElseIf: false }], + // disallow empty statements + 'no-empty': ERROR, + // disallow empty functions, except for standalone funcs/arrows + 'no-empty-function': ERROR, + // disallow empty static blocks + 'no-empty-static-block': ERROR, + // disallow `null` comparisons without type-checking operators + 'no-eq-null': ERROR, + // disallow use of eval() + 'no-eval': ERROR, + // disallow adding to native types + 'no-extend-native': ERROR, + // disallow unnecessary function binding + 'no-extra-bind': ERROR, + // disallow unnecessary boolean casts + 'no-extra-boolean-cast': [ERROR, { enforceForInnerExpressions: true }], + // disallow unnecessary labels + 'no-extra-label': ERROR, + // disallow reassignments of native objects + 'no-global-assign': ERROR, + // disallow use of eval()-like methods + 'no-implied-eval': ERROR, + // disallow usage of __iterator__ property + 'no-iterator': ERROR, + // disallow labels that share a name with a variable + 'no-label-var': ERROR, + // disallow use of labels for anything other then loops and switches + 'no-labels': [ERROR, { allowLoop: false, allowSwitch: false }], + // disallow unnecessary nested blocks + 'no-lone-blocks': ERROR, + // disallow `if` as the only statement in an `else` block + 'no-lonely-if': ERROR, + // disallow function declarations and expressions inside loop statements + 'no-loop-func': OFF, + // disallow use of multiline strings + 'no-multi-str': ERROR, + // disallow use of new operator when not part of the assignment or comparison + 'no-new': ERROR, + // disallow use of new operator for Function object + 'no-new-func': ERROR, + // disallows creating new instances of String, Number, and Boolean + 'no-new-wrappers': ERROR, + // disallow `\8` and `\9` escape sequences in string literals + 'no-nonoctal-decimal-escape': ERROR, + // disallow calls to the `Object` constructor without an argument + 'no-object-constructor': ERROR, + // disallow use of (old style) octal literals + 'no-octal': ERROR, + // disallow use of octal escape sequences in string literals, such as var foo = 'Copyright \251'; + 'no-octal-escape': ERROR, + // disallow usage of __proto__ property + 'no-proto': ERROR, + // disallow declaring the same variable more then once + 'no-redeclare': [ERROR, { builtinGlobals: false }], + // disallow specific global variables + 'no-restricted-globals': [ERROR, ...confusingBrowserGlobals], + // disallow specified syntax + 'no-restricted-syntax': [ERROR, + { + selector: 'ForInStatement', + message: '`for-in` loops are disallowed since iterate over the prototype chain', + }, + ], + // disallow use of `javascript:` urls. + 'no-script-url': ERROR, + // disallow use of comma operator + 'no-sequences': ERROR, + // disallow declaration of variables already declared in the outer scope + 'no-shadow': ERROR, + // disallow shadowing of names such as arguments + 'no-shadow-restricted-names': ERROR, + // restrict what can be thrown as an exception + 'no-throw-literal': ERROR, + // disallow initializing variables to `undefined` + 'no-undef-init': ERROR, + // disallow dangling underscores in identifiers + 'no-underscore-dangle': ERROR, + // disallow the use of boolean literals in conditional expressions and prefer `a || b` over `a ? a : b` + 'no-unneeded-ternary': [ERROR, { defaultAssignment: false }], + // disallow usage of expressions in statement position + 'no-unused-expressions': [ERROR, { + allowShortCircuit: true, + allowTernary: true, + allowTaggedTemplates: true, + ignoreDirectives: true, + }], + // disallow unused labels + 'no-unused-labels': ERROR, + // disallow unnecessary calls to `.call()` and `.apply()` + 'no-useless-call': ERROR, + // disallow unnecessary catch clauses + 'no-useless-catch': ERROR, + // disallow unnecessary computed property keys in object literals + 'no-useless-computed-key': ERROR, + // disallow useless string concatenation + 'no-useless-concat': ERROR, + // disallow unnecessary constructors + 'no-useless-constructor': ERROR, + // disallow unnecessary escape characters + 'no-useless-escape': ERROR, + // disallow renaming import, export, and destructured assignments to the same name + 'no-useless-rename': ERROR, + // disallow redundant return statements + 'no-useless-return': ERROR, + // require let or const instead of var + 'no-var': ERROR, + // disallow void operators + 'no-void': ERROR, + // disallow use of the with statement + 'no-with': ERROR, + // require or disallow method and property shorthand syntax for object literals + 'object-shorthand': ERROR, + // require assignment operator shorthand where possible + 'operator-assignment': [ERROR, 'always'], + // require using arrow functions for callbacks + 'prefer-arrow-callback': ERROR, + // require const declarations for variables that are never reassigned after declared + 'prefer-const': [ERROR, { destructuring: 'all' }], + // require destructuring from arrays and/or objects + 'prefer-destructuring': [ERROR, { + VariableDeclarator: { + array: true, + object: true, + }, + AssignmentExpression: { + array: true, + object: false, + }, + }, { + enforceForRenamedProperties: false, + }], + // prefer the exponentiation operator over `Math.pow()` + 'prefer-exponentiation-operator': ERROR, + // disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals + 'prefer-numeric-literals': ERROR, + // prefer `Object.hasOwn` + 'prefer-object-has-own': ERROR, + // disallow use of the `RegExp` constructor in favor of regular expression literals + 'prefer-regex-literals': [ERROR, { disallowRedundantWrapping: true }], + // require rest parameters instead of `arguments` + 'prefer-rest-params': ERROR, + // require spread operators instead of `.apply()` + 'prefer-spread': ERROR, + // require template literals instead of string concatenation + 'prefer-template': ERROR, + // require use of the second argument for parseInt() + radix: ERROR, + // disallow generator functions that do not have `yield` + 'require-yield': ERROR, + // require strict mode directives + strict: [ERROR, 'global'], + // require symbol descriptions + 'symbol-description': ERROR, + // disallow "Yoda" conditions + yoda: [ERROR, NEVER], + + // layout & formatting: + // enforce spacing inside array brackets + '@stylistic/array-bracket-spacing': [ERROR, NEVER], + // require parentheses around arrow function arguments + '@stylistic/arrow-parens': [ERROR, 'as-needed'], + // enforce consistent spacing before and after the arrow in arrow functions + '@stylistic/arrow-spacing': ERROR, + // enforce spacing inside single-line blocks + '@stylistic/block-spacing': [ERROR, ALWAYS], + // enforce one true brace style + '@stylistic/brace-style': [ERROR, '1tbs', { allowSingleLine: true }], + // enforce trailing commas in multiline object literals + '@stylistic/comma-dangle': [ERROR, 'always-multiline'], + // enforce spacing after comma + '@stylistic/comma-spacing': ERROR, + // enforce one true comma style + '@stylistic/comma-style': [ERROR, 'last'], + // disallow padding inside computed properties + '@stylistic/computed-property-spacing': [ERROR, NEVER], + // enforce consistent line breaks after opening and before closing braces + '@stylistic/curly-newline': [ERROR, { consistent: true }], + // enforce newline before and after dot + '@stylistic/dot-location': [ERROR, 'property'], + // enforce one newline at the end of files + '@stylistic/eol-last': [ERROR, ALWAYS], + // disallow space between function identifier and application + '@stylistic/function-call-spacing': ERROR, + // require spacing around the `*` in `function *` expressions + '@stylistic/generator-star-spacing': [ERROR, 'both'], + // enforce the location of arrow function bodies + '@stylistic/implicit-arrow-linebreak': [ERROR, 'beside'], + // enforce consistent indentation + '@stylistic/indent': [ERROR, 2, { + ignoredNodes: ['ConditionalExpression'], + SwitchCase: 1, + VariableDeclarator: 'first', + }], + // enforces spacing between keys and values in object literal properties + '@stylistic/key-spacing': [ERROR, { beforeColon: false, afterColon: true }], + // require a space before & after certain keywords + '@stylistic/keyword-spacing': [ERROR, { before: true, after: true }], + // enforce consistent linebreak style + '@stylistic/linebreak-style': [ERROR, 'unix'], + // specify the maximum length of a line in your program + '@stylistic/max-len': [ERROR, { + code: 140, + tabWidth: 2, + ignoreRegExpLiterals: true, + ignoreTemplateLiterals: true, + ignoreUrls: true, + ignorePattern: '', + }], + // enforce a maximum number of statements allowed per line + '@stylistic/max-statements-per-line': [ERROR, { max: 2 }], + // require parentheses when invoking a constructor with no arguments + '@stylistic/new-parens': ERROR, + // disallow unnecessary semicolons + '@stylistic/no-extra-semi': ERROR, + // disallow the use of leading or trailing decimal points in numeric literals + '@stylistic/no-floating-decimal': ERROR, + // disallow mixed spaces and tabs for indentation + '@stylistic/no-mixed-spaces-and-tabs': ERROR, + // disallow use of multiple spaces + '@stylistic/no-multi-spaces': [ERROR, { ignoreEOLComments: true }], + // disallow multiple empty lines and only one newline at the end + '@stylistic/no-multiple-empty-lines': [ERROR, { max: 1, maxEOF: 1 }], + // disallow tabs + '@stylistic/no-tabs': ERROR, + // disallow trailing whitespace at the end of lines + '@stylistic/no-trailing-spaces': ERROR, + // disallow whitespace before properties + '@stylistic/no-whitespace-before-property': ERROR, + // enforce the location of single-line statements + '@stylistic/nonblock-statement-body-position': [ERROR, 'beside'], + // enforce consistent line breaks after opening and before closing braces + '@stylistic/object-curly-newline': [ERROR, { consistent: true }], + // enforce spaces inside braces + '@stylistic/object-curly-spacing': [ERROR, ALWAYS], + // require newlines around variable declarations with initializations + '@stylistic/one-var-declaration-per-line': [ERROR, 'initializations'], + // enforce padding within blocks + '@stylistic/padded-blocks': [ERROR, NEVER], + // disallow blank lines after 'use strict' + '@stylistic/padding-line-between-statements': [ERROR, { blankLine: NEVER, prev: 'directive', next: '*' }], + // require or disallow use of quotes around object literal property names + '@stylistic/quote-props': [ERROR, 'as-needed', { keywords: false }], + // specify whether double or single quotes should be used + '@stylistic/quotes': [ERROR, 'single', { avoidEscape: true }], + // enforce spacing between rest and spread operators and their expressions + '@stylistic/rest-spread-spacing': ERROR, + // require or disallow use of semicolons instead of ASI + '@stylistic/semi': [ERROR, ALWAYS], + // enforce spacing before and after semicolons + '@stylistic/semi-spacing': ERROR, + // enforce location of semicolons + '@stylistic/semi-style': [ERROR, 'last'], + // require or disallow space before blocks + '@stylistic/space-before-blocks': ERROR, + // require or disallow space before function opening parenthesis + '@stylistic/space-before-function-paren': [ERROR, { anonymous: ALWAYS, named: NEVER }], + // require or disallow spaces inside parentheses + '@stylistic/space-in-parens': ERROR, + // require spaces around operators + '@stylistic/space-infix-ops': ERROR, + // require or disallow spaces before/after unary operators + '@stylistic/space-unary-ops': ERROR, + // require or disallow a space immediately following the // or /* in a comment + '@stylistic/spaced-comment': [ERROR, ALWAYS, { + line: { exceptions: ['/'] }, + block: { exceptions: ['*'] }, + }], + // enforce spacing around colons of switch statements + '@stylistic/switch-colon-spacing': ERROR, + // require or disallow spacing around embedded expressions of template strings + '@stylistic/template-curly-spacing': [ERROR, ALWAYS], + // disallow spacing between template tags and their literals + '@stylistic/template-tag-spacing': [ERROR, NEVER], + // require spacing around the `*` in `yield *` expressions + '@stylistic/yield-star-spacing': [ERROR, 'both'], + + // ascii + // forbid non-ascii chars in ast node names + 'ascii/valid-name': ERROR, + + // import: + // forbid any invalid exports, i.e. re-export of the same name + 'import/export': ERROR, + // ensure all imports appear before other statements + 'import/first': ERROR, + // enforce a newline after import statements + 'import/newline-after-import': ERROR, + // forbid import of modules using absolute paths + 'import/no-absolute-path': ERROR, + // forbid AMD imports + 'import/no-amd': ERROR, + // forbid cycle dependencies + 'import/no-cycle': [ERROR, { commonjs: true }], + // disallow importing from the same path more than once + 'import/no-duplicates': ERROR, + // forbid `require()` calls with expressions + 'import/no-dynamic-require': ERROR, + // forbid empty named import blocks + 'import/no-empty-named-blocks': ERROR, + // forbid imports with CommonJS exports + 'import/no-import-module-exports': ERROR, + // forbid a module from importing itself + 'import/no-self-import': ERROR, + // ensure imports point to files / modules that can be resolved + 'import/no-unresolved': [ERROR, { commonjs: true }], + // forbid useless path segments + 'import/no-useless-path-segments': ERROR, + // forbid Webpack loader syntax in imports + 'import/no-webpack-loader-syntax': ERROR, + + // node: + // enforce the style of file extensions in `import` declarations + 'node/file-extension-in-import': ERROR, + // require require() calls to be placed at top-level module scope + 'node/global-require': ERROR, + // disallow deprecated APIs + 'node/no-deprecated-api': ERROR, + // disallow the assignment to `exports` + 'node/no-exports-assign': ERROR, + // disallow require calls to be mixed with regular variable declarations + 'node/no-mixed-requires': [ERROR, { grouping: true, allowCall: false }], + // disallow new operators with calls to require + 'node/no-new-require': ERROR, + // disallow string concatenation with `__dirname` and `__filename` + 'node/no-path-concat': ERROR, + // disallow the use of `process.exit()` + 'node/no-process-exit': ERROR, + // disallow synchronous methods + 'node/no-sync': ERROR, + // prefer `node:` protocol + 'node/prefer-node-protocol': ERROR, + // prefer global + 'node/prefer-global/buffer': [ERROR, ALWAYS], + 'node/prefer-global/console': [ERROR, ALWAYS], + 'node/prefer-global/process': [ERROR, ALWAYS], + 'node/prefer-global/text-decoder': [ERROR, ALWAYS], + 'node/prefer-global/text-encoder': [ERROR, ALWAYS], + 'node/prefer-global/url-search-params': [ERROR, ALWAYS], + 'node/prefer-global/url': [ERROR, ALWAYS], + // prefer promises + 'node/prefer-promises/dns': ERROR, + 'node/prefer-promises/fs': ERROR, + + // array-func: + // avoid reversing the array and running a method on it if there is an equivalent of the method operating on the array from the other end + 'array-func/avoid-reverse': ERROR, + // prefer using the `mapFn` callback of `Array.from` over an immediate `.map()` call on the `Array.from` result + 'array-func/from-map': ERROR, + // avoid the `this` parameter when providing arrow function as callback in array functions + 'array-func/no-unnecessary-this-arg': ERROR, + + // promise: + // enforces the use of `catch()` on un-returned promises + 'promise/catch-or-return': ERROR, + // avoid calling `cb()` inside of a `then()` or `catch()` + 'promise/no-callback-in-promise': ERROR, + // disallow creating new promises with paths that resolve multiple times + 'promise/no-multiple-resolved': ERROR, + // avoid nested `then()` or `catch()` statements + 'promise/no-nesting': ERROR, + // avoid calling new on a `Promise` static method + 'promise/no-new-statics': ERROR, + // avoid using promises inside of callbacks + 'promise/no-promise-in-callback': ERROR, + // disallow return statements in `finally()` + 'promise/no-return-in-finally': ERROR, + // avoid wrapping values in `Promise.resolve` or `Promise.reject` when not needed + 'promise/no-return-wrap': ERROR, + // enforce consistent param names when creating new promises + 'promise/param-names': [ERROR, { + resolvePattern: '^resolve', + rejectPattern: '^reject', + }], + // prefer `async` / `await` to the callback pattern + 'promise/prefer-await-to-callbacks': ERROR, + // prefer `await` to `then()` / `catch()` / `finally()` for reading `Promise` values + 'promise/prefer-await-to-then': [ERROR, { strict: true }], + // prefer catch to `then(a, b)` / `then(null, b)` for handling errors + 'promise/prefer-catch': ERROR, + // disallow use of non-standard `Promise` static methods + 'promise/spec-only': [OFF, { allowedMethods: [ + 'prototype', // `eslint-plugin-promise` bug, https://github.com/eslint-community/eslint-plugin-promise/issues/533 + 'try', + 'undefined', // `eslint-plugin-promise` bug, https://github.com/eslint-community/eslint-plugin-promise/issues/534 + ] }], + // ensures the proper number of arguments are passed to `Promise` functions + 'promise/valid-params': ERROR, + + // unicorn + // enforce a specific parameter name in `catch` clauses + 'unicorn/catch-error-name': [ERROR, { name: ERROR, ignore: [/^err/] }], + // enforce consistent assertion style with `node:assert` + 'unicorn/consistent-assert': ERROR, + // prefer passing `Date` directly to the constructor when cloning + 'unicorn/consistent-date-clone': ERROR, + // prefer consistent types when spreading a ternary in an array literal + 'unicorn/consistent-empty-array-spread': ERROR, + // enforce consistent style for element existence checks with `indexOf()`, `lastIndexOf()`, `findIndex()`, and `findLastIndex()` + 'unicorn/consistent-existence-index-check': ERROR, + // enforce correct `Error` subclassing + 'unicorn/custom-error-definition': ERROR, + // enforce passing a message value when throwing a built-in error + 'unicorn/error-message': ERROR, + // require escape sequences to use uppercase values + 'unicorn/escape-case': [ERROR, 'uppercase'], + // enforce a case style for filenames + 'unicorn/filename-case': [ERROR, { case: 'kebabCase' }], + // enforce specifying rules to disable in `eslint-disable` comments + 'unicorn/no-abusive-eslint-disable': ERROR, + // disallow recursive access to `this` within getters and setters + 'unicorn/no-accessor-recursion': ERROR, + // prefer `Array#toReversed()` over `Array#reverse()` + 'unicorn/no-array-reverse': ERROR, + // disallow using `await` in `Promise` method parameters + 'unicorn/no-await-in-promise-methods': ERROR, + // do not use leading/trailing space between `console.log` parameters + 'unicorn/no-console-spaces': ERROR, + // enforce the use of unicode escapes instead of hexadecimal escapes + 'unicorn/no-hex-escape': ERROR, + // disallow immediate mutation after variable assignment + // that cause problems with objects in ES3 syntax, but since unicorn team + // don't wanna add an option to allow it, manually disable this rule in such problem cases + // https://github.com/sindresorhus/eslint-plugin-unicorn/issues/2796 + 'unicorn/no-immediate-mutation': ERROR, + // disallow `instanceof` with built-in objects + 'unicorn/no-instanceof-builtins': [ERROR, { strategy: 'loose' }], + // disallow invalid options in `fetch` and `Request` + 'unicorn/no-invalid-fetch-options': ERROR, + // prevent calling `EventTarget#removeEventListener()` with the result of an expression + 'unicorn/no-invalid-remove-event-listener': ERROR, + // disallow `if` statements as the only statement in `if` blocks without `else` + 'unicorn/no-lonely-if': ERROR, + // disallow named usage of default import and export + 'unicorn/no-named-default': ERROR, + // disallow negated expression in equality check + 'unicorn/no-negation-in-equality-check': ERROR, + // enforce the use of `Buffer.from()` and `Buffer.alloc()` instead of the deprecated `new Buffer()` + 'unicorn/no-new-buffer': ERROR, + // disallow passing single-element arrays to `Promise` methods + 'unicorn/no-single-promise-in-promise-methods': ERROR, + // forbid classes that only have static members + 'unicorn/no-static-only-class': ERROR, + // disallow `then` property + 'unicorn/no-thenable': ERROR, + // disallow comparing `undefined` using `typeof` when it's not required + 'unicorn/no-typeof-undefined': ERROR, + // disallow using 1 as the depth argument of `Array#flat()` + 'unicorn/no-unnecessary-array-flat-depth': ERROR, + // disallow using `.length` or `Infinity` as the `deleteCount` or `skipCount` argument of `Array#{ splice, toSpliced }()` + 'unicorn/no-unnecessary-array-splice-count': ERROR, + // disallow awaiting non-promise values + 'unicorn/no-unnecessary-await': ERROR, + // disallow using `.length` or `Infinity` as the end argument of `{ Array, String, %TypedArray% }#slice()` + 'unicorn/no-unnecessary-slice-end': ERROR, + // disallow unreadable array destructuring + 'unicorn/no-unreadable-array-destructuring': ERROR, + // disallow unreadable IIFEs + 'unicorn/no-unreadable-iife': ERROR, + // disallow unused object properties + 'unicorn/no-unused-properties': ERROR, + // disallow useless values or fallbacks in `Set`, `Map`, `WeakSet`, or `WeakMap` + 'unicorn/no-useless-collection-argument': ERROR, + // disallow unnecessary `Error.captureStackTrace()` + 'unicorn/no-useless-error-capture-stack-trace': ERROR, + // forbid useless fallback when spreading in object literals + 'unicorn/no-useless-fallback-in-spread': ERROR, + // disallow useless array length check + 'unicorn/no-useless-length-check': ERROR, + // disallow returning / yielding `Promise.{ resolve, reject }` in async functions or promise callbacks + 'unicorn/no-useless-promise-resolve-reject': ERROR, + // disallow useless spread + 'unicorn/no-useless-spread': ERROR, + // disallow useless `case` in `switch` statements + 'unicorn/no-useless-switch-case': ERROR, + // enforce lowercase identifier and uppercase value for number literals + 'unicorn/number-literal-case': [ERROR, { hexadecimalValue: 'uppercase' }], + // enforce the style of numeric separators by correctly grouping digits + 'unicorn/numeric-separators-style': [ERROR, { + onlyIfContainsSeparator: true, + number: { minimumDigits: 0, groupLength: 3 }, + binary: { minimumDigits: 0, groupLength: 4 }, + octal: { minimumDigits: 0, groupLength: 4 }, + hexadecimal: { minimumDigits: 0, groupLength: 2 }, + }], + // prefer `.find()` over the first element from `.filter()` + 'unicorn/prefer-array-find': [ERROR, { checkFromLast: true }], + // use `.flat()` to flatten an array of arrays + 'unicorn/prefer-array-flat': ERROR, + // use `.flatMap()` to map and then flatten an array instead of using `.map().flat()` + 'unicorn/prefer-array-flat-map': ERROR, + // prefer `Array#indexOf` over `Array#findIndex`` when looking for the index of an item + 'unicorn/prefer-array-index-of': ERROR, + // prefer `.some()` over `.filter().length` check and `.find()` + 'unicorn/prefer-array-some': ERROR, + // prefer `.at()` method for index access and `String#charAt()` + 'unicorn/prefer-at': [ERROR, { checkAllIndexAccess: false }], + // prefer `BigInt` literals over the constructor + 'unicorn/prefer-bigint-literals': ERROR, + // prefer `Blob#{ arrayBuffer, text }` over `FileReader#{ readAsArrayBuffer, readAsText }` + 'unicorn/prefer-blob-reading-methods': ERROR, + // prefer class field declarations over this assignments in constructors + 'unicorn/prefer-class-fields': ERROR, + // prefer using `Element#classList.toggle()` to toggle class names + 'unicorn/prefer-classlist-toggle': ERROR, + // prefer `Date.now()` to get the number of milliseconds since the Unix Epoch + 'unicorn/prefer-date-now': ERROR, + // prefer default parameters over reassignment + 'unicorn/prefer-default-parameters': ERROR, + // prefer `EventTarget` over `EventEmitter` + 'unicorn/prefer-event-target': ERROR, + // prefer `globalThis` over `window`, `self`, and `global` + 'unicorn/prefer-global-this': ERROR, + // prefer `.includes()` over `.indexOf()` and `Array#some()` when checking for existence or non-existence + 'unicorn/prefer-includes': ERROR, + // prefer reading a `JSON` file as a buffer + 'unicorn/prefer-json-parse-buffer': ERROR, + // prefer using a logical operator over a ternary + 'unicorn/prefer-logical-operator-over-ternary': ERROR, + // prefer `Math.min()` and `Math.max()` over ternaries for simple comparisons + 'unicorn/prefer-math-min-max': ERROR, + // prefer modern `Math` APIs over legacy patterns + 'unicorn/prefer-modern-math-apis': ERROR, + // prefer negative index over `.length - index` when possible + 'unicorn/prefer-negative-index': ERROR, + // prefer using the `node:` protocol when importing Node builtin modules + 'unicorn/prefer-node-protocol': ERROR, + // prefer using `Object.fromEntries()` to transform a list of key-value pairs into an object + 'unicorn/prefer-object-from-entries': ERROR, + // prefer omitting the `catch` binding parameter + 'unicorn/prefer-optional-catch-binding': ERROR, + // prefer `Response.json()` over `new Response(JSON.stringify())` + 'unicorn/prefer-response-static-json': ERROR, + // prefer using `structuredClone` to create a deep clone + 'unicorn/prefer-structured-clone': ERROR, + // prefer using `Set#size` instead of `Array#length` + 'unicorn/prefer-set-size': ERROR, + // enforce combining multiple `Array#push`, `Element#classList.{ add, remove }()` or `importScripts` into one call + 'unicorn/prefer-single-call': ERROR, + // prefer `String#replaceAll()` over regex searches with the global flag + 'unicorn/prefer-string-replace-all': ERROR, + // prefer `String#{ startsWith, endsWith }()` over `RegExp#test()` + 'unicorn/prefer-string-starts-ends-with': ERROR, + // prefer `String#{ trimStart, trimEnd }()` over `String#{ trimLeft, trimRight }()` + 'unicorn/prefer-string-trim-start-end': ERROR, + // prefer `switch` over multiple `else-if` + 'unicorn/prefer-switch': [ERROR, { minimumCases: 3 }], + // enforce consistent relative `URL` style + 'unicorn/relative-url-style': [ERROR, ALWAYS], + // enforce using the separator argument with `Array#join()` + 'unicorn/require-array-join-separator': ERROR, + // require non-empty specifier list in import and export statements + 'unicorn/require-module-specifiers': ERROR, + // enforce using the digits argument with `Number#toFixed()` + 'unicorn/require-number-to-fixed-digits-argument': ERROR, + // enforce using the `targetOrigin`` argument with `window.postMessage()` + 'unicorn/require-post-message-target-origin': ERROR, + // forbid braces for case clauses + 'unicorn/switch-case-braces': [ERROR, 'avoid'], + // fix whitespace-insensitive template indentation + 'unicorn/template-indent': OFF, // waiting for `String.dedent` + // enforce consistent case for text encoding identifiers + 'unicorn/text-encoding-identifier-case': ERROR, + // require `new` when throwing an error + 'unicorn/throw-new-error': ERROR, + + // sonarjs + // alternatives in regular expressions should be grouped when used with anchors + 'sonarjs/anchor-precedence': ERROR, + // arguments to built-in functions should match documented types + 'sonarjs/argument-type': OFF, // it seems does not work + // bitwise operators should not be used in boolean contexts + 'sonarjs/bitwise-operators': ERROR, + // function call arguments should not start on new lines + 'sonarjs/call-argument-line': ERROR, + // class names should comply with a naming convention + 'sonarjs/class-name': [ERROR, { format: '^[A-Z$][a-zA-Z0-9]*$' }], + // comma and logical `OR` operators should not be used in switch cases + 'sonarjs/comma-or-logical-or-case': ERROR, + // cyclomatic complexity of functions should not be too high + 'sonarjs/cyclomatic-complexity': [OFF, { threshold: 16 }], + // expressions should not be too complex + 'sonarjs/expression-complexity': [OFF, { max: 3 }], + // `in` should not be used with primitive types + 'sonarjs/in-operator-type-error': ERROR, + // functions should be called consistently with or without `new` + 'sonarjs/inconsistent-function-call': ERROR, + // `new` should only be used with functions and classes + 'sonarjs/new-operator-misuse': [ERROR, { considerJSDoc: false }], + // `Array#{ sort, toSorted }` should use a compare function + 'sonarjs/no-alphabetical-sort': ERROR, + // `delete` should not be used on arrays + 'sonarjs/no-array-delete': ERROR, + // array indexes should be numeric + 'sonarjs/no-associative-arrays': ERROR, + // `switch` statements should not contain non-case labels + 'sonarjs/no-case-label-in-switch': ERROR, + // collection sizes and array length comparisons should make sense + 'sonarjs/no-collection-size-mischeck': ERROR, + // two branches in a conditional structure should not have exactly the same implementation + 'sonarjs/no-duplicated-branches': ERROR, + // collection elements should not be replaced unconditionally + 'sonarjs/no-element-overwrite': ERROR, + // empty collections should not be accessed or iterated + 'sonarjs/no-empty-collection': ERROR, + // function calls should not pass extra arguments + 'sonarjs/no-extra-arguments': ERROR, + // `for-in` should not be used with iterables + 'sonarjs/no-for-in-iterable': ERROR, + // global `this` object should not be used + 'sonarjs/no-global-this': ERROR, + // boolean expressions should not be gratuitous + 'sonarjs/no-gratuitous-expressions': ERROR, + // `in` should not be used on arrays + 'sonarjs/no-in-misuse': ERROR, + // strings and non-strings should not be added + 'sonarjs/no-incorrect-string-concat': ERROR, + // function returns should not be invariant + 'sonarjs/no-invariant-returns': ERROR, + // literals should not be used as functions + 'sonarjs/no-literal-call': ERROR, + // array-mutating methods should not be used misleadingly + 'sonarjs/no-misleading-array-reverse': ERROR, + // assignments should not be redundant + 'sonarjs/no-redundant-assignments': ERROR, + // boolean literals should not be redundant + 'sonarjs/no-redundant-boolean': ERROR, + // jump statements should not be redundant + 'sonarjs/no-redundant-jump': ERROR, + // redundant pairs of parentheses should be removed + 'sonarjs/no-redundant-parentheses': ERROR, + // variables should be defined before being used + 'sonarjs/no-reference-error': ERROR, + // conditionals should start on new lines + 'sonarjs/no-same-line-conditional': ERROR, + // `switch` statements should have at least 3 `case` clauses + 'sonarjs/no-small-switch': ERROR, + // promise rejections should not be caught by `try` blocks + 'sonarjs/no-try-promise': ERROR, + // `undefined` should not be passed as the value of optional parameters + 'sonarjs/no-undefined-argument': ERROR, + // errors should not be created without being thrown + 'sonarjs/no-unthrown-error': ERROR, + // collection and array contents should be used + 'sonarjs/no-unused-collection': ERROR, + // the output of functions that don't return anything should not be used + 'sonarjs/no-use-of-empty-return-value': ERROR, + // values should not be uselessly incremented + 'sonarjs/no-useless-increment': ERROR, + // non-existent operators `=+`, `=-` and `=!` should not be used + 'sonarjs/non-existent-operator': ERROR, + // properties of variables with `null` or `undefined` values should not be accessed + 'sonarjs/null-dereference': ERROR, // it seems does not work + // arithmetic operations should not result in `NaN` + 'sonarjs/operation-returning-nan': ERROR, + // local variables should not be declared and then immediately returned or thrown + 'sonarjs/prefer-immediate-return': ERROR, + // object literal syntax should be used + 'sonarjs/prefer-object-literal': ERROR, + // shorthand promises should be used + 'sonarjs/prefer-promise-shorthand': ERROR, + // return of boolean expressions should not be wrapped into an `if-then-else` statement + 'sonarjs/prefer-single-boolean-return': ERROR, + // a `while` loop should be used instead of a `for` loop with condition only + 'sonarjs/prefer-while': ERROR, + // using slow regular expressions is security-sensitive + 'sonarjs/slow-regex': ERROR, + // regular expressions with the global flag should be used with caution + 'sonarjs/stateful-regex': ERROR, + // comparison operators should not be used with strings + 'sonarjs/strings-comparison': ERROR, + // `super()` should be invoked appropriately + 'sonarjs/super-invocation': ERROR, + // results of operations on strings should not be ignored + 'sonarjs/useless-string-operation': ERROR, + // values not convertible to numbers should not be used in numeric comparisons + 'sonarjs/values-not-convertible-to-numbers': ERROR, + + // math + // enforce the conversion to absolute values to be the method you prefer + 'math/abs': [ERROR, { prefer: 'Math.abs' }], + // disallow static calculations that go to infinity + 'math/no-static-infinity-calculations': ERROR, + // disallow static calculations that go to `NaN` + 'math/no-static-nan-calculations': ERROR, + // enforce the use of exponentiation (`**`) operator instead of other calculations + 'math/prefer-exponentiation-operator': ERROR, + // enforce the use of `Math.cbrt()` instead of other cube root calculations + 'math/prefer-math-cbrt': ERROR, + // enforce the use of `Math.E` instead of other ways + 'math/prefer-math-e': ERROR, + // enforce the use of `Math.hypot()` instead of other hypotenuse calculations + 'math/prefer-math-hypot': ERROR, + // enforce the use of `Math.LN10` instead of other ways + 'math/prefer-math-ln10': ERROR, + // enforce the use of `Math.LN2` instead of other ways + 'math/prefer-math-ln2': ERROR, + // enforce the use of `Math.log10` instead of other ways + 'math/prefer-math-log10': ERROR, + // enforce the use of `Math.LOG10E` instead of other ways + 'math/prefer-math-log10e': ERROR, + // enforce the use of `Math.log2` instead of other ways + 'math/prefer-math-log2': ERROR, + // enforce the use of `Math.LOG2E` instead of other ways + 'math/prefer-math-log2e': ERROR, + // enforce the use of `Math.PI` instead of literal number + 'math/prefer-math-pi': ERROR, + // enforce the use of `Math.sqrt()` instead of other square root calculations + 'math/prefer-math-sqrt': ERROR, + // enforce the use of `Math.SQRT1_2` instead of other ways + 'math/prefer-math-sqrt1-2': ERROR, + // enforce the use of `Math.SQRT2` instead of other ways + 'math/prefer-math-sqrt2': ERROR, + // enforce the use of `Math.sumPrecise()` instead of other summation methods + 'math/prefer-math-sum-precise': ERROR, + // enforce the use of `Math.trunc()` instead of other truncations + 'math/prefer-math-trunc': [ERROR, { reportBitwise: false }], + // enforce the use of `Number.EPSILON` instead of other ways + 'math/prefer-number-epsilon': ERROR, + // enforce the use of `Number.isFinite()` instead of other checking ways + 'math/prefer-number-is-finite': ERROR, + // enforce the use of `Number.isInteger()` instead of other checking ways + 'math/prefer-number-is-integer': ERROR, + // enforce the use of `Number.isNaN()` instead of other checking ways + 'math/prefer-number-is-nan': ERROR, + // enforce the use of `Number.isSafeInteger()` instead of other checking ways + 'math/prefer-number-is-safe-integer': ERROR, + // enforce the use of `Number.MAX_SAFE_INTEGER` instead of other ways + 'math/prefer-number-max-safe-integer': ERROR, + // enforce the use of `Number.MAX_VALUE` instead of literal number + 'math/prefer-number-max-value': ERROR, + // enforce the use of `Number.MIN_SAFE_INTEGER` instead of other ways + 'math/prefer-number-min-safe-integer': ERROR, + // enforce the use of `Number.MIN_VALUE` instead of literal number + 'math/prefer-number-min-value': ERROR, + + // regexp + // disallow confusing quantifiers + 'regexp/confusing-quantifier': ERROR, + // enforce consistent escaping of control characters + 'regexp/control-character-escape': ERROR, + // enforce single grapheme in string literal + 'regexp/grapheme-string-literal': ERROR, + // enforce consistent usage of hexadecimal escape + 'regexp/hexadecimal-escape': [ERROR, NEVER], + // enforce into your favorite case + 'regexp/letter-case': [ERROR, { + caseInsensitive: 'lowercase', + unicodeEscape: 'uppercase', + }], + // enforce match any character style + 'regexp/match-any': [ERROR, { allows: ['[\\S\\s]', 'dotAll'] }], + // enforce use of escapes on negation + 'regexp/negation': ERROR, + // disallow elements that contradict assertions + 'regexp/no-contradiction-with-assertion': ERROR, + // disallow control characters + 'regexp/no-control-character': ERROR, + // disallow duplicate characters in the RegExp character class + 'regexp/no-dupe-characters-character-class': ERROR, + // disallow duplicate disjunctions + 'regexp/no-dupe-disjunctions': [ERROR, { report: 'all' }], + // disallow alternatives without elements + 'regexp/no-empty-alternative': ERROR, + // disallow capturing group that captures empty + 'regexp/no-empty-capturing-group': ERROR, + // disallow character classes that match no characters + 'regexp/no-empty-character-class': ERROR, + // disallow empty group + 'regexp/no-empty-group': ERROR, + // disallow empty lookahead assertion or empty lookbehind assertion + 'regexp/no-empty-lookarounds-assertion': ERROR, + // reports empty string literals in character classes + 'regexp/no-empty-string-literal': ERROR, + // disallow escape backspace `([\b])` + 'regexp/no-escape-backspace': ERROR, + // disallow unnecessary nested lookaround assertions + 'regexp/no-extra-lookaround-assertions': ERROR, + // disallow invalid regular expression strings in RegExp constructors + 'regexp/no-invalid-regexp': ERROR, + // disallow invisible raw character + 'regexp/no-invisible-character': ERROR, + // disallow lazy quantifiers at the end of an expression + 'regexp/no-lazy-ends': ERROR, + // disallow legacy RegExp features + 'regexp/no-legacy-features': ERROR, + // disallow capturing groups that do not behave as one would expect + 'regexp/no-misleading-capturing-group': ERROR, + // disallow multi-code-point characters in character classes and quantifiers + 'regexp/no-misleading-unicode-character': ERROR, + // disallow missing `g` flag in patterns used in `String#matchAll` and `String#replaceAll` + 'regexp/no-missing-g-flag': ERROR, + // disallow non-standard flags + 'regexp/no-non-standard-flag': ERROR, + // disallow obscure character ranges + 'regexp/no-obscure-range': ERROR, + // disallow octal escape sequence + 'regexp/no-octal': ERROR, + // disallow optional assertions + 'regexp/no-optional-assertion': ERROR, + // disallow backreferences that reference a group that might not be matched + 'regexp/no-potentially-useless-backreference': ERROR, + // disallow standalone backslashes + 'regexp/no-standalone-backslash': ERROR, + // disallow trivially nested assertions + 'regexp/no-trivially-nested-assertion': ERROR, + // disallow nested quantifiers that can be rewritten as one quantifier + 'regexp/no-trivially-nested-quantifier': ERROR, + // disallow unused capturing group + 'regexp/no-unused-capturing-group': ERROR, + // disallow assertions that are known to always accept (or reject) + 'regexp/no-useless-assertions': ERROR, + // disallow useless backreferences in regular expressions + 'regexp/no-useless-backreference': ERROR, + // disallow character class with one character + 'regexp/no-useless-character-class': ERROR, + // disallow useless `$` replacements in replacement string + 'regexp/no-useless-dollar-replacements': ERROR, + // disallow unnecessary string escaping + 'regexp/no-useless-escape': ERROR, + // disallow unnecessary regex flags + 'regexp/no-useless-flag': ERROR, + // disallow unnecessarily non-greedy quantifiers + 'regexp/no-useless-lazy': ERROR, + // disallow unnecessary non-capturing group + 'regexp/no-useless-non-capturing-group': ERROR, + // disallow quantifiers that can be removed + 'regexp/no-useless-quantifier': ERROR, + // disallow unnecessary range of characters by using a hyphen + 'regexp/no-useless-range': ERROR, + // reports any unnecessary set operands + 'regexp/no-useless-set-operand': ERROR, + // reports the string alternatives of a single character in `\q{...}`, it can be placed outside `\q{...}` + 'regexp/no-useless-string-literal': ERROR, + // disallow unnecessary `{n,m}`` quantifier + 'regexp/no-useless-two-nums-quantifier': ERROR, + // disallow quantifiers with a maximum of zero + 'regexp/no-zero-quantifier': ERROR, + // disallow the alternatives of lookarounds that end with a non-constant quantifier + 'regexp/optimal-lookaround-quantifier': ERROR, + // require optimal quantifiers for concatenated quantifiers + 'regexp/optimal-quantifier-concatenation': ERROR, + // enforce using character class + 'regexp/prefer-character-class': ERROR, + // enforce using `\d` + 'regexp/prefer-d': ERROR, + // enforces escape of replacement `$` character (`$$`) + 'regexp/prefer-escape-replacement-dollar-char': ERROR, + // prefer lookarounds over capturing group that do not replace + 'regexp/prefer-lookaround': [ERROR, { lookbehind: true, strictTypes: true }], + // enforce using named backreferences + 'regexp/prefer-named-backreference': ERROR, + // enforce using named capture group in regular expression + 'regexp/prefer-named-capture-group': ERROR, + // enforce using named replacement + 'regexp/prefer-named-replacement': ERROR, + // enforce using `+` quantifier + 'regexp/prefer-plus-quantifier': ERROR, + // prefer predefined assertion over equivalent lookarounds + 'regexp/prefer-predefined-assertion': ERROR, + // enforce using quantifier + 'regexp/prefer-quantifier': ERROR, + // enforce using `?` quantifier + 'regexp/prefer-question-quantifier': ERROR, + // enforce using character class range + 'regexp/prefer-range': [ERROR, { target: 'alphanumeric' }], + // enforce that `RegExp#exec` is used instead of `String#match` if no global flag is provided + 'regexp/prefer-regexp-exec': ERROR, + // enforce that `RegExp#test` is used instead of `String#match` and `RegExp#exec` + 'regexp/prefer-regexp-test': ERROR, + // enforce using result array `.groups`` + 'regexp/prefer-result-array-groups': ERROR, + // enforce using `*` quantifier + 'regexp/prefer-star-quantifier': ERROR, + // enforce use of unicode codepoint escapes + 'regexp/prefer-unicode-codepoint-escapes': ERROR, + // enforce using `\w` + 'regexp/prefer-w': ERROR, + // aims to optimize patterns by simplifying set operations in character classes (with v flag) + 'regexp/simplify-set-operations': ERROR, + // sort alternatives if order doesn't matter + 'regexp/sort-alternatives': ERROR, + // enforces elements order in character class + 'regexp/sort-character-class-elements': ERROR, + // require regex flags to be sorted + 'regexp/sort-flags': ERROR, + // disallow not strictly valid regular expressions + 'regexp/strict': ERROR, + // enforce consistent usage of unicode escape or unicode codepoint escape + 'regexp/unicode-escape': ERROR, + // use the `i` flag if it simplifies the pattern + 'regexp/use-ignore-case': ERROR, + // ReDoS vulnerability check + 'redos/no-vulnerable': [ERROR, { timeout: 1e3 }], + + // disallow function declarations in if statement clauses without using blocks + 'es/no-function-declarations-in-if-statement-clauses-without-block': ERROR, + // disallow initializers in for-in heads + 'es/no-initializers-in-for-in': ERROR, + // disallow \u2028 and \u2029 in string literals + 'es/no-json-superset': ERROR, + // disallow labelled function declarations + 'es/no-labelled-function-declarations': ERROR, + // disallow the `RegExp.prototype.compile` method + 'es/no-regexp-prototype-compile': ERROR, + + // eslint-comments: + // disallow duplicate `eslint-disable` comments + 'eslint-comments/no-duplicate-disable': ERROR, + // disallow `eslint-disable` comments without rule names + 'eslint-comments/no-unlimited-disable': ERROR, + // disallow unused `eslint-disable` comments + // it's clearly disabled since result of some rules (like `redos/no-vulnerable`) is non-deterministic + // and anyway it's reported because of `reportUnusedDisableDirectives` option + 'eslint-comments/no-unused-disable': OFF, + // disallow unused `eslint-enable` comments + 'eslint-comments/no-unused-enable': ERROR, + // require include descriptions in eslint directive-comments + 'eslint-comments/require-description': ERROR, + + // suggest better alternatives to some dependencies + 'depend/ban-dependencies': [ERROR, { allowed: [ + 'mkdirp', // TODO: drop from `core-js@4` + ] }], +}; + +const noAsyncAwait = { + // prefer `async` / `await` to the callback pattern + 'promise/prefer-await-to-callbacks': OFF, + // prefer `await` to `then()` / `catch()` / `finally()` for reading `Promise` values + 'promise/prefer-await-to-then': OFF, +}; + +const useES3Syntax = { + ...noAsyncAwait, + // encourages use of dot notation whenever possible + 'dot-notation': [ERROR, { allowKeywords: false }], + // disallow logical assignment operator shorthand + 'logical-assignment-operators': [ERROR, NEVER], + // disallow function or variable declarations in nested blocks + 'no-inner-declarations': ERROR, + // disallow specified syntax + 'no-restricted-syntax': OFF, + // require let or const instead of var + 'no-var': OFF, + // require or disallow method and property shorthand syntax for object literals + 'object-shorthand': OFF, + // require using arrow functions for callbacks + 'prefer-arrow-callback': OFF, + // require const declarations for variables that are never reassigned after declared + 'prefer-const': OFF, + // require destructuring from arrays and/or objects + 'prefer-destructuring': OFF, + // prefer the exponentiation operator over `Math.pow()` + 'prefer-exponentiation-operator': OFF, + // require rest parameters instead of `arguments` + 'prefer-rest-params': OFF, + // require spread operators instead of `.apply()` + 'prefer-spread': OFF, + // require template literals instead of string concatenation + 'prefer-template': OFF, + // disallow trailing commas in multiline object literals + '@stylistic/comma-dangle': [ERROR, NEVER], + // require or disallow use of quotes around object literal property names + '@stylistic/quote-props': [ERROR, 'as-needed', { keywords: true }], + // enforce the use of exponentiation (`**`) operator instead of other calculations + 'math/prefer-exponentiation-operator': OFF, + // prefer lookarounds over capturing group that do not replace + 'regexp/prefer-lookaround': [ERROR, { lookbehind: false, strictTypes: true }], + // enforce using named capture group in regular expression + 'regexp/prefer-named-capture-group': OFF, + // prefer class field declarations over this assignments in constructors + 'unicorn/prefer-class-fields': OFF, + // prefer default parameters over reassignment + 'unicorn/prefer-default-parameters': OFF, + // prefer using a logical operator over a ternary + 'unicorn/prefer-logical-operator-over-ternary': OFF, + // prefer omitting the `catch` binding parameter + 'unicorn/prefer-optional-catch-binding': OFF, +}; + +const forbidNonStandardBuiltIns = { + // disallow non-standard built-in methods + 'es/no-nonstandard-array-properties': ERROR, + 'es/no-nonstandard-array-prototype-properties': ERROR, + 'es/no-nonstandard-arraybuffer-properties': ERROR, + 'es/no-nonstandard-arraybuffer-prototype-properties': ERROR, + 'es/no-nonstandard-asyncdisposablestack-properties': ERROR, + 'es/no-nonstandard-asyncdisposablestack-prototype-properties': ERROR, + 'es/no-nonstandard-atomics-properties': ERROR, + 'es/no-nonstandard-bigint-properties': ERROR, + 'es/no-nonstandard-bigint-prototype-properties': ERROR, + 'es/no-nonstandard-boolean-properties': ERROR, + 'es/no-nonstandard-boolean-prototype-properties': ERROR, + 'es/no-nonstandard-dataview-properties': ERROR, + 'es/no-nonstandard-dataview-prototype-properties': ERROR, + 'es/no-nonstandard-date-properties': ERROR, + 'es/no-nonstandard-date-prototype-properties': ERROR, + 'es/no-nonstandard-disposablestack-properties': ERROR, + 'es/no-nonstandard-disposablestack-prototype-properties': ERROR, + 'es/no-nonstandard-error-properties': ERROR, + 'es/no-nonstandard-finalizationregistry-properties': ERROR, + 'es/no-nonstandard-finalizationregistry-prototype-properties': ERROR, + 'es/no-nonstandard-function-properties': ERROR, + 'es/no-nonstandard-intl-collator-properties': ERROR, + 'es/no-nonstandard-intl-collator-prototype-properties': ERROR, + 'es/no-nonstandard-intl-datetimeformat-properties': ERROR, + 'es/no-nonstandard-intl-datetimeformat-prototype-properties': ERROR, + 'es/no-nonstandard-intl-displaynames-properties': ERROR, + 'es/no-nonstandard-intl-displaynames-prototype-properties': ERROR, + 'es/no-nonstandard-intl-listformat-properties': ERROR, + 'es/no-nonstandard-intl-listformat-prototype-properties': ERROR, + 'es/no-nonstandard-intl-locale-properties': ERROR, + 'es/no-nonstandard-intl-locale-prototype-properties': ERROR, + 'es/no-nonstandard-intl-numberformat-properties': ERROR, + 'es/no-nonstandard-intl-numberformat-prototype-properties': ERROR, + 'es/no-nonstandard-intl-pluralrules-properties': ERROR, + 'es/no-nonstandard-intl-pluralrules-prototype-properties': ERROR, + 'es/no-nonstandard-intl-properties': ERROR, + 'es/no-nonstandard-intl-relativetimeformat-properties': ERROR, + 'es/no-nonstandard-intl-relativetimeformat-prototype-properties': ERROR, + 'es/no-nonstandard-intl-segmenter-properties': ERROR, + 'es/no-nonstandard-intl-segmenter-prototype-properties': ERROR, + 'es/no-nonstandard-iterator-properties': ERROR, + 'es/no-nonstandard-iterator-prototype-properties': ERROR, + 'es/no-nonstandard-json-properties': ERROR, + 'es/no-nonstandard-map-properties': ERROR, + 'es/no-nonstandard-map-prototype-properties': ERROR, + 'es/no-nonstandard-math-properties': ERROR, + 'es/no-nonstandard-number-properties': ERROR, + 'es/no-nonstandard-number-prototype-properties': ERROR, + 'es/no-nonstandard-object-properties': ERROR, + 'es/no-nonstandard-promise-properties': ERROR, + 'es/no-nonstandard-promise-prototype-properties': ERROR, + 'es/no-nonstandard-proxy-properties': ERROR, + 'es/no-nonstandard-reflect-properties': ERROR, + 'es/no-nonstandard-regexp-properties': ERROR, + 'es/no-nonstandard-regexp-prototype-properties': ERROR, + 'es/no-nonstandard-set-properties': ERROR, + 'es/no-nonstandard-set-prototype-properties': ERROR, + 'es/no-nonstandard-sharedarraybuffer-properties': ERROR, + 'es/no-nonstandard-sharedarraybuffer-prototype-properties': ERROR, + 'es/no-nonstandard-string-properties': ERROR, + 'es/no-nonstandard-string-prototype-properties': ERROR, + 'es/no-nonstandard-symbol-properties': [ERROR, { allow: [ + 'sham', // non-standard flag + ] }], + 'es/no-nonstandard-symbol-prototype-properties': ERROR, + 'es/no-nonstandard-typed-array-properties': ERROR, + 'es/no-nonstandard-typed-array-prototype-properties': ERROR, + 'es/no-nonstandard-weakmap-properties': ERROR, + 'es/no-nonstandard-weakmap-prototype-properties': ERROR, + 'es/no-nonstandard-weakref-properties': ERROR, + 'es/no-nonstandard-weakref-prototype-properties': ERROR, + 'es/no-nonstandard-weakset-properties': ERROR, + 'es/no-nonstandard-weakset-prototype-properties': ERROR, +}; + +const forbidCompletelyNonExistentBuiltIns = { + ...forbidNonStandardBuiltIns, + // disallow non-standard built-in methods + 'es/no-nonstandard-array-properties': [ERROR, { allow: [ + 'isTemplateObject', + ] }], + 'es/no-nonstandard-array-prototype-properties': [ERROR, { allow: [ + 'filterReject', + 'uniqueBy', + // TODO: drop from `core-js@4` + 'filterOut', + 'group', + 'groupBy', + 'groupByToMap', + 'groupToMap', + 'lastIndex', + 'lastItem', + ] }], + 'es/no-nonstandard-bigint-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'range', + ] }], + 'es/no-nonstandard-dataview-prototype-properties': [ERROR, { allow: [ + 'getUint8Clamped', + 'setUint8Clamped', + ] }], + 'es/no-nonstandard-function-properties': [ERROR, { allow: [ + 'isCallable', + 'isConstructor', + ] }], + 'es/no-nonstandard-iterator-properties': [ERROR, { allow: [ + 'range', + 'zip', + 'zipKeyed', + ] }], + 'es/no-nonstandard-iterator-prototype-properties': [ERROR, { allow: [ + 'chunks', + 'sliding', + 'toAsync', + 'windows', + // TODO: drop from `core-js@4` + 'asIndexedPairs', + 'indexed', + ] }], + 'es/no-nonstandard-map-properties': [ERROR, { allow: [ + 'from', + 'of', + // TODO: drop from `core-js@4` + 'keyBy', + ] }], + 'es/no-nonstandard-map-prototype-properties': [ERROR, { allow: [ + 'getOrInsert', + 'getOrInsertComputed', + // TODO: drop from `core-js@4` + 'deleteAll', + 'emplace', + 'every', + 'filter', + 'find', + 'findKey', + 'includes', + 'keyOf', + 'mapKeys', + 'mapValues', + 'merge', + 'reduce', + 'some', + 'update', + 'updateOrInsert', + 'upsert', + ] }], + 'es/no-nonstandard-math-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'DEG_PER_RAD', + 'RAD_PER_DEG', + 'clamp', + 'degrees', + 'fscale', + 'iaddh', + 'imulh', + 'isubh', + 'radians', + 'scale', + 'seededPRNG', + 'signbit', + 'umulh', + ] }], + 'es/no-nonstandard-number-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'fromString', + 'range', + ] }], + 'es/no-nonstandard-number-prototype-properties': [ERROR, { allow: [ + 'clamp', + ] }], + 'es/no-nonstandard-object-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'iterateEntries', + 'iterateKeys', + 'iterateValues', + ] }], + 'es/no-nonstandard-reflect-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'defineMetadata', + 'deleteMetadata', + 'getMetadata', + 'getMetadataKeys', + 'getOwnMetadata', + 'getOwnMetadataKeys', + 'hasMetadata', + 'hasOwnMetadata', + 'metadata', + ] }], + 'es/no-nonstandard-set-properties': [ERROR, { allow: [ + 'from', + 'of', + ] }], + 'es/no-nonstandard-set-prototype-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'addAll', + 'deleteAll', + 'every', + 'filter', + 'find', + 'join', + 'map', + 'reduce', + 'some', + ] }], + 'es/no-nonstandard-string-properties': [ERROR, { allow: [ + 'cooked', + 'dedent', + ] }], + 'es/no-nonstandard-string-prototype-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'codePoints', + ] }], + 'es/no-nonstandard-symbol-properties': [ERROR, { allow: [ + 'customMatcher', + 'isRegisteredSymbol', + 'isWellKnownSymbol', + 'metadata', + 'sham', // non-standard flag + // TODO: drop from `core-js@4` + 'isRegistered', + 'isWellKnown', + 'matcher', + 'metadataKey', + 'observable', + 'patternMatch', + 'replaceAll', + 'useSetter', + 'useSimple', + ] }], + 'es/no-nonstandard-typed-array-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'fromAsync', + ] }], + 'es/no-nonstandard-typed-array-prototype-properties': [ERROR, { allow: [ + 'filterReject', + 'uniqueBy', + // TODO: drop from `core-js@4` + 'filterOut', + 'groupBy', + ] }], + 'es/no-nonstandard-weakmap-properties': [ERROR, { allow: [ + 'from', + 'of', + ] }], + 'es/no-nonstandard-weakmap-prototype-properties': [ERROR, { allow: [ + 'getOrInsert', + 'getOrInsertComputed', + // TODO: drop from `core-js@4` + 'deleteAll', + 'emplace', + 'upsert', + ] }], + 'es/no-nonstandard-weakset-properties': [ERROR, { allow: [ + 'from', + 'of', + ] }], + 'es/no-nonstandard-weakset-prototype-properties': [ERROR, { allow: [ + // TODO: drop from `core-js@4` + 'addAll', + 'deleteAll', + ] }], +}; + +const forbidESAnnexBBuiltIns = { + 'es/no-date-prototype-getyear-setyear': ERROR, + 'es/no-date-prototype-togmtstring': ERROR, + 'es/no-escape-unescape': ERROR, + 'es/no-legacy-object-prototype-accessor-methods': ERROR, + 'es/no-string-create-html-methods': ERROR, + 'es/no-string-prototype-trimleft-trimright': ERROR, + // prefer `String#slice` over `String#{ substr, substring }` + 'unicorn/prefer-string-slice': ERROR, +}; + +const forbidES5BuiltIns = { + 'es/no-array-isarray': ERROR, + 'es/no-array-prototype-every': ERROR, + 'es/no-array-prototype-filter': ERROR, + 'es/no-array-prototype-foreach': ERROR, + 'es/no-array-prototype-indexof': ERROR, + 'es/no-array-prototype-lastindexof': ERROR, + 'es/no-array-prototype-map': ERROR, + 'es/no-array-prototype-reduce': ERROR, + 'es/no-array-prototype-reduceright': ERROR, + 'es/no-array-prototype-some': ERROR, + 'es/no-date-now': ERROR, + 'es/no-function-prototype-bind': ERROR, + 'es/no-json': ERROR, + 'es/no-object-create': ERROR, + 'es/no-object-defineproperties': ERROR, + 'es/no-object-defineproperty': ERROR, + 'es/no-object-freeze': ERROR, + 'es/no-object-getownpropertydescriptor': ERROR, + 'es/no-object-getownpropertynames': ERROR, + 'es/no-object-getprototypeof': ERROR, + 'es/no-object-isextensible': ERROR, + 'es/no-object-isfrozen': ERROR, + 'es/no-object-issealed': ERROR, + 'es/no-object-keys': ERROR, + 'es/no-object-preventextensions': ERROR, + 'es/no-object-seal': ERROR, + 'es/no-string-prototype-trim': ERROR, + // prefer `Date.now()` to get the number of milliseconds since the Unix Epoch + 'unicorn/prefer-date-now': OFF, + // prefer `globalThis` over `window`, `self`, and `global` + 'unicorn/prefer-global-this': OFF, +}; + +const forbidES2015BuiltIns = { + 'es/no-array-from': ERROR, + 'es/no-array-of': ERROR, + 'es/no-array-prototype-copywithin': ERROR, + 'es/no-array-prototype-entries': ERROR, + 'es/no-array-prototype-fill': ERROR, + 'es/no-array-prototype-find': ERROR, + 'es/no-array-prototype-findindex': ERROR, + 'es/no-array-prototype-keys': ERROR, + 'es/no-array-prototype-values': ERROR, + 'es/no-map': ERROR, + 'es/no-math-acosh': ERROR, + 'es/no-math-asinh': ERROR, + 'es/no-math-atanh': ERROR, + 'es/no-math-cbrt': ERROR, + 'es/no-math-clz32': ERROR, + 'es/no-math-cosh': ERROR, + 'es/no-math-expm1': ERROR, + 'es/no-math-fround': ERROR, + 'es/no-math-hypot': ERROR, + 'es/no-math-imul': ERROR, + 'es/no-math-log10': ERROR, + 'es/no-math-log1p': ERROR, + 'es/no-math-log2': ERROR, + 'es/no-math-sign': ERROR, + 'es/no-math-sinh': ERROR, + 'es/no-math-tanh': ERROR, + 'es/no-math-trunc': ERROR, + 'es/no-number-epsilon': ERROR, + 'es/no-number-isfinite': ERROR, + 'es/no-number-isinteger': ERROR, + 'es/no-number-isnan': ERROR, + 'es/no-number-issafeinteger': ERROR, + 'es/no-number-maxsafeinteger': ERROR, + 'es/no-number-minsafeinteger': ERROR, + 'es/no-number-parsefloat': ERROR, + 'es/no-number-parseint': ERROR, + 'es/no-object-assign': ERROR, + 'es/no-object-getownpropertysymbols': ERROR, + 'es/no-object-is': ERROR, + 'es/no-object-setprototypeof': ERROR, + 'es/no-promise': ERROR, + 'es/no-proxy': ERROR, + 'es/no-reflect': ERROR, + 'es/no-regexp-prototype-flags': ERROR, + 'es/no-set': ERROR, + 'es/no-string-fromcodepoint': ERROR, + 'es/no-string-prototype-codepointat': ERROR, + 'es/no-string-prototype-endswith': ERROR, + 'es/no-string-prototype-includes': ERROR, + 'es/no-string-prototype-normalize': ERROR, + 'es/no-string-prototype-repeat': ERROR, + 'es/no-string-prototype-startswith': ERROR, + 'es/no-string-raw': ERROR, + 'es/no-symbol': ERROR, + 'es/no-typed-arrays': ERROR, + 'es/no-weak-map': ERROR, + 'es/no-weak-set': ERROR, + // enforce the use of `Math.cbrt()` instead of other cube root calculations + 'math/prefer-math-cbrt': OFF, + // enforce the use of `Math.hypot()` instead of other hypotenuse calculations + 'math/prefer-math-hypot': OFF, + // enforce the use of `Math.log10` instead of other ways + 'math/prefer-math-log10': OFF, + // enforce the use of `Math.log10` instead of other ways + 'math/prefer-math-log2': OFF, + // enforce the use of `Math.trunc()` instead of other truncations + 'math/prefer-math-trunc': OFF, + // enforce the use of `Number.EPSILON` instead of other ways + 'math/prefer-number-epsilon': OFF, + // enforce the use of `Number.isFinite()` instead of other checking ways + 'math/prefer-number-is-finite': OFF, + // enforce the use of `Number.isInteger()` instead of other checking ways + 'math/prefer-number-is-integer': OFF, + // enforce the use of `Number.isNaN()` instead of other checking ways + 'math/prefer-number-is-nan': OFF, + // enforce the use of `Number.isSafeInteger()` instead of other checking ways + 'math/prefer-number-is-safe-integer': OFF, + // enforce the use of `Number.MAX_SAFE_INTEGER` instead of other ways + 'math/prefer-number-max-safe-integer': OFF, + // enforce the use of `Number.MIN_SAFE_INTEGER` instead of other ways + 'math/prefer-number-min-safe-integer': OFF, + // prefer modern `Math` APIs over legacy patterns + 'unicorn/prefer-modern-math-apis': OFF, + // prefer `String#{ startsWith, endsWith }()` over `RegExp#test()` + 'unicorn/prefer-string-starts-ends-with': OFF, +}; + +const forbidES2016BuiltIns = { + 'es/no-array-prototype-includes': ERROR, + // prefer `.includes()` over `.indexOf()` and `Array#some()` when checking for existence or non-existence + 'unicorn/prefer-includes': OFF, +}; + +const forbidES2017BuiltIns = { + 'es/no-atomics': ERROR, + 'es/no-object-entries': ERROR, + 'es/no-object-getownpropertydescriptors': ERROR, + 'es/no-object-values': ERROR, + 'es/no-shared-array-buffer': ERROR, + 'es/no-string-prototype-padstart-padend': ERROR, +}; + +const forbidES2018BuiltIns = { + 'es/no-promise-prototype-finally': ERROR, +}; + +const forbidES2019BuiltIns = { + 'es/no-array-prototype-flat': ERROR, + 'es/no-object-fromentries': ERROR, + 'es/no-string-prototype-trimstart-trimend': ERROR, + 'es/no-symbol-prototype-description': ERROR, + // use `.flat()` to flatten an array of arrays + 'unicorn/prefer-array-flat': OFF, + // prefer using `Object.fromEntries()` to transform a list of key-value pairs into an object + 'unicorn/prefer-object-from-entries': OFF, + // prefer `String#{ trimStart, trimEnd }()` over `String#{ trimLeft, trimRight }()` + 'unicorn/prefer-string-trim-start-end': OFF, +}; + +const forbidES2020BuiltIns = { + 'es/no-bigint': ERROR, + 'es/no-global-this': ERROR, + 'es/no-promise-all-settled': ERROR, + 'es/no-regexp-unicode-property-escapes-2020': ERROR, + 'es/no-string-prototype-matchall': ERROR, + 'es/no-symbol-matchall': ERROR, + // prefer `BigInt` literals over the constructor + 'unicorn/prefer-bigint-literals': OFF, +}; + +const forbidES2021BuiltIns = { + 'es/no-promise-any': ERROR, + 'es/no-regexp-unicode-property-escapes-2021': ERROR, + 'es/no-string-prototype-replaceall': ERROR, + 'es/no-weakrefs': ERROR, + // prefer `String#replaceAll()` over regex searches with the global flag + 'unicorn/prefer-string-replace-all': OFF, +}; + +const forbidES2022BuiltIns = { + // prefer `Object.hasOwn` + 'prefer-object-has-own': OFF, + 'es/no-array-prototype-at': ERROR, + 'es/no-error-cause': ERROR, + 'es/no-object-hasown': ERROR, + 'es/no-regexp-d-flag': ERROR, + 'es/no-regexp-unicode-property-escapes-2022': ERROR, + 'es/no-string-prototype-at': ERROR, + // prefer `.at()` method for index access and `String#charAt()` + 'unicorn/prefer-at': OFF, +}; + +const forbidES2023BuiltIns = { + 'es/no-array-prototype-findlast-findlastindex': ERROR, + 'es/no-array-prototype-toreversed': ERROR, + 'es/no-array-prototype-tosorted': ERROR, + 'es/no-array-prototype-tospliced': ERROR, + 'es/no-array-prototype-with': ERROR, + 'es/no-regexp-unicode-property-escapes-2023': ERROR, + // prefer `Array#toReversed()` over `Array#reverse()` + 'unicorn/no-array-reverse': OFF, +}; + +const forbidES2024BuiltIns = { + 'es/no-arraybuffer-prototype-transfer': ERROR, + 'es/no-atomics-waitasync': ERROR, + 'es/no-map-groupby': ERROR, + 'es/no-object-groupby': ERROR, + 'es/no-promise-withresolvers': ERROR, + 'es/no-regexp-v-flag': ERROR, + 'es/no-resizable-and-growable-arraybuffers': ERROR, + 'es/no-string-prototype-iswellformed': ERROR, + 'es/no-string-prototype-towellformed': ERROR, +}; + +const forbidES2025BuiltIns = { + 'es/no-dataview-prototype-getfloat16-setfloat16': ERROR, + 'es/no-float16array': ERROR, + 'es/no-iterator': ERROR, + 'es/no-iterator-prototype-drop': ERROR, + 'es/no-iterator-prototype-every': ERROR, + 'es/no-iterator-prototype-filter': ERROR, + 'es/no-iterator-prototype-find': ERROR, + 'es/no-iterator-prototype-flatmap': ERROR, + 'es/no-iterator-prototype-foreach': ERROR, + 'es/no-iterator-prototype-map': ERROR, + 'es/no-iterator-prototype-reduce': ERROR, + 'es/no-iterator-prototype-some': ERROR, + 'es/no-iterator-prototype-take': ERROR, + 'es/no-iterator-prototype-toarray': ERROR, + 'es/no-math-f16round': ERROR, + 'es/no-promise-try': ERROR, + 'es/no-set-prototype-difference': ERROR, + 'es/no-set-prototype-intersection': ERROR, + 'es/no-set-prototype-isdisjointfrom': ERROR, + 'es/no-set-prototype-issubsetof': ERROR, + 'es/no-set-prototype-issupersetof': ERROR, + 'es/no-set-prototype-symmetricdifference': ERROR, + 'es/no-set-prototype-union': ERROR, +}; + +const forbidES2026BuiltIns = { + 'es/no-array-fromasync': ERROR, + 'es/no-asyncdisposablestack': ERROR, + 'es/no-error-iserror': ERROR, + 'es/no-iterator-concat': ERROR, + 'es/no-json-israwjson': ERROR, + 'es/no-json-parse-reviver-context-parameter': ERROR, + 'es/no-json-rawjson': ERROR, + 'es/no-math-sumprecise': ERROR, + 'es/no-suppressederror': ERROR, + 'es/no-symbol-asyncdispose': ERROR, + 'es/no-symbol-dispose': ERROR, + 'es/no-uint8array-frombase64': ERROR, + 'es/no-uint8array-fromhex': ERROR, + 'es/no-uint8array-prototype-setfrombase64': ERROR, + 'es/no-uint8array-prototype-setfromhex': ERROR, + 'es/no-uint8array-prototype-tobase64': ERROR, + 'es/no-uint8array-prototype-tohex': ERROR, + // enforce the use of `Math.sumPrecise` instead of other summation methods + 'math/prefer-math-sum-precise': OFF, +}; + +const forbidES2016IntlBuiltIns = { + 'es/no-intl-getcanonicallocales': ERROR, +}; + +const forbidES2017IntlBuiltIns = { + 'es/no-intl-datetimeformat-prototype-formattoparts': ERROR, +}; + +const forbidES2018IntlBuiltIns = { + 'es/no-intl-numberformat-prototype-formattoparts': ERROR, + 'es/no-intl-pluralrules': ERROR, +}; + +const forbidES2020IntlBuiltIns = { + 'es/no-intl-locale': ERROR, + 'es/no-intl-relativetimeformat': ERROR, +}; + +const forbidES2021IntlBuiltIns = { + 'es/no-intl-datetimeformat-prototype-formatrange': ERROR, + 'es/no-intl-displaynames': ERROR, + 'es/no-intl-listformat': ERROR, +}; + +const forbidES2022IntlBuiltIns = { + 'es/no-intl-segmenter': ERROR, + 'es/no-intl-supportedvaluesof': ERROR, +}; + +const forbidES2023IntlBuiltIns = { + 'es/no-intl-numberformat-prototype-formatrange': ERROR, + 'es/no-intl-numberformat-prototype-formatrangetoparts': ERROR, + 'es/no-intl-pluralrules-prototype-selectrange': ERROR, +}; + +const forbidES2025IntlBuiltIns = { + 'es/no-intl-durationformat': ERROR, +}; + +const forbidES2026IntlBuiltIns = { + 'es/no-intl-locale-prototype-firstdayofweek': ERROR, + 'es/no-intl-locale-prototype-getcalendars': ERROR, + 'es/no-intl-locale-prototype-getcollations': ERROR, + 'es/no-intl-locale-prototype-gethourcycles': ERROR, + 'es/no-intl-locale-prototype-getnumberingsystems': ERROR, + 'es/no-intl-locale-prototype-gettextinfo': ERROR, + 'es/no-intl-locale-prototype-gettimezones': ERROR, + 'es/no-intl-locale-prototype-getweekinfo': ERROR, +}; + +const forbidSomeES2025Syntax = { + 'es/no-regexp-duplicate-named-capturing-groups': ERROR, + 'es/no-regexp-modifiers': ERROR, + 'es/no-import-attributes': ERROR, + 'es/no-dynamic-import-options': ERROR, + 'es/no-trailing-dynamic-import-commas': ERROR, + 'es/no-json-modules': ERROR, +}; + +const forbidModernBuiltIns = { + ...forbidESAnnexBBuiltIns, + ...forbidES5BuiltIns, + ...forbidES2015BuiltIns, + ...forbidES2016BuiltIns, + ...forbidES2017BuiltIns, + ...forbidES2018BuiltIns, + ...forbidES2019BuiltIns, + ...forbidES2020BuiltIns, + ...forbidES2021BuiltIns, + ...forbidES2022BuiltIns, + ...forbidES2023BuiltIns, + ...forbidES2024BuiltIns, + ...forbidES2025BuiltIns, + ...forbidES2026BuiltIns, + ...forbidES2016IntlBuiltIns, + ...forbidES2017IntlBuiltIns, + ...forbidES2018IntlBuiltIns, + ...forbidES2020IntlBuiltIns, + ...forbidES2021IntlBuiltIns, + ...forbidES2022IntlBuiltIns, + ...forbidES2023IntlBuiltIns, + ...forbidES2025IntlBuiltIns, + // prefer using `structuredClone` to create a deep clone + 'unicorn/prefer-structured-clone': OFF, +}; + +const polyfills = { + // prefer `node:` protocol + 'node/prefer-node-protocol': OFF, + // enforces the use of `catch()` on un-returned promises + 'promise/catch-or-return': OFF, + // avoid nested `then()` or `catch()` statements + 'promise/no-nesting': OFF, + // prefer catch to `then(a, b)` / `then(null, b)` for handling errors + 'promise/prefer-catch': OFF, + // prefer `RegExp#test()` over `String#match()` and `RegExp#exec()` + // use `RegExp#exec()` since it does not have implicit calls under the hood + 'regexp/prefer-regexp-test': OFF, + // shorthand promises should be used + 'sonarjs/prefer-promise-shorthand': OFF, + // disallow `instanceof` with built-in objects + 'unicorn/no-instanceof-builtins': OFF, +}; + +const transpiledAndPolyfilled = { + ...noAsyncAwait, + // disallow accessor properties + 'es/no-accessor-properties': ERROR, + // disallow async functions + 'es/no-async-functions': ERROR, + // disallow async iteration + 'es/no-async-iteration': ERROR, + // disallow generators + 'es/no-generators': ERROR, + // disallow top-level `await` + 'es/no-top-level-await': ERROR, + // unpolyfillable es2015 builtins + 'es/no-proxy': ERROR, + // disallow duplicate named capture groups + 'es/no-regexp-duplicate-named-capturing-groups': OFF, + 'es/no-string-prototype-normalize': ERROR, + // unpolyfillable es2017 builtins + 'es/no-atomics': ERROR, + 'es/no-shared-array-buffer': ERROR, + // unpolyfillable es2020 builtins + 'es/no-bigint': ERROR, + // unpolyfillable es2021 builtins + 'es/no-weakrefs': ERROR, + // prefer lookarounds over capturing group that do not replace + 'regexp/prefer-lookaround': [ERROR, { lookbehind: false, strictTypes: true }], + // enforce using named capture group in regular expression + 'regexp/prefer-named-capture-group': OFF, + // prefer `BigInt` literals over the constructor + 'unicorn/prefer-bigint-literals': OFF, + ...forbidSomeES2025Syntax, + ...forbidCompletelyNonExistentBuiltIns, +}; + +const nodePackages = { + // disallow logical assignment operator shorthand + 'logical-assignment-operators': [ERROR, NEVER], + // disallow unsupported ECMAScript built-ins on the specified version + 'node/no-unsupported-features/node-builtins': [ERROR, { version: PACKAGES_NODE_VERSIONS, allowExperimental: false }], + // prefer `node:` protocol + 'node/prefer-node-protocol': OFF, + // prefer promises + 'node/prefer-promises/dns': OFF, + 'node/prefer-promises/fs': OFF, + // prefer lookarounds over capturing group that do not replace + 'regexp/prefer-lookaround': [ERROR, { lookbehind: false, strictTypes: true }], + // enforce using named capture group in regular expression + 'regexp/prefer-named-capture-group': OFF, + // prefer class field declarations over this assignments in constructors + 'unicorn/prefer-class-fields': OFF, + // prefer using a logical operator over a ternary + 'unicorn/prefer-logical-operator-over-ternary': OFF, + // prefer using the `node:` protocol when importing Node builtin modules + 'unicorn/prefer-node-protocol': OFF, + // prefer omitting the `catch` binding parameter + 'unicorn/prefer-optional-catch-binding': OFF, + // prefer using `structuredClone` to create a deep clone + 'unicorn/prefer-structured-clone': OFF, + ...disable(forbidES5BuiltIns), + ...disable(forbidES2015BuiltIns), + ...disable(forbidES2016BuiltIns), + ...disable(forbidES2017BuiltIns), + 'es/no-atomics': ERROR, + 'es/no-shared-array-buffer': ERROR, + // disallow top-level `await` + 'es/no-top-level-await': ERROR, + ...forbidES2018BuiltIns, + ...forbidES2019BuiltIns, + ...forbidES2020BuiltIns, + ...forbidES2021BuiltIns, + ...forbidES2022BuiltIns, + ...forbidES2023BuiltIns, + ...forbidES2024BuiltIns, + ...forbidES2025BuiltIns, + ...forbidES2026BuiltIns, + ...disable(forbidES2016IntlBuiltIns), + ...disable(forbidES2017IntlBuiltIns), + ...forbidES2018IntlBuiltIns, + ...forbidES2020IntlBuiltIns, + ...forbidES2021IntlBuiltIns, + ...forbidES2022IntlBuiltIns, + ...forbidES2023IntlBuiltIns, + ...forbidES2025IntlBuiltIns, + ...forbidES2026IntlBuiltIns, + ...forbidSomeES2025Syntax, +}; + +const nodeDev = { + // disallow unsupported ECMAScript built-ins on the specified version + 'node/no-unsupported-features/node-builtins': [ERROR, { version: DEV_NODE_VERSIONS, ignores: ['fetch'], allowExperimental: false }], + ...disable(forbidModernBuiltIns), + ...forbidES2023BuiltIns, + 'es/no-array-prototype-findlast-findlastindex': OFF, + ...forbidES2024BuiltIns, + ...forbidES2025BuiltIns, + ...forbidES2026BuiltIns, + 'es/no-intl-supportedvaluesof': ERROR, + ...forbidES2023IntlBuiltIns, + ...forbidES2025IntlBuiltIns, + ...forbidES2026IntlBuiltIns, + // ReDoS vulnerability check + 'redos/no-vulnerable': OFF, + // prefer top-level await + 'unicorn/prefer-top-level-await': ERROR, + ...forbidSomeES2025Syntax, +}; + +const tests = { + // relax for testing: + // enforces return statements in callbacks of array's methods + 'array-callback-return': OFF, + // specify the maximum number of statement allowed in a function + 'max-statements': OFF, + // disallow function declarations and expressions inside loop statements + 'no-loop-func': OFF, + // disallow use of new operator when not part of the assignment or comparison + 'no-new': OFF, + // disallow use of new operator for Function object + 'no-new-func': OFF, + // disallows creating new instances of String, Number, and Boolean + 'no-new-wrappers': OFF, + // disallow specified syntax + 'no-restricted-syntax': OFF, + // restrict what can be thrown as an exception + 'no-throw-literal': OFF, + // disallow usage of expressions in statement position + 'no-unused-expressions': OFF, + // disallow dangling underscores in identifiers + 'no-underscore-dangle': [ERROR, { allow: [ + '__defineGetter__', + '__defineSetter__', + '__lookupGetter__', + '__lookupSetter__', + ] }], + // disallow unnecessary calls to `.call()` and `.apply()` + 'no-useless-call': OFF, + // specify the maximum length of a line in your program + '@stylistic/max-len': [ERROR, { ...base['@stylistic/max-len'][1], code: 180 }], + // enforces the use of `catch()` on un-returned promises + 'promise/catch-or-return': OFF, + // prefer catch to `then(a, b)` / `then(null, b)` for handling errors + 'promise/prefer-catch': OFF, + // shorthand promises should be used + 'sonarjs/prefer-promise-shorthand': OFF, + // enforce passing a message value when throwing a built-in error + 'unicorn/error-message': OFF, + // prefer `Array#toReversed()` over `Array#reverse()` + 'unicorn/no-array-reverse': OFF, + // disallow immediate mutation after variable assignment + 'unicorn/no-immediate-mutation': OFF, + // disallow `instanceof` with built-in objects + 'unicorn/no-instanceof-builtins': OFF, + // prefer `.at()` method for index access and `String#charAt()` + 'unicorn/prefer-at': OFF, + // prefer `.includes()` over `.indexOf()` and `Array#some()` when checking for existence or non-existence + 'unicorn/prefer-includes': OFF, + // ReDoS vulnerability check + 'redos/no-vulnerable': OFF, + // allow Annex B methods for testing + ...disable(forbidESAnnexBBuiltIns), +}; + +const qunit = { + // ensure the correct number of assert arguments is used + 'qunit/assert-args': ERROR, + // enforce comparison assertions have arguments in the right order + 'qunit/literal-compare-order': ERROR, + // forbid the use of `assert.equal` + 'qunit/no-assert-equal': ERROR, + // require use of boolean assertions + 'qunit/no-assert-equal-boolean': ERROR, + // disallow binary logical expressions in assert arguments + 'qunit/no-assert-logical-expression': ERROR, + // forbid async calls in loops + 'qunit/no-async-in-loops': ERROR, + // disallow async module callbacks + 'qunit/no-async-module-callbacks': ERROR, + // forbid the use of `asyncTest` + 'qunit/no-async-test': ERROR, + // forbid commented tests + 'qunit/no-commented-tests': ERROR, + // forbid comparing relational expression to boolean in assertions + 'qunit/no-compare-relation-boolean': ERROR, + // prevent early return in a qunit test + 'qunit/no-early-return': ERROR, + // forbid the use of global qunit assertions + 'qunit/no-global-assertions': ERROR, + // forbid the use of global `expect` + 'qunit/no-global-expect': ERROR, + // forbid the use of global `module` / `test` / `asyncTest` + 'qunit/no-global-module-test': ERROR, + // forbid use of global `stop` / `start` + 'qunit/no-global-stop-start': ERROR, + // disallow the use of hooks from ancestor modules + 'qunit/no-hooks-from-ancestor-modules': ERROR, + // forbid identical test and module names + 'qunit/no-identical-names': ERROR, + // forbid use of `QUnit.init` + 'qunit/no-init': ERROR, + // forbid use of `QUnit.jsDump` + 'qunit/no-jsdump': ERROR, + // disallow the use of `assert.equal` / `assert.ok` / `assert.notEqual` / `assert.notOk`` + 'qunit/no-loose-assertions': ERROR, + // forbid `QUnit.test()` calls inside callback of another `QUnit.test` + 'qunit/no-nested-tests': ERROR, + // forbid equality comparisons in `assert.{ ok, notOk }` + 'qunit/no-ok-equality': ERROR, + // disallow `QUnit.only` + 'qunit/no-only': ERROR, + // forbid the use of `QUnit.push` + 'qunit/no-qunit-push': ERROR, + // forbid `QUnit.start` within tests or test hooks + 'qunit/no-qunit-start-in-tests': ERROR, + // forbid the use of `QUnit.stop` + 'qunit/no-qunit-stop': ERROR, + // forbid overwriting of QUnit logging callbacks + 'qunit/no-reassign-log-callbacks': ERROR, + // forbid use of `QUnit.reset` + 'qunit/no-reset': ERROR, + // forbid setup / teardown module hooks + 'qunit/no-setup-teardown': ERROR, + // forbid expect argument in `QUnit.test` + 'qunit/no-test-expect-argument': ERROR, + // forbid assert.throws() with block, string, and message + 'qunit/no-throws-string': ERROR, + // enforce use of objects as expected value in `assert.propEqual` + 'qunit/require-object-in-propequal': ERROR, + // require that all async calls should be resolved in tests + 'qunit/resolve-async': ERROR, +}; + +const playwright = { + // enforce Playwright APIs to be awaited + 'playwright/missing-playwright-await': ERROR, + // disallow usage of `page.$eval()` and `page.$$eval()` + 'playwright/no-eval': ERROR, + // disallow using `page.pause()` + 'playwright/no-page-pause': ERROR, + // prevent unsafe variable references in `page.evaluate()` + 'playwright/no-unsafe-references': ERROR, + // disallow unnecessary awaits for Playwright methods + 'playwright/no-useless-await': ERROR, +}; + +const yaml = { + // disallow empty mapping values + 'yaml/no-empty-mapping-value': ERROR, +}; + +const json = { + // enforce spacing inside array brackets + 'jsonc/array-bracket-spacing': [ERROR, NEVER], + // disallow trailing commas in multiline object literals + 'jsonc/comma-dangle': [ERROR, NEVER], + // enforce one true comma style + 'jsonc/comma-style': [ERROR, 'last'], + // enforce consistent indentation + 'jsonc/indent': [ERROR, 2], + // enforces spacing between keys and values in object literal properties + 'jsonc/key-spacing': [ERROR, { beforeColon: false, afterColon: true }], + // disallow BigInt literals + 'jsonc/no-bigint-literals': ERROR, + // disallow binary expression + 'jsonc/no-binary-expression': ERROR, + // disallow binary numeric literals + 'jsonc/no-binary-numeric-literals': ERROR, + // disallow comments + 'jsonc/no-comments': ERROR, + // disallow duplicate keys when creating object literals + 'jsonc/no-dupe-keys': ERROR, + // disallow escape sequences in identifiers. + 'jsonc/no-escape-sequence-in-identifier': ERROR, + // disallow leading or trailing decimal points in numeric literals + 'jsonc/no-floating-decimal': ERROR, + // disallow hexadecimal numeric literals + 'jsonc/no-hexadecimal-numeric-literals': ERROR, + // disallow `Infinity` + 'jsonc/no-infinity': ERROR, + // disallow irregular whitespace + 'jsonc/no-irregular-whitespace': [ERROR, {}], + // disallow use of multiline strings + 'jsonc/no-multi-str': ERROR, + // disallow `NaN` + 'jsonc/no-nan': ERROR, + // disallow number property keys + 'jsonc/no-number-props': ERROR, + // disallow numeric separators + 'jsonc/no-numeric-separators': ERROR, + // disallow use of octal escape sequences in string literals, such as var foo = 'Copyright \251'; + 'jsonc/no-octal-escape': ERROR, + // disallow octal numeric literals + 'jsonc/no-octal-numeric-literals': ERROR, + // disallow legacy octal literals + 'jsonc/no-octal': ERROR, + // disallow parentheses around the expression + 'jsonc/no-parenthesized': ERROR, + // disallow plus sign + 'jsonc/no-plus-sign': ERROR, + // disallow RegExp literals + 'jsonc/no-regexp-literals': ERROR, + // disallow sparse arrays + 'jsonc/no-sparse-arrays': ERROR, + // disallow template literals + 'jsonc/no-template-literals': ERROR, + // disallow `undefined` + 'jsonc/no-undefined-value': ERROR, + // disallow Unicode code point escape sequences. + 'jsonc/no-unicode-codepoint-escapes': ERROR, + // disallow unnecessary string escaping + 'jsonc/no-useless-escape': ERROR, + // enforce consistent line breaks after opening and before closing braces + 'jsonc/object-curly-newline': [ERROR, { consistent: true }], + // enforce spaces inside braces + 'jsonc/object-curly-spacing': [ERROR, ALWAYS], + // require or disallow use of quotes around object literal property names + 'jsonc/quote-props': [ERROR, ALWAYS], + // specify whether double or single quotes should be used + 'jsonc/quotes': [ERROR, 'double'], + // require or disallow spaces before/after unary operators + 'jsonc/space-unary-ops': ERROR, + // disallow invalid number for JSON + 'jsonc/valid-json-number': ERROR, + // specify the maximum length of a line in your program + '@stylistic/max-len': OFF, + // require strict mode directives + strict: OFF, +}; + +const packageJSON = { + // enforce that names for bin properties are in kebab case + 'package-json/bin-name-casing': ERROR, + // enforce consistent format for the exports field (implicit or explicit subpaths) + 'package-json/exports-subpaths-style': [ERROR, { prefer: 'explicit' }], + // reports on unnecessary empty arrays and objects + 'package-json/no-empty-fields': ERROR, + // prevents adding unnecessary / redundant files + 'package-json/no-redundant-files': ERROR, + // warns when `publishConfig.access` is used in unscoped packages + 'package-json/no-redundant-publishConfig': ERROR, + // disallows unnecessary properties in private packages + 'package-json/restrict-private-properties': ERROR, + // enforce that names for `scripts` are in kebab case (optionally separated by colons) + 'package-json/scripts-name-casing': ERROR, + // enforce that package dependencies are unique + 'package-json/unique-dependencies': ERROR, + // enforce that the author field is a valid npm author specification + 'package-json/valid-author': ERROR, + // enforce that the `bundleDependencies` (or `bundledDependencies`) property is valid + 'package-json/valid-bundleDependencies': ERROR, + // enforce that the `bin` property is valid + 'package-json/valid-bin': ERROR, + // enforce that the `config` property is valid + 'package-json/valid-config': ERROR, + // enforce that the `contributors` property is valid + 'package-json/valid-contributors': ERROR, + // enforce that the `cpu` property is valid + 'package-json/valid-cpu': ERROR, + // enforce that the `dependencies` property is valid + 'package-json/valid-dependencies': ERROR, + // enforce that the `description` property is valid + 'package-json/valid-description': ERROR, + // enforce that the `directories` property is valid + 'package-json/valid-directories': ERROR, + // enforce that the `engines` property is valid + 'package-json/valid-engines': ERROR, + // enforce that the `exports` property is valid + 'package-json/valid-exports': ERROR, + // enforce that the `files` property is valid + 'package-json/valid-files': ERROR, + // enforce that the `homepage` property is valid + 'package-json/valid-homepage': ERROR, + // enforce that the `keywords` property is valid + 'package-json/valid-keywords': ERROR, + // enforce that the `license` property is valid + 'package-json/valid-license': ERROR, + // enforce that the `main` property is valid + 'package-json/valid-main': ERROR, + // enforce that the `man` property is valid + 'package-json/valid-man': ERROR, + // enforce that the `os` property is valid + 'package-json/valid-os': ERROR, + // enforce that the `private` property is valid + 'package-json/valid-private': ERROR, + // enforce that the `publishConfig` property is valid + 'package-json/valid-publishConfig': ERROR, + // enforce that the `repository` property is valid + 'package-json/valid-repository': ERROR, + // enforce that if repository directory is specified, it matches the path to the package.json file + 'package-json/valid-repository-directory': ERROR, + // enforce that the `scripts` property is valid. + 'package-json/valid-scripts': ERROR, + // enforce that the `sideEffects` property is valid. + 'package-json/valid-sideEffects': ERROR, + // enforce that the `type` property is valid + 'package-json/valid-type': ERROR, + // enforce that package versions are valid semver specifiers + 'package-json/valid-version': ERROR, + // enforce that the `workspaces` property is valid + 'package-json/valid-workspaces': ERROR, +}; + +const packagesPackageJSON = { + // enforce either object or shorthand declaration for repository + 'package-json/repository-shorthand': [ERROR, { form: 'object' }], + // ensures that proper attribution is included, requiring that either `author` or `contributors` is defined, + // and that if `contributors` is present, it should include at least one contributor + 'package-json/require-attribution': ERROR, + // requires the `author` property to be present + 'package-json/require-author': ERROR, + // requires the `bugs`` property to be present + 'package-json/require-bugs': ERROR, + // requires the `description` property to be present + 'package-json/require-description': ERROR, + // requires the `engines` property to be present + // TODO: core-js@4 + // 'package-json/require-engines': ERROR, + // requires the `exports` property to be present + // TODO: core-js@4 + // 'package-json/require-exports': ERROR, + // requires the `license` property to be present + 'package-json/require-license': ERROR, + // requires the `name` property to be present + 'package-json/require-name': ERROR, + // requires the `sideEffects` property to be present + 'package-json/require-sideEffects': ERROR, + // requires the `types` property to be present + // TODO: core-js@4 + // 'package-json/require-types': ERROR, + // requires the `version` property to be present + 'package-json/require-version': ERROR, + // enforce that package names are valid npm package names + 'package-json/valid-name': ERROR, +}; + +const nodeDependencies = { + // enforce the versions of the engines of the dependencies to be compatible + 'node-dependencies/compat-engines': ERROR, + // disallow having dependencies on deprecate packages + 'node-dependencies/no-deprecated': ERROR, + // enforce versions that is valid as a semantic version + 'node-dependencies/valid-semver': ERROR, +}; + +const markdown = { + ...base, + ...disable(forbidModernBuiltIns), + ...forbidCompletelyNonExistentBuiltIns, + // allow use of console + 'no-console': OFF, + // disallow use of new operator when not part of the assignment or comparison + 'no-new': OFF, + // disallow specified syntax + 'no-restricted-syntax': OFF, + // disallow use of undeclared variables unless mentioned in a /*global */ block + 'no-undef': OFF, + // disallow usage of expressions in statement position + 'no-unused-expressions': OFF, + // disallow declaration of variables that are not used in the code + 'no-unused-vars': OFF, + // require let or const instead of var + 'no-var': OFF, + // require const declarations for variables that are never reassigned after declared + 'prefer-const': OFF, + // disallow use of the `RegExp` constructor in favor of regular expression literals + 'prefer-regex-literals': OFF, + // disallow top-level `await` + 'es/no-top-level-await': OFF, + // ensure imports point to files / modules that can be resolved + 'import/no-unresolved': OFF, + // enforces the use of `catch()` on un-returned promises + 'promise/catch-or-return': OFF, + // enforce that `RegExp#exec` is used instead of `String#match` if no global flag is provided + 'regexp/prefer-regexp-exec': OFF, + // variables should be defined before being used + 'sonarjs/no-reference-error': OFF, + // specify the maximum length of a line in your program + '@stylistic/max-len': [ERROR, { ...base['@stylistic/max-len'][1], code: 200 }], +}; + +const globalsESNext = { + AsyncIterator: READONLY, + compositeKey: READONLY, + compositeSymbol: READONLY, +}; + +const globalsZX = { + $: READONLY, + __dirname: READONLY, + __filename: READONLY, + argv: READONLY, + cd: READONLY, + chalk: READONLY, + echo: READONLY, + fetch: READONLY, + fs: READONLY, + glob: READONLY, + nothrow: READONLY, + os: READONLY, + path: READONLY, + question: READONLY, + require: READONLY, + sleep: READONLY, + stdin: READONLY, + which: READONLY, + within: READONLY, + YAML: READONLY, +}; + +export default [ + { + ignores: [ + 'deno/corejs/**', + 'docs/**', + 'packages/core-js-bundle/!(package.json)', + 'packages/core-js-compat/!(package).json', + 'packages/core-js-pure/override/**', + 'tests/**/bundles/**', + 'tests/compat/compat-data.js', + 'tests/unit-@(global|pure)/index.js', + 'website/dist/**', + 'website/src/public/*', + 'website/templates/**', + ], + }, + { + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'script', + // unnecessary global builtins disabled by related rules + globals: { + ...globals.builtin, + ...globals.browser, + ...globals.node, + ...globals.worker, + }, + }, + linterOptions: { + reportUnusedDisableDirectives: true, + }, + plugins: { + '@stylistic': pluginStylistic, + 'array-func': pluginArrayFunc, + ascii: pluginASCII, + depend: pluginDepend, + es: pluginESX, + 'eslint-comments': pluginESlintComments, + filename: pluginFilename, + import: pluginImport, + jsonc: pluginJSONC, + markdown: pluginMarkdown, + math: pluginMath, + node: pluginN, + 'node-dependencies': pluginNodeDependencies, + 'package-json': pluginPackageJSON, + playwright: pluginPlaywright, + promise: pluginPromise, + qunit: pluginQUnit, + redos: pluginReDoS, + regexp: pluginRegExp, + sonarjs: pluginSonarJS, + unicorn: pluginUnicorn, + yaml: pluginYaml, + }, + rules: { + ...base, + ...forbidNonStandardBuiltIns, + ...forbidESAnnexBBuiltIns, + }, + settings: { + 'es-x': { allowTestedProperty: true }, + }, + }, + { + files: [ + '**/*.mjs', + 'tests/eslint/**', + ], + languageOptions: { + sourceType: 'module', + }, + }, + { + files: [ + 'packages/core-js?(-pure)/**', + 'tests/@(compat|worker)/*.js', + ], + languageOptions: { + ecmaVersion: 3, + }, + rules: useES3Syntax, + }, + { + files: [ + 'packages/core-js?(-pure)/**', + 'tests/@(helpers|unit-pure|worker)/**', + 'tests/compat/@(browsers|hermes|node|rhino)-runner.js', + ], + rules: forbidModernBuiltIns, + }, + { + files: [ + 'packages/core-js?(-pure)/**', + ], + rules: polyfills, + }, + { + files: [ + '**/postinstall.js', + ], + rules: disable(forbidES5BuiltIns), + }, + { + files: [ + 'packages/core-js?(-pure)/**/instance/**', + ], + rules: { + ...disable(forbidModernBuiltIns), + ...forbidCompletelyNonExistentBuiltIns, + }, + }, + { + files: [ + 'tests/@(helpers|unit-@(global|pure)|wpt-url-resources)/**', + ], + languageOptions: { + sourceType: 'module', + }, + rules: transpiledAndPolyfilled, + }, + { + files: [ + 'tests/**', + ], + rules: tests, + }, + { + files: [ + 'tests/compat/tests.js', + ], + rules: forbidCompletelyNonExistentBuiltIns, + }, + { + files: [ + 'tests/@(helpers|unit-@(global|pure))/**', + ], + languageOptions: { + globals: globals.qunit, + }, + rules: qunit, + }, + { + files: [ + 'scripts/usage/**', + ], + rules: playwright, + }, + { + files: [ + 'packages/core-js-@(builder|compat)/**', + ], + rules: nodePackages, + }, + { + files: [ + '*.js', + 'packages/core-js-compat/src/**', + 'scripts/**', + 'tests/compat/*.mjs', + 'tests/@(compat-@(data|tools)|eslint|entries|observables|promises-aplus|unit-@(karma|node))/**', + 'website/runner.mjs', + 'website/helpers.mjs', + ], + rules: nodeDev, + }, + { + files: [ + 'tests/@(compat|unit-global)/**', + ], + languageOptions: { + globals: globalsESNext, + }, + }, + { + files: [ + '@(scripts|tests)/*/**', + ], + rules: { + // disable this rule for lazily installed dependencies + 'import/no-unresolved': [ERROR, { commonjs: true, ignore: ['^[^.]'] }], + }, + }, + { + files: [ + 'packages/core-js-compat/src/**', + 'scripts/**', + 'tests/**/*.mjs', + 'website/**.mjs', + ], + languageOptions: { + // zx + globals: globalsZX, + }, + rules: { + // allow use of console + 'no-console': OFF, + // import used for tasks + 'import/first': OFF, + }, + }, + { + rules: { + // ensure that filenames match a convention + 'filename/match': [ERROR, /^[\da-z][\d\-.a-z]*[\da-z]$/], + }, + }, + { + files: [ + 'packages/core-js?(-pure)/modules/**', + ], + rules: { + // ensure that filenames match a convention + 'filename/match': [ERROR, /^(?:es|esnext|web)(?:\.[a-z][\d\-a-z]*[\da-z])+$/], + }, + }, + { + files: [ + 'tests/@(unit-@(global|pure))/**', + ], + rules: { + // ensure that filenames match a convention + 'filename/match': [ERROR, /^(?:es|esnext|helpers|web)(?:\.[a-z][\d\-a-z]*[\da-z])+$/], + }, + }, + { + language: 'yaml/yaml', + files: ['*.yaml', '*.yml'], + rules: yaml, + }, + { + files: ['**/*.json'], + languageOptions: { + parser: parserJSONC, + }, + rules: json, + }, + { + files: ['**/package.json'], + rules: { + ...packageJSON, + ...nodeDependencies, + }, + }, + { + files: ['packages/*/package.json'], + rules: packagesPackageJSON, + }, + { + files: ['**/*.md'], + processor: 'markdown/markdown', + }, + { + files: ['**/*.md/*.js'], + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'module', + }, + rules: markdown, + }, + { + files: ['**/*.md/*'], + rules: { + // enforce a case style for filenames + 'unicorn/filename-case': OFF, + // ensure that filenames match a convention + 'filename/match': OFF, + }, + }, + { + files: [ + 'website/src/js/*', + ], + languageOptions: { + sourceType: 'module', + }, + rules: { + ...transpiledAndPolyfilled, + 'no-restricted-globals': OFF, + 'unicorn/prefer-global-this': OFF, + '@stylistic/quotes': [ERROR, 'single', { allowTemplateLiterals: ALWAYS }], + }, + }, + { + files: [ + 'website/**', + ], + rules: { + 'import/no-unresolved': OFF, + }, + }, +]; diff --git a/tests/eslint/package-lock.json b/tests/eslint/package-lock.json new file mode 100644 index 000000000000..da6bc6fbcc62 --- /dev/null +++ b/tests/eslint/package-lock.json @@ -0,0 +1,4734 @@ +{ + "name": "tests/eslint", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests/eslint", + "devDependencies": { + "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0", + "@eslint/markdown": "^7.5.1", + "@stylistic/eslint-plugin": "^5.6.1", + "confusing-browser-globals": "^1.0.11", + "eslint": "^9.39.2", + "eslint-plugin-array-func": "^5.1.0", + "eslint-plugin-ascii": "^2.0.0", + "eslint-plugin-depend": "^1.4.0", + "eslint-plugin-es-x": "^9.3.0", + "eslint-plugin-filename": "^1.0.3", + "eslint-plugin-import-x": "^4.16.1", + "eslint-plugin-jsonc": "^2.21.0", + "eslint-plugin-math": "^0.13.1", + "eslint-plugin-n": "^17.23.1", + "eslint-plugin-node-dependencies": "^1.3.0", + "eslint-plugin-package-json": "^0.85.0", + "eslint-plugin-playwright": "^2.4.0", + "eslint-plugin-promise": "^7.2.1", + "eslint-plugin-qunit": "^8.2.5", + "eslint-plugin-redos": "^4.5.0", + "eslint-plugin-regexp": "^2.10.0", + "eslint-plugin-sonarjs": "^3.0.5", + "eslint-plugin-unicorn": "^62.0.0", + "eslint-yaml": "^0.1.0", + "globals": "^16.5.0", + "jsonc-eslint-parser": "^2.4.2" + } + }, + "node_modules/@altano/repository-tools": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@altano/repository-tools/-/repository-tools-2.0.1.tgz", + "integrity": "sha512-YE/52CkFtb+YtHPgbWPai7oo5N9AKnMuP5LM+i2AG7G1H2jdYBCO1iDnkDE3dZ3C1MIgckaF+d5PNRulgt0bdw==", + "dev": true, + "license": "ISC" + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", + "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@eslint-community/eslint-plugin-eslint-comments": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.5.0.tgz", + "integrity": "sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "ignore": "^5.2.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", + "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/markdown": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@eslint/markdown/-/markdown-7.5.1.tgz", + "integrity": "sha512-R8uZemG9dKTbru/DQRPblbJyXpObwKzo8rv1KYGGuPUPtjM4LXBYM9q5CIZAComzZupws3tWbDwam5AFpPLyJQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "examples/*" + ], + "dependencies": { + "@eslint/core": "^0.17.0", + "@eslint/plugin-kit": "^0.4.1", + "github-slugger": "^2.0.0", + "mdast-util-from-markdown": "^2.0.2", + "mdast-util-frontmatter": "^2.0.1", + "mdast-util-gfm": "^3.1.0", + "micromark-extension-frontmatter": "^2.0.0", + "micromark-extension-gfm": "^3.0.0", + "micromark-util-normalize-identifier": "^2.0.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", + "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", + "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "4.2.10" + }, + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true, + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz", + "integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.6.1.tgz", + "integrity": "sha512-JCs+MqoXfXrRPGbGmho/zGS/jMcn3ieKl/A8YImqib76C8kjgZwq5uUFzc30lJkMvcchuRn6/v8IApLxli3Jyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.9.0", + "@typescript-eslint/types": "^8.47.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/types": { + "version": "8.50.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.50.0.tgz", + "integrity": "sha512-iX1mgmGrXdANhhITbpp2QQM2fGehBse9LbTf0sidWK6yg/NE+uhV5dfU1g6EYPlcReYmkE9QLPq/2irKAmtS9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.10", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.10.tgz", + "integrity": "sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001761", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz", + "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js-compat": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", + "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decode-named-character-reference": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz", + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/detect-indent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.2.tgz", + "integrity": "sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/detect-newline": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-4.0.1.tgz", + "integrity": "sha512-qE3Veg1YXzGHQhlA6jzebZN2qVf6NX+A7m7qlhCGG30dJixrAQhYOsJjsnBjJkCSmuOPpCk30145fr8FV0bzog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/empathic": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz", + "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.4", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz", + "integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", + "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-compat-utils": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.5.tgz", + "integrity": "sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-fix-utils": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/eslint-fix-utils/-/eslint-fix-utils-0.4.0.tgz", + "integrity": "sha512-nCEciwqByGxsKiWqZjqK7xfL+7dUX9Pi0UL3J0tOwfxVN9e6Y59UxEt1ZYsc3XH0ce6T1WQM/QU2DbKK/6IG7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "@types/estree": ">=1", + "eslint": ">=8" + }, + "peerDependenciesMeta": { + "@types/estree": { + "optional": true + } + } + }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, + "node_modules/eslint-json-compat-utils": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/eslint-json-compat-utils/-/eslint-json-compat-utils-0.2.1.tgz", + "integrity": "sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esquery": "^1.6.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": "*", + "jsonc-eslint-parser": "^2.4.0" + }, + "peerDependenciesMeta": { + "@eslint/json": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-array-func": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-5.1.0.tgz", + "integrity": "sha512-+OULB0IQdENBmBf8pHMPPObgV6QyfeXFin483jPonOaiurI9UFmc8UydWriK5f5Gel8xBhQLA6NzMwbck1BUJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8.51.0" + } + }, + "node_modules/eslint-plugin-ascii": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-ascii/-/eslint-plugin-ascii-2.0.0.tgz", + "integrity": "sha512-hITZHSGWjot8R7iRuEBFRr7atPf2Rre31Kgwr2KryXGq1ah/KwpwtnhoX3uCo+xEE5SWDz2o85WfJ9fRdMCb/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-depend": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-depend/-/eslint-plugin-depend-1.4.0.tgz", + "integrity": "sha512-MQs+m4nHSfgAO9bJDsBzqw0ofK/AOA0vfeY/6ahofqcUMLeM6/D1sTYs21fOhc17kNU/gn58YCtj20XaAssh2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "empathic": "^2.0.0", + "module-replacements": "^2.10.1", + "semver": "^7.6.3" + } + }, + "node_modules/eslint-plugin-es-x": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-9.3.0.tgz", + "integrity": "sha512-jI+xZmZeyIntW7p5b6FqmbsasXPHgmjChzFCtgUfukKntCT46pjHylhRokw3Ae4M0pIK6QGCGDE3aaayZbifQQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.12.1", + "eslint-type-tracer": "^0.4.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "eslint": ">=9.29.0" + } + }, + "node_modules/eslint-plugin-filename": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-filename/-/eslint-plugin-filename-1.0.3.tgz", + "integrity": "sha512-9NhQ8Z1G/wEIBf32ZKDvO2ctjMHNhqrKjSndPdK8JvMuqatbNHiahS4UgRJ1eeRZif+t0ZdSh2/JLPvYdYieGA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-import-x": { + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.1.tgz", + "integrity": "sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "^8.35.0", + "comment-parser": "^1.4.1", + "debug": "^4.4.1", + "eslint-import-context": "^0.1.9", + "is-glob": "^4.0.3", + "minimatch": "^9.0.3 || ^10.0.1", + "semver": "^7.7.2", + "stable-hash-x": "^0.2.0", + "unrs-resolver": "^1.9.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-import-x" + }, + "peerDependencies": { + "@typescript-eslint/utils": "^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "eslint-import-resolver-node": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/utils": { + "optional": true + }, + "eslint-import-resolver-node": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-import-x/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-jsonc": { + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.21.0.tgz", + "integrity": "sha512-HttlxdNG5ly3YjP1cFMP62R4qKLxJURfBZo2gnMY+yQojZxkLyOpY1H1KRTKBmvQeSG9pIpSGEhDjE17vvYosg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.1", + "diff-sequences": "^27.5.1", + "eslint-compat-utils": "^0.6.4", + "eslint-json-compat-utils": "^0.2.1", + "espree": "^9.6.1 || ^10.3.0", + "graphemer": "^1.4.0", + "jsonc-eslint-parser": "^2.4.0", + "natural-compare": "^1.4.0", + "synckit": "^0.6.2 || ^0.7.3 || ^0.11.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-math": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-math/-/eslint-plugin-math-0.13.1.tgz", + "integrity": "sha512-vQSl7LpmgKggEKnkgzre+5zbFyuIDcqzlL/lXnTBRuA6T2/K0zzJ17gsie6+eip6X68r+PTlC2KpJYvHnWyp5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "eslint-type-tracer": "^0.4.0" + }, + "engines": { + "node": "^18 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=8.57.0" + } + }, + "node_modules/eslint-plugin-n": { + "version": "17.23.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.23.1.tgz", + "integrity": "sha512-68PealUpYoHOBh332JLLD9Sj7OQUDkFpmcfqt8R9sySfFSeuGJjMTJQvCRRB96zO3A/PELRLkPrzsHmzEFQQ5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.5.0", + "enhanced-resolve": "^5.17.1", + "eslint-plugin-es-x": "^7.8.0", + "get-tsconfig": "^4.8.1", + "globals": "^15.11.0", + "globrex": "^0.1.2", + "ignore": "^5.3.2", + "semver": "^7.6.3", + "ts-declaration-location": "^1.0.6" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": ">=8.23.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/eslint-compat-utils": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz", + "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-n/node_modules/eslint-plugin-es-x": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz", + "integrity": "sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://opencollective.com/eslint" + ], + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.1.2", + "@eslint-community/regexpp": "^4.11.0", + "eslint-compat-utils": "^0.5.1" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-plugin-n/node_modules/globals": { + "version": "15.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz", + "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint-plugin-node-dependencies": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node-dependencies/-/eslint-plugin-node-dependencies-1.3.0.tgz", + "integrity": "sha512-DeB67/C1Cz8OIJPWj4O4Np1c/Xy/Igv9Cqd9UKwWcSZ+azseiNNBJb8lQtVLm7C6fuic/ePWm/ttb0iADtEKww==", + "dev": true, + "funding": [ + "https://github.com/sponsors/ota-meshi", + "https://github.com/sponsors/JounQin" + ], + "license": "MIT", + "dependencies": { + "eslint-compat-utils": "^0.6.5", + "jsonc-eslint-parser": "^2.0.2", + "npm-package-arg": "^12.0.2", + "package-json": "^10.0.1", + "semver": "^7.3.5", + "synckit": "^0.11.0", + "undici": "^6.21.2 || ^7.8.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "peerDependencies": { + "eslint": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-package-json": { + "version": "0.85.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-package-json/-/eslint-plugin-package-json-0.85.0.tgz", + "integrity": "sha512-MrOxFvhbqLuk4FIPG9v3u9Amn0n137J8LKILHvgfxK3rRyAHEVzuZM0CtpXFTx7cx4LzmAzONtlpjbM0UFNuTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@altano/repository-tools": "^2.0.1", + "change-case": "^5.4.4", + "detect-indent": "^7.0.2", + "detect-newline": "^4.0.1", + "eslint-fix-utils": "~0.4.0", + "package-json-validator": "~0.59.0", + "semver": "^7.7.3", + "sort-object-keys": "^2.0.0", + "sort-package-json": "^3.4.0", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "peerDependencies": { + "eslint": ">=8.0.0", + "jsonc-eslint-parser": "^2.0.0" + } + }, + "node_modules/eslint-plugin-playwright": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-2.4.0.tgz", + "integrity": "sha512-MWNXfXlLfwXAjj4Z80PvCCFCXgCYy5OCHan57Z/beGrjkJ3maG1GanuGX8Ck6T6fagplBx2ZdkifxSfByftaTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "globals": "^16.4.0" + }, + "engines": { + "node": ">=16.9.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz", + "integrity": "sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-qunit": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-qunit/-/eslint-plugin-qunit-8.2.5.tgz", + "integrity": "sha512-qr7RJCYImKQjB+39q4q46i1l7p1V3joHzBE5CAYfxn5tfVFjrnjn/tw7q/kDyweU9kAIcLul0Dx/KWVUCb3BgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-utils": "^3.0.0", + "requireindex": "^1.2.0" + }, + "engines": { + "node": "^16.0.0 || ^18.0.0 || >=20.0.0" + } + }, + "node_modules/eslint-plugin-redos": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-redos/-/eslint-plugin-redos-4.5.0.tgz", + "integrity": "sha512-MwEEpFRmt7MWoqLCdAgN2DyOKnIVzRm3bqCUIQc/+iMJhkRxDCZ+wYQpkaYAZzemDlqUGGQ+twL3AahTNQtqFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "recheck": "4.5.0" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "eslint": ">= 3" + } + }, + "node_modules/eslint-plugin-regexp": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.10.0.tgz", + "integrity": "sha512-ovzQT8ESVn5oOe5a7gIDPD5v9bCSjIFJu57sVPDqgPRXicQzOnYfFN21WoQBQF18vrhT5o7UMKFwJQVVjyJ0ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "comment-parser": "^1.4.0", + "jsdoc-type-pratt-parser": "^4.0.0", + "refa": "^0.12.1", + "regexp-ast-analysis": "^0.7.1", + "scslre": "^0.3.0" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "eslint": ">=8.44.0" + } + }, + "node_modules/eslint-plugin-sonarjs": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-3.0.5.tgz", + "integrity": "sha512-dI62Ff3zMezUToi161hs2i1HX1ie8Ia2hO0jtNBfdgRBicAG4ydy2WPt0rMTrAe3ZrlqhpAO3w1jcQEdneYoFA==", + "dev": true, + "license": "LGPL-3.0-only", + "dependencies": { + "@eslint-community/regexpp": "4.12.1", + "builtin-modules": "3.3.0", + "bytes": "3.1.2", + "functional-red-black-tree": "1.0.1", + "jsx-ast-utils-x": "0.1.0", + "lodash.merge": "4.6.2", + "minimatch": "9.0.5", + "scslre": "0.3.0", + "semver": "7.7.2", + "typescript": ">=5" + }, + "peerDependencies": { + "eslint": "^8.0.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint-plugin-sonarjs/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "62.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-62.0.0.tgz", + "integrity": "sha512-HIlIkGLkvf29YEiS/ImuDZQbP12gWyx5i3C6XrRxMvVdqMroCI9qoVYCoIl17ChN+U89pn9sVwLxhIWj5nEc7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "@eslint-community/eslint-utils": "^4.9.0", + "@eslint/plugin-kit": "^0.4.0", + "change-case": "^5.4.4", + "ci-info": "^4.3.1", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.46.0", + "esquery": "^1.6.0", + "find-up-simple": "^1.0.1", + "globals": "^16.4.0", + "indent-string": "^5.0.0", + "is-builtin-module": "^5.0.0", + "jsesc": "^3.1.0", + "pluralize": "^8.0.0", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.13.0", + "semver": "^7.7.3", + "strip-indent": "^4.1.1" + }, + "engines": { + "node": "^20.10.0 || >=21.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" + }, + "peerDependencies": { + "eslint": ">=9.38.0" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-type-tracer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/eslint-type-tracer/-/eslint-type-tracer-0.4.1.tgz", + "integrity": "sha512-7kDovYNNitAxahP/qQ9UrHssUk8d6V5Y9MQaDiHPKsJrk1g6STDqVHjJPu8ycn1+qE4D0jwQRN7waRrxrX9k+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0" + }, + "engines": { + "node": "^18 || >=20" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "eslint": ">=8" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-yaml": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/eslint-yaml/-/eslint-yaml-0.1.0.tgz", + "integrity": "sha512-pesNMedofHMB2JFuu4JV/ZrWKH+ZjeY5a9hL957qcMlQd+FZ1HCLN+ZraORNrhzVl0q+pJkCvXCAPr9IeHqddA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint/core": "^0.15.2", + "@eslint/plugin-kit": "^0.3.5", + "yaml": "^2.8.1" + } + }, + "node_modules/eslint-yaml/node_modules/@eslint/core": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", + "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/eslint-yaml/node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", + "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/git-hooks-list": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-4.1.1.tgz", + "integrity": "sha512-cmP497iLq54AZnv4YRAEMnEyQ1eIn4tGKbmswqwmFV4GBnAqE8NLtWxxdXa++AalfgL5EBH4IxTPyquEuGY/jA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/fisker/git-hooks-list?sponsor=1" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "dev": true, + "license": "ISC" + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/globals": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", + "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-builtin-module": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-5.0.0.tgz", + "integrity": "sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^5.0.0" + }, + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-builtin-module/node_modules/builtin-modules": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-5.0.0.tgz", + "integrity": "sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdoc-type-pratt-parser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.8.0.tgz", + "integrity": "sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.2.tgz", + "integrity": "sha512-1e4qoRgnn448pRuMvKGsFFymUCquZV0mpGgOyIKNgD3JVDTsVJyRBGH/Fm0tBb8WsWGgmB1mDe6/yJMQM37DUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsonc-eslint-parser/node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/jsx-ast-utils-x": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils-x/-/jsx-ast-utils-x-0.1.0.tgz", + "integrity": "sha512-eQQBjBnsVtGacsG9uJNB8qOr3yA8rga4wAaGG1qRcBzSIvfhERLrWxMAM1hp5fcS6Abo8M4+bUBTekYR0qTPQw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/ky": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.14.1.tgz", + "integrity": "sha512-hYje4L9JCmpEQBtudo+v52X5X8tgWXUYyPcxKSuxQNboqufecl9VMWjGiucAFH060AwPXHZuH+WB2rrqfkmafw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-2.0.1.tgz", + "integrity": "sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "escape-string-regexp": "^5.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-extension-frontmatter": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-frontmatter/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-frontmatter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-2.0.0.tgz", + "integrity": "sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fault": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/module-replacements": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/module-replacements/-/module-replacements-2.10.1.tgz", + "integrity": "sha512-qkKuLpMHDqRSM676OPL7HUpCiiP3NSxgf8NNR1ga2h/iJLNKTsOSjMEwrcT85DMSti2vmOqxknOVBGWj6H6etQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/npm-package-arg": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg/node_modules/validate-npm-package-name": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", + "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-10.0.1.tgz", + "integrity": "sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ky": "^1.2.0", + "registry-auth-token": "^5.0.2", + "registry-url": "^6.0.1", + "semver": "^7.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-json-validator": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/package-json-validator/-/package-json-validator-0.59.0.tgz", + "integrity": "sha512-WBTDKtO9pBa9GmA1sPbQHqlWxRdnHNfLFIIA49PPgV7px/rG27gHX57DWy77qyu374fla4veaIHy+gA+qRRuug==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.2", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^7.0.0", + "yargs": "~18.0.0" + }, + "bin": { + "pjv": "lib/bin/pjv.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true, + "license": "ISC" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/recheck": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/recheck/-/recheck-4.5.0.tgz", + "integrity": "sha512-kPnbOV6Zfx9a25AZ++28fI1q78L/UVRQmmuazwVRPfiiqpMs+WbOU69Shx820XgfKWfak0JH75PUvZMFtRGSsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "synckit": "0.9.2" + }, + "engines": { + "node": ">=20" + }, + "optionalDependencies": { + "recheck-jar": "4.5.0", + "recheck-linux-x64": "4.5.0", + "recheck-macos-arm64": "4.5.0", + "recheck-macos-x64": "4.5.0", + "recheck-windows-x64": "4.5.0" + } + }, + "node_modules/recheck-jar": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/recheck-jar/-/recheck-jar-4.5.0.tgz", + "integrity": "sha512-Ad7oCQmY8cQLzd3QVNXjzZ+S6MbImGhR4AaW2yiGzteOfMV45522rt6nSzFyt8p3mCEaMcm/4MoZrMSxUcCbrA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/recheck-linux-x64": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/recheck-linux-x64/-/recheck-linux-x64-4.5.0.tgz", + "integrity": "sha512-52kXsR/v+IbGIKYYFZfSZcgse/Ci9IA2HnuzrtvRRcfODkcUGe4n72ESQ8nOPwrdHFg9i4j9/YyPh1HWWgpJ6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/recheck-macos-arm64": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/recheck-macos-arm64/-/recheck-macos-arm64-4.5.0.tgz", + "integrity": "sha512-qIyK3dRuLkORQvv0b59fZZRXweSmjjWaoA4K8Kgifz0anMBH4pqsDV6plBlgjcRmW9yC12wErIRzifREaKnk2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/recheck-macos-x64": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/recheck-macos-x64/-/recheck-macos-x64-4.5.0.tgz", + "integrity": "sha512-1wp/eiLxcjC/Ex4wurlrS/LGzt8IiF4TiK5sEjldu4HVAKdNCnnmsS9a5vFpfcikDz4ZuZlLlTi1VbQTxHlwZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/recheck-windows-x64": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/recheck-windows-x64/-/recheck-windows-x64-4.5.0.tgz", + "integrity": "sha512-ekBKwAp0oKkMULn5zgmHEYLwSJfkfb95AbTtbDkQazNkqYw9PRD/mVyFUR6Ff2IeRyZI0gxy+N2AKBISWydhug==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/recheck/node_modules/@pkgr/core": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.2.tgz", + "integrity": "sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/recheck/node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, + "node_modules/refa": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/refa/-/refa-0.12.1.tgz", + "integrity": "sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.8.0" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/regexp-ast-analysis": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/regexp-ast-analysis/-/regexp-ast-analysis-0.7.1.tgz", + "integrity": "sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.1" + }, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", + "dev": true, + "license": "MIT", + "bin": { + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/registry-auth-token": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz", + "integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pnpm/npm-conf": "^2.1.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/registry-url": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", + "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "1.2.8" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.5" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/scslre": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/scslre/-/scslre-0.3.0.tgz", + "integrity": "sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.8.0", + "refa": "^0.12.0", + "regexp-ast-analysis": "^0.7.0" + }, + "engines": { + "node": "^14.0.0 || >=16.0.0" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sort-object-keys": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-2.0.1.tgz", + "integrity": "sha512-R89fO+z3x7hiKPXX5P0qim+ge6Y60AjtlW+QQpRozrrNcR1lw9Pkpm5MLB56HoNvdcLHL4wbpq16OcvGpEDJIg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sort-package-json": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-3.6.0.tgz", + "integrity": "sha512-fyJsPLhWvY7u2KsKPZn1PixbXp+1m7V8NWqU8CvgFRbMEX41Ffw1kD8n0CfJiGoaSfoAvbrqRRl/DcHO8omQOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-indent": "^7.0.2", + "detect-newline": "^4.0.1", + "git-hooks-list": "^4.1.1", + "is-plain-obj": "^4.1.0", + "semver": "^7.7.3", + "sort-object-keys": "^2.0.1", + "tinyglobby": "^0.2.15" + }, + "bin": { + "sort-package-json": "cli.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-indent": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.1.1.tgz", + "integrity": "sha512-SlyRoSkdh1dYP0PzclLE7r0M9sgbFKKMFXpFRUMNuKhQSbC6VQIGzq3E0qsfvGJaUFJPGv6Ws1NZ/haTAjfbMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/synckit": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/ts-declaration-location": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz", + "integrity": "sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==", + "dev": true, + "funding": [ + { + "type": "ko-fi", + "url": "https://ko-fi.com/rebeccastevens" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/ts-declaration-location" + } + ], + "license": "BSD-3-Clause", + "dependencies": { + "picomatch": "^4.0.2" + }, + "peerDependencies": { + "typescript": ">=4.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.16.0.tgz", + "integrity": "sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.1.tgz", + "integrity": "sha512-BM0Upcemlce8/9+HE+/VpWqn3u3mYh6Om/FEC8yPMnEHwf710fW5Q6fhjT1SQyRlZD1G9CJbgfH+rWgAcIvjlQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", + "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/tests/eslint/package.json b/tests/eslint/package.json new file mode 100644 index 000000000000..fe1300cd32c5 --- /dev/null +++ b/tests/eslint/package.json @@ -0,0 +1,32 @@ +{ + "name": "tests/eslint", + "type": "module", + "devDependencies": { + "@eslint/markdown": "^7.5.1", + "@eslint-community/eslint-plugin-eslint-comments": "^4.5.0", + "@stylistic/eslint-plugin": "^5.6.1", + "confusing-browser-globals": "^1.0.11", + "eslint": "^9.39.2", + "eslint-plugin-array-func": "^5.1.0", + "eslint-plugin-ascii": "^2.0.0", + "eslint-plugin-depend": "^1.4.0", + "eslint-plugin-es-x": "^9.3.0", + "eslint-plugin-filename": "^1.0.3", + "eslint-plugin-import-x": "^4.16.1", + "eslint-plugin-jsonc": "^2.21.0", + "eslint-plugin-math": "^0.13.1", + "eslint-plugin-n": "^17.23.1", + "eslint-plugin-node-dependencies": "^1.3.0", + "eslint-plugin-package-json": "^0.85.0", + "eslint-plugin-playwright": "^2.4.0", + "eslint-plugin-promise": "^7.2.1", + "eslint-plugin-qunit": "^8.2.5", + "eslint-plugin-redos": "^4.5.0", + "eslint-plugin-regexp": "^2.10.0", + "eslint-plugin-sonarjs": "^3.0.5", + "eslint-plugin-unicorn": "^62.0.0", + "eslint-yaml": "^0.1.0", + "globals": "^16.5.0", + "jsonc-eslint-parser": "^2.4.2" + } +} diff --git a/tests/eslint/runner.mjs b/tests/eslint/runner.mjs new file mode 100644 index 000000000000..4ab10ff9f141 --- /dev/null +++ b/tests/eslint/runner.mjs @@ -0,0 +1,3 @@ +process.env.ESLINT_USE_FLAT_CONFIG = true; + +await $`TIMING=1 eslint --concurrency=auto --config ./tests/eslint/eslint.config.js ./`; diff --git a/tests/helpers/constants.js b/tests/helpers/constants.js index ca89c26e0c4b..8154b6c4c0b9 100644 --- a/tests/helpers/constants.js +++ b/tests/helpers/constants.js @@ -1,6 +1,8 @@ +import defineProperty from 'core-js-pure/es/object/define-property'; + export const DESCRIPTORS = !!(() => { try { - return Object.defineProperty({}, 'a', { + return defineProperty({}, 'a', { get() { return 7; }, @@ -12,7 +14,11 @@ export const GLOBAL = Function('return this')(); export const NATIVE = GLOBAL.NATIVE || false; -export const TYPED_ARRAYS = { +export const NODE = typeof Bun == 'undefined' && Object.prototype.toString.call(GLOBAL.process).slice(8, -1) === 'process'; + +export const BUN = typeof Bun != 'undefined' && Object.prototype.toString.call(GLOBAL.process).slice(8, -1) === 'process'; + +const $TYPED_ARRAYS = { Float32Array: 4, Float64Array: 8, Int8Array: 1, @@ -24,6 +30,25 @@ export const TYPED_ARRAYS = { Uint8ClampedArray: 1, }; +export const TYPED_ARRAYS = []; + +for (const name in $TYPED_ARRAYS) TYPED_ARRAYS.push({ + name, + TypedArray: GLOBAL[name], + bytes: $TYPED_ARRAYS[name], + $: Number, +}); + +export const TYPED_ARRAYS_WITH_BIG_INT = [...TYPED_ARRAYS]; + +for (const name of ['BigInt64Array', 'BigUint64Array']) if (GLOBAL[name]) TYPED_ARRAYS_WITH_BIG_INT.push({ + name, + TypedArray: GLOBAL[name], + bytes: 8, + // eslint-disable-next-line es/no-bigint -- safe + $: BigInt, +}); + export const LITTLE_ENDIAN = (() => { try { return new GLOBAL.Uint8Array(new GLOBAL.Uint16Array([1]).buffer)[0] === 1; @@ -32,18 +57,26 @@ export const LITTLE_ENDIAN = (() => { } })(); +// eslint-disable-next-line es/no-object-setprototypeof -- detection export const PROTO = !!Object.setPrototypeOf || '__proto__' in Object.prototype; -export const STRICT = !function () { - return this; -}(); +export let REDEFINABLE_PROTO = false; + +try { + // Chrome 27- bug, also a bug for native `JSON.parse` + defineProperty({}, '__proto__', { value: 42, writable: true, configurable: true, enumerable: true }); + REDEFINABLE_PROTO = true; +} catch { /* empty */ } export const STRICT_THIS = (function () { return this; })(); +export const STRICT = !STRICT_THIS; + export const FREEZING = !function () { try { + // eslint-disable-next-line es/no-object-isextensible, es/no-object-preventextensions -- detection return Object.isExtensible(Object.preventExtensions({})); } catch { return true; @@ -54,10 +87,26 @@ export const CORRECT_PROTOTYPE_GETTER = !function () { try { function F() { /* empty */ } F.prototype.constructor = null; + // eslint-disable-next-line es/no-object-getprototypeof -- detection return Object.getPrototypeOf(new F()) !== F.prototype; } catch { return true; } }(); +// FF < 23 bug +export const REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR = DESCRIPTORS && !function () { + try { + defineProperty([], 'length', { writable: false }); + } catch { + return true; + } +}(); + export const WHITESPACES = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; + +// eslint-disable-next-line es/no-number-maxsafeinteger -- safe +export const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; + +// eslint-disable-next-line es/no-number-minsafeinteger -- safe +export const MIN_SAFE_INTEGER = Number.MIN_SAFE_INTEGER || -9007199254740991; diff --git a/tests/helpers/helpers.js b/tests/helpers/helpers.js index a4051aa8ec18..4e2afe2dfa57 100644 --- a/tests/helpers/helpers.js +++ b/tests/helpers/helpers.js @@ -1,5 +1,11 @@ import Promise from 'core-js-pure/es/promise'; -import ITERATOR from 'core-js-pure/features/symbol/iterator'; +import ITERATOR from 'core-js-pure/es/symbol/iterator'; +import ASYNC_ITERATOR from 'core-js-pure/es/symbol/async-iterator'; + +export function is(a, b) { + // eslint-disable-next-line no-self-compare -- NaN check + return a === b ? a !== 0 || 1 / a === 1 / b : a !== a && b !== b; +} export function createIterator(elements, methods) { let index = 0; @@ -17,6 +23,18 @@ export function createIterator(elements, methods) { return iterator; } +export function createSetLike(elements) { + return { + size: elements.length, + has(it) { + return includes(elements, it); + }, + keys() { + return createIterator(elements); + }, + }; +} + export function createIterable(elements, methods) { const iterable = { called: false, @@ -40,16 +58,59 @@ export function createIterable(elements, methods) { return iterable; } +export function createAsyncIterable(elements, methods) { + const iterable = { + called: false, + received: false, + [ASYNC_ITERATOR]() { + iterable.received = true; + let index = 0; + const iterator = { + next() { + iterable.called = true; + return Promise.resolve({ + value: elements[index++], + done: index > elements.length, + }); + }, + }; + if (methods) for (const key in methods) iterator[key] = methods[key]; + return iterator; + }, + }; + return iterable; +} + +export function createConversionChecker(value, string) { + const checker = { + $valueOf: 0, + $toString: 0, + valueOf() { + checker.$valueOf++; + return value; + }, + toString() { + checker.$toString++; + return arguments.length > 1 ? string : String(value); + }, + }; + + return checker; +} + +export function arrayFromArrayLike(source) { + const { length } = source; + const result = Array(length); + for (let index = 0; index < length; index++) { + result[index] = source[index]; + } return result; +} + export function includes(target, wanted) { for (const element of target) if (wanted === element) return true; return false; } -export function is(a, b) { - // eslint-disable-next-line no-self-compare - return a === b ? a !== 0 || 1 / a === 1 / b : a != a && b != b; -} - export const nativeSubclass = (() => { try { if (Function(` @@ -63,9 +124,10 @@ export const nativeSubclass = (() => { } catch { /* empty */ } })(); -export function timeLimitedPromise(time, fn) { +export function timeLimitedPromise(time, functionOrPromise) { return Promise.race([ - new Promise(fn), new Promise((resolve, reject) => { + typeof functionOrPromise == 'function' ? new Promise(functionOrPromise) : functionOrPromise, + new Promise((resolve, reject) => { setTimeout(reject, time); }), ]); @@ -76,19 +138,45 @@ export function timeLimitedPromise(time, fn) { export function patchRegExp$exec(run) { return assert => { const originalExec = RegExp.prototype.exec; - // eslint-disable-next-line no-extend-native - RegExp.prototype.exec = function () { - return originalExec.apply(this, arguments); + // eslint-disable-next-line no-extend-native -- required for testing + RegExp.prototype.exec = function (...args) { + return originalExec.apply(this, args); }; try { return run(assert); - // In very old IE try / finally does not work without catch. - // eslint-disable-next-line no-useless-catch + // eslint-disable-next-line no-useless-catch -- in very old IE try / finally does not work without catch } catch (error) { throw error; } finally { - // eslint-disable-next-line no-extend-native + // eslint-disable-next-line no-extend-native -- required for testing RegExp.prototype.exec = originalExec; } }; } + +export function fromSource(source) { + try { + return Function(`return ${ source }`)(); + } catch { /* empty */ } +} + +export function arrayToBuffer(array) { + const { length } = array; + const buffer = new ArrayBuffer(length); + // eslint-disable-next-line es/no-typed-arrays -- safe + const view = new DataView(buffer); + for (let i = 0; i < length; ++i) { + view.setUint8(i, array[i]); + } + return buffer; +} + +export function bufferToArray(buffer) { + const array = []; + // eslint-disable-next-line es/no-typed-arrays -- safe + const view = new DataView(buffer); + for (let i = 0, { byteLength } = view; i < byteLength; ++i) { + array.push(view.getUint8(i)); + } + return array; +} diff --git a/tests/helpers/qunit-helpers.js b/tests/helpers/qunit-helpers.js index 542a2fcc6ec3..dce318dea6f6 100644 --- a/tests/helpers/qunit-helpers.js +++ b/tests/helpers/qunit-helpers.js @@ -1,171 +1,191 @@ -import { DESCRIPTORS, GLOBAL } from './constants'; -import isIterable from 'core-js-pure/features/is-iterable'; +import { DESCRIPTORS } from './constants.js'; +import assign from 'core-js-pure/es/object/assign'; +import defineProperties from 'core-js-pure/es/object/define-properties'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import reduce from 'core-js-pure/es/array/reduce'; +import isIterable from 'core-js-pure/es/is-iterable'; import ASYNC_ITERATOR from 'core-js-pure/es/symbol/async-iterator'; -import { is } from './helpers'; +import { is, arrayFromArrayLike } from './helpers.js'; -const { toString, propertyIsEnumerable } = Object.prototype.propertyIsEnumerable; +// for Babel template transform +// eslint-disable-next-line es/no-object-freeze -- safe +if (!Object.freeze) Object.freeze = Object; +// eslint-disable-next-line es/no-object-defineproperties -- safe +if (!DESCRIPTORS) Object.defineProperties = defineProperties; -GLOBAL.USE_FUNCTION_CONSTRUCTOR = true; +// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe +const { getOwnPropertyDescriptor } = Object; +const { toString, propertyIsEnumerable } = Object.prototype; -QUnit.assert.arity = function (fn, length, message) { - this.pushResult({ - result: fn.length === length, - actual: fn.length, - expected: length, - message: message || `arity is ${ length }`, - }); -}; +const { assert } = QUnit; -QUnit.assert.arrayEqual = function (a, b, message) { - let result = true; - if (a.length !== b.length) { - result = false; - } else { - for (let i = 0, { length } = a; i < length; ++i) { - if (!is(a[i], b[i])) { - result = false; - break; - } - } - } - this.pushResult({ - result, - actual: [].slice.call(a), - expected: [].slice.call(b), - message, - }); -}; - -QUnit.assert.epsilon = function (a, b, E, message) { - this.pushResult({ - result: Math.abs(a - b) <= (E != null ? E : 1e-11), - actual: a, - expected: b, - message, - }); -}; - -QUnit.assert.isFunction = function (fn, message) { - this.pushResult({ - result: typeof fn === 'function' || toString.call(fn).slice(8, -1) === 'Function', - actual: false, - expected: true, - message: message || 'is function', - }); -}; - -QUnit.assert.isAsyncIterable = function (it, message) { - this.pushResult({ - result: typeof it == 'object' && typeof it[ASYNC_ITERATOR] == 'function', - actual: false, - expected: true, - message: message || 'is async iterable', - }); -}; - -QUnit.assert.isIterable = function (it, message) { - this.pushResult({ - result: isIterable(it), - actual: false, - expected: true, - message: message || 'is iterable', - }); -}; - -QUnit.assert.isIterator = function (it, message) { - this.pushResult({ - result: typeof it === 'object' && typeof it.next === 'function', - actual: false, - expected: true, - message: message || 'is iterator', - }); -}; - -QUnit.assert.looksNative = function (fn, message) { - this.pushResult({ - result: /native code/.test(Function.prototype.toString.call(fn)), - actual: false, - expected: true, - message: message || 'looks native', - }); -}; - -QUnit.assert.name = function (fn, name, message) { - if (typeof fn == 'function' && 'name' in fn) { +assign(assert, { + arity(fn, length, message) { + this.same(fn.length, length, message ?? `The arity of the function is ${ length }`); + }, + arrayEqual(a, b, message) { + this.deepEqual(arrayFromArrayLike(a), arrayFromArrayLike(b), message); + }, + avoid(message = 'It should never be called') { + this.ok(false, message); + }, + // TODO: Drop from future `core-js` versions + // available from `qunit@2.21` + closeTo(actual, expected, delta, message) { + if (typeof delta != 'number') throw new TypeError('closeTo() requires a delta argument'); + const result = Math.abs(actual - expected) <= delta; this.pushResult({ - result: fn.name === name, - actual: fn.name, - expected: name, - message: message || `name is '${ name }'`, + result, + actual, + expected, + message: message ?? `The value should be within ${ delta } inclusive`, }); - } else { + }, + enumerable(O, key, message) { + const result = !DESCRIPTORS || propertyIsEnumerable.call(O, key); this.pushResult({ - result: true, - actual: true, - expected: true, - message: 'Function#name property test makes no sense', + result, + actual: result, + expected: 'The property should be enumerable', + message: DESCRIPTORS + ? message ?? `${ typeof key == 'symbol' ? 'property' : `'${ key }'` } is enumerable` + : 'Enumerability is not applicable', }); - } -}; - -QUnit.assert.enumerable = function (O, key, message) { - if (DESCRIPTORS) { + }, + // TODO: Drop from future `core-js` versions + // unavailable in `qunit@1` that's required for testing in IE9-, Chrome 38, etc. + false(value, message = 'The value is `false`') { + this.same(value, false, message); + }, + isAsyncIterable(actual, message = 'The value is async iterable') { this.pushResult({ - result: propertyIsEnumerable.call(O, key), - actual: false, - expected: true, - message: message || `${ typeof key === 'symbol' ? 'method' : `'${ key }'` } is enumerable`, + result: typeof actual == 'object' && typeof actual[ASYNC_ITERATOR] == 'function', + actual, + expected: 'The value should be async iterable', + message, }); - } else { + }, + isFunction(fn, message) { this.pushResult({ - result: true, - actual: true, - expected: true, - message: 'Enumerability is not applicable', + result: typeof fn == 'function' || toString.call(fn).slice(8, -1) === 'Function', + actual: typeof fn, + expected: 'The value should be a function', + message: message ?? 'The value is a function', }); - } -}; - -QUnit.assert.nonEnumerable = function (O, key, message) { - if (DESCRIPTORS) { + }, + isIterable(actual, message = 'The value is iterable') { this.pushResult({ - result: !propertyIsEnumerable.call(O, key), - actual: false, - expected: true, - message: message || `${ typeof key === 'symbol' ? 'method' : `'${ key }'` } is non-enumerable`, + result: isIterable(actual), + actual, + expected: 'The value should be iterable', + message, }); - } else { + }, + isIterator(actual, message = 'The object is an iterator') { this.pushResult({ - result: true, - actual: true, - expected: true, - message: 'Enumerability is not applicable', + result: typeof actual == 'object' && typeof actual.next == 'function', + actual, + expected: 'The object should be an iterator', + message, }); - } -}; - -QUnit.assert.notThrows = function (fn, message) { - let throws, result, error; - try { - result = fn(); - throws = false; - } catch (err) { - throws = true; - error = err; - } - this.pushResult({ - result: !throws && result, - actual: throws ? error : result, - expected: throws ? undefined : true, - message: message || 'does not throw', - }); -}; + }, + looksNative(fn, message = 'The function looks like a native') { + const source = Function.prototype.toString.call(fn); + this.pushResult({ + result: /native code/.test(source), + actual: source, + expected: 'The function should look like a native', + message, + }); + }, + name(fn, expected, message) { + const applicable = typeof fn == 'function' && 'name' in fn; + const actual = fn.name; + this.pushResult({ + result: applicable ? actual === expected : true, + actual, + expected, + message: applicable + ? message ?? `The function name is '${ expected }'` + : 'Function#name property test makes no sense', + }); + }, + nonConfigurable(O, key, message) { + const result = !DESCRIPTORS || !getOwnPropertyDescriptor(O, key)?.configurable; + this.pushResult({ + result, + actual: result, + expected: 'The property should be non-configurable', + message: DESCRIPTORS + ? message ?? `${ typeof key == 'symbol' ? 'property' : `'${ key }'` } is non-configurable` + : 'Configurability is not applicable', + }); + }, + nonEnumerable(O, key, message) { + const result = !DESCRIPTORS || !propertyIsEnumerable.call(O, key); + this.pushResult({ + result, + actual: result, + expected: 'The property should be non-enumerable', + message: DESCRIPTORS + ? message ?? `${ typeof key == 'symbol' ? 'property' : `'${ key }'` } is non-enumerable` + : 'Enumerability is not applicable', + }); + }, + nonWritable(O, key, message) { + const result = !DESCRIPTORS || !getOwnPropertyDescriptor(O, key)?.writable; + this.pushResult({ + result, + actual: result, + expected: 'The property should be non-writable', + message: DESCRIPTORS + ? message ?? `${ typeof key == 'symbol' ? 'property' : `'${ key }'` } is non-writable` + : 'Writability is not applicable', + }); + }, + notSame(actual, expected, message) { + this.pushResult({ + result: !is(actual, expected), + actual, + expected: 'Something different', + message, + }); + }, + notThrows(fn, message = 'Does not throw') { + let result = false; + let actual; + try { + actual = fn(); + result = true; + } catch (error) { + actual = error; + } + this.pushResult({ + result, + actual, + expected: 'It should not throw an error', + message, + }); + }, + required(message = 'It should be called') { + this.ok(true, message); + }, + same(actual, expected, message) { + this.pushResult({ + result: is(actual, expected), + actual, + expected, + message, + }); + }, + // TODO: Drop from future `core-js` versions + // unavailable in `qunit@1` that's required for testing in IE9-, Chrome 38, etc. + true(value, message = 'The value is `true`') { + this.same(value, true, message); + }, +}); -QUnit.assert.same = function (a, b, message) { - this.pushResult({ - result: is(a, b), - actual: a, - expected: b, - message, - }); -}; +assert.skip = reduce(getOwnPropertyNames(assert), (skip, method) => { + skip[method] = () => { /* empty */ }; + return skip; +}, {}); diff --git a/tests/observables/adapter-pure.js b/tests/observables/adapter-pure.js deleted file mode 100644 index 3de907621337..000000000000 --- a/tests/observables/adapter-pure.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict'; -const core = require('../../packages/core-js-pure'); -global.Promise = core.Promise; -global.Symbol = core.Symbol; -// eslint-disable-next-line import/no-unresolved -require('../bundles/observables-tests/default').runTests(core.Observable); diff --git a/tests/observables/adapter.js b/tests/observables/adapter.js deleted file mode 100644 index 63530fa3b79b..000000000000 --- a/tests/observables/adapter.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; -delete global.Observable; -require('../../packages/core-js'); -// eslint-disable-next-line import/no-unresolved -require('../bundles/observables-tests/default').runTests(global.Observable); diff --git a/tests/observables/adapter.mjs b/tests/observables/adapter.mjs new file mode 100644 index 000000000000..b600aeddeca2 --- /dev/null +++ b/tests/observables/adapter.mjs @@ -0,0 +1,13 @@ +/* eslint-disable import/no-dynamic-require -- dynamic */ +delete globalThis.Observable; + +const pkg = argv.pure ? 'core-js-pure' : 'core-js'; + +// eslint-disable-next-line import/no-unresolved -- generated later +const { runTests } = require('./bundles/observables-tests/default'); + +globalThis.Symbol = require(`../../packages/${ pkg }/full/symbol`); +globalThis.Promise = require(`../../packages/${ pkg }/full/promise`); +const Observable = require(`../../packages/${ pkg }/full/observable`); + +runTests(Observable); diff --git a/tests/observables/package-lock.json b/tests/observables/package-lock.json new file mode 100644 index 000000000000..fd74545abec3 --- /dev/null +++ b/tests/observables/package-lock.json @@ -0,0 +1,1008 @@ +{ + "name": "tests/observables", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests/observables", + "devDependencies": { + "@babel/cli": "^7.28.3", + "es-observable": "tc39/proposal-observable#d3404f06bc70c7c578a5047dfb3dc813730e3319", + "moon-unit": "0.2.2" + } + }, + "node_modules/@babel/cli": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.28.3.tgz", + "integrity": "sha512-n1RU5vuCX0CsaqaXm9I0KUCNKNQMy5epmzl/xdSSm70bSqhg9GWhgeosypyQLc0bK24+Xpk1WGzZlI9pJtkZdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.28", + "commander": "^6.2.0", + "convert-source-map": "^2.0.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.2.0", + "make-dir": "^2.1.0", + "slash": "^2.0.0" + }, + "bin": { + "babel": "bin/babel.js", + "babel-external-helpers": "bin/babel-external-helpers.js" + }, + "engines": { + "node": ">=6.9.0" + }, + "optionalDependencies": { + "@nicolo-ribaudo/chokidar-2": "2.1.8-no-fsevents.3", + "chokidar": "^3.6.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nicolo-ribaudo/chokidar-2": { + "version": "2.1.8-no-fsevents.3", + "resolved": "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.3.tgz", + "integrity": "sha512-s88O1aVtXftvp5bCPB7WnmXc5IwOZZ7YPuwNPt+GtOOXpPvad1LfbmjYv+qII7zP6RU2QGnqve27dnLycEnyEQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.10", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.10.tgz", + "integrity": "sha512-2VIKvDx8Z1a9rTB2eCkdPE5nSe28XnA+qivGnWHoB40hMMt/h1hSz0960Zqsn6ZyxWXUie0EBdElKv8may20AA==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001761", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001761.tgz", + "integrity": "sha512-JF9ptu1vP2coz98+5051jZ4PwQgd2ni8A+gYSN7EA7dPKIMf0pDlSUxhdmVOaV3/fYK5uWBkgSXJaRLr4+3A6g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0", + "peer": true + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/es-observable": { + "version": "0.3.0", + "resolved": "git+ssh://git@github.com/tc39/proposal-observable.git#d3404f06bc70c7c578a5047dfb3dc813730e3319", + "integrity": "sha512-9dpXmMu1Ssl24wqJGFHQUdquFwEE9P/u9UQjMLuR5XYQAzz0acEOLTMhYncVOjNcqSswFjftTe8dgAj0sqz1JA==", + "dev": true + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "optional": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "peer": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/moon-unit": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/moon-unit/-/moon-unit-0.2.2.tgz", + "integrity": "sha512-MJMMeBg1u5Colum/DhhKZtw6SUQet2hg298xrm+5+ScQH+t6YNSMMcD4sQ2mA8/7hKXK7pv0p4dEgPyVB5U7UQ==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "peer": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC", + "peer": true + } + } +} diff --git a/tests/observables/package.json b/tests/observables/package.json new file mode 100644 index 000000000000..e97f1c29fcad --- /dev/null +++ b/tests/observables/package.json @@ -0,0 +1,8 @@ +{ + "name": "tests/observables", + "devDependencies": { + "@babel/cli": "^7.28.3", + "es-observable": "tc39/proposal-observable#d3404f06bc70c7c578a5047dfb3dc813730e3319", + "moon-unit": "0.2.2" + } +} diff --git a/tests/observables/runner.mjs b/tests/observables/runner.mjs new file mode 100644 index 000000000000..1e9ff3923150 --- /dev/null +++ b/tests/observables/runner.mjs @@ -0,0 +1,5 @@ +await $`babel --config-file ../../babel.config.js node_modules/es-observable/test/ -d ./bundles/observables-tests/`; + +for (const mode of ['global', 'pure']) { + await $`zx adapter.mjs --${ mode }`; +} diff --git a/tests/promises-aplus-native.html b/tests/promises-aplus-native.html deleted file mode 100644 index 73910238514b..000000000000 --- a/tests/promises-aplus-native.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - Promises/A+ Tests, Against Your Browser! - - - -
- - - - - - diff --git a/tests/promises-aplus.html b/tests/promises-aplus.html deleted file mode 100644 index 31a612c1fb6f..000000000000 --- a/tests/promises-aplus.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Promises/A+ Tests, Against Your Browser! - - - -
- - - - - - - diff --git a/tests/promises-aplus/adapter.js b/tests/promises-aplus/adapter.js deleted file mode 100644 index b3fca75baacd..000000000000 --- a/tests/promises-aplus/adapter.js +++ /dev/null @@ -1,28 +0,0 @@ -delete global.Promise; - -var Promise = require('../../packages/core-js').Promise; -var assert = require('assert'); - -module.exports = { - deferred: function () { - var deferred = {}; - deferred.promise = new Promise(function (resolve, reject) { - deferred.resolve = resolve; - deferred.reject = reject; - }); - return deferred; - }, - resolved: function (value) { - return Promise.resolve(value); - }, - rejected: function (reason) { - return Promise.reject(reason); - }, - defineGlobalPromise: function (global) { - global.Promise = Promise; - global.assert = assert; - }, - removeGlobalPromise: function () { - delete global.Promise; - } -}; diff --git a/tests/promises/adapter.js b/tests/promises/adapter.js new file mode 100644 index 000000000000..9b126759dc41 --- /dev/null +++ b/tests/promises/adapter.js @@ -0,0 +1,32 @@ +'use strict'; +delete globalThis.Promise; + +const pkg = process.argv.includes('--pure') ? 'core-js-pure' : 'core-js'; + +// eslint-disable-next-line import/no-dynamic-require -- dynamic +const Promise = require(`../../packages/${ pkg }/es/promise`); +const assert = require('node:assert'); + +module.exports = { + deferred() { + const deferred = {}; + deferred.promise = new Promise((resolve, reject) => { + deferred.resolve = resolve; + deferred.reject = reject; + }); + return deferred; + }, + resolved(value) { + return Promise.resolve(value); + }, + rejected(reason) { + return Promise.reject(reason); + }, + defineGlobalPromise() { + globalThis.Promise = Promise; + globalThis.assert = assert; + }, + removeGlobalPromise() { + delete globalThis.Promise; + }, +}; diff --git a/tests/promises/package-lock.json b/tests/promises/package-lock.json new file mode 100644 index 000000000000..4609854f4d6c --- /dev/null +++ b/tests/promises/package-lock.json @@ -0,0 +1,743 @@ +{ + "name": "tests/promises", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests/promises", + "devDependencies": { + "promises-aplus-tests": "^2.1.2", + "promises-es6-tests": "~0.5.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/commander": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", + "integrity": "sha512-CD452fnk0jQyk3NfnK+KkR/hUPoHt5pVaKHogtyyv3N0U4QfAal9W0/rXLOg/vVZgQKa7jdtXypKs1YAip11uQ==", + "dev": true, + "engines": { + "node": ">= 0.6.x" + } + }, + "node_modules/debug": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", + "integrity": "sha512-X0rGvJcskG1c3TgSCPqHJ0XJgwlcvOC7elJ5Y0hYuKBZoVqWpAMfLOeIh2UI/DCQ5ruodIjvsugZtjUYUw2pUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "0.7.1" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/diff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", + "integrity": "sha512-VzVc42hMZbYU9Sx/ltb7KYuQ6pqAw+cbFWVy4XKdkuEL2CFaRLGEnISPs7YdzaUGpi+CpIqvRmu7hPQ4T7EQ5w==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz", + "integrity": "sha512-cQpUid7bdTUnFin8S7BnNdOk+/eDqQmKgCANSyd/jAhrKEvxUvr9VQ8XZzXiOtest8NLfk3FSBZzwvemZNQ6Vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/formatio": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz", + "integrity": "sha512-cPh7is6k3d8tIUh+pnXXuAbD/uhSXGgqLPw0UrYpv5lfdJ+MMMSjx40JNpqP7Top9Nt25YomWEiRmkHbOvkCaA==", + "deprecated": "This package is unmaintained. Use @sinonjs/formatio instead", + "dev": true, + "dependencies": { + "samsam": "~1.1" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", + "integrity": "sha512-hVb0zwEZwC1FXSKRPFTeOtN7AArJcJlI6ULGLtrstaswKNlrTJqAA+1lYlSUop4vjA423xlBzqfVS3iWGlqJ+g==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "BSD", + "dependencies": { + "inherits": "2", + "minimatch": "0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/growl": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha512-RTBwDHhNuOx4F0hqzItc/siXCasGfC4DeWcBamclWd+6jWtBaeB/SGbMkGf0eiQoW7ib8JpvOgnUsmgMHI3Mfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arguments": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.2.0.tgz", + "integrity": "sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/jade": { + "version": "0.26.3", + "resolved": "https://registry.npmjs.org/jade/-/jade-0.26.3.tgz", + "integrity": "sha512-mkk3vzUHFjzKjpCXeu+IjXeZD+QOTjUUdubgmHtHTDwvAO2ZTkMTTVrapts5CWz3JvJryh/4KWZpjeZrCepZ3A==", + "deprecated": "Jade has been renamed to pug, please install the latest version of pug instead of jade", + "dev": true, + "dependencies": { + "commander": "0.6.1", + "mkdirp": "0.3.0" + }, + "bin": { + "jade": "bin/jade" + } + }, + "node_modules/jade/node_modules/commander": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-0.6.1.tgz", + "integrity": "sha512-0fLycpl1UMTGX257hRsu/arL/cUbcvQM4zMKwvLvzXtfdezIV4yotPS2dYtknF+NmEfWSoCEF6+hj9XLm/6hEw==", + "dev": true, + "engines": { + "node": ">= 0.4.x" + } + }, + "node_modules/jade/node_modules/mkdirp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz", + "integrity": "sha512-OHsdUcVAQ6pOtg5JYWpCBo9W/GySVuwvP9hueRMW7UqshC0tbfzLv8wjySTPm3tfUZ/21CE9E1pJagOA91Pxew==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "license": "MIT/X11", + "engines": { + "node": "*" + } + }, + "node_modules/lolex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-1.3.2.tgz", + "integrity": "sha512-YYp8cqz7/8eruZ15L1mzcPkvLYxipfdsWIDESvNdNmQP9o7TsDitRhNuV2xb7aFu2ofZngao1jiVrVZ842x4BQ==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/lru-cache": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", + "integrity": "sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/minimatch": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", + "integrity": "sha512-WFX1jI1AaxNTZVOHLBVazwTWKaQjoykSzCBNXB72vDTCzopQGtyP91tKdFK5cv1+qMwPyiTu1HqUriqplI8pcA==", + "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue", + "dev": true, + "license": "MIT", + "dependencies": { + "lru-cache": "2", + "sigmund": "~1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "0.0.8" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-2.5.3.tgz", + "integrity": "sha512-jNt2iEk9FPmZLzL+sm4FNyOIDYXf2wUU6L4Cc8OIKK/kzgMHKPi4YhTZqG4bW4kQVdIv6wutDybRhXfdnujA1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "2.3.0", + "debug": "2.2.0", + "diff": "1.4.0", + "escape-string-regexp": "1.0.2", + "glob": "3.2.11", + "growl": "1.9.2", + "jade": "0.26.3", + "mkdirp": "0.5.1", + "supports-color": "1.2.0", + "to-iso-string": "0.0.2" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 0.8.x" + } + }, + "node_modules/ms": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", + "integrity": "sha512-lRLiIR9fSNpnP6TC4v8+4OU7oStC01esuNowdQ34L+Gk8e5Puoc88IqJ+XAY/B3Mn2ZKis8l8HX90oU8ivzUHg==", + "dev": true + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/promises-aplus-tests": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/promises-aplus-tests/-/promises-aplus-tests-2.1.2.tgz", + "integrity": "sha512-XiDfjQqx+rHLof8CU9xPOMLsjiXXxr3fkjE7WJjUzXttffB8K/nsnNsPTcwS4VvHliSjGVsYVqIjFeTHw53f5w==", + "dev": true, + "license": "WTFPL", + "dependencies": { + "mocha": "^2.5.3", + "sinon": "^1.10.3", + "underscore": "~1.8.3" + }, + "bin": { + "promises-aplus-tests": "lib/cli.js" + } + }, + "node_modules/promises-es6-tests": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/promises-es6-tests/-/promises-es6-tests-0.5.0.tgz", + "integrity": "sha512-pIv6ssXSnKGoWHf0AnLF9RiPzvbEGGPyYsxWfER/dJ98HI5DdChujb1t64ULgDyqL9g4xv6/fn1erJ0KAynwng==", + "dev": true, + "license": "ECMA", + "bin": { + "promises-es6-tests": "lib/cli.js" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/samsam": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz", + "integrity": "sha512-iVL7LibpM3tl4rQPweOXXrmjGegxx27flTOjQEZD3PXe4oZNFzuz6Si4mgleK/JWU/hyCvtV01RUovjvBEpDmw==", + "deprecated": "This package has been deprecated in favour of @sinonjs/samsam", + "dev": true + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g==", + "dev": true, + "license": "ISC" + }, + "node_modules/sinon": { + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", + "integrity": "sha512-M9rtyQxKfcTTdB64rpPSRaTzOvunb+HHPv/3PxvNPrEDnFSny95Pi6/3VoD471ody0ay0IHyzT3BErfcLXj6NA==", + "deprecated": "16.1.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "formatio": "1.1.1", + "lolex": "1.3.2", + "samsam": "1.1.2", + "util": ">=0.10.3 <1" + }, + "engines": { + "node": ">=0.1.103" + } + }, + "node_modules/supports-color": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-1.2.0.tgz", + "integrity": "sha512-mS5xsnjTh5b7f2DM6bch6lR582UCOTphzINlZnDsfpIRrwI6r58rb6YSSGsdexkm8qw2bBVO2ID2fnJOTuLiPA==", + "dev": true, + "license": "MIT", + "bin": { + "supports-color": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-iso-string": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/to-iso-string/-/to-iso-string-0.0.2.tgz", + "integrity": "sha512-oeHLgfWA7d0CPQa6h0+i5DAJZISz5un0d5SHPkw+Untclcvzv9T+AC3CvGXlZJdOlIbxbTfyyzlqCXc5hjpXYg==", + "deprecated": "to-iso-string has been deprecated, use @segment/to-iso-string instead.", + "dev": true, + "license": "MIT" + }, + "node_modules/underscore": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", + "integrity": "sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg==", + "dev": true, + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + } + } +} diff --git a/tests/promises/package.json b/tests/promises/package.json new file mode 100644 index 000000000000..d6c32ebf3252 --- /dev/null +++ b/tests/promises/package.json @@ -0,0 +1,7 @@ +{ + "name": "tests/promises", + "devDependencies": { + "promises-aplus-tests": "^2.1.2", + "promises-es6-tests": "~0.5.0" + } +} diff --git a/tests/promises/runner.mjs b/tests/promises/runner.mjs new file mode 100644 index 000000000000..7568ba8b5d3c --- /dev/null +++ b/tests/promises/runner.mjs @@ -0,0 +1,3 @@ +for (const mode of ['global', 'pure']) for (const set of ['aplus', 'es6']) { + await $`promises-${ set }-tests adapter --timeout 1000 --color --${ mode }`; +} diff --git a/tests/publint/package-lock.json b/tests/publint/package-lock.json new file mode 100644 index 000000000000..078bca69cf2f --- /dev/null +++ b/tests/publint/package-lock.json @@ -0,0 +1,85 @@ +{ + "name": "tests/publint", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests/publint", + "devDependencies": { + "publint": "^0.3.16" + } + }, + "node_modules/@publint/pack": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@publint/pack/-/pack-0.1.2.tgz", + "integrity": "sha512-S+9ANAvUmjutrshV4jZjaiG8XQyuJIZ8a4utWmN/vW1sgQ9IfBnPndwkmQYw53QmouOIytT874u65HEmu6H5jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://bjornlu.com/sponsor" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/package-manager-detector": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz", + "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/publint": { + "version": "0.3.16", + "resolved": "https://registry.npmjs.org/publint/-/publint-0.3.16.tgz", + "integrity": "sha512-MFqyfRLAExPVZdTQFwkAQELzA8idyXzROVOytg6nEJ/GEypXBUmMGrVaID8cTuzRS1U5L8yTOdOJtMXgFUJAeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@publint/pack": "^0.1.2", + "package-manager-detector": "^1.6.0", + "picocolors": "^1.1.1", + "sade": "^1.8.1" + }, + "bin": { + "publint": "src/cli.js" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://bjornlu.com/sponsor" + } + }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + } + } +} diff --git a/tests/publint/package.json b/tests/publint/package.json new file mode 100644 index 000000000000..9b011eee0837 --- /dev/null +++ b/tests/publint/package.json @@ -0,0 +1,6 @@ +{ + "name": "tests/publint", + "devDependencies": { + "publint": "^0.3.16" + } +} diff --git a/tests/publint/runner.mjs b/tests/publint/runner.mjs new file mode 100644 index 000000000000..33696cfba8bf --- /dev/null +++ b/tests/publint/runner.mjs @@ -0,0 +1,5 @@ +const pkgs = await glob('packages/*/package.json'); + +await Promise.all(pkgs.map(async pkg => { + return $`publint ${ pkg.slice(0, -13) }`; +})); diff --git a/tests/pure.html b/tests/pure.html deleted file mode 100644 index cc742452e36d..000000000000 --- a/tests/pure.html +++ /dev/null @@ -1,8 +0,0 @@ - - -Core - -
-
- - \ No newline at end of file diff --git a/tests/pure/es.array.concat.js b/tests/pure/es.array.concat.js deleted file mode 100644 index c4fb5ac6152f..000000000000 --- a/tests/pure/es.array.concat.js +++ /dev/null @@ -1,31 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; -import concat from 'core-js-pure/features/array/concat'; - -/* eslint-disable no-sparse-arrays */ -QUnit.test('Array#concat', assert => { - assert.isFunction(concat); - let array = [1, 2]; - const sparseArray = [1, , 2]; - const nonSpreadableArray = [1, 2]; - nonSpreadableArray[Symbol.isConcatSpreadable] = false; - const arrayLike = { 0: 1, 1: 2, length: 2 }; - const spreadableArrayLike = { 0: 1, 1: 2, length: 2, [Symbol.isConcatSpreadable]: true }; - assert.deepEqual(concat(array), [1, 2], '#1'); - assert.deepEqual(concat(sparseArray), [1, , 2], '#2'); - assert.deepEqual(concat(nonSpreadableArray), [[1, 2]], '#3'); - assert.deepEqual(concat(arrayLike), [{ 0: 1, 1: 2, length: 2 }], '#4'); - assert.deepEqual(concat(spreadableArrayLike), [1, 2], '#5'); - assert.deepEqual(concat([], array), [1, 2], '#6'); - assert.deepEqual(concat([], sparseArray), [1, , 2], '#7'); - assert.deepEqual(concat([], nonSpreadableArray), [[1, 2]], '#8'); - assert.deepEqual(concat([], arrayLike), [{ 0: 1, 1: 2, length: 2 }], '#9'); - assert.deepEqual(concat([], spreadableArrayLike), [1, 2], '#10'); - assert.deepEqual(concat(array, sparseArray, nonSpreadableArray, arrayLike, spreadableArrayLike), [ - 1, 2, 1, , 2, [1, 2], { 0: 1, 1: 2, length: 2 }, 1, 2, - ], '#11'); - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(concat(array).foo, 1, '@@species'); -}); diff --git a/tests/pure/es.array.copy-within.js b/tests/pure/es.array.copy-within.js deleted file mode 100644 index 8c0b3995a0c0..000000000000 --- a/tests/pure/es.array.copy-within.js +++ /dev/null @@ -1,25 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import copyWithin from 'core-js-pure/features/array/copy-within'; - -QUnit.test('Array#copyWithin', assert => { - assert.isFunction(copyWithin); - const array = [1]; - assert.strictEqual(copyWithin(array, 0), array); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 0, 3), [4, 5, 3, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 1, 3), [1, 4, 5, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 1, 2), [1, 3, 4, 5, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 2, 2), [1, 2, 3, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 0, 3, 4), [4, 2, 3, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 1, 3, 4), [1, 4, 3, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 1, 2, 4), [1, 3, 4, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 0, -2), [4, 5, 3, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 0, -2, -1), [4, 2, 3, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], -4, -3, -2), [1, 3, 3, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], -4, -3, -1), [1, 3, 4, 4, 5]); - assert.deepEqual(copyWithin([1, 2, 3, 4, 5], -4, -3), [1, 3, 4, 5, 5]); - if (STRICT) { - assert.throws(() => copyWithin(null, 0), TypeError); - assert.throws(() => copyWithin(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.array.every.js b/tests/pure/es.array.every.js deleted file mode 100644 index c1b90fc3051b..000000000000 --- a/tests/pure/es.array.every.js +++ /dev/null @@ -1,32 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import every from 'core-js-pure/features/array/every'; - -QUnit.test('Array#every', assert => { - assert.isFunction(every); - const array = [1]; - const context = {}; - every(array, function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.ok(every([1, 2, 3], it => typeof it === 'number')); - assert.ok(every([1, 2, 3], it => it < 4)); - assert.ok(!every([1, 2, 3], it => it < 3)); - assert.ok(!every([1, 2, 3], it => typeof it === 'string')); - assert.ok(every([1, 2, 3], function () { - return +this === 1; - }, 1)); - let rez = ''; - every([1, 2, 3], (value, key) => rez += key); - assert.ok(rez === '012'); - const arr = [1, 2, 3]; - assert.ok(every(arr, (value, key, that) => that === arr)); - if (STRICT) { - assert.throws(() => every(null, () => { /* empty */ }), TypeError); - assert.throws(() => every(undefined, () => { /* empty */ }), TypeError); - } -}); diff --git a/tests/pure/es.array.fill.js b/tests/pure/es.array.fill.js deleted file mode 100644 index da54eb028ae3..000000000000 --- a/tests/pure/es.array.fill.js +++ /dev/null @@ -1,19 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import fill from 'core-js-pure/features/array/fill'; - -QUnit.test('Array#fill', assert => { - assert.isFunction(fill); - const array = fill(Array(5), 5); - assert.strictEqual(array, array); - assert.deepEqual(fill(Array(5), 5), [5, 5, 5, 5, 5]); - assert.deepEqual(fill(Array(5), 5, 1), [undefined, 5, 5, 5, 5]); - assert.deepEqual(fill(Array(5), 5, 1, 4), [undefined, 5, 5, 5, undefined]); - assert.deepEqual(fill(Array(5), 5, 6, 1), [undefined, undefined, undefined, undefined, undefined]); - assert.deepEqual(fill(Array(5), 5, -3, 4), [undefined, undefined, 5, 5, undefined]); - assert.arrayEqual(fill({ length: 5 }, 5), [5, 5, 5, 5, 5]); - if (STRICT) { - assert.throws(() => fill(null, 0), TypeError); - assert.throws(() => fill(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.array.filter.js b/tests/pure/es.array.filter.js deleted file mode 100644 index d751315ffe2b..000000000000 --- a/tests/pure/es.array.filter.js +++ /dev/null @@ -1,27 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import Symbol from 'core-js-pure/features/symbol'; -import filter from 'core-js-pure/features/array/filter'; - -QUnit.test('Array#filter', assert => { - assert.isFunction(filter); - let array = [1]; - const context = {}; - filter(array, function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.deepEqual([1, 2, 3, 4, 5], filter([1, 2, 3, 'q', {}, 4, true, 5], it => typeof it === 'number')); - if (STRICT) { - assert.throws(() => filter(null, () => { /* empty */ }), TypeError); - assert.throws(() => filter(undefined, () => { /* empty */ }), TypeError); - } - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(filter(array, Boolean).foo, 1, '@@species'); -}); diff --git a/tests/pure/es.array.find-index.js b/tests/pure/es.array.find-index.js deleted file mode 100644 index 677a2ef6097f..000000000000 --- a/tests/pure/es.array.find-index.js +++ /dev/null @@ -1,20 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import findIndex from 'core-js-pure/features/array/find-index'; - -QUnit.test('Array#findIndex', assert => { - assert.isFunction(findIndex); - const array = [1]; - const context = {}; - findIndex(array, function (value, key, that) { - assert.strictEqual(this, context); - assert.strictEqual(value, 1); - assert.strictEqual(key, 0); - assert.strictEqual(that, array); - }, context); - assert.strictEqual(findIndex([1, 3, NaN, 42, {}], it => it === 42), 3); - if (STRICT) { - assert.throws(() => findIndex(null, 0), TypeError); - assert.throws(() => findIndex(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.array.find.js b/tests/pure/es.array.find.js deleted file mode 100644 index ffa5c91d5097..000000000000 --- a/tests/pure/es.array.find.js +++ /dev/null @@ -1,21 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import find from 'core-js-pure/features/array/find'; - -QUnit.test('Array#find', assert => { - assert.isFunction(find); - const array = [1]; - const context = {}; - find(array, function (value, key, that) { - assert.strictEqual(this, context); - assert.strictEqual(value, 1); - assert.strictEqual(key, 0); - assert.strictEqual(that, array); - }, context); - assert.strictEqual(find([1, 3, NaN, 42, {}], it => it === 42), 42); - assert.strictEqual(find([1, 3, NaN, 42, {}], it => it === 43), undefined); - if (STRICT) { - assert.throws(() => find(null, 0), TypeError); - assert.throws(() => find(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.array.flat-map.js b/tests/pure/es.array.flat-map.js deleted file mode 100644 index cf29f67d3b28..000000000000 --- a/tests/pure/es.array.flat-map.js +++ /dev/null @@ -1,27 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import flatMap from 'core-js-pure/features/array/flat-map'; - -QUnit.test('Array#flatMap', assert => { - assert.isFunction(flatMap); - assert.deepEqual(flatMap([], it => it), []); - assert.deepEqual(flatMap([1, 2, 3], it => it), [1, 2, 3]); - assert.deepEqual(flatMap([1, 2, 3], it => [it, it]), [1, 1, 2, 2, 3, 3]); - assert.deepEqual(flatMap([1, 2, 3], it => [[it], [it]]), [[1], [1], [2], [2], [3], [3]]); - assert.deepEqual(flatMap([1, [2, 3]], () => 1), [1, 1]); - const array = [1]; - const context = {}; - flatMap(array, function (value, index, that) { - assert.same(value, 1); - assert.same(index, 0); - assert.same(that, array); - assert.same(this, context); - }, context); - if (STRICT) { - assert.throws(() => flatMap(null, it => it), TypeError); - assert.throws(() => flatMap(undefined, it => it), TypeError); - } - assert.notThrows(() => flatMap({ length: -1 }, () => { - throw new Error(); - }).length === 0, 'uses ToLength'); -}); diff --git a/tests/pure/es.array.flat.js b/tests/pure/es.array.flat.js deleted file mode 100644 index 0f510e4bf941..000000000000 --- a/tests/pure/es.array.flat.js +++ /dev/null @@ -1,28 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -import flat from 'core-js-pure/features/array/flat'; -import defineProperty from 'core-js-pure/features/object/define-property'; - -QUnit.test('Array#flat', assert => { - assert.isFunction(flat); - assert.deepEqual(flat([]), []); - const array = [1, [2, 3], [4, [5, 6]]]; - assert.deepEqual(flat(array, 0), array); - assert.deepEqual(flat(array, 1), [1, 2, 3, 4, [5, 6]]); - assert.deepEqual(flat(array), [1, 2, 3, 4, [5, 6]]); - assert.deepEqual(flat(array, 2), [1, 2, 3, 4, 5, 6]); - assert.deepEqual(flat(array, 3), [1, 2, 3, 4, 5, 6]); - assert.deepEqual(flat(array, -1), array); - assert.deepEqual(flat(array, Infinity), [1, 2, 3, 4, 5, 6]); - if (STRICT) { - assert.throws(() => flat(null), TypeError); - assert.throws(() => flat(undefined), TypeError); - } - if (DESCRIPTORS) { - assert.notThrows(() => flat(defineProperty({ length: -1 }, 0, { - get() { - throw new Error(); - }, - })).length === 0, 'uses ToLength'); - } -}); diff --git a/tests/pure/es.array.for-each.js b/tests/pure/es.array.for-each.js deleted file mode 100644 index 2fbd80184910..000000000000 --- a/tests/pure/es.array.for-each.js +++ /dev/null @@ -1,47 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import forEach from 'core-js-pure/features/array/for-each'; - -QUnit.test('Array#forEach', assert => { - assert.isFunction(forEach); - let array = [1]; - const context = {}; - forEach(array, function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - let result = ''; - forEach([1, 2, 3], it => { - result += it; - }); - assert.ok(result === '123'); - result = ''; - forEach([1, 2, 3], (value, key) => { - result += key; - }); - assert.ok(result === '012'); - result = ''; - forEach([1, 2, 3], (value, key, that) => { - result += that; - }); - assert.ok(result === '1,2,31,2,31,2,3'); - result = ''; - forEach([1, 2, 3], function () { - result += this; - }, 1); - assert.ok(result === '111'); - result = ''; - array = []; - array[5] = ''; - forEach(array, (value, key) => { - result += key; - }); - assert.ok(result === '5'); - if (STRICT) { - assert.throws(() => forEach(null, () => { /* empty */ }), TypeError); - assert.throws(() => forEach(undefined, () => { /* empty */ }), TypeError); - } -}); diff --git a/tests/pure/es.array.from.js b/tests/pure/es.array.from.js deleted file mode 100644 index 9b858e7dd8b5..000000000000 --- a/tests/pure/es.array.from.js +++ /dev/null @@ -1,124 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; -import { createIterable } from '../helpers/helpers'; - -import Symbol from 'core-js-pure/features/symbol'; -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; -import from from 'core-js-pure/features/array/from'; -import defineProperty from 'core-js-pure/features/object/define-property'; - -QUnit.test('Array.from', assert => { - assert.isFunction(from); - assert.arity(from, 1); - let types = { - 'array-like': { - length: '3', - 0: '1', - 1: '2', - 2: '3', - }, - arguments: function () { - return arguments; - }('1', '2', '3'), - array: ['1', '2', '3'], - iterable: createIterable(['1', '2', '3']), - string: '123', - }; - for (const type in types) { - const data = types[type]; - assert.arrayEqual(from(data), ['1', '2', '3'], `Works with ${ type }`); - assert.arrayEqual(from(data, it => it ** 2), [1, 4, 9], `Works with ${ type } + mapFn`); - } - types = { - 'array-like': { - length: 1, - 0: 1, - }, - arguments: function () { - return arguments; - }(1), - array: [1], - iterable: createIterable([1]), - string: '1', - }; - for (const type in types) { - const data = types[type]; - const context = {}; - assert.arrayEqual(from(data, function (value, key) { - assert.same(this, context, `Works with ${ type }, correct callback context`); - assert.same(value, type === 'string' ? '1' : 1, `Works with ${ type }, correct callback key`); - assert.same(key, 0, `Works with ${ type }, correct callback value`); - assert.same(arguments.length, 2, `Works with ${ type }, correct callback arguments number`); - return 42; - }, context), [42], `Works with ${ type }, correct result`); - } - const primitives = [false, true, 0]; - for (const primitive of primitives) { - assert.arrayEqual(from(primitive), [], `Works with ${ primitive }`); - } - assert.throws(() => from(null), TypeError, 'Throws on null'); - assert.throws(() => from(undefined), TypeError, 'Throws on undefined'); - assert.arrayEqual(from('𠮷𠮷𠮷'), ['𠮷', '𠮷', '𠮷'], 'Uses correct string iterator'); - let done = true; - from(createIterable([1, 2, 3], { - return() { - return done = false; - }, - }), () => false); - assert.ok(done, '.return #default'); - done = false; - try { - from(createIterable([1, 2, 3], { - return() { - return done = true; - }, - }), () => { - throw new Error(); - }); - } catch { /* empty */ } - assert.ok(done, '.return #throw'); - class C { /* empty */ } - let instance = from.call(C, createIterable([1, 2])); - assert.ok(instance instanceof C, 'generic, iterable case, instanceof'); - assert.arrayEqual(instance, [1, 2], 'generic, iterable case, elements'); - instance = from.call(C, { - 0: 1, - 1: 2, - length: 2, - }); - assert.ok(instance instanceof C, 'generic, array-like case, instanceof'); - assert.arrayEqual(instance, [1, 2], 'generic, array-like case, elements'); - let array = [1, 2, 3]; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return getIteratorMethod([]).call(this); - }; - assert.arrayEqual(from(array), [1, 2, 3], 'Array with custom iterator, elements'); - assert.ok(done, 'call @@iterator in Array with custom iterator'); - array = [1, 2, 3]; - delete array[1]; - assert.arrayEqual(from(array, String), ['1', 'undefined', '3'], 'Ignores holes'); - assert.notThrows(() => from({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }), 'Uses ToLength'); - assert.arrayEqual(from([], undefined), [], 'Works with undefined as asecond argument'); - assert.throws(() => from([], null), TypeError, 'Throws with null as second argument'); - assert.throws(() => from([], 0), TypeError, 'Throws with 0 as second argument'); - assert.throws(() => from([], ''), TypeError, 'Throws with "" as second argument'); - assert.throws(() => from([], false), TypeError, 'Throws with false as second argument'); - assert.throws(() => from([], {}), TypeError, 'Throws with {} as second argument'); - if (DESCRIPTORS) { - let called = false; - defineProperty(C.prototype, 0, { - set() { - called = true; - }, - }); - from.call(C, [1, 2, 3]); - assert.ok(!called, 'Should not call prototype accessors'); - } -}); diff --git a/tests/pure/es.array.includes.js b/tests/pure/es.array.includes.js deleted file mode 100644 index ddf559d83720..000000000000 --- a/tests/pure/es.array.includes.js +++ /dev/null @@ -1,22 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import includes from 'core-js-pure/features/array/includes'; - -QUnit.test('Array#includes', assert => { - assert.isFunction(includes); - const object = {}; - const array = [1, 2, 3, -0, object]; - assert.ok(includes(array, 1)); - assert.ok(includes(array, -0)); - assert.ok(includes(array, 0)); - assert.ok(includes(array, object)); - assert.ok(!includes(array, 4)); - assert.ok(!includes(array, -0.5)); - assert.ok(!includes(array, {})); - assert.ok(includes(Array(1), undefined)); - assert.ok(includes([NaN], NaN)); - if (STRICT) { - assert.throws(() => includes(null, 0), TypeError); - assert.throws(() => includes(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.array.index-of.js b/tests/pure/es.array.index-of.js deleted file mode 100644 index 054967a0a794..000000000000 --- a/tests/pure/es.array.index-of.js +++ /dev/null @@ -1,20 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import indexOf from 'core-js-pure/features/array/index-of'; - -QUnit.test('Array#indexOf', assert => { - assert.isFunction(indexOf); - assert.same(0, indexOf([1, 1, 1], 1)); - assert.same(-1, indexOf([1, 2, 3], 1, 1)); - assert.same(1, indexOf([1, 2, 3], 2, 1)); - assert.same(-1, indexOf([1, 2, 3], 2, -1)); - assert.same(1, indexOf([1, 2, 3], 2, -2)); - assert.same(-1, indexOf([NaN], NaN)); - assert.same(3, indexOf(Array(2).concat([1, 2, 3]), 2)); - assert.same(-1, indexOf(Array(1), undefined)); - assert.same(0, indexOf([1], 1, -0), "shouldn't return negative zero"); - if (STRICT) { - assert.throws(() => indexOf(null, 0), TypeError); - assert.throws(() => indexOf(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.array.is-array.js b/tests/pure/es.array.is-array.js deleted file mode 100644 index b90967e3aa27..000000000000 --- a/tests/pure/es.array.is-array.js +++ /dev/null @@ -1,10 +0,0 @@ -import isArray from 'core-js-pure/features/array/is-array'; - -QUnit.test('Array.isArray', assert => { - assert.isFunction(isArray); - assert.ok(!isArray({})); - assert.ok(!isArray(function () { - return arguments; - }())); - assert.ok(isArray([])); -}); diff --git a/tests/pure/es.array.iterator.js b/tests/pure/es.array.iterator.js deleted file mode 100644 index 98756a1de0cb..000000000000 --- a/tests/pure/es.array.iterator.js +++ /dev/null @@ -1,100 +0,0 @@ -import { keys, values, entries } from 'core-js-pure/features/array'; -import Symbol from 'core-js-pure/features/symbol'; -import getIterator from 'core-js-pure/features/get-iterator'; - -QUnit.test('Array#@@iterator', assert => { - assert.isFunction(values); - const iterator = getIterator(['q', 'w', 'e']); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); - assert.strictEqual(String(iterator), '[object Array Iterator]'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Array#keys', assert => { - assert.isFunction(keys); - const iterator = keys(['q', 'w', 'e']); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); - assert.deepEqual(iterator.next(), { - value: 0, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 1, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 2, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Array#values', assert => { - assert.isFunction(values); - const iterator = values(['q', 'w', 'e']); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Array#entries', assert => { - assert.isFunction(entries); - const iterator = entries(['q', 'w', 'e']); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); - assert.deepEqual(iterator.next(), { - value: [0, 'q'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: [1, 'w'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: [2, 'e'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/pure/es.array.join.js b/tests/pure/es.array.join.js deleted file mode 100644 index e8e279d86296..000000000000 --- a/tests/pure/es.array.join.js +++ /dev/null @@ -1,14 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import join from 'core-js-pure/features/array/join'; - -QUnit.test('Array#join', assert => { - assert.isFunction(join); - assert.strictEqual(join([1, 2, 3], undefined), '1,2,3'); - assert.strictEqual(join('123'), '1,2,3'); - assert.strictEqual(join('123', '|'), '1|2|3'); - if (STRICT) { - assert.throws(() => join(null), TypeError); - assert.throws(() => join(undefined), TypeError); - } -}); diff --git a/tests/pure/es.array.last-index-of.js b/tests/pure/es.array.last-index-of.js deleted file mode 100644 index e400001c1286..000000000000 --- a/tests/pure/es.array.last-index-of.js +++ /dev/null @@ -1,20 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import lastIndexOf from 'core-js-pure/features/array/last-index-of'; - -QUnit.test('Array#lastIndexOf', assert => { - assert.isFunction(lastIndexOf); - assert.same(2, lastIndexOf([1, 1, 1], 1)); - assert.same(-1, lastIndexOf([1, 2, 3], 3, 1)); - assert.same(1, lastIndexOf([1, 2, 3], 2, 1)); - assert.same(-1, lastIndexOf([1, 2, 3], 2, -3)); - assert.same(-1, lastIndexOf([1, 2, 3], 1, -4)); - assert.same(1, lastIndexOf([1, 2, 3], 2, -2)); - assert.same(-1, lastIndexOf([NaN], NaN)); - assert.same(1, lastIndexOf([1, 2, 3].concat(Array(2)), 2)); - assert.same(0, lastIndexOf([1], 1, -0), "shouldn't return negative zero"); - if (STRICT) { - assert.throws(() => lastIndexOf(null, 0), TypeError); - assert.throws(() => lastIndexOf(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.array.map.js b/tests/pure/es.array.map.js deleted file mode 100644 index 7b98af13b89e..000000000000 --- a/tests/pure/es.array.map.js +++ /dev/null @@ -1,31 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import Symbol from 'core-js-pure/features/symbol'; -import map from 'core-js-pure/features/array/map'; - -QUnit.test('Array#map', assert => { - assert.isFunction(map); - let array = [1]; - const context = {}; - map(array, function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.deepEqual([2, 3, 4], map([1, 2, 3], it => it + 1)); - assert.deepEqual([1, 3, 5], map([1, 2, 3], (value, key) => value + key)); - assert.deepEqual([2, 2, 2], map([1, 2, 3], function () { - return +this; - }, 2)); - if (STRICT) { - assert.throws(() => map(null, () => { /* empty */ }), TypeError); - assert.throws(() => map(undefined, () => { /* empty */ }), TypeError); - } - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(map(array, Boolean).foo, 1, '@@species'); -}); diff --git a/tests/pure/es.array.of.js b/tests/pure/es.array.of.js deleted file mode 100644 index f5bacd22e6e9..000000000000 --- a/tests/pure/es.array.of.js +++ /dev/null @@ -1,27 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import of from 'core-js-pure/features/array/of'; -import defineProperty from 'core-js-pure/features/object/define-property'; - -QUnit.test('Array.of', assert => { - assert.isFunction(of); - assert.arity(of, 0); - assert.deepEqual(of(1), [1]); - assert.deepEqual(of(1, 2, 3), [1, 2, 3]); - class C { /* empty */ } - const instance = of.call(C, 1, 2); - assert.ok(instance instanceof C); - assert.strictEqual(instance[0], 1); - assert.strictEqual(instance[1], 2); - assert.strictEqual(instance.length, 2); - if (DESCRIPTORS) { - let called = false; - defineProperty(C.prototype, 0, { - set() { - called = true; - }, - }); - of.call(C, 1, 2, 3); - assert.ok(!called, 'Should not call prototype accessors'); - } -}); diff --git a/tests/pure/es.array.reduce-right.js b/tests/pure/es.array.reduce-right.js deleted file mode 100644 index de60bfc70b79..000000000000 --- a/tests/pure/es.array.reduce-right.js +++ /dev/null @@ -1,40 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import reduceRight from 'core-js-pure/features/array/reduce-right'; - -QUnit.test('Array#reduceRight', assert => { - assert.isFunction(reduceRight); - const array = [1]; - const accumulator = {}; - reduceRight(array, function (memo, value, key, that) { - assert.same(arguments.length, 4, 'correct number of callback arguments'); - assert.same(memo, accumulator, 'correct callback accumulator'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - }, accumulator); - assert.same(reduceRight([1, 2, 3], ((a, b) => a + b), 1), 7, 'works with initial accumulator'); - reduceRight([1, 2], (memo, value, key) => { - assert.same(memo, 2, 'correct default accumulator'); - assert.same(value, 1, 'correct start value without initial accumulator'); - assert.same(key, 0, 'correct start index without initial accumulator'); - }); - assert.same(reduceRight([1, 2, 3], (a, b) => a + b), 6, 'works without initial accumulator'); - let values = ''; - let keys = ''; - reduceRight([1, 2, 3], (memo, value, key) => { - values += value; - keys += key; - }, 0); - assert.same(values, '321', 'correct order #1'); - assert.same(keys, '210', 'correct order #2'); - assert.same(reduceRight({ - 0: 1, - 1: 2, - length: 2, - }, (a, b) => a + b), 3, 'generic'); - if (STRICT) { - assert.throws(() => reduceRight(null, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduceRight(undefined, () => { /* empty */ }, 1), TypeError); - } -}); diff --git a/tests/pure/es.array.reduce.js b/tests/pure/es.array.reduce.js deleted file mode 100644 index 5668017016cf..000000000000 --- a/tests/pure/es.array.reduce.js +++ /dev/null @@ -1,40 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import reduce from 'core-js-pure/features/array/reduce'; - -QUnit.test('Array#reduce', assert => { - assert.isFunction(reduce); - const array = [1]; - const accumulator = {}; - reduce(array, function (memo, value, key, that) { - assert.same(arguments.length, 4, 'correct number of callback arguments'); - assert.same(memo, accumulator, 'correct callback accumulator'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - }, accumulator); - assert.same(reduce([1, 2, 3], ((a, b) => a + b), 1), 7, 'works with initial accumulator'); - reduce([1, 2], (memo, value, key) => { - assert.same(memo, 1, 'correct default accumulator'); - assert.same(value, 2, 'correct start value without initial accumulator'); - assert.same(key, 1, 'correct start index without initial accumulator'); - }); - assert.same(reduce([1, 2, 3], (a, b) => a + b), 6, 'works without initial accumulator'); - let values = ''; - let keys = ''; - reduce([1, 2, 3], (memo, value, key) => { - values += value; - keys += key; - }, 0); - assert.same(values, '123', 'correct order #1'); - assert.same(keys, '012', 'correct order #2'); - assert.same(reduce({ - 0: 1, - 1: 2, - length: 2, - }, (a, b) => a + b), 3, 'generic'); - if (STRICT) { - assert.throws(() => reduce(null, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce(undefined, () => { /* empty */ }, 1), TypeError); - } -}); diff --git a/tests/pure/es.array.reverse.js b/tests/pure/es.array.reverse.js deleted file mode 100644 index 7c89cd1410a2..000000000000 --- a/tests/pure/es.array.reverse.js +++ /dev/null @@ -1,18 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import reverse from 'core-js-pure/features/array/reverse'; - -QUnit.test('Array#reverse', assert => { - assert.isFunction(reverse); - const a = [1, 2.2, 3.3]; - function fn() { - +a; - reverse(a); - } - fn(); - assert.arrayEqual(a, [3.3, 2.2, 1]); - if (STRICT) { - assert.throws(() => reverse(null, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reverse(undefined, () => { /* empty */ }, 1), TypeError); - } -}); diff --git a/tests/pure/es.array.slice.js b/tests/pure/es.array.slice.js deleted file mode 100644 index f99c6d5e5a6c..000000000000 --- a/tests/pure/es.array.slice.js +++ /dev/null @@ -1,31 +0,0 @@ -import { GLOBAL } from '../helpers/constants'; - -import { slice, isArray } from 'core-js-pure/features/array'; -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('Array#slice', assert => { - assert.isFunction(slice); - let array = ['1', '2', '3', '4', '5']; - assert.deepEqual(slice(array), array); - assert.deepEqual(slice(array, 1, 3), ['2', '3']); - assert.deepEqual(slice(array, 1, undefined), ['2', '3', '4', '5']); - assert.deepEqual(slice(array, 1, -1), ['2', '3', '4']); - assert.deepEqual(slice(array, -2, -1), ['4']); - assert.deepEqual(slice(array, -2, -3), []); - const string = '12345'; - assert.deepEqual(slice(string), array); - assert.deepEqual(slice(string, 1, 3), ['2', '3']); - assert.deepEqual(slice(string, 1, undefined), ['2', '3', '4', '5']); - assert.deepEqual(slice(string, 1, -1), ['2', '3', '4']); - assert.deepEqual(slice(string, -2, -1), ['4']); - assert.deepEqual(slice(string, -2, -3), []); - const list = GLOBAL.document && document.body && document.body.childNodes; - if (list) { - assert.notThrows(() => isArray(slice(list)), 'works with NodeList'); - } - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(slice(array).foo, 1, '@@species'); -}); diff --git a/tests/pure/es.array.some.js b/tests/pure/es.array.some.js deleted file mode 100644 index ea5f46134c9a..000000000000 --- a/tests/pure/es.array.some.js +++ /dev/null @@ -1,35 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import some from 'core-js-pure/features/array/some'; - -QUnit.test('Array#some', assert => { - assert.isFunction(some); - let array = [1]; - const context = {}; - some(array, function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.ok(some([1, '2', 3], it => typeof it === 'number')); - assert.ok(some([1, 2, 3], it => it < 3)); - assert.ok(!some([1, 2, 3], it => it < 0)); - assert.ok(!some([1, 2, 3], it => typeof it === 'string')); - assert.ok(!some([1, 2, 3], function () { - return +this !== 1; - }, 1)); - let result = ''; - some([1, 2, 3], (value, key) => { - result += key; - return false; - }); - assert.ok(result === '012'); - array = [1, 2, 3]; - assert.ok(!some(array, (value, key, that) => that !== array)); - if (STRICT) { - assert.throws(() => some(null, () => { /* empty */ }), TypeError); - assert.throws(() => some(undefined, () => { /* empty */ }), TypeError); - } -}); diff --git a/tests/pure/es.array.sort.js b/tests/pure/es.array.sort.js deleted file mode 100644 index 73074a0c14dc..000000000000 --- a/tests/pure/es.array.sort.js +++ /dev/null @@ -1,14 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import sort from 'core-js-pure/features/array/sort'; - -QUnit.test('Array#sort', assert => { - assert.isFunction(sort); - assert.notThrows(() => sort([1, 2, 3], undefined), 'works with undefined'); - assert.throws(() => sort([1, 2, 3], null), 'throws on null'); - assert.throws(() => sort([1, 2, 3], {}), 'throws on {}'); - if (STRICT) { - assert.throws(() => sort(null), TypeError, 'ToObject(this)'); - assert.throws(() => sort(undefined), TypeError, 'ToObject(this)'); - } -}); diff --git a/tests/pure/es.array.splice.js b/tests/pure/es.array.splice.js deleted file mode 100644 index 2e6327c32773..000000000000 --- a/tests/pure/es.array.splice.js +++ /dev/null @@ -1,36 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import splice from 'core-js-pure/features/array/splice'; -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('Array#splice', assert => { - assert.isFunction(splice); - let array = [1, 2, 3, 4, 5]; - assert.deepEqual(splice(array, 2), [3, 4, 5]); - assert.deepEqual(array, [1, 2]); - array = [1, 2, 3, 4, 5]; - assert.deepEqual(splice(array, -2), [4, 5]); - assert.deepEqual(array, [1, 2, 3]); - array = [1, 2, 3, 4, 5]; - assert.deepEqual(splice(array, 2, 2), [3, 4]); - assert.deepEqual(array, [1, 2, 5]); - array = [1, 2, 3, 4, 5]; - assert.deepEqual(splice(array, 2, -2), []); - assert.deepEqual(array, [1, 2, 3, 4, 5]); - array = [1, 2, 3, 4, 5]; - assert.deepEqual(splice(array, 2, 2, 6, 7), [3, 4]); - assert.deepEqual(array, [1, 2, 6, 7, 5]); - if (STRICT) { - assert.throws(() => splice(null), TypeError); - assert.throws(() => splice(undefined), TypeError); - } - assert.deepEqual(splice({ - length: -1, - 0: 1, - }), [], 'uses ToLength'); - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(splice(array).foo, 1, '@@species'); -}); diff --git a/tests/pure/es.date.now.js b/tests/pure/es.date.now.js deleted file mode 100644 index aabcddafebfb..000000000000 --- a/tests/pure/es.date.now.js +++ /dev/null @@ -1,6 +0,0 @@ -import now from 'core-js-pure/features/date/now'; - -QUnit.test('Date.now', assert => { - assert.isFunction(now); - assert.ok(+new Date() - now() < 10, 'Date.now() ~ +new Date'); -}); diff --git a/tests/pure/es.date.to-iso-string.js b/tests/pure/es.date.to-iso-string.js deleted file mode 100644 index e11e40baa4f1..000000000000 --- a/tests/pure/es.date.to-iso-string.js +++ /dev/null @@ -1,13 +0,0 @@ -import toISOString from 'core-js-pure/features/date/to-iso-string'; - -QUnit.test('Date#toISOString', assert => { - assert.isFunction(toISOString); - assert.strictEqual(toISOString(new Date(0)), '1970-01-01T00:00:00.000Z'); - assert.strictEqual(toISOString(new Date(1e12 + 1)), '2001-09-09T01:46:40.001Z'); - assert.strictEqual(toISOString(new Date(-5e13 - 1)), '0385-07-25T07:06:39.999Z'); - const future = toISOString(new Date(1e15 + 1)); - assert.ok(future === '+033658-09-27T01:46:40.001Z' || future === '33658-09-27T01:46:40.001Z'); - const prehistoric = toISOString(new Date(-1e15 + 1)); - assert.ok(prehistoric === '-029719-04-05T22:13:20.001Z' || prehistoric === '-29719-04-05T22:13:20.001Z'); - assert.throws(() => toISOString(new Date(NaN)), RangeError); -}); diff --git a/tests/pure/es.function.bind.js b/tests/pure/es.function.bind.js deleted file mode 100644 index a5717ea5830d..000000000000 --- a/tests/pure/es.function.bind.js +++ /dev/null @@ -1,26 +0,0 @@ -import bind from 'core-js-pure/features/function/bind'; - -QUnit.test('Function#bind', assert => { - assert.isFunction(bind); - const object = { a: 42 }; - assert.ok(bind(function () { - return this.a; - }, object)() === 42); - assert.ok(new (bind(() => { /* empty */ }, object))().a === undefined); - function C(a, b) { - this.a = a; - this.b = b; - } - const instance = new (bind(C, null, 1))(2); - assert.ok(instance instanceof C); - assert.strictEqual(instance.a, 1); - assert.strictEqual(instance.b, 2); - assert.ok(bind((it => it), null, 42)() === 42); - const regExpTest = bind(RegExp.prototype.test, /a/); - assert.ok(regExpTest('a')); - const Date2017 = bind(Date, null, 2017); - const date = new Date2017(11); - assert.ok(date instanceof Date); - assert.strictEqual(date.getFullYear(), 2017); - assert.strictEqual(date.getMonth(), 11); -}); diff --git a/tests/pure/es.function.has-instance.js b/tests/pure/es.function.has-instance.js deleted file mode 100644 index ca12b1554386..000000000000 --- a/tests/pure/es.function.has-instance.js +++ /dev/null @@ -1,7 +0,0 @@ -import HAS_INSTANCE from 'core-js-pure/features/symbol/has-instance'; - -QUnit.test('Function#@@hasInstance', assert => { - assert.ok(HAS_INSTANCE in Function.prototype); - assert.ok(Function[HAS_INSTANCE](() => { /* empty */ })); - assert.ok(!Function[HAS_INSTANCE]({})); -}); diff --git a/tests/pure/es.global-this.js b/tests/pure/es.global-this.js deleted file mode 100644 index d2648fd1f405..000000000000 --- a/tests/pure/es.global-this.js +++ /dev/null @@ -1,6 +0,0 @@ -import globalThis from 'core-js-pure/features/global-this'; - -QUnit.test('globalThis', assert => { - assert.same(globalThis, Object(globalThis), 'is object'); - assert.same(globalThis.Math, Math, 'contains globals'); -}); diff --git a/tests/pure/es.map.js b/tests/pure/es.map.js deleted file mode 100644 index 2d19d65e0962..000000000000 --- a/tests/pure/es.map.js +++ /dev/null @@ -1,407 +0,0 @@ -/* eslint-disable sonarjs/no-element-overwrite */ - -import { createIterable, is, nativeSubclass } from '../helpers/helpers'; -import { DESCRIPTORS } from '../helpers/constants'; - -import { Set, Map, Symbol } from 'core-js-pure'; -import getIterator from 'core-js-pure/features/get-iterator'; -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; -import { freeze, getOwnPropertyDescriptor, keys, getOwnPropertyNames, getOwnPropertySymbols } from 'core-js-pure/features/object'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; - -QUnit.test('Map', assert => { - assert.isFunction(Map); - assert.ok('clear' in Map.prototype, 'clear in Map.prototype'); - assert.ok('delete' in Map.prototype, 'delete in Map.prototype'); - assert.ok('forEach' in Map.prototype, 'forEach in Map.prototype'); - assert.ok('get' in Map.prototype, 'get in Map.prototype'); - assert.ok('has' in Map.prototype, 'has in Map.prototype'); - assert.ok('set' in Map.prototype, 'set in Map.prototype'); - assert.ok(new Map() instanceof Map, 'new Map instanceof Map'); - assert.strictEqual(new Map(createIterable([[1, 1], [2, 2], [3, 3]])).size, 3, 'Init from iterable'); - assert.strictEqual(new Map([[freeze({}), 1], [2, 3]]).size, 2, 'Support frozen objects'); - let done = false; - try { - new Map(createIterable([null, 1, 2], { - return() { - return done = true; - }, - })); - } catch { /* empty */ } - assert.ok(done, '.return #throw'); - const array = []; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return getIteratorMethod([]).call(this); - }; - new Map(array); - assert.ok(done); - const object = {}; - new Map().set(object, 1); - if (DESCRIPTORS) { - const results = []; - for (const key in object) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(object), []); - } - assert.arrayEqual(getOwnPropertyNames(object), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); - if (ownKeys) assert.arrayEqual(ownKeys(object), []); - if (nativeSubclass) { - const Subclass = nativeSubclass(Map); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof Map, 'correct subclassing with native classes #2'); - assert.strictEqual(new Subclass().set(1, 2).get(1), 2, 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('Map#clear', assert => { - assert.isFunction(Map.prototype.clear); - let map = new Map(); - map.clear(); - assert.strictEqual(map.size, 0); - map = new Map().set(1, 2).set(2, 3).set(1, 4); - map.clear(); - assert.strictEqual(map.size, 0); - assert.ok(!map.has(1)); - assert.ok(!map.has(2)); - const frozen = freeze({}); - map = new Map().set(1, 2).set(frozen, 3); - map.clear(); - assert.strictEqual(map.size, 0, 'Support frozen objects'); - assert.ok(!map.has(1)); - assert.ok(!map.has(frozen)); -}); - -QUnit.test('Map#delete', assert => { - assert.isFunction(Map.prototype.delete); - const object = {}; - const map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 7); - map.set(2, 5); - map.set(1, 4); - map.set(object, 9); - assert.strictEqual(map.size, 5); - assert.ok(map.delete(NaN)); - assert.strictEqual(map.size, 4); - assert.ok(!map.delete(4)); - assert.strictEqual(map.size, 4); - map.delete([]); - assert.strictEqual(map.size, 4); - map.delete(object); - assert.strictEqual(map.size, 3); - const frozen = freeze({}); - map.set(frozen, 42); - assert.strictEqual(map.size, 4); - map.delete(frozen); - assert.strictEqual(map.size, 3); -}); - -QUnit.test('Map#forEach', assert => { - assert.isFunction(Map.prototype.forEach); - let result = {}; - let count = 0; - const object = {}; - let map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 7); - map.set(2, 5); - map.set(1, 4); - map.set(object, 9); - map.forEach((value, key) => { - count++; - result[value] = key; - }); - assert.strictEqual(count, 5); - assert.deepEqual(result, { - 1: NaN, - 7: 3, - 5: 2, - 4: 1, - 9: object, - }); - map = new Map(); - map.set('0', 9); - map.set('1', 9); - map.set('2', 9); - map.set('3', 9); - result = ''; - map.forEach((value, key) => { - result += key; - if (key === '2') { - map.delete('2'); - map.delete('3'); - map.delete('1'); - map.set('4', 9); - } - }); - assert.strictEqual(result, '0124'); - map = new Map([['0', 1]]); - result = ''; - map.forEach(it => { - map.delete('0'); - if (result !== '') throw new Error(); - result += it; - }); - assert.strictEqual(result, '1'); - assert.throws(() => Map.prototype.forEach.call(new Set(), () => { /* empty */ }), 'non-generic'); -}); - -QUnit.test('Map#get', assert => { - assert.isFunction(Map.prototype.get); - const object = {}; - const frozen = freeze({}); - const map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 1); - map.set(2, 5); - map.set(1, 4); - map.set(frozen, 42); - map.set(object, object); - assert.strictEqual(map.get(NaN), 1); - assert.strictEqual(map.get(4), undefined); - assert.strictEqual(map.get({}), undefined); - assert.strictEqual(map.get(object), object); - assert.strictEqual(map.get(frozen), 42); - assert.strictEqual(map.get(2), 5); -}); - -QUnit.test('Map#has', assert => { - assert.isFunction(Map.prototype.has); - const object = {}; - const frozen = freeze({}); - const map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 1); - map.set(2, 5); - map.set(1, 4); - map.set(frozen, 42); - map.set(object, object); - assert.ok(map.has(NaN)); - assert.ok(map.has(object)); - assert.ok(map.has(2)); - assert.ok(map.has(frozen)); - assert.ok(!map.has(4)); - assert.ok(!map.has({})); -}); - -QUnit.test('Map#set', assert => { - assert.isFunction(Map.prototype.set); - const object = {}; - let map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 1); - map.set(2, 5); - map.set(1, 4); - map.set(object, object); - assert.ok(map.size === 5); - const chain = map.set(7, 2); - assert.strictEqual(chain, map); - map.set(7, 2); - assert.strictEqual(map.size, 6); - assert.strictEqual(map.get(7), 2); - assert.strictEqual(map.get(NaN), 1); - map.set(NaN, 42); - assert.strictEqual(map.size, 6); - assert.strictEqual(map.get(NaN), 42); - map.set({}, 11); - assert.strictEqual(map.size, 7); - assert.strictEqual(map.get(object), object); - map.set(object, 27); - assert.strictEqual(map.size, 7); - assert.strictEqual(map.get(object), 27); - map = new Map(); - map.set(NaN, 2); - map.set(NaN, 3); - map.set(NaN, 4); - assert.strictEqual(map.size, 1); - const frozen = freeze({}); - map = new Map().set(frozen, 42); - assert.strictEqual(map.get(frozen), 42); -}); - -QUnit.test('Map#size', assert => { - const map = new Map(); - map.set(2, 1); - const { size } = map; - assert.strictEqual(typeof size, 'number', 'size is number'); - assert.strictEqual(size, 1, 'size is correct'); - if (DESCRIPTORS) { - const sizeDescriptor = getOwnPropertyDescriptor(Map.prototype, 'size'); - assert.ok(sizeDescriptor && sizeDescriptor.get, 'size is getter'); - assert.ok(sizeDescriptor && !sizeDescriptor.set, 'size isnt setter'); - assert.throws(() => Map.prototype.size, TypeError); - } -}); - -QUnit.test('Map & -0', assert => { - let map = new Map(); - map.set(-0, 1); - assert.strictEqual(map.size, 1); - assert.ok(map.has(0)); - assert.ok(map.has(-0)); - assert.strictEqual(map.get(0), 1); - assert.strictEqual(map.get(-0), 1); - map.forEach((val, key) => { - assert.ok(!is(key, -0)); - }); - map.delete(-0); - assert.strictEqual(map.size, 0); - map = new Map([[-0, 1]]); - map.forEach((val, key) => { - assert.ok(!is(key, -0)); - }); - map = new Map(); - map.set(4, 4); - map.set(3, 3); - map.set(2, 2); - map.set(1, 1); - map.set(0, 0); - assert.ok(map.has(-0)); -}); - -QUnit.test('Map#@@toStringTag', assert => { - assert.strictEqual(Map.prototype[Symbol.toStringTag], 'Map', 'Map::@@toStringTag is `Map`'); - assert.strictEqual(String(new Map()), '[object Map]', 'correct stringification'); -}); - -QUnit.test('Map Iterator', assert => { - const map = new Map(); - map.set('a', 1); - map.set('b', 2); - map.set('c', 3); - map.set('d', 4); - const results = []; - const iterator = map.keys(); - results.push(iterator.next().value); - assert.ok(map.delete('a')); - assert.ok(map.delete('b')); - assert.ok(map.delete('c')); - map.set('e'); - results.push(iterator.next().value); - results.push(iterator.next().value); - assert.ok(iterator.next().done); - map.set('f'); - assert.ok(iterator.next().done); - assert.deepEqual(results, ['a', 'd', 'e']); -}); - -QUnit.test('Map#keys', assert => { - assert.isFunction(Map.prototype.keys); - const map = new Map(); - map.set('a', 'q'); - map.set('s', 'w'); - map.set('d', 'e'); - const iterator = map.keys(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Map Iterator'); - assert.deepEqual(iterator.next(), { - value: 'a', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 's', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'd', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Map#values', assert => { - assert.isFunction(Map.prototype.values); - const map = new Map(); - map.set('a', 'q'); - map.set('s', 'w'); - map.set('d', 'e'); - const iterator = map.values(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Map Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Map#entries', assert => { - assert.isFunction(Map.prototype.entries); - const map = new Map(); - map.set('a', 'q'); - map.set('s', 'w'); - map.set('d', 'e'); - const iterator = map.entries(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Map Iterator'); - assert.deepEqual(iterator.next(), { - value: ['a', 'q'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['s', 'w'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['d', 'e'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Map#@@iterator', assert => { - const map = new Map(); - map.set('a', 'q'); - map.set('s', 'w'); - map.set('d', 'e'); - const iterator = getIterator(map); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Map Iterator'); - assert.strictEqual(String(iterator), '[object Map Iterator]'); - assert.deepEqual(iterator.next(), { - value: ['a', 'q'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['s', 'w'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['d', 'e'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/pure/es.math.acosh.js b/tests/pure/es.math.acosh.js deleted file mode 100644 index bbd177bf8d6c..000000000000 --- a/tests/pure/es.math.acosh.js +++ /dev/null @@ -1,17 +0,0 @@ -import acosh from 'core-js-pure/features/math/acosh'; -import EPSILON from 'core-js-pure/features/number/epsilon'; - -QUnit.test('Math.acosh', assert => { - assert.isFunction(acosh); - assert.same(acosh(NaN), NaN); - assert.same(acosh(0.5), NaN); - assert.same(acosh(-1), NaN); - assert.same(acosh(-1e300), NaN); - assert.same(acosh(1), 0); - assert.strictEqual(acosh(Infinity), Infinity); - assert.epsilon(acosh(1234), 7.811163220849231); - assert.epsilon(acosh(8.88), 2.8737631531629235); - assert.epsilon(acosh(1e+160), 369.10676205960726); - assert.epsilon(acosh(Number.MAX_VALUE), 710.475860073944); - assert.epsilon(acosh(1 + EPSILON), 2.1073424255447017e-8); -}); diff --git a/tests/pure/es.math.asinh.js b/tests/pure/es.math.asinh.js deleted file mode 100644 index 1b883e0f368b..000000000000 --- a/tests/pure/es.math.asinh.js +++ /dev/null @@ -1,15 +0,0 @@ -import asinh from 'core-js-pure/features/math/asinh'; - -QUnit.test('Math.asinh', assert => { - assert.isFunction(asinh); - assert.same(asinh(NaN), NaN); - assert.same(asinh(0), 0); - assert.same(asinh(-0), -0); - assert.strictEqual(asinh(Infinity), Infinity); - assert.strictEqual(asinh(-Infinity), -Infinity); - assert.epsilon(asinh(1234), 7.811163549201245); - assert.epsilon(asinh(9.99), 2.997227420191335); - assert.epsilon(asinh(1e150), 346.0809111296668); - assert.epsilon(asinh(1e7), 16.811242831518268); - assert.epsilon(asinh(-1e7), -16.811242831518268); -}); diff --git a/tests/pure/es.math.atanh.js b/tests/pure/es.math.atanh.js deleted file mode 100644 index eaa01b9ce244..000000000000 --- a/tests/pure/es.math.atanh.js +++ /dev/null @@ -1,19 +0,0 @@ -import atanh from 'core-js-pure/features/math/atanh'; - -QUnit.test('Math.atanh', assert => { - assert.isFunction(atanh); - assert.same(atanh(NaN), NaN); - assert.same(atanh(-2), NaN); - assert.same(atanh(-1.5), NaN); - assert.same(atanh(2), NaN); - assert.same(atanh(1.5), NaN); - assert.strictEqual(atanh(-1), -Infinity); - assert.strictEqual(atanh(1), Infinity); - assert.same(atanh(0), 0); - assert.same(atanh(-0), -0); - assert.same(atanh(-1e300), NaN); - assert.same(atanh(1e300), NaN); - assert.epsilon(atanh(0.5), 0.5493061443340549); - assert.epsilon(atanh(-0.5), -0.5493061443340549); - assert.epsilon(atanh(0.444), 0.47720201260109457); -}); diff --git a/tests/pure/es.math.cbrt.js b/tests/pure/es.math.cbrt.js deleted file mode 100644 index 63a518882a7a..000000000000 --- a/tests/pure/es.math.cbrt.js +++ /dev/null @@ -1,14 +0,0 @@ -import cbrt from 'core-js-pure/features/math/cbrt'; - -QUnit.test('Math.cbrt', assert => { - assert.isFunction(cbrt); - assert.same(cbrt(NaN), NaN); - assert.same(cbrt(0), 0); - assert.same(cbrt(-0), -0); - assert.strictEqual(cbrt(Infinity), Infinity); - assert.strictEqual(cbrt(-Infinity), -Infinity); - assert.strictEqual(cbrt(-8), -2); - assert.strictEqual(cbrt(8), 2); - assert.epsilon(cbrt(-1000), -10); - assert.epsilon(cbrt(1000), 10); -}); diff --git a/tests/pure/es.math.clz32.js b/tests/pure/es.math.clz32.js deleted file mode 100644 index 2ad23a2df1b5..000000000000 --- a/tests/pure/es.math.clz32.js +++ /dev/null @@ -1,11 +0,0 @@ -import clz32 from 'core-js-pure/features/math/clz32'; - -QUnit.test('Math.clz32', assert => { - assert.isFunction(clz32); - assert.strictEqual(clz32(0), 32); - assert.strictEqual(clz32(1), 31); - assert.same(clz32(-1), 0); - assert.strictEqual(clz32(0.6), 32); - assert.same(clz32(2 ** 32 - 1), 0); - assert.strictEqual(clz32(2 ** 32), 32); -}); diff --git a/tests/pure/es.math.cosh.js b/tests/pure/es.math.cosh.js deleted file mode 100644 index de2cd985834d..000000000000 --- a/tests/pure/es.math.cosh.js +++ /dev/null @@ -1,15 +0,0 @@ -import cosh from 'core-js-pure/features/math/cosh'; - -QUnit.test('Math.cosh', assert => { - assert.isFunction(cosh); - assert.same(cosh(NaN), NaN); - assert.strictEqual(cosh(0), 1); - assert.strictEqual(cosh(-0), 1); - assert.strictEqual(cosh(Infinity), Infinity); - assert.strictEqual(cosh(-Infinity), Infinity); - assert.epsilon(cosh(12), 81377.395712574, 1e-9); - assert.epsilon(cosh(22), 1792456423.065795780980053377, 1e-5); - assert.epsilon(cosh(-10), 11013.23292010332313972137); - assert.epsilon(cosh(-23), 4872401723.1244513000, 1e-5); - assert.epsilon(cosh(710), 1.1169973830808557e+308, 1e+295); -}); diff --git a/tests/pure/es.math.expm1.js b/tests/pure/es.math.expm1.js deleted file mode 100644 index b7cfbcb3f70a..000000000000 --- a/tests/pure/es.math.expm1.js +++ /dev/null @@ -1,12 +0,0 @@ -import expm1 from 'core-js-pure/features/math/expm1'; - -QUnit.test('Math.expm1', assert => { - assert.isFunction(expm1); - assert.same(expm1(NaN), NaN); - assert.same(expm1(0), 0); - assert.same(expm1(-0), -0); - assert.strictEqual(expm1(Infinity), Infinity); - assert.strictEqual(expm1(-Infinity), -1); - assert.epsilon(expm1(10), 22025.465794806718); - assert.epsilon(expm1(-10), -0.9999546000702375); -}); diff --git a/tests/pure/es.math.fround.js b/tests/pure/es.math.fround.js deleted file mode 100644 index 5aaf6a07df79..000000000000 --- a/tests/pure/es.math.fround.js +++ /dev/null @@ -1,29 +0,0 @@ -import fround from 'core-js-pure/features/math/fround'; - -QUnit.test('Math.fround', assert => { - assert.isFunction(fround); - assert.same(fround(undefined), NaN); - assert.same(fround(NaN), NaN); - assert.same(fround(0), 0); - assert.same(fround(-0), -0); - assert.same(fround(Number.MIN_VALUE), 0); - assert.same(fround(-Number.MIN_VALUE), -0); - assert.strictEqual(fround(Infinity), Infinity); - assert.strictEqual(fround(-Infinity), -Infinity); - assert.strictEqual(fround(1.7976931348623157e+308), Infinity); - assert.strictEqual(fround(-1.7976931348623157e+308), -Infinity); - assert.strictEqual(fround(3.4028235677973366e+38), Infinity); - assert.strictEqual(fround(3), 3); - assert.strictEqual(fround(-3), -3); - const maxFloat32 = 3.4028234663852886e+38; - const minFloat32 = 1.401298464324817e-45; - assert.strictEqual(fround(maxFloat32), maxFloat32); - assert.strictEqual(fround(-maxFloat32), -maxFloat32); - assert.strictEqual(fround(maxFloat32 + 2 ** 102), maxFloat32); - assert.strictEqual(fround(minFloat32), minFloat32); - assert.strictEqual(fround(-minFloat32), -minFloat32); - assert.same(fround(minFloat32 / 2), 0); - assert.same(fround(-minFloat32 / 2), -0); - assert.strictEqual(fround(minFloat32 / 2 + 2 ** -202), minFloat32); - assert.strictEqual(fround(-minFloat32 / 2 - 2 ** -202), -minFloat32); -}); diff --git a/tests/pure/es.math.hypot.js b/tests/pure/es.math.hypot.js deleted file mode 100644 index 21f39cc5a3d0..000000000000 --- a/tests/pure/es.math.hypot.js +++ /dev/null @@ -1,41 +0,0 @@ -import hypot from 'core-js-pure/features/math/hypot'; - -QUnit.test('Math.hypot', assert => { - const { sqrt } = Math; - assert.isFunction(hypot); - assert.strictEqual(hypot(), 0); - assert.strictEqual(hypot(1), 1); - assert.same(hypot('', 0), 0); - assert.same(hypot(0, ''), 0); - assert.strictEqual(hypot(Infinity, 0), Infinity, 'Infinity, 0'); - assert.strictEqual(hypot(-Infinity, 0), Infinity, '-Infinity, 0'); - assert.strictEqual(hypot(0, Infinity), Infinity, '0, Infinity'); - assert.strictEqual(hypot(0, -Infinity), Infinity, '0, -Infinity'); - assert.strictEqual(hypot(Infinity, NaN), Infinity, 'Infinity, NaN'); - assert.strictEqual(hypot(NaN, -Infinity), Infinity, 'NaN, -Infinity'); - assert.same(hypot(NaN, 0), NaN, 'NaN, 0'); - assert.same(hypot(0, NaN), NaN, '0, NaN'); - assert.same(hypot(0, -0), 0); - assert.same(hypot(0, 0), 0); - assert.same(hypot(-0, -0), 0); - assert.same(hypot(-0, 0), 0); - assert.strictEqual(hypot(0, 1), 1); - assert.strictEqual(hypot(0, -1), 1); - assert.strictEqual(hypot(-0, 1), 1); - assert.strictEqual(hypot(-0, -1), 1); - assert.same(hypot(0), 0); - assert.strictEqual(hypot(1), 1); - assert.strictEqual(hypot(2), 2); - assert.strictEqual(hypot(0, 0, 1), 1); - assert.strictEqual(hypot(0, 1, 0), 1); - assert.strictEqual(hypot(1, 0, 0), 1); - assert.strictEqual(hypot(2, 3, 4), sqrt(2 * 2 + 3 * 3 + 4 * 4)); - assert.strictEqual(hypot(2, 3, 4, 5), sqrt(2 * 2 + 3 * 3 + 4 * 4 + 5 * 5)); - assert.epsilon(hypot(66, 66), 93.33809511662427); - assert.epsilon(hypot(0.1, 100), 100.0000499999875); - assert.strictEqual(hypot(1e+300, 1e+300), 1.4142135623730952e+300); - assert.strictEqual(Math.floor(hypot(1e-300, 1e-300) * 1e308), 141421356); - assert.strictEqual(hypot(1e+300, 1e+300, 2, 3), 1.4142135623730952e+300); - assert.strictEqual(hypot(-3, 4), 5); - assert.strictEqual(hypot(3, -4), 5); -}); diff --git a/tests/pure/es.math.imul.js b/tests/pure/es.math.imul.js deleted file mode 100644 index 6cb9c7028733..000000000000 --- a/tests/pure/es.math.imul.js +++ /dev/null @@ -1,40 +0,0 @@ -import imul from 'core-js-pure/features/math/imul'; - -QUnit.test('Math.imul', assert => { - assert.isFunction(imul); - assert.same(imul(0, 0), 0); - assert.strictEqual(imul(123, 456), 56088); - assert.strictEqual(imul(-123, 456), -56088); - assert.strictEqual(imul(123, -456), -56088); - assert.strictEqual(imul(19088743, 4275878552), 602016552); - assert.same(imul(false, 7), 0); - assert.same(imul(7, false), 0); - assert.same(imul(false, false), 0); - assert.strictEqual(imul(true, 7), 7); - assert.strictEqual(imul(7, true), 7); - assert.strictEqual(imul(true, true), 1); - assert.same(imul(undefined, 7), 0); - assert.same(imul(7, undefined), 0); - assert.same(imul(undefined, undefined), 0); - assert.same(imul('str', 7), 0); - assert.same(imul(7, 'str'), 0); - assert.same(imul({}, 7), 0); - assert.same(imul(7, {}), 0); - assert.same(imul([], 7), 0); - assert.same(imul(7, []), 0); - assert.strictEqual(imul(0xFFFFFFFF, 5), -5); - assert.strictEqual(imul(0xFFFFFFFE, 5), -10); - assert.strictEqual(imul(2, 4), 8); - assert.strictEqual(imul(-1, 8), -8); - assert.strictEqual(imul(-2, -2), 4); - assert.same(imul(-0, 7), 0); - assert.same(imul(7, -0), 0); - assert.same(imul(0.1, 7), 0); - assert.same(imul(7, 0.1), 0); - assert.same(imul(0.9, 7), 0); - assert.same(imul(7, 0.9), 0); - assert.strictEqual(imul(1.1, 7), 7); - assert.strictEqual(imul(7, 1.1), 7); - assert.strictEqual(imul(1.9, 7), 7); - assert.strictEqual(imul(7, 1.9), 7); -}); diff --git a/tests/pure/es.math.log10.js b/tests/pure/es.math.log10.js deleted file mode 100644 index 75ffad0239ea..000000000000 --- a/tests/pure/es.math.log10.js +++ /dev/null @@ -1,18 +0,0 @@ -import log10 from 'core-js-pure/features/math/log10'; - -QUnit.test('Math.log10', assert => { - assert.isFunction(log10); - assert.same(log10(''), log10(0)); - assert.same(log10(NaN), NaN); - assert.same(log10(-1), NaN); - assert.same(log10(0), -Infinity); - assert.same(log10(-0), -Infinity); - assert.same(log10(1), 0); - assert.same(log10(Infinity), Infinity); - assert.epsilon(log10(0.1), -1); - assert.epsilon(log10(0.5), -0.3010299956639812); - assert.epsilon(log10(1.5), 0.17609125905568124); - assert.epsilon(log10(5), 0.6989700043360189); - assert.epsilon(log10(50), 1.6989700043360187); - assert.epsilon(log10(1000), 3); -}); diff --git a/tests/pure/es.math.log1p.js b/tests/pure/es.math.log1p.js deleted file mode 100644 index 31926fcb55ea..000000000000 --- a/tests/pure/es.math.log1p.js +++ /dev/null @@ -1,14 +0,0 @@ -import log1p from 'core-js-pure/features/math/log1p'; - -QUnit.test('Math.log1p', assert => { - assert.isFunction(log1p); - assert.same(log1p(''), log1p(0)); - assert.same(log1p(NaN), NaN); - assert.same(log1p(-2), NaN); - assert.same(log1p(-1), -Infinity); - assert.same(log1p(0), 0); - assert.same(log1p(-0), -0); - assert.same(log1p(Infinity), Infinity); - assert.epsilon(log1p(5), 1.791759469228055); - assert.epsilon(log1p(50), 3.9318256327243257); -}); diff --git a/tests/pure/es.math.log2.js b/tests/pure/es.math.log2.js deleted file mode 100644 index 112569d8843a..000000000000 --- a/tests/pure/es.math.log2.js +++ /dev/null @@ -1,15 +0,0 @@ -import log2 from 'core-js-pure/features/math/log2'; - -QUnit.test('Math.log2', assert => { - assert.isFunction(log2); - assert.same(log2(''), log2(0)); - assert.same(log2(NaN), NaN); - assert.same(log2(-1), NaN); - assert.same(log2(0), -Infinity); - assert.same(log2(-0), -Infinity); - assert.same(log2(1), 0); - assert.same(log2(Infinity), Infinity); - assert.same(log2(0.5), -1); - assert.same(log2(32), 5); - assert.epsilon(log2(5), 2.321928094887362); -}); diff --git a/tests/pure/es.math.sign.js b/tests/pure/es.math.sign.js deleted file mode 100644 index 1e125522f8bf..000000000000 --- a/tests/pure/es.math.sign.js +++ /dev/null @@ -1,15 +0,0 @@ -import sign from 'core-js-pure/features/math/sign'; - -QUnit.test('Math.sign', assert => { - assert.isFunction(sign); - assert.same(sign(NaN), NaN); - assert.same(sign(), NaN); - assert.same(sign(-0), -0); - assert.same(sign(0), 0); - assert.strictEqual(sign(Infinity), 1); - assert.strictEqual(sign(-Infinity), -1); - assert.strictEqual(sign(13510798882111488), 1); - assert.strictEqual(sign(-13510798882111488), -1); - assert.strictEqual(sign(42.5), 1); - assert.strictEqual(sign(-42.5), -1); -}); diff --git a/tests/pure/es.math.sinh.js b/tests/pure/es.math.sinh.js deleted file mode 100644 index 5ab60944352e..000000000000 --- a/tests/pure/es.math.sinh.js +++ /dev/null @@ -1,13 +0,0 @@ -import sinh from 'core-js-pure/features/math/sinh'; - -QUnit.test('Math.sinh', assert => { - assert.isFunction(sinh); - assert.same(sinh(NaN), NaN); - assert.same(sinh(0), 0); - assert.same(sinh(-0), -0); - assert.strictEqual(sinh(Infinity), Infinity); - assert.strictEqual(sinh(-Infinity), -Infinity); - assert.epsilon(sinh(-5), -74.20321057778875); - assert.epsilon(sinh(2), 3.6268604078470186); - assert.strictEqual(sinh(-2e-17), -2e-17); -}); diff --git a/tests/pure/es.math.tanh.js b/tests/pure/es.math.tanh.js deleted file mode 100644 index 1aea79aa7432..000000000000 --- a/tests/pure/es.math.tanh.js +++ /dev/null @@ -1,11 +0,0 @@ -import tanh from 'core-js-pure/features/math/tanh'; - -QUnit.test('Math.tanh', assert => { - assert.isFunction(tanh); - assert.same(tanh(NaN), NaN); - assert.same(tanh(0), 0); - assert.same(tanh(-0), -0); - assert.strictEqual(tanh(Infinity), 1); - assert.strictEqual(tanh(90), 1); - assert.epsilon(tanh(10), 0.9999999958776927); -}); diff --git a/tests/pure/es.math.trunc.js b/tests/pure/es.math.trunc.js deleted file mode 100644 index 1de71bde794a..000000000000 --- a/tests/pure/es.math.trunc.js +++ /dev/null @@ -1,20 +0,0 @@ -import trunc from 'core-js-pure/features/math/trunc'; - -QUnit.test('Math.trunc', assert => { - assert.isFunction(trunc); - assert.same(trunc(NaN), NaN, 'NaN -> NaN'); - assert.same(trunc(-0), -0, '-0 -> -0'); - assert.same(trunc(0), 0, '0 -> 0'); - assert.same(trunc(Infinity), Infinity, 'Infinity -> Infinity'); - assert.same(trunc(-Infinity), -Infinity, '-Infinity -> -Infinity'); - assert.same(trunc(null), 0, 'null -> 0'); - assert.same(trunc({}), NaN, '{} -> NaN'); - assert.strictEqual(trunc([]), 0, '[] -> 0'); - assert.strictEqual(trunc(1.01), 1, '1.01 -> 0'); - assert.strictEqual(trunc(1.99), 1, '1.99 -> 0'); - assert.strictEqual(trunc(-1), -1, '-1 -> -1'); - assert.strictEqual(trunc(-1.99), -1, '-1.99 -> -1'); - assert.strictEqual(trunc(-555.555), -555, '-555.555 -> -555'); - assert.strictEqual(trunc(0x20000000000001), 0x20000000000001, '0x20000000000001 -> 0x20000000000001'); - assert.strictEqual(trunc(-0x20000000000001), -0x20000000000001, '-0x20000000000001 -> -0x20000000000001'); -}); diff --git a/tests/pure/es.number.epsilon.js b/tests/pure/es.number.epsilon.js deleted file mode 100644 index 40b051db7bdf..000000000000 --- a/tests/pure/es.number.epsilon.js +++ /dev/null @@ -1,7 +0,0 @@ -import EPSILON from 'core-js-pure/features/number/epsilon'; - -QUnit.test('Number.EPSILON', assert => { - assert.strictEqual(EPSILON, 2 ** -52, 'Is 2^-52'); - assert.ok(1 !== 1 + EPSILON, '1 isnt 1 + EPSILON'); - assert.strictEqual(1, 1 + EPSILON / 2, '1 is 1 + EPSILON / 2'); -}); diff --git a/tests/pure/es.number.is-finite.js b/tests/pure/es.number.is-finite.js deleted file mode 100644 index e073d340f0d1..000000000000 --- a/tests/pure/es.number.is-finite.js +++ /dev/null @@ -1,40 +0,0 @@ -import isFinite from 'core-js-pure/features/number/is-finite'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Number.isFinite', assert => { - assert.isFunction(isFinite); - const finite = [ - 1, - 0.1, - -1, - 2 ** 16, - 2 ** 16 - 1, - 2 ** 31, - 2 ** 31 - 1, - 2 ** 32, - 2 ** 32 - 1, - -0, - ]; - for (const value of finite) { - assert.ok(isFinite(value), `isFinite ${ typeof value } ${ value }`); - } - const notFinite = [ - NaN, - Infinity, - 'NaN', - '5', - false, - new Number(NaN), - new Number(Infinity), - new Number(5), - new Number(0.1), - undefined, - null, - {}, - function () { /* empty */ }, - ]; - for (const value of notFinite) { - assert.ok(!isFinite(value), `not isFinite ${ typeof value } ${ value }`); - } - assert.ok(!isFinite(create(null)), 'Number.isFinite(Object.create(null)) -> false'); -}); diff --git a/tests/pure/es.number.is-integer.js b/tests/pure/es.number.is-integer.js deleted file mode 100644 index 90090aaad42c..000000000000 --- a/tests/pure/es.number.is-integer.js +++ /dev/null @@ -1,40 +0,0 @@ -import isInteger from 'core-js-pure/features/number/is-integer'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Number.isInteger', assert => { - assert.isFunction(isInteger); - const integers = [ - 1, - -1, - 2 ** 16, - 2 ** 16 - 1, - 2 ** 31, - 2 ** 31 - 1, - 2 ** 32, - 2 ** 32 - 1, - -0, - ]; - for (const value of integers) { - assert.ok(isInteger(value), `isInteger ${ typeof value } ${ value }`); - } - const notIntegers = [ - NaN, - 0.1, - Infinity, - 'NaN', - '5', - false, - new Number(NaN), - new Number(Infinity), - new Number(5), - new Number(0.1), - undefined, - null, - {}, - function () { /* empty */ }, - ]; - for (const value of notIntegers) { - assert.ok(!isInteger(value), `not isInteger ${ typeof value } ${ value }`); - } - assert.ok(!isInteger(create(null)), 'Number.isInteger(Object.create(null)) -> false'); -}); diff --git a/tests/pure/es.number.is-nan.js b/tests/pure/es.number.is-nan.js deleted file mode 100644 index 041d0c4872b6..000000000000 --- a/tests/pure/es.number.is-nan.js +++ /dev/null @@ -1,35 +0,0 @@ -import isNaN from 'core-js-pure/features/number/is-nan'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Number.isNaN', assert => { - assert.isFunction(isNaN); - assert.ok(isNaN(NaN), 'Number.isNaN NaN'); - const notNaNs = [ - 1, - 0.1, - -1, - 2 ** 16, - 2 ** 16 - 1, - 2 ** 31, - 2 ** 31 - 1, - 2 ** 32, - 2 ** 32 - 1, - -0, - Infinity, - 'NaN', - '5', - false, - new Number(NaN), - new Number(Infinity), - new Number(5), - new Number(0.1), - undefined, - null, - {}, - function () { /* empty */ }, - ]; - for (const value of notNaNs) { - assert.ok(!isNaN(value), `not Number.isNaN ${ typeof value } ${ value }`); - } - assert.ok(!isNaN(create(null)), 'Number.isNaN(Object.create(null)) -> false'); -}); diff --git a/tests/pure/es.number.is-safe-integer.js b/tests/pure/es.number.is-safe-integer.js deleted file mode 100644 index 8045b7039b69..000000000000 --- a/tests/pure/es.number.is-safe-integer.js +++ /dev/null @@ -1,44 +0,0 @@ -import isSafeInteger from 'core-js-pure/features/number/is-safe-integer'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Number.isSafeInteger', assert => { - assert.isFunction(isSafeInteger); - const safeIntegers = [ - 1, - -1, - 2 ** 16, - 2 ** 16 - 1, - 2 ** 31, - 2 ** 31 - 1, - 2 ** 32, - 2 ** 32 - 1, - -0, - 9007199254740991, - -9007199254740991, - ]; - for (const value of safeIntegers) { - assert.ok(isSafeInteger(value), `isSafeInteger ${ typeof value } ${ value }`); - } - const notSafeIntegers = [ - 9007199254740992, - -9007199254740992, - NaN, - 0.1, - Infinity, - 'NaN', - '5', - false, - new Number(NaN), - new Number(Infinity), - new Number(5), - new Number(0.1), - undefined, - null, - {}, - function () { /* empty */ }, - ]; - for (const value of notSafeIntegers) { - assert.ok(!isSafeInteger(value), `not isSafeInteger ${ typeof value } ${ value }`); - } - assert.ok(!isSafeInteger(create(null)), 'Number.isSafeInteger(Object.create(null)) -> false'); -}); diff --git a/tests/pure/es.number.max-safe-integer.js b/tests/pure/es.number.max-safe-integer.js deleted file mode 100644 index 38d4e6ccacf4..000000000000 --- a/tests/pure/es.number.max-safe-integer.js +++ /dev/null @@ -1,5 +0,0 @@ -import MAX_SAFE_INTEGER from 'core-js-pure/features/number/max-safe-integer'; - -QUnit.test('Number.MAX_SAFE_INTEGER', assert => { - assert.strictEqual(MAX_SAFE_INTEGER, 2 ** 53 - 1, 'Is 2^53 - 1'); -}); diff --git a/tests/pure/es.number.min-safe-integer.js b/tests/pure/es.number.min-safe-integer.js deleted file mode 100644 index 1bbd3e4e86a2..000000000000 --- a/tests/pure/es.number.min-safe-integer.js +++ /dev/null @@ -1,5 +0,0 @@ -import MIN_SAFE_INTEGER from 'core-js-pure/features/number/min-safe-integer'; - -QUnit.test('Number.MIN_SAFE_INTEGER', assert => { - assert.strictEqual(MIN_SAFE_INTEGER, -(2 ** 53) + 1, 'Is -2^53 + 1'); -}); diff --git a/tests/pure/es.number.parse-float.js b/tests/pure/es.number.parse-float.js deleted file mode 100644 index f8390ec38fb2..000000000000 --- a/tests/pure/es.number.parse-float.js +++ /dev/null @@ -1,18 +0,0 @@ -import { WHITESPACES } from '../helpers/constants'; - -import parseFloat from 'core-js-pure/features/number/parse-float'; - -QUnit.test('Number.parseFloat', assert => { - assert.isFunction(parseFloat); - assert.arity(parseFloat, 1); - assert.same(parseFloat('0'), 0); - assert.same(parseFloat(' 0'), 0); - assert.same(parseFloat('+0'), 0); - assert.same(parseFloat(' +0'), 0); - assert.same(parseFloat('-0'), -0); - assert.same(parseFloat(' -0'), -0); - assert.same(parseFloat(`${ WHITESPACES }+0`), 0); - assert.same(parseFloat(`${ WHITESPACES }-0`), -0); - assert.same(parseFloat(null), NaN); - assert.same(parseFloat(undefined), NaN); -}); diff --git a/tests/pure/es.number.parse-int.js b/tests/pure/es.number.parse-int.js deleted file mode 100644 index ade560594a4b..000000000000 --- a/tests/pure/es.number.parse-int.js +++ /dev/null @@ -1,35 +0,0 @@ -import { WHITESPACES } from '../helpers/constants'; - -import parseInt from 'core-js-pure/features/number/parse-int'; - -QUnit.test('Number.parseInt', assert => { - assert.isFunction(parseInt); - assert.arity(parseInt, 2); - for (let radix = 2; radix <= 36; ++radix) { - assert.same(parseInt('10', radix), radix, `radix ${ radix }`); - } - const strings = ['01', '08', '10', '42']; - for (const string of strings) { - assert.same(parseInt(string), parseInt(string, 10), `default radix is 10: ${ string }`); - } - assert.same(parseInt('0x16'), parseInt('0x16', 16), 'default radix is 16: 0x16'); - assert.same(parseInt(' 0x16'), parseInt('0x16', 16), 'ignores leading whitespace #1'); - assert.same(parseInt(' 42'), parseInt('42', 10), 'ignores leading whitespace #2'); - assert.same(parseInt(' 08'), parseInt('08', 10), 'ignores leading whitespace #3'); - assert.same(parseInt(`${ WHITESPACES }08`), parseInt('08', 10), 'ignores leading whitespace #4'); - assert.same(parseInt(`${ WHITESPACES }0x16`), parseInt('0x16', 16), 'ignores leading whitespace #5'); - const fakeZero = { - valueOf() { - return 0; - }, - }; - assert.same(parseInt('08', fakeZero), parseInt('08', 10), 'valueOf #1'); - assert.same(parseInt('0x16', fakeZero), parseInt('0x16', 16), 'valueOf #2'); - assert.same(parseInt('-0xF'), -15, 'signed hex #1'); - assert.same(parseInt('-0xF', 16), -15, 'signed hex #2'); - assert.same(parseInt('+0xF'), 15, 'signed hex #3'); - assert.same(parseInt('+0xF', 16), 15, 'signed hex #4'); - assert.same(parseInt('10', -4294967294), 2, 'radix uses ToUint32'); - assert.same(parseInt(null), NaN); - assert.same(parseInt(undefined), NaN); -}); diff --git a/tests/pure/es.number.to-fixed.js b/tests/pure/es.number.to-fixed.js deleted file mode 100644 index 0e7c200affeb..000000000000 --- a/tests/pure/es.number.to-fixed.js +++ /dev/null @@ -1,66 +0,0 @@ -import toFixed from 'core-js-pure/features/number/to-fixed'; - -QUnit.test('Number#toFixed', assert => { - assert.isFunction(toFixed); - assert.same(toFixed(0.00008, 3), '0.000'); - assert.same(toFixed(0.9, 0), '1'); - assert.same(toFixed(1.255, 2), '1.25'); - assert.same(toFixed(1843654265.0774949, 5), '1843654265.07749'); - assert.same(toFixed(1000000000000000128, 0), '1000000000000000128'); - assert.same(toFixed(1), '1'); - assert.same(toFixed(1, 0), '1'); - assert.same(toFixed(1, 1), '1.0'); - assert.same(toFixed(1, 1.1), '1.0'); - assert.same(toFixed(1, 0.9), '1'); - assert.same(toFixed(1, '0'), '1'); - assert.same(toFixed(1, '1'), '1.0'); - assert.same(toFixed(1, '1.1'), '1.0'); - assert.same(toFixed(1, '0.9'), '1'); - assert.same(toFixed(1, NaN), '1'); - assert.same(toFixed(1, 'some string'), '1'); - assert.notThrows(() => toFixed(1, -0.1) === '1'); - assert.same(toFixed(Object(1)), '1'); - assert.same(toFixed(Object(1), 0), '1'); - assert.same(toFixed(Object(1), 1), '1.0'); - assert.same(toFixed(Object(1), 1.1), '1.0'); - assert.same(toFixed(Object(1), 0.9), '1'); - assert.same(toFixed(Object(1), '0'), '1'); - assert.same(toFixed(Object(1), '1'), '1.0'); - assert.same(toFixed(Object(1), '1.1'), '1.0'); - assert.same(toFixed(Object(1), '0.9'), '1'); - assert.same(toFixed(Object(1), NaN), '1'); - assert.same(toFixed(Object(1), 'some string'), '1'); - assert.notThrows(() => toFixed(Object(1), -0.1) === '1'); - assert.same(toFixed(NaN), 'NaN'); - assert.same(toFixed(NaN, 0), 'NaN'); - assert.same(toFixed(NaN, 1), 'NaN'); - assert.same(toFixed(NaN, 1.1), 'NaN'); - assert.same(toFixed(NaN, 0.9), 'NaN'); - assert.same(toFixed(NaN, '0'), 'NaN'); - assert.same(toFixed(NaN, '1'), 'NaN'); - assert.same(toFixed(NaN, '1.1'), 'NaN'); - assert.same(toFixed(NaN, '0.9'), 'NaN'); - assert.same(toFixed(NaN, NaN), 'NaN'); - assert.same(toFixed(NaN, 'some string'), 'NaN'); - assert.notThrows(() => toFixed(NaN, -0.1) === 'NaN'); - assert.same(toFixed(1e21), String(1e21)); - assert.same(toFixed(1e21, 0), String(1e21)); - assert.same(toFixed(1e21, 1), String(1e21)); - assert.same(toFixed(1e21, 1.1), String(1e21)); - assert.same(toFixed(1e21, 0.9), String(1e21)); - assert.same(toFixed(1e21, '0'), String(1e21)); - assert.same(toFixed(1e21, '1'), String(1e21)); - assert.same(toFixed(1e21, '1.1'), String(1e21)); - assert.same(toFixed(1e21, '0.9'), String(1e21)); - assert.same(toFixed(1e21, NaN), String(1e21)); - assert.same(toFixed(1e21, 'some string'), String(1e21)); - assert.notThrows(() => toFixed(1e21, -0.1) === String(1e21)); - assert.throws(() => toFixed(1, -101), RangeError, 'If f < 0 or f > 20, throw a RangeError exception.'); - assert.throws(() => toFixed(1, 101), RangeError, 'If f < 0 or f > 20, throw a RangeError exception.'); - assert.throws(() => toFixed(NaN, Infinity), RangeError, 'If f < 0 or f > 20, throw a RangeError exception.'); - assert.throws(() => toFixed({}, 1), TypeError, '? thisNumberValue(this value)'); - assert.throws(() => toFixed('123', 1), TypeError, '? thisNumberValue(this value)'); - assert.throws(() => toFixed(false, 1), TypeError, '? thisNumberValue(this value)'); - assert.throws(() => toFixed(null, 1), TypeError, '? thisNumberValue(this value)'); - assert.throws(() => toFixed(undefined, 1), TypeError, '? thisNumberValue(this value)'); -}); diff --git a/tests/pure/es.object.assign.js b/tests/pure/es.object.assign.js deleted file mode 100644 index 50883950faa9..000000000000 --- a/tests/pure/es.object.assign.js +++ /dev/null @@ -1,64 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import Symbol from 'core-js-pure/features/symbol'; -import { assign, keys, defineProperty } from 'core-js-pure/features/object'; - -QUnit.test('Object.assign', assert => { - assert.isFunction(assign); - let object = { q: 1 }; - assert.strictEqual(object, assign(object, { bar: 2 }), 'assign return target'); - assert.strictEqual(object.bar, 2, 'assign define properties'); - assert.deepEqual(assign({}, { q: 1 }, { w: 2 }), { q: 1, w: 2 }); - assert.deepEqual(assign({}, 'qwe'), { 0: 'q', 1: 'w', 2: 'e' }); - assert.throws(() => assign(null, { q: 1 }), TypeError); - assert.throws(() => assign(undefined, { q: 1 }), TypeError); - let string = assign('qwe', { q: 1 }); - assert.strictEqual(typeof string, 'object'); - assert.strictEqual(String(string), 'qwe'); - assert.strictEqual(string.q, 1); - assert.same(assign({}, { valueOf: 42 }).valueOf, 42, 'IE enum keys bug'); - if (DESCRIPTORS) { - object = { baz: 1 }; - assign(object, defineProperty({}, 'bar', { - get() { - return this.baz + 1; - }, - })); - assert.ok(object.bar === undefined, "assign don't copy descriptors"); - object = { a: 'a' }; - const c = Symbol('c'); - const d = Symbol('d'); - object[c] = 'c'; - defineProperty(object, 'b', { value: 'b' }); - defineProperty(object, d, { value: 'd' }); - const object2 = assign({}, object); - assert.strictEqual(object2.a, 'a', 'a'); - assert.strictEqual(object2.b, undefined, 'b'); - assert.strictEqual(object2[c], 'c', 'c'); - assert.strictEqual(object2[d], undefined, 'd'); - try { - assert.strictEqual(Function('assign', ` - return assign({ b: 1 }, { get a() { - delete this.b; - }, b: 2 }); - `)(assign).b, 1); - } catch { /* empty */ } - try { - assert.strictEqual(Function('assign', ` - return assign({ b: 1 }, { get a() { - Object.defineProperty(this, "b", { - value: 4, - enumerable: false - }); - }, b: 2 }); - `)(assign).b, 1); - } catch { /* empty */ } - } - string = 'abcdefghijklmnopqrst'; - const result = {}; - for (let i = 0, { length } = string; i < length; ++i) { - const char = string.charAt(i); - result[char] = char; - } - assert.strictEqual(keys(assign({}, result)).join(''), string); -}); diff --git a/tests/pure/es.object.create.js b/tests/pure/es.object.create.js deleted file mode 100644 index 2a564b50454c..000000000000 --- a/tests/pure/es.object.create.js +++ /dev/null @@ -1,34 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import { create, getPrototypeOf, getOwnPropertyNames } from 'core-js-pure/features/object'; - -QUnit.test('Object.create', assert => { - function getPropertyNames(object) { - let result = []; - do { - result = result.concat(getOwnPropertyNames(object)); - } while (object = getPrototypeOf(object)); - return result; - } - assert.isFunction(create); - assert.arity(create, 2); - let object = { q: 1 }; - assert.ok({}.isPrototypeOf.call(object, create(object))); - assert.ok(create(object).q === 1); - function C() { - return this.a = 1; - } - assert.ok(create(new C()) instanceof C); - assert.ok(C.prototype === getPrototypeOf(getPrototypeOf(create(new C())))); - assert.ok(create(new C()).a === 1); - assert.ok(create({}, { a: { value: 42 } }).a === 42); - object = create(null, { w: { value: 2 } }); - assert.same(object, Object(object)); - assert.ok(!('toString' in object)); - assert.ok(object.w === 2); - assert.deepEqual(getPropertyNames(create(null)), []); -}); - -QUnit.test('Object.create.sham flag', assert => { - assert.same(create.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/pure/es.object.define-getter.js b/tests/pure/es.object.define-getter.js deleted file mode 100644 index 692545ed20ab..000000000000 --- a/tests/pure/es.object.define-getter.js +++ /dev/null @@ -1,21 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -import { __defineGetter__, __defineSetter__ } from 'core-js-pure/features/object'; - -if (DESCRIPTORS) { - QUnit.test('Object#__defineGetter__', assert => { - assert.isFunction(__defineGetter__); - const object = {}; - assert.same(__defineGetter__(object, 'key', () => 42), undefined, 'void'); - assert.same(object.key, 42, 'works'); - __defineSetter__(object, 'key', function () { - this.foo = 43; - }); - object.key = 44; - assert.ok(object.key === 42 && object.foo === 43, 'works with setter'); - if (STRICT) { - assert.throws(() => __defineGetter__(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); - assert.throws(() => __defineGetter__(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); - } - }); -} diff --git a/tests/pure/es.object.define-properties.js b/tests/pure/es.object.define-properties.js deleted file mode 100644 index b74adac851b2..000000000000 --- a/tests/pure/es.object.define-properties.js +++ /dev/null @@ -1,17 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import defineProperties from 'core-js-pure/features/object/define-properties'; - -QUnit.test('Object.defineProperties', assert => { - assert.isFunction(defineProperties); - assert.arity(defineProperties, 2); - const source = {}; - const result = defineProperties(source, { q: { value: 42 }, w: { value: 33 } }); - assert.same(result, source); - assert.same(result.q, 42); - assert.same(result.w, 33); -}); - -QUnit.test('Object.defineProperties.sham flag', assert => { - assert.same(defineProperties.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/pure/es.object.define-property.js b/tests/pure/es.object.define-property.js deleted file mode 100644 index d0a8a4db4e07..000000000000 --- a/tests/pure/es.object.define-property.js +++ /dev/null @@ -1,21 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import { defineProperty, create } from 'core-js-pure/features/object'; - -QUnit.test('Object.defineProperty', assert => { - assert.isFunction(defineProperty); - assert.arity(defineProperty, 3); - const source = {}; - const result = defineProperty(source, 'q', { - value: 42, - }); - assert.same(result, source); - assert.same(result.q, 42); - assert.throws(() => defineProperty(42, 1, {})); - assert.throws(() => defineProperty({}, create(null), {})); - assert.throws(() => defineProperty({}, 1, 1)); -}); - -QUnit.test('Object.defineProperty.sham flag', assert => { - assert.same(defineProperty.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/pure/es.object.define-setter.js b/tests/pure/es.object.define-setter.js deleted file mode 100644 index 5724add31a1b..000000000000 --- a/tests/pure/es.object.define-setter.js +++ /dev/null @@ -1,26 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -import { __defineGetter__, __defineSetter__ } from 'core-js-pure/features/object'; - -if (DESCRIPTORS) { - QUnit.test('Object#__defineSetter__', assert => { - assert.isFunction(__defineSetter__); - let object = {}; - assert.same(__defineSetter__(object, 'key', function () { - this.foo = 43; - }), undefined, 'void'); - object.key = 44; - assert.same(object.foo, 43, 'works'); - object = {}; - __defineSetter__(object, 'key', function () { - this.foo = 43; - }); - __defineGetter__(object, 'key', () => 42); - object.key = 44; - assert.ok(object.key === 42 && object.foo === 43, 'works with getter'); - if (STRICT) { - assert.throws(() => __defineSetter__(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); - assert.throws(() => __defineSetter__(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); - } - }); -} diff --git a/tests/pure/es.object.freeze.js b/tests/pure/es.object.freeze.js deleted file mode 100644 index 9f726f709ffa..000000000000 --- a/tests/pure/es.object.freeze.js +++ /dev/null @@ -1,19 +0,0 @@ -import { freeze, keys, getOwnPropertyNames, getOwnPropertySymbols } from 'core-js-pure/features/object'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; - -QUnit.test('Object.freeze', assert => { - assert.isFunction(freeze); - assert.arity(freeze, 1); - const data = [42, 'foo', false, null, undefined, {}]; - for (const value of data) { - assert.notThrows(() => freeze(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); - assert.same(freeze(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); - } - const results = []; - for (const key in freeze({})) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(freeze({})), []); - assert.arrayEqual(getOwnPropertyNames(freeze({})), []); - assert.arrayEqual(getOwnPropertySymbols(freeze({})), []); - assert.arrayEqual(ownKeys(freeze({})), []); -}); diff --git a/tests/pure/es.object.from-entries.js b/tests/pure/es.object.from-entries.js deleted file mode 100644 index 803e4d2edba2..000000000000 --- a/tests/pure/es.object.from-entries.js +++ /dev/null @@ -1,28 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import fromEntries from 'core-js-pure/features/object/from-entries'; -import Set from 'core-js-pure/features/set'; - -QUnit.test('Object.fromEntries', assert => { - assert.isFunction(fromEntries); - assert.arity(fromEntries, 1); - assert.name(fromEntries, 'fromEntries'); - - assert.ok(fromEntries([]) instanceof Object); - assert.same(fromEntries([['foo', 1]]).foo, 1); - assert.same(fromEntries(createIterable([['bar', 2]])).bar, 2); - - class Unit { - constructor(id) { - this.id = id; - } - toString() { - return `unit${ this.id }`; - } - } - const units = new Set([new Unit(101), new Unit(102), new Unit(103)]); - const object = fromEntries(units.entries()); - assert.same(object.unit101.id, 101); - assert.same(object.unit102.id, 102); - assert.same(object.unit103.id, 103); -}); diff --git a/tests/pure/es.object.get-own-property-descriptor.js b/tests/pure/es.object.get-own-property-descriptor.js deleted file mode 100644 index 2411059e451b..000000000000 --- a/tests/pure/es.object.get-own-property-descriptor.js +++ /dev/null @@ -1,25 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import getOwnPropertyDescriptor from 'core-js-pure/features/object/get-own-property-descriptor'; - -QUnit.test('Object.getOwnPropertyDescriptor', assert => { - assert.isFunction(getOwnPropertyDescriptor); - assert.arity(getOwnPropertyDescriptor, 2); - assert.deepEqual(getOwnPropertyDescriptor({ q: 42 }, 'q'), { - writable: true, - enumerable: true, - configurable: true, - value: 42, - }); - assert.ok(getOwnPropertyDescriptor({}, 'toString') === undefined); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => getOwnPropertyDescriptor(value) || true, `accept ${ typeof value }`); - } - assert.throws(() => getOwnPropertyDescriptor(null), TypeError, 'throws on null'); - assert.throws(() => getOwnPropertyDescriptor(undefined), TypeError, 'throws on undefined'); -}); - -QUnit.test('Object.getOwnPropertyDescriptor.sham flag', assert => { - assert.same(getOwnPropertyDescriptor.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/pure/es.object.get-own-property-descriptors.js b/tests/pure/es.object.get-own-property-descriptors.js deleted file mode 100644 index e90eef80d003..000000000000 --- a/tests/pure/es.object.get-own-property-descriptors.js +++ /dev/null @@ -1,40 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import Symbol from 'core-js-pure/features/symbol'; -import { create, getOwnPropertyDescriptors } from 'core-js-pure/features/object'; - -QUnit.test('Object.getOwnPropertyDescriptors', assert => { - assert.isFunction(getOwnPropertyDescriptors); - const object = create({ q: 1 }, { e: { value: 3 } }); - object.w = 2; - const symbol = Symbol('4'); - object[symbol] = 4; - const descriptors = getOwnPropertyDescriptors(object); - assert.strictEqual(descriptors.q, undefined); - assert.deepEqual(descriptors.w, { - enumerable: true, - configurable: true, - writable: true, - value: 2, - }); - if (DESCRIPTORS) { - assert.deepEqual(descriptors.e, { - enumerable: false, - configurable: false, - writable: false, - value: 3, - }); - } else { - assert.deepEqual(descriptors.e, { - enumerable: true, - configurable: true, - writable: true, - value: 3, - }); - } - assert.strictEqual(descriptors[symbol].value, 4); -}); - -QUnit.test('Object.getOwnPropertyDescriptors.sham flag', assert => { - assert.same(getOwnPropertyDescriptors.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/pure/es.object.get-own-property-names.js b/tests/pure/es.object.get-own-property-names.js deleted file mode 100644 index 5fd043086c87..000000000000 --- a/tests/pure/es.object.get-own-property-names.js +++ /dev/null @@ -1,43 +0,0 @@ -import { GLOBAL } from '../helpers/constants'; -import { includes } from '../helpers/helpers'; - -import getOwnPropertyNames from 'core-js-pure/features/object/get-own-property-names'; - -QUnit.test('Object.getOwnPropertyNames', assert => { - assert.isFunction(getOwnPropertyNames); - assert.arity(getOwnPropertyNames, 1); - function F1() { - this.w = 1; - } - function F2() { - this.toString = 1; - } - F1.prototype.q = F2.prototype.q = 1; - const names = getOwnPropertyNames([1, 2, 3]); - assert.strictEqual(names.length, 4); - assert.ok(includes(names, '0')); - assert.ok(includes(names, '1')); - assert.ok(includes(names, '2')); - assert.ok(includes(names, 'length')); - assert.deepEqual(getOwnPropertyNames(new F1()), ['w']); - assert.deepEqual(getOwnPropertyNames(new F2()), ['toString']); - assert.ok(includes(getOwnPropertyNames(Array.prototype), 'toString')); - assert.ok(includes(getOwnPropertyNames(Object.prototype), 'toString')); - assert.ok(includes(getOwnPropertyNames(Object.prototype), 'constructor')); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => getOwnPropertyNames(value), `accept ${ typeof value }`); - } - assert.throws(() => getOwnPropertyNames(null), TypeError, 'throws on null'); - assert.throws(() => getOwnPropertyNames(undefined), TypeError, 'throws on undefined'); - if (GLOBAL.document) { - assert.notThrows(() => { - const iframe = document.createElement('iframe'); - iframe.src = 'http://example.com/'; - document.documentElement.appendChild(iframe); - const window = iframe.contentWindow; - document.documentElement.removeChild(iframe); - return getOwnPropertyNames(window); - }, 'IE11 bug with iframe and window'); - } -}); diff --git a/tests/pure/es.object.get-prototype-of.js b/tests/pure/es.object.get-prototype-of.js deleted file mode 100644 index 3308941607d5..000000000000 --- a/tests/pure/es.object.get-prototype-of.js +++ /dev/null @@ -1,33 +0,0 @@ -import { CORRECT_PROTOTYPE_GETTER } from '../helpers/constants'; - -import { create, getPrototypeOf } from 'core-js-pure/features/object'; - -QUnit.test('Object.getPrototypeOf', assert => { - assert.isFunction(getPrototypeOf); - assert.arity(getPrototypeOf, 1); - assert.ok(getPrototypeOf({}) === Object.prototype); - assert.ok(getPrototypeOf([]) === Array.prototype); - function F() { /* empty */ } - assert.ok(getPrototypeOf(new F()) === F.prototype); - const object = { q: 1 }; - assert.ok(getPrototypeOf(create(object)) === object); - assert.ok(getPrototypeOf(create(null)) === null); - assert.ok(getPrototypeOf(getPrototypeOf({})) === null); - function Foo() { /* empty */ } - Foo.prototype.foo = 'foo'; - function Bar() { /* empty */ } - Bar.prototype = create(Foo.prototype); - Bar.prototype.constructor = Bar; - assert.strictEqual(getPrototypeOf(Bar.prototype).foo, 'foo'); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => getPrototypeOf(value), `accept ${ typeof value }`); - } - assert.throws(() => getPrototypeOf(null), TypeError, 'throws on null'); - assert.throws(() => getPrototypeOf(undefined), TypeError, 'throws on undefined'); - assert.strictEqual(getPrototypeOf('foo'), String.prototype); -}); - -QUnit.test('Object.getPrototypeOf.sham flag', assert => { - assert.same(getPrototypeOf.sham, CORRECT_PROTOTYPE_GETTER ? undefined : true); -}); diff --git a/tests/pure/es.object.is-extensible.js b/tests/pure/es.object.is-extensible.js deleted file mode 100644 index e2940c25534f..000000000000 --- a/tests/pure/es.object.is-extensible.js +++ /dev/null @@ -1,12 +0,0 @@ -import isExtensible from 'core-js-pure/features/object/is-extensible'; - -QUnit.test('Object.isExtensible', assert => { - assert.isFunction(isExtensible); - assert.arity(isExtensible, 1); - const primitives = [42, 'string', false, null, undefined]; - for (const value of primitives) { - assert.notThrows(() => isExtensible(value) || true, `accept ${ value }`); - assert.same(isExtensible(value), false, `returns false on ${ value }`); - } - assert.same(isExtensible({}), true); -}); diff --git a/tests/pure/es.object.is-frozen.js b/tests/pure/es.object.is-frozen.js deleted file mode 100644 index f380ffc39e7a..000000000000 --- a/tests/pure/es.object.is-frozen.js +++ /dev/null @@ -1,12 +0,0 @@ -import isFrozen from 'core-js-pure/features/object/is-frozen'; - -QUnit.test('Object.isFrozen', assert => { - assert.isFunction(isFrozen); - assert.arity(isFrozen, 1); - const primitives = [42, 'string', false, null, undefined]; - for (const value of primitives) { - assert.notThrows(() => isFrozen(value) || true, `accept ${ value }`); - assert.same(isFrozen(value), true, `returns true on ${ value }`); - } - assert.same(isFrozen({}), false); -}); diff --git a/tests/pure/es.object.is-sealed.js b/tests/pure/es.object.is-sealed.js deleted file mode 100644 index fb417b299d87..000000000000 --- a/tests/pure/es.object.is-sealed.js +++ /dev/null @@ -1,12 +0,0 @@ -import isSealed from 'core-js-pure/features/object/is-sealed'; - -QUnit.test('Object.isSealed', assert => { - assert.isFunction(isSealed); - assert.arity(isSealed, 1); - const primitives = [42, 'string', false, null, undefined]; - for (const value of primitives) { - assert.notThrows(() => isSealed(value) || true, `accept ${ value }`); - assert.same(isSealed(value), true, `returns true on ${ value }`); - } - assert.same(isSealed({}), false); -}); diff --git a/tests/pure/es.object.is.js b/tests/pure/es.object.is.js deleted file mode 100644 index 005052ce0a70..000000000000 --- a/tests/pure/es.object.is.js +++ /dev/null @@ -1,9 +0,0 @@ -import is from 'core-js-pure/features/object/is'; - -QUnit.test('Object.is', assert => { - assert.isFunction(is); - assert.ok(is(1, 1), '1 is 1'); - assert.ok(is(NaN, NaN), '1 is 1'); - assert.ok(!is(0, -0), '0 isnt -0'); - assert.ok(!is({}, {}), '{} isnt {}'); -}); diff --git a/tests/pure/es.object.keys.js b/tests/pure/es.object.keys.js deleted file mode 100644 index 5a36daec4551..000000000000 --- a/tests/pure/es.object.keys.js +++ /dev/null @@ -1,25 +0,0 @@ -import { includes } from '../helpers/helpers'; - -import keys from 'core-js-pure/features/object/keys'; - -QUnit.test('Object.keys', assert => { - assert.isFunction(keys); - assert.arity(keys, 1); - function F1() { - this.w = 1; - } - function F2() { - this.toString = 1; - } - F1.prototype.q = F2.prototype.q = 1; - assert.deepEqual(keys([1, 2, 3]), ['0', '1', '2']); - assert.deepEqual(keys(new F1()), ['w']); - assert.deepEqual(keys(new F2()), ['toString']); - assert.ok(!includes(keys(Array.prototype), 'push')); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => keys(value), `accept ${ typeof value }`); - } - assert.throws(() => keys(null), TypeError, 'throws on null'); - assert.throws(() => keys(undefined), TypeError, 'throws on undefined'); -}); diff --git a/tests/pure/es.object.lookup-getter.js b/tests/pure/es.object.lookup-getter.js deleted file mode 100644 index cc3cda36a7f2..000000000000 --- a/tests/pure/es.object.lookup-getter.js +++ /dev/null @@ -1,21 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -import { __lookupGetter__, __defineGetter__, create } from 'core-js-pure/features/object'; - -if (DESCRIPTORS) { - QUnit.test('Object#__lookupGetter__', assert => { - assert.isFunction(__lookupGetter__); - assert.same(__lookupGetter__({}, 'key'), undefined, 'empty object'); - assert.same(__lookupGetter__({ key: 42 }, 'key'), undefined, 'data descriptor'); - const object = {}; - function getter() { /* empty */ } - __defineGetter__(object, 'key', getter); - assert.same(__lookupGetter__(object, 'key'), getter, 'own getter'); - assert.same(__lookupGetter__(create(object), 'key'), getter, 'proto getter'); - assert.same(__lookupGetter__(create(object), 'foo'), undefined, 'empty proto'); - if (STRICT) { - assert.throws(() => __lookupGetter__(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); - assert.throws(() => __lookupGetter__(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); - } - }); -} diff --git a/tests/pure/es.object.lookup-setter.js b/tests/pure/es.object.lookup-setter.js deleted file mode 100644 index 03685f529bcc..000000000000 --- a/tests/pure/es.object.lookup-setter.js +++ /dev/null @@ -1,21 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -import { __lookupSetter__, __defineSetter__, create } from 'core-js-pure/features/object'; - -if (DESCRIPTORS) { - QUnit.test('Object#__lookupSetter__', assert => { - assert.isFunction(__lookupSetter__); - assert.same(__lookupSetter__({}, 'key'), undefined, 'empty object'); - assert.same(__lookupSetter__({ key: 42 }, 'key'), undefined, 'data descriptor'); - const object = {}; - function setter() { /* empty */ } - __defineSetter__(object, 'key', setter); - assert.same(__lookupSetter__(object, 'key'), setter, 'own getter'); - assert.same(__lookupSetter__(create(object), 'key'), setter, 'proto getter'); - assert.same(__lookupSetter__(create(object), 'foo'), undefined, 'empty proto'); - if (STRICT) { - assert.throws(() => __lookupSetter__(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); - assert.throws(() => __lookupSetter__(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); - } - }); -} diff --git a/tests/pure/es.object.prevent-extensions.js b/tests/pure/es.object.prevent-extensions.js deleted file mode 100644 index affb495e3126..000000000000 --- a/tests/pure/es.object.prevent-extensions.js +++ /dev/null @@ -1,19 +0,0 @@ -import { preventExtensions, keys, getOwnPropertyNames, getOwnPropertySymbols } from 'core-js-pure/features/object'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; - -QUnit.test('Object.preventExtensions', assert => { - assert.isFunction(preventExtensions); - assert.arity(preventExtensions, 1); - const data = [42, 'foo', false, null, undefined, {}]; - for (const value of data) { - assert.notThrows(() => preventExtensions(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); - assert.same(preventExtensions(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); - } - const results = []; - for (const key in preventExtensions({})) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(preventExtensions({})), []); - assert.arrayEqual(getOwnPropertyNames(preventExtensions({})), []); - assert.arrayEqual(getOwnPropertySymbols(preventExtensions({})), []); - assert.arrayEqual(ownKeys(preventExtensions({})), []); -}); diff --git a/tests/pure/es.object.seal.js b/tests/pure/es.object.seal.js deleted file mode 100644 index eafc8cbac684..000000000000 --- a/tests/pure/es.object.seal.js +++ /dev/null @@ -1,19 +0,0 @@ -import { seal, keys, getOwnPropertyNames, getOwnPropertySymbols } from 'core-js-pure/features/object'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; - -QUnit.test('Object.seal', assert => { - assert.isFunction(seal); - assert.arity(seal, 1); - const data = [42, 'foo', false, null, undefined, {}]; - for (const value of data) { - assert.notThrows(() => seal(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); - assert.same(seal(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); - } - const results = []; - for (const key in seal({})) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(seal({})), []); - assert.arrayEqual(getOwnPropertyNames(seal({})), []); - assert.arrayEqual(getOwnPropertySymbols(seal({})), []); - assert.arrayEqual(ownKeys(seal({})), []); -}); diff --git a/tests/pure/es.object.set-prototype-of.js b/tests/pure/es.object.set-prototype-of.js deleted file mode 100644 index 40666894533a..000000000000 --- a/tests/pure/es.object.set-prototype-of.js +++ /dev/null @@ -1,16 +0,0 @@ -import { PROTO } from '../helpers/constants'; - -import setPrototypeOf from 'core-js-pure/features/object/set-prototype-of'; - -if (PROTO) QUnit.test('Object.setPrototypeOf', assert => { - assert.isFunction(setPrototypeOf); - assert.ok('apply' in setPrototypeOf({}, Function.prototype), 'Parent properties in target'); - assert.strictEqual(setPrototypeOf({ a: 2 }, { - b() { - return this.a ** 2; - }, - }).b(), 4, 'Child and parent properties in target'); - const object = {}; - assert.strictEqual(setPrototypeOf(object, { a: 1 }), object, 'setPrototypeOf return target'); - assert.ok(!('toString' in setPrototypeOf({}, null)), 'Can set null as prototype'); -}); diff --git a/tests/pure/es.parse-float.js b/tests/pure/es.parse-float.js deleted file mode 100644 index 5b5e4ca34613..000000000000 --- a/tests/pure/es.parse-float.js +++ /dev/null @@ -1,17 +0,0 @@ -import { WHITESPACES } from '../helpers/constants'; -import parseFloat from 'core-js-pure/features/parse-float'; - -QUnit.test('parseFloat', assert => { - assert.isFunction(parseFloat); - assert.arity(parseFloat, 1); - assert.same(parseFloat('0'), 0); - assert.same(parseFloat(' 0'), 0); - assert.same(parseFloat('+0'), 0); - assert.same(parseFloat(' +0'), 0); - assert.same(parseFloat('-0'), -0); - assert.same(parseFloat(' -0'), -0); - assert.same(parseFloat(`${ WHITESPACES }+0`), 0); - assert.same(parseFloat(`${ WHITESPACES }-0`), -0); - assert.same(parseFloat(null), NaN); - assert.same(parseFloat(undefined), NaN); -}); diff --git a/tests/pure/es.parse-int.js b/tests/pure/es.parse-int.js deleted file mode 100644 index 386105656847..000000000000 --- a/tests/pure/es.parse-int.js +++ /dev/null @@ -1,34 +0,0 @@ -import { WHITESPACES } from '../helpers/constants'; -import parseInt from 'core-js-pure/features/parse-int'; - -QUnit.test('parseInt', assert => { - assert.isFunction(parseInt); - assert.arity(parseInt, 2); - for (let radix = 2; radix <= 36; ++radix) { - assert.same(parseInt('10', radix), radix, `radix ${ radix }`); - } - const strings = ['01', '08', '10', '42']; - for (const string of strings) { - assert.same(parseInt(string), parseInt(string, 10), `default radix is 10: ${ string }`); - } - assert.same(parseInt('0x16'), parseInt('0x16', 16), 'default radix is 16: 0x16'); - assert.same(parseInt(' 0x16'), parseInt('0x16', 16), 'ignores leading whitespace #1'); - assert.same(parseInt(' 42'), parseInt('42', 10), 'ignores leading whitespace #2'); - assert.same(parseInt(' 08'), parseInt('08', 10), 'ignores leading whitespace #3'); - assert.same(parseInt(`${ WHITESPACES }08`), parseInt('08', 10), 'ignores leading whitespace #4'); - assert.same(parseInt(`${ WHITESPACES }0x16`), parseInt('0x16', 16), 'ignores leading whitespace #5'); - const fakeZero = { - valueOf() { - return 0; - }, - }; - assert.same(parseInt('08', fakeZero), parseInt('08', 10), 'valueOf #1'); - assert.same(parseInt('0x16', fakeZero), parseInt('0x16', 16), 'valueOf #2'); - assert.same(parseInt('-0xF'), -15, 'signed hex #1'); - assert.same(parseInt('-0xF', 16), -15, 'signed hex #2'); - assert.same(parseInt('+0xF'), 15, 'signed hex #3'); - assert.same(parseInt('+0xF', 16), 15, 'signed hex #4'); - assert.same(parseInt('10', -4294967294), 2, 'radix uses ToUint32'); - assert.same(parseInt(null), NaN); - assert.same(parseInt(undefined), NaN); -}); diff --git a/tests/pure/es.promise.all-settled.js b/tests/pure/es.promise.all-settled.js deleted file mode 100644 index 72e513a904ec..000000000000 --- a/tests/pure/es.promise.all-settled.js +++ /dev/null @@ -1,33 +0,0 @@ -import Promise from 'core-js-pure/es/promise'; - -QUnit.test('Promise.allSettled', assert => { - assert.isFunction(Promise.allSettled); - assert.arity(Promise.allSettled, 1); - assert.ok(Promise.allSettled([1, 2, 3]) instanceof Promise, 'returns a promise'); -}); - -QUnit.test('Promise.allSettled, resolved', assert => { - assert.expect(1); - const async = assert.async(); - Promise.allSettled([ - Promise.resolve(1), - Promise.reject(2), - Promise.resolve(3), - ]).then(it => { - assert.deepEqual(it, [ - { value: 1, status: 'fulfilled' }, - { reason: 2, status: 'rejected' }, - { value: 3, status: 'fulfilled' }, - ], 'resolved with a correct value'); - async(); - }); -}); - -QUnit.test('Promise.allSettled, rejected', assert => { - assert.expect(1); - const async = assert.async(); - Promise.allSettled().catch(() => { - assert.ok(true, 'rejected as expected'); - async(); - }); -}); diff --git a/tests/pure/es.promise.finally.js b/tests/pure/es.promise.finally.js deleted file mode 100644 index 44d7091f3fb6..000000000000 --- a/tests/pure/es.promise.finally.js +++ /dev/null @@ -1,39 +0,0 @@ -import Promise from 'core-js-pure/features/promise'; - -QUnit.test('Promise#finally', assert => { - assert.isFunction(Promise.prototype.finally); - assert.arity(Promise.prototype.finally, 1); - assert.nonEnumerable(Promise.prototype, 'finally'); - assert.ok(Promise.resolve(42).finally(() => { /* empty */ }) instanceof Promise, 'returns a promise'); -}); - -QUnit.test('Promise#finally, resolved', assert => { - assert.expect(3); - const async = assert.async(); - let called = 0; - let argument = null; - Promise.resolve(42).finally(it => { - called++; - argument = it; - }).then(it => { - assert.same(it, 42, 'resolved with a correct value'); - assert.same(called, 1, 'onFinally function called one time'); - assert.same(argument, undefined, 'onFinally function called with a correct argument'); - async(); - }); -}); - -QUnit.test('Promise#finally, rejected', assert => { - assert.expect(2); - const async = assert.async(); - let called = 0; - let argument = null; - Promise.reject(42).finally(it => { - called++; - argument = it; - }).catch(() => { - assert.same(called, 1, 'onFinally function called one time'); - assert.same(argument, undefined, 'onFinally function called with a correct argument'); - async(); - }); -}); diff --git a/tests/pure/es.promise.js b/tests/pure/es.promise.js deleted file mode 100644 index 6e9d0fcb4c79..000000000000 --- a/tests/pure/es.promise.js +++ /dev/null @@ -1,440 +0,0 @@ -import { DESCRIPTORS, GLOBAL, PROTO, STRICT } from '../helpers/constants'; -import { createIterable } from '../helpers/helpers'; - -import { Promise, Symbol } from 'core-js-pure'; -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; -import { setPrototypeOf, create } from 'core-js-pure/features/object'; -import bind from 'core-js-pure/features/function/bind'; - -QUnit.test('Promise', assert => { - assert.isFunction(Promise); - assert.throws(() => { - Promise(); - }, 'throws w/o `new`'); - new Promise(function (resolve, reject) { - assert.isFunction(resolve, 'resolver is function'); - assert.isFunction(reject, 'rejector is function'); - if (STRICT) assert.same(this, undefined, 'correct executor context'); - }); -}); - -if (DESCRIPTORS) QUnit.test('Promise operations order', assert => { - let resolve, resolve2; - assert.expect(1); - const EXPECTED_ORDER = 'DEHAFGBC'; - const async = assert.async(); - let result = ''; - const promise1 = new Promise(r => { - resolve = r; - }); - resolve({ - then() { - result += 'A'; - throw Error(); - }, - }); - promise1.catch(() => { - result += 'B'; - }); - promise1.catch(() => { - result += 'C'; - assert.same(result, EXPECTED_ORDER); - async(); - }); - const promise2 = new Promise(r => { - resolve2 = r; - }); - resolve2(Object.defineProperty({}, 'then', { - get() { - result += 'D'; - throw Error(); - }, - })); - result += 'E'; - promise2.catch(() => { - result += 'F'; - }); - promise2.catch(() => { - result += 'G'; - }); - result += 'H'; - setTimeout(() => { - if (!~result.indexOf('C')) { - assert.same(result, EXPECTED_ORDER); - async(); - } - }, 1e3); -}); - -QUnit.test('Promise#then', assert => { - assert.isFunction(Promise.prototype.then); - assert.nonEnumerable(Promise.prototype, 'then'); - let promise = new Promise(resolve => { - resolve(42); - }); - let FakePromise1 = promise.constructor = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - const FakePromise2 = FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(promise.then(() => { /* empty */ }) instanceof FakePromise2, 'subclassing, @@species pattern'); - promise = new Promise(resolve => { - resolve(42); - }); - promise.constructor = FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(promise.then(() => { /* empty */ }) instanceof Promise, 'subclassing, incorrect `this` pattern'); - promise = new Promise(resolve => { - resolve(42); - }); - promise.constructor = FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise1[Symbol.species] = function () { /* empty */ }; - assert.throws(() => { - promise.then(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #1'); - FakePromise1[Symbol.species] = function (executor) { - executor(null, () => { /* empty */ }); - }; - assert.throws(() => { - promise.then(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #2'); - FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, null); - }; - assert.throws(() => { - promise.then(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #3'); -}); - -QUnit.test('Promise#catch', assert => { - assert.isFunction(Promise.prototype.catch); - assert.nonEnumerable(Promise.prototype, 'catch'); - let promise = new Promise(resolve => { - resolve(42); - }); - let FakePromise1 = promise.constructor = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - const FakePromise2 = FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(promise.catch(() => { /* empty */ }) instanceof FakePromise2, 'subclassing, @@species pattern'); - promise = new Promise(resolve => { - resolve(42); - }); - promise.constructor = FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(promise.catch(() => { /* empty */ }) instanceof Promise, 'subclassing, incorrect `this` pattern'); - promise = new Promise(resolve => { - resolve(42); - }); - promise.constructor = FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise1[Symbol.species] = function () { /* empty */ }; - assert.throws(() => { - promise.catch(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #1'); - FakePromise1[Symbol.species] = function (executor) { - executor(null, () => { /* empty */ }); - }; - assert.throws(() => { - promise.catch(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #2'); - FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, null); - }; - assert.throws(() => { - promise.catch(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #3'); - assert.same(Promise.prototype.catch.call({ - then(x, y) { - return y; - }, - }, 42), 42, 'calling `.then`'); -}); - -QUnit.test('Promise#@@toStringTag', assert => { - assert.ok(Promise.prototype[Symbol.toStringTag] === 'Promise', 'Promise::@@toStringTag is `Promise`'); - assert.strictEqual(String(new Promise(() => { /* empty */ })), '[object Promise]', 'correct stringification'); -}); - -QUnit.test('Promise.all', assert => { - const { all, resolve } = Promise; - assert.isFunction(all); - assert.arity(all, 1); - const iterable = createIterable([1, 2, 3]); - Promise.all(iterable).catch(() => { /* empty */ }); - assert.ok(iterable.received, 'works with iterables: iterator received'); - assert.ok(iterable.called, 'works with iterables: next called'); - const array = []; - let done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return getIteratorMethod([]).call(this); - }; - Promise.all(array); - assert.ok(done); - assert.throws(() => { - all.call(null, []).catch(() => { /* empty */ }); - }, TypeError, 'throws without context'); - done = false; - try { - Promise.resolve = function () { - throw new Error(); - }; - Promise.all(createIterable([1, 2, 3], { - return() { - done = true; - }, - })).catch(() => { /* empty */ }); - } catch (error) { /* empty */ } - Promise.resolve = resolve; - assert.ok(done, 'iteration closing'); - let FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - let FakePromise2 = FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise1.resolve = FakePromise2.resolve = bind(Promise.resolve, Promise); - assert.ok(all.call(FakePromise1, [1, 2, 3]) instanceof FakePromise1, 'subclassing, `this` pattern'); - FakePromise1 = function () { /* empty */ }; - FakePromise2 = function (executor) { - executor(null, () => { /* empty */ }); - }; - const FakePromise3 = function (executor) { - executor(() => { /* empty */ }, null); - }; - FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = bind(Promise.resolve, Promise); - assert.throws(() => { - all.call(FakePromise1, [1, 2, 3]); - }, 'NewPromiseCapability validations, #1'); - assert.throws(() => { - all.call(FakePromise2, [1, 2, 3]); - }, 'NewPromiseCapability validations, #2'); - assert.throws(() => { - all.call(FakePromise3, [1, 2, 3]); - }, 'NewPromiseCapability validations, #3'); -}); - -QUnit.test('Promise.race', assert => { - const { race, resolve } = Promise; - assert.isFunction(race); - assert.arity(race, 1); - const iterable = createIterable([1, 2, 3]); - Promise.race(iterable).catch(() => { /* empty */ }); - assert.ok(iterable.received, 'works with iterables: iterator received'); - assert.ok(iterable.called, 'works with iterables: next called'); - const array = []; - let done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return getIteratorMethod([]).call(this); - }; - Promise.race(array); - assert.ok(done); - assert.throws(() => { - race.call(null, []).catch(() => { /* empty */ }); - }, TypeError, 'throws without context'); - done = false; - try { - Promise.resolve = function () { - throw new Error(); - }; - Promise.race(createIterable([1, 2, 3], { - return() { - done = true; - }, - })).catch(() => { /* empty */ }); - } catch (error) { /* empty */ } - Promise.resolve = resolve; - assert.ok(done, 'iteration closing'); - let FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - let FakePromise2 = FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise1.resolve = FakePromise2.resolve = bind(Promise.resolve, Promise); - assert.ok(race.call(FakePromise1, [1, 2, 3]) instanceof FakePromise1, 'subclassing, `this` pattern'); - FakePromise1 = function () { /* empty */ }; - FakePromise2 = function (executor) { - executor(null, () => { /* empty */ }); - }; - const FakePromise3 = function (executor) { - executor(() => { /* empty */ }, null); - }; - FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = bind(Promise.resolve, Promise); - assert.throws(() => { - race.call(FakePromise1, [1, 2, 3]); - }, 'NewPromiseCapability validations, #1'); - assert.throws(() => { - race.call(FakePromise2, [1, 2, 3]); - }, 'NewPromiseCapability validations, #2'); - assert.throws(() => { - race.call(FakePromise3, [1, 2, 3]); - }, 'NewPromiseCapability validations, #3'); -}); - -QUnit.test('Promise.resolve', assert => { - const { resolve } = Promise; - assert.isFunction(resolve); - assert.throws(() => { - resolve.call(null, 1).catch(() => { /* empty */ }); - }, TypeError, 'throws without context'); - function FakePromise1(executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - } - FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(resolve.call(FakePromise1, 42) instanceof FakePromise1, 'subclassing, `this` pattern'); - assert.throws(() => { - resolve.call(() => { /* empty */ }, 42); - }, 'NewPromiseCapability validations, #1'); - assert.throws(() => { - resolve.call(executor => { - executor(null, () => { /* empty */ }); - }, 42); - }, 'NewPromiseCapability validations, #2'); - assert.throws(() => { - resolve.call(executor => { - executor(() => { /* empty */ }, null); - }, 42); - }, 'NewPromiseCapability validations, #3'); -}); - -QUnit.test('Promise.reject', assert => { - const { reject } = Promise; - assert.isFunction(reject); - assert.throws(() => { - reject.call(null, 1).catch(() => { /* empty */ }); - }, TypeError, 'throws without context'); - function FakePromise1(executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - } - FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(reject.call(FakePromise1, 42) instanceof FakePromise1, 'subclassing, `this` pattern'); - assert.throws(() => { - reject.call(() => { /* empty */ }, 42); - }, 'NewPromiseCapability validations, #1'); - assert.throws(() => { - reject.call(executor => { - executor(null, () => { /* empty */ }); - }, 42); - }, 'NewPromiseCapability validations, #2'); - assert.throws(() => { - reject.call(executor => { - executor(() => { /* empty */ }, null); - }, 42); - }, 'NewPromiseCapability validations, #3'); -}); - -if (PROTO) QUnit.test('Promise subclassing', assert => { - function SubPromise(executor) { - const self = new Promise(executor); - setPrototypeOf(self, SubPromise.prototype); - self.mine = 'subclass'; - return self; - } - setPrototypeOf(SubPromise, Promise); - SubPromise.prototype = create(Promise.prototype); - SubPromise.prototype.constructor = SubPromise; - let promise1 = SubPromise.resolve(5); - assert.strictEqual(promise1.mine, 'subclass'); - promise1 = promise1.then(it => { - assert.strictEqual(it, 5); - }); - assert.strictEqual(promise1.mine, 'subclass'); - let promise2 = new SubPromise(resolve => { - resolve(6); - }); - assert.strictEqual(promise2.mine, 'subclass'); - promise2 = promise2.then(it => { - assert.strictEqual(it, 6); - }); - assert.strictEqual(promise2.mine, 'subclass'); - const promise3 = SubPromise.all([promise1, promise2]); - assert.strictEqual(promise3.mine, 'subclass'); - assert.ok(promise3 instanceof Promise); - assert.ok(promise3 instanceof SubPromise); - promise3.then(assert.async(), it => { - assert.ok(it, false); - }); -}); - -// qunit@2.5 strange bug -QUnit.skip('Unhandled rejection tracking', assert => { - let done = false; - const resume = assert.async(); - if (GLOBAL.process) { - assert.expect(3); - function onunhandledrejection(reason, promise) { - process.removeListener('unhandledRejection', onunhandledrejection); - assert.same(promise, $promise, 'unhandledRejection, promise'); - assert.same(reason, 42, 'unhandledRejection, reason'); - $promise.catch(() => { - // empty - }); - } - function onrejectionhandled(promise) { - process.removeListener('rejectionHandled', onrejectionhandled); - assert.same(promise, $promise, 'rejectionHandled, promise'); - done || resume(); - done = true; - } - process.on('unhandledRejection', onunhandledrejection); - process.on('rejectionHandled', onrejectionhandled); - } else { - if (GLOBAL.addEventListener) { - assert.expect(8); - function onunhandledrejection(it) { - assert.same(it.promise, $promise, 'addEventListener(unhandledrejection), promise'); - assert.same(it.reason, 42, 'addEventListener(unhandledrejection), reason'); - GLOBAL.removeEventListener('unhandledrejection', onunhandledrejection); - } - GLOBAL.addEventListener('rejectionhandled', onunhandledrejection); - function onrejectionhandled(it) { - assert.same(it.promise, $promise, 'addEventListener(rejectionhandled), promise'); - assert.same(it.reason, 42, 'addEventListener(rejectionhandled), reason'); - GLOBAL.removeEventListener('rejectionhandled', onrejectionhandled); - } - GLOBAL.addEventListener('rejectionhandled', onrejectionhandled); - } else assert.expect(4); - GLOBAL.onunhandledrejection = function (it) { - assert.same(it.promise, $promise, 'onunhandledrejection, promise'); - assert.same(it.reason, 42, 'onunhandledrejection, reason'); - setTimeout(() => { - $promise.catch(() => { - // empty - }); - }, 1); - GLOBAL.onunhandledrejection = null; - }; - GLOBAL.onrejectionhandled = function (it) { - assert.same(it.promise, $promise, 'onrejectionhandled, promise'); - assert.same(it.reason, 42, 'onrejectionhandled, reason'); - GLOBAL.onrejectionhandled = null; - done || resume(); - done = true; - }; - } - Promise.reject(43).catch(() => { - // empty - }); - const $promise = Promise.reject(42); - setTimeout(() => { - done || resume(); - done = true; - }, 3e3); -}); diff --git a/tests/pure/es.reflect.apply.js b/tests/pure/es.reflect.apply.js deleted file mode 100644 index f96e599ab3b8..000000000000 --- a/tests/pure/es.reflect.apply.js +++ /dev/null @@ -1,18 +0,0 @@ -import apply from 'core-js-pure/features/reflect/apply'; - -QUnit.test('Reflect.apply', assert => { - assert.isFunction(apply); - assert.arity(apply, 3); - if ('name' in apply) { - assert.name(apply, 'apply'); - } - assert.strictEqual(apply(Array.prototype.push, [1, 2], [3, 4, 5]), 5); - function F(a, b, c) { - return a + b + c; - } - F.apply = 42; - assert.strictEqual(apply(F, null, ['foo', 'bar', 'baz']), 'foobarbaz', 'works with redefined apply'); - assert.throws(() => apply(42, null, []), TypeError, 'throws on primitive'); - assert.throws(() => apply(() => { /* empty */ }, null), TypeError, 'throws without third argument'); - assert.throws(() => apply(() => { /* empty */ }, null, '123'), TypeError, 'throws on primitive as third argument'); -}); diff --git a/tests/pure/es.reflect.construct.js b/tests/pure/es.reflect.construct.js deleted file mode 100644 index abcf47c06e04..000000000000 --- a/tests/pure/es.reflect.construct.js +++ /dev/null @@ -1,27 +0,0 @@ -import construct from 'core-js-pure/features/reflect/construct'; -import getPrototypeOf from 'core-js-pure/features/object/get-prototype-of'; - -QUnit.test('Reflect.construct', assert => { - assert.isFunction(construct); - assert.arity(construct, 2); - if ('name' in construct) { - assert.name(construct, 'construct'); - } - function A(a, b, c) { - this.qux = a + b + c; - } - assert.strictEqual(construct(A, ['foo', 'bar', 'baz']).qux, 'foobarbaz', 'basic'); - A.apply = 42; - assert.strictEqual(construct(A, ['foo', 'bar', 'baz']).qux, 'foobarbaz', 'works with redefined apply'); - const instance = construct(function () { - this.x = 42; - }, [], Array); - assert.strictEqual(instance.x, 42, 'constructor with newTarget'); - assert.ok(instance instanceof Array, 'prototype with newTarget'); - assert.throws(() => construct(42, []), TypeError, 'throws on primitive'); - function B() { /* empty */ } - B.prototype = 42; - assert.notThrows(() => getPrototypeOf(construct(B, [])) === Object.prototype); - assert.notThrows(() => typeof construct(Date, []).getTime() === 'number', 'works with native constructors with 2 arguments'); - assert.throws(() => construct(() => { /* empty */ }), 'throws when the second argument is not an object'); -}); diff --git a/tests/pure/es.reflect.define-property.js b/tests/pure/es.reflect.define-property.js deleted file mode 100644 index 3d3618b65cd4..000000000000 --- a/tests/pure/es.reflect.define-property.js +++ /dev/null @@ -1,41 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import defineProperty from 'core-js-pure/features/reflect/define-property'; -import { getOwnPropertyDescriptor, create } from 'core-js-pure/features/object'; - -QUnit.test('Reflect.defineProperty', assert => { - assert.isFunction(defineProperty); - assert.arity(defineProperty, 3); - if ('name' in defineProperty) { - assert.name(defineProperty, 'defineProperty'); - } - let object = {}; - assert.strictEqual(defineProperty(object, 'foo', { value: 123 }), true); - assert.strictEqual(object.foo, 123); - if (DESCRIPTORS) { - object = {}; - defineProperty(object, 'foo', { - value: 123, - enumerable: true, - }); - assert.deepEqual(getOwnPropertyDescriptor(object, 'foo'), { - value: 123, - enumerable: true, - configurable: false, - writable: false, - }); - assert.strictEqual(defineProperty(object, 'foo', { - value: 42, - }), false); - } - assert.throws(() => defineProperty(42, 'foo', { - value: 42, - }), TypeError, 'throws on primitive'); - assert.throws(() => defineProperty(42, 1, {})); - assert.throws(() => defineProperty({}, create(null), {})); - assert.throws(() => defineProperty({}, 1, 1)); -}); - -QUnit.test('Reflect.defineProperty.sham flag', assert => { - assert.same(defineProperty.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/pure/es.reflect.delete-property.js b/tests/pure/es.reflect.delete-property.js deleted file mode 100644 index 70b90576bd82..000000000000 --- a/tests/pure/es.reflect.delete-property.js +++ /dev/null @@ -1,21 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import deleteProperty from 'core-js-pure/features/reflect/delete-property'; -import { defineProperty, keys } from 'core-js-pure/features/object'; - -QUnit.test('Reflect.deleteProperty', assert => { - assert.isFunction(deleteProperty); - assert.arity(deleteProperty, 2); - if ('name' in deleteProperty) { - assert.name(deleteProperty, 'deleteProperty'); - } - const object = { bar: 456 }; - assert.strictEqual(deleteProperty(object, 'bar'), true); - assert.ok(keys(object).length === 0); - if (DESCRIPTORS) { - assert.strictEqual(deleteProperty(defineProperty({}, 'foo', { - value: 42, - }), 'foo'), false); - } - assert.throws(() => deleteProperty(42, 'foo'), TypeError, 'throws on primitive'); -}); diff --git a/tests/pure/es.reflect.get-own-property-descriptor.js b/tests/pure/es.reflect.get-own-property-descriptor.js deleted file mode 100644 index c5a96866e740..000000000000 --- a/tests/pure/es.reflect.get-own-property-descriptor.js +++ /dev/null @@ -1,19 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import getOwnPropertyDescriptor from 'core-js-pure/features/reflect/get-own-property-descriptor'; - -QUnit.test('Reflect.getOwnPropertyDescriptor', assert => { - assert.isFunction(getOwnPropertyDescriptor); - assert.arity(getOwnPropertyDescriptor, 2); - if ('name' in getOwnPropertyDescriptor) { - assert.name(getOwnPropertyDescriptor, 'getOwnPropertyDescriptor'); - } - const object = { baz: 789 }; - const descriptor = getOwnPropertyDescriptor(object, 'baz'); - assert.strictEqual(descriptor.value, 789); - assert.throws(() => getOwnPropertyDescriptor(42, 'constructor'), TypeError, 'throws on primitive'); -}); - -QUnit.test('Reflect.getOwnPropertyDescriptor.sham flag', assert => { - assert.same(getOwnPropertyDescriptor.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/pure/es.reflect.get-prototype-of.js b/tests/pure/es.reflect.get-prototype-of.js deleted file mode 100644 index d1c4337b2e36..000000000000 --- a/tests/pure/es.reflect.get-prototype-of.js +++ /dev/null @@ -1,17 +0,0 @@ -import { CORRECT_PROTOTYPE_GETTER } from '../helpers/constants'; - -import getPrototypeOf from 'core-js-pure/features/reflect/get-prototype-of'; - -QUnit.test('Reflect.getPrototypeOf', assert => { - assert.isFunction(getPrototypeOf); - assert.arity(getPrototypeOf, 1); - if ('name' in getPrototypeOf) { - assert.name(getPrototypeOf, 'getPrototypeOf'); - } - assert.strictEqual(getPrototypeOf([]), Array.prototype); - assert.throws(() => getPrototypeOf(42), TypeError, 'throws on primitive'); -}); - -QUnit.test('Reflect.getPrototypeOf.sham flag', assert => { - assert.same(getPrototypeOf.sham, CORRECT_PROTOTYPE_GETTER ? undefined : true); -}); diff --git a/tests/pure/es.reflect.get.js b/tests/pure/es.reflect.get.js deleted file mode 100644 index 1dfc8d77d2a3..000000000000 --- a/tests/pure/es.reflect.get.js +++ /dev/null @@ -1,35 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import get from 'core-js-pure/features/reflect/get'; -import { defineProperty, create } from 'core-js-pure/features/object'; - -QUnit.test('Reflect.get', assert => { - assert.isFunction(get); - if ('name' in get) { - assert.name(get, 'get'); - } - assert.strictEqual(get({ qux: 987 }, 'qux'), 987); - if (DESCRIPTORS) { - const target = create(defineProperty({ z: 3 }, 'w', { - get() { - return this; - }, - }), { - x: { - value: 1, - }, - y: { - get() { - return this; - }, - }, - }); - const receiver = {}; - assert.strictEqual(get(target, 'x', receiver), 1, 'get x'); - assert.strictEqual(get(target, 'y', receiver), receiver, 'get y'); - assert.strictEqual(get(target, 'z', receiver), 3, 'get z'); - assert.strictEqual(get(target, 'w', receiver), receiver, 'get w'); - assert.strictEqual(get(target, 'u', receiver), undefined, 'get u'); - } - assert.throws(() => get(42, 'constructor'), TypeError, 'throws on primitive'); -}); diff --git a/tests/pure/es.reflect.has.js b/tests/pure/es.reflect.has.js deleted file mode 100644 index ed41b19bab17..000000000000 --- a/tests/pure/es.reflect.has.js +++ /dev/null @@ -1,14 +0,0 @@ -import has from 'core-js-pure/features/reflect/has'; - -QUnit.test('Reflect.has', assert => { - assert.isFunction(has); - assert.arity(has, 2); - if ('name' in has) { - assert.name(has, 'has'); - } - const object = { qux: 987 }; - assert.strictEqual(has(object, 'qux'), true); - assert.strictEqual(has(object, 'qwe'), false); - assert.strictEqual(has(object, 'toString'), true); - assert.throws(() => has(42, 'constructor'), TypeError, 'throws on primitive'); -}); diff --git a/tests/pure/es.reflect.is-extensible.js b/tests/pure/es.reflect.is-extensible.js deleted file mode 100644 index 77c58484e33d..000000000000 --- a/tests/pure/es.reflect.is-extensible.js +++ /dev/null @@ -1,17 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import isExtensible from 'core-js-pure/features/reflect/is-extensible'; -import preventExtensions from 'core-js-pure/features/object/prevent-extensions'; - -QUnit.test('Reflect.isExtensible', assert => { - assert.isFunction(isExtensible); - assert.arity(isExtensible, 1); - if ('name' in isExtensible) { - assert.name(isExtensible, 'isExtensible'); - } - assert.ok(isExtensible({})); - if (DESCRIPTORS) { - assert.ok(!isExtensible(preventExtensions({}))); - } - assert.throws(() => isExtensible(42), TypeError, 'throws on primitive'); -}); diff --git a/tests/pure/es.reflect.own-keys.js b/tests/pure/es.reflect.own-keys.js deleted file mode 100644 index 633e1ce8e40f..000000000000 --- a/tests/pure/es.reflect.own-keys.js +++ /dev/null @@ -1,26 +0,0 @@ -import { includes } from '../helpers/helpers'; - -import Symbol from 'core-js-pure/features/symbol'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; -import { defineProperty, create } from 'core-js-pure/features/object'; - -QUnit.test('Reflect.ownKeys', assert => { - assert.isFunction(ownKeys); - assert.arity(ownKeys, 1); - if ('name' in ownKeys) { - assert.name(ownKeys, 'ownKeys'); - } - const object = { a: 1 }; - defineProperty(object, 'b', { - value: 2, - }); - object[Symbol('c')] = 3; - let keys = ownKeys(object); - assert.strictEqual(keys.length, 3, 'ownKeys return all own keys'); - assert.ok(includes(keys, 'a'), 'ownKeys return all own keys: simple'); - assert.ok(includes(keys, 'b'), 'ownKeys return all own keys: hidden'); - assert.strictEqual(object[keys[2]], 3, 'ownKeys return all own keys: symbol'); - keys = ownKeys(create(object)); - assert.strictEqual(keys.length, 0, 'ownKeys return only own keys'); - assert.throws(() => ownKeys(42), TypeError, 'throws on primitive'); -}); diff --git a/tests/pure/es.reflect.prevent-extensions.js b/tests/pure/es.reflect.prevent-extensions.js deleted file mode 100644 index 3689e5859c0a..000000000000 --- a/tests/pure/es.reflect.prevent-extensions.js +++ /dev/null @@ -1,22 +0,0 @@ -import { DESCRIPTORS, FREEZING } from '../helpers/constants'; - -import preventExtensions from 'core-js-pure/features/reflect/prevent-extensions'; -import isExtensible from 'core-js-pure/features/object/is-extensible'; - -QUnit.test('Reflect.preventExtensions', assert => { - assert.isFunction(preventExtensions); - assert.arity(preventExtensions, 1); - if ('name' in preventExtensions) { - assert.name(preventExtensions, 'preventExtensions'); - } - const object = {}; - assert.ok(preventExtensions(object), true); - if (DESCRIPTORS) { - assert.ok(!isExtensible(object)); - } - assert.throws(() => preventExtensions(42), TypeError, 'throws on primitive'); -}); - -QUnit.test('Reflect.preventExtensions.sham flag', assert => { - assert.same(preventExtensions.sham, FREEZING ? undefined : true); -}); diff --git a/tests/pure/es.reflect.set-prototype-of.js b/tests/pure/es.reflect.set-prototype-of.js deleted file mode 100644 index a44dd50f920c..000000000000 --- a/tests/pure/es.reflect.set-prototype-of.js +++ /dev/null @@ -1,17 +0,0 @@ -import { PROTO } from '../helpers/constants'; - -import setPrototypeOf from 'core-js-pure/features/reflect/set-prototype-of'; - -if (PROTO) QUnit.test('Reflect.setPrototypeOf', assert => { - assert.isFunction(setPrototypeOf); - if ('name' in setPrototypeOf) { - assert.name(setPrototypeOf, 'setPrototypeOf'); - } - let object = {}; - assert.ok(setPrototypeOf(object, Array.prototype), true); - assert.ok(object instanceof Array); - assert.throws(() => setPrototypeOf({}, 42), TypeError); - assert.throws(() => setPrototypeOf(42, {}), TypeError, 'throws on primitive'); - object = {}; - assert.ok(setPrototypeOf(object, object) === false, 'false on recursive __proto__'); -}); diff --git a/tests/pure/es.reflect.set.js b/tests/pure/es.reflect.set.js deleted file mode 100644 index 1b8b92115ea3..000000000000 --- a/tests/pure/es.reflect.set.js +++ /dev/null @@ -1,85 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import set from 'core-js-pure/features/reflect/set'; -import { defineProperty, getOwnPropertyDescriptor, create, getPrototypeOf } from 'core-js-pure/features/object'; - -QUnit.test('Reflect.set', assert => { - assert.isFunction(set); - if ('name' in set) { - assert.name(set, 'set'); - } - const object = {}; - assert.ok(set(object, 'quux', 654), true); - assert.strictEqual(object.quux, 654); - let target = {}; - const receiver = {}; - set(target, 'foo', 1, receiver); - assert.strictEqual(target.foo, undefined, 'target.foo === undefined'); - assert.strictEqual(receiver.foo, 1, 'receiver.foo === 1'); - if (DESCRIPTORS) { - defineProperty(receiver, 'bar', { - value: 0, - writable: true, - enumerable: false, - configurable: true, - }); - set(target, 'bar', 1, receiver); - assert.strictEqual(receiver.bar, 1, 'receiver.bar === 1'); - assert.strictEqual(getOwnPropertyDescriptor(receiver, 'bar').enumerable, false, 'enumerability not overridden'); - let out = null; - target = create(defineProperty({ z: 3 }, 'w', { - set() { - out = this; - }, - }), { - x: { - value: 1, - writable: true, - configurable: true, - }, - y: { - set() { - out = this; - }, - }, - c: { - value: 1, - writable: false, - configurable: false, - }, - }); - assert.strictEqual(set(target, 'x', 2, target), true, 'set x'); - assert.strictEqual(target.x, 2, 'set x'); - out = null; - assert.strictEqual(set(target, 'y', 2, target), true, 'set y'); - assert.strictEqual(out, target, 'set y'); - assert.strictEqual(set(target, 'z', 4, target), true); - assert.strictEqual(target.z, 4, 'set z'); - out = null; - assert.strictEqual(set(target, 'w', 1, target), true, 'set w'); - assert.strictEqual(out, target, 'set w'); - assert.strictEqual(set(target, 'u', 0, target), true, 'set u'); - assert.strictEqual(target.u, 0, 'set u'); - assert.strictEqual(set(target, 'c', 2, target), false, 'set c'); - assert.strictEqual(target.c, 1, 'set c'); - - // https://github.com/zloirock/core-js/issues/392 - let o = defineProperty({}, 'test', { - writable: false, - configurable: true, - }); - assert.strictEqual(set(getPrototypeOf(o), 'test', 1, o), false); - - // https://github.com/zloirock/core-js/issues/393 - o = defineProperty({}, 'test', { - get() { /* empty */ }, - }); - assert.notThrows(() => !set(getPrototypeOf(o), 'test', 1, o)); - o = defineProperty({}, 'test', { - // eslint-disable-next-line no-unused-vars - set(v) { /* empty */ }, - }); - assert.notThrows(() => !set(getPrototypeOf(o), 'test', 1, o)); - } - assert.throws(() => set(42, 'q', 42), TypeError, 'throws on primitive'); -}); diff --git a/tests/pure/es.set.js b/tests/pure/es.set.js deleted file mode 100644 index 996af9214ea5..000000000000 --- a/tests/pure/es.set.js +++ /dev/null @@ -1,401 +0,0 @@ -/* eslint-disable sonarjs/no-element-overwrite */ - -import { createIterable, is, nativeSubclass } from '../helpers/helpers'; -import { DESCRIPTORS } from '../helpers/constants'; - -import { Set, Map, Symbol } from 'core-js-pure'; -import getIterator from 'core-js-pure/features/get-iterator'; -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; -import { freeze, getOwnPropertyDescriptor, keys, getOwnPropertyNames, getOwnPropertySymbols } from 'core-js-pure/features/object'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set', assert => { - assert.isFunction(Set); - assert.ok('add' in Set.prototype, 'add in Set.prototype'); - assert.ok('clear' in Set.prototype, 'clear in Set.prototype'); - assert.ok('delete' in Set.prototype, 'delete in Set.prototype'); - assert.ok('forEach' in Set.prototype, 'forEach in Set.prototype'); - assert.ok('has' in Set.prototype, 'has in Set.prototype'); - assert.ok(new Set() instanceof Set, 'new Set instanceof Set'); - const set = new Set(); - set.add(1); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - assert.strictEqual(set.size, 3); - const result = []; - set.forEach(val => { - result.push(val); - }); - assert.deepEqual(result, [1, 2, 3]); - assert.strictEqual(new Set(createIterable([1, 2, 3])).size, 3, 'Init from iterable'); - assert.strictEqual(new Set([freeze({}), 1]).size, 2, 'Support frozen objects'); - assert.strictEqual(new Set([NaN, NaN, NaN]).size, 1); - assert.deepEqual(from(new Set([3, 4]).add(2).add(1)), [3, 4, 2, 1]); - let done = false; - const { add } = Set.prototype; - Set.prototype.add = function () { - throw new Error(); - }; - try { - new Set(createIterable([null, 1, 2], { - return() { - return done = true; - }, - })); - } catch { /* empty */ } - Set.prototype.add = add; - assert.ok(done, '.return #throw'); - const array = []; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return getIteratorMethod([]).call(this); - }; - new Set(array); - assert.ok(done); - const object = {}; - new Set().add(object); - if (DESCRIPTORS) { - const results = []; - for (const key in results) keys.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(object), []); - } - assert.arrayEqual(getOwnPropertyNames(object), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); - if (ownKeys) assert.arrayEqual(ownKeys(object), []); - if (nativeSubclass) { - const Subclass = nativeSubclass(Set); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof Set, 'correct subclassing with native classes #2'); - assert.ok(new Subclass().add(2).has(2), 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('Set#add', assert => { - assert.isFunction(Set.prototype.add); - const array = []; - let set = new Set(); - set.add(NaN); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.add(array); - assert.strictEqual(set.size, 5); - const chain = set.add(NaN); - assert.strictEqual(chain, set); - assert.strictEqual(set.size, 5); - set.add(2); - assert.strictEqual(set.size, 5); - set.add(array); - assert.strictEqual(set.size, 5); - set.add([]); - assert.strictEqual(set.size, 6); - set.add(4); - assert.strictEqual(set.size, 7); - const frozen = freeze({}); - set = new Set(); - set.add(frozen); - assert.ok(set.has(frozen)); -}); - -QUnit.test('Set#clear', assert => { - assert.isFunction(Set.prototype.clear); - let set = new Set(); - set.clear(); - assert.strictEqual(set.size, 0); - set = new Set(); - set.add(1); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.clear(); - assert.strictEqual(set.size, 0); - assert.ok(!set.has(1)); - assert.ok(!set.has(2)); - assert.ok(!set.has(3)); - const frozen = freeze({}); - set = new Set(); - set.add(1); - set.add(frozen); - set.clear(); - assert.strictEqual(set.size, 0, 'Support frozen objects'); - assert.ok(!set.has(1)); - assert.ok(!set.has(frozen)); -}); - -QUnit.test('Set#delete', assert => { - assert.isFunction(Set.prototype.delete); - const array = []; - const set = new Set(); - set.add(NaN); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.add(array); - assert.strictEqual(set.size, 5); - assert.strictEqual(set.delete(NaN), true); - assert.strictEqual(set.size, 4); - assert.strictEqual(set.delete(4), false); - assert.strictEqual(set.size, 4); - set.delete([]); - assert.strictEqual(set.size, 4); - set.delete(array); - assert.strictEqual(set.size, 3); - const frozen = freeze({}); - set.add(frozen); - assert.strictEqual(set.size, 4); - set.delete(frozen); - assert.strictEqual(set.size, 3); -}); - -QUnit.test('Set#forEach', assert => { - assert.isFunction(Set.prototype.forEach); - let result = []; - let count = 0; - let set = new Set(); - set.add(1); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.forEach(value => { - count++; - result.push(value); - }); - assert.strictEqual(count, 3); - assert.deepEqual(result, [1, 2, 3]); - set = new Set(); - set.add('0'); - set.add('1'); - set.add('2'); - set.add('3'); - result = ''; - set.forEach(it => { - result += it; - if (it === '2') { - set.delete('2'); - set.delete('3'); - set.delete('1'); - set.add('4'); - } - }); - assert.strictEqual(result, '0124'); - set = new Set(); - set.add('0'); - result = ''; - set.forEach(it => { - set.delete('0'); - if (result !== '') throw new Error(); - result += it; - }); - assert.strictEqual(result, '0'); - assert.throws(() => { - Set.prototype.forEach.call(new Map(), () => { /* empty */ }); - }, 'non-generic'); -}); - -QUnit.test('Set#has', assert => { - assert.isFunction(Set.prototype.has); - const array = []; - const frozen = freeze({}); - const set = new Set(); - set.add(NaN); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.add(frozen); - set.add(array); - assert.ok(set.has(NaN)); - assert.ok(set.has(array)); - assert.ok(set.has(frozen)); - assert.ok(set.has(2)); - assert.ok(!set.has(4)); - assert.ok(!set.has([])); -}); - -QUnit.test('Set#size', assert => { - const set = new Set(); - set.add(1); - const { size } = set; - assert.strictEqual(typeof size, 'number', 'size is number'); - assert.strictEqual(size, 1, 'size is correct'); - if (DESCRIPTORS) { - const sizeDescriptor = getOwnPropertyDescriptor(Set.prototype, 'size'); - assert.ok(sizeDescriptor && sizeDescriptor.get, 'size is getter'); - assert.ok(sizeDescriptor && !sizeDescriptor.set, 'size isnt setter'); - assert.throws(() => { - Set.prototype.size; - }, TypeError); - } -}); - -QUnit.test('Set & -0', assert => { - let set = new Set(); - set.add(-0); - assert.strictEqual(set.size, 1); - assert.ok(set.has(0)); - assert.ok(set.has(-0)); - set.forEach(it => { - assert.ok(!is(it, -0)); - }); - set.delete(-0); - assert.strictEqual(set.size, 0); - set = new Set([-0]); - set.forEach(key => { - assert.ok(!is(key, -0)); - }); - set = new Set(); - set.add(4); - set.add(3); - set.add(2); - set.add(1); - set.add(0); - assert.ok(set.has(-0)); -}); - -QUnit.test('Set#@@toStringTag', assert => { - assert.strictEqual(Set.prototype[Symbol.toStringTag], 'Set', 'Set::@@toStringTag is `Set`'); - assert.strictEqual(String(new Set()), '[object Set]', 'correct stringification'); -}); - -QUnit.test('Set Iterator', assert => { - const set = new Set(); - set.add('a'); - set.add('b'); - set.add('c'); - set.add('d'); - const results = []; - const iterator = set.keys(); - results.push(iterator.next().value); - assert.ok(set.delete('a')); - assert.ok(set.delete('b')); - assert.ok(set.delete('c')); - set.add('e'); - results.push(iterator.next().value); - results.push(iterator.next().value); - assert.ok(iterator.next().done); - set.add('f'); - assert.ok(iterator.next().done); - assert.deepEqual(results, ['a', 'd', 'e']); -}); - -QUnit.test('Set#keys', assert => { - assert.isFunction(Set.prototype.keys); - const set = new Set(); - set.add('q'); - set.add('w'); - set.add('e'); - const iterator = set.keys(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Set Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Set#values', assert => { - assert.isFunction(Set.prototype.values); - const set = new Set(); - set.add('q'); - set.add('w'); - set.add('e'); - const iterator = set.values(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Set Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Set#entries', assert => { - assert.isFunction(Set.prototype.entries); - const set = new Set(); - set.add('q'); - set.add('w'); - set.add('e'); - const iterator = set.entries(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Set Iterator'); - assert.deepEqual(iterator.next(), { - value: ['q', 'q'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['w', 'w'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['e', 'e'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Set#@@iterator', assert => { - const set = new Set(); - set.add('q'); - set.add('w'); - set.add('e'); - const iterator = getIterator(set); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Set Iterator'); - assert.strictEqual(String(iterator), '[object Set Iterator]'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/pure/es.string.anchor.js b/tests/pure/es.string.anchor.js deleted file mode 100644 index f3231f9b65e5..000000000000 --- a/tests/pure/es.string.anchor.js +++ /dev/null @@ -1,7 +0,0 @@ -import anchor from 'core-js-pure/features/string/anchor'; - -QUnit.test('String#anchor', assert => { - assert.isFunction(anchor); - assert.same(anchor('a', 'b'), '
a', 'lower case'); - assert.same(anchor('a', '"'), 'a', 'escape quotes'); -}); diff --git a/tests/pure/es.string.big.js b/tests/pure/es.string.big.js deleted file mode 100644 index e13a1664e571..000000000000 --- a/tests/pure/es.string.big.js +++ /dev/null @@ -1,6 +0,0 @@ -import big from 'core-js-pure/features/string/big'; - -QUnit.test('String#big', assert => { - assert.isFunction(big); - assert.same(big('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.blink.js b/tests/pure/es.string.blink.js deleted file mode 100644 index 18cfe1550bdd..000000000000 --- a/tests/pure/es.string.blink.js +++ /dev/null @@ -1,6 +0,0 @@ -import blink from 'core-js-pure/features/string/blink'; - -QUnit.test('String#blink', assert => { - assert.isFunction(blink); - assert.same(blink('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.bold.js b/tests/pure/es.string.bold.js deleted file mode 100644 index 37836d79c58a..000000000000 --- a/tests/pure/es.string.bold.js +++ /dev/null @@ -1,6 +0,0 @@ -import bold from 'core-js-pure/features/string/bold'; - -QUnit.test('String#bold', assert => { - assert.isFunction(bold); - assert.same(bold('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.code-point-at.js b/tests/pure/es.string.code-point-at.js deleted file mode 100644 index 48770a8b815f..000000000000 --- a/tests/pure/es.string.code-point-at.js +++ /dev/null @@ -1,60 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import codePointAt from 'core-js-pure/features/string/code-point-at'; - -QUnit.test('String#codePointAt', assert => { - assert.isFunction(codePointAt); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', ''), 0x61); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', '_'), 0x61); - assert.strictEqual(codePointAt('abc\uD834\uDF06def'), 0x61); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', -Infinity), undefined); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', -1), undefined); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', -0), 0x61); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', 0), 0x61); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', 3), 0x1D306); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', 4), 0xDF06); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', 5), 0x64); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', 42), undefined); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', Infinity), undefined); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', Infinity), undefined); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', NaN), 0x61); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', false), 0x61); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', null), 0x61); - assert.strictEqual(codePointAt('abc\uD834\uDF06def', undefined), 0x61); - assert.strictEqual(codePointAt('\uD834\uDF06def', ''), 0x1D306); - assert.strictEqual(codePointAt('\uD834\uDF06def', '1'), 0xDF06); - assert.strictEqual(codePointAt('\uD834\uDF06def', '_'), 0x1D306); - assert.strictEqual(codePointAt('\uD834\uDF06def'), 0x1D306); - assert.strictEqual(codePointAt('\uD834\uDF06def', -1), undefined); - assert.strictEqual(codePointAt('\uD834\uDF06def', -0), 0x1D306); - assert.strictEqual(codePointAt('\uD834\uDF06def', 0), 0x1D306); - assert.strictEqual(codePointAt('\uD834\uDF06def', 1), 0xDF06); - assert.strictEqual(codePointAt('\uD834\uDF06def', 42), undefined); - assert.strictEqual(codePointAt('\uD834\uDF06def', false), 0x1D306); - assert.strictEqual(codePointAt('\uD834\uDF06def', null), 0x1D306); - assert.strictEqual(codePointAt('\uD834\uDF06def', undefined), 0x1D306); - assert.strictEqual(codePointAt('\uD834abc', ''), 0xD834); - assert.strictEqual(codePointAt('\uD834abc', '_'), 0xD834); - assert.strictEqual(codePointAt('\uD834abc'), 0xD834); - assert.strictEqual(codePointAt('\uD834abc', -1), undefined); - assert.strictEqual(codePointAt('\uD834abc', -0), 0xD834); - assert.strictEqual(codePointAt('\uD834abc', 0), 0xD834); - assert.strictEqual(codePointAt('\uD834abc', false), 0xD834); - assert.strictEqual(codePointAt('\uD834abc', NaN), 0xD834); - assert.strictEqual(codePointAt('\uD834abc', null), 0xD834); - assert.strictEqual(codePointAt('\uD834abc', undefined), 0xD834); - assert.strictEqual(codePointAt('\uDF06abc', ''), 0xDF06); - assert.strictEqual(codePointAt('\uDF06abc', '_'), 0xDF06); - assert.strictEqual(codePointAt('\uDF06abc'), 0xDF06); - assert.strictEqual(codePointAt('\uDF06abc', -1), undefined); - assert.strictEqual(codePointAt('\uDF06abc', -0), 0xDF06); - assert.strictEqual(codePointAt('\uDF06abc', 0), 0xDF06); - assert.strictEqual(codePointAt('\uDF06abc', false), 0xDF06); - assert.strictEqual(codePointAt('\uDF06abc', NaN), 0xDF06); - assert.strictEqual(codePointAt('\uDF06abc', null), 0xDF06); - assert.strictEqual(codePointAt('\uDF06abc', undefined), 0xDF06); - if (STRICT) { - assert.throws(() => codePointAt(null, 0), TypeError); - assert.throws(() => codePointAt(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.string.ends-with.js b/tests/pure/es.string.ends-with.js deleted file mode 100644 index 3d942d187ee4..000000000000 --- a/tests/pure/es.string.ends-with.js +++ /dev/null @@ -1,33 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import Symbol from 'core-js-pure/features/symbol'; -import endsWith from 'core-js-pure/features/string/ends-with'; - -QUnit.test('String#endsWith', assert => { - assert.isFunction(endsWith); - assert.ok(endsWith('undefined')); - assert.ok(!endsWith('undefined', null)); - assert.ok(endsWith('abc', '')); - assert.ok(endsWith('abc', 'c')); - assert.ok(endsWith('abc', 'bc')); - assert.ok(!endsWith('abc', 'ab')); - assert.ok(endsWith('abc', '', NaN)); - assert.ok(!endsWith('abc', 'c', -1)); - assert.ok(endsWith('abc', 'a', 1)); - assert.ok(endsWith('abc', 'c', Infinity)); - assert.ok(endsWith('abc', 'a', true)); - assert.ok(!endsWith('abc', 'c', 'x')); - assert.ok(!endsWith('abc', 'a', 'x')); - if (STRICT) { - assert.throws(() => endsWith(null, '.'), TypeError); - assert.throws(() => endsWith(undefined, '.'), TypeError); - } - const regexp = /./; - assert.throws(() => endsWith('/./', regexp), TypeError); - regexp[Symbol.match] = false; - assert.notThrows(() => endsWith('/./', regexp)); - const object = {}; - assert.notThrows(() => endsWith('[object Object]', object)); - object[Symbol.match] = true; - assert.throws(() => endsWith('[object Object]', object), TypeError); -}); diff --git a/tests/pure/es.string.fixed.js b/tests/pure/es.string.fixed.js deleted file mode 100644 index 1c6643c76386..000000000000 --- a/tests/pure/es.string.fixed.js +++ /dev/null @@ -1,6 +0,0 @@ -import fixed from 'core-js-pure/features/string/fixed'; - -QUnit.test('String#fixed', assert => { - assert.isFunction(fixed); - assert.same(fixed('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.fontcolor.js b/tests/pure/es.string.fontcolor.js deleted file mode 100644 index fce499826f80..000000000000 --- a/tests/pure/es.string.fontcolor.js +++ /dev/null @@ -1,7 +0,0 @@ -import fontcolor from 'core-js-pure/features/string/fontcolor'; - -QUnit.test('String#fontcolor', assert => { - assert.isFunction(fontcolor); - assert.same(fontcolor('a', 'b'), 'a', 'lower case'); - assert.same(fontcolor('a', '"'), 'a', 'escape quotes'); -}); diff --git a/tests/pure/es.string.fontsize.js b/tests/pure/es.string.fontsize.js deleted file mode 100644 index b7c699146b7b..000000000000 --- a/tests/pure/es.string.fontsize.js +++ /dev/null @@ -1,7 +0,0 @@ -import fontsize from 'core-js-pure/features/string/fontsize'; - -QUnit.test('String#fontsize', assert => { - assert.isFunction(fontsize); - assert.same(fontsize('a', 'b'), 'a', 'lower case'); - assert.same(fontsize('a', '"'), 'a', 'escape quotes'); -}); diff --git a/tests/pure/es.string.from-code-point.js b/tests/pure/es.string.from-code-point.js deleted file mode 100644 index 8e980b0ea764..000000000000 --- a/tests/pure/es.string.from-code-point.js +++ /dev/null @@ -1,49 +0,0 @@ -import fromCodePoint from 'core-js-pure/features/string/from-code-point'; - -QUnit.test('String.fromCodePoint', assert => { - assert.isFunction(fromCodePoint); - assert.arity(fromCodePoint, 1); - if ('name' in fromCodePoint) { - assert.name(fromCodePoint, 'fromCodePoint'); - } - assert.strictEqual(fromCodePoint(''), '\0'); - assert.strictEqual(fromCodePoint(), ''); - assert.strictEqual(fromCodePoint(-0), '\0'); - assert.strictEqual(fromCodePoint(0), '\0'); - assert.strictEqual(fromCodePoint(0x1D306), '\uD834\uDF06'); - assert.strictEqual(fromCodePoint(0x1D306, 0x61, 0x1D307), '\uD834\uDF06a\uD834\uDF07'); - assert.strictEqual(fromCodePoint(0x61, 0x62, 0x1D307), 'ab\uD834\uDF07'); - assert.strictEqual(fromCodePoint(false), '\0'); - assert.strictEqual(fromCodePoint(null), '\0'); - assert.throws(() => fromCodePoint('_'), RangeError); - assert.throws(() => fromCodePoint('+Infinity'), RangeError); - assert.throws(() => fromCodePoint('-Infinity'), RangeError); - assert.throws(() => fromCodePoint(-1), RangeError); - assert.throws(() => fromCodePoint(0x10FFFF + 1), RangeError); - assert.throws(() => fromCodePoint(3.14), RangeError); - assert.throws(() => fromCodePoint(3e-2), RangeError); - assert.throws(() => fromCodePoint(-Infinity), RangeError); - assert.throws(() => fromCodePoint(Infinity), RangeError); - assert.throws(() => fromCodePoint(NaN), RangeError); - assert.throws(() => fromCodePoint(undefined), RangeError); - assert.throws(() => fromCodePoint({}), RangeError); - assert.throws(() => fromCodePoint(/./), RangeError); - let number = 0x60; - assert.strictEqual(fromCodePoint({ - valueOf() { - return ++number; - }, - }), 'a'); - assert.strictEqual(number, 0x61); - // one code unit per symbol - let counter = 2 ** 15 * 3 / 2; - let result = []; - while (--counter >= 0) result.push(0); - // should not throw - fromCodePoint.apply(null, result); - counter = 2 ** 15 * 3 / 2; - result = []; - while (--counter >= 0) result.push(0xFFFF + 1); - // should not throw - fromCodePoint.apply(null, result); -}); diff --git a/tests/pure/es.string.includes.js b/tests/pure/es.string.includes.js deleted file mode 100644 index c3fc2f193639..000000000000 --- a/tests/pure/es.string.includes.js +++ /dev/null @@ -1,24 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import Symbol from 'core-js-pure/features/symbol'; -import includes from 'core-js-pure/features/string/includes'; - -QUnit.test('String#includes', assert => { - assert.isFunction(includes); - assert.ok(!includes('abc')); - assert.ok(includes('aundefinedb')); - assert.ok(includes('abcd', 'b', 1)); - assert.ok(!includes('abcd', 'b', 2)); - if (STRICT) { - assert.throws(() => includes(null, '.'), TypeError); - assert.throws(() => includes(undefined, '.'), TypeError); - } - const re = /./; - assert.throws(() => includes('/./', re), TypeError); - re[Symbol.match] = false; - assert.notThrows(() => includes('/./', re)); - const O = {}; - assert.notThrows(() => includes('[object Object]', O)); - O[Symbol.match] = true; - assert.throws(() => includes('[object Object]', O), TypeError); -}); diff --git a/tests/pure/es.string.italics.js b/tests/pure/es.string.italics.js deleted file mode 100644 index 02476c883277..000000000000 --- a/tests/pure/es.string.italics.js +++ /dev/null @@ -1,6 +0,0 @@ -import italics from 'core-js-pure/features/string/italics'; - -QUnit.test('String#italics', assert => { - assert.isFunction(italics); - assert.same(italics('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.iterator.js b/tests/pure/es.string.iterator.js deleted file mode 100644 index f39a8c84c3bd..000000000000 --- a/tests/pure/es.string.iterator.js +++ /dev/null @@ -1,44 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; -import getIterator from 'core-js-pure/features/get-iterator'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('String#@@iterator', assert => { - let iterator = getIterator('qwe'); - assert.isIterator(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'String Iterator'); - assert.strictEqual(String(iterator), '[object String Iterator]'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - assert.strictEqual(from('𠮷𠮷𠮷').length, 3); - iterator = getIterator('𠮷𠮷𠮷'); - assert.deepEqual(iterator.next(), { - value: '𠮷', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: '𠮷', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: '𠮷', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/pure/es.string.link.js b/tests/pure/es.string.link.js deleted file mode 100644 index 073cf16f2619..000000000000 --- a/tests/pure/es.string.link.js +++ /dev/null @@ -1,7 +0,0 @@ -import link from 'core-js-pure/features/string/link'; - -QUnit.test('String#link', assert => { - assert.isFunction(link); - assert.same(link('a', 'b'), 'a', 'lower case'); - assert.same(link('a', '"'), 'a', 'escape quotes'); -}); diff --git a/tests/pure/es.string.match-all.js b/tests/pure/es.string.match-all.js deleted file mode 100644 index 16f888745f65..000000000000 --- a/tests/pure/es.string.match-all.js +++ /dev/null @@ -1,132 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import matchAll from 'core-js-pure/es/string/match-all'; -import Symbol from 'core-js-pure/es/symbol'; -import assign from 'core-js-pure/es/object/assign'; - -QUnit.test('String#matchAll', assert => { - assert.isFunction(matchAll); - let data = ['aabc', { toString() { - return 'aabc'; - } }]; - for (const target of data) { - const iterator = matchAll(target, /[ac]/g); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.deepEqual(iterator.next(), { - value: assign(['a'], { - input: 'aabc', - index: 0, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['a'], { - input: 'aabc', - index: 1, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['c'], { - input: 'aabc', - index: 3, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - } - let iterator = matchAll('1111a2b3cccc', /(\d)(\D)/g); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'RegExp String Iterator'); - assert.strictEqual(String(iterator), '[object RegExp String Iterator]'); - assert.deepEqual(iterator.next(), { - value: assign(['1a', '1', 'a'], { - input: '1111a2b3cccc', - index: 3, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['2b', '2', 'b'], { - input: '1111a2b3cccc', - index: 5, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['3c', '3', 'c'], { - input: '1111a2b3cccc', - index: 7, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - assert.throws(() => matchAll('1111a2b3cccc', /(\d)(\D)/), TypeError); - iterator = matchAll('1111a2b3cccc', '(\\d)(\\D)'); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.deepEqual(iterator.next(), { - value: assign(['1a', '1', 'a'], { - input: '1111a2b3cccc', - index: 3, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['2b', '2', 'b'], { - input: '1111a2b3cccc', - index: 5, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['3c', '3', 'c'], { - input: '1111a2b3cccc', - index: 7, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - /* IE8- issue - iterator = matchAll('abc', /\B/g); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.deepEqual(iterator.next(), { - value: assign([''], { - input: 'abc', - index: 1, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign([''], { - input: 'abc', - index: 2, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - */ - data = [null, undefined, NaN, 42, {}, []]; - for (const target of data) { - assert.notThrows(() => matchAll('', target), `Not throws on ${ target } as the first argument`); - } - if (STRICT) { - assert.throws(() => matchAll(null, /./g), TypeError, 'Throws on null as `this`'); - assert.throws(() => matchAll(undefined, /./g), TypeError, 'Throws on undefined as `this`'); - } -}); diff --git a/tests/pure/es.string.pad-end.js b/tests/pure/es.string.pad-end.js deleted file mode 100644 index 0dc0ce6b665b..000000000000 --- a/tests/pure/es.string.pad-end.js +++ /dev/null @@ -1,18 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import padEnd from 'core-js-pure/features/string/pad-end'; - -QUnit.test('String#padEnd', assert => { - assert.isFunction(padEnd); - assert.strictEqual(padEnd('abc', 5), 'abc '); - assert.strictEqual(padEnd('abc', 4, 'de'), 'abcd'); - assert.strictEqual(padEnd('abc'), 'abc'); - assert.strictEqual(padEnd('abc', 5, '_'), 'abc__'); - assert.strictEqual(padEnd('', 0), ''); - assert.strictEqual(padEnd('foo', 1), 'foo'); - assert.strictEqual(padEnd('foo', 5, ''), 'foo'); - if (STRICT) { - assert.throws(() => padEnd(null, 0), TypeError); - assert.throws(() => padEnd(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.string.pad-start.js b/tests/pure/es.string.pad-start.js deleted file mode 100644 index 33ca463d6425..000000000000 --- a/tests/pure/es.string.pad-start.js +++ /dev/null @@ -1,18 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import padStart from 'core-js-pure/features/string/pad-start'; - -QUnit.test('String#padStart', assert => { - assert.isFunction(padStart); - assert.strictEqual(padStart('abc', 5), ' abc'); - assert.strictEqual(padStart('abc', 4, 'de'), 'dabc'); - assert.strictEqual(padStart('abc'), 'abc'); - assert.strictEqual(padStart('abc', 5, '_'), '__abc'); - assert.strictEqual(padStart('', 0), ''); - assert.strictEqual(padStart('foo', 1), 'foo'); - assert.strictEqual(padStart('foo', 5, ''), 'foo'); - if (STRICT) { - assert.throws(() => padStart(null, 0), TypeError); - assert.throws(() => padStart(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.string.raw.js b/tests/pure/es.string.raw.js deleted file mode 100644 index 18a98eb2ba53..000000000000 --- a/tests/pure/es.string.raw.js +++ /dev/null @@ -1,14 +0,0 @@ -import raw from 'core-js-pure/features/string/raw'; - -QUnit.test('String.raw', assert => { - assert.isFunction(raw); - assert.arity(raw, 1); - if ('name' in raw) { - assert.name(raw, 'raw'); - } - assert.strictEqual(raw({ raw: ['Hi\\n', '!'] }, 'Bob'), 'Hi\\nBob!', 'raw is array'); - assert.strictEqual(raw({ raw: 'test' }, 0, 1, 2), 't0e1s2t', 'raw is string'); - assert.strictEqual(raw({ raw: 'test' }, 0), 't0est', 'lacks substituting'); - assert.throws(() => raw({}), TypeError); - assert.throws(() => raw({ raw: null }), TypeError); -}); diff --git a/tests/pure/es.string.repeat.js b/tests/pure/es.string.repeat.js deleted file mode 100644 index 218ce3d272fa..000000000000 --- a/tests/pure/es.string.repeat.js +++ /dev/null @@ -1,15 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import repeat from 'core-js-pure/features/string/repeat'; - -QUnit.test('String#repeat', assert => { - assert.isFunction(repeat); - assert.strictEqual(repeat('qwe', 3), 'qweqweqwe'); - assert.strictEqual(repeat('qwe', 2.5), 'qweqwe'); - assert.throws(() => repeat('qwe', -1), RangeError); - assert.throws(() => repeat('qwe', Infinity), RangeError); - if (STRICT) { - assert.throws(() => repeat(null, 1), TypeError); - assert.throws(() => repeat(undefined, 1), TypeError); - } -}); diff --git a/tests/pure/es.string.small.js b/tests/pure/es.string.small.js deleted file mode 100644 index 981319b1f849..000000000000 --- a/tests/pure/es.string.small.js +++ /dev/null @@ -1,6 +0,0 @@ -import small from 'core-js-pure/features/string/small'; - -QUnit.test('String#small', assert => { - assert.isFunction(small); - assert.same(small('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.starts-with.js b/tests/pure/es.string.starts-with.js deleted file mode 100644 index 94a99edce9b3..000000000000 --- a/tests/pure/es.string.starts-with.js +++ /dev/null @@ -1,32 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import Symbol from 'core-js-pure/features/symbol'; -import startsWith from 'core-js-pure/features/string/starts-with'; - -QUnit.test('String#startsWith', assert => { - assert.isFunction(startsWith); - assert.ok(startsWith('undefined')); - assert.ok(!startsWith('undefined', null)); - assert.ok(startsWith('abc', '')); - assert.ok(startsWith('abc', 'a')); - assert.ok(startsWith('abc', 'ab')); - assert.ok(!startsWith('abc', 'bc')); - assert.ok(startsWith('abc', '', NaN)); - assert.ok(startsWith('abc', 'a', -1)); - assert.ok(!startsWith('abc', 'a', 1)); - assert.ok(!startsWith('abc', 'a', Infinity)); - assert.ok(startsWith('abc', 'b', true)); - assert.ok(startsWith('abc', 'a', 'x')); - if (STRICT) { - assert.throws(() => startsWith(null, '.'), TypeError); - assert.throws(() => startsWith(undefined, '.'), TypeError); - } - const regexp = /./; - assert.throws(() => startsWith('/./', regexp), TypeError); - regexp[Symbol.match] = false; - assert.notThrows(() => startsWith('/./', regexp)); - const object = {}; - assert.notThrows(() => startsWith('[object Object]', object)); - object[Symbol.match] = true; - assert.throws(() => startsWith('[object Object]', object), TypeError); -}); diff --git a/tests/pure/es.string.strike.js b/tests/pure/es.string.strike.js deleted file mode 100644 index 718f44ca20aa..000000000000 --- a/tests/pure/es.string.strike.js +++ /dev/null @@ -1,6 +0,0 @@ -import strike from 'core-js-pure/features/string/strike'; - -QUnit.test('String#strike', assert => { - assert.isFunction(strike); - assert.same(strike('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.sub.js b/tests/pure/es.string.sub.js deleted file mode 100644 index 3f7c3e0c383a..000000000000 --- a/tests/pure/es.string.sub.js +++ /dev/null @@ -1,6 +0,0 @@ -import sub from 'core-js-pure/features/string/sub'; - -QUnit.test('String#sub', assert => { - assert.isFunction(sub); - assert.same(sub('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.sup.js b/tests/pure/es.string.sup.js deleted file mode 100644 index b762025800ef..000000000000 --- a/tests/pure/es.string.sup.js +++ /dev/null @@ -1,6 +0,0 @@ -import sup from 'core-js-pure/features/string/sup'; - -QUnit.test('String#sup', assert => { - assert.isFunction(sup); - assert.same(sup('a'), 'a', 'lower case'); -}); diff --git a/tests/pure/es.string.trim-end.js b/tests/pure/es.string.trim-end.js deleted file mode 100644 index 17e580e33033..000000000000 --- a/tests/pure/es.string.trim-end.js +++ /dev/null @@ -1,25 +0,0 @@ -import { STRICT, WHITESPACES } from '../helpers/constants'; - -import { trimRight, trimEnd } from 'core-js-pure/features/string'; - -QUnit.test('String#trimRight', assert => { - assert.isFunction(trimRight); - assert.strictEqual(trimRight(' \n q w e \n '), ' \n q w e', 'removes whitespaces at right side of string'); - assert.strictEqual(trimRight(WHITESPACES), '', 'removes all whitespaces'); - assert.strictEqual(trimRight('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trimRight(null, 0), TypeError); - assert.throws(() => trimRight(undefined, 0), TypeError); - } -}); - -QUnit.test('String#trimEnd', assert => { - assert.isFunction(trimEnd); - assert.strictEqual(trimEnd(' \n q w e \n '), ' \n q w e', 'removes whitespaces at right side of string'); - assert.strictEqual(trimEnd(WHITESPACES), '', 'removes all whitespaces'); - assert.strictEqual(trimEnd('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trimEnd(null, 0), TypeError); - assert.throws(() => trimEnd(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.string.trim-start.js b/tests/pure/es.string.trim-start.js deleted file mode 100644 index 1001e7decf97..000000000000 --- a/tests/pure/es.string.trim-start.js +++ /dev/null @@ -1,25 +0,0 @@ -import { STRICT, WHITESPACES } from '../helpers/constants'; - -import { trimLeft, trimStart } from 'core-js-pure/features/string'; - -QUnit.test('String#trimLeft', assert => { - assert.isFunction(trimLeft); - assert.strictEqual(trimLeft(' \n q w e \n '), 'q w e \n ', 'removes whitespaces at left side of string'); - assert.strictEqual(trimLeft(WHITESPACES), '', 'removes all whitespaces'); - assert.strictEqual(trimLeft('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trimLeft(null, 0), TypeError); - assert.throws(() => trimLeft(undefined, 0), TypeError); - } -}); - -QUnit.test('String#trimStart', assert => { - assert.isFunction(trimStart); - assert.strictEqual(trimStart(' \n q w e \n '), 'q w e \n ', 'removes whitespaces at left side of string'); - assert.strictEqual(trimStart(WHITESPACES), '', 'removes all whitespaces'); - assert.strictEqual(trimStart('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trimStart(null, 0), TypeError); - assert.throws(() => trimStart(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.string.trim.js b/tests/pure/es.string.trim.js deleted file mode 100644 index 92bffbbd94e3..000000000000 --- a/tests/pure/es.string.trim.js +++ /dev/null @@ -1,14 +0,0 @@ -import { STRICT, WHITESPACES } from '../helpers/constants'; - -import trim from 'core-js-pure/features/string/trim'; - -QUnit.test('String#trim', assert => { - assert.isFunction(trim); - assert.strictEqual(trim(' \n q w e \n '), 'q w e', 'removes whitespaces at left & right side of string'); - assert.strictEqual(trim(WHITESPACES), '', 'removes all whitespaces'); - assert.strictEqual(trim('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trim(null, 0), TypeError); - assert.throws(() => trim(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/es.symbol.async-iterator.js b/tests/pure/es.symbol.async-iterator.js deleted file mode 100644 index c774b24df3db..000000000000 --- a/tests/pure/es.symbol.async-iterator.js +++ /dev/null @@ -1,6 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('Symbol.asyncIterator', assert => { - assert.ok('asyncIterator' in Symbol, 'Symbol.asyncIterator available'); - assert.ok(Object(Symbol.asyncIterator) instanceof Symbol, 'Symbol.asyncIterator is symbol'); -}); diff --git a/tests/pure/es.symbol.js b/tests/pure/es.symbol.js deleted file mode 100644 index 9f35b95a162c..000000000000 --- a/tests/pure/es.symbol.js +++ /dev/null @@ -1,287 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -import core from 'core-js-pure'; -import { - defineProperty, - defineProperties, - getOwnPropertyDescriptor, - getOwnPropertyNames, - getOwnPropertySymbols, - keys, - create, -} from 'core-js-pure/features/object'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; - -const { Symbol, JSON } = core; - -QUnit.test('Symbol', assert => { - assert.isFunction(Symbol); - const symbol1 = Symbol('symbol'); - const symbol2 = Symbol('symbol'); - assert.ok(symbol1 !== symbol2, 'Symbol("symbol") !== Symbol("symbol")'); - const object = {}; - object[symbol1] = 42; - assert.ok(object[symbol1] === 42, 'Symbol() work as key'); - assert.ok(object[symbol2] !== 42, 'Various symbols from one description are various keys'); - if (DESCRIPTORS) { - let count = 0; - // eslint-disable-next-line no-unused-vars - for (const key in object) count++; - assert.ok(count === 0, 'object[Symbol()] is not enumerable'); - } -}); - -QUnit.test('Well-known Symbols', assert => { - const wks = [ - 'hasInstance', - 'isConcatSpreadable', - 'iterator', - 'match', - 'matchAll', - 'replace', - 'search', - 'species', - 'split', - 'toPrimitive', - 'toStringTag', - 'unscopables', - ]; - for (const name of wks) { - assert.ok(name in Symbol, `Symbol.${ name } available`); - assert.ok(Object(Symbol[name]) instanceof Symbol, `Symbol.${ name } is symbol`); - } -}); - -QUnit.test('Global symbol registry', assert => { - assert.isFunction(Symbol.for, 'Symbol.for is function'); - assert.isFunction(Symbol.keyFor, 'Symbol.keyFor is function'); - const symbol = Symbol.for('foo'); - assert.strictEqual(Symbol.for('foo'), symbol); - assert.strictEqual(Symbol.keyFor(symbol), 'foo'); - assert.throws(() => Symbol.keyFor('foo'), 'throws on non-symbol'); -}); - -QUnit.test('Symbol#@@toPrimitive', assert => { - const symbol = Symbol(); - assert.isFunction(Symbol.prototype[Symbol.toPrimitive]); - assert.same(symbol, symbol[Symbol.toPrimitive](), 'works'); -}); - -QUnit.test('Symbol#@@toStringTag', assert => { - assert.ok(Symbol.prototype[Symbol.toStringTag] === 'Symbol', 'Symbol::@@toStringTag is `Symbol`'); -}); - -QUnit.test('Object.getOwnPropertySymbols', assert => { - assert.isFunction(getOwnPropertySymbols); - const prototype = { q: 1, w: 2, e: 3 }; - prototype[Symbol()] = 42; - prototype[Symbol()] = 43; - assert.deepEqual(getOwnPropertyNames(prototype).sort(), ['e', 'q', 'w']); - assert.strictEqual(getOwnPropertySymbols(prototype).length, 2); - const object = create(prototype); - object.a = 1; - object.s = 2; - object.d = 3; - object[Symbol()] = 44; - assert.deepEqual(getOwnPropertyNames(object).sort(), ['a', 'd', 's']); - assert.strictEqual(getOwnPropertySymbols(object).length, 1); - assert.strictEqual(getOwnPropertySymbols(Object.prototype).length, 0); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => getOwnPropertySymbols(value), `accept ${ typeof value }`); - } -}); - -if (JSON) { - QUnit.test('Symbols & JSON.stringify', assert => { - assert.strictEqual(JSON.stringify([ - 1, - Symbol('foo'), - false, - Symbol('bar'), - {}, - ]), '[1,null,false,null,{}]', 'array value'); - assert.strictEqual(JSON.stringify({ - symbol: Symbol('symbol'), - }), '{}', 'object value'); - if (DESCRIPTORS) { - const object = { bar: 2 }; - object[Symbol('symbol')] = 1; - assert.strictEqual(JSON.stringify(object), '{"bar":2}', 'object key'); - } - assert.strictEqual(JSON.stringify(Symbol('symbol')), undefined, 'symbol value'); - if (typeof Symbol() === 'symbol') { - assert.strictEqual(JSON.stringify(Object(Symbol('symbol'))), '{}', 'boxed symbol'); - } - assert.strictEqual(JSON.stringify(undefined, () => 42), '42', 'replacer works with top-level undefined'); - }); -} - -if (DESCRIPTORS) { - QUnit.test('Symbols & descriptors', assert => { - const d = Symbol('d'); - const e = Symbol('e'); - const f = Symbol('f'); - const i = Symbol('i'); - const j = Symbol('j'); - const prototype = { g: 'g' }; - prototype[i] = 'i'; - defineProperty(prototype, 'h', { - value: 'h', - }); - defineProperty(prototype, 'j', { - value: 'j', - }); - const object = create(prototype); - object.a = 'a'; - object[d] = 'd'; - defineProperty(object, 'b', { - value: 'b', - }); - defineProperty(object, 'c', { - value: 'c', - enumerable: true, - }); - defineProperty(object, e, { - configurable: true, - writable: true, - value: 'e', - }); - const descriptor = { - value: 'f', - enumerable: true, - }; - defineProperty(object, f, descriptor); - assert.strictEqual(descriptor.enumerable, true, 'defineProperty not changes descriptor object'); - assert.deepEqual(getOwnPropertyDescriptor(object, 'a'), { - configurable: true, - writable: true, - enumerable: true, - value: 'a', - }, 'getOwnPropertyDescriptor a'); - assert.deepEqual(getOwnPropertyDescriptor(object, 'b'), { - configurable: false, - writable: false, - enumerable: false, - value: 'b', - }, 'getOwnPropertyDescriptor b'); - assert.deepEqual(getOwnPropertyDescriptor(object, 'c'), { - configurable: false, - writable: false, - enumerable: true, - value: 'c', - }, 'getOwnPropertyDescriptor c'); - assert.deepEqual(getOwnPropertyDescriptor(object, d), { - configurable: true, - writable: true, - enumerable: true, - value: 'd', - }, 'getOwnPropertyDescriptor d'); - assert.deepEqual(getOwnPropertyDescriptor(object, e), { - configurable: true, - writable: true, - enumerable: false, - value: 'e', - }, 'getOwnPropertyDescriptor e'); - assert.deepEqual(getOwnPropertyDescriptor(object, f), { - configurable: false, - writable: false, - enumerable: true, - value: 'f', - }, 'getOwnPropertyDescriptor f'); - assert.strictEqual(getOwnPropertyDescriptor(object, 'g'), undefined, 'getOwnPropertyDescriptor g'); - assert.strictEqual(getOwnPropertyDescriptor(object, 'h'), undefined, 'getOwnPropertyDescriptor h'); - assert.strictEqual(getOwnPropertyDescriptor(object, i), undefined, 'getOwnPropertyDescriptor i'); - assert.strictEqual(getOwnPropertyDescriptor(object, j), undefined, 'getOwnPropertyDescriptor j'); - assert.strictEqual(getOwnPropertyDescriptor(object, 'k'), undefined, 'getOwnPropertyDescriptor k'); - assert.strictEqual(getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable, false, 'getOwnPropertyDescriptor on Object.prototype'); - assert.strictEqual(getOwnPropertyDescriptor(Object.prototype, d), undefined, 'getOwnPropertyDescriptor on Object.prototype missed symbol'); - assert.strictEqual(keys(object).length, 2, 'Object.keys'); - assert.strictEqual(getOwnPropertyNames(object).length, 3, 'Object.getOwnPropertyNames'); - assert.strictEqual(getOwnPropertySymbols(object).length, 3, 'Object.getOwnPropertySymbols'); - assert.strictEqual(ownKeys(object).length, 6, 'Reflect.ownKeys'); - delete object[e]; - object[e] = 'e'; - assert.deepEqual(getOwnPropertyDescriptor(object, e), { - configurable: true, - writable: true, - enumerable: true, - value: 'e', - }, 'redefined non-enum key'); - }); - - QUnit.test('Symbols & Object.defineProperties', assert => { - const c = Symbol('c'); - const d = Symbol('d'); - const descriptors = { - a: { - value: 'a', - }, - }; - descriptors[c] = { - value: 'c', - }; - defineProperty(descriptors, 'b', { - value: { - value: 'b', - }, - }); - defineProperty(descriptors, d, { - value: { - value: 'd', - }, - }); - const object = defineProperties({}, descriptors); - assert.strictEqual(object.a, 'a', 'a'); - assert.strictEqual(object.b, undefined, 'b'); - assert.strictEqual(object[c], 'c', 'c'); - assert.strictEqual(object[d], undefined, 'd'); - }); - - QUnit.test('Symbols & Object.create', assert => { - const c = Symbol('c'); - const d = Symbol('d'); - const descriptors = { - a: { - value: 'a', - }, - }; - descriptors[c] = { - value: 'c', - }; - defineProperty(descriptors, 'b', { - value: { - value: 'b', - }, - }); - defineProperty(descriptors, d, { - value: { - value: 'd', - }, - }); - const object = create(null, descriptors); - assert.strictEqual(object.a, 'a', 'a'); - assert.strictEqual(object.b, undefined, 'b'); - assert.strictEqual(object[c], 'c', 'c'); - assert.strictEqual(object[d], undefined, 'd'); - }); - - const constructors = ['Map', 'Set', 'Promise']; - for (const name of constructors) { - QUnit.test(`${ name }@@species`, assert => { - assert.strictEqual(core[name][Symbol.species], core[name], `${ name }@@species === ${ name }`); - const Subclass = create(core[name]); - assert.strictEqual(Subclass[Symbol.species], Subclass, `${ name } subclass`); - }); - } - - QUnit.test('Array@@species', assert => { - assert.strictEqual(Array[Symbol.species], Array, 'Array@@species === Array'); - const Subclass = create(Array); - assert.strictEqual(Subclass[Symbol.species], Subclass, 'Array subclass'); - }); - - QUnit.test('Symbol.sham flag', assert => { - assert.same(Symbol.sham, typeof Symbol() === 'symbol' ? undefined : true); - }); -} diff --git a/tests/pure/es.weak-map.js b/tests/pure/es.weak-map.js deleted file mode 100644 index c71214c54016..000000000000 --- a/tests/pure/es.weak-map.js +++ /dev/null @@ -1,147 +0,0 @@ -import { createIterable, nativeSubclass } from '../helpers/helpers'; -import { DESCRIPTORS } from '../helpers/constants'; - -import { Symbol, WeakMap } from 'core-js-pure'; -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; -import { freeze, keys, getOwnPropertyNames, getOwnPropertySymbols } from 'core-js-pure/features/object'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; - -QUnit.test('WeakMap', assert => { - assert.isFunction(WeakMap); - assert.ok('delete' in WeakMap.prototype, 'delete in WeakMap.prototype'); - assert.ok('get' in WeakMap.prototype, 'get in WeakMap.prototype'); - assert.ok('has' in WeakMap.prototype, 'has in WeakMap.prototype'); - assert.ok('set' in WeakMap.prototype, 'set in WeakMap.prototype'); - assert.ok(new WeakMap() instanceof WeakMap, 'new WeakMap instanceof WeakMap'); - let object = {}; - assert.strictEqual(new WeakMap(createIterable([[object, 42]])).get(object), 42, 'Init from iterable'); - let weakmap = new WeakMap(); - const frozen = freeze({}); - weakmap.set(frozen, 42); - assert.strictEqual(weakmap.get(frozen), 42, 'Support frozen objects'); - weakmap = new WeakMap(); - weakmap.set(frozen, 42); - assert.strictEqual(weakmap.has(frozen), true, 'works with frozen objects, #1'); - assert.strictEqual(weakmap.get(frozen), 42, 'works with frozen objects, #2'); - weakmap.delete(frozen); - assert.strictEqual(weakmap.has(frozen), false, 'works with frozen objects, #3'); - assert.strictEqual(weakmap.get(frozen), undefined, 'works with frozen objects, #4'); - let done = false; - try { - new WeakMap(createIterable([null, 1, 2], { - return() { - return done = true; - }, - })); - } catch { /* empty */ } - assert.ok(done, '.return #throw'); - assert.ok(!('clear' in WeakMap.prototype), 'should not contains `.clear` method'); - const array = []; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return getIteratorMethod([]).call(this); - }; - new WeakMap(array); - assert.ok(done); - object = {}; - new WeakMap().set(object, 1); - if (DESCRIPTORS) { - const results = []; - for (const key in object) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(object), []); - } - assert.arrayEqual(getOwnPropertyNames(object), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); - if (ownKeys) assert.arrayEqual(ownKeys(object), []); - if (nativeSubclass) { - const Subclass = nativeSubclass(WeakMap); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof WeakMap, 'correct subclassing with native classes #2'); - object = {}; - assert.same(new Subclass().set(object, 2).get(object), 2, 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('WeakMap#delete', assert => { - assert.isFunction(WeakMap.prototype.delete); - const a = {}; - const b = {}; - const weakmap = new WeakMap(); - weakmap.set(a, 42); - weakmap.set(b, 21); - assert.ok(weakmap.has(a) && weakmap.has(b), 'WeakMap has values before .delete()'); - weakmap.delete(a); - assert.ok(!weakmap.has(a) && weakmap.has(b), 'WeakMap hasn`t value after .delete()'); - assert.notThrows(() => !weakmap.delete(1), 'return false on primitive'); - const object = {}; - weakmap.set(object, 42); - freeze(object); - assert.ok(weakmap.has(object), 'works with frozen objects #1'); - weakmap.delete(object); - assert.ok(!weakmap.has(object), 'works with frozen objects #2'); -}); - -QUnit.test('WeakMap#get', assert => { - assert.isFunction(WeakMap.prototype.get); - const weakmap = new WeakMap(); - assert.strictEqual(weakmap.get({}), undefined, 'WeakMap .get() before .set() return undefined'); - let object = {}; - weakmap.set(object, 42); - assert.strictEqual(weakmap.get(object), 42, 'WeakMap .get() return value'); - weakmap.delete(object); - assert.strictEqual(weakmap.get(object), undefined, 'WeakMap .get() after .delete() return undefined'); - assert.notThrows(() => weakmap.get(1) === undefined, 'return undefined on primitive'); - object = {}; - weakmap.set(object, 42); - freeze(object); - assert.same(weakmap.get(object), 42, 'works with frozen objects #1'); - weakmap.delete(object); - assert.same(weakmap.get(object), undefined, 'works with frozen objects #2'); -}); - -QUnit.test('WeakMap#has', assert => { - assert.isFunction(WeakMap.prototype.has); - const weakmap = new WeakMap(); - assert.ok(!weakmap.has({}), 'WeakMap .has() before .set() return false'); - let object = {}; - weakmap.set(object, 42); - assert.ok(weakmap.has(object), 'WeakMap .has() return true'); - weakmap.delete(object); - assert.ok(!weakmap.has(object), 'WeakMap .has() after .delete() return false'); - assert.notThrows(() => !weakmap.has(1), 'return false on primitive'); - object = {}; - weakmap.set(object, 42); - freeze(object); - assert.ok(weakmap.has(object), 'works with frozen objects #1'); - weakmap.delete(object); - assert.ok(!weakmap.has(object), 'works with frozen objects #2'); -}); - -QUnit.test('WeakMap#set', assert => { - assert.isFunction(WeakMap.prototype.set); - const weakmap = new WeakMap(); - const object = {}; - weakmap.set(object, 33); - assert.same(weakmap.get(object), 33, 'works with object as keys'); - assert.ok(weakmap.set({}, 42) === weakmap, 'chaining'); - assert.throws(() => new WeakMap().set(42, 42), 'throws with primitive keys'); - const object1 = freeze({}); - const object2 = {}; - weakmap.set(object1, 42); - weakmap.set(object2, 42); - freeze(object); - assert.same(weakmap.get(object1), 42, 'works with frozen objects #1'); - assert.same(weakmap.get(object2), 42, 'works with frozen objects #2'); - weakmap.delete(object1); - weakmap.delete(object2); - assert.same(weakmap.get(object1), undefined, 'works with frozen objects #3'); - assert.same(weakmap.get(object2), undefined, 'works with frozen objects #4'); -}); - -QUnit.test('WeakMap#@@toStringTag', assert => { - assert.strictEqual(WeakMap.prototype[Symbol.toStringTag], 'WeakMap', 'WeakMap::@@toStringTag is `WeakMap`'); - assert.strictEqual(String(new WeakMap()), '[object WeakMap]', 'correct stringification'); -}); diff --git a/tests/pure/es.weak-set.js b/tests/pure/es.weak-set.js deleted file mode 100644 index a1f06a22d6f7..000000000000 --- a/tests/pure/es.weak-set.js +++ /dev/null @@ -1,95 +0,0 @@ -import { createIterable, nativeSubclass } from '../helpers/helpers'; -import { DESCRIPTORS } from '../helpers/constants'; - -import { Symbol, WeakSet } from 'core-js-pure'; -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; -import { freeze, keys, getOwnPropertyNames, getOwnPropertySymbols } from 'core-js-pure/features/object'; -import ownKeys from 'core-js-pure/features/reflect/own-keys'; - -QUnit.test('WeakSet', assert => { - assert.isFunction(WeakSet); - assert.ok('add' in WeakSet.prototype, 'add in WeakSet.prototype'); - assert.ok('delete' in WeakSet.prototype, 'delete in WeakSet.prototype'); - assert.ok('has' in WeakSet.prototype, 'has in WeakSet.prototype'); - assert.ok(new WeakSet() instanceof WeakSet, 'new WeakSet instanceof WeakSet'); - let object = {}; - assert.ok(new WeakSet(createIterable([object])).has(object), 'Init from iterable'); - const weakset = new WeakSet(); - const frozen = freeze({}); - weakset.add(frozen); - assert.strictEqual(weakset.has(frozen), true, 'works with frozen objects, #1'); - weakset.delete(frozen); - assert.strictEqual(weakset.has(frozen), false, 'works with frozen objects, #2'); - let done = false; - try { - new WeakSet(createIterable([null, 1, 2], { - return() { - return done = true; - }, - })); - } catch { /* empty */ } - assert.ok(done, '.return #throw'); - assert.ok(!('clear' in WeakSet.prototype), 'should not contains `.clear` method'); - const array = []; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return getIteratorMethod([]).call(this); - }; - new WeakSet(array); - assert.ok(done); - object = {}; - new WeakSet().add(object); - if (DESCRIPTORS) { - const results = []; - for (const key in object) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(object), []); - } - assert.arrayEqual(getOwnPropertyNames(object), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); - if (ownKeys) assert.arrayEqual(ownKeys(object), []); - if (nativeSubclass) { - const Subclass = nativeSubclass(WeakSet); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof WeakSet, 'correct subclassing with native classes #2'); - object = {}; - assert.ok(new Subclass().add(object).has(object), 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('WeakSet#add', assert => { - assert.isFunction(WeakSet.prototype.add); - const weakset = new WeakSet(); - assert.ok(weakset.add({}) === weakset, 'chaining'); - assert.throws(() => new WeakSet().add(42), 'throws with primitive keys'); -}); - -QUnit.test('WeakSet#delete', assert => { - assert.isFunction(WeakSet.prototype.delete); - const a = {}; - const b = {}; - const weakset = new WeakSet().add(a).add(b); - assert.ok(weakset.has(a) && weakset.has(b), 'WeakSet has values before .delete()'); - weakset.delete(a); - assert.ok(!weakset.has(a) && weakset.has(b), 'WeakSet has`nt value after .delete()'); - assert.notThrows(() => !weakset.delete(1), 'return false on primitive'); -}); - -QUnit.test('WeakSet#has', assert => { - assert.isFunction(WeakSet.prototype.has); - const weakset = new WeakSet(); - assert.ok(!weakset.has({}), 'WeakSet has`nt value'); - const object = {}; - weakset.add(object); - assert.ok(weakset.has(object), 'WeakSet has value after .add()'); - weakset.delete(object); - assert.ok(!weakset.has(object), 'WeakSet hasn`t value after .delete()'); - assert.notThrows(() => !weakset.has(1), 'return false on primitive'); -}); - -QUnit.test('WeakSet::@@toStringTag', assert => { - assert.strictEqual(WeakSet.prototype[Symbol.toStringTag], 'WeakSet', 'WeakSet::@@toStringTag is `WeakSet`'); - assert.strictEqual(String(new WeakSet()), '[object WeakSet]', 'correct stringification'); -}); diff --git a/tests/pure/esnext.aggregate-error.js b/tests/pure/esnext.aggregate-error.js deleted file mode 100644 index 70c6c352f5b8..000000000000 --- a/tests/pure/esnext.aggregate-error.js +++ /dev/null @@ -1,13 +0,0 @@ -import AggregateError from 'core-js-pure/features/aggregate-error'; - -QUnit.test('AggregateError', assert => { - assert.isFunction(AggregateError); - assert.arity(AggregateError, 2); - assert.name(AggregateError, 'AggregateError'); - assert.ok(new AggregateError([1]) instanceof AggregateError); - assert.ok(new AggregateError([1]) instanceof Error); - assert.ok(AggregateError([1]) instanceof AggregateError); - assert.ok(AggregateError([1]) instanceof Error); - assert.same(AggregateError([1], 'foo').message, 'foo'); - assert.deepEqual(AggregateError([1, 2, 3]).errors, [1, 2, 3]); -}); diff --git a/tests/pure/esnext.array.is-template-object.js b/tests/pure/esnext.array.is-template-object.js deleted file mode 100644 index b5279eeeca0a..000000000000 --- a/tests/pure/esnext.array.is-template-object.js +++ /dev/null @@ -1,26 +0,0 @@ -import isTemplateObject from 'core-js-pure/features/array/is-template-object'; -import freeze from 'core-js-pure/features/object/freeze'; - -QUnit.test('Array.isTemplateObject', assert => { - assert.isFunction(isTemplateObject); - assert.arity(isTemplateObject, 1); - assert.name(isTemplateObject, 'isTemplateObject'); - - assert.ok(!isTemplateObject(undefined)); - assert.ok(!isTemplateObject(null)); - assert.ok(!isTemplateObject({})); - assert.ok(!isTemplateObject(function () { - return arguments; - }())); - assert.ok(!isTemplateObject([])); - assert.ok(!isTemplateObject(freeze([]))); - - const template = (() => { - try { - // eslint-disable-next-line no-template-curly-in-string - return Function('return (it => it)`qwe${ 123 }asd`')(); - } catch { /* empty */ } - })(); - - if (template) assert.ok(isTemplateObject(template)); -}); diff --git a/tests/pure/esnext.async-iterator.as-indexed-pairs.js b/tests/pure/esnext.async-iterator.as-indexed-pairs.js deleted file mode 100644 index 2206cc933d18..000000000000 --- a/tests/pure/esnext.async-iterator.as-indexed-pairs.js +++ /dev/null @@ -1,23 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; - -QUnit.test('AsyncIterator#asIndexedPairs', assert => { - assert.expect(8); - const async = assert.async(); - const { asIndexedPairs } = AsyncIterator.prototype; - - assert.isFunction(asIndexedPairs); - assert.arity(asIndexedPairs, 0); - assert.nonEnumerable(AsyncIterator.prototype, 'asIndexedPairs'); - - asIndexedPairs.call(createIterator(['a', 'b', 'c'])).toArray().then(it => { - assert.same(it.toString(), '0,a,1,b,2,c', 'basic functionality'); - async(); - }); - - assert.throws(() => asIndexedPairs.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => asIndexedPairs.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => asIndexedPairs.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => asIndexedPairs.call([], () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.constructor.js b/tests/pure/esnext.async-iterator.constructor.js deleted file mode 100644 index 5dd77d7a3bb2..000000000000 --- a/tests/pure/esnext.async-iterator.constructor.js +++ /dev/null @@ -1,21 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('AsyncIterator', assert => { - assert.isFunction(AsyncIterator); - assert.arity(AsyncIterator, 0); - - assert.ok(AsyncIterator.from([1, 2, 3]) instanceof AsyncIterator, 'Async From Proxy'); - assert.ok(AsyncIterator.from([1, 2, 3]).drop(1) instanceof AsyncIterator, 'Async Drop Proxy'); - - assert.ok(new AsyncIterator() instanceof AsyncIterator, 'constructor'); - assert.throws(() => AsyncIterator(), 'throws w/o `new`'); -}); - -QUnit.test('AsyncIterator#constructor', assert => { - assert.strictEqual(AsyncIterator.prototype.constructor, AsyncIterator, 'AsyncIterator#constructor is AsyncIterator'); -}); - -QUnit.test('AsyncIterator#@@toStringTag', assert => { - assert.strictEqual(AsyncIterator.prototype[Symbol.toStringTag], 'AsyncIterator', 'AsyncIterator::@@toStringTag is `AsyncIterator`'); -}); diff --git a/tests/pure/esnext.async-iterator.drop.js b/tests/pure/esnext.async-iterator.drop.js deleted file mode 100644 index 8989f61fccff..000000000000 --- a/tests/pure/esnext.async-iterator.drop.js +++ /dev/null @@ -1,32 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; - -QUnit.test('AsyncIterator#drop', assert => { - assert.expect(12); - const async = assert.async(); - const { drop } = AsyncIterator.prototype; - - assert.isFunction(drop); - assert.arity(drop, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'drop'); - - drop.call(createIterator([1, 2, 3]), 1).toArray().then(it => { - assert.arrayEqual(it, [2, 3], 'basic functionality'); - return drop.call(createIterator([1, 2, 3]), 1.5).toArray(); - }).then(it => { - assert.arrayEqual(it, [2, 3], 'float'); - return drop.call(createIterator([1, 2, 3]), 4).toArray(); - }).then(it => { - assert.arrayEqual(it, [], 'big'); - return drop.call(createIterator([1, 2, 3]), 0).toArray(); - }).then(it => { - assert.arrayEqual(it, [1, 2, 3], 'zero'); - }).then(() => async()); - - assert.throws(() => drop.call(undefined, 1), TypeError); - assert.throws(() => drop.call(null, 1), TypeError); - assert.throws(() => drop.call({}, 1), TypeError); - assert.throws(() => drop.call([], 1), TypeError); - assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); -}); diff --git a/tests/pure/esnext.async-iterator.every.js b/tests/pure/esnext.async-iterator.every.js deleted file mode 100644 index 0db1306eda12..000000000000 --- a/tests/pure/esnext.async-iterator.every.js +++ /dev/null @@ -1,38 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#every', assert => { - assert.expect(16); - const async = assert.async(); - const { every } = AsyncIterator.prototype; - - assert.isFunction(every); - assert.arity(every, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'every'); - - every.call(createIterator([1, 2, 3]), it => typeof it === 'number').then(result => { - assert.ok(result, 'basic functionality, +'); - return every.call(createIterator([1, 2, 3]), it => it === 2); - }).then(result => { - assert.ok(!result, 'basic functionality, -'); - return every.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - }).then(() => { - return every.call(createIterator([1]), () => { throw 42; }); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => every.call([], () => { /* empty */ }), TypeError); - assert.throws(() => every.call(createIterator([1]), undefined), TypeError); - assert.throws(() => every.call(createIterator([1]), null), TypeError); - assert.throws(() => every.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.filter.js b/tests/pure/esnext.async-iterator.filter.js deleted file mode 100644 index 21d456d0b577..000000000000 --- a/tests/pure/esnext.async-iterator.filter.js +++ /dev/null @@ -1,35 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#filter', assert => { - assert.expect(15); - const async = assert.async(); - const { filter } = AsyncIterator.prototype; - - assert.isFunction(filter); - assert.arity(filter, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'filter'); - - filter.call(createIterator([1, 2, 3]), it => it % 2).toArray().then(it => { - assert.arrayEqual(it, [1, 3], 'basic functionality'); - return filter.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - }).then(() => { - return filter.call(createIterator([1]), () => { throw 42; }).toArray(); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call([], () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(createIterator([1]), undefined), TypeError); - assert.throws(() => filter.call(createIterator([1]), null), TypeError); - assert.throws(() => filter.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.find.js b/tests/pure/esnext.async-iterator.find.js deleted file mode 100644 index 6837e309015e..000000000000 --- a/tests/pure/esnext.async-iterator.find.js +++ /dev/null @@ -1,38 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#find', assert => { - assert.expect(16); - const async = assert.async(); - const { find } = AsyncIterator.prototype; - - assert.isFunction(find); - assert.arity(find, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'find'); - - find.call(createIterator([2, 3, 4]), it => it % 2).then(result => { - assert.same(result, 3, 'basic functionality, +'); - return find.call(createIterator([1, 2, 3]), it => it === 4); - }).then(result => { - assert.same(result, undefined, 'basic functionality, -'); - return find.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - }).then(() => { - return find.call(createIterator([1]), () => { throw 42; }); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => find.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => find.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => find.call([], () => { /* empty */ }), TypeError); - assert.throws(() => find.call(createIterator([1]), undefined), TypeError); - assert.throws(() => find.call(createIterator([1]), null), TypeError); - assert.throws(() => find.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.flat-map.js b/tests/pure/esnext.async-iterator.flat-map.js deleted file mode 100644 index d670dfd3ef2e..000000000000 --- a/tests/pure/esnext.async-iterator.flat-map.js +++ /dev/null @@ -1,35 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator, createIterable } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#flatMap', assert => { - assert.expect(15); - const async = assert.async(); - const { flatMap } = AsyncIterator.prototype; - - assert.isFunction(flatMap); - assert.arity(flatMap, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'flatMap'); - - flatMap.call(createIterator([1, [], 2, createIterable([3, 4]), [5, 6], 'ab']), it => typeof it == 'number' ? -it : it).toArray().then(it => { - assert.arrayEqual(it, [-1, -2, 3, 4, 5, 6, 'ab'], 'basic functionality'); - return flatMap.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - }).then(() => { - return flatMap.call(createIterator([1]), () => { throw 42; }).toArray(); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => flatMap.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call([], () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), undefined), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), null), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.for-each.js b/tests/pure/esnext.async-iterator.for-each.js deleted file mode 100644 index 3dad7272ef0d..000000000000 --- a/tests/pure/esnext.async-iterator.for-each.js +++ /dev/null @@ -1,37 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#forEach', assert => { - assert.expect(15); - const async = assert.async(); - const { forEach } = AsyncIterator.prototype; - - assert.isFunction(forEach); - assert.arity(forEach, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'forEach'); - - const array = []; - - forEach.call(createIterator([1, 2, 3]), it => array.push(it)).then(() => { - assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); - return forEach.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - }).then(() => { - return forEach.call(createIterator([1]), () => { throw 42; }); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call([], () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call(createIterator([1]), undefined), TypeError); - assert.throws(() => forEach.call(createIterator([1]), null), TypeError); - assert.throws(() => forEach.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.from.js b/tests/pure/esnext.async-iterator.from.js deleted file mode 100644 index e5aecc59d7b3..000000000000 --- a/tests/pure/esnext.async-iterator.from.js +++ /dev/null @@ -1,31 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; -import assign from 'core-js-pure/features/object/assign'; -import values from 'core-js-pure/features/array/values'; - -QUnit.test('AsyncIterator.from', assert => { - assert.expect(9); - const async = assert.async(); - const { from } = AsyncIterator; - - assert.isFunction(from); - assert.arity(from, 1); - - assert.ok(AsyncIterator.from(values([])) instanceof AsyncIterator, 'proxy, iterator'); - - assert.ok(AsyncIterator.from([]) instanceof AsyncIterator, 'proxy, iterable'); - - AsyncIterator.from([1, 2, 3]).toArray().then(result => { - assert.arrayEqual(result, [1, 2, 3], 'just a proxy'); - async(); - }); - - const asyncIterator = assign(new AsyncIterator(), { - next: () => { /* empty */ }, - }); - - assert.same(AsyncIterator.from(asyncIterator), asyncIterator, 'does not wrap AsyncIterator instanses'); - - assert.throws(() => from(undefined), TypeError); - assert.throws(() => from(null), TypeError); - assert.throws(() => from({}), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.map.js b/tests/pure/esnext.async-iterator.map.js deleted file mode 100644 index 4d6e75e7743a..000000000000 --- a/tests/pure/esnext.async-iterator.map.js +++ /dev/null @@ -1,35 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#map', assert => { - assert.expect(15); - const async = assert.async(); - const { map } = AsyncIterator.prototype; - - assert.isFunction(map); - assert.arity(map, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'map'); - - map.call(createIterator([1, 2, 3]), it => it ** 2).toArray().then(it => { - assert.arrayEqual(it, [1, 4, 9], 'basic functionality'); - return map.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - }).then(() => { - return map.call(createIterator([1]), () => { throw 42; }).toArray(); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => map.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => map.call([], () => { /* empty */ }), TypeError); - assert.throws(() => map.call(createIterator([1]), undefined), TypeError); - assert.throws(() => map.call(createIterator([1]), null), TypeError); - assert.throws(() => map.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.reduce.js b/tests/pure/esnext.async-iterator.reduce.js deleted file mode 100644 index 697f118eb013..000000000000 --- a/tests/pure/esnext.async-iterator.reduce.js +++ /dev/null @@ -1,42 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#reduce', assert => { - assert.expect(18); - const async = assert.async(); - const { reduce } = AsyncIterator.prototype; - - assert.isFunction(reduce); - assert.arity(reduce, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'reduce'); - - reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1).then(it => { - assert.same(it, 7, 'basic functionality, initial'); - return reduce.call(createIterator([2]), function (a, b) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 2, 'arguments length'); - assert.same(a, 1, 'argument 1'); - assert.same(b, 2, 'argument 2'); - }, 1); - }).then(() => { - return reduce.call(createIterator([1, 2, 3]), (a, b) => a + b); - }).then(it => { - assert.same(it, 6, 'basic functionality, no initial'); - return reduce.call(createIterator([]), (a, b) => a + b); - }).catch(() => { - assert.ok(true, 'reduce an empty interble with no initial'); - return reduce.call(createIterator([1]), () => { throw 42; }, 1); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => reduce.call(undefined, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call(null, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call({}, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call([], () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), undefined, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), null, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), {}, 1), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.some.js b/tests/pure/esnext.async-iterator.some.js deleted file mode 100644 index 4fddb31160f1..000000000000 --- a/tests/pure/esnext.async-iterator.some.js +++ /dev/null @@ -1,38 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#some', assert => { - assert.expect(16); - const async = assert.async(); - const { some } = AsyncIterator.prototype; - - assert.isFunction(some); - assert.arity(some, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'some'); - - some.call(createIterator([1, 2, 3]), it => it === 2).then(result => { - assert.ok(result, 'basic functionality, +'); - return some.call(createIterator([1, 2, 3]), it => it === 4); - }).then(result => { - assert.ok(!result, 'basic functionality, -'); - return some.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - }).then(() => { - return some.call(createIterator([1]), () => { throw 42; }); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => some.call([], () => { /* empty */ }), TypeError); - assert.throws(() => some.call(createIterator([1]), undefined), TypeError); - assert.throws(() => some.call(createIterator([1]), null), TypeError); - assert.throws(() => some.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.async-iterator.take.js b/tests/pure/esnext.async-iterator.take.js deleted file mode 100644 index 5e1f4b2abb9d..000000000000 --- a/tests/pure/esnext.async-iterator.take.js +++ /dev/null @@ -1,32 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; - -QUnit.test('AsyncIterator#take', assert => { - assert.expect(12); - const async = assert.async(); - const { take } = AsyncIterator.prototype; - - assert.isFunction(take); - assert.arity(take, 1); - assert.nonEnumerable(AsyncIterator.prototype, 'take'); - - take.call(createIterator([1, 2, 3]), 2).toArray().then(it => { - assert.arrayEqual(it, [1, 2], 'basic functionality'); - return take.call(createIterator([1, 2, 3]), 1.5).toArray(); - }).then(it => { - assert.arrayEqual(it, [1], 'float'); - return take.call(createIterator([1, 2, 3]), 4).toArray(); - }).then(it => { - assert.arrayEqual(it, [1, 2, 3], 'big'); - return take.call(createIterator([1, 2, 3]), 0).toArray(); - }).then(it => { - assert.arrayEqual(it, [], 'zero'); - }).then(() => async()); - - assert.throws(() => take.call(undefined, 1), TypeError); - assert.throws(() => take.call(null, 1), TypeError); - assert.throws(() => take.call({}, 1), TypeError); - assert.throws(() => take.call([], 1), TypeError); - assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); -}); diff --git a/tests/pure/esnext.async-iterator.to-array.js b/tests/pure/esnext.async-iterator.to-array.js deleted file mode 100644 index 46a517bb1fce..000000000000 --- a/tests/pure/esnext.async-iterator.to-array.js +++ /dev/null @@ -1,23 +0,0 @@ -import AsyncIterator from 'core-js-pure/features/async-iterator'; - -import { createIterator } from '../helpers/helpers'; - -QUnit.test('AsyncIterator#toArray', assert => { - assert.expect(8); - const async = assert.async(); - const { toArray } = AsyncIterator.prototype; - - assert.isFunction(toArray); - assert.arity(toArray, 0); - assert.nonEnumerable(AsyncIterator.prototype, 'toArray'); - - toArray.call(createIterator([1, 2, 3])).then(it => { - assert.arrayEqual(it, [1, 2, 3]); - async(); - }); - - assert.throws(() => toArray.call(undefined), TypeError); - assert.throws(() => toArray.call(null), TypeError); - assert.throws(() => toArray.call({}), TypeError); - assert.throws(() => toArray.call([]), TypeError); -}); diff --git a/tests/pure/esnext.composite-key.js b/tests/pure/esnext.composite-key.js deleted file mode 100644 index c83932d20adf..000000000000 --- a/tests/pure/esnext.composite-key.js +++ /dev/null @@ -1,46 +0,0 @@ -/* eslint-disable no-self-compare */ -import { FREEZING } from '../helpers/constants'; - -import compositeKey from 'core-js-pure/features/composite-key'; -import { getPrototypeOf, isFrozen } from 'core-js-pure/features/object'; - -QUnit.test('compositeKey', assert => { - assert.isFunction(compositeKey); - if (compositeKey.name) assert.name(compositeKey, 'compositeKey'); - - const key = compositeKey({}); - assert.same(typeof key, 'object'); - assert.same({}.toString.call(key), '[object Object]'); - assert.same(getPrototypeOf(key), null); - if (FREEZING) assert.ok(isFrozen(key)); - - const a = ['a']; - const b = ['b']; - const c = ['c']; - - assert.ok(compositeKey(a) === compositeKey(a)); - assert.ok(compositeKey(a) !== compositeKey(['a'])); - assert.ok(compositeKey(a) !== compositeKey(a, 1)); - assert.ok(compositeKey(a) !== compositeKey(a, b)); - assert.ok(compositeKey(a, 1) === compositeKey(a, 1)); - assert.ok(compositeKey(a, b) === compositeKey(a, b)); - assert.ok(compositeKey(a, b) !== compositeKey(b, a)); - assert.ok(compositeKey(a, b, c) === compositeKey(a, b, c)); - assert.ok(compositeKey(a, b, c) !== compositeKey(c, b, a)); - assert.ok(compositeKey(a, b, c) !== compositeKey(a, c, b)); - assert.ok(compositeKey(a, b, c, 1) !== compositeKey(a, b, c)); - assert.ok(compositeKey(a, b, c, 1) === compositeKey(a, b, c, 1)); - assert.ok(compositeKey(1, a) === compositeKey(1, a)); - assert.ok(compositeKey(1, a) !== compositeKey(a, 1)); - assert.ok(compositeKey(1, a, 2, b) === compositeKey(1, a, 2, b)); - assert.ok(compositeKey(1, a, 2, b) !== compositeKey(1, a, b, 2)); - assert.ok(compositeKey(1, 2, a, b) === compositeKey(1, 2, a, b)); - assert.ok(compositeKey(1, 2, a, b) !== compositeKey(1, a, b, 2)); - assert.ok(compositeKey(a, a) === compositeKey(a, a)); - assert.ok(compositeKey(a, a) !== compositeKey(a, ['a'])); - assert.ok(compositeKey(a, a) !== compositeKey(a, b)); - - assert.throws(() => compositeKey(), TypeError); - assert.throws(() => compositeKey(1, 2), TypeError); - assert.throws(() => compositeKey('foo', null, true), TypeError); -}); diff --git a/tests/pure/esnext.composite-symbol.js b/tests/pure/esnext.composite-symbol.js deleted file mode 100644 index 084d4c79a490..000000000000 --- a/tests/pure/esnext.composite-symbol.js +++ /dev/null @@ -1,41 +0,0 @@ -/* eslint-disable no-self-compare */ -import compositeSymbol from 'core-js-pure/features/composite-symbol'; -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('compositeSymbol', assert => { - assert.isFunction(compositeSymbol); - if (compositeSymbol.name) assert.name(compositeSymbol, 'compositeSymbol'); - - assert.ok(Object(compositeSymbol({})) instanceof Symbol); - - const a = ['a']; - const b = ['b']; - const c = ['c']; - - assert.ok(compositeSymbol(a) === compositeSymbol(a)); - assert.ok(compositeSymbol(a) !== compositeSymbol(['a'])); - assert.ok(compositeSymbol(a) !== compositeSymbol(a, 1)); - assert.ok(compositeSymbol(a) !== compositeSymbol(a, b)); - assert.ok(compositeSymbol(a, 1) === compositeSymbol(a, 1)); - assert.ok(compositeSymbol(a, b) === compositeSymbol(a, b)); - assert.ok(compositeSymbol(a, b) !== compositeSymbol(b, a)); - assert.ok(compositeSymbol(a, b, c) === compositeSymbol(a, b, c)); - assert.ok(compositeSymbol(a, b, c) !== compositeSymbol(c, b, a)); - assert.ok(compositeSymbol(a, b, c) !== compositeSymbol(a, c, b)); - assert.ok(compositeSymbol(a, b, c, 1) !== compositeSymbol(a, b, c)); - assert.ok(compositeSymbol(a, b, c, 1) === compositeSymbol(a, b, c, 1)); - assert.ok(compositeSymbol(1, a) === compositeSymbol(1, a)); - assert.ok(compositeSymbol(1, a) !== compositeSymbol(a, 1)); - assert.ok(compositeSymbol(1, a, 2, b) === compositeSymbol(1, a, 2, b)); - assert.ok(compositeSymbol(1, a, 2, b) !== compositeSymbol(1, a, b, 2)); - assert.ok(compositeSymbol(1, 2, a, b) === compositeSymbol(1, 2, a, b)); - assert.ok(compositeSymbol(1, 2, a, b) !== compositeSymbol(1, a, b, 2)); - assert.ok(compositeSymbol(a, a) === compositeSymbol(a, a)); - assert.ok(compositeSymbol(a, a) !== compositeSymbol(a, ['a'])); - assert.ok(compositeSymbol(a, a) !== compositeSymbol(a, b)); - assert.ok(compositeSymbol() === compositeSymbol()); - assert.ok(compositeSymbol(1, 2) === compositeSymbol(1, 2)); - assert.ok(compositeSymbol(1, 2) !== compositeSymbol(2, 1)); - assert.ok(compositeSymbol('foo', null, true) === compositeSymbol('foo', null, true)); - assert.ok(compositeSymbol('string') === Symbol.for('string')); -}); diff --git a/tests/pure/esnext.iterator.as-indexed-pairs.js b/tests/pure/esnext.iterator.as-indexed-pairs.js deleted file mode 100644 index e7a79c945696..000000000000 --- a/tests/pure/esnext.iterator.as-indexed-pairs.js +++ /dev/null @@ -1,18 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator#asIndexedPairs', assert => { - const { asIndexedPairs } = Iterator.prototype; - - assert.isFunction(asIndexedPairs); - assert.arity(asIndexedPairs, 0); - assert.nonEnumerable(Iterator.prototype, 'asIndexedPairs'); - - assert.arrayEqual(asIndexedPairs.call(createIterator(['a', 'b', 'c'])).toArray().toString(), '0,a,1,b,2,c', 'basic functionality'); - - assert.throws(() => asIndexedPairs.call(undefined, TypeError)); - assert.throws(() => asIndexedPairs.call(null, TypeError)); - assert.throws(() => asIndexedPairs.call({}, TypeError)); - assert.throws(() => asIndexedPairs.call([], TypeError)); -}); diff --git a/tests/pure/esnext.iterator.constructor.js b/tests/pure/esnext.iterator.constructor.js deleted file mode 100644 index bd338be031ee..000000000000 --- a/tests/pure/esnext.iterator.constructor.js +++ /dev/null @@ -1,22 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; -import Symbol from 'core-js-pure/features/symbol'; - -import { createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator', assert => { - assert.isFunction(Iterator); - assert.arity(Iterator, 0); - - assert.ok(Iterator.from(createIterator([1, 2, 3])) instanceof Iterator, 'From Proxy'); - - assert.ok(new Iterator() instanceof Iterator, 'constructor'); - assert.throws(() => Iterator(), 'throws w/o `new`'); -}); - -QUnit.test('Iterator#constructor', assert => { - assert.strictEqual(Iterator.prototype.constructor, Iterator, 'Iterator#constructor is Iterator'); -}); - -QUnit.test('Iterator#@@toStringTag', assert => { - assert.strictEqual(Iterator.prototype[Symbol.toStringTag], 'Iterator', 'Iterator::@@toStringTag is `Iterator`'); -}); diff --git a/tests/pure/esnext.iterator.drop.js b/tests/pure/esnext.iterator.drop.js deleted file mode 100644 index de35ea80e482..000000000000 --- a/tests/pure/esnext.iterator.drop.js +++ /dev/null @@ -1,22 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator#drop', assert => { - const { drop } = Iterator.prototype; - - assert.isFunction(drop); - assert.arity(drop, 1); - assert.nonEnumerable(Iterator.prototype, 'drop'); - - assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 1).toArray(), [2, 3], 'basic functionality'); - assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 1.5).toArray(), [2, 3], 'float'); - assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 4).toArray(), [], 'big'); - assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 0).toArray(), [1, 2, 3], 'zero'); - - assert.throws(() => drop.call(undefined, 1), TypeError); - assert.throws(() => drop.call(null, 1), TypeError); - assert.throws(() => drop.call({}, 1), TypeError); - assert.throws(() => drop.call([], 1), TypeError); - assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); -}); diff --git a/tests/pure/esnext.iterator.every.js b/tests/pure/esnext.iterator.every.js deleted file mode 100644 index 7115a6247e7d..000000000000 --- a/tests/pure/esnext.iterator.every.js +++ /dev/null @@ -1,28 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#every', assert => { - const { every } = Iterator.prototype; - - assert.isFunction(every); - assert.arity(every, 1); - assert.nonEnumerable(Iterator.prototype, 'every'); - - assert.ok(every.call(createIterator([1, 2, 3]), it => typeof it == 'number'), 'basic functionality #1'); - assert.ok(!every.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #2'); - every.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => every.call([], () => { /* empty */ }), TypeError); - assert.throws(() => every.call(createIterator([1]), undefined), TypeError); - assert.throws(() => every.call(createIterator([1]), null), TypeError); - assert.throws(() => every.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.iterator.filter.js b/tests/pure/esnext.iterator.filter.js deleted file mode 100644 index 1920401f401b..000000000000 --- a/tests/pure/esnext.iterator.filter.js +++ /dev/null @@ -1,27 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#filter', assert => { - const { filter } = Iterator.prototype; - - assert.isFunction(filter); - assert.arity(filter, 1); - assert.nonEnumerable(Iterator.prototype, 'filter'); - - assert.arrayEqual(filter.call(createIterator([1, 2, 3]), it => it % 2).toArray(), [1, 3], 'basic functionality'); - filter.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call([], () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(createIterator([1]), undefined), TypeError); - assert.throws(() => filter.call(createIterator([1]), null), TypeError); - assert.throws(() => filter.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.iterator.find.js b/tests/pure/esnext.iterator.find.js deleted file mode 100644 index 339587651098..000000000000 --- a/tests/pure/esnext.iterator.find.js +++ /dev/null @@ -1,27 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#find', assert => { - const { find } = Iterator.prototype; - - assert.isFunction(find); - assert.arity(find, 1); - assert.nonEnumerable(Iterator.prototype, 'find'); - - assert.same(find.call(createIterator([1, 2, 3]), it => !(it % 2)), 2, 'basic functionality'); - find.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => find.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => find.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => find.call([], () => { /* empty */ }), TypeError); - assert.throws(() => find.call(createIterator([1]), undefined), TypeError); - assert.throws(() => find.call(createIterator([1]), null), TypeError); - assert.throws(() => find.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.iterator.flat-map.js b/tests/pure/esnext.iterator.flat-map.js deleted file mode 100644 index a5f807e01627..000000000000 --- a/tests/pure/esnext.iterator.flat-map.js +++ /dev/null @@ -1,31 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator, createIterable } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#flatMap', assert => { - const { flatMap } = Iterator.prototype; - - assert.isFunction(flatMap); - assert.arity(flatMap, 1); - assert.nonEnumerable(Iterator.prototype, 'flatMap'); - - assert.arrayEqual( - flatMap.call(createIterator([1, [], 2, createIterable([3, 4]), [5, 6], 'ab']), it => typeof it == 'number' ? -it : it).toArray(), - [-1, -2, 3, 4, 5, 6, 'ab'], - 'basic functionality', - ); - flatMap.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - - assert.throws(() => flatMap.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call([], () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), undefined), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), null), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.iterator.for-each.js b/tests/pure/esnext.iterator.for-each.js deleted file mode 100644 index 212cabfb2a8c..000000000000 --- a/tests/pure/esnext.iterator.for-each.js +++ /dev/null @@ -1,32 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#forEach', assert => { - const { forEach } = Iterator.prototype; - - assert.isFunction(forEach); - assert.arity(forEach, 1); - assert.nonEnumerable(Iterator.prototype, 'forEach'); - - const array = []; - - forEach.call(createIterator([1, 2, 3]), it => array.push(it)); - - assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); - - forEach.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call([], () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call(createIterator([1]), undefined), TypeError); - assert.throws(() => forEach.call(createIterator([1]), null), TypeError); - assert.throws(() => forEach.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.iterator.from.js b/tests/pure/esnext.iterator.from.js deleted file mode 100644 index 85c2645b5604..000000000000 --- a/tests/pure/esnext.iterator.from.js +++ /dev/null @@ -1,20 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterable, createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator.from', assert => { - const { from } = Iterator; - - assert.isFunction(from); - assert.arity(from, 1); - - assert.ok(Iterator.from(createIterator([1, 2, 3])) instanceof Iterator, 'proxy, iterator'); - - assert.ok(Iterator.from(createIterable([1, 2, 3])) instanceof Iterator, 'proxy, iterable'); - - assert.arrayEqual(Iterator.from(createIterable([1, 2, 3])).toArray(), [1, 2, 3], 'just a proxy'); - - assert.throws(() => from(undefined), TypeError); - assert.throws(() => from(null), TypeError); - assert.throws(() => from({}), TypeError); -}); diff --git a/tests/pure/esnext.iterator.map.js b/tests/pure/esnext.iterator.map.js deleted file mode 100644 index 01617417588e..000000000000 --- a/tests/pure/esnext.iterator.map.js +++ /dev/null @@ -1,27 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#map', assert => { - const { map } = Iterator.prototype; - - assert.isFunction(map); - assert.arity(map, 1); - assert.nonEnumerable(Iterator.prototype, 'map'); - - assert.arrayEqual(map.call(createIterator([1, 2, 3]), it => it ** 2).toArray(), [1, 4, 9], 'basic functionality'); - map.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - - assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => map.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => map.call([], () => { /* empty */ }), TypeError); - assert.throws(() => map.call(createIterator([1]), undefined), TypeError); - assert.throws(() => map.call(createIterator([1]), null), TypeError); - assert.throws(() => map.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.iterator.reduce.js b/tests/pure/esnext.iterator.reduce.js deleted file mode 100644 index 8a4af9f4ecb1..000000000000 --- a/tests/pure/esnext.iterator.reduce.js +++ /dev/null @@ -1,29 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#reduce', assert => { - const { reduce } = Iterator.prototype; - - assert.isFunction(reduce); - assert.arity(reduce, 1); - assert.nonEnumerable(Iterator.prototype, 'reduce'); - - assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1), 7, 'basic functionality'); - assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b), 6, 'basic functionality, no init'); - reduce.call(createIterator([2]), function (a, b) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 2, 'arguments length'); - assert.same(a, 1, 'argument 1'); - assert.same(b, 2, 'argument 2'); - }, 1); - - assert.throws(() => reduce.call(undefined, (a, b) => a + b, 0), TypeError); - assert.throws(() => reduce.call(null, (a, b) => a + b, 0), TypeError); - assert.throws(() => reduce.call({}, (a, b) => a + b, 0), TypeError); - assert.throws(() => reduce.call([], (a, b) => a + b, 0), TypeError); - assert.throws(() => reduce.call(createIterator([1]), undefined, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), null, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), {}, 1), TypeError); -}); diff --git a/tests/pure/esnext.iterator.some.js b/tests/pure/esnext.iterator.some.js deleted file mode 100644 index 7c8e39a2f54c..000000000000 --- a/tests/pure/esnext.iterator.some.js +++ /dev/null @@ -1,28 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#some', assert => { - const { some } = Iterator.prototype; - - assert.isFunction(some); - assert.arity(some, 1); - assert.nonEnumerable(Iterator.prototype, 'some'); - - assert.ok(some.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #1'); - assert.ok(!some.call(createIterator([1, 2, 3]), it => typeof it == 'string'), 'basic functionality #2'); - some.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => some.call([], () => { /* empty */ }), TypeError); - assert.throws(() => some.call(createIterator([1]), undefined), TypeError); - assert.throws(() => some.call(createIterator([1]), null), TypeError); - assert.throws(() => some.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/pure/esnext.iterator.take.js b/tests/pure/esnext.iterator.take.js deleted file mode 100644 index a75e637afc21..000000000000 --- a/tests/pure/esnext.iterator.take.js +++ /dev/null @@ -1,22 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator#take', assert => { - const { take } = Iterator.prototype; - - assert.isFunction(take); - assert.arity(take, 1); - assert.nonEnumerable(Iterator.prototype, 'take'); - - assert.arrayEqual(take.call(createIterator([1, 2, 3]), 2).toArray(), [1, 2], 'basic functionality'); - assert.arrayEqual(take.call(createIterator([1, 2, 3]), 1.5).toArray(), [1], 'float'); - assert.arrayEqual(take.call(createIterator([1, 2, 3]), 4).toArray(), [1, 2, 3], 'big'); - assert.arrayEqual(take.call(createIterator([1, 2, 3]), 0).toArray(), [], 'zero'); - - assert.throws(() => take.call(undefined, 1), TypeError); - assert.throws(() => take.call(null, 1), TypeError); - assert.throws(() => take.call({}, 1), TypeError); - assert.throws(() => take.call([], 1), TypeError); - assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); -}); diff --git a/tests/pure/esnext.iterator.to-array.js b/tests/pure/esnext.iterator.to-array.js deleted file mode 100644 index 2a40ab4a96c3..000000000000 --- a/tests/pure/esnext.iterator.to-array.js +++ /dev/null @@ -1,21 +0,0 @@ -import Iterator from 'core-js-pure/features/iterator'; - -import { createIterable, createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator#toArray', assert => { - const { toArray } = Iterator.prototype; - - assert.isFunction(toArray); - assert.arity(toArray, 0); - assert.nonEnumerable(Iterator.prototype, 'toArray'); - - assert.arrayEqual(Iterator.from('123').toArray(), ['1', '2', '3']); - assert.arrayEqual(Iterator.from(createIterable([1, 2, 3])).toArray(), [1, 2, 3]); - - assert.arrayEqual(toArray.call(createIterator([1, 2, 3])), [1, 2, 3]); - - assert.throws(() => toArray.call(undefined), TypeError); - assert.throws(() => toArray.call(null), TypeError); - assert.throws(() => toArray.call({}), TypeError); - assert.throws(() => toArray.call([]), TypeError); -}); diff --git a/tests/pure/esnext.map.delete-all.js b/tests/pure/esnext.map.delete-all.js deleted file mode 100644 index 0ee8242f6b67..000000000000 --- a/tests/pure/esnext.map.delete-all.js +++ /dev/null @@ -1,31 +0,0 @@ -import Map from 'core-js-pure/features/map'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Map#deleteAll', assert => { - const { deleteAll } = Map.prototype; - - assert.isFunction(deleteAll); - assert.arity(deleteAll, 0); - assert.nonEnumerable(Map.prototype, 'deleteAll'); - - let set = new Map([[1, 2], [2, 3], [3, 4]]); - assert.same(set.deleteAll(1, 2), true); - assert.deepEqual(from(set), [[3, 4]]); - - set = new Map([[1, 2], [2, 3], [3, 4]]); - assert.same(set.deleteAll(3, 4), false); - assert.deepEqual(from(set), [[1, 2], [2, 3]]); - - set = new Map([[1, 2], [2, 3], [3, 4]]); - assert.same(set.deleteAll(4, 5), false); - assert.deepEqual(from(set), [[1, 2], [2, 3], [3, 4]]); - - set = new Map([[1, 2], [2, 3], [3, 4]]); - assert.same(set.deleteAll(), true); - assert.deepEqual(from(set), [[1, 2], [2, 3], [3, 4]]); - - assert.notThrows(() => !deleteAll.call({ delete() { /* empty */ } }, 1, 2, 3)); - assert.throws(() => deleteAll.call({}, 1, 2, 3), TypeError); - assert.throws(() => deleteAll.call(undefined, 1, 2, 3), TypeError); - assert.throws(() => deleteAll.call(null, 1, 2, 3), TypeError); -}); diff --git a/tests/pure/esnext.map.every.js b/tests/pure/esnext.map.every.js deleted file mode 100644 index 063682479fee..000000000000 --- a/tests/pure/esnext.map.every.js +++ /dev/null @@ -1,35 +0,0 @@ -import Map from 'core-js-pure/features/map'; - -QUnit.test('Map#every', assert => { - const { every } = Map.prototype; - assert.isFunction(every); - assert.arity(every, 1); - assert.name(every, 'every'); - assert.nonEnumerable(Map.prototype, 'every'); - - let map = new Map([[9, 1]]); - const context = {}; - map.every(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 9, 'correct index in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - map = new Map([[0, 1], [1, 2], [2, 3]]); - assert.ok(map.every(it => typeof it === 'number')); - assert.ok(map.every(it => it < 4)); - assert.ok(!map.every(it => it < 3)); - assert.ok(!map.every(it => typeof it === 'string')); - assert.ok(map.every(function () { - return +this === 1; - }, 1)); - let result = ''; - map.every((value, key) => result += key); - assert.ok(result === '012'); - assert.ok(map.every((value, key, that) => that === map)); - - assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.map.filter.js b/tests/pure/esnext.map.filter.js deleted file mode 100644 index 31c019cd750a..000000000000 --- a/tests/pure/esnext.map.filter.js +++ /dev/null @@ -1,44 +0,0 @@ -import Map from 'core-js-pure/features/map'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Map#filter', assert => { - const { filter } = Map.prototype; - - assert.isFunction(filter); - assert.arity(filter, 1); - assert.name(filter, 'filter'); - assert.nonEnumerable(Map.prototype, 'filter'); - - const map = new Map([[1, 2]]); - const context = {}; - map.filter(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.deepEqual(from(new Map([ - ['a', 1], - [1, 2], - ['b', 3], - [2, 'q'], - ['c', {}], - [3, 4], - ['d', true], - [4, 5], - ]).filter(it => typeof it === 'number')), [ - ['a', 1], - [1, 2], - ['b', 3], - [3, 4], - [4, 5], - ]); - - assert.ok(new Map().filter(it => it) instanceof Map); - - assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.map.from.js b/tests/pure/esnext.map.from.js deleted file mode 100644 index e59039048ab7..000000000000 --- a/tests/pure/esnext.map.from.js +++ /dev/null @@ -1,30 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Map from 'core-js-pure/features/map'; -import toArray from 'core-js-pure/features/array/from'; - -QUnit.test('Map.from', assert => { - const { from } = Map; - assert.isFunction(from); - assert.arity(from, 1); - assert.ok(Map.from() instanceof Map); - assert.deepEqual(toArray(Map.from([])), []); - assert.deepEqual(toArray(Map.from([[1, 2]])), [[1, 2]]); - assert.deepEqual(toArray(Map.from([[1, 2], [2, 3], [1, 4]])), [[1, 4], [2, 3]]); - assert.deepEqual(toArray(Map.from(createIterable([[1, 2], [2, 3], [1, 4]]))), [[1, 4], [2, 3]]); - const pair = [1, 2]; - const context = {}; - Map.from([pair], function (element, index) { - assert.same(element, pair); - assert.same(index, 0); - assert.same(this, context); - return element; - }, context); - assert.throws(() => from([1, 2])); - let arg = null; - function F(it) { - return arg = it; - } - from.call(F, createIterable([1, 2, 3]), it => it ** 2); - assert.deepEqual(arg, [1, 4, 9]); -}); diff --git a/tests/pure/esnext.map.group-by.js b/tests/pure/esnext.map.group-by.js deleted file mode 100644 index 8e1a8b9e02db..000000000000 --- a/tests/pure/esnext.map.group-by.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Map from 'core-js-pure/features/map'; -import toArray from 'core-js-pure/features/array/from'; - -QUnit.test('Map.groupBy', assert => { - const { groupBy } = Map; - - assert.isFunction(groupBy); - assert.arity(groupBy, 2); - assert.name(groupBy, 'groupBy'); - - assert.ok(Map.groupBy([], it => it) instanceof Map); - - assert.deepEqual(toArray(Map.groupBy([], it => it)), []); - assert.deepEqual(toArray(Map.groupBy([1, 2], it => it ** 2)), [[1, [1]], [4, [2]]]); - assert.deepEqual(toArray(Map.groupBy([1, 2, 1], it => it ** 2)), [[1, [1, 1]], [4, [2]]]); - assert.deepEqual(toArray(Map.groupBy(createIterable([1, 2]), it => it ** 2)), [[1, [1]], [4, [2]]]); - - const element = {}; - Map.groupBy([element], it => assert.same(it, element)); - - assert.throws(() => groupBy([1, 2], it => it)); -}); diff --git a/tests/pure/esnext.map.includes.js b/tests/pure/esnext.map.includes.js deleted file mode 100644 index 90c92bbf260f..000000000000 --- a/tests/pure/esnext.map.includes.js +++ /dev/null @@ -1,24 +0,0 @@ -import Map from 'core-js-pure/features/map'; - -QUnit.test('Map#includes', assert => { - const { includes } = Map.prototype; - assert.isFunction(includes); - assert.name(includes, 'includes'); - assert.arity(includes, 1); - assert.nonEnumerable(Map.prototype, 'includes'); - - const object = {}; - const map = new Map([[1, 1], [2, 2], [3, 3], [4, -0], [5, object], [6, NaN]]); - assert.ok(map.includes(1)); - assert.ok(map.includes(-0)); - assert.ok(map.includes(0)); - assert.ok(map.includes(object)); - assert.ok(!map.includes(4)); - assert.ok(!map.includes(-0.5)); - assert.ok(!map.includes({})); - assert.ok(map.includes(NaN)); - - assert.throws(() => includes.call({}, 1), TypeError); - assert.throws(() => includes.call(undefined, 1), TypeError); - assert.throws(() => includes.call(null, 1), TypeError); -}); diff --git a/tests/pure/esnext.map.key-by.js b/tests/pure/esnext.map.key-by.js deleted file mode 100644 index 541d2e7079ec..000000000000 --- a/tests/pure/esnext.map.key-by.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Map from 'core-js-pure/features/map'; -import toArray from 'core-js-pure/features/array/from'; - -QUnit.test('Map.keyBy', assert => { - const { keyBy } = Map; - - assert.isFunction(keyBy); - assert.arity(keyBy, 2); - assert.name(keyBy, 'keyBy'); - - assert.ok(Map.keyBy([], it => it) instanceof Map); - - assert.deepEqual(toArray(Map.keyBy([], it => it)), []); - assert.deepEqual(toArray(Map.keyBy([1, 2], it => it ** 2)), [[1, 1], [4, 2]]); - assert.deepEqual(toArray(Map.keyBy([1, 2, 1], it => it ** 2)), [[1, 1], [4, 2]]); - assert.deepEqual(toArray(Map.keyBy(createIterable([1, 2]), it => it ** 2)), [[1, 1], [4, 2]]); - - const element = {}; - Map.keyBy([element], it => assert.same(it, element)); - - assert.throws(() => keyBy([1, 2], it => it)); -}); diff --git a/tests/pure/esnext.map.map-keys.js b/tests/pure/esnext.map.map-keys.js deleted file mode 100644 index 16b74f642ed3..000000000000 --- a/tests/pure/esnext.map.map-keys.js +++ /dev/null @@ -1,47 +0,0 @@ -import Map from 'core-js-pure/features/map'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Map#mapKeys', assert => { - const { mapKeys } = Map.prototype; - - assert.isFunction(mapKeys); - assert.arity(mapKeys, 1); - assert.name(mapKeys, 'mapKeys'); - assert.nonEnumerable(Map.prototype, 'mapKeys'); - - const map = new Map([[1, 2]]); - const context = {}; - map.mapKeys(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Map().mapKeys(it => it) instanceof Map); - - assert.deepEqual(from(new Map([ - ['a', 1], - [1, 2], - ['b', 3], - [2, 'q'], - ['c', {}], - [3, 4], - ['d', true], - [4, 5], - ]).mapKeys((value, key) => `${ key }${ value }`)), [ - ['a1', 1], - ['12', 2], - ['b3', 3], - ['2q', 'q'], - ['c[object Object]', {}], - ['34', 4], - ['dtrue', true], - ['45', 5], - ]); - - assert.throws(() => mapKeys.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => mapKeys.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => mapKeys.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.map.map-values.js b/tests/pure/esnext.map.map-values.js deleted file mode 100644 index de7527686ae0..000000000000 --- a/tests/pure/esnext.map.map-values.js +++ /dev/null @@ -1,47 +0,0 @@ -import Map from 'core-js-pure/features/map'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Map#mapValues', assert => { - const { mapValues } = Map.prototype; - - assert.isFunction(mapValues); - assert.arity(mapValues, 1); - assert.name(mapValues, 'mapValues'); - assert.nonEnumerable(Map.prototype, 'mapValues'); - - const map = new Map([[1, 2]]); - const context = {}; - map.mapValues(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Map().mapValues(it => it) instanceof Map); - - assert.deepEqual(from(new Map([ - ['a', 1], - [1, 2], - ['b', 3], - [2, 'q'], - ['c', {}], - [3, 4], - ['d', true], - [4, 5], - ]).mapValues((value, key) => `${ key }${ value }`)), [ - ['a', 'a1'], - [1, '12'], - ['b', 'b3'], - [2, '2q'], - ['c', 'c[object Object]'], - [3, '34'], - ['d', 'dtrue'], - [4, '45'], - ]); - - assert.throws(() => mapValues.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => mapValues.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => mapValues.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.map.merge.js b/tests/pure/esnext.map.merge.js deleted file mode 100644 index fdd8b38cd2bf..000000000000 --- a/tests/pure/esnext.map.merge.js +++ /dev/null @@ -1,26 +0,0 @@ -import Map from 'core-js-pure/features/map'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Map#merge', assert => { - const { merge } = Map.prototype; - - assert.isFunction(merge); - assert.arity(merge, 1); - assert.name(merge, 'merge'); - assert.nonEnumerable(Map.prototype, 'merge'); - - const map = new Map([[1, 2]]); - const result = map.merge([[3, 4]]); - assert.ok(result === map); - assert.ok(result instanceof Map); - - assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[5, 6]])), [[1, 2], [3, 4], [5, 6]]); - assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[3, 5], [5, 6]])), [[1, 2], [3, 5], [5, 6]]); - assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([])), [[1, 2], [3, 4]]); - - assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[3, 5]], [[5, 6]])), [[1, 2], [3, 5], [5, 6]]); - - assert.throws(() => merge.call({}, [[1, 2]]), TypeError); - assert.throws(() => merge.call(undefined, [[1, 2]]), TypeError); - assert.throws(() => merge.call(null, [[1, 2]]), TypeError); -}); diff --git a/tests/pure/esnext.map.of.js b/tests/pure/esnext.map.of.js deleted file mode 100644 index d6d4e98e77e2..000000000000 --- a/tests/pure/esnext.map.of.js +++ /dev/null @@ -1,18 +0,0 @@ -import Map from 'core-js-pure/features/map'; -import toArray from 'core-js-pure/features/array/from'; - -QUnit.test('Map.of', assert => { - const { of } = Map; - assert.isFunction(of); - assert.arity(of, 0); - assert.ok(Map.of() instanceof Map); - assert.deepEqual(toArray(Map.of([1, 2])), [[1, 2]]); - assert.deepEqual(toArray(Map.of([1, 2], [2, 3], [1, 4])), [[1, 4], [2, 3]]); - assert.throws(() => of(1)); - let arg = null; - function F(it) { - return arg = it; - } - of.call(F, 1, 2, 3); - assert.deepEqual(arg, [1, 2, 3]); -}); diff --git a/tests/pure/esnext.map.some.js b/tests/pure/esnext.map.some.js deleted file mode 100644 index 5db731077a98..000000000000 --- a/tests/pure/esnext.map.some.js +++ /dev/null @@ -1,38 +0,0 @@ -import Map from 'core-js-pure/features/map'; - -QUnit.test('Map#some', assert => { - const { some } = Map.prototype; - assert.isFunction(some); - assert.arity(some, 1); - assert.name(some, 'some'); - assert.nonEnumerable(Map.prototype, 'some'); - - let map = new Map([[9, 1]]); - const context = {}; - map.some(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 9, 'correct index in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - map = new Map([[0, 1], [1, '2'], [2, 3]]); - assert.ok(map.some(it => typeof it === 'number')); - assert.ok(map.some(it => it < 3)); - assert.ok(!map.some(it => it < 0)); - assert.ok(map.some(it => typeof it === 'string')); - assert.ok(!map.some(function () { - return +this !== 1; - }, 1)); - let result = ''; - map.some((value, key) => { - result += key; - return false; - }); - assert.same(result, '012'); - assert.ok(map.some((value, key, that) => that === map)); - - assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.map.update-or-insert.js b/tests/pure/esnext.map.update-or-insert.js deleted file mode 100644 index 881796b669cf..000000000000 --- a/tests/pure/esnext.map.update-or-insert.js +++ /dev/null @@ -1,38 +0,0 @@ -import Map from 'core-js-pure/features/map'; - -QUnit.test('Map#updateOrInsert', assert => { - const { updateOrInsert } = Map.prototype; - assert.isFunction(updateOrInsert); - assert.arity(updateOrInsert, 2); - assert.name(updateOrInsert, 'upsert'); - assert.nonEnumerable(Map.prototype, 'updateOrInsert'); - - const map = new Map([['a', 2]]); - assert.same(map.updateOrInsert('a', function (value) { - assert.same(arguments.length, 1, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - return value ** 2; - }, () => { - assert.ok(false, 'should not be called'); - return 3; - }), 4, 'returns a correct value'); - assert.same(map.updateOrInsert('b', value => { - assert.ok(false, 'should not be called'); - return value ** 2; - }, function () { - assert.same(arguments.length, 0, 'correct number of callback arguments'); - return 3; - }), 3, 'returns a correct value'); - assert.same(map.size, 2, 'correct size'); - assert.same(map.get('a'), 4, 'correct result #1'); - assert.same(map.get('b'), 3, 'correct result #2'); - - assert.same(new Map([['a', 2]]).updateOrInsert('b', null, () => 3), 3); - assert.same(new Map([['a', 2]]).updateOrInsert('a', value => value ** 2), 4); - - assert.throws(() => new Map().updateOrInsert('a'), TypeError); - assert.throws(() => updateOrInsert.call({}, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => updateOrInsert.call([], 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => updateOrInsert.call(undefined, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => updateOrInsert.call(null, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.map.upsert.js b/tests/pure/esnext.map.upsert.js deleted file mode 100644 index 08c5255f154a..000000000000 --- a/tests/pure/esnext.map.upsert.js +++ /dev/null @@ -1,38 +0,0 @@ -import Map from 'core-js-pure/features/map'; - -QUnit.test('Map#upsert', assert => { - const { upsert } = Map.prototype; - assert.isFunction(upsert); - assert.arity(upsert, 2); - assert.name(upsert, 'upsert'); - assert.nonEnumerable(Map.prototype, 'upsert'); - - const map = new Map([['a', 2]]); - assert.same(map.upsert('a', function (value) { - assert.same(arguments.length, 1, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - return value ** 2; - }, () => { - assert.ok(false, 'should not be called'); - return 3; - }), 4, 'returns a correct value'); - assert.same(map.upsert('b', value => { - assert.ok(false, 'should not be called'); - return value ** 2; - }, function () { - assert.same(arguments.length, 0, 'correct number of callback arguments'); - return 3; - }), 3, 'returns a correct value'); - assert.same(map.size, 2, 'correct size'); - assert.same(map.get('a'), 4, 'correct result #1'); - assert.same(map.get('b'), 3, 'correct result #2'); - - assert.same(new Map([['a', 2]]).upsert('b', null, () => 3), 3); - assert.same(new Map([['a', 2]]).upsert('a', value => value ** 2), 4); - - assert.throws(() => new Map().upsert('a'), TypeError); - assert.throws(() => upsert.call({}, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call([], 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call(undefined, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call(null, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.math.clamp.js b/tests/pure/esnext.math.clamp.js deleted file mode 100644 index fd055f6bcf00..000000000000 --- a/tests/pure/esnext.math.clamp.js +++ /dev/null @@ -1,9 +0,0 @@ -import clamp from 'core-js-pure/features/math/clamp'; - -QUnit.test('Math.clamp', assert => { - assert.isFunction(clamp); - assert.arity(clamp, 3); - assert.same(clamp(2, 4, 6), 4); - assert.same(clamp(4, 2, 6), 4); - assert.same(clamp(6, 2, 4), 4); -}); diff --git a/tests/pure/esnext.math.deg-per-rad.js b/tests/pure/esnext.math.deg-per-rad.js deleted file mode 100644 index d2b4ee9aa91c..000000000000 --- a/tests/pure/esnext.math.deg-per-rad.js +++ /dev/null @@ -1,5 +0,0 @@ -import DEG_PER_RAD from 'core-js-pure/features/math/deg-per-rad'; - -QUnit.test('Math.DEG_PER_RAD', assert => { - assert.strictEqual(DEG_PER_RAD, Math.PI / 180, 'Is Math.PI / 180'); -}); diff --git a/tests/pure/esnext.math.degrees.js b/tests/pure/esnext.math.degrees.js deleted file mode 100644 index 3df96d052407..000000000000 --- a/tests/pure/esnext.math.degrees.js +++ /dev/null @@ -1,10 +0,0 @@ -import degrees from 'core-js-pure/features/math/degrees'; - -QUnit.test('Math.degrees', assert => { - assert.isFunction(degrees); - assert.arity(degrees, 1); - assert.same(degrees(0), 0); - assert.same(degrees(Math.PI / 2), 90); - assert.same(degrees(Math.PI), 180); - assert.same(degrees(3 * Math.PI / 2), 270); -}); diff --git a/tests/pure/esnext.math.fscale.js b/tests/pure/esnext.math.fscale.js deleted file mode 100644 index 7f8a347df18e..000000000000 --- a/tests/pure/esnext.math.fscale.js +++ /dev/null @@ -1,10 +0,0 @@ -import fscale from 'core-js-pure/features/math/fscale'; - -QUnit.test('Math.fscale', assert => { - assert.isFunction(fscale); - assert.arity(fscale, 5); - assert.same(fscale(3, 1, 2, 1, 2), 3); - assert.same(fscale(0, 3, 5, 8, 10), 5); - assert.same(fscale(1, 1, 1, 1, 1), NaN); - assert.same(fscale(-1, -1, -1, -1, -1), NaN); -}); diff --git a/tests/pure/esnext.math.rad-per-deg.js b/tests/pure/esnext.math.rad-per-deg.js deleted file mode 100644 index 6c744030ca90..000000000000 --- a/tests/pure/esnext.math.rad-per-deg.js +++ /dev/null @@ -1,5 +0,0 @@ -import RAD_PER_DEG from 'core-js-pure/features/math/rad-per-deg'; - -QUnit.test('Math.RAD_PER_DEG', assert => { - assert.strictEqual(RAD_PER_DEG, 180 / Math.PI, 'Is 180 / Math.PI'); -}); diff --git a/tests/pure/esnext.math.radians.js b/tests/pure/esnext.math.radians.js deleted file mode 100644 index f974f155aa96..000000000000 --- a/tests/pure/esnext.math.radians.js +++ /dev/null @@ -1,10 +0,0 @@ -import radians from 'core-js-pure/features/math/radians'; - -QUnit.test('Math.radians', assert => { - assert.isFunction(radians); - assert.arity(radians, 1); - assert.same(radians(0), 0); - assert.same(radians(90), Math.PI / 2); - assert.same(radians(180), Math.PI); - assert.same(radians(270), 3 * Math.PI / 2); -}); diff --git a/tests/pure/esnext.math.scale.js b/tests/pure/esnext.math.scale.js deleted file mode 100644 index 3ca41ff9cfbd..000000000000 --- a/tests/pure/esnext.math.scale.js +++ /dev/null @@ -1,10 +0,0 @@ -import scale from 'core-js-pure/features/math/scale'; - -QUnit.test('Math.scale', assert => { - assert.isFunction(scale); - assert.arity(scale, 5); - assert.same(scale(3, 1, 2, 1, 2), 3); - assert.same(scale(0, 3, 5, 8, 10), 5); - assert.same(scale(1, 1, 1, 1, 1), NaN); - assert.same(scale(-1, -1, -1, -1, -1), NaN); -}); diff --git a/tests/pure/esnext.math.signbit.js b/tests/pure/esnext.math.signbit.js deleted file mode 100644 index 9e29c8e08580..000000000000 --- a/tests/pure/esnext.math.signbit.js +++ /dev/null @@ -1,15 +0,0 @@ -import signbit from 'core-js-pure/features/math/signbit'; - -QUnit.test('Math.signbit', assert => { - assert.isFunction(signbit); - assert.same(signbit(NaN), NaN); - assert.same(signbit(), NaN); - assert.same(signbit(-0), false); - assert.same(signbit(0), true); - assert.strictEqual(signbit(Infinity), true); - assert.strictEqual(signbit(-Infinity), false); - assert.strictEqual(signbit(13510798882111488), true); - assert.strictEqual(signbit(-13510798882111488), false); - assert.strictEqual(signbit(42.5), true); - assert.strictEqual(signbit(-42.5), false); -}); diff --git a/tests/pure/esnext.number.from-string.js b/tests/pure/esnext.number.from-string.js deleted file mode 100644 index 7c6b2f1bfd03..000000000000 --- a/tests/pure/esnext.number.from-string.js +++ /dev/null @@ -1,37 +0,0 @@ -import fromString from 'core-js-pure/features/number/from-string'; - -QUnit.test('Number.fromString', assert => { - assert.isFunction(fromString); - assert.name(fromString, 'fromString'); - assert.arity(fromString, 2); - assert.throws(() => fromString(undefined), TypeError, 'The first argument should be a string #1'); - assert.throws(() => fromString(Object('10')), TypeError, 'The first argument should be a string #1'); - assert.throws(() => fromString(''), SyntaxError, 'Empty string'); - assert.same(fromString('-10', 2), -2, 'Works with negative numbers'); - assert.throws(() => fromString('-'), SyntaxError, '-'); - assert.same(fromString('10'), 10, 'Default radix is 10 #1'); - assert.same(fromString('10', undefined), 10, 'Default radix is 10 #2'); - for (let radix = 2; radix <= 36; ++radix) { - assert.same(fromString('10', radix), radix, `Radix ${ radix }`); - } - assert.throws(() => fromString('10', -4294967294), RangeError, 'Radix uses ToInteger #1'); - assert.same(fromString('10', 2.5), 2, 'Radix uses ToInteger #2'); - assert.same(fromString('42'), 42); - assert.same(fromString('42', 10), 42); - assert.throws(() => fromString('0xc0ffee'), SyntaxError); - assert.throws(() => fromString('0o755'), SyntaxError); - assert.throws(() => fromString('0b00101010'), SyntaxError); - assert.throws(() => fromString('C0FFEE', 16), SyntaxError); - assert.same(fromString('c0ffee', 16), 12648430); - assert.same(fromString('755', 8), 493); - assert.throws(() => fromString(''), SyntaxError); - assert.throws(() => fromString(' '), SyntaxError); - assert.throws(() => fromString(' 1'), SyntaxError); - assert.throws(() => fromString(' \n '), SyntaxError); - assert.throws(() => fromString('x'), SyntaxError); - assert.throws(() => fromString('1234', 0), RangeError); - assert.throws(() => fromString('1234', 1), RangeError); - assert.throws(() => fromString('1234', 37), RangeError); - assert.throws(() => fromString('010'), SyntaxError); - assert.throws(() => fromString('1_000_000_000'), SyntaxError); -}); diff --git a/tests/pure/esnext.observable.js b/tests/pure/esnext.observable.js deleted file mode 100644 index 2642cacb98ab..000000000000 --- a/tests/pure/esnext.observable.js +++ /dev/null @@ -1,55 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import { Observable, Symbol } from 'core-js-pure'; - -QUnit.test('Observable', assert => { - assert.isFunction(Observable); - assert.arity(Observable, 1); - assert.throws(() => Observable(() => { /* empty */ }), 'throws w/o `new`'); - const observable = new Observable(function (subscriptionObserver) { - assert.same(typeof subscriptionObserver, 'object', 'Subscription observer is object'); - assert.same(subscriptionObserver.constructor, Object); - const { next, error, complete } = subscriptionObserver; - assert.isFunction(next); - assert.isFunction(error); - assert.isFunction(complete); - assert.arity(next, 1); - assert.arity(error, 1); - assert.arity(complete, 0); - if (STRICT) { - assert.same(this, undefined, 'correct executor context'); - } - }); - observable.subscribe({}); - assert.ok(observable instanceof Observable); -}); - -QUnit.test('Observable#subscribe', assert => { - assert.isFunction(Observable.prototype.subscribe); - assert.arity(Observable.prototype.subscribe, 1); - const subscription = new Observable(() => { /* empty */ }).subscribe({}); - assert.same(typeof subscription, 'object', 'Subscription is object'); - assert.same(subscription.constructor, Object); - assert.isFunction(subscription.unsubscribe); - assert.arity(subscription.unsubscribe, 0); -}); - -QUnit.test('Observable#constructor', assert => { - assert.same(Observable.prototype.constructor, Observable); -}); - -QUnit.test('Observable#@@observable', assert => { - assert.isFunction(Observable.prototype[Symbol.observable]); - const observable = new Observable(() => { /* empty*/ }); - assert.same(observable[Symbol.observable](), observable); -}); - -QUnit.test('Observable.of', assert => { - assert.isFunction(Observable.of); - assert.arity(Observable.of, 0); -}); - -QUnit.test('Observable.from', assert => { - assert.isFunction(Observable.from); - assert.arity(Observable.from, 1); -}); diff --git a/tests/pure/esnext.promise.any.js b/tests/pure/esnext.promise.any.js deleted file mode 100644 index 613d6239c7ff..000000000000 --- a/tests/pure/esnext.promise.any.js +++ /dev/null @@ -1,53 +0,0 @@ -import { AggregateError, Promise } from 'core-js-pure/features'; - -QUnit.test('Promise.any', assert => { - assert.isFunction(Promise.any); - assert.arity(Promise.any, 1); - assert.ok(Promise.any([1, 2, 3]) instanceof Promise, 'returns a promise'); -}); - -QUnit.test('Promise.any, resolved', assert => { - assert.expect(1); - const async = assert.async(); - Promise.any([ - Promise.resolve(1), - Promise.reject(2), - Promise.resolve(3), - ]).then(it => { - assert.same(it, 1, 'resolved with a correct value'); - async(); - }); -}); - -QUnit.test('Promise.any, rejected #1', assert => { - assert.expect(2); - const async = assert.async(); - Promise.any([ - Promise.reject(1), - Promise.reject(2), - Promise.reject(3), - ]).catch(error => { - assert.ok(error instanceof AggregateError, 'instanceof AggregateError'); - assert.deepEqual(error.errors, [1, 2, 3], 'rejected with a correct value'); - async(); - }); -}); - -QUnit.test('Promise.any, rejected #2', assert => { - assert.expect(1); - const async = assert.async(); - Promise.any().catch(() => { - assert.ok(true, 'rejected as expected'); - async(); - }); -}); - -QUnit.test('Promise.any, rejected #3', assert => { - assert.expect(2); - const async = assert.async(); - Promise.any([]).catch(error => { - assert.ok(error instanceof AggregateError, 'instanceof AggregateError'); - assert.deepEqual(error.errors, [], 'rejected with a correct value'); - async(); - }); -}); diff --git a/tests/pure/esnext.promise.try.js b/tests/pure/esnext.promise.try.js deleted file mode 100644 index cad2828b435a..000000000000 --- a/tests/pure/esnext.promise.try.js +++ /dev/null @@ -1,27 +0,0 @@ -import Promise from 'core-js-pure/features/promise'; - -QUnit.test('Promise.try', assert => { - assert.isFunction(Promise.try); - assert.arity(Promise.try, 1); - assert.ok(Promise.try(() => 42) instanceof Promise, 'returns a promise'); -}); - -QUnit.test('Promise.try, resolved', assert => { - assert.expect(1); - const async = assert.async(); - Promise.try(() => 42).then(it => { - assert.same(it, 42, 'resolved with a correct value'); - async(); - }); -}); - -QUnit.test('Promise.try, rejected', assert => { - assert.expect(1); - const async = assert.async(); - Promise.try(() => { - throw new Error(); - }).catch(() => { - assert.ok(true, 'rejected as expected'); - async(); - }); -}); diff --git a/tests/pure/esnext.reflect.delete-metadata.js b/tests/pure/esnext.reflect.delete-metadata.js deleted file mode 100644 index 417f1fecf239..000000000000 --- a/tests/pure/esnext.reflect.delete-metadata.js +++ /dev/null @@ -1,19 +0,0 @@ -import { defineMetadata, hasOwnMetadata, deleteMetadata } from 'core-js-pure/features/reflect'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Reflect.deleteMetadata', assert => { - assert.isFunction(deleteMetadata); - assert.arity(deleteMetadata, 2); - assert.throws(() => deleteMetadata('key', undefined, undefined), TypeError); - assert.same(deleteMetadata('key', {}, undefined), false); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.same(deleteMetadata('key', object, undefined), true); - const prototype = {}; - defineMetadata('key', 'value', prototype, undefined); - assert.same(deleteMetadata('key', create(prototype), undefined), false); - object = {}; - defineMetadata('key', 'value', object, undefined); - deleteMetadata('key', object, undefined); - assert.same(hasOwnMetadata('key', object, undefined), false); -}); diff --git a/tests/pure/esnext.reflect.get-metadata-keys.js b/tests/pure/esnext.reflect.get-metadata-keys.js deleted file mode 100644 index 9003d0658ecd..000000000000 --- a/tests/pure/esnext.reflect.get-metadata-keys.js +++ /dev/null @@ -1,51 +0,0 @@ -import { defineMetadata, getMetadataKeys } from 'core-js-pure/features/reflect'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Reflect.getMetadataKeys', assert => { - assert.isFunction(getMetadataKeys); - assert.arity(getMetadataKeys, 1); - assert.throws(() => getMetadataKeys(undefined, undefined), TypeError); - assert.deepEqual(getMetadataKeys({}, undefined), []); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key']); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key']); - object = {}; - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1']); - object = {}; - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - defineMetadata('key0', 'value', object, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1']); - prototype = {}; - defineMetadata('key2', 'value', prototype, undefined); - object = create(prototype); - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1', 'key2']); - object = {}; - assert.deepEqual(getMetadataKeys({}, 'name'), []); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.deepEqual(getMetadataKeys(object, 'name'), ['key']); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.deepEqual(getMetadataKeys(object, 'name'), ['key']); - object = {}; - defineMetadata('key0', 'value', object, 'name'); - defineMetadata('key1', 'value', object, 'name'); - defineMetadata('key0', 'value', object, 'name'); - assert.deepEqual(getMetadataKeys(object, 'name'), ['key0', 'key1']); - prototype = {}; - defineMetadata('key2', 'value', prototype, 'name'); - object = create(prototype); - defineMetadata('key0', 'value', object, 'name'); - defineMetadata('key1', 'value', object, 'name'); - assert.deepEqual(getMetadataKeys(object, 'name'), ['key0', 'key1', 'key2']); -}); diff --git a/tests/pure/esnext.reflect.get-own-matadata.js b/tests/pure/esnext.reflect.get-own-matadata.js deleted file mode 100644 index 8008c31868cb..000000000000 --- a/tests/pure/esnext.reflect.get-own-matadata.js +++ /dev/null @@ -1,24 +0,0 @@ -import { defineMetadata, getOwnMetadata } from 'core-js-pure/features/reflect'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Reflect.getOwnMetadata', assert => { - assert.isFunction(getOwnMetadata); - assert.arity(getOwnMetadata, 2); - assert.throws(() => getOwnMetadata('key', undefined, undefined), TypeError); - assert.same(getOwnMetadata('key', {}, undefined), undefined); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.same(getOwnMetadata('key', object, undefined), 'value'); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.same(getOwnMetadata('key', object, undefined), undefined); - assert.same(getOwnMetadata('key', {}, 'name'), undefined); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.same(getOwnMetadata('key', object, 'name'), 'value'); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.same(getOwnMetadata('key', object, 'name'), undefined); -}); diff --git a/tests/pure/esnext.reflect.get-own-metadata-keys.js b/tests/pure/esnext.reflect.get-own-metadata-keys.js deleted file mode 100644 index 91ef047a168b..000000000000 --- a/tests/pure/esnext.reflect.get-own-metadata-keys.js +++ /dev/null @@ -1,51 +0,0 @@ -import { defineMetadata, getOwnMetadataKeys } from 'core-js-pure/features/reflect'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Reflect.getOwnMetadataKeys', assert => { - assert.isFunction(getOwnMetadataKeys); - assert.arity(getOwnMetadataKeys, 1); - assert.throws(() => getOwnMetadataKeys(undefined, undefined), TypeError); - assert.deepEqual(getOwnMetadataKeys({}, undefined), []); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key']); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), []); - object = {}; - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); - object = {}; - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - defineMetadata('key0', 'value', object, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); - prototype = {}; - defineMetadata('key2', 'value', prototype, undefined); - object = create(prototype); - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); - object = {}; - assert.deepEqual(getOwnMetadataKeys({}, 'name'), []); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key']); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.deepEqual(getOwnMetadataKeys(object, 'name'), []); - object = {}; - defineMetadata('key0', 'value', object, 'name'); - defineMetadata('key1', 'value', object, 'name'); - defineMetadata('key0', 'value', object, 'name'); - assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key0', 'key1']); - prototype = {}; - defineMetadata('key2', 'value', prototype, 'name'); - object = create(prototype); - defineMetadata('key0', 'value', object, 'name'); - defineMetadata('key1', 'value', object, 'name'); - assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key0', 'key1']); -}); diff --git a/tests/pure/esnext.reflect.has-metadata.js b/tests/pure/esnext.reflect.has-metadata.js deleted file mode 100644 index 5c3a5608cf80..000000000000 --- a/tests/pure/esnext.reflect.has-metadata.js +++ /dev/null @@ -1,24 +0,0 @@ -import { defineMetadata, hasMetadata } from 'core-js-pure/features/reflect'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Reflect.hasMetadata', assert => { - assert.isFunction(hasMetadata); - assert.arity(hasMetadata, 2); - assert.throws(() => hasMetadata('key', undefined, undefined), TypeError); - assert.same(hasMetadata('key', {}, undefined), false); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.same(hasMetadata('key', object, undefined), true); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.same(hasMetadata('key', object, undefined), true); - assert.same(hasMetadata('key', {}, 'name'), false); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.same(hasMetadata('key', object, 'name'), true); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.same(hasMetadata('key', object, 'name'), true); -}); diff --git a/tests/pure/esnext.reflect.has-own-metadata.js b/tests/pure/esnext.reflect.has-own-metadata.js deleted file mode 100644 index d03d236644a5..000000000000 --- a/tests/pure/esnext.reflect.has-own-metadata.js +++ /dev/null @@ -1,24 +0,0 @@ -import { defineMetadata, hasOwnMetadata } from 'core-js-pure/features/reflect'; -import create from 'core-js-pure/features/object/create'; - -QUnit.test('Reflect.hasOwnMetadata', assert => { - assert.isFunction(hasOwnMetadata); - assert.arity(hasOwnMetadata, 2); - assert.throws(() => hasOwnMetadata('key', undefined, undefined), TypeError); - assert.same(hasOwnMetadata('key', {}, undefined), false); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.same(hasOwnMetadata('key', object, undefined), true); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.same(hasOwnMetadata('key', object, undefined), false); - assert.same(hasOwnMetadata('key', {}, 'name'), false); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.same(hasOwnMetadata('key', object, 'name'), true); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.same(hasOwnMetadata('key', object, 'name'), false); -}); diff --git a/tests/pure/esnext.reflect.metadata.js b/tests/pure/esnext.reflect.metadata.js deleted file mode 100644 index 38fe4f28208c..000000000000 --- a/tests/pure/esnext.reflect.metadata.js +++ /dev/null @@ -1,15 +0,0 @@ -import { metadata, hasOwnMetadata } from 'core-js-pure/features/reflect'; - -QUnit.test('Reflect.metadata', assert => { - assert.isFunction(metadata); - assert.arity(metadata, 2); - assert.isFunction(metadata('key', 'value')); - const decorator = metadata('key', 'value'); - assert.throws(() => decorator(undefined, 'name'), TypeError); - let target = function () { /* empty */ }; - decorator(target); - assert.same(hasOwnMetadata('key', target, undefined), true); - target = {}; - decorator(target, 'name'); - assert.same(hasOwnMetadata('key', target, 'name'), true); -}); diff --git a/tests/pure/esnext.set.add-all.js b/tests/pure/esnext.set.add-all.js deleted file mode 100644 index 1c857a368057..000000000000 --- a/tests/pure/esnext.set.add-all.js +++ /dev/null @@ -1,23 +0,0 @@ -import Set from 'core-js-pure/features/set'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set#addAll', assert => { - const { addAll } = Set.prototype; - - assert.isFunction(addAll); - assert.arity(addAll, 0); - assert.name(addAll, 'addAll'); - assert.nonEnumerable(Set.prototype, 'addAll'); - - const set = new Set([1]); - assert.same(set.addAll(2), set); - - assert.deepEqual(from(new Set([1, 2, 3]).addAll(4, 5)), [1, 2, 3, 4, 5]); - assert.deepEqual(from(new Set([1, 2, 3]).addAll(3, 4)), [1, 2, 3, 4]); - assert.deepEqual(from(new Set([1, 2, 3]).addAll()), [1, 2, 3]); - - assert.notThrows(() => addAll.call({ add() { /* empty */ } }, 1, 2, 3)); - assert.throws(() => addAll.call({}, 1, 2, 3), TypeError); - assert.throws(() => addAll.call(undefined, 1, 2, 3), TypeError); - assert.throws(() => addAll.call(null, 1, 2, 3), TypeError); -}); diff --git a/tests/pure/esnext.set.delete-all.js b/tests/pure/esnext.set.delete-all.js deleted file mode 100644 index fb1050c3deb9..000000000000 --- a/tests/pure/esnext.set.delete-all.js +++ /dev/null @@ -1,32 +0,0 @@ -import Set from 'core-js-pure/features/set'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set#deleteAll', assert => { - const { deleteAll } = Set.prototype; - - assert.isFunction(deleteAll); - assert.arity(deleteAll, 0); - assert.name(deleteAll, 'deleteAll'); - assert.nonEnumerable(Set.prototype, 'deleteAll'); - - let set = new Set([1, 2, 3]); - assert.same(set.deleteAll(1, 2), true); - assert.deepEqual(from(set), [3]); - - set = new Set([1, 2, 3]); - assert.same(set.deleteAll(3, 4), false); - assert.deepEqual(from(set), [1, 2]); - - set = new Set([1, 2, 3]); - assert.same(set.deleteAll(4, 5), false); - assert.deepEqual(from(set), [1, 2, 3]); - - set = new Set([1, 2, 3]); - assert.same(set.deleteAll(), true); - assert.deepEqual(from(set), [1, 2, 3]); - - assert.notThrows(() => !deleteAll.call({ delete() { /* empty */ } }, 1, 2, 3)); - assert.throws(() => deleteAll.call({}, 1, 2, 3), TypeError); - assert.throws(() => deleteAll.call(undefined, 1, 2, 3), TypeError); - assert.throws(() => deleteAll.call(null, 1, 2, 3), TypeError); -}); diff --git a/tests/pure/esnext.set.difference.js b/tests/pure/esnext.set.difference.js deleted file mode 100644 index 3d74471b482b..000000000000 --- a/tests/pure/esnext.set.difference.js +++ /dev/null @@ -1,26 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Set from 'core-js-pure/features/set'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set#difference', assert => { - const { difference } = Set.prototype; - - assert.isFunction(difference); - assert.arity(difference, 1); - assert.name(difference, 'difference'); - assert.nonEnumerable(Set.prototype, 'difference'); - - const set = new Set([1]); - assert.ok(set.difference([2]) !== set); - - assert.deepEqual(from(new Set([1, 2, 3]).difference([4, 5])), [1, 2, 3]); - assert.deepEqual(from(new Set([1, 2, 3]).difference([3, 4])), [1, 2]); - assert.deepEqual(from(new Set([1, 2, 3]).difference(createIterable([3, 4]))), [1, 2]); - - assert.throws(() => new Set([1, 2, 3]).difference(), TypeError); - - assert.throws(() => difference.call({}, [1, 2, 3]), TypeError); - assert.throws(() => difference.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => difference.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/pure/esnext.set.every.js b/tests/pure/esnext.set.every.js deleted file mode 100644 index 5916ac61d156..000000000000 --- a/tests/pure/esnext.set.every.js +++ /dev/null @@ -1,29 +0,0 @@ -import Set from 'core-js-pure/features/set'; - -QUnit.test('Set#every', assert => { - const { every } = Set.prototype; - - assert.isFunction(every); - assert.arity(every, 1); - assert.name(every, 'every'); - assert.nonEnumerable(Set.prototype, 'every'); - - const set = new Set([1]); - const context = {}; - set.every(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, set, 'correct link to set in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.same(new Set([1, 2, 3]).every(it => typeof it === 'number'), true); - assert.same(new Set(['1', '2', '3']).some(it => typeof it === 'number'), false); - assert.same(new Set([1, '2', 3]).every(it => typeof it === 'number'), false); - assert.same(new Set().every(it => typeof it === 'number'), true); - - assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.set.filter.js b/tests/pure/esnext.set.filter.js deleted file mode 100644 index cd27f72a5d8d..000000000000 --- a/tests/pure/esnext.set.filter.js +++ /dev/null @@ -1,29 +0,0 @@ -import Set from 'core-js-pure/features/set'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set#filter', assert => { - const { filter } = Set.prototype; - - assert.isFunction(filter); - assert.arity(filter, 1); - assert.name(filter, 'filter'); - assert.nonEnumerable(Set.prototype, 'filter'); - - const set = new Set([1]); - const context = {}; - set.filter(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, set, 'correct link to set in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Set().filter(it => it) instanceof Set); - - assert.deepEqual(from(new Set([1, 2, 3, 'q', {}, 4, true, 5]).filter(it => typeof it === 'number')), [1, 2, 3, 4, 5]); - - assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.set.from.js b/tests/pure/esnext.set.from.js deleted file mode 100644 index ecac4dc1fd3c..000000000000 --- a/tests/pure/esnext.set.from.js +++ /dev/null @@ -1,29 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Set from 'core-js-pure/features/set'; -import toArray from 'core-js-pure/features/array/from'; - -QUnit.test('Set.from', assert => { - const { from } = Set; - assert.isFunction(from); - assert.arity(from, 1); - assert.ok(Set.from() instanceof Set); - assert.deepEqual(toArray(Set.from([])), []); - assert.deepEqual(toArray(Set.from([1])), [1]); - assert.deepEqual(toArray(Set.from([1, 2, 3, 2, 1])), [1, 2, 3]); - assert.deepEqual(toArray(Set.from(createIterable([1, 2, 3, 2, 1]))), [1, 2, 3]); - const context = {}; - Set.from([1], function (element, index) { - assert.same(element, 1); - assert.same(index, 0); - assert.same(this, context); - return element; - }, context); - assert.throws(() => from(1)); - let arg = null; - function F(it) { - return arg = it; - } - from.call(F, createIterable([1, 2, 3]), it => it ** 2); - assert.deepEqual(arg, [1, 4, 9]); -}); diff --git a/tests/pure/esnext.set.intersection.js b/tests/pure/esnext.set.intersection.js deleted file mode 100644 index a5200c0f1753..000000000000 --- a/tests/pure/esnext.set.intersection.js +++ /dev/null @@ -1,26 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Set from 'core-js-pure/features/set'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set#intersection', assert => { - const { intersection } = Set.prototype; - - assert.isFunction(intersection); - assert.arity(intersection, 1); - assert.name(intersection, 'intersection'); - assert.nonEnumerable(Set.prototype, 'intersection'); - - const set = new Set([1]); - assert.ok(set.intersection([2]) !== set); - - assert.deepEqual(from(new Set([1, 2, 3]).intersection([4, 5])), []); - assert.deepEqual(from(new Set([1, 2, 3]).intersection([2, 3, 4])), [2, 3]); - assert.deepEqual(from(new Set([1, 2, 3]).intersection(createIterable([2, 3, 4]))), [2, 3]); - - assert.throws(() => new Set([1, 2, 3]).intersection(), TypeError); - - assert.throws(() => intersection.call({}, [1, 2, 3]), TypeError); - assert.throws(() => intersection.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => intersection.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/pure/esnext.set.is-disjoint-from.js b/tests/pure/esnext.set.is-disjoint-from.js deleted file mode 100644 index aaa966c00b56..000000000000 --- a/tests/pure/esnext.set.is-disjoint-from.js +++ /dev/null @@ -1,25 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Set from 'core-js-pure/features/set'; - -QUnit.test('Set#isDisjointFrom', assert => { - const { isDisjointFrom } = Set.prototype; - - assert.isFunction(isDisjointFrom); - assert.arity(isDisjointFrom, 1); - assert.name(isDisjointFrom, 'isDisjointFrom'); - assert.nonEnumerable(Set.prototype, 'isDisjointFrom'); - - assert.ok(new Set([1]).isDisjointFrom([2])); - assert.ok(!new Set([1]).isDisjointFrom([1])); - assert.ok(new Set([1, 2, 3]).isDisjointFrom([4, 5, 6])); - assert.ok(!new Set([1, 2, 3]).isDisjointFrom([5, 4, 3])); - - assert.ok(new Set([1]).isDisjointFrom(createIterable([2]))); - assert.ok(!new Set([1]).isDisjointFrom(createIterable([1]))); - - assert.throws(() => new Set([1, 2, 3]).isDisjointFrom(), TypeError); - assert.throws(() => isDisjointFrom.call({}, [1, 2, 3]), TypeError); - assert.throws(() => isDisjointFrom.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => isDisjointFrom.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/pure/esnext.set.is-subset-of.js b/tests/pure/esnext.set.is-subset-of.js deleted file mode 100644 index 3c6c98efd9af..000000000000 --- a/tests/pure/esnext.set.is-subset-of.js +++ /dev/null @@ -1,31 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Set from 'core-js-pure/features/set'; - -QUnit.test('Set#isSubsetOf', assert => { - const { isSubsetOf } = Set.prototype; - - assert.isFunction(isSubsetOf); - assert.arity(isSubsetOf, 1); - assert.name(isSubsetOf, 'isSubsetOf'); - assert.nonEnumerable(Set.prototype, 'isSubsetOf'); - - assert.ok(new Set([1]).isSubsetOf([1, 2, 3])); - assert.ok(!new Set([1]).isSubsetOf([2, 3, 4])); - assert.ok(new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2, 1])); - assert.ok(!new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2])); - - assert.ok(new Set([1]).isSubsetOf(createIterable([1, 2, 3]))); - assert.ok(!new Set([1]).isSubsetOf(createIterable([2, 3, 4]))); - - assert.ok(new Set([1]).isSubsetOf({ has: () => true })); - assert.ok(!new Set([1]).isSubsetOf({ has: () => false })); - - assert.ok(isSubsetOf.call('ab', ['a', 'b', 'c'])); - assert.ok(!isSubsetOf.call('ab', ['a'])); - - assert.throws(() => new Set([1, 2, 3]).isSubsetOf(), TypeError); - assert.throws(() => isSubsetOf.call({}, [1, 2, 3]), TypeError); - assert.throws(() => isSubsetOf.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => isSubsetOf.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/pure/esnext.set.is-superset-of.js b/tests/pure/esnext.set.is-superset-of.js deleted file mode 100644 index 4dfba8fd32e9..000000000000 --- a/tests/pure/esnext.set.is-superset-of.js +++ /dev/null @@ -1,25 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Set from 'core-js-pure/features/set'; - -QUnit.test('Set#isSupersetOf', assert => { - const { isSupersetOf } = Set.prototype; - - assert.isFunction(isSupersetOf); - assert.arity(isSupersetOf, 1); - assert.name(isSupersetOf, 'isSupersetOf'); - assert.nonEnumerable(Set.prototype, 'isSupersetOf'); - - assert.ok(new Set([1, 2, 3]).isSupersetOf([1])); - assert.ok(!new Set([2, 3, 4]).isSupersetOf([1])); - assert.ok(new Set([5, 4, 3, 2, 1]).isSupersetOf([1, 2, 3])); - assert.ok(!new Set([5, 4, 3, 2]).isSupersetOf([1, 2, 3])); - - assert.ok(new Set([1, 2, 3]).isSupersetOf(createIterable([1]))); - assert.ok(!new Set([2, 3, 4]).isSupersetOf(createIterable([1]))); - - assert.throws(() => new Set([1, 2, 3]).isSupersetOf(), TypeError); - assert.throws(() => isSupersetOf.call({}, [1, 2, 3]), TypeError); - assert.throws(() => isSupersetOf.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => isSupersetOf.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/pure/esnext.set.join.js b/tests/pure/esnext.set.join.js deleted file mode 100644 index ed225c0834b4..000000000000 --- a/tests/pure/esnext.set.join.js +++ /dev/null @@ -1,18 +0,0 @@ -import Set from 'core-js-pure/features/set'; - -QUnit.test('Set#join', assert => { - const { join } = Set.prototype; - - assert.isFunction(join); - assert.arity(join, 1); - assert.name(join, 'join'); - assert.nonEnumerable(Set.prototype, 'join'); - - assert.strictEqual(new Set([1, 2, 3]).join(), '1,2,3'); - assert.strictEqual(new Set([1, 2, 3]).join(undefined), '1,2,3'); - assert.strictEqual(new Set([1, 2, 3]).join('|'), '1|2|3'); - - assert.throws(() => join.call({}), TypeError); - assert.throws(() => join.call(undefined), TypeError); - assert.throws(() => join.call(null), TypeError); -}); diff --git a/tests/pure/esnext.set.map.js b/tests/pure/esnext.set.map.js deleted file mode 100644 index b5de55fc35a3..000000000000 --- a/tests/pure/esnext.set.map.js +++ /dev/null @@ -1,30 +0,0 @@ -import Set from 'core-js-pure/features/set'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set#map', assert => { - const { map } = Set.prototype; - - assert.isFunction(map); - assert.arity(map, 1); - assert.name(map, 'map'); - assert.nonEnumerable(Set.prototype, 'map'); - - const set = new Set([1]); - const context = {}; - set.map(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, set, 'correct link to set in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Set().map(it => it) instanceof Set); - - assert.deepEqual(from(new Set([1, 2, 3]).map(it => it ** 2)), [1, 4, 9]); - assert.deepEqual(from(new Set([1, 2, 3]).map(it => it % 2)), [1, 0]); - - assert.throws(() => map.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.set.of.js b/tests/pure/esnext.set.of.js deleted file mode 100644 index ddb06a748e28..000000000000 --- a/tests/pure/esnext.set.of.js +++ /dev/null @@ -1,18 +0,0 @@ -import Set from 'core-js-pure/features/set'; -import toArray from 'core-js-pure/features/array/from'; - -QUnit.test('Set.of', assert => { - const { of } = Set; - assert.isFunction(of); - assert.arity(of, 0); - assert.ok(Set.of() instanceof Set); - assert.deepEqual(toArray(Set.of(1)), [1]); - assert.deepEqual(toArray(Set.of(1, 2, 3, 2, 1)), [1, 2, 3]); - assert.throws(() => of(1)); - let arg = null; - function F(it) { - return arg = it; - } - of.call(F, 1, 2, 3); - assert.deepEqual(arg, [1, 2, 3]); -}); diff --git a/tests/pure/esnext.set.some.js b/tests/pure/esnext.set.some.js deleted file mode 100644 index 365530145cee..000000000000 --- a/tests/pure/esnext.set.some.js +++ /dev/null @@ -1,29 +0,0 @@ -import Set from 'core-js-pure/features/set'; - -QUnit.test('Set#some', assert => { - const { some } = Set.prototype; - - assert.isFunction(some); - assert.arity(some, 1); - assert.name(some, 'some'); - assert.nonEnumerable(Set.prototype, 'some'); - - const set = new Set([1]); - const context = {}; - set.some(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, set, 'correct link to set in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.same(new Set([1, 2, 3]).some(it => typeof it === 'number'), true); - assert.same(new Set(['1', '2', '3']).some(it => typeof it === 'number'), false); - assert.same(new Set([1, '2', 3]).some(it => typeof it === 'number'), true); - assert.same(new Set().some(it => typeof it === 'number'), false); - - assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.set.symmetric-difference.js b/tests/pure/esnext.set.symmetric-difference.js deleted file mode 100644 index 983966828d82..000000000000 --- a/tests/pure/esnext.set.symmetric-difference.js +++ /dev/null @@ -1,26 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Set from 'core-js-pure/features/set'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set#symmetricDifference', assert => { - const { symmetricDifference } = Set.prototype; - - assert.isFunction(symmetricDifference); - assert.arity(symmetricDifference, 1); - assert.name(symmetricDifference, 'symmetricDifference'); - assert.nonEnumerable(Set.prototype, 'symmetricDifference'); - - const set = new Set([1]); - assert.ok(set.symmetricDifference([2]) !== set); - - assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference([4, 5])), [1, 2, 3, 4, 5]); - assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference([3, 4])), [1, 2, 4]); - assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createIterable([3, 4]))), [1, 2, 4]); - - assert.throws(() => new Set([1, 2, 3]).symmetricDifference(), TypeError); - - assert.throws(() => symmetricDifference.call({}, [1, 2, 3]), TypeError); - assert.throws(() => symmetricDifference.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => symmetricDifference.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/pure/esnext.set.union.js b/tests/pure/esnext.set.union.js deleted file mode 100644 index c411e1bc6784..000000000000 --- a/tests/pure/esnext.set.union.js +++ /dev/null @@ -1,26 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import Set from 'core-js-pure/features/set'; -import from from 'core-js-pure/features/array/from'; - -QUnit.test('Set#union', assert => { - const { union } = Set.prototype; - - assert.isFunction(union); - assert.arity(union, 1); - assert.name(union, 'union'); - assert.nonEnumerable(Set.prototype, 'union'); - - const set = new Set([1]); - assert.ok(set.union([2]) !== set); - - assert.deepEqual(from(new Set([1, 2, 3]).union([4, 5])), [1, 2, 3, 4, 5]); - assert.deepEqual(from(new Set([1, 2, 3]).union([3, 4])), [1, 2, 3, 4]); - assert.deepEqual(from(new Set([1, 2, 3]).union(createIterable([3, 4]))), [1, 2, 3, 4]); - - assert.throws(() => new Set([1, 2, 3]).union(), TypeError); - - assert.throws(() => union.call({}, [1, 2, 3]), TypeError); - assert.throws(() => union.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => union.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/pure/esnext.string.at.js b/tests/pure/esnext.string.at.js deleted file mode 100644 index d1ad885b674f..000000000000 --- a/tests/pure/esnext.string.at.js +++ /dev/null @@ -1,94 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import at from 'core-js-pure/features/string/at'; - -QUnit.test('String#at', assert => { - assert.isFunction(at); - // String that starts with a BMP symbol - assert.strictEqual(at('abc\uD834\uDF06def', -Infinity), ''); - assert.strictEqual(at('abc\uD834\uDF06def', -1), ''); - assert.strictEqual(at('abc\uD834\uDF06def', -0), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', +0), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', 1), 'b'); - assert.strictEqual(at('abc\uD834\uDF06def', 3), '\uD834\uDF06'); - assert.strictEqual(at('abc\uD834\uDF06def', 4), '\uDF06'); - assert.strictEqual(at('abc\uD834\uDF06def', 5), 'd'); - assert.strictEqual(at('abc\uD834\uDF06def', 42), ''); - assert.strictEqual(at('abc\uD834\uDF06def', Infinity), ''); - assert.strictEqual(at('abc\uD834\uDF06def', null), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', undefined), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def'), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', false), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', NaN), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', ''), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', '_'), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', '1'), 'b'); - assert.strictEqual(at('abc\uD834\uDF06def', []), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', {}), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', -0.9), 'a'); - assert.strictEqual(at('abc\uD834\uDF06def', 1.9), 'b'); - assert.strictEqual(at('abc\uD834\uDF06def', 7.9), 'f'); - assert.strictEqual(at('abc\uD834\uDF06def', 2 ** 32), ''); - // String that starts with an astral symbol - assert.strictEqual(at('\uD834\uDF06def', -Infinity), ''); - assert.strictEqual(at('\uD834\uDF06def', -1), ''); - assert.strictEqual(at('\uD834\uDF06def', -0), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', 0), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', 1), '\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', 2), 'd'); - assert.strictEqual(at('\uD834\uDF06def', 3), 'e'); - assert.strictEqual(at('\uD834\uDF06def', 4), 'f'); - assert.strictEqual(at('\uD834\uDF06def', 42), ''); - assert.strictEqual(at('\uD834\uDF06def', Infinity), ''); - assert.strictEqual(at('\uD834\uDF06def', null), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', undefined), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def'), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', false), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', NaN), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', ''), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', '_'), '\uD834\uDF06'); - assert.strictEqual(at('\uD834\uDF06def', '1'), '\uDF06'); - // Lone high surrogates - assert.strictEqual(at('\uD834abc', -Infinity), ''); - assert.strictEqual(at('\uD834abc', -1), ''); - assert.strictEqual(at('\uD834abc', -0), '\uD834'); - assert.strictEqual(at('\uD834abc', 0), '\uD834'); - assert.strictEqual(at('\uD834abc', 1), 'a'); - assert.strictEqual(at('\uD834abc', 42), ''); - assert.strictEqual(at('\uD834abc', Infinity), ''); - assert.strictEqual(at('\uD834abc', null), '\uD834'); - assert.strictEqual(at('\uD834abc', undefined), '\uD834'); - assert.strictEqual(at('\uD834abc'), '\uD834'); - assert.strictEqual(at('\uD834abc', false), '\uD834'); - assert.strictEqual(at('\uD834abc', NaN), '\uD834'); - assert.strictEqual(at('\uD834abc', ''), '\uD834'); - assert.strictEqual(at('\uD834abc', '_'), '\uD834'); - assert.strictEqual(at('\uD834abc', '1'), 'a'); - // Lone low surrogates - assert.strictEqual(at('\uDF06abc', -Infinity), ''); - assert.strictEqual(at('\uDF06abc', -1), ''); - assert.strictEqual(at('\uDF06abc', -0), '\uDF06'); - assert.strictEqual(at('\uDF06abc', 0), '\uDF06'); - assert.strictEqual(at('\uDF06abc', 1), 'a'); - assert.strictEqual(at('\uDF06abc', 42), ''); - assert.strictEqual(at('\uDF06abc', Infinity), ''); - assert.strictEqual(at('\uDF06abc', null), '\uDF06'); - assert.strictEqual(at('\uDF06abc', undefined), '\uDF06'); - assert.strictEqual(at('\uDF06abc'), '\uDF06'); - assert.strictEqual(at('\uDF06abc', false), '\uDF06'); - assert.strictEqual(at('\uDF06abc', NaN), '\uDF06'); - assert.strictEqual(at('\uDF06abc', ''), '\uDF06'); - assert.strictEqual(at('\uDF06abc', '_'), '\uDF06'); - assert.strictEqual(at('\uDF06abc', '1'), 'a'); - assert.strictEqual(at(42, 0), '4'); - assert.strictEqual(at(42, 1), '2'); - assert.strictEqual(at({ - toString() { - return 'abc'; - }, - }, 2), 'c'); - if (STRICT) { - assert.throws(() => at(null, 0), TypeError); - assert.throws(() => at(undefined, 0), TypeError); - } -}); diff --git a/tests/pure/esnext.string.code-points.js b/tests/pure/esnext.string.code-points.js deleted file mode 100644 index 56e0c79afeb6..000000000000 --- a/tests/pure/esnext.string.code-points.js +++ /dev/null @@ -1,44 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; -import codePoints from 'core-js-pure/features/string/code-points'; - -QUnit.test('String#codePoints', assert => { - assert.isFunction(codePoints); - let iterator = codePoints('qwe'); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'String Iterator'); - assert.strictEqual(String(iterator), '[object String Iterator]'); - assert.deepEqual(iterator.next(), { - value: { codePoint: 113, position: 0 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: { codePoint: 119, position: 1 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: { codePoint: 101, position: 2 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - iterator = codePoints('𠮷𠮷𠮷'); - assert.deepEqual(iterator.next(), { - value: { codePoint: 134071, position: 0 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: { codePoint: 134071, position: 2 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: { codePoint: 134071, position: 4 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/pure/esnext.string.replace-all.js b/tests/pure/esnext.string.replace-all.js deleted file mode 100644 index 2688c610ea73..000000000000 --- a/tests/pure/esnext.string.replace-all.js +++ /dev/null @@ -1,37 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -import replaceAll from 'core-js-pure/features/string/replace-all'; -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('String#replaceAll', assert => { - assert.isFunction(replaceAll); - assert.same(replaceAll('q=query+string+parameters', '+', ' '), 'q=query string parameters'); - assert.same(replaceAll('foo', 'o', {}), 'f[object Object][object Object]'); - assert.same(replaceAll('[object Object]x[object Object]', {}, 'y'), 'yxy'); - assert.same(replaceAll({}, 'bject', 'lolo'), '[ololo Ololo]'); - assert.same(replaceAll('aba', 'b', (search, i, string) => { - assert.same(search, 'b', '`search` is `b`'); - assert.same(i, 0, '`i` is 0'); - assert.same(string, 'aba', '`string` is `aba`'); - return 'c'; - }), 'aca'); - const searcher = { - [Symbol.replace](O, replaceValue) { - assert.same(this, searcher, '`this` is `searcher`'); - assert.same(String(O), 'aba', '`O` is `aba`'); - assert.same(String(replaceValue), 'c', '`replaceValue` is `c`'); - return 'foo'; - }, - }; - assert.same(replaceAll('aba', searcher, 'c'), 'foo'); - assert.same(replaceAll('aba', 'b'), 'aundefineda'); - assert.same(replaceAll('xxx', '', '_'), '_x_x_x_'); - if (STRICT) { - assert.throws(() => replaceAll(null, 'a', 'b'), TypeError); - assert.throws(() => replaceAll(undefined, 'a', 'b'), TypeError); - } - assert.throws(() => replaceAll('b.b.b.b.b', /\./, 'a'), TypeError); - assert.same(replaceAll('b.b.b.b.b', /\./g, 'a'), 'babababab'); - const object = {}; - assert.same(replaceAll('[object Object]', object, 'a'), 'a'); -}); diff --git a/tests/pure/esnext.symbol.async-dispose.js b/tests/pure/esnext.symbol.async-dispose.js deleted file mode 100644 index 564a4094990b..000000000000 --- a/tests/pure/esnext.symbol.async-dispose.js +++ /dev/null @@ -1,6 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('Symbol.asyncDispose', assert => { - assert.ok('asyncDispose' in Symbol, 'Symbol.asyncDispose available'); - assert.ok(Object(Symbol.asyncDispose) instanceof Symbol, 'Symbol.asyncDispose is symbol'); -}); diff --git a/tests/pure/esnext.symbol.dispose.js b/tests/pure/esnext.symbol.dispose.js deleted file mode 100644 index bef01dbc05f8..000000000000 --- a/tests/pure/esnext.symbol.dispose.js +++ /dev/null @@ -1,6 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('Symbol.dispose', assert => { - assert.ok('dispose' in Symbol, 'Symbol.dispose available'); - assert.ok(Object(Symbol.dispose) instanceof Symbol, 'Symbol.dispose is symbol'); -}); diff --git a/tests/pure/esnext.symbol.observable.js b/tests/pure/esnext.symbol.observable.js deleted file mode 100644 index 4842a6970e9d..000000000000 --- a/tests/pure/esnext.symbol.observable.js +++ /dev/null @@ -1,6 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('Symbol.observable', assert => { - assert.ok('observable' in Symbol, 'Symbol.observable available'); - assert.ok(Object(Symbol.observable) instanceof Symbol, 'Symbol.observable is symbol'); -}); diff --git a/tests/pure/esnext.symbol.pattern-match.js b/tests/pure/esnext.symbol.pattern-match.js deleted file mode 100644 index 02ceaf9a03f9..000000000000 --- a/tests/pure/esnext.symbol.pattern-match.js +++ /dev/null @@ -1,6 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('Symbol.patternMatch', assert => { - assert.ok('patternMatch' in Symbol, 'Symbol.patternMatch available'); - assert.ok(Object(Symbol.patternMatch) instanceof Symbol, 'Symbol.patternMatch is symbol'); -}); diff --git a/tests/pure/esnext.symbol.replace-all.js b/tests/pure/esnext.symbol.replace-all.js deleted file mode 100644 index 85996dafad77..000000000000 --- a/tests/pure/esnext.symbol.replace-all.js +++ /dev/null @@ -1,6 +0,0 @@ -import Symbol from 'core-js-pure/features/symbol'; - -QUnit.test('Symbol.replaceAll', assert => { - assert.ok('replaceAll' in Symbol, 'Symbol.replaceAll is available'); - assert.ok(Object(Symbol.replaceAll) instanceof Symbol, 'Symbol.replaceAll is symbol'); -}); diff --git a/tests/pure/esnext.weak-map.delete-all.js b/tests/pure/esnext.weak-map.delete-all.js deleted file mode 100644 index a7e8d677f0c5..000000000000 --- a/tests/pure/esnext.weak-map.delete-all.js +++ /dev/null @@ -1,52 +0,0 @@ -import WeakMap from 'core-js-pure/features/weak-map'; - -QUnit.test('WeakMap#deleteAll', assert => { - const { deleteAll } = WeakMap.prototype; - - assert.isFunction(deleteAll); - assert.arity(deleteAll, 0); - assert.nonEnumerable(WeakMap.prototype, 'deleteAll'); - - const a = []; - const b = []; - const c = []; - const d = []; - const e = []; - - let set = new WeakMap([[a, 1], [b, 2], [c, 3]]); - assert.same(set.deleteAll(a, b), true); - assert.ok(!set.has(a)); - assert.ok(!set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakMap([[a, 1], [b, 2], [c, 3]]); - assert.same(set.deleteAll(c, d), false); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(!set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakMap([[a, 1], [b, 2], [c, 3]]); - assert.same(set.deleteAll(d, e), false); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakMap([[a, 1], [b, 2], [c, 3]]); - assert.same(set.deleteAll(), true); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - assert.notThrows(() => !deleteAll.call({ delete() { /* empty */ } }, a, b, c)); - assert.throws(() => deleteAll.call({}, a, b, c), TypeError); - assert.throws(() => deleteAll.call(undefined, a, b, c), TypeError); - assert.throws(() => deleteAll.call(null, a, b, c), TypeError); -}); diff --git a/tests/pure/esnext.weak-map.from.js b/tests/pure/esnext.weak-map.from.js deleted file mode 100644 index ce3e8b1856a6..000000000000 --- a/tests/pure/esnext.weak-map.from.js +++ /dev/null @@ -1,28 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import WeakMap from 'core-js-pure/features/weak-map'; - -QUnit.test('WeakMap.from', assert => { - const { from } = WeakMap; - assert.isFunction(from); - assert.arity(from, 1); - assert.ok(WeakMap.from() instanceof WeakMap); - const array = []; - assert.same(WeakMap.from([[array, 2]]).get(array), 2); - assert.same(WeakMap.from(createIterable([[array, 2]])).get(array), 2); - const pair = [{}, 1]; - const context = {}; - WeakMap.from([pair], function (element, index) { - assert.same(element, pair); - assert.same(index, 0); - assert.same(this, context); - return element; - }, context); - assert.throws(() => from([{}, 1])); - let arg = null; - function F(it) { - return arg = it; - } - from.call(F, createIterable([1, 2, 3]), it => it ** 2); - assert.deepEqual(arg, [1, 4, 9]); -}); diff --git a/tests/pure/esnext.weak-map.of.js b/tests/pure/esnext.weak-map.of.js deleted file mode 100644 index 014e0f1e5447..000000000000 --- a/tests/pure/esnext.weak-map.of.js +++ /dev/null @@ -1,17 +0,0 @@ -import WeakMap from 'core-js-pure/features/weak-map'; - -QUnit.test('WeakMap.of', assert => { - const { of } = WeakMap; - assert.isFunction(of); - assert.arity(of, 0); - const array = []; - assert.ok(WeakMap.of() instanceof WeakMap); - assert.same(WeakMap.of([array, 2]).get(array), 2); - assert.throws(() => of(1)); - let arg = null; - function F(it) { - return arg = it; - } - of.call(F, 1, 2, 3); - assert.deepEqual(arg, [1, 2, 3]); -}); diff --git a/tests/pure/esnext.weak-map.upsert.js b/tests/pure/esnext.weak-map.upsert.js deleted file mode 100644 index 33065eade7ef..000000000000 --- a/tests/pure/esnext.weak-map.upsert.js +++ /dev/null @@ -1,40 +0,0 @@ -import WeakMap from 'core-js-pure/features/weak-map'; - -QUnit.test('WeakMap#upsert', assert => { - const { upsert } = WeakMap.prototype; - assert.isFunction(upsert); - assert.arity(upsert, 2); - assert.name(upsert, 'upsert'); - assert.nonEnumerable(WeakMap.prototype, 'upsert'); - - const a = {}; - const b = {}; - - const map = new WeakMap([[a, 2]]); - assert.same(map.upsert(a, function (value) { - assert.same(arguments.length, 1, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - return value ** 2; - }, () => { - assert.ok(false, 'should not be called'); - return 3; - }), 4, 'returns a correct value'); - assert.same(map.upsert(b, value => { - assert.ok(false, 'should not be called'); - return value ** 2; - }, function () { - assert.same(arguments.length, 0, 'correct number of callback arguments'); - return 3; - }), 3, 'returns a correct value'); - assert.same(map.get(a), 4, 'correct result #1'); - assert.same(map.get(b), 3, 'correct result #2'); - - assert.same(new WeakMap([[a, 2]]).upsert(b, null, () => 3), 3); - assert.same(new WeakMap([[a, 2]]).upsert(a, value => value ** 2), 4); - - assert.throws(() => new WeakMap().upsert(a), TypeError); - assert.throws(() => upsert.call({}, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call([], a, () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call(undefined, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call(null, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); -}); diff --git a/tests/pure/esnext.weak-set.add-all.js b/tests/pure/esnext.weak-set.add-all.js deleted file mode 100644 index 83ed02f1446f..000000000000 --- a/tests/pure/esnext.weak-set.add-all.js +++ /dev/null @@ -1,34 +0,0 @@ -import WeakSet from 'core-js-pure/features/weak-set'; - -QUnit.test('WeakSet#addAll', assert => { - const { addAll } = WeakSet.prototype; - - assert.isFunction(addAll); - assert.arity(addAll, 0); - assert.name(addAll, 'addAll'); - assert.nonEnumerable(WeakSet.prototype, 'addAll'); - - const a = []; - const b = []; - const c = []; - - let set = new WeakSet([a]); - assert.same(set.addAll(b), set); - - set = new WeakSet([a]).addAll(b, c); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - - set = new WeakSet([a]).addAll(a, b); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - - set = new WeakSet([a]).addAll(); - assert.ok(set.has(a)); - - assert.notThrows(() => addAll.call({ add() { /* empty */ } }, a, b, c)); - assert.throws(() => addAll.call({}, a, b, c), TypeError); - assert.throws(() => addAll.call(undefined, a, b, c), TypeError); - assert.throws(() => addAll.call(null, a, b, c), TypeError); -}); diff --git a/tests/pure/esnext.weak-set.delete-all.js b/tests/pure/esnext.weak-set.delete-all.js deleted file mode 100644 index 631d3c6c0434..000000000000 --- a/tests/pure/esnext.weak-set.delete-all.js +++ /dev/null @@ -1,53 +0,0 @@ -import WeakSet from 'core-js-pure/features/weak-set'; - -QUnit.test('WeakSet#deleteAll', assert => { - const { deleteAll } = WeakSet.prototype; - - assert.isFunction(deleteAll); - assert.arity(deleteAll, 0); - assert.name(deleteAll, 'deleteAll'); - assert.nonEnumerable(WeakSet.prototype, 'deleteAll'); - - const a = []; - const b = []; - const c = []; - const d = []; - const e = []; - - let set = new WeakSet([a, b, c]); - assert.same(set.deleteAll(a, b), true); - assert.ok(!set.has(a)); - assert.ok(!set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakSet([a, b, c]); - assert.same(set.deleteAll(c, d), false); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(!set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakSet([a, b, c]); - assert.same(set.deleteAll(d, e), false); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakSet([a, b, c]); - assert.same(set.deleteAll(), true); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - assert.notThrows(() => !deleteAll.call({ delete() { /* empty */ } }, a, b, c)); - assert.throws(() => deleteAll.call({}, a, b, c), TypeError); - assert.throws(() => deleteAll.call(undefined, a, b, c), TypeError); - assert.throws(() => deleteAll.call(null, a, b, c), TypeError); -}); diff --git a/tests/pure/esnext.weak-set.from.js b/tests/pure/esnext.weak-set.from.js deleted file mode 100644 index d6aba358afc7..000000000000 --- a/tests/pure/esnext.weak-set.from.js +++ /dev/null @@ -1,28 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import WeakSet from 'core-js-pure/features/weak-set'; - -QUnit.test('WeakSet.from', assert => { - const { from } = WeakSet; - assert.isFunction(from); - assert.arity(from, 1); - assert.ok(WeakSet.from() instanceof WeakSet); - const array = []; - assert.ok(WeakSet.from([array]).has(array)); - assert.ok(WeakSet.from(createIterable([array])).has(array)); - const object = {}; - const context = {}; - WeakSet.from([object], function (element, index) { - assert.same(element, object); - assert.same(index, 0); - assert.same(this, context); - return element; - }, context); - assert.throws(() => from({})); - let arg = null; - function F(it) { - return arg = it; - } - from.call(F, createIterable([1, 2, 3]), it => it ** 2); - assert.deepEqual(arg, [1, 4, 9]); -}); diff --git a/tests/pure/esnext.weak-set.of.js b/tests/pure/esnext.weak-set.of.js deleted file mode 100644 index e6c8b6a636d8..000000000000 --- a/tests/pure/esnext.weak-set.of.js +++ /dev/null @@ -1,17 +0,0 @@ -import WeakSet from 'core-js-pure/features/weak-set'; - -QUnit.test('WeakSet.of', assert => { - const { of } = WeakSet; - assert.isFunction(of); - assert.arity(of, 0); - const array = []; - assert.ok(WeakSet.of() instanceof WeakSet); - assert.ok(WeakSet.of(array).has(array)); - assert.throws(() => of(1)); - let arg = null; - function F(it) { - arg = it; - } - of.call(F, 1, 2, 3); - assert.deepEqual(arg, [1, 2, 3]); -}); diff --git a/tests/pure/helpers.get-iterator-method.js b/tests/pure/helpers.get-iterator-method.js deleted file mode 100644 index 483a0a213a4b..000000000000 --- a/tests/pure/helpers.get-iterator-method.js +++ /dev/null @@ -1,17 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; - -QUnit.test('getIteratorMethod helper', assert => { - assert.isFunction(getIteratorMethod); - const iterable = createIterable([]); - const iterFn = getIteratorMethod(iterable); - assert.isFunction(iterFn); - assert.isIterator(iterFn.call(iterable)); - assert.isFunction(getIteratorMethod([])); - assert.isFunction(getIteratorMethod(function () { - return arguments; - }())); - assert.isFunction(getIteratorMethod(Array.prototype)); - assert.strictEqual(getIteratorMethod({}), undefined); -}); diff --git a/tests/pure/helpers.get-iterator.js b/tests/pure/helpers.get-iterator.js deleted file mode 100644 index db10d06a9641..000000000000 --- a/tests/pure/helpers.get-iterator.js +++ /dev/null @@ -1,13 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import getIterator from 'core-js-pure/features/get-iterator'; - -QUnit.test('getIterator helper', assert => { - assert.isFunction(getIterator); - assert.isIterator(getIterator([])); - assert.isIterator(getIterator(function () { - return arguments; - }())); - assert.isIterator(getIterator(createIterable([]))); - assert.throws(() => getIterator({}), TypeError); -}); diff --git a/tests/pure/helpers.is-iterable.js b/tests/pure/helpers.is-iterable.js deleted file mode 100644 index f0a72fd1ce74..000000000000 --- a/tests/pure/helpers.is-iterable.js +++ /dev/null @@ -1,14 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -import isIterable from 'core-js-pure/features/is-iterable'; - -QUnit.test('isIterable helper', assert => { - assert.isFunction(isIterable); - assert.ok(isIterable(createIterable([]))); - assert.ok(isIterable([])); - assert.ok(isIterable(function () { - return arguments; - }())); - assert.ok(isIterable(Array.prototype)); - assert.ok(!isIterable({})); -}); diff --git a/tests/pure/index.js b/tests/pure/index.js deleted file mode 100644 index 468a02c19433..000000000000 --- a/tests/pure/index.js +++ /dev/null @@ -1,268 +0,0 @@ -/* eslint-disable import/first */ -import '../helpers/qunit-helpers'; -import { GLOBAL } from '../helpers/constants'; - -QUnit.module('ES'); -import './es.array.concat'; -import './es.array.copy-within'; -import './es.array.every'; -import './es.array.fill'; -import './es.array.filter'; -import './es.array.find-index'; -import './es.array.find'; -import './es.array.for-each'; -import './es.array.flat'; -import './es.array.flat-map'; -import './es.array.from'; -import './es.array.includes'; -import './es.array.index-of'; -import './es.array.is-array'; -import './es.array.iterator'; -import './es.array.join'; -import './es.array.last-index-of'; -import './es.array.map'; -import './es.array.of'; -import './es.array.reduce-right'; -import './es.array.reduce'; -import './es.array.reverse'; -import './es.array.slice'; -import './es.array.some'; -import './es.array.sort'; -import './es.array.splice'; -import './es.date.now'; -import './es.date.to-iso-string'; -import './es.date.to-json'; -import './es.function.bind'; -import './es.function.has-instance'; -import './es.global-this'; -import './es.map'; -import './es.math.acosh'; -import './es.math.asinh'; -import './es.math.atanh'; -import './es.math.cbrt'; -import './es.math.clz32'; -import './es.math.cosh'; -import './es.math.expm1'; -import './es.math.fround'; -import './es.math.hypot'; -import './es.math.imul'; -import './es.math.log10'; -import './es.math.log1p'; -import './es.math.log2'; -import './es.math.sign'; -import './es.math.sinh'; -import './es.math.tanh'; -import './es.math.trunc'; -import './es.number.epsilon'; -import './es.number.is-finite'; -import './es.number.is-integer'; -import './es.number.is-nan'; -import './es.number.is-safe-integer'; -import './es.number.max-safe-integer'; -import './es.number.min-safe-integer'; -import './es.number.parse-float'; -import './es.number.parse-int'; -import './es.number.to-fixed'; -import './es.number.to-precision'; -import './es.object.assign'; -import './es.object.create'; -import './es.object.define-getter'; -import './es.object.define-properties'; -import './es.object.define-property'; -import './es.object.define-setter'; -import './es.object.entries'; -import './es.object.freeze'; -import './es.object.from-entries'; -import './es.object.get-own-property-descriptor'; -import './es.object.get-own-property-descriptors'; -import './es.object.get-own-property-names'; -import './es.object.get-prototype-of'; -import './es.object.is-extensible'; -import './es.object.is-frozen'; -import './es.object.is-sealed'; -import './es.object.is'; -import './es.object.keys'; -import './es.object.lookup-getter'; -import './es.object.lookup-setter'; -import './es.object.prevent-extensions'; -import './es.object.seal'; -import './es.object.set-prototype-of'; -import './es.object.values'; -import './es.parse-float'; -import './es.parse-int'; -import './es.promise'; -import './es.promise.all-settled'; -import './es.promise.finally'; -import './es.reflect.apply'; -import './es.reflect.construct'; -import './es.reflect.define-property'; -import './es.reflect.delete-property'; -import './es.reflect.get-own-property-descriptor'; -import './es.reflect.get-prototype-of'; -import './es.reflect.get'; -import './es.reflect.has'; -import './es.reflect.is-extensible'; -import './es.reflect.own-keys'; -import './es.reflect.prevent-extensions'; -import './es.reflect.set-prototype-of'; -import './es.reflect.set'; -import './es.set'; -import './es.string.anchor'; -import './es.string.big'; -import './es.string.blink'; -import './es.string.bold'; -import './es.string.code-point-at'; -import './es.string.ends-with'; -import './es.string.fixed'; -import './es.string.fontcolor'; -import './es.string.fontsize'; -import './es.string.from-code-point'; -import './es.string.includes'; -import './es.string.italics'; -import './es.string.iterator'; -import './es.string.link'; -import './es.string.match-all'; -import './es.string.pad-end'; -import './es.string.pad-start'; -import './es.string.raw'; -import './es.string.repeat'; -import './es.string.small'; -import './es.string.starts-with'; -import './es.string.strike'; -import './es.string.sub'; -import './es.string.sup'; -import './es.string.trim'; -import './es.string.trim-start'; -import './es.string.trim-end'; -import './es.symbol'; -import './es.symbol.async-iterator'; -import './es.weak-map'; -import './es.weak-set'; - -QUnit.module('ESNext'); -import './esnext.aggregate-error'; -import './esnext.array.is-template-object'; -import './esnext.async-iterator.constructor'; -import './esnext.async-iterator.as-indexed-pairs'; -import './esnext.async-iterator.drop'; -import './esnext.async-iterator.every'; -import './esnext.async-iterator.filter'; -import './esnext.async-iterator.find'; -import './esnext.async-iterator.flat-map'; -import './esnext.async-iterator.for-each'; -import './esnext.async-iterator.from'; -import './esnext.async-iterator.map'; -import './esnext.async-iterator.reduce'; -import './esnext.async-iterator.some'; -import './esnext.async-iterator.take'; -import './esnext.async-iterator.to-array'; -import './esnext.composite-key'; -import './esnext.composite-symbol'; -import './esnext.iterator.constructor'; -import './esnext.iterator.as-indexed-pairs'; -import './esnext.iterator.drop'; -import './esnext.iterator.every'; -import './esnext.iterator.filter'; -import './esnext.iterator.find'; -import './esnext.iterator.flat-map'; -import './esnext.iterator.for-each'; -import './esnext.iterator.from'; -import './esnext.iterator.map'; -import './esnext.iterator.reduce'; -import './esnext.iterator.some'; -import './esnext.iterator.take'; -import './esnext.iterator.to-array'; -import './esnext.math.clamp'; -import './esnext.math.deg-per-rad'; -import './esnext.math.degrees'; -import './esnext.math.fscale'; -import './esnext.math.iaddh'; -import './esnext.math.imulh'; -import './esnext.math.isubh'; -import './esnext.math.rad-per-deg'; -import './esnext.math.radians'; -import './esnext.math.scale'; -import './esnext.math.signbit'; -import './esnext.math.umulh'; -import './esnext.math.seeded-prng'; -import './esnext.number.from-string'; -import './esnext.observable'; -import './esnext.promise.any'; -import './esnext.promise.try'; -import './esnext.reflect.define-metadata'; -import './esnext.reflect.delete-metadata'; -import './esnext.reflect.get-metadata-keys'; -import './esnext.reflect.get-metadata'; -import './esnext.reflect.get-own-matadata'; -import './esnext.reflect.get-own-metadata-keys'; -import './esnext.reflect.has-metadata'; -import './esnext.reflect.has-own-metadata'; -import './esnext.reflect.metadata'; -import './esnext.map.delete-all'; -import './esnext.map.every'; -import './esnext.map.filter'; -import './esnext.map.find'; -import './esnext.map.find-key'; -import './esnext.map.from'; -import './esnext.map.group-by'; -import './esnext.map.includes'; -import './esnext.map.key-by'; -import './esnext.map.key-of'; -import './esnext.map.map-keys'; -import './esnext.map.map-values'; -import './esnext.map.merge'; -import './esnext.map.of'; -import './esnext.map.reduce'; -import './esnext.map.some'; -import './esnext.map.update'; -import './esnext.map.update-or-insert'; -import './esnext.map.upsert'; -import './esnext.set.add-all'; -import './esnext.set.delete-all'; -import './esnext.set.difference'; -import './esnext.set.every'; -import './esnext.set.filter'; -import './esnext.set.find'; -import './esnext.set.from'; -import './esnext.set.intersection'; -import './esnext.set.is-disjoint-from'; -import './esnext.set.is-subset-of'; -import './esnext.set.is-superset-of'; -import './esnext.set.join'; -import './esnext.set.map'; -import './esnext.set.of'; -import './esnext.set.reduce'; -import './esnext.set.some'; -import './esnext.set.symmetric-difference'; -import './esnext.set.union'; -import './esnext.string.at'; -import './esnext.string.code-points'; -import './esnext.symbol.async-dispose'; -import './esnext.symbol.dispose'; -import './esnext.symbol.observable'; -import './esnext.symbol.pattern-match'; -import './esnext.symbol.replace-all'; -import './esnext.weak-map.delete-all'; -import './esnext.weak-map.from'; -import './esnext.weak-map.of'; -import './esnext.weak-map.upsert'; -import './esnext.weak-set.add-all'; -import './esnext.weak-set.delete-all'; -import './esnext.weak-set.from'; -import './esnext.weak-set.of'; - -QUnit.module('Web'); -import './web.dom-collections.iterator'; -import './web.immediate'; -import './web.queue-microtask'; -import './web.timers'; -import './web.url'; -import './web.url-search-params'; - -QUnit.module('Helpers'); -import './helpers.get-iterator-method'; -import './helpers.get-iterator'; -import './helpers.is-iterable'; - -import core from 'core-js-pure'; -GLOBAL.core = core; diff --git a/tests/pure/web.dom-collections.iterator.js b/tests/pure/web.dom-collections.iterator.js deleted file mode 100644 index 31ae88486273..000000000000 --- a/tests/pure/web.dom-collections.iterator.js +++ /dev/null @@ -1,58 +0,0 @@ -import { GLOBAL } from '../helpers/constants'; - -import Symbol from 'core-js-pure/features/symbol'; -import getIteratorMethod from 'core-js-pure/features/get-iterator-method'; - -QUnit.test('Iterable DOM collections', assert => { - let absent = true; - const collections = [ - 'CSSRuleList', - 'CSSStyleDeclaration', - 'CSSValueList', - 'ClientRectList', - 'DOMRectList', - 'DOMStringList', - 'DOMTokenList', - 'DataTransferItemList', - 'FileList', - 'HTMLAllCollection', - 'HTMLCollection', - 'HTMLFormElement', - 'HTMLSelectElement', - 'MediaList', - 'MimeTypeArray', - 'NamedNodeMap', - 'NodeList', - 'PaintRequestList', - 'Plugin', - 'PluginArray', - 'SVGLengthList', - 'SVGNumberList', - 'SVGPathSegList', - 'SVGPointList', - 'SVGStringList', - 'SVGTransformList', - 'SourceBufferList', - 'StyleSheetList', - 'TextTrackCueList', - 'TextTrackList', - 'TouchList', - ]; - - for (const name of collections) { - const Collection = GLOBAL[name]; - if (Collection) { - assert.same(Collection.prototype[Symbol.toStringTag], name, `${ name }::@@toStringTag is '${ name }'`); - assert.isFunction(getIteratorMethod(Collection.prototype), `${ name }::@@iterator is function`); - absent = false; - } - } - - if (GLOBAL.NodeList && GLOBAL.document && document.querySelectorAll && document.querySelectorAll('div') instanceof NodeList) { - assert.isFunction(getIteratorMethod(document.querySelectorAll('div')), 'works with document.querySelectorAll'); - } - - if (absent) { - assert.ok(true, 'DOM collections are absent'); - } -}); diff --git a/tests/pure/web.immediate.js b/tests/pure/web.immediate.js deleted file mode 100644 index e4f951b72372..000000000000 --- a/tests/pure/web.immediate.js +++ /dev/null @@ -1,37 +0,0 @@ -import { timeLimitedPromise } from '../helpers/helpers'; - -import { setImmediate, clearImmediate } from 'core-js-pure'; - -QUnit.test('setImmediate / clearImmediate', assert => { - let called = false; - assert.expect(6); - assert.isFunction(setImmediate, 'setImmediate is function'); - assert.isFunction(clearImmediate, 'clearImmediate is function'); - timeLimitedPromise(1e3, res => { - setImmediate(() => { - called = true; - res(); - }); - }).then(() => { - assert.ok(true, 'setImmediate works'); - }).catch(() => { - assert.ok(false, 'setImmediate works'); - }).then(assert.async()); - assert.strictEqual(called, false, 'setImmediate is async'); - timeLimitedPromise(1e3, res => { - setImmediate((a, b) => { - res(a + b); - }, 'a', 'b'); - }).then(it => { - assert.strictEqual(it, 'ab', 'setImmediate works with additional args'); - }).catch(() => { - assert.ok(false, 'setImmediate works with additional args'); - }).then(assert.async()); - timeLimitedPromise(50, res => { - clearImmediate(setImmediate(res)); - }).then(() => { - assert.ok(false, 'clearImmediate works'); - }).catch(() => { - assert.ok(true, 'clearImmediate works'); - }).then(assert.async()); -}); diff --git a/tests/pure/web.queue-microtask.js b/tests/pure/web.queue-microtask.js deleted file mode 100644 index 349dfad15ecb..000000000000 --- a/tests/pure/web.queue-microtask.js +++ /dev/null @@ -1,25 +0,0 @@ -import queueMicrotask from 'core-js-pure/features/queue-microtask'; - -QUnit.test('queueMicrotask', assert => { - assert.expect(3); - assert.isFunction(queueMicrotask); - assert.arity(queueMicrotask, 1); - const async = assert.async(); - let done = false; - let after = false; - queueMicrotask(() => { - if (!done) { - done = true; - assert.ok(after, 'works'); - async(); - } - }); - setTimeout(() => { - if (!done) { - done = true; - assert.ok(false, 'fails'); - async(); - } - }, 3e3); - after = true; -}); diff --git a/tests/pure/web.timers.js b/tests/pure/web.timers.js deleted file mode 100644 index 4fdb1e15a517..000000000000 --- a/tests/pure/web.timers.js +++ /dev/null @@ -1,43 +0,0 @@ -import { timeLimitedPromise } from '../helpers/helpers'; - -import { setTimeout, setInterval } from 'core-js-pure'; - -QUnit.test('setTimeout / clearTimeout', assert => { - assert.expect(2); - - timeLimitedPromise(1e3, resolve => { - setTimeout((a, b) => { resolve(a + b); }, 10, 'a', 'b'); - }).then(it => { - assert.strictEqual(it, 'ab', 'setTimeout works with additional args'); - }).catch(() => { - assert.ok(false, 'setTimeout works with additional args'); - }).then(assert.async()); - - timeLimitedPromise(50, resolve => { - clearTimeout(setTimeout(resolve, 10)); - }).then(() => { - assert.ok(false, 'clearImmediate works with wraped setTimeout'); - }).catch(() => { - assert.ok(true, 'clearImmediate works with wraped setTimeout'); - }).then(assert.async()); -}); - -QUnit.test('setInterval / clearInterval', assert => { - assert.expect(1); - - timeLimitedPromise(1e4, (resolve, reject) => { - let i = 0; - const interval = setInterval((a, b) => { - if (a + b !== 'ab' || i > 2) reject({ a, b, i }); - if (i++ === 2) { - clearInterval(interval); - setTimeout(resolve, 30); - } - }, 5, 'a', 'b'); - }).then(() => { - assert.ok(true, 'setInterval & clearInterval works with additional args'); - }).catch(error => { - if (!error) error = {}; - assert.ok(false, `setInterval & clearInterval works with additional args: ${ error.a }, ${ error.b }, times: ${ error.i }`); - }).then(assert.async()); -}); diff --git a/tests/pure/web.url-search-params.js b/tests/pure/web.url-search-params.js deleted file mode 100644 index 74b646076c8c..000000000000 --- a/tests/pure/web.url-search-params.js +++ /dev/null @@ -1,802 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; -import { createIterable } from '../helpers/helpers'; - -import { Symbol, URL, URLSearchParams } from 'core-js-pure'; - -QUnit.test('URLSearchParams', assert => { - assert.isFunction(URLSearchParams); - assert.arity(URLSearchParams, 0); - - assert.same(String(new URLSearchParams()), ''); - assert.same(String(new URLSearchParams('')), ''); - assert.same(String(new URLSearchParams('a=b')), 'a=b'); - assert.same(String(new URLSearchParams(new URLSearchParams('a=b'))), 'a=b'); - assert.same(String(new URLSearchParams([])), ''); - assert.same(String(new URLSearchParams([[1, 2], ['a', 'b']])), '1=2&a=b'); - assert.same(String(new URLSearchParams(createIterable([createIterable(['a', 'b']), createIterable(['c', 'd'])]))), 'a=b&c=d'); - assert.same(String(new URLSearchParams({})), ''); - assert.same(String(new URLSearchParams({ 1: 2, a: 'b' })), '1=2&a=b'); - - assert.same(String(new URLSearchParams('?a=b')), 'a=b', 'leading ? should be ignored'); - assert.same(String(new URLSearchParams('??a=b')), '%3Fa=b'); - assert.same(String(new URLSearchParams('?')), ''); - assert.same(String(new URLSearchParams('??')), '%3F='); - - assert.same(String(new URLSearchParams('a=b c')), 'a=b+c'); - assert.same(String(new URLSearchParams('a=b&b=c&a=d')), 'a=b&b=c&a=d'); - - assert.same(String(new URLSearchParams('a==')), 'a=%3D'); - assert.same(String(new URLSearchParams('a=b=')), 'a=b%3D'); - assert.same(String(new URLSearchParams('a=b=c')), 'a=b%3Dc'); - assert.same(String(new URLSearchParams('a==b')), 'a=%3Db'); - - let params = new URLSearchParams('a=b'); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.has('b'), false, 'search params object has not got name "b"'); - - params = new URLSearchParams('a=b&c'); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.has('c'), true, 'search params object has name "c"'); - - params = new URLSearchParams('&a&&& &&&&&a+b=& c&m%c3%b8%c3%b8'); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.has('a b'), true, 'search params object has name "a b"'); - assert.same(params.has(' '), true, 'search params object has name " "'); - assert.same(params.has('c'), false, 'search params object did not have the name "c"'); - assert.same(params.has(' c'), true, 'search params object has name " c"'); - assert.same(params.has('møø'), true, 'search params object has name "møø"'); - - params = new URLSearchParams('a=b+c'); - assert.same(params.get('a'), 'b c', 'parse +'); - params = new URLSearchParams('a+b=c'); - assert.same(params.get('a b'), 'c', 'parse +'); - - params = new URLSearchParams('a=b c'); - assert.same(params.get('a'), 'b c', 'parse " "'); - params = new URLSearchParams('a b=c'); - assert.same(params.get('a b'), 'c', 'parse " "'); - - params = new URLSearchParams('a=b%20c'); - assert.same(params.get('a'), 'b c', 'parse %20'); - params = new URLSearchParams('a%20b=c'); - assert.same(params.get('a b'), 'c', 'parse %20'); - - params = new URLSearchParams('a=b\0c'); - assert.same(params.get('a'), 'b\0c', 'parse \\0'); - params = new URLSearchParams('a\0b=c'); - assert.same(params.get('a\0b'), 'c', 'parse \\0'); - - params = new URLSearchParams('a=b%00c'); - assert.same(params.get('a'), 'b\0c', 'parse %00'); - params = new URLSearchParams('a%00b=c'); - assert.same(params.get('a\0b'), 'c', 'parse %00'); - - params = new URLSearchParams('a=b\u2384'); - assert.same(params.get('a'), 'b\u2384', 'parse \u2384'); - params = new URLSearchParams('a\u2384b=c'); - assert.same(params.get('a\u2384b'), 'c', 'parse \u2384'); - - params = new URLSearchParams('a=b%e2%8e%84'); - assert.same(params.get('a'), 'b\u2384', 'parse %e2%8e%84'); - params = new URLSearchParams('a%e2%8e%84b=c'); - assert.same(params.get('a\u2384b'), 'c', 'parse %e2%8e%84'); - - params = new URLSearchParams('a=b\uD83D\uDCA9c'); - assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse \uD83D\uDCA9'); - params = new URLSearchParams('a\uD83D\uDCA9b=c'); - assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse \uD83D\uDCA9'); - - params = new URLSearchParams('a=b%f0%9f%92%a9c'); - assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); - params = new URLSearchParams('a%f0%9f%92%a9b=c'); - assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); - - params = new URLSearchParams(); - params.set('query', '+15555555555'); - assert.same(params.toString(), 'query=%2B15555555555'); - assert.same(params.get('query'), '+15555555555', 'parse encoded +'); - params = new URLSearchParams(params.toString()); - assert.same(params.get('query'), '+15555555555', 'parse encoded +'); - - const testData = [ - { input: '?a=%', output: [['a', '%']], name: 'handling %' }, - { input: { '+': '%C2' }, output: [['+', '%C2']], name: 'object with +' }, - { input: { c: 'x', a: '?' }, output: [['c', 'x'], ['a', '?']], name: 'object with two keys' }, - { input: [['c', 'x'], ['a', '?']], output: [['c', 'x'], ['a', '?']], name: 'array with two keys' }, - // eslint-disable-next-line max-len - // !!! { input: { 'a\0b': '42', 'c\uD83D': '23', dሴ: 'foo' }, output: [['a\0b', '42'], ['c\uFFFD', '23'], ['d\u1234', 'foo']], name: 'object with NULL, non-ASCII, and surrogate keys' }, - ]; - - for (const { input, output, name } of testData) { - params = new URLSearchParams(input); - let i = 0; - params.forEach((value, key) => { - const [reqKey, reqValue] = output[i++]; - assert.same(key, reqKey, `construct with ${ name }`); - assert.same(value, reqValue, `construct with ${ name }`); - }); - } - - assert.throws(() => { - URLSearchParams(''); - }, 'throws w/o `new`'); - - assert.throws(() => { - new URLSearchParams([[1, 2, 3]]); - }, 'sequence elements must be pairs #1'); - - assert.throws(() => { - new URLSearchParams([createIterable([createIterable([1, 2, 3])])]); - }, 'sequence elements must be pairs #2'); - - assert.throws(() => { - new URLSearchParams([[1]]); - }, 'sequence elements must be pairs #3'); - - assert.throws(() => { - new URLSearchParams([createIterable([createIterable([1])])]); - }, 'sequence elements must be pairs #4'); -}); - -QUnit.test('URLSearchParams#append', assert => { - const { append } = URLSearchParams.prototype; - assert.isFunction(append); - assert.arity(append, 2); - assert.enumerable(URLSearchParams.prototype, 'append'); - - assert.same(new URLSearchParams().append('a', 'b'), undefined, 'void'); - - let params = new URLSearchParams(); - params.append('a', 'b'); - assert.same(String(params), 'a=b'); - params.append('a', 'b'); - assert.same(String(params), 'a=b&a=b'); - params.append('a', 'c'); - assert.same(String(params), 'a=b&a=b&a=c'); - - params = new URLSearchParams(); - params.append('', ''); - assert.same(String(params), '='); - params.append('', ''); - assert.same(String(params), '=&='); - - params = new URLSearchParams(); - params.append(undefined, undefined); - assert.same(String(params), 'undefined=undefined'); - params.append(undefined, undefined); - assert.same(String(params), 'undefined=undefined&undefined=undefined'); - - params = new URLSearchParams(); - params.append(null, null); - assert.same(String(params), 'null=null'); - params.append(null, null); - assert.same(String(params), 'null=null&null=null'); - - params = new URLSearchParams(); - params.append('first', 1); - params.append('second', 2); - params.append('third', ''); - params.append('first', 10); - assert.ok(params.has('first'), 'search params object has name "first"'); - assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); - assert.same(params.get('second'), '2', 'search params object has name "second" with value "2"'); - assert.same(params.get('third'), '', 'search params object has name "third" with value ""'); - params.append('first', 10); - assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); - - assert.throws(() => { - return new URLSearchParams('').append(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#delete', assert => { - const $delete = URLSearchParams.prototype.delete; - assert.isFunction($delete); - assert.arity($delete, 1); - assert.enumerable(URLSearchParams.prototype, 'delete'); - - let params = new URLSearchParams('a=b&c=d'); - params.delete('a'); - assert.same(String(params), 'c=d'); - - params = new URLSearchParams('a=a&b=b&a=a&c=c'); - params.delete('a'); - assert.same(String(params), 'b=b&c=c'); - - params = new URLSearchParams('a=a&=&b=b&c=c'); - params.delete(''); - assert.same(String(params), 'a=a&b=b&c=c'); - - params = new URLSearchParams('a=a&null=null&b=b'); - params.delete(null); - assert.same(String(params), 'a=a&b=b'); - - params = new URLSearchParams('a=a&undefined=undefined&b=b'); - params.delete(undefined); - assert.same(String(params), 'a=a&b=b'); - - params = new URLSearchParams(); - params.append('first', 1); - assert.same(params.has('first'), true, 'search params object has name "first"'); - assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); - params.delete('first'); - assert.same(params.has('first'), false, 'search params object has no "first" name'); - params.append('first', 1); - params.append('first', 10); - params.delete('first'); - assert.same(params.has('first'), false, 'search params object has no "first" name'); - - if (DESCRIPTORS) { - let url = new URL('http://example.com/?param1¶m2'); - url.searchParams.delete('param1'); - url.searchParams.delete('param2'); - assert.same(String(url), 'http://example.com/', 'url.href does not have ?'); - assert.same(url.search, '', 'url.search does not have ?'); - - url = new URL('http://example.com/?'); - url.searchParams.delete('param1'); - // assert.same(String(url), 'http://example.com/', 'url.href does not have ?'); // Safari bug - assert.same(url.search, '', 'url.search does not have ?'); - } - - assert.throws(() => { - return new URLSearchParams('').delete(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#get', assert => { - const { get } = URLSearchParams.prototype; - assert.isFunction(get); - assert.arity(get, 1); - assert.enumerable(URLSearchParams.prototype, 'get'); - - let params = new URLSearchParams('a=b&c=d'); - assert.same(params.get('a'), 'b'); - assert.same(params.get('c'), 'd'); - assert.same(params.get('e'), null); - - params = new URLSearchParams('a=b&c=d&a=e'); - assert.same(params.get('a'), 'b'); - - params = new URLSearchParams('=b&c=d'); - assert.same(params.get(''), 'b'); - - params = new URLSearchParams('a=&c=d&a=e'); - assert.same(params.get('a'), ''); - - params = new URLSearchParams('first=second&third&&'); - assert.same(params.has('first'), true, 'Search params object has name "first"'); - assert.same(params.get('first'), 'second', 'Search params object has name "first" with value "second"'); - assert.same(params.get('third'), '', 'Search params object has name "third" with the empty value.'); - assert.same(params.get('fourth'), null, 'Search params object has no "fourth" name and value.'); - - assert.same(new URLSearchParams('a=b c').get('a'), 'b c'); - assert.same(new URLSearchParams('a b=c').get('a b'), 'c'); - - assert.same(new URLSearchParams('a=b%20c').get('a'), 'b c', 'parse %20'); - assert.same(new URLSearchParams('a%20b=c').get('a b'), 'c', 'parse %20'); - - assert.same(new URLSearchParams('a=b\0c').get('a'), 'b\0c', 'parse \\0'); - assert.same(new URLSearchParams('a\0b=c').get('a\0b'), 'c', 'parse \\0'); - - assert.same(new URLSearchParams('a=b%2Bc').get('a'), 'b+c', 'parse %2B'); - assert.same(new URLSearchParams('a%2Bb=c').get('a+b'), 'c', 'parse %2B'); - - assert.same(new URLSearchParams('a=b%00c').get('a'), 'b\0c', 'parse %00'); - assert.same(new URLSearchParams('a%00b=c').get('a\0b'), 'c', 'parse %00'); - - assert.same(new URLSearchParams('a==').get('a'), '=', 'parse ='); - assert.same(new URLSearchParams('a=b=').get('a'), 'b=', 'parse ='); - assert.same(new URLSearchParams('a=b=c').get('a'), 'b=c', 'parse ='); - assert.same(new URLSearchParams('a==b').get('a'), '=b', 'parse ='); - - assert.same(new URLSearchParams('a=b\u2384').get('a'), 'b\u2384', 'parse \\u2384'); - assert.same(new URLSearchParams('a\u2384b=c').get('a\u2384b'), 'c', 'parse \\u2384'); - - assert.same(new URLSearchParams('a=b%e2%8e%84').get('a'), 'b\u2384', 'parse %e2%8e%84'); - assert.same(new URLSearchParams('a%e2%8e%84b=c').get('a\u2384b'), 'c', 'parse %e2%8e%84'); - - assert.same(new URLSearchParams('a=b\uD83D\uDCA9c').get('a'), 'b\uD83D\uDCA9c', 'parse \\uD83D\\uDCA9'); - assert.same(new URLSearchParams('a\uD83D\uDCA9b=c').get('a\uD83D\uDCA9b'), 'c', 'parse \\uD83D\\uDCA9'); - - assert.same(new URLSearchParams('a=b%f0%9f%92%a9c').get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); - assert.same(new URLSearchParams('a%f0%9f%92%a9b=c').get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); - - assert.same(new URLSearchParams('=').get(''), '', 'parse ='); - - assert.throws(() => { - return new URLSearchParams('').get(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#getAll', assert => { - const { getAll } = URLSearchParams.prototype; - assert.isFunction(getAll); - assert.arity(getAll, 1); - assert.enumerable(URLSearchParams.prototype, 'getAll'); - - let params = new URLSearchParams('a=b&c=d'); - assert.arrayEqual(params.getAll('a'), ['b']); - assert.arrayEqual(params.getAll('c'), ['d']); - assert.arrayEqual(params.getAll('e'), []); - - params = new URLSearchParams('a=b&c=d&a=e'); - assert.arrayEqual(params.getAll('a'), ['b', 'e']); - - params = new URLSearchParams('=b&c=d'); - assert.arrayEqual(params.getAll(''), ['b']); - - params = new URLSearchParams('a=&c=d&a=e'); - assert.arrayEqual(params.getAll('a'), ['', 'e']); - - params = new URLSearchParams('a=1&a=2&a=3&a'); - assert.arrayEqual(params.getAll('a'), ['1', '2', '3', ''], 'search params object has expected name "a" values'); - params.set('a', 'one'); - assert.arrayEqual(params.getAll('a'), ['one'], 'search params object has expected name "a" values'); - - assert.throws(() => { - return new URLSearchParams('').getAll(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#has', assert => { - const { has } = URLSearchParams.prototype; - assert.isFunction(has); - assert.arity(has, 1); - assert.enumerable(URLSearchParams.prototype, 'has'); - - let params = new URLSearchParams('a=b&c=d'); - assert.same(params.has('a'), true); - assert.same(params.has('c'), true); - assert.same(params.has('e'), false); - - params = new URLSearchParams('a=b&c=d&a=e'); - assert.same(params.has('a'), true); - - params = new URLSearchParams('=b&c=d'); - assert.same(params.has(''), true); - - params = new URLSearchParams('null=a'); - assert.same(params.has(null), true); - - params = new URLSearchParams('a=b&c=d&&'); - params.append('first', 1); - params.append('first', 2); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.has('c'), true, 'search params object has name "c"'); - assert.same(params.has('first'), true, 'search params object has name "first"'); - assert.same(params.has('d'), false, 'search params object has no name "d"'); - params.delete('first'); - assert.same(params.has('first'), false, 'search params object has no name "first"'); - - assert.throws(() => { - return new URLSearchParams('').has(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#set', assert => { - const { set } = URLSearchParams.prototype; - assert.isFunction(set); - assert.arity(set, 2); - assert.enumerable(URLSearchParams.prototype, 'set'); - - let params = new URLSearchParams('a=b&c=d'); - params.set('a', 'B'); - assert.same(String(params), 'a=B&c=d'); - - params = new URLSearchParams('a=b&c=d&a=e'); - params.set('a', 'B'); - assert.same(String(params), 'a=B&c=d'); - params.set('e', 'f'); - assert.same(String(params), 'a=B&c=d&e=f'); - - params = new URLSearchParams('a=1&a=2&a=3'); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.get('a'), '1', 'search params object has name "a" with value "1"'); - params.set('first', 4); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.get('a'), '1', 'search params object has name "a" with value "1"'); - assert.same(String(params), 'a=1&a=2&a=3&first=4'); - params.set('a', 4); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.get('a'), '4', 'search params object has name "a" with value "4"'); - assert.same(String(params), 'a=4&first=4'); - - assert.throws(() => { - return new URLSearchParams('').set(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#sort', assert => { - const { sort } = URLSearchParams.prototype; - assert.isFunction(sort); - assert.arity(sort, 0); - assert.enumerable(URLSearchParams.prototype, 'sort'); - - let params = new URLSearchParams('a=1&b=4&a=3&b=2'); - params.sort(); - assert.same(String(params), 'a=1&a=3&b=4&b=2'); - params.delete('a'); - params.append('a', '0'); - params.append('b', '0'); - params.sort(); - assert.same(String(params), 'a=0&b=4&b=2&b=0'); - - const testData = [ - { - input: 'z=b&a=b&z=a&a=a', - output: [['a', 'b'], ['a', 'a'], ['z', 'b'], ['z', 'a']], - }, - { - input: '\uFFFD=x&\uFFFC&\uFFFD=a', - output: [['\uFFFC', ''], ['\uFFFD', 'x'], ['\uFFFD', 'a']], - }, - { - input: 'ffi&🌈', // 🌈 > code point, but < code unit because two code units - output: [['🌈', ''], ['ffi', '']], - }, - { - input: 'é&e\uFFFD&e\u0301', - output: [['e\u0301', ''], ['e\uFFFD', ''], ['é', '']], - }, - { - input: 'z=z&a=a&z=y&a=b&z=x&a=c&z=w&a=d&z=v&a=e&z=u&a=f&z=t&a=g', - // eslint-disable-next-line max-len - output: [['a', 'a'], ['a', 'b'], ['a', 'c'], ['a', 'd'], ['a', 'e'], ['a', 'f'], ['a', 'g'], ['z', 'z'], ['z', 'y'], ['z', 'x'], ['z', 'w'], ['z', 'v'], ['z', 'u'], ['z', 't']], - }, - { - input: 'bbb&bb&aaa&aa=x&aa=y', - output: [['aa', 'x'], ['aa', 'y'], ['aaa', ''], ['bb', ''], ['bbb', '']], - }, - { - input: 'z=z&=f&=t&=x', - output: [['', 'f'], ['', 't'], ['', 'x'], ['z', 'z']], - }, - { - input: 'a🌈&a💩', - output: [['a🌈', ''], ['a💩', '']], - }, - ]; - - for (const { input, output } of testData) { - let i = 0; - params = new URLSearchParams(input); - params.sort(); - params.forEach((value, key) => { - const [reqKey, reqValue] = output[i++]; - assert.same(key, reqKey); - assert.same(value, reqValue); - }); - - i = 0; - const url = new URL(`?${ input }`, 'https://example/'); - params = url.searchParams; - params.sort(); - params.forEach((value, key) => { - const [reqKey, reqValue] = output[i++]; - assert.same(key, reqKey); - assert.same(value, reqValue); - }); - } - - if (DESCRIPTORS) { - const url = new URL('http://example.com/?'); - url.searchParams.sort(); - assert.same(url.href, 'http://example.com/', 'Sorting non-existent params removes ? from URL'); - assert.same(url.search, '', 'Sorting non-existent params removes ? from URL'); - } -}); - -QUnit.test('URLSearchParams#toString', assert => { - const { toString } = URLSearchParams.prototype; - assert.isFunction(toString); - assert.arity(toString, 0); - - let params = new URLSearchParams(); - params.append('a', 'b c'); - assert.same(String(params), 'a=b+c'); - params.delete('a'); - params.append('a b', 'c'); - assert.same(String(params), 'a+b=c'); - - params = new URLSearchParams(); - params.append('a', ''); - assert.same(String(params), 'a='); - params.append('a', ''); - assert.same(String(params), 'a=&a='); - params.append('', 'b'); - assert.same(String(params), 'a=&a=&=b'); - params.append('', ''); - assert.same(String(params), 'a=&a=&=b&='); - params.append('', ''); - assert.same(String(params), 'a=&a=&=b&=&='); - - params = new URLSearchParams(); - params.append('', 'b'); - assert.same(String(params), '=b'); - params.append('', 'b'); - assert.same(String(params), '=b&=b'); - - params = new URLSearchParams(); - params.append('', ''); - assert.same(String(params), '='); - params.append('', ''); - assert.same(String(params), '=&='); - - params = new URLSearchParams(); - params.append('a', 'b+c'); - assert.same(String(params), 'a=b%2Bc'); - params.delete('a'); - params.append('a+b', 'c'); - assert.same(String(params), 'a%2Bb=c'); - - params = new URLSearchParams(); - params.append('=', 'a'); - assert.same(String(params), '%3D=a'); - params.append('b', '='); - assert.same(String(params), '%3D=a&b=%3D'); - - params = new URLSearchParams(); - params.append('&', 'a'); - assert.same(String(params), '%26=a'); - params.append('b', '&'); - assert.same(String(params), '%26=a&b=%26'); - - params = new URLSearchParams(); - params.append('a', '\r'); - assert.same(String(params), 'a=%0D'); - - params = new URLSearchParams(); - params.append('a', '\n'); - assert.same(String(params), 'a=%0A'); - - params = new URLSearchParams(); - params.append('a', '\r\n'); - assert.same(String(params), 'a=%0D%0A'); - - params = new URLSearchParams(); - params.append('a', 'b%c'); - assert.same(String(params), 'a=b%25c'); - params.delete('a'); - params.append('a%b', 'c'); - assert.same(String(params), 'a%25b=c'); - - params = new URLSearchParams(); - params.append('a', 'b\0c'); - assert.same(String(params), 'a=b%00c'); - params.delete('a'); - params.append('a\0b', 'c'); - assert.same(String(params), 'a%00b=c'); - - params = new URLSearchParams(); - params.append('a', 'b\uD83D\uDCA9c'); - assert.same(String(params), 'a=b%F0%9F%92%A9c'); - params.delete('a'); - params.append('a\uD83D\uDCA9b', 'c'); - assert.same(String(params), 'a%F0%9F%92%A9b=c'); - - params = new URLSearchParams('a=b&c=d&&e&&'); - assert.same(String(params), 'a=b&c=d&e='); - params = new URLSearchParams('a = b &a=b&c=d%20'); - assert.same(String(params), 'a+=+b+&a=b&c=d+'); - params = new URLSearchParams('a=&a=b'); - assert.same(String(params), 'a=&a=b'); -}); - -QUnit.test('URLSearchParams#forEach', assert => { - const { forEach } = URLSearchParams.prototype; - assert.isFunction(forEach); - assert.arity(forEach, 1); - assert.enumerable(URLSearchParams.prototype, 'forEach'); - - const expectedValues = { a: '1', b: '2', c: '3' }; - let params = new URLSearchParams('a=1&b=2&c=3'); - let result = ''; - params.forEach((value, key, that) => { - assert.same(params.get(key), expectedValues[key]); - assert.same(value, expectedValues[key]); - assert.same(that, params); - result += key; - }); - assert.same(result, 'abc'); - - new URL('http://a.b/c').searchParams.forEach(() => { - assert.ok(false, 'should not be called'); - }); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); - params = url.searchParams; - result = ''; - params.forEach((val, key) => { - url.search = 'x=1&y=2&z=3'; - result += key + val; - }); - assert.same(result, 'a1y2z3'); - } - - // fails in Chrome 66- - params = new URLSearchParams('a=1&b=2&c=3'); - result = ''; - params.forEach((value, key) => { - params.delete('b'); - result += key + value; - }); - assert.same(result, 'a1c3'); -}); - -QUnit.test('URLSearchParams#entries', assert => { - const { entries } = URLSearchParams.prototype; - assert.isFunction(entries); - assert.arity(entries, 0); - assert.enumerable(URLSearchParams.prototype, 'entries'); - - const expectedValues = { a: '1', b: '2', c: '3' }; - let params = new URLSearchParams('a=1&b=2&c=3'); - let iterator = params.entries(); - let result = ''; - let entry; - while (!(entry = iterator.next()).done) { - const [key, value] = entry.value; - assert.same(params.get(key), expectedValues[key]); - assert.same(value, expectedValues[key]); - result += key; - } - assert.same(result, 'abc'); - - assert.ok(new URL('http://a.b/c').searchParams.entries().next().done, 'should be finished'); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); - iterator = url.searchParams.entries(); - result = ''; - while (!(entry = iterator.next()).done) { - const [key, value] = entry.value; - url.search = 'x=1&y=2&z=3'; - result += key + value; - } - assert.same(result, 'a1y2z3'); - } - - // fails in Chrome 66- - params = new URLSearchParams('a=1&b=2&c=3'); - iterator = params.entries(); - result = ''; - while (!(entry = iterator.next()).done) { - params.delete('b'); - const [key, value] = entry.value; - result += key + value; - } - assert.same(result, 'a1c3'); -}); - -QUnit.test('URLSearchParams#keys', assert => { - const { keys } = URLSearchParams.prototype; - assert.isFunction(keys); - assert.arity(keys, 0); - assert.enumerable(URLSearchParams.prototype, 'keys'); - - let iterator = new URLSearchParams('a=1&b=2&c=3').keys(); - let result = ''; - let entry; - while (!(entry = iterator.next()).done) { - result += entry.value; - } - assert.same(result, 'abc'); - - assert.ok(new URL('http://a.b/c').searchParams.keys().next().done, 'should be finished'); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); - iterator = url.searchParams.keys(); - result = ''; - while (!(entry = iterator.next()).done) { - const key = entry.value; - url.search = 'x=1&y=2&z=3'; - result += key; - } - assert.same(result, 'ayz'); - } - - // fails in Chrome 66- - const params = new URLSearchParams('a=1&b=2&c=3'); - iterator = params.keys(); - result = ''; - while (!(entry = iterator.next()).done) { - params.delete('b'); - const key = entry.value; - result += key; - } - assert.same(result, 'ac'); -}); - -QUnit.test('URLSearchParams#values', assert => { - const { values } = URLSearchParams.prototype; - assert.isFunction(values); - assert.arity(values, 0); - assert.enumerable(URLSearchParams.prototype, 'values'); - - let iterator = new URLSearchParams('a=1&b=2&c=3').values(); - let result = ''; - let entry; - while (!(entry = iterator.next()).done) { - result += entry.value; - } - assert.same(result, '123'); - - assert.ok(new URL('http://a.b/c').searchParams.values().next().done, 'should be finished'); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=a&b=b&c=c&d=d'); - iterator = url.searchParams.keys(); - result = ''; - while (!(entry = iterator.next()).done) { - const { value } = entry; - url.search = 'x=x&y=y&z=z'; - result += value; - } - assert.same(result, 'ayz'); - } - - // fails in Chrome 66- - const params = new URLSearchParams('a=1&b=2&c=3'); - iterator = params.values(); - result = ''; - while (!(entry = iterator.next()).done) { - params.delete('b'); - const key = entry.value; - result += key; - } - assert.same(result, '13'); -}); - -QUnit.test('URLSearchParams#@@iterator', assert => { - const entries = URLSearchParams.prototype[Symbol.iterator]; - assert.isFunction(entries); - assert.arity(entries, 0); - - assert.same(entries, URLSearchParams.prototype.entries); - - const expectedValues = { a: '1', b: '2', c: '3' }; - let params = new URLSearchParams('a=1&b=2&c=3'); - let iterator = params[Symbol.iterator](); - let result = ''; - let entry; - while (!(entry = iterator.next()).done) { - const [key, value] = entry.value; - assert.same(params.get(key), expectedValues[key]); - assert.same(value, expectedValues[key]); - result += key; - } - assert.same(result, 'abc'); - - assert.ok(new URL('http://a.b/c').searchParams[Symbol.iterator]().next().done, 'should be finished'); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); - iterator = url.searchParams[Symbol.iterator](); - result = ''; - while (!(entry = iterator.next()).done) { - const [key, value] = entry.value; - url.search = 'x=1&y=2&z=3'; - result += key + value; - } - assert.same(result, 'a1y2z3'); - } - - // fails in Chrome 66- - params = new URLSearchParams('a=1&b=2&c=3'); - iterator = params[Symbol.iterator](); - result = ''; - while (!(entry = iterator.next()).done) { - params.delete('b'); - const [key, value] = entry.value; - result += key + value; - } - assert.same(result, 'a1c3'); -}); diff --git a/tests/pure/web.url.js b/tests/pure/web.url.js deleted file mode 100644 index ab6d5d6f3bb0..000000000000 --- a/tests/pure/web.url.js +++ /dev/null @@ -1,660 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; -import urlTestData from '../wpt-url-resources/urltestdata'; -import settersTestData from '../wpt-url-resources/setters'; -import toASCIITestData from '../wpt-url-resources/toascii'; - -import { URL, URLSearchParams } from 'core-js-pure'; - -const { hasOwnProperty } = Object.prototype; - -QUnit.test('URL constructor', assert => { - assert.isFunction(URL); - assert.arity(URL, 1); - - assert.same(String(new URL('http://www.domain.com/a/b')), 'http://www.domain.com/a/b'); - assert.same(String(new URL('/c/d', 'http://www.domain.com/a/b')), 'http://www.domain.com/c/d'); - assert.same(String(new URL('b/c', 'http://www.domain.com/a/b')), 'http://www.domain.com/a/b/c'); - assert.same(String(new URL('b/c', new URL('http://www.domain.com/a/b'))), 'http://www.domain.com/a/b/c'); - assert.same(String(new URL({ toString: () => 'https://example.org/' })), 'https://example.org/'); - - assert.same(String(new URL('nonspecial://example.com/')), 'nonspecial://example.com/'); - - assert.same(String(new URL('https://xn--g6w251d/')), 'https://xn--g6w251d/', 'unicode parsing'); - assert.same(String(new URL('https://xn--xx-flcmn5bht.xn--e1aybc/')), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - assert.same(String(new URL('https://xn--xx-flcmn5bht.xn--e1aybc/')), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - assert.same(String(new URL('http://example.com/', 'https://example.org/')), 'http://example.com/'); - assert.same(String(new URL('https://example.com/', 'https://example.org/')), 'https://example.com/'); - assert.same(String(new URL('nonspecial://Example.com/', 'https://example.org/')), 'nonspecial://Example.com/'); - assert.same(String(new URL('http:Example.com/', 'https://example.org/')), 'http://example.com/'); - assert.same(String(new URL('https:Example.com/', 'https://example.org/')), 'https://example.org/Example.com/'); - assert.same(String(new URL('nonspecial:Example.com/', 'https://example.org/')), 'nonspecial:Example.com/'); - - assert.same(String(new URL('http://192.168.0.240/')), 'http://192.168.0.240/'); - assert.same(String(new URL('http://[20:0:0:1::ff]/')), 'http://[20:0:0:1::ff]/'); - // assert.same(String(new URL('http://257.168.0xF0')), 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // TypeError in Chrome and Safari - assert.same(String(new URL('http://0300.168.0xg0/')), 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); - - assert.same(String(new URL('file:///var/log/system.log')), 'file:///var/log/system.log', 'file scheme'); - // assert.same(String(new URL('file://nnsc.nsf.net/bar/baz')), 'file://nnsc.nsf.net/bar/baz', 'file scheme'); // 'file:///bar/baz' in FF - // assert.same(String(new URL('file://localhost/bar/baz')), 'file:///bar/baz', 'file scheme'); // 'file://localhost/bar/baz' in Chrome - - assert.throws(() => new URL(), 'TypeError: Failed to construct \'URL\': 1 argument required, but only 0 present.'); - assert.throws(() => new URL(''), 'TypeError: Failed to construct \'URL\': Invalid URL'); - assert.throws(() => new URL('', 'about:blank'), 'TypeError: Failed to construct \'URL\': Invalid URL'); - assert.throws(() => new URL('abc'), 'TypeError: Failed to construct \'URL\': Invalid URL'); - assert.throws(() => new URL('//abc'), 'TypeError: Failed to construct \'URL\': Invalid URL'); - assert.throws(() => new URL('http://www.domain.com/', 'abc'), 'TypeError: Failed to construct \'URL\': Invalid base URL'); - assert.throws(() => new URL('http://www.domain.com/', null), 'TypeError: Failed to construct \'URL\': Invalid base URL'); - assert.throws(() => new URL('//abc', null), 'TypeError: Failed to construct \'URL\': Invalid base URL'); - assert.throws(() => new URL('http://[20:0:0:1:0:0:0:ff'), 'incorrect IPv6'); - assert.throws(() => new URL('http://[20:0:0:1:0:0:0:fg]'), 'incorrect IPv6'); - // assert.throws(() => new URL('http://a%b'), 'forbidden host code point'); // no error in FF - assert.throws(() => new URL('1http://zloirock.ru'), 'incorrect scheme'); -}); - -QUnit.test('URL#href', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'href')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'href'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.href, 'http://zloirock.ru/'); - - if (DESCRIPTORS) { - url.searchParams.append('foo', 'bar'); - assert.same(url.href, 'http://zloirock.ru/?foo=bar'); - - url = new URL('http://zloirock.ru/foo'); - url.href = 'https://xn--g6w251d/'; - assert.same(url.href, 'https://xn--g6w251d/', 'unicode parsing'); - assert.same(String(url), 'https://xn--g6w251d/', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.href = 'https://xn--xx-flcmn5bht.xn--e1aybc/'; - assert.same(url.href, 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - assert.same(String(url), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.href = 'https://xn--xx-flcmn5bht.xn--e1aybc/'; - assert.same(url.href, 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - assert.same(String(url), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - - url = new URL('http://zloirock.ru/'); - url.href = 'http://192.168.0.240/'; - assert.same(url.href, 'http://192.168.0.240/'); - assert.same(String(url), 'http://192.168.0.240/'); - - url = new URL('http://zloirock.ru/'); - url.href = 'http://[20:0:0:1::ff]/'; - assert.same(url.href, 'http://[20:0:0:1::ff]/'); - assert.same(String(url), 'http://[20:0:0:1::ff]/'); - - // url = new URL('http://zloirock.ru/'); - // url.href = 'http://257.168.0xF0'; // TypeError and Safari - // assert.same(url.href, 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // `F` instead of `f` in Chrome - // assert.same(String(url), 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // `F` instead of `f` in Chrome - - url = new URL('http://zloirock.ru/'); - url.href = 'http://0300.168.0xg0/'; - assert.same(url.href, 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); - assert.same(String(url), 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); - - url = new URL('http://192.168.0.240/'); - url.href = 'file:///var/log/system.log'; - assert.same(url.href, 'file:///var/log/system.log', 'file -> ip'); - assert.same(String(url), 'file:///var/log/system.log', 'file -> ip'); - - url = new URL('file:///var/log/system.log'); - url.href = 'http://192.168.0.240/'; - assert.same(url.href, 'http://192.168.0.240/', 'file -> http'); - assert.same(String(url), 'http://192.168.0.240/', 'file -> http'); - - // assert.throws(() => new URL('http://zloirock.ru/').href = undefined, 'incorrect URL'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = '', 'incorrect URL'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = 'abc', 'incorrect URL'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = '//abc', 'incorrect URL'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://[20:0:0:1:0:0:0:ff', 'incorrect IPv6'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://[20:0:0:1:0:0:0:fg]', 'incorrect IPv6'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://a%b', 'forbidden host code point'); // no error in Chrome and FF - // assert.throws(() => new URL('http://zloirock.ru/').href = '1http://zloirock.ru', 'incorrect scheme'); // no error in Chrome - } -}); - -QUnit.test('URL#origin', assert => { - const url = new URL('http://es6.zloirock.ru/tests.html'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'origin')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'origin'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - } - - assert.same(url.origin, 'http://es6.zloirock.ru/'); - - assert.same(new URL('https://xn--g6w251d/tests').origin, 'https://xn--g6w251d/'); -}); - -QUnit.test('URL#protocol', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'protocol')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'protocol'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.protocol, 'http:'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.protocol = 'https'; - assert.same(url.protocol, 'https:'); - assert.same(String(url), 'https://zloirock.ru/'); - - // https://nodejs.org/api/url.html#url_special_schemes - // url = new URL('http://zloirock.ru/'); - // url.protocol = 'fish'; - // assert.same(url.protocol, 'http:'); - // assert.same(url.href, 'http://zloirock.ru/'); - // assert.same(String(url), 'http://zloirock.ru/'); - - url = new URL('http://zloirock.ru/'); - url.protocol = '1http'; - assert.same(url.protocol, 'http:'); - assert.same(url.href, 'http://zloirock.ru/', 'incorrect scheme'); - assert.same(String(url), 'http://zloirock.ru/', 'incorrect scheme'); - } -}); - -QUnit.test('URL#username', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'username')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'username'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.username, ''); - - url = new URL('http://username@zloirock.ru/'); - assert.same(url.username, 'username'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.username = 'username'; - assert.same(url.username, 'username'); - assert.same(String(url), 'http://username@zloirock.ru/'); - } -}); - -QUnit.test('URL#password', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'password')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'password'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.password, ''); - - url = new URL('http://username:password@zloirock.ru/'); - assert.same(url.password, 'password'); - - // url = new URL('http://:password@zloirock.ru/'); // TypeError in FF - // assert.same(url.password, 'password'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.username = 'username'; - url.password = 'password'; - assert.same(url.password, 'password'); - assert.same(String(url), 'http://username:password@zloirock.ru/'); - - // url = new URL('http://zloirock.ru/'); - // url.password = 'password'; - // assert.same(url.password, 'password'); // '' in FF - // assert.same(String(url), 'http://:password@zloirock.ru/'); // 'http://zloirock.ru/' in FF - } -}); - -QUnit.test('URL#host', assert => { - let url = new URL('http://zloirock.ru:81/path'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'host')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'host'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.host, 'zloirock.ru:81'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru:81/path'); - url.host = 'example.com:82'; - assert.same(url.host, 'example.com:82'); - assert.same(String(url), 'http://example.com:82/path'); - - // url = new URL('http://zloirock.ru:81/path'); - // url.host = 'other?domain.com'; - // assert.same(String(url), 'http://other:81/path'); // 'http://other/?domain.com/path' in Safari - - url = new URL('https://www.mydomain.com:8080/path/'); - url.host = 'www.otherdomain.com:80'; - assert.same(url.href, 'https://www.otherdomain.com:80/path/', 'set default port for another protocol'); - - // url = new URL('https://www.mydomain.com:8080/path/'); - // url.host = 'www.otherdomain.com:443'; - // assert.same(url.href, 'https://www.otherdomain.com/path/', 'set default port'); - - url = new URL('http://zloirock.ru/foo'); - url.host = '測試'; - assert.same(url.host, 'xn--g6w251d', 'unicode parsing'); - assert.same(String(url), 'http://xn--g6w251d/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.host = 'xxпривет.тест'; - assert.same(url.host, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); - assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.host = 'xxПРИВЕТ.тест'; - assert.same(url.host, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); - assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.host = '0300.168.0xF0'; - assert.same(url.host, '192.168.0.240'); - assert.same(String(url), 'http://192.168.0.240/foo'); - - // url = new URL('http://zloirock.ru/foo'); - // url.host = '[20:0:0:1:0:0:0:ff]'; - // assert.same(url.host, '[20:0:0:1::ff]'); // ':0' in Chrome, 'zloirock.ru' in Safari - // assert.same(String(url), 'http://[20:0:0:1::ff]/foo'); // 'http://[20:0/foo' in Chrome, 'http://zloirock.ru/foo' in Safari - - // url = new URL('file:///var/log/system.log'); - // url.host = 'nnsc.nsf.net'; // does not work in FF - // assert.same(url.hostname, 'nnsc.nsf.net', 'file'); - // assert.same(String(url), 'file://nnsc.nsf.net/var/log/system.log', 'file'); - - // url = new URL('http://zloirock.ru/'); - // url.host = '[20:0:0:1:0:0:0:ff'; - // assert.same(url.host, 'zloirock.ru', 'incorrect IPv6'); // ':0' in Chrome - // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0/' in Chrome - - // url = new URL('http://zloirock.ru/'); - // url.host = '[20:0:0:1:0:0:0:fg]'; - // assert.same(url.host, 'zloirock.ru', 'incorrect IPv6'); // ':0' in Chrome - // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0/' in Chrome - - // url = new URL('http://zloirock.ru/'); - // url.host = 'a%b'; - // assert.same(url.host, 'zloirock.ru', 'forbidden host code point'); // '' in Chrome, 'a%b' in FF - // assert.same(String(url), 'http://zloirock.ru/', 'forbidden host code point'); // 'http://a%25b/' in Chrome, 'http://a%b/' in FF - } -}); - -QUnit.test('URL#hostname', assert => { - let url = new URL('http://zloirock.ru:81/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'hostname')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'hostname'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.hostname, 'zloirock.ru'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru:81/'); - url.hostname = 'example.com'; - assert.same(url.hostname, 'example.com'); - assert.same(String(url), 'http://example.com:81/'); - - // url = new URL('http://zloirock.ru:81/'); - // url.hostname = 'example.com:82'; - // assert.same(url.hostname, 'example.com'); // '' in Chrome - // assert.same(String(url), 'http://example.com:81/'); // 'ttp://example.com:82:81/' in Chrome - - url = new URL('http://zloirock.ru/foo'); - url.hostname = '測試'; - assert.same(url.hostname, 'xn--g6w251d', 'unicode parsing'); - assert.same(String(url), 'http://xn--g6w251d/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.hostname = 'xxпривет.тест'; - assert.same(url.hostname, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); - assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.hostname = 'xxПРИВЕТ.тест'; - assert.same(url.hostname, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); - assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.hostname = '0300.168.0xF0'; - assert.same(url.hostname, '192.168.0.240'); - assert.same(String(url), 'http://192.168.0.240/foo'); - - // url = new URL('http://zloirock.ru/foo'); - // url.hostname = '[20:0:0:1:0:0:0:ff]'; - // assert.same(url.hostname, '[20:0:0:1::ff]'); // 'zloirock.ru' in Safari - // assert.same(String(url), 'http://[20:0:0:1::ff]/foo'); // 'http://zloirock.ru/foo' in Safari - - // url = new URL('file:///var/log/system.log'); - // url.hostname = 'nnsc.nsf.net'; // does not work in FF - // assert.same(url.hostname, 'nnsc.nsf.net', 'file'); - // assert.same(String(url), 'file://nnsc.nsf.net/var/log/system.log', 'file'); - - // url = new URL('http://zloirock.ru/'); - // url.hostname = '[20:0:0:1:0:0:0:ff'; - // assert.same(url.hostname, 'zloirock.ru', 'incorrect IPv6'); // '' in Chrome - // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0:0:1:0:0:0:ff' in Chrome - - // url = new URL('http://zloirock.ru/'); - // url.hostname = '[20:0:0:1:0:0:0:fg]'; - // assert.same(url.hostname, 'zloirock.ru', 'incorrect IPv6'); // '' in Chrome - // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0:0:1:0:0:0:ff/' in Chrome - - // url = new URL('http://zloirock.ru/'); - // url.hostname = 'a%b'; - // assert.same(url.hostname, 'zloirock.ru', 'forbidden host code point'); // '' in Chrome, 'a%b' in FF - // assert.same(String(url), 'http://zloirock.ru/', 'forbidden host code point'); // 'http://a%25b/' in Chrome, 'http://a%b/' in FF - } -}); - -QUnit.test('URL#port', assert => { - let url = new URL('http://zloirock.ru:1337/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'port')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'port'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.port, '1337'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.port = 80; - assert.same(url.port, ''); - assert.same(String(url), 'http://zloirock.ru/'); - url.port = 1337; - assert.same(url.port, '1337'); - assert.same(String(url), 'http://zloirock.ru:1337/'); - // url.port = 'abcd'; - // assert.same(url.port, '1337'); // '0' in Chrome - // assert.same(String(url), 'http://zloirock.ru:1337/'); // 'http://zloirock.ru:0/' in Chrome - // url.port = '5678abcd'; - // assert.same(url.port, '5678'); // '1337' in FF - // assert.same(String(url), 'http://zloirock.ru:5678/'); // 'http://zloirock.ru:1337/"' in FF - url.port = 1234.5678; - assert.same(url.port, '1234'); - assert.same(String(url), 'http://zloirock.ru:1234/'); - // url.port = 1e10; - // assert.same(url.port, '1234'); // '0' in Chrome - // assert.same(String(url), 'http://zloirock.ru:1234/'); // 'http://zloirock.ru:0/' in Chrome - } -}); - -QUnit.test('URL#pathname', assert => { - let url = new URL('http://zloirock.ru/foo/bar'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'pathname')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'pathname'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.pathname, '/foo/bar'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.pathname = 'bar/baz'; - assert.same(url.pathname, '/bar/baz'); - assert.same(String(url), 'http://zloirock.ru/bar/baz'); - } -}); - -QUnit.test('URL#search', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'search')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'search'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.search, ''); - - url = new URL('http://zloirock.ru/?foo=bar'); - assert.same(url.search, '?foo=bar'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/?'); - assert.same(url.search, ''); - assert.same(String(url), 'http://zloirock.ru/?'); - url.search = 'foo=bar'; - assert.same(url.search, '?foo=bar'); - assert.same(String(url), 'http://zloirock.ru/?foo=bar'); - url.search = '?bar=baz'; - assert.same(url.search, '?bar=baz'); - assert.same(String(url), 'http://zloirock.ru/?bar=baz'); - url.search = ''; - assert.same(url.search, ''); - assert.same(String(url), 'http://zloirock.ru/'); - } -}); - -QUnit.test('URL#searchParams', assert => { - let url = new URL('http://zloirock.ru/?foo=bar&bar=baz'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'searchParams')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'searchParams'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - } - - assert.ok(url.searchParams instanceof URLSearchParams); - assert.same(url.searchParams.get('foo'), 'bar'); - assert.same(url.searchParams.get('bar'), 'baz'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.searchParams.append('foo', 'bar'); - assert.same(String(url), 'http://zloirock.ru/?foo=bar'); - - url = new URL('http://zloirock.ru/'); - url.search = 'foo=bar'; - assert.same(url.searchParams.get('foo'), 'bar'); - - url = new URL('http://zloirock.ru/?foo=bar&bar=baz'); - url.search = ''; - assert.same(url.searchParams.has('foo'), false); - } -}); - -QUnit.test('URL#hash', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'hash')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'hash'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.hash, ''); - - url = new URL('http://zloirock.ru/#foo'); - assert.same(url.hash, '#foo'); - - url = new URL('http://zloirock.ru/#'); - assert.same(url.hash, ''); - assert.same(String(url), 'http://zloirock.ru/#'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/#'); - url.hash = 'foo'; - assert.same(url.hash, '#foo'); - assert.same(String(url), 'http://zloirock.ru/#foo'); - url.hash = ''; - assert.same(url.hash, ''); - assert.same(String(url), 'http://zloirock.ru/'); - // url.hash = '#'; - // assert.same(url.hash, ''); - // assert.same(String(url), 'http://zloirock.ru/'); // 'http://zloirock.ru/#' in FF - url.hash = '#foo'; - assert.same(url.hash, '#foo'); - assert.same(String(url), 'http://zloirock.ru/#foo'); - url.hash = '#foo#bar'; - assert.same(url.hash, '#foo#bar'); - assert.same(String(url), 'http://zloirock.ru/#foo#bar'); - - url = new URL('http://zloirock.ru/'); - url.hash = 'абa'; - assert.same(url.hash, '#%D0%B0%D0%B1a'); - - // url = new URL('http://zloirock.ru/'); - // url.hash = '\udc01\ud802a'; - // assert.same(url.hash, '#%EF%BF%BD%EF%BF%BDa', 'unmatched surrogates'); - } -}); - -QUnit.test('URL#toJSON', assert => { - const { toJSON } = URL.prototype; - assert.isFunction(toJSON); - assert.arity(toJSON, 0); - assert.enumerable(URL.prototype, 'toJSON'); - - const url = new URL('http://zloirock.ru/'); - assert.same(url.toJSON(), 'http://zloirock.ru/'); - - if (DESCRIPTORS) { - url.searchParams.append('foo', 'bar'); - assert.same(url.toJSON(), 'http://zloirock.ru/?foo=bar'); - } -}); - -QUnit.test('URL#toString', assert => { - const { toString } = URL.prototype; - assert.isFunction(toString); - assert.arity(toString, 0); - assert.enumerable(URL.prototype, 'toString'); - - const url = new URL('http://zloirock.ru/'); - assert.same(url.toString(), 'http://zloirock.ru/'); - - if (DESCRIPTORS) { - url.searchParams.append('foo', 'bar'); - assert.same(url.toString(), 'http://zloirock.ru/?foo=bar'); - } -}); - -QUnit.test('URL.sham', assert => { - assert.same(URL.sham, DESCRIPTORS ? undefined : true); -}); - -// `core-js` URL implementation pass all (exclude some encoding-ralated) tests -// from the next 3 test cases, but URLs from all of popular browsers fail a serious part of tests. -// Replacing all of them does not looks like a good idea, so next test cases disabled by default. - -// see https://github.com/web-platform-tests/wpt/blob/master/url -QUnit.skip('WPT URL constructor tests', assert => { - for (const expected of urlTestData) { - if (typeof expected == 'string') continue; - const name = `Parsing: <${ expected.input }> against <${ expected.base }>`; - if (expected.failure) { - assert.throws(() => new URL(expected.input, expected.base || 'about:blank'), name); - } else { - const url = new URL(expected.input, expected.base || 'about:blank'); - assert.same(url.href, expected.href, `${ name }: href`); - assert.same(url.protocol, expected.protocol, `${ name }: protocol`); - assert.same(url.username, expected.username, `${ name }: username`); - assert.same(url.password, expected.password, `${ name }: password`); - assert.same(url.host, expected.host, `${ name }: host`); - assert.same(url.hostname, expected.hostname, `${ name }: hostname`); - assert.same(url.port, expected.port, `${ name }: port`); - assert.same(url.pathname, expected.pathname, `${ name }: pathname`); - assert.same(url.search, expected.search, `${ name }: search`); - if ('searchParams' in expected) { - assert.same(url.searchParams.toString(), expected.searchParams, `${ name }: searchParams`); - } - assert.same(url.hash, expected.hash, `${ name }: hash`); - if ('origin' in expected) { - assert.same(url.origin, expected.origin, `${ name }: origin`); - } - } - } -}); - -// see https://github.com/web-platform-tests/wpt/blob/master/url -if (DESCRIPTORS) QUnit.skip('WPT URL setters tests', assert => { - for (const setter in settersTestData) { - const testCases = settersTestData[setter]; - for (const { href, newValue, comment, expected } of testCases) { - let name = `Setting <${ href }>.${ setter } = '${ newValue }'.`; - if (comment) name += ` ${ comment }`; - - const url = new URL(href); - url[setter] = newValue; - for (const attribute in expected) { - assert.same(url[attribute], expected[attribute], name); - } - } - } -}); - -// see https://github.com/web-platform-tests/wpt/blob/master/url -QUnit.skip('WPT conversion to ASCII tests', assert => { - for (const { comment, input, output } of toASCIITestData) { - let name = `Parsing: <${ input }>`; - if (comment) name += ` ${ comment }`; - if (output === null) { - assert.throws(() => new URL(`https://${ input }/x`), name); - } else { - const url = new URL(`https://${ input }/x`); - assert.same(url.host, output, name); - assert.same(url.hostname, output, name); - assert.same(url.pathname, '/x', name); - assert.same(url.href, `https://${ output }/x`, name); - } - } -}); diff --git a/tests/test262/package-lock.json b/tests/test262/package-lock.json new file mode 100644 index 000000000000..2f33139060a4 --- /dev/null +++ b/tests/test262/package-lock.json @@ -0,0 +1,1212 @@ +{ + "name": "test262", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "test262", + "devDependencies": { + "test262": "tc39/test262#f95832e793861fddbb2b84861c05fd21706adf6c", + "test262-harness": "^10.0.0" + } + }, + "node_modules/@bazel/runfiles": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@bazel/runfiles/-/runfiles-6.5.0.tgz", + "integrity": "sha512-RzahvqTkfpY2jsDxo8YItPX+/iZ6hbiikw1YhE0bA9EKBR5Og8Pa6FHn9PO9M0zaXRVsr0GFQLKbB/0rzy9SzA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/after": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", + "integrity": "sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arraybuffer.slice": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", + "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "dev": true, + "license": "MIT" + }, + "node_modules/ast-types": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.12.4.tgz", + "integrity": "sha512-ky/YVYCbtVAS8TdMIaTiPFHwEpRB5z1hctepJplTr3UW5q8TDrpIMCILyk8pmLxGtn2KCtC/lSn7zOsaI7nzDw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/backo2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", + "integrity": "sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-arraybuffer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz", + "integrity": "sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/blob": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/component-bind": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", + "integrity": "sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/component-inherit": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", + "integrity": "sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true, + "license": "MIT" + }, + "node_modules/engine.io": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.6.2.tgz", + "integrity": "sha512-C4JjGQZLY3kWlIDx0BQNKizbrfpb7NahxDztGdN5jrPK2ghmXiNDN+E/t0JzDeNRZxPVaszxEng42Pmj27X/0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.4.1", + "debug": "~4.1.0", + "engine.io-parser": "~2.2.0", + "ws": "~7.5.10" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/engine.io-client": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.5.tgz", + "integrity": "sha512-4qE5ECwT5N+Q1F2obOkW3A8ikiWtgWkKquB08ppCY06YPj0qY1GXL5u3XeMzfyX6sXEJz+raweshqDGZQ+wY/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "~1.3.0", + "component-inherit": "0.0.3", + "debug": "~3.1.0", + "engine.io-parser": "~2.2.0", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "ws": "~7.5.10", + "xmlhttprequest-ssl": "~1.6.2", + "yeast": "0.1.2" + } + }, + "node_modules/engine.io-client/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/engine.io-client/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/engine.io-client/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/engine.io-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.2.1.tgz", + "integrity": "sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.4", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "node_modules/engine.io/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/error-stack-parser": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz", + "integrity": "sha512-xhuSYd8wLgOXwNgjcPeXMPL/IiiA1Huck+OPvClpJViVNNlJVtM41o+1emp7bPvlCJwCatFX2DWc05/DgfbWzA==", + "dev": true, + "license": "Unlicense", + "dependencies": { + "stackframe": "^0.3.1" + } + }, + "node_modules/eshost": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eshost/-/eshost-9.0.0.tgz", + "integrity": "sha512-hq1phapnwdDoBO/o5PhcGoex9ueAY2xlQEcvA0zq/u4J+yUypFnBEh1gZABLlmdM1ZmOBDbjawUb/ICDdvyJVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-stack-parser": "^1.3.3", + "is-symlink": "^0.1.1", + "recast": "^0.17.5", + "selenium-webdriver": "^4.0.0-alpha.1", + "server-destroy": "^1.0.1", + "socket.io": "^2.3.0", + "unique-temp-dir": "^1.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-binary2": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", + "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "2.0.1" + } + }, + "node_modules/has-binary2/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-cors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", + "integrity": "sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/indexof": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", + "integrity": "sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==", + "dev": true + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/is-symlink": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-symlink/-/is-symlink-0.1.1.tgz", + "integrity": "sha512-HAC7xFRN4t4mVutcQfWzwAFNlD8tQFUSVwOeBLbTtgUf+Lb74AfhMT54ZcsYZ1vB5T08BLJH2z8y8im5lLcCMg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/klaw": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-2.1.1.tgz", + "integrity": "sha512-kuInGWCNc98b1ghOqBJfqPOvAKn9HHgm+SdluR5VNfdA7rs7uNsuXGy7CCqsP6pFKPpUoCH4s9o00GEj9xONHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, + "node_modules/parseqs": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.6.tgz", + "integrity": "sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==", + "dev": true, + "license": "MIT" + }, + "node_modules/parseuri": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.6.tgz", + "integrity": "sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/recast": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.17.6.tgz", + "integrity": "sha512-yoQRMRrK1lszNtbkGyM4kN45AwylV5hMiuEveUBlxytUViWevjvX6w+tzJt1LH4cfUhWt4NZvy3ThIhu6+m5wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ast-types": "0.12.4", + "esprima": "~4.0.0", + "private": "^0.1.8", + "source-map": "~0.6.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true, + "license": "ISC" + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/selenium-webdriver": { + "version": "4.38.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.38.0.tgz", + "integrity": "sha512-5/UXXFSQmn7FGQkbcpAqvfhzflUdMWtT7QqpEgkFD6Q6rDucxB5EUfzgjmr6JbUj30QodcW3mDXehzoeS/Vy5w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/SeleniumHQ" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/selenium" + } + ], + "license": "Apache-2.0", + "dependencies": { + "@bazel/runfiles": "^6.3.1", + "jszip": "^3.10.1", + "tmp": "^0.2.5", + "ws": "^8.18.3" + }, + "engines": { + "node": ">= 20.0.0" + } + }, + "node_modules/server-destroy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", + "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true, + "license": "ISC" + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.5.1.tgz", + "integrity": "sha512-eaTE4tBKRD6RFoetquMbxgvcpvoDtRyIlkIMI/SMK2bsKvbENTsDeeu4GJ/z9c90yOWxB7b/eC+yKLPbHnH6bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.1.0", + "engine.io": "~3.6.0", + "has-binary2": "~1.0.2", + "socket.io-adapter": "~1.1.0", + "socket.io-client": "2.5.0", + "socket.io-parser": "~3.4.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.2.tgz", + "integrity": "sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io-client": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.5.0.tgz", + "integrity": "sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "backo2": "1.0.2", + "component-bind": "1.0.0", + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "engine.io-client": "~3.5.0", + "has-binary2": "~1.0.2", + "indexof": "0.0.1", + "parseqs": "0.0.6", + "parseuri": "0.0.6", + "socket.io-parser": "~3.3.0", + "to-array": "0.1.4" + } + }, + "node_modules/socket.io-client/node_modules/debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/socket.io-client/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io-client/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io-client/node_modules/socket.io-parser": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.4.tgz", + "integrity": "sha512-z/pFQB3x+EZldRRzORYW1vwVO8m/3ILkswtnpoeU6Ve3cbMWkmHEWDAVJn4QJtchiiFTo5j7UG2QvwxvaA9vow==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "~1.3.0", + "debug": "~3.1.0", + "isarray": "2.0.1" + } + }, + "node_modules/socket.io-parser": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.4.3.tgz", + "integrity": "sha512-1rE4dZN3kCI/E5wixd393hmbqa78vVpkKmnEJhLeWoS/C5hbFYAbcSfnWoaVH43u9ToUVtzKjguxEZq+1XZfCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "1.2.1", + "debug": "~4.1.0", + "isarray": "2.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io-parser/node_modules/isarray": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", + "integrity": "sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stackframe": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz", + "integrity": "sha512-XmoiF4T5nuWEp2x2w92WdGjdHGY/cZa6LIbRsDRQR/Xlk4uW0PAUlH1zJYVffocwKpCdwyuypIp25xsSXEtZHw==", + "dev": true, + "license": "SEE LICENSE IN LICENSE" + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/test262": { + "version": "5.0.0", + "resolved": "git+ssh://git@github.com/tc39/test262.git#f95832e793861fddbb2b84861c05fd21706adf6c", + "integrity": "sha512-vWEuc0LURL/mJWi5nG726OKQN9Xc6wnnAnJe2fvreNh9U0DF6h9Xp8EMQJnHcWU7AwDn5OtCummEDl9NKQGXnw==", + "dev": true, + "license": "BSD" + }, + "node_modules/test262-harness": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/test262-harness/-/test262-harness-10.0.0.tgz", + "integrity": "sha512-ntNOi+q6NMXYNAa7nwg7IgP+8ahcdqvPvkEUu6TN38nkTHIBjB/KY5jLIUD70Qk4EKd15rHHfSGDc1SVdblj4w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "eshost": "^9.0.0", + "minimatch": "^3.0.4", + "rxjs": "^6.4.0", + "test262-stream": "^1.3.0", + "yargs": "^13.2.2" + }, + "bin": { + "test262-harness": "bin/run.js" + } + }, + "node_modules/test262-stream": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/test262-stream/-/test262-stream-1.4.0.tgz", + "integrity": "sha512-s364askxqgyWAtIwvYCG5nYT3P32g9ByEt1ML49ubFlPE52GA6fG5ZZGmf4y/YJgKtppRAZZ7YVd9NOsk1oUxA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "js-yaml": "^3.2.1", + "klaw": "^2.1.0" + } + }, + "node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-array": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", + "integrity": "sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==", + "dev": true + }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true, + "license": "0BSD" + }, + "node_modules/uid2": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", + "integrity": "sha512-5gSP1liv10Gjp8cMEnFd6shzkL/D6W1uhXSFNCxDC+YI8+L8wkCYCbJ7n77Ezb4wE/xzMogecE+DtamEe9PZjg==", + "dev": true + }, + "node_modules/unique-temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", + "integrity": "sha512-tE68ki2FndoVdPioyiz8mYaJeX3xU/9lk4dml7KlLKEkWLtDGAYeg5LGjE2dMkzB8d6R3HbcKTn/I14nukP2dw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^0.5.1", + "os-tmpdir": "^1.0.1", + "uid2": "0.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/which-module": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz", + "integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xmlhttprequest-ssl": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.6.3.tgz", + "integrity": "sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yeast": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", + "integrity": "sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/tests/test262/package.json b/tests/test262/package.json new file mode 100644 index 000000000000..04fca0470e68 --- /dev/null +++ b/tests/test262/package.json @@ -0,0 +1,7 @@ +{ + "name": "test262", + "devDependencies": { + "test262": "tc39/test262#f95832e793861fddbb2b84861c05fd21706adf6c", + "test262-harness": "^10.0.0" + } +} diff --git a/tests/test262/preprocessor.js b/tests/test262/preprocessor.js new file mode 100644 index 000000000000..7248a3b4dadf --- /dev/null +++ b/tests/test262/preprocessor.js @@ -0,0 +1,62 @@ +'use strict'; +const include = [ + 'Array', + // 'ArrayBuffer', + 'ArrayIteratorPrototype', + 'Boolean', + // 'DataView', + // 'Date', + 'Error', + 'Function/prototype', + 'Iterator', + 'JSON', + 'Map', + 'MapIteratorPrototype', + 'Math', + 'NativeErrors', + 'Number', + 'Object', + 'Promise', + 'Reflect', + 'RegExp', + 'RegExpStringIteratorPrototype', + 'Set', + 'SetIteratorPrototype', + 'String', + 'StringIteratorPrototype', + 'Symbol', + // 'TypedArray', + // 'TypedArrayConstructors', + 'WeakMap', + 'WeakSet', + 'decodeURI', + 'decodeURIComponent', + 'encodeURI', + 'encodeURIComponent', + 'escape', + 'isFinite', + 'isNaN', + 'parseFloat', + 'parseInt', + 'unescape', +]; + +const exclude = [ + '/Function/prototype/toString/', + '/Object/internals/DefineOwnProperty/', + // conflict with iterators helpers proposal + '/Object/prototype/toString/symbol-tag-non-str-builtin', + '/RegExp/property-escapes/', + 'detached-buffer', + 'detach-typedarray', + // we can't implement this behavior on methods 100% proper and compatible with ES3 + // in case of application some hacks this line will be removed + 'not-a-constructor', +]; + +module.exports = test => { + const { file } = test; + if (!include.some(namespace => file.includes(`built-ins/${ namespace }/`))) return null; + if (exclude.some(it => file.includes(it))) return null; + return test; +}; diff --git a/tests/test262/runner.mjs b/tests/test262/runner.mjs new file mode 100644 index 000000000000..f46b3d65d817 --- /dev/null +++ b/tests/test262/runner.mjs @@ -0,0 +1,17 @@ +const featuresExclude = [ + 'arraybuffer-transfer', + 'regexp-duplicate-named-groups', + 'regexp-modifiers', + 'regexp-v-flag', + 'resizable-arraybuffer', +]; + +await $`test262-harness \ + --features-exclude=${ featuresExclude.join(',') } \ + --threads=${ os.cpus().length } \ + --host-args="--unhandled-rejections=none" \ + --preprocessor=preprocessor.js \ + --prelude=../../packages/core-js-bundle/index.js \ + --test262-dir=node_modules/test262 \ + node_modules/test262/test/built-ins/**/*.js \ +`; diff --git a/tests/tests.html b/tests/tests.html deleted file mode 100644 index 13a5517bb7dd..000000000000 --- a/tests/tests.html +++ /dev/null @@ -1,13 +0,0 @@ - - -Core - -
-
- - - - - \ No newline at end of file diff --git a/tests/tests/es.array-buffer.is-view.js b/tests/tests/es.array-buffer.is-view.js deleted file mode 100644 index 821ca3e7049a..000000000000 --- a/tests/tests/es.array-buffer.is-view.js +++ /dev/null @@ -1,21 +0,0 @@ -import { GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; - -QUnit.test('ArrayBuffer.isView', assert => { - const { isView } = ArrayBuffer; - assert.isFunction(isView); - assert.arity(isView, 1); - assert.name(isView, 'isView'); - assert.looksNative(isView); - assert.nonEnumerable(ArrayBuffer, 'isView'); - for (const name in TYPED_ARRAYS) { - if (GLOBAL[name]) { - assert.same(isView(new GLOBAL[name]([1])), true, `${ name } - true`); - } - } - assert.same(isView(new DataView(new ArrayBuffer(1))), true, 'DataView - true'); - assert.same(isView(new ArrayBuffer(1)), false, 'ArrayBuffer - false'); - const examples = [undefined, null, false, true, 0, 1, '', 'qwe', {}, [], function () { /* empty */ }]; - for (const example of examples) { - assert.same(isView(example), false, `${ example } - false`); - } -}); diff --git a/tests/tests/es.array-buffer.slice.js b/tests/tests/es.array-buffer.slice.js deleted file mode 100644 index 6f6dc26fdbcd..000000000000 --- a/tests/tests/es.array-buffer.slice.js +++ /dev/null @@ -1,37 +0,0 @@ -QUnit.test('ArrayBuffer#slice', assert => { - const { slice } = ArrayBuffer.prototype; - - function arrayToBuffer(it) { - const buffer = new ArrayBuffer(it.length); - const view = new DataView(buffer); - for (let i = 0, { length } = it; i < length; ++i) { - view.setUint8(i, it[i]); - } - return buffer; - } - - function bufferToArray(it) { - const results = []; - const view = new DataView(it); - for (let i = 0, { byteLength } = view; i < byteLength; ++i) { - results.push(view.getUint8(i)); - } - return results; - } - - assert.isFunction(slice); - assert.arity(slice, 2); - assert.name(slice, 'slice'); - assert.looksNative(slice); - // assert.nonEnumerable(ArrayBuffer.prototype, 'slice'); - const buffer = arrayToBuffer([1, 2, 3, 4, 5]); - assert.ok(buffer instanceof ArrayBuffer, 'correct buffer'); - assert.ok(buffer.slice() !== buffer, 'returns new buffer'); - assert.ok(buffer.slice() instanceof ArrayBuffer, 'correct instance'); - assert.arrayEqual(bufferToArray(buffer.slice()), [1, 2, 3, 4, 5]); - assert.arrayEqual(bufferToArray(buffer.slice(1, 3)), [2, 3]); - assert.arrayEqual(bufferToArray(buffer.slice(1, undefined)), [2, 3, 4, 5]); - assert.arrayEqual(bufferToArray(buffer.slice(1, -1)), [2, 3, 4]); - assert.arrayEqual(bufferToArray(buffer.slice(-2, -1)), [4]); - assert.arrayEqual(bufferToArray(buffer.slice(-2, -3)), []); -}); diff --git a/tests/tests/es.array.concat.js b/tests/tests/es.array.concat.js deleted file mode 100644 index d5bb824a14df..000000000000 --- a/tests/tests/es.array.concat.js +++ /dev/null @@ -1,33 +0,0 @@ -/* eslint-disable no-sparse-arrays */ -QUnit.test('Array#concat', assert => { - const { concat } = Array.prototype; - assert.isFunction(concat); - assert.arity(concat, 1); - assert.name(concat, 'concat'); - assert.looksNative(concat); - assert.nonEnumerable(Array.prototype, 'concat'); - let array = [1, 2]; - const sparseArray = [1, , 2]; - const nonSpreadableArray = [1, 2]; - nonSpreadableArray[Symbol.isConcatSpreadable] = false; - const arrayLike = { 0: 1, 1: 2, length: 2 }; - const spreadableArrayLike = { 0: 1, 1: 2, length: 2, [Symbol.isConcatSpreadable]: true }; - assert.deepEqual(array.concat(), [1, 2], '#1'); - assert.deepEqual(sparseArray.concat(), [1, , 2], '#2'); - assert.deepEqual(nonSpreadableArray.concat(), [[1, 2]], '#3'); - assert.deepEqual(concat.call(arrayLike), [{ 0: 1, 1: 2, length: 2 }], '#4'); - assert.deepEqual(concat.call(spreadableArrayLike), [1, 2], '#5'); - assert.deepEqual([].concat(array), [1, 2], '#6'); - assert.deepEqual([].concat(sparseArray), [1, , 2], '#7'); - assert.deepEqual([].concat(nonSpreadableArray), [[1, 2]], '#8'); - assert.deepEqual([].concat(arrayLike), [{ 0: 1, 1: 2, length: 2 }], '#9'); - assert.deepEqual([].concat(spreadableArrayLike), [1, 2], '#10'); - assert.deepEqual(array.concat(sparseArray, nonSpreadableArray, arrayLike, spreadableArrayLike), [ - 1, 2, 1, , 2, [1, 2], { 0: 1, 1: 2, length: 2 }, 1, 2, - ], '#11'); - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(array.concat().foo, 1, '@@species'); -}); diff --git a/tests/tests/es.array.copy-within.js b/tests/tests/es.array.copy-within.js deleted file mode 100644 index a6c314bb9aa0..000000000000 --- a/tests/tests/es.array.copy-within.js +++ /dev/null @@ -1,42 +0,0 @@ -import { NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#copyWithin', assert => { - const { copyWithin } = Array.prototype; - assert.isFunction(copyWithin); - assert.arity(copyWithin, 2); - assert.name(copyWithin, 'copyWithin'); - assert.looksNative(copyWithin); - const array = [1]; - assert.strictEqual(array.copyWithin(0), array); - assert.nonEnumerable(Array.prototype, 'copyWithin'); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(0, 3), [4, 5, 3, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(1, 3), [1, 4, 5, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(1, 2), [1, 3, 4, 5, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(2, 2), [1, 2, 3, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(0, 3, 4), [4, 2, 3, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(1, 3, 4), [1, 4, 3, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(1, 2, 4), [1, 3, 4, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(0, -2), [4, 5, 3, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(0, -2, -1), [4, 2, 3, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(-4, -3, -2), [1, 3, 3, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(-4, -3, -1), [1, 3, 4, 4, 5]); - assert.deepEqual([1, 2, 3, 4, 5].copyWithin(-4, -3), [1, 3, 4, 5, 5]); - if (STRICT) { - assert.throws(() => copyWithin.call(null, 0), TypeError); - assert.throws(() => copyWithin.call(undefined, 0), TypeError); - } - if (NATIVE) { - assert.deepEqual(copyWithin.call({ - 0: 1, - 1: 2, - 2: 3, - length: -1, - }, 1, 2), { - 0: 1, - 1: 2, - 2: 3, - length: -1, - }, 'uses ToLength'); - } - assert.ok('copyWithin' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); diff --git a/tests/tests/es.array.every.js b/tests/tests/es.array.every.js deleted file mode 100644 index 49fcde75a181..000000000000 --- a/tests/tests/es.array.every.js +++ /dev/null @@ -1,43 +0,0 @@ -import { NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#every', assert => { - const { every } = Array.prototype; - assert.isFunction(every); - assert.arity(every, 1); - assert.name(every, 'every'); - assert.looksNative(every); - assert.nonEnumerable(Array.prototype, 'every'); - let array = [1]; - const context = {}; - array.every(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.ok([1, 2, 3].every(it => typeof it === 'number')); - assert.ok([1, 2, 3].every(it => it < 4)); - assert.ok(![1, 2, 3].every(it => it < 3)); - assert.ok(![1, 2, 3].every(it => typeof it === 'string')); - assert.ok([1, 2, 3].every(function () { - return +this === 1; - }, 1)); - let result = ''; - [1, 2, 3].every((value, key) => result += key); - assert.ok(result === '012'); - array = [1, 2, 3]; - assert.ok(array.every((value, key, that) => that === array)); - if (STRICT) { - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - } - if (NATIVE) { - assert.notThrows(() => every.call({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }), 'uses ToLength'); - } -}); diff --git a/tests/tests/es.array.fill.js b/tests/tests/es.array.fill.js deleted file mode 100644 index 2f56f7e0cd51..000000000000 --- a/tests/tests/es.array.fill.js +++ /dev/null @@ -1,32 +0,0 @@ -import { DESCRIPTORS, NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#fill', assert => { - const { fill } = Array.prototype; - assert.isFunction(fill); - assert.arity(fill, 1); - assert.name(fill, 'fill'); - assert.looksNative(fill); - assert.nonEnumerable(Array.prototype, 'fill'); - const array = new Array(5); - assert.strictEqual(array.fill(5), array); - assert.deepEqual(Array(5).fill(5), [5, 5, 5, 5, 5]); - assert.deepEqual(Array(5).fill(5, 1), [undefined, 5, 5, 5, 5]); - assert.deepEqual(Array(5).fill(5, 1, 4), [undefined, 5, 5, 5, undefined]); - assert.deepEqual(Array(5).fill(5, 6, 1), [undefined, undefined, undefined, undefined, undefined]); - assert.deepEqual(Array(5).fill(5, -3, 4), [undefined, undefined, 5, 5, undefined]); - assert.arrayEqual(fill.call({ length: 5 }, 5), [5, 5, 5, 5, 5]); - if (STRICT) { - assert.throws(() => fill.call(null, 0), TypeError); - assert.throws(() => fill.call(undefined, 0), TypeError); - } - if (NATIVE && DESCRIPTORS) { - assert.notThrows(() => fill.call(Object.defineProperty({ - length: -1, - }, 0, { - set() { - throw Error(); - }, - })), 'uses ToLength'); - } - assert.ok('fill' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); diff --git a/tests/tests/es.array.filter.js b/tests/tests/es.array.filter.js deleted file mode 100644 index 15ee5f0eda76..000000000000 --- a/tests/tests/es.array.filter.js +++ /dev/null @@ -1,35 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('Array#filter', assert => { - const { filter } = Array.prototype; - assert.isFunction(filter); - assert.arity(filter, 1); - assert.name(filter, 'filter'); - assert.looksNative(filter); - assert.nonEnumerable(Array.prototype, 'filter'); - let array = [1]; - const context = {}; - array.filter(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.deepEqual([1, 2, 3, 4, 5], [1, 2, 3, 'q', {}, 4, true, 5].filter(it => typeof it === 'number')); - if (STRICT) { - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - } - assert.notThrows(() => filter.call({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }), 'uses ToLength'); - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(array.filter(Boolean).foo, 1, '@@species'); -}); diff --git a/tests/tests/es.array.find-index.js b/tests/tests/es.array.find-index.js deleted file mode 100644 index 9552e85cb458..000000000000 --- a/tests/tests/es.array.find-index.js +++ /dev/null @@ -1,34 +0,0 @@ -import { DESCRIPTORS, NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#findIndex', assert => { - const { findIndex } = Array.prototype; - assert.isFunction(findIndex); - assert.arity(findIndex, 1); - assert.name(findIndex, 'findIndex'); - assert.looksNative(findIndex); - assert.nonEnumerable(Array.prototype, 'findIndex'); - const array = [1]; - const context = {}; - array.findIndex(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.same([1, 3, NaN, 42, {}].findIndex(it => it === 42), 3); - assert.same([1, 3, NaN, 42, {}].findIndex(it => it === 43), -1); - if (STRICT) { - assert.throws(() => findIndex.call(null, 0), TypeError); - assert.throws(() => findIndex.call(undefined, 0), TypeError); - } - if (NATIVE && DESCRIPTORS) { - assert.notThrows(() => findIndex.call({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }) === -1, 'uses ToLength'); - } - assert.ok('findIndex' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); diff --git a/tests/tests/es.array.find.js b/tests/tests/es.array.find.js deleted file mode 100644 index bdd8ee40f91f..000000000000 --- a/tests/tests/es.array.find.js +++ /dev/null @@ -1,34 +0,0 @@ -import { DESCRIPTORS, NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#find', assert => { - const { find } = Array.prototype; - assert.isFunction(find); - assert.arity(find, 1); - assert.name(find, 'find'); - assert.looksNative(find); - assert.nonEnumerable(Array.prototype, 'find'); - const array = [1]; - const context = {}; - array.find(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.same([1, 3, NaN, 42, {}].find(it => it === 42), 42); - assert.same([1, 3, NaN, 42, {}].find(it => it === 43), undefined); - if (STRICT) { - assert.throws(() => find.call(null, 0), TypeError); - assert.throws(() => find.call(undefined, 0), TypeError); - } - if (NATIVE && DESCRIPTORS) { - assert.notThrows(() => find.call({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }) === undefined, 'uses ToLength'); - } - assert.ok('find' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); diff --git a/tests/tests/es.array.flat-map.js b/tests/tests/es.array.flat-map.js deleted file mode 100644 index 351bb08db14a..000000000000 --- a/tests/tests/es.array.flat-map.js +++ /dev/null @@ -1,32 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('Array#flatMap', assert => { - const { flatMap } = Array.prototype; - assert.isFunction(flatMap); - assert.name(flatMap, 'flatMap'); - assert.arity(flatMap, 1); - assert.looksNative(flatMap); - assert.nonEnumerable(Array.prototype, 'flatMap'); - assert.deepEqual([].flatMap(it => it), []); - assert.deepEqual([1, 2, 3].flatMap(it => it), [1, 2, 3]); - assert.deepEqual([1, 2, 3].flatMap(it => [it, it]), [1, 1, 2, 2, 3, 3]); - assert.deepEqual([1, 2, 3].flatMap(it => [[it], [it]]), [[1], [1], [2], [2], [3], [3]]); - assert.deepEqual([1, [2, 3]].flatMap(() => 1), [1, 1]); - const array = [1]; - const context = {}; - array.flatMap(function (value, key, that) { - assert.same(value, 1); - assert.same(key, 0); - assert.same(that, array); - assert.same(this, context); - return value; - }, context); - if (STRICT) { - assert.throws(() => flatMap.call(null, it => it), TypeError); - assert.throws(() => flatMap.call(undefined, it => it), TypeError); - } - assert.notThrows(() => flatMap.call({ length: -1 }, () => { - throw new Error(); - }).length === 0, 'uses ToLength'); - assert.ok('flatMap' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); diff --git a/tests/tests/es.array.flat.js b/tests/tests/es.array.flat.js deleted file mode 100644 index 06ebc93a22b2..000000000000 --- a/tests/tests/es.array.flat.js +++ /dev/null @@ -1,32 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -QUnit.test('Array#flat', assert => { - const { flat } = Array.prototype; - const { defineProperty } = Object; - assert.isFunction(flat); - assert.name(flat, 'flat'); - assert.arity(flat, 0); - assert.looksNative(flat); - assert.nonEnumerable(Array.prototype, 'flat'); - assert.deepEqual([].flat(), []); - const array = [1, [2, 3], [4, [5, 6]]]; - assert.deepEqual(array.flat(0), array); - assert.deepEqual(array.flat(1), [1, 2, 3, 4, [5, 6]]); - assert.deepEqual(array.flat(), [1, 2, 3, 4, [5, 6]]); - assert.deepEqual(array.flat(2), [1, 2, 3, 4, 5, 6]); - assert.deepEqual(array.flat(3), [1, 2, 3, 4, 5, 6]); - assert.deepEqual(array.flat(-1), array); - assert.deepEqual(array.flat(Infinity), [1, 2, 3, 4, 5, 6]); - if (STRICT) { - assert.throws(() => flat.call(null), TypeError); - assert.throws(() => flat.call(undefined), TypeError); - } - if (DESCRIPTORS) { - assert.notThrows(() => flat.call(defineProperty({ length: -1 }, 0, { - get() { - throw new Error(); - }, - })).length === 0, 'uses ToLength'); - } - assert.ok('flat' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); diff --git a/tests/tests/es.array.for-each.js b/tests/tests/es.array.for-each.js deleted file mode 100644 index 0e174c01f7aa..000000000000 --- a/tests/tests/es.array.for-each.js +++ /dev/null @@ -1,62 +0,0 @@ -import { NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#forEach', assert => { - const { forEach } = Array.prototype; - assert.isFunction(forEach); - assert.arity(forEach, 1); - assert.name(forEach, 'forEach'); - assert.looksNative(forEach); - assert.nonEnumerable(Array.prototype, 'forEach'); - let array = [1]; - const context = {}; - array.forEach(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - let result = ''; - [1, 2, 3].forEach(value => { - result += value; - }); - assert.ok(result === '123'); - result = ''; - [1, 2, 3].forEach((value, key) => { - result += key; - }); - assert.ok(result === '012'); - result = ''; - [1, 2, 3].forEach((value, key, that) => { - result += that; - }); - assert.ok(result === '1,2,31,2,31,2,3'); - result = ''; - [1, 2, 3].forEach(function () { - result += this; - }, 1); - assert.ok(result === '111'); - result = ''; - array = []; - array[5] = ''; - array.forEach((value, key) => { - result += key; - }); - assert.ok(result === '5'); - if (STRICT) { - assert.throws(() => { - forEach.call(null, () => { /* empty */ }); - }, TypeError); - assert.throws(() => { - forEach.call(undefined, () => { /* empty */ }); - }, TypeError); - } - if (NATIVE) { - assert.notThrows(() => forEach.call({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }) === undefined, 'uses ToLength'); - } -}); diff --git a/tests/tests/es.array.from.js b/tests/tests/es.array.from.js deleted file mode 100644 index 2d9a7ab395ad..000000000000 --- a/tests/tests/es.array.from.js +++ /dev/null @@ -1,125 +0,0 @@ -import { DESCRIPTORS, GLOBAL } from '../helpers/constants'; -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Array.from', assert => { - const Symbol = GLOBAL.Symbol || {}; - const { from } = Array; - const { defineProperty } = Object; - assert.isFunction(from); - assert.arity(from, 1); - assert.name(from, 'from'); - assert.looksNative(from); - assert.nonEnumerable(Array, 'from'); - let types = { - 'array-like': { - length: '3', - 0: '1', - 1: '2', - 2: '3', - }, - arguments: function () { - return arguments; - }('1', '2', '3'), - array: ['1', '2', '3'], - iterable: createIterable(['1', '2', '3']), - string: '123', - }; - for (const type in types) { - const data = types[type]; - assert.arrayEqual(from(data), ['1', '2', '3'], `Works with ${ type }`); - assert.arrayEqual(from(data, it => it ** 2), [1, 4, 9], `Works with ${ type } + mapFn`); - } - types = { - 'array-like': { - length: 1, - 0: 1, - }, - arguments: function () { - return arguments; - }(1), - array: [1], - iterable: createIterable([1]), - string: '1', - }; - for (const type in types) { - const data = types[type]; - const context = {}; - assert.arrayEqual(from(data, function (value, key) { - assert.same(this, context, `Works with ${ type }, correct callback context`); - assert.same(value, type === 'string' ? '1' : 1, `Works with ${ type }, correct callback key`); - assert.same(key, 0, `Works with ${ type }, correct callback value`); - assert.same(arguments.length, 2, `Works with ${ type }, correct callback arguments number`); - return 42; - }, context), [42], `Works with ${ type }, correct result`); - } - const primitives = [false, true, 0]; - for (const primitive of primitives) { - assert.arrayEqual(from(primitive), [], `Works with ${ primitive }`); - } - assert.throws(() => from(null), TypeError, 'Throws on null'); - assert.throws(() => from(undefined), TypeError, 'Throws on undefined'); - assert.arrayEqual(from('𠮷𠮷𠮷'), ['𠮷', '𠮷', '𠮷'], 'Uses correct string iterator'); - let done = true; - from(createIterable([1, 2, 3], { - return() { - return done = false; - }, - }), () => false); - assert.ok(done, '.return #default'); - done = false; - try { - from(createIterable([1, 2, 3], { - return() { - return done = true; - }, - }), () => { - throw new Error(); - }); - } catch { /* empty */ } - assert.ok(done, '.return #throw'); - class C { /* empty */ } - let instance = from.call(C, createIterable([1, 2])); - assert.ok(instance instanceof C, 'generic, iterable case, instanceof'); - assert.arrayEqual(instance, [1, 2], 'generic, iterable case, elements'); - instance = from.call(C, { - 0: 1, - 1: 2, - length: 2, - }); - assert.ok(instance instanceof C, 'generic, array-like case, instanceof'); - assert.arrayEqual(instance, [1, 2], 'generic, array-like case, elements'); - let array = [1, 2, 3]; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return [][Symbol.iterator].call(this); - }; - assert.arrayEqual(from(array), [1, 2, 3], 'Array with custom iterator, elements'); - assert.ok(done, 'call @@iterator in Array with custom iterator'); - array = [1, 2, 3]; - delete array[1]; - assert.arrayEqual(from(array, String), ['1', 'undefined', '3'], 'Ignores holes'); - assert.notThrows(() => from({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }).length === 0, 'Uses ToLength'); - assert.arrayEqual(from([], undefined), [], 'Works with undefined as asecond argument'); - assert.throws(() => from([], null), TypeError, 'Throws with null as second argument'); - assert.throws(() => from([], 0), TypeError, 'Throws with 0 as second argument'); - assert.throws(() => from([], ''), TypeError, 'Throws with "" as second argument'); - assert.throws(() => from([], false), TypeError, 'Throws with false as second argument'); - assert.throws(() => from([], {}), TypeError, 'Throws with {} as second argument'); - if (DESCRIPTORS) { - let called = false; - defineProperty(C.prototype, 0, { - set() { - called = true; - }, - }); - from.call(C, [1, 2, 3]); - assert.ok(!called, 'Should not call prototype accessors'); - } -}); diff --git a/tests/tests/es.array.includes.js b/tests/tests/es.array.includes.js deleted file mode 100644 index ba1a65cda8a5..000000000000 --- a/tests/tests/es.array.includes.js +++ /dev/null @@ -1,35 +0,0 @@ -import { DESCRIPTORS, NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#includes', assert => { - const { includes } = Array.prototype; - assert.isFunction(includes); - assert.name(includes, 'includes'); - assert.arity(includes, 1); - assert.looksNative(includes); - assert.nonEnumerable(Array.prototype, 'includes'); - const object = {}; - const array = [1, 2, 3, -0, object]; - assert.ok(array.includes(1)); - assert.ok(array.includes(-0)); - assert.ok(array.includes(0)); - assert.ok(array.includes(object)); - assert.ok(!array.includes(4)); - assert.ok(!array.includes(-0.5)); - assert.ok(!array.includes({})); - assert.ok(Array(1).includes(undefined)); - assert.ok([NaN].includes(NaN)); - if (STRICT) { - assert.throws(() => includes.call(null, 0), TypeError); - assert.throws(() => includes.call(undefined, 0), TypeError); - } - if (NATIVE && DESCRIPTORS) { - assert.notThrows(() => includes.call(Object.defineProperty({ - length: -1, - }, 0, { - get() { - throw new Error(); - }, - }), 1) === false, 'uses ToLength'); - } - assert.ok('includes' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); diff --git a/tests/tests/es.array.index-of.js b/tests/tests/es.array.index-of.js deleted file mode 100644 index fd007a48ba60..000000000000 --- a/tests/tests/es.array.index-of.js +++ /dev/null @@ -1,32 +0,0 @@ -import { DESCRIPTORS, NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#indexOf', assert => { - const { indexOf } = Array.prototype; - assert.isFunction(indexOf); - assert.arity(indexOf, 1); - assert.name(indexOf, 'indexOf'); - assert.looksNative(indexOf); - assert.nonEnumerable(Array.prototype, 'indexOf'); - assert.same(0, [1, 1, 1].indexOf(1)); - assert.same(-1, [1, 2, 3].indexOf(1, 1)); - assert.same(1, [1, 2, 3].indexOf(2, 1)); - assert.same(-1, [1, 2, 3].indexOf(2, -1)); - assert.same(1, [1, 2, 3].indexOf(2, -2)); - assert.same(-1, [NaN].indexOf(NaN)); - assert.same(3, Array(2).concat([1, 2, 3]).indexOf(2)); - assert.same(-1, Array(1).indexOf(undefined)); - assert.same(0, [1].indexOf(1, -0), "shouldn't return negative zero"); - if (STRICT) { - assert.throws(() => indexOf.call(null, 0), TypeError); - assert.throws(() => indexOf.call(undefined, 0), TypeError); - } - if (NATIVE && DESCRIPTORS) { - assert.notThrows(() => indexOf.call(Object.defineProperty({ - length: -1, - }, 0, { - get() { - throw new Error(); - }, - }), 1) === -1, 'uses ToLength'); - } -}); diff --git a/tests/tests/es.array.is-array.js b/tests/tests/es.array.is-array.js deleted file mode 100644 index 813bb2075491..000000000000 --- a/tests/tests/es.array.is-array.js +++ /dev/null @@ -1,13 +0,0 @@ -QUnit.test('Array.isArray', assert => { - const { isArray } = Array; - assert.isFunction(isArray); - assert.arity(isArray, 1); - assert.name(isArray, 'isArray'); - assert.looksNative(isArray); - assert.nonEnumerable(Array, 'isArray'); - assert.ok(!isArray({})); - assert.ok(!isArray(function () { - return arguments; - }())); - assert.ok(isArray([])); -}); diff --git a/tests/tests/es.array.iterator.js b/tests/tests/es.array.iterator.js deleted file mode 100644 index 3ab0c35cacd7..000000000000 --- a/tests/tests/es.array.iterator.js +++ /dev/null @@ -1,155 +0,0 @@ -import { GLOBAL, NATIVE } from '../helpers/constants'; - -const Symbol = GLOBAL.Symbol || {}; - -QUnit.test('Array#keys', assert => { - const { keys } = Array.prototype; - assert.isFunction(keys); - assert.arity(keys, 0); - assert.name(keys, 'keys'); - assert.looksNative(keys); - assert.nonEnumerable(Array.prototype, 'keys'); - const iterator = ['q', 'w', 'e'].keys(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); - assert.strictEqual(String(iterator), '[object Array Iterator]'); - assert.deepEqual(iterator.next(), { - value: 0, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 1, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 2, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - if (NATIVE) { - assert.deepEqual(keys.call({ - length: -1, - }).next(), { - value: undefined, - done: true, - }, 'uses ToLength'); - } - assert.ok('keys' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); - -QUnit.test('Array#values', assert => { - const { values } = Array.prototype; - assert.isFunction(values); - assert.arity(values, 0); - assert.name(values, 'values'); - assert.looksNative(values); - assert.nonEnumerable(Array.prototype, 'values'); - const iterator = ['q', 'w', 'e'].values(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - if (NATIVE) { - assert.deepEqual(values.call({ - length: -1, - }).next(), { - value: undefined, - done: true, - }, 'uses ToLength'); - } - assert.ok('values' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); - -QUnit.test('Array#entries', assert => { - const { entries } = Array.prototype; - assert.isFunction(entries); - assert.arity(entries, 0); - assert.name(entries, 'entries'); - assert.looksNative(entries); - assert.nonEnumerable(Array.prototype, 'entries'); - const iterator = ['q', 'w', 'e'].entries(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); - assert.deepEqual(iterator.next(), { - value: [0, 'q'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: [1, 'w'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: [2, 'e'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - if (NATIVE) { - assert.deepEqual(entries.call({ - length: -1, - }).next(), { - value: undefined, - done: true, - }, 'uses ToLength'); - } - assert.ok('entries' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); -}); - -QUnit.test('Array#@@iterator', assert => { - assert.isIterable(Array.prototype); - assert.arity(Array.prototype[Symbol.iterator], 0); - assert.name(Array.prototype[Symbol.iterator], 'values'); - assert.looksNative(Array.prototype[Symbol.iterator]); - assert.nonEnumerable(Array.prototype, Symbol.iterator); - assert.strictEqual(Array.prototype[Symbol.iterator], Array.prototype.values); - const iterator = ['q', 'w', 'e'][Symbol.iterator](); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - if (NATIVE) { - assert.deepEqual(Array.prototype[Symbol.iterator].call({ - length: -1, - }).next(), { - value: undefined, - done: true, - }, 'uses ToLength'); - } -}); diff --git a/tests/tests/es.array.join.js b/tests/tests/es.array.join.js deleted file mode 100644 index 88ea30c8a28e..000000000000 --- a/tests/tests/es.array.join.js +++ /dev/null @@ -1,17 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('Array#join', assert => { - const { join } = Array.prototype; - assert.isFunction(join); - assert.arity(join, 1); - assert.name(join, 'join'); - assert.looksNative(join); - assert.nonEnumerable(Array.prototype, 'join'); - assert.strictEqual(join.call([1, 2, 3], undefined), '1,2,3'); - assert.strictEqual(join.call('123'), '1,2,3'); - assert.strictEqual(join.call('123', '|'), '1|2|3'); - if (STRICT) { - assert.throws(() => join.call(null, 0), TypeError); - assert.throws(() => join.call(undefined, 0), TypeError); - } -}); diff --git a/tests/tests/es.array.last-index-of.js b/tests/tests/es.array.last-index-of.js deleted file mode 100644 index f38a06ce31e5..000000000000 --- a/tests/tests/es.array.last-index-of.js +++ /dev/null @@ -1,39 +0,0 @@ -import { DESCRIPTORS, NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#lastIndexOf', assert => { - const { lastIndexOf } = Array.prototype; - assert.isFunction(lastIndexOf); - assert.arity(lastIndexOf, 1); - assert.name(lastIndexOf, 'lastIndexOf'); - assert.looksNative(lastIndexOf); - assert.nonEnumerable(Array.prototype, 'lastIndexOf'); - assert.same(2, [1, 1, 1].lastIndexOf(1)); - assert.same(-1, [1, 2, 3].lastIndexOf(3, 1)); - assert.same(1, [1, 2, 3].lastIndexOf(2, 1)); - assert.same(-1, [1, 2, 3].lastIndexOf(2, -3)); - assert.same(-1, [1, 2, 3].lastIndexOf(1, -4)); - assert.same(1, [1, 2, 3].lastIndexOf(2, -2)); - assert.same(-1, [NaN].lastIndexOf(NaN)); - assert.same(1, [1, 2, 3].concat(Array(2)).lastIndexOf(2)); - assert.same(0, [1].lastIndexOf(1, -0), "shouldn't return negative zero"); - if (STRICT) { - assert.throws(() => lastIndexOf.call(null, 0), TypeError); - assert.throws(() => lastIndexOf.call(undefined, 0), TypeError); - } - if (NATIVE && DESCRIPTORS) { - assert.notThrows(() => lastIndexOf.call(Object.defineProperties({ - length: -1, - }, { - 2147483646: { - get() { - throw new Error(); - }, - }, - 4294967294: { - get() { - throw new Error(); - }, - }, - }), 1) === -1, 'uses ToLength'); - } -}); diff --git a/tests/tests/es.array.map.js b/tests/tests/es.array.map.js deleted file mode 100644 index 9b5f64f8307d..000000000000 --- a/tests/tests/es.array.map.js +++ /dev/null @@ -1,39 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('Array#map', assert => { - const { map } = Array.prototype; - assert.isFunction(map); - assert.arity(map, 1); - assert.name(map, 'map'); - assert.looksNative(map); - assert.nonEnumerable(Array.prototype, 'map'); - let array = [1]; - const context = {}; - array.map(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.deepEqual([2, 3, 4], [1, 2, 3].map(value => value + 1)); - assert.deepEqual([1, 3, 5], [1, 2, 3].map((value, key) => value + key)); - assert.deepEqual([2, 2, 2], [1, 2, 3].map(function () { - return +this; - }, 2)); - if (STRICT) { - assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); - } - assert.notThrows(() => map.call({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }).length === 0, 'uses ToLength'); - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(array.map(Boolean).foo, 1, '@@species'); -}); diff --git a/tests/tests/es.array.of.js b/tests/tests/es.array.of.js deleted file mode 100644 index 97213caa5c6b..000000000000 --- a/tests/tests/es.array.of.js +++ /dev/null @@ -1,28 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Array.of', assert => { - const { defineProperty } = Object; - assert.isFunction(Array.of); - assert.arity(Array.of, 0); - assert.name(Array.of, 'of'); - assert.looksNative(Array.of); - assert.nonEnumerable(Array, 'of'); - assert.deepEqual(Array.of(1), [1]); - assert.deepEqual(Array.of(1, 2, 3), [1, 2, 3]); - class C { /* empty */ } - const instance = Array.of.call(C, 1, 2); - assert.ok(instance instanceof C); - assert.strictEqual(instance[0], 1); - assert.strictEqual(instance[1], 2); - assert.strictEqual(instance.length, 2); - if (DESCRIPTORS) { - let called = false; - defineProperty(C.prototype, 0, { - set() { - called = true; - }, - }); - Array.of.call(C, 1, 2, 3); - assert.ok(!called, 'Should not call prototype accessors'); - } -}); diff --git a/tests/tests/es.array.reduce-right.js b/tests/tests/es.array.reduce-right.js deleted file mode 100644 index a10813eaa79a..000000000000 --- a/tests/tests/es.array.reduce-right.js +++ /dev/null @@ -1,52 +0,0 @@ -import { NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#reduceRight', assert => { - const { reduceRight } = Array.prototype; - assert.isFunction(reduceRight); - assert.arity(reduceRight, 1); - assert.name(reduceRight, 'reduceRight'); - assert.looksNative(reduceRight); - assert.nonEnumerable(Array.prototype, 'reduceRight'); - const array = [1]; - const accumulator = {}; - array.reduceRight(function (memo, value, key, that) { - assert.same(arguments.length, 4, 'correct number of callback arguments'); - assert.same(memo, accumulator, 'correct callback accumulator'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - }, accumulator); - assert.same([1, 2, 3].reduceRight(((a, b) => a + b), 1), 7, 'works with initial accumulator'); - [1, 2].reduceRight((memo, value, key) => { - assert.same(memo, 2, 'correct default accumulator'); - assert.same(value, 1, 'correct start value without initial accumulator'); - assert.same(key, 0, 'correct start index without initial accumulator'); - }); - assert.same([1, 2, 3].reduceRight((a, b) => a + b), 6, 'works without initial accumulator'); - let values = ''; - let keys = ''; - [1, 2, 3].reduceRight((memo, value, key) => { - values += value; - keys += key; - }, 0); - assert.same(values, '321', 'correct order #1'); - assert.same(keys, '210', 'correct order #2'); - assert.same(reduceRight.call({ - 0: 1, - 1: 2, - length: 2, - }, (a, b) => a + b), 3, 'generic'); - if (STRICT) { - assert.throws(() => reduceRight.call(null, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduceRight.call(undefined, () => { /* empty */ }, 1), TypeError); - } - if (NATIVE) { - assert.notThrows(() => reduceRight.call({ - length: -1, - 2147483646: 0, - 4294967294: 0, - }, () => { - throw new Error(); - }, 1) === undefined, 'uses ToLength'); - } -}); diff --git a/tests/tests/es.array.reduce.js b/tests/tests/es.array.reduce.js deleted file mode 100644 index d1c523cbf5f8..000000000000 --- a/tests/tests/es.array.reduce.js +++ /dev/null @@ -1,51 +0,0 @@ -import { NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#reduce', assert => { - const { reduce } = Array.prototype; - assert.isFunction(reduce); - assert.arity(reduce, 1); - assert.name(reduce, 'reduce'); - assert.looksNative(reduce); - assert.nonEnumerable(Array.prototype, 'reduce'); - const array = [1]; - const accumulator = {}; - array.reduce(function (memo, value, key, that) { - assert.same(arguments.length, 4, 'correct number of callback arguments'); - assert.same(memo, accumulator, 'correct callback accumulator'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - }, accumulator); - assert.same([1, 2, 3].reduce(((a, b) => a + b), 1), 7, 'works with initial accumulator'); - [1, 2].reduce((memo, value, key) => { - assert.same(memo, 1, 'correct default accumulator'); - assert.same(value, 2, 'correct start value without initial accumulator'); - assert.same(key, 1, 'correct start index without initial accumulator'); - }); - assert.same([1, 2, 3].reduce((a, b) => a + b), 6, 'works without initial accumulator'); - let values = ''; - let keys = ''; - [1, 2, 3].reduce((memo, value, key) => { - values += value; - keys += key; - }, 0); - assert.same(values, '123', 'correct order #1'); - assert.same(keys, '012', 'correct order #2'); - assert.same(reduce.call({ - 0: 1, - 1: 2, - length: 2, - }, (a, b) => a + b), 3, 'generic'); - if (STRICT) { - assert.throws(() => reduce.call(null, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call(undefined, () => { /* empty */ }, 1), TypeError); - } - if (NATIVE) { - assert.notThrows(() => reduce.call({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }, 1) === undefined, 'uses ToLength'); - } -}); diff --git a/tests/tests/es.array.reverse.js b/tests/tests/es.array.reverse.js deleted file mode 100644 index c901d410f954..000000000000 --- a/tests/tests/es.array.reverse.js +++ /dev/null @@ -1,21 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('Array#reverse', assert => { - const { reverse } = Array.prototype; - assert.isFunction(reverse); - assert.arity(reverse, 0); - assert.name(reverse, 'reverse'); - assert.looksNative(reverse); - assert.nonEnumerable(Array.prototype, 'reverse'); - const a = [1, 2.2, 3.3]; - function fn() { - +a; - a.reverse(); - } - fn(); - assert.arrayEqual(a, [3.3, 2.2, 1]); - if (STRICT) { - assert.throws(() => reverse.call(null, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reverse.call(undefined, () => { /* empty */ }, 1), TypeError); - } -}); diff --git a/tests/tests/es.array.slice.js b/tests/tests/es.array.slice.js deleted file mode 100644 index 826f4a8fdaa5..000000000000 --- a/tests/tests/es.array.slice.js +++ /dev/null @@ -1,44 +0,0 @@ -import { GLOBAL, NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#slice', assert => { - const { slice } = Array.prototype; - const { isArray } = Array; - assert.isFunction(slice); - assert.arity(slice, 2); - assert.name(slice, 'slice'); - assert.looksNative(slice); - assert.nonEnumerable(Array.prototype, 'slice'); - let array = ['1', '2', '3', '4', '5']; - assert.deepEqual(array.slice(), array); - assert.deepEqual(array.slice(1, 3), ['2', '3']); - assert.deepEqual(array.slice(1, undefined), ['2', '3', '4', '5']); - assert.deepEqual(array.slice(1, -1), ['2', '3', '4']); - assert.deepEqual(array.slice(-2, -1), ['4']); - assert.deepEqual(array.slice(-2, -3), []); - const string = '12345'; - assert.deepEqual(slice.call(string), array); - assert.deepEqual(slice.call(string, 1, 3), ['2', '3']); - assert.deepEqual(slice.call(string, 1, undefined), ['2', '3', '4', '5']); - assert.deepEqual(slice.call(string, 1, -1), ['2', '3', '4']); - assert.deepEqual(slice.call(string, -2, -1), ['4']); - assert.deepEqual(slice.call(string, -2, -3), []); - const list = GLOBAL.document && document.body && document.body.childNodes; - if (list) { - assert.notThrows(() => isArray(slice.call(list)), 'works on NodeList'); - } - if (NATIVE) { - if (STRICT) { - assert.throws(() => slice.call(null), TypeError); - assert.throws(() => slice.call(undefined), TypeError); - } - assert.deepEqual(slice.call({ - length: -1, - 0: 1, - }, 0, 1), [], 'uses ToLength'); - } - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(array.slice().foo, 1, '@@species'); -}); diff --git a/tests/tests/es.array.some.js b/tests/tests/es.array.some.js deleted file mode 100644 index a70c9af2f961..000000000000 --- a/tests/tests/es.array.some.js +++ /dev/null @@ -1,46 +0,0 @@ -import { NATIVE, STRICT } from '../helpers/constants'; - -QUnit.test('Array#some', assert => { - const { some } = Array.prototype; - assert.isFunction(some); - assert.arity(some, 1); - assert.name(some, 'some'); - assert.looksNative(some); - assert.nonEnumerable(Array.prototype, 'some'); - let array = [1]; - const context = {}; - array.some(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.ok([1, '2', 3].some(value => typeof value === 'number')); - assert.ok([1, 2, 3].some(value => value < 3)); - assert.ok(![1, 2, 3].some(value => value < 0)); - assert.ok(![1, 2, 3].some(value => typeof value === 'string')); - assert.ok(![1, 2, 3].some(function () { - return +this !== 1; - }, 1)); - let result = ''; - [1, 2, 3].some((value, key) => { - result += key; - return false; - }); - assert.ok(result === '012'); - array = [1, 2, 3]; - assert.ok(!array.some((value, key, that) => that !== array)); - if (STRICT) { - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - } - if (NATIVE) { - assert.notThrows(() => some.call({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }) === false, 'uses ToLength'); - } -}); diff --git a/tests/tests/es.array.sort.js b/tests/tests/es.array.sort.js deleted file mode 100644 index c6bb7c9d9043..000000000000 --- a/tests/tests/es.array.sort.js +++ /dev/null @@ -1,17 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('Array#sort', assert => { - const { sort } = Array.prototype; - assert.isFunction(sort); - assert.arity(sort, 1); - assert.name(sort, 'sort'); - assert.looksNative(sort); - assert.nonEnumerable(Array.prototype, 'sort'); - assert.notThrows(() => [1, 2, 3].sort(undefined).length === 3, 'works with undefined'); - assert.throws(() => [1, 2, 3].sort(null), 'throws on null'); - assert.throws(() => [1, 2, 3].sort({}), 'throws on {}'); - if (STRICT) { - assert.throws(() => sort.call(null), TypeError, 'ToObject(this)'); - assert.throws(() => sort.call(undefined), TypeError, 'ToObject(this)'); - } -}); diff --git a/tests/tests/es.array.splice.js b/tests/tests/es.array.splice.js deleted file mode 100644 index f8b8d4779a49..000000000000 --- a/tests/tests/es.array.splice.js +++ /dev/null @@ -1,38 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('Array#splice', assert => { - const { splice } = Array.prototype; - assert.isFunction(splice); - assert.arity(splice, 2); - assert.name(splice, 'splice'); - assert.looksNative(splice); - assert.nonEnumerable(Array.prototype, 'splice'); - let array = [1, 2, 3, 4, 5]; - assert.deepEqual(array.splice(2), [3, 4, 5]); - assert.deepEqual(array, [1, 2]); - array = [1, 2, 3, 4, 5]; - assert.deepEqual(array.splice(-2), [4, 5]); - assert.deepEqual(array, [1, 2, 3]); - array = [1, 2, 3, 4, 5]; - assert.deepEqual(array.splice(2, 2), [3, 4]); - assert.deepEqual(array, [1, 2, 5]); - array = [1, 2, 3, 4, 5]; - assert.deepEqual(array.splice(2, -2), []); - assert.deepEqual(array, [1, 2, 3, 4, 5]); - array = [1, 2, 3, 4, 5]; - assert.deepEqual(array.splice(2, 2, 6, 7), [3, 4]); - assert.deepEqual(array, [1, 2, 6, 7, 5]); - if (STRICT) { - assert.throws(() => splice.call(null), TypeError); - assert.throws(() => splice.call(undefined), TypeError); - } - assert.deepEqual(splice.call({ - length: -1, - 0: 1, - }), [], 'uses ToLength'); - array = []; - array.constructor = { [Symbol.species]: function () { // eslint-disable-line object-shorthand - return { foo: 1 }; - } }; - assert.same(array.splice().foo, 1, '@@species'); -}); diff --git a/tests/tests/es.date.now.js b/tests/tests/es.date.now.js deleted file mode 100644 index a590332fcedd..000000000000 --- a/tests/tests/es.date.now.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('Date.now', assert => { - const { now } = Date; - assert.isFunction(now); - assert.arity(now, 0); - assert.name(now, 'now'); - assert.looksNative(now); - assert.nonEnumerable(Date, 'now'); - assert.ok(+new Date() - now() < 10, 'Date.now() ~ +new Date'); -}); diff --git a/tests/tests/es.date.to-iso-string.js b/tests/tests/es.date.to-iso-string.js deleted file mode 100644 index fa5a4dbe25ce..000000000000 --- a/tests/tests/es.date.to-iso-string.js +++ /dev/null @@ -1,16 +0,0 @@ -QUnit.test('Date#toISOString', assert => { - const { toISOString } = Date.prototype; - assert.isFunction(toISOString); - assert.arity(toISOString, 0); - assert.name(toISOString, 'toISOString'); - assert.looksNative(toISOString); - assert.nonEnumerable(Date.prototype, 'toISOString'); - assert.strictEqual(new Date(0).toISOString(), '1970-01-01T00:00:00.000Z'); - assert.strictEqual(new Date(1e12 + 1).toISOString(), '2001-09-09T01:46:40.001Z'); - assert.strictEqual(new Date(-5e13 - 1).toISOString(), '0385-07-25T07:06:39.999Z'); - const future = new Date(1e15 + 1).toISOString(); - assert.ok(future === '+033658-09-27T01:46:40.001Z' || future === '33658-09-27T01:46:40.001Z'); - const prehistoric = new Date(-1e15 + 1).toISOString(); - assert.ok(prehistoric === '-029719-04-05T22:13:20.001Z' || prehistoric === '-29719-04-05T22:13:20.001Z'); - assert.throws(() => new Date(NaN).toISOString(), RangeError); -}); diff --git a/tests/tests/es.function.bind.js b/tests/tests/es.function.bind.js deleted file mode 100644 index 52e7e8e8a15e..000000000000 --- a/tests/tests/es.function.bind.js +++ /dev/null @@ -1,28 +0,0 @@ -QUnit.test('Function#bind', assert => { - const { bind } = Function.prototype; - assert.isFunction(bind); - assert.arity(bind, 1); - assert.name(bind, 'bind'); - assert.looksNative(bind); - assert.nonEnumerable(Function.prototype, 'bind'); - assert.same(function () { - return this.a; - }.bind({ a: 42 })(), 42); - assert.same(new (function () { /* empty */ })().a, undefined); - function A(a, b) { - this.a = a; - this.b = b; - } - const instance = new (A.bind(null, 1))(2); - assert.ok(instance instanceof A); - assert.strictEqual(instance.a, 1); - assert.strictEqual(instance.b, 2); - assert.same((it => it).bind(null, 42)(), 42); - const regExpTest = RegExp.prototype.test.bind(/a/); - assert.ok(regExpTest('a')); - const Date2017 = Date.bind(null, 2017); - const date = new Date2017(11); - assert.ok(date instanceof Date); - assert.strictEqual(date.getFullYear(), 2017); - assert.strictEqual(date.getMonth(), 11); -}); diff --git a/tests/tests/es.function.has-instance.js b/tests/tests/es.function.has-instance.js deleted file mode 100644 index d702427b61ee..000000000000 --- a/tests/tests/es.function.has-instance.js +++ /dev/null @@ -1,6 +0,0 @@ -QUnit.test('Function#@@hasInstance', assert => { - assert.ok(Symbol.hasInstance in Function.prototype); - assert.nonEnumerable(Function.prototype, Symbol.hasInstance); - assert.ok(Function[Symbol.hasInstance](() => { /* empty */ })); - assert.ok(!Function[Symbol.hasInstance]({})); -}); diff --git a/tests/tests/es.function.name.js b/tests/tests/es.function.name.js deleted file mode 100644 index 80f1bda77de2..000000000000 --- a/tests/tests/es.function.name.js +++ /dev/null @@ -1,24 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -if (DESCRIPTORS) { - QUnit.test('Function#name', assert => { - assert.ok('name' in Function.prototype); - assert.nonEnumerable(Function.prototype, 'name'); - function foo() { /* empty */ } - assert.same(foo.name, 'foo'); - assert.same(function () { /* empty */ }.name, ''); - if (Object.freeze) { - assert.same(Object.freeze(() => { /* empty */ }).name, ''); - } - function bar() { /* empty */ } - bar.toString = function () { - throw new Error(); - }; - assert.notThrows(() => bar.name === 'bar', 'works with redefined `.toString`'); - const baz = Object(() => { /* empty */ }); - baz.toString = function () { - return ''; - }; - assert.same(baz.name, ''); - }); -} diff --git a/tests/tests/es.map.js b/tests/tests/es.map.js deleted file mode 100644 index 0fd00f6f9b44..000000000000 --- a/tests/tests/es.map.js +++ /dev/null @@ -1,461 +0,0 @@ -/* eslint-disable sonarjs/no-element-overwrite */ - -import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants'; -import { createIterable, is, nativeSubclass } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; -const { getOwnPropertyDescriptor, keys, getOwnPropertyNames, getOwnPropertySymbols, freeze } = Object; -const { ownKeys } = GLOBAL.Reflect || {}; - -QUnit.test('Map', assert => { - assert.isFunction(Map); - assert.arity(Map, 0); - assert.name(Map, 'Map'); - assert.looksNative(Map); - assert.ok('clear' in Map.prototype, 'clear in Map.prototype'); - assert.ok('delete' in Map.prototype, 'delete in Map.prototype'); - assert.ok('forEach' in Map.prototype, 'forEach in Map.prototype'); - assert.ok('get' in Map.prototype, 'get in Map.prototype'); - assert.ok('has' in Map.prototype, 'has in Map.prototype'); - assert.ok('set' in Map.prototype, 'set in Map.prototype'); - assert.ok(new Map() instanceof Map, 'new Map instanceof Map'); - assert.strictEqual(new Map(createIterable([[1, 1], [2, 2], [3, 3]])).size, 3, 'Init from iterable'); - assert.strictEqual(new Map([[freeze({}), 1], [2, 3]]).size, 2, 'Support frozen objects'); - let done = false; - try { - new Map(createIterable([null, 1, 2], { - return() { - return done = true; - }, - })); - } catch { /* empty */ } - assert.ok(done, '.return #throw'); - const array = []; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return [][Symbol.iterator].call(this); - }; - new Map(array); - assert.ok(done); - const object = {}; - new Map().set(object, 1); - if (DESCRIPTORS) { - const results = []; - for (const key in object) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(object), []); - } - assert.arrayEqual(getOwnPropertyNames(object), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); - if (ownKeys) assert.arrayEqual(ownKeys(object), []); - if (nativeSubclass) { - const Subclass = nativeSubclass(Map); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof Map, 'correct subclassing with native classes #2'); - assert.strictEqual(new Subclass().set(1, 2).get(1), 2, 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('Map#clear', assert => { - assert.isFunction(Map.prototype.clear); - assert.arity(Map.prototype.clear, 0); - assert.name(Map.prototype.clear, 'clear'); - assert.looksNative(Map.prototype.clear); - assert.nonEnumerable(Map.prototype, 'clear'); - let map = new Map(); - map.clear(); - assert.strictEqual(map.size, 0); - map = new Map(); - map.set(1, 2); - map.set(2, 3); - map.set(1, 4); - map.clear(); - assert.strictEqual(map.size, 0); - assert.ok(!map.has(1)); - assert.ok(!map.has(2)); - const frozen = freeze({}); - map = new Map(); - map.set(1, 2); - map.set(frozen, 3); - map.clear(); - assert.strictEqual(map.size, 0, 'Support frozen objects'); - assert.ok(!map.has(1)); - assert.ok(!map.has(frozen)); -}); - -QUnit.test('Map#delete', assert => { - assert.isFunction(Map.prototype.delete); - assert.arity(Map.prototype.delete, 1); - if (NATIVE) assert.name(Map.prototype.delete, 'delete'); - assert.looksNative(Map.prototype.delete); - assert.nonEnumerable(Map.prototype, 'delete'); - const object = {}; - const map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 7); - map.set(2, 5); - map.set(1, 4); - map.set(object, 9); - assert.strictEqual(map.size, 5); - assert.ok(map.delete(NaN)); - assert.strictEqual(map.size, 4); - assert.ok(!map.delete(4)); - assert.strictEqual(map.size, 4); - map.delete([]); - assert.strictEqual(map.size, 4); - map.delete(object); - assert.strictEqual(map.size, 3); - const frozen = freeze({}); - map.set(frozen, 42); - assert.strictEqual(map.size, 4); - map.delete(frozen); - assert.strictEqual(map.size, 3); -}); - -QUnit.test('Map#forEach', assert => { - assert.isFunction(Map.prototype.forEach); - assert.arity(Map.prototype.forEach, 1); - assert.name(Map.prototype.forEach, 'forEach'); - assert.looksNative(Map.prototype.forEach); - assert.nonEnumerable(Map.prototype, 'forEach'); - let result = {}; - let count = 0; - const object = {}; - let map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 7); - map.set(2, 5); - map.set(1, 4); - map.set(object, 9); - map.forEach((value, key) => { - count++; - result[value] = key; - }); - assert.strictEqual(count, 5); - assert.deepEqual(result, { - 1: NaN, - 7: 3, - 5: 2, - 4: 1, - 9: object, - }); - map = new Map(); - map.set('0', 9); - map.set('1', 9); - map.set('2', 9); - map.set('3', 9); - result = ''; - map.forEach((value, key) => { - result += key; - if (key === '2') { - map.delete('2'); - map.delete('3'); - map.delete('1'); - map.set('4', 9); - } - }); - assert.strictEqual(result, '0124'); - map = new Map([['0', 1]]); - result = ''; - map.forEach(it => { - map.delete('0'); - if (result !== '') throw new Error(); - result += it; - }); - assert.strictEqual(result, '1'); - assert.throws(() => { - Map.prototype.forEach.call(new Set(), () => { /* empty */ }); - }, 'non-generic'); -}); - -QUnit.test('Map#get', assert => { - assert.isFunction(Map.prototype.get); - assert.name(Map.prototype.get, 'get'); - assert.arity(Map.prototype.get, 1); - assert.looksNative(Map.prototype.get); - assert.nonEnumerable(Map.prototype, 'get'); - const object = {}; - const frozen = freeze({}); - const map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 1); - map.set(2, 5); - map.set(1, 4); - map.set(frozen, 42); - map.set(object, object); - assert.strictEqual(map.get(NaN), 1); - assert.strictEqual(map.get(4), undefined); - assert.strictEqual(map.get({}), undefined); - assert.strictEqual(map.get(object), object); - assert.strictEqual(map.get(frozen), 42); - assert.strictEqual(map.get(2), 5); -}); - -QUnit.test('Map#has', assert => { - assert.isFunction(Map.prototype.has); - assert.name(Map.prototype.has, 'has'); - assert.arity(Map.prototype.has, 1); - assert.looksNative(Map.prototype.has); - assert.nonEnumerable(Map.prototype, 'has'); - const object = {}; - const frozen = freeze({}); - const map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 1); - map.set(2, 5); - map.set(1, 4); - map.set(frozen, 42); - map.set(object, object); - assert.ok(map.has(NaN)); - assert.ok(map.has(object)); - assert.ok(map.has(2)); - assert.ok(map.has(frozen)); - assert.ok(!map.has(4)); - assert.ok(!map.has({})); -}); - -QUnit.test('Map#set', assert => { - assert.isFunction(Map.prototype.set); - assert.name(Map.prototype.set, 'set'); - assert.arity(Map.prototype.set, 2); - assert.looksNative(Map.prototype.set); - assert.nonEnumerable(Map.prototype, 'set'); - const object = {}; - let map = new Map(); - map.set(NaN, 1); - map.set(2, 1); - map.set(3, 1); - map.set(2, 5); - map.set(1, 4); - map.set(object, object); - assert.ok(map.size === 5); - const chain = map.set(7, 2); - assert.strictEqual(chain, map); - map.set(7, 2); - assert.strictEqual(map.size, 6); - assert.strictEqual(map.get(7), 2); - assert.strictEqual(map.get(NaN), 1); - map.set(NaN, 42); - assert.strictEqual(map.size, 6); - assert.strictEqual(map.get(NaN), 42); - map.set({}, 11); - assert.strictEqual(map.size, 7); - assert.strictEqual(map.get(object), object); - map.set(object, 27); - assert.strictEqual(map.size, 7); - assert.strictEqual(map.get(object), 27); - map = new Map(); - map.set(NaN, 2); - map.set(NaN, 3); - map.set(NaN, 4); - assert.strictEqual(map.size, 1); - const frozen = freeze({}); - map = new Map().set(frozen, 42); - assert.strictEqual(map.get(frozen), 42); -}); - -QUnit.test('Map#size', assert => { - assert.nonEnumerable(Map.prototype, 'size'); - const map = new Map(); - map.set(2, 1); - const { size } = map; - assert.strictEqual(typeof size, 'number', 'size is number'); - assert.strictEqual(size, 1, 'size is correct'); - if (DESCRIPTORS) { - const sizeDescriptor = getOwnPropertyDescriptor(Map.prototype, 'size'); - assert.ok(sizeDescriptor && sizeDescriptor.get, 'size is getter'); - assert.ok(sizeDescriptor && !sizeDescriptor.set, 'size isnt setter'); - assert.throws(() => Map.prototype.size, TypeError); - } -}); - -QUnit.test('Map & -0', assert => { - let map = new Map(); - map.set(-0, 1); - assert.strictEqual(map.size, 1); - assert.ok(map.has(0)); - assert.ok(map.has(-0)); - assert.strictEqual(map.get(0), 1); - assert.strictEqual(map.get(-0), 1); - map.forEach((val, key) => { - assert.ok(!is(key, -0)); - }); - map.delete(-0); - assert.strictEqual(map.size, 0); - map = new Map([[-0, 1]]); - map.forEach((val, key) => { - assert.ok(!is(key, -0)); - }); - map = new Map(); - map.set(4, 4); - map.set(3, 3); - map.set(2, 2); - map.set(1, 1); - map.set(0, 0); - assert.ok(map.has(-0)); -}); - -QUnit.test('Map#@@toStringTag', assert => { - assert.strictEqual(Map.prototype[Symbol.toStringTag], 'Map', 'Map::@@toStringTag is `Map`'); - assert.strictEqual(String(new Map()), '[object Map]', 'correct stringification'); -}); - -QUnit.test('Map Iterator', assert => { - const map = new Map(); - map.set('a', 1); - map.set('b', 2); - map.set('c', 3); - map.set('d', 4); - const results = []; - const iterator = map.keys(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.nonEnumerable(iterator, 'next'); - assert.nonEnumerable(iterator, Symbol.iterator); - results.push(iterator.next().value); - assert.ok(map.delete('a')); - assert.ok(map.delete('b')); - assert.ok(map.delete('c')); - map.set('e'); - results.push(iterator.next().value); - results.push(iterator.next().value); - assert.ok(iterator.next().done); - map.set('f'); - assert.ok(iterator.next().done); - assert.deepEqual(results, ['a', 'd', 'e']); -}); - -QUnit.test('Map#keys', assert => { - assert.isFunction(Map.prototype.keys); - assert.name(Map.prototype.keys, 'keys'); - assert.arity(Map.prototype.keys, 0); - assert.looksNative(Map.prototype.keys); - assert.nonEnumerable(Map.prototype, 'keys'); - const map = new Map(); - map.set('a', 'q'); - map.set('s', 'w'); - map.set('d', 'e'); - const iterator = map.keys(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Map Iterator'); - assert.deepEqual(iterator.next(), { - value: 'a', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 's', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'd', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Map#values', assert => { - assert.isFunction(Map.prototype.values); - assert.name(Map.prototype.values, 'values'); - assert.arity(Map.prototype.values, 0); - assert.looksNative(Map.prototype.values); - assert.nonEnumerable(Map.prototype, 'values'); - const map = new Map(); - map.set('a', 'q'); - map.set('s', 'w'); - map.set('d', 'e'); - const iterator = map.values(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Map Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Map#entries', assert => { - assert.isFunction(Map.prototype.entries); - assert.name(Map.prototype.entries, 'entries'); - assert.arity(Map.prototype.entries, 0); - assert.looksNative(Map.prototype.entries); - assert.nonEnumerable(Map.prototype, 'entries'); - const map = new Map(); - map.set('a', 'q'); - map.set('s', 'w'); - map.set('d', 'e'); - const iterator = map.entries(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Map Iterator'); - assert.deepEqual(iterator.next(), { - value: ['a', 'q'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['s', 'w'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['d', 'e'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Map#@@iterator', assert => { - assert.isIterable(Map.prototype); - assert.name(Map.prototype.entries, 'entries'); - assert.arity(Map.prototype.entries, 0); - assert.looksNative(Map.prototype[Symbol.iterator]); - assert.strictEqual(Map.prototype[Symbol.iterator], Map.prototype.entries); - const map = new Map(); - map.set('a', 'q'); - map.set('s', 'w'); - map.set('d', 'e'); - const iterator = map[Symbol.iterator](); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Map Iterator'); - assert.strictEqual(String(iterator), '[object Map Iterator]'); - assert.deepEqual(iterator.next(), { - value: ['a', 'q'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['s', 'w'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['d', 'e'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/tests/es.math.acosh.js b/tests/tests/es.math.acosh.js deleted file mode 100644 index 5c37af6b73a5..000000000000 --- a/tests/tests/es.math.acosh.js +++ /dev/null @@ -1,19 +0,0 @@ -QUnit.test('Math.acosh', assert => { - const { acosh } = Math; - assert.isFunction(acosh); - assert.name(acosh, 'acosh'); - assert.arity(acosh, 1); - assert.looksNative(acosh); - assert.nonEnumerable(Math, 'acosh'); - assert.same(acosh(NaN), NaN); - assert.same(acosh(0.5), NaN); - assert.same(acosh(-1), NaN); - assert.same(acosh(-1e300), NaN); - assert.same(acosh(1), 0); - assert.strictEqual(acosh(Infinity), Infinity); - assert.epsilon(acosh(1234), 7.811163220849231); - assert.epsilon(acosh(8.88), 2.8737631531629235); - assert.epsilon(acosh(1e+160), 369.10676205960726); - assert.epsilon(acosh(Number.MAX_VALUE), 710.475860073944); - assert.epsilon(acosh(1 + Number.EPSILON), 2.1073424255447017e-8); -}); diff --git a/tests/tests/es.math.asinh.js b/tests/tests/es.math.asinh.js deleted file mode 100644 index 55b7a7ab465b..000000000000 --- a/tests/tests/es.math.asinh.js +++ /dev/null @@ -1,18 +0,0 @@ -QUnit.test('Math.asinh', assert => { - const { asinh } = Math; - assert.isFunction(asinh); - assert.name(asinh, 'asinh'); - assert.arity(asinh, 1); - assert.looksNative(asinh); - assert.nonEnumerable(Math, 'asinh'); - assert.same(asinh(NaN), NaN); - assert.same(asinh(0), 0); - assert.same(asinh(-0), -0); - assert.strictEqual(asinh(Infinity), Infinity); - assert.strictEqual(asinh(-Infinity), -Infinity); - assert.epsilon(asinh(1234), 7.811163549201245); - assert.epsilon(asinh(9.99), 2.997227420191335); - assert.epsilon(asinh(1e150), 346.0809111296668); - assert.epsilon(asinh(1e7), 16.811242831518268); - assert.epsilon(asinh(-1e7), -16.811242831518268); -}); diff --git a/tests/tests/es.math.atanh.js b/tests/tests/es.math.atanh.js deleted file mode 100644 index 754b70e57d5d..000000000000 --- a/tests/tests/es.math.atanh.js +++ /dev/null @@ -1,22 +0,0 @@ -QUnit.test('Math.atanh', assert => { - const { atanh } = Math; - assert.isFunction(atanh); - assert.name(atanh, 'atanh'); - assert.arity(atanh, 1); - assert.looksNative(atanh); - assert.nonEnumerable(Math, 'atanh'); - assert.same(atanh(NaN), NaN); - assert.same(atanh(-2), NaN); - assert.same(atanh(-1.5), NaN); - assert.same(atanh(2), NaN); - assert.same(atanh(1.5), NaN); - assert.strictEqual(atanh(-1), -Infinity); - assert.strictEqual(atanh(1), Infinity); - assert.same(atanh(0), 0); - assert.same(atanh(-0), -0); - assert.same(atanh(-1e300), NaN); - assert.same(atanh(1e300), NaN); - assert.epsilon(atanh(0.5), 0.5493061443340549); - assert.epsilon(atanh(-0.5), -0.5493061443340549); - assert.epsilon(atanh(0.444), 0.47720201260109457); -}); diff --git a/tests/tests/es.math.cbrt.js b/tests/tests/es.math.cbrt.js deleted file mode 100644 index bd828cef47ee..000000000000 --- a/tests/tests/es.math.cbrt.js +++ /dev/null @@ -1,17 +0,0 @@ -QUnit.test('Math.cbrt', assert => { - const { cbrt } = Math; - assert.isFunction(cbrt); - assert.name(cbrt, 'cbrt'); - assert.arity(cbrt, 1); - assert.looksNative(cbrt); - assert.nonEnumerable(Math, 'cbrt'); - assert.same(cbrt(NaN), NaN); - assert.same(cbrt(0), 0); - assert.same(cbrt(-0), -0); - assert.strictEqual(cbrt(Infinity), Infinity); - assert.strictEqual(cbrt(-Infinity), -Infinity); - assert.strictEqual(cbrt(-8), -2); - assert.strictEqual(cbrt(8), 2); - assert.epsilon(cbrt(-1000), -10); - assert.epsilon(cbrt(1000), 10); -}); diff --git a/tests/tests/es.math.clz32.js b/tests/tests/es.math.clz32.js deleted file mode 100644 index e2a348322b8a..000000000000 --- a/tests/tests/es.math.clz32.js +++ /dev/null @@ -1,14 +0,0 @@ -QUnit.test('Math.clz32', assert => { - const { clz32 } = Math; - assert.isFunction(clz32); - assert.name(clz32, 'clz32'); - assert.arity(clz32, 1); - assert.looksNative(clz32); - assert.nonEnumerable(Math, 'clz32'); - assert.strictEqual(clz32(0), 32); - assert.strictEqual(clz32(1), 31); - assert.same(clz32(-1), 0); - assert.strictEqual(clz32(0.6), 32); - assert.same(clz32(2 ** 32 - 1), 0); - assert.strictEqual(clz32(2 ** 32), 32); -}); diff --git a/tests/tests/es.math.cosh.js b/tests/tests/es.math.cosh.js deleted file mode 100644 index 950f7fdf9b18..000000000000 --- a/tests/tests/es.math.cosh.js +++ /dev/null @@ -1,18 +0,0 @@ -QUnit.test('Math.cosh', assert => { - const { cosh } = Math; - assert.isFunction(cosh); - assert.name(cosh, 'cosh'); - assert.arity(cosh, 1); - assert.looksNative(cosh); - assert.nonEnumerable(Math, 'cosh'); - assert.same(cosh(NaN), NaN); - assert.strictEqual(cosh(0), 1); - assert.strictEqual(cosh(-0), 1); - assert.strictEqual(cosh(Infinity), Infinity); - assert.strictEqual(cosh(-Infinity), Infinity); - assert.epsilon(cosh(12), 81377.395712574, 1e-9); - assert.epsilon(cosh(22), 1792456423.065795780980053377, 1e-5); - assert.epsilon(cosh(-10), 11013.23292010332313972137); - assert.epsilon(cosh(-23), 4872401723.1244513000, 1e-5); - assert.epsilon(cosh(710), 1.1169973830808557e+308, 1e+295); -}); diff --git a/tests/tests/es.math.expm1.js b/tests/tests/es.math.expm1.js deleted file mode 100644 index b6dc6b7df84d..000000000000 --- a/tests/tests/es.math.expm1.js +++ /dev/null @@ -1,15 +0,0 @@ -QUnit.test('Math.expm1', assert => { - const { expm1 } = Math; - assert.isFunction(expm1); - assert.name(expm1, 'expm1'); - assert.arity(expm1, 1); - assert.looksNative(expm1); - assert.nonEnumerable(Math, 'expm1'); - assert.same(expm1(NaN), NaN); - assert.same(expm1(0), 0); - assert.same(expm1(-0), -0); - assert.strictEqual(expm1(Infinity), Infinity); - assert.strictEqual(expm1(-Infinity), -1); - assert.epsilon(expm1(10), 22025.465794806718); - assert.epsilon(expm1(-10), -0.9999546000702375); -}); diff --git a/tests/tests/es.math.fround.js b/tests/tests/es.math.fround.js deleted file mode 100644 index 3268d913ddcd..000000000000 --- a/tests/tests/es.math.fround.js +++ /dev/null @@ -1,32 +0,0 @@ -QUnit.test('Math.fround', assert => { - const { fround } = Math; - assert.isFunction(fround); - assert.name(fround, 'fround'); - assert.arity(fround, 1); - assert.looksNative(fround); - assert.nonEnumerable(Math, 'fround'); - assert.same(fround(undefined), NaN); - assert.same(fround(NaN), NaN); - assert.same(fround(0), 0); - assert.same(fround(-0), -0); - assert.same(fround(Number.MIN_VALUE), 0); - assert.same(fround(-Number.MIN_VALUE), -0); - assert.strictEqual(fround(Infinity), Infinity); - assert.strictEqual(fround(-Infinity), -Infinity); - assert.strictEqual(fround(1.7976931348623157e+308), Infinity); - assert.strictEqual(fround(-1.7976931348623157e+308), -Infinity); - assert.strictEqual(fround(3.4028235677973366e+38), Infinity); - assert.strictEqual(fround(3), 3); - assert.strictEqual(fround(-3), -3); - const maxFloat32 = 3.4028234663852886e+38; - const minFloat32 = 1.401298464324817e-45; - assert.strictEqual(fround(maxFloat32), maxFloat32); - assert.strictEqual(fround(-maxFloat32), -maxFloat32); - assert.strictEqual(fround(maxFloat32 + 2 ** 102), maxFloat32); - assert.strictEqual(fround(minFloat32), minFloat32); - assert.strictEqual(fround(-minFloat32), -minFloat32); - assert.same(fround(minFloat32 / 2), 0); - assert.same(fround(-minFloat32 / 2), -0); - assert.strictEqual(fround(minFloat32 / 2 + 2 ** -202), minFloat32); - assert.strictEqual(fround(-minFloat32 / 2 - 2 ** -202), -minFloat32); -}); diff --git a/tests/tests/es.math.hypot.js b/tests/tests/es.math.hypot.js deleted file mode 100644 index 7f740203f079..000000000000 --- a/tests/tests/es.math.hypot.js +++ /dev/null @@ -1,43 +0,0 @@ -QUnit.test('Math.hypot', assert => { - const { hypot, sqrt } = Math; - assert.isFunction(hypot); - assert.name(hypot, 'hypot'); - assert.arity(hypot, 2); - assert.looksNative(hypot); - assert.nonEnumerable(Math, 'hypot'); - assert.strictEqual(hypot(), 0); - assert.strictEqual(hypot(1), 1); - assert.same(hypot('', 0), 0); - assert.same(hypot(0, ''), 0); - assert.strictEqual(hypot(Infinity, 0), Infinity, 'Infinity, 0'); - assert.strictEqual(hypot(-Infinity, 0), Infinity, '-Infinity, 0'); - assert.strictEqual(hypot(0, Infinity), Infinity, '0, Infinity'); - assert.strictEqual(hypot(0, -Infinity), Infinity, '0, -Infinity'); - assert.strictEqual(hypot(Infinity, NaN), Infinity, 'Infinity, NaN'); - assert.strictEqual(hypot(NaN, -Infinity), Infinity, 'NaN, -Infinity'); - assert.same(hypot(NaN, 0), NaN, 'NaN, 0'); - assert.same(hypot(0, NaN), NaN, '0, NaN'); - assert.same(hypot(0, -0), 0); - assert.same(hypot(0, 0), 0); - assert.same(hypot(-0, -0), 0); - assert.same(hypot(-0, 0), 0); - assert.strictEqual(hypot(0, 1), 1); - assert.strictEqual(hypot(0, -1), 1); - assert.strictEqual(hypot(-0, 1), 1); - assert.strictEqual(hypot(-0, -1), 1); - assert.same(hypot(0), 0); - assert.strictEqual(hypot(1), 1); - assert.strictEqual(hypot(2), 2); - assert.strictEqual(hypot(0, 0, 1), 1); - assert.strictEqual(hypot(0, 1, 0), 1); - assert.strictEqual(hypot(1, 0, 0), 1); - assert.strictEqual(hypot(2, 3, 4), sqrt(2 * 2 + 3 * 3 + 4 * 4)); - assert.strictEqual(hypot(2, 3, 4, 5), sqrt(2 * 2 + 3 * 3 + 4 * 4 + 5 * 5)); - assert.epsilon(hypot(66, 66), 93.33809511662427); - assert.epsilon(hypot(0.1, 100), 100.0000499999875); - assert.strictEqual(hypot(1e+300, 1e+300), 1.4142135623730952e+300); - assert.strictEqual(Math.floor(hypot(1e-300, 1e-300) * 1e308), 141421356); - assert.strictEqual(hypot(1e+300, 1e+300, 2, 3), 1.4142135623730952e+300); - assert.strictEqual(hypot(-3, 4), 5); - assert.strictEqual(hypot(3, -4), 5); -}); diff --git a/tests/tests/es.math.imul.js b/tests/tests/es.math.imul.js deleted file mode 100644 index 787376d17b2d..000000000000 --- a/tests/tests/es.math.imul.js +++ /dev/null @@ -1,43 +0,0 @@ -QUnit.test('Math.imul', assert => { - const { imul } = Math; - assert.isFunction(imul); - assert.name(imul, 'imul'); - assert.arity(imul, 2); - assert.looksNative(imul); - assert.nonEnumerable(Math, 'imul'); - assert.same(imul(0, 0), 0); - assert.strictEqual(imul(123, 456), 56088); - assert.strictEqual(imul(-123, 456), -56088); - assert.strictEqual(imul(123, -456), -56088); - assert.strictEqual(imul(19088743, 4275878552), 602016552); - assert.same(imul(false, 7), 0); - assert.same(imul(7, false), 0); - assert.same(imul(false, false), 0); - assert.strictEqual(imul(true, 7), 7); - assert.strictEqual(imul(7, true), 7); - assert.strictEqual(imul(true, true), 1); - assert.same(imul(undefined, 7), 0); - assert.same(imul(7, undefined), 0); - assert.same(imul(undefined, undefined), 0); - assert.same(imul('str', 7), 0); - assert.same(imul(7, 'str'), 0); - assert.same(imul({}, 7), 0); - assert.same(imul(7, {}), 0); - assert.same(imul([], 7), 0); - assert.same(imul(7, []), 0); - assert.strictEqual(imul(0xFFFFFFFF, 5), -5); - assert.strictEqual(imul(0xFFFFFFFE, 5), -10); - assert.strictEqual(imul(2, 4), 8); - assert.strictEqual(imul(-1, 8), -8); - assert.strictEqual(imul(-2, -2), 4); - assert.same(imul(-0, 7), 0); - assert.same(imul(7, -0), 0); - assert.same(imul(0.1, 7), 0); - assert.same(imul(7, 0.1), 0); - assert.same(imul(0.9, 7), 0); - assert.same(imul(7, 0.9), 0); - assert.strictEqual(imul(1.1, 7), 7); - assert.strictEqual(imul(7, 1.1), 7); - assert.strictEqual(imul(1.9, 7), 7); - assert.strictEqual(imul(7, 1.9), 7); -}); diff --git a/tests/tests/es.math.log10.js b/tests/tests/es.math.log10.js deleted file mode 100644 index ca6d4a8197d3..000000000000 --- a/tests/tests/es.math.log10.js +++ /dev/null @@ -1,21 +0,0 @@ -QUnit.test('Math.log10', assert => { - const { log10 } = Math; - assert.isFunction(log10); - assert.name(log10, 'log10'); - assert.arity(log10, 1); - assert.looksNative(log10); - assert.nonEnumerable(Math, 'log10'); - assert.same(log10(''), log10(0)); - assert.same(log10(NaN), NaN); - assert.same(log10(-1), NaN); - assert.same(log10(0), -Infinity); - assert.same(log10(-0), -Infinity); - assert.same(log10(1), 0); - assert.same(log10(Infinity), Infinity); - assert.epsilon(log10(0.1), -1); - assert.epsilon(log10(0.5), -0.3010299956639812); - assert.epsilon(log10(1.5), 0.17609125905568124); - assert.epsilon(log10(5), 0.6989700043360189); - assert.epsilon(log10(50), 1.6989700043360187); - assert.epsilon(log10(1000), 3); -}); diff --git a/tests/tests/es.math.log1p.js b/tests/tests/es.math.log1p.js deleted file mode 100644 index 62f74b28f30d..000000000000 --- a/tests/tests/es.math.log1p.js +++ /dev/null @@ -1,17 +0,0 @@ -QUnit.test('Math.log1p', assert => { - const { log1p } = Math; - assert.isFunction(log1p); - assert.name(log1p, 'log1p'); - assert.arity(log1p, 1); - assert.looksNative(log1p); - assert.nonEnumerable(Math, 'log1p'); - assert.same(log1p(''), log1p(0)); - assert.same(log1p(NaN), NaN); - assert.same(log1p(-2), NaN); - assert.same(log1p(-1), -Infinity); - assert.same(log1p(0), 0); - assert.same(log1p(-0), -0); - assert.same(log1p(Infinity), Infinity); - assert.epsilon(log1p(5), 1.791759469228055); - assert.epsilon(log1p(50), 3.9318256327243257); -}); diff --git a/tests/tests/es.math.log2.js b/tests/tests/es.math.log2.js deleted file mode 100644 index 78122ce29043..000000000000 --- a/tests/tests/es.math.log2.js +++ /dev/null @@ -1,18 +0,0 @@ -QUnit.test('Math.log2', assert => { - const { log2 } = Math; - assert.isFunction(log2); - assert.name(log2, 'log2'); - assert.arity(log2, 1); - assert.looksNative(log2); - assert.nonEnumerable(Math, 'log2'); - assert.same(log2(''), log2(0)); - assert.same(log2(NaN), NaN); - assert.same(log2(-1), NaN); - assert.same(log2(0), -Infinity); - assert.same(log2(-0), -Infinity); - assert.same(log2(1), 0); - assert.same(log2(Infinity), Infinity); - assert.same(log2(0.5), -1); - assert.same(log2(32), 5); - assert.epsilon(log2(5), 2.321928094887362); -}); diff --git a/tests/tests/es.math.sign.js b/tests/tests/es.math.sign.js deleted file mode 100644 index a0a3eba6b966..000000000000 --- a/tests/tests/es.math.sign.js +++ /dev/null @@ -1,18 +0,0 @@ -QUnit.test('Math.sign', assert => { - const { sign } = Math; - assert.isFunction(sign); - assert.name(sign, 'sign'); - assert.arity(sign, 1); - assert.looksNative(sign); - assert.nonEnumerable(Math, 'sign'); - assert.same(sign(NaN), NaN); - assert.same(sign(), NaN); - assert.same(sign(-0), -0); - assert.same(sign(0), 0); - assert.strictEqual(sign(Infinity), 1); - assert.strictEqual(sign(-Infinity), -1); - assert.strictEqual(sign(13510798882111488), 1); - assert.strictEqual(sign(-13510798882111488), -1); - assert.strictEqual(sign(42.5), 1); - assert.strictEqual(sign(-42.5), -1); -}); diff --git a/tests/tests/es.math.sinh.js b/tests/tests/es.math.sinh.js deleted file mode 100644 index c2ed8d749dea..000000000000 --- a/tests/tests/es.math.sinh.js +++ /dev/null @@ -1,16 +0,0 @@ -QUnit.test('Math.sinh', assert => { - const { sinh } = Math; - assert.isFunction(sinh); - assert.name(sinh, 'sinh'); - assert.arity(sinh, 1); - assert.looksNative(sinh); - assert.nonEnumerable(Math, 'sinh'); - assert.same(sinh(NaN), NaN); - assert.same(sinh(0), 0); - assert.same(sinh(-0), -0); - assert.strictEqual(sinh(Infinity), Infinity); - assert.strictEqual(sinh(-Infinity), -Infinity); - assert.epsilon(sinh(-5), -74.20321057778875); - assert.epsilon(sinh(2), 3.6268604078470186); - assert.strictEqual(sinh(-2e-17), -2e-17); -}); diff --git a/tests/tests/es.math.tanh.js b/tests/tests/es.math.tanh.js deleted file mode 100644 index 2efff5d6d0ab..000000000000 --- a/tests/tests/es.math.tanh.js +++ /dev/null @@ -1,17 +0,0 @@ -import { NATIVE } from '../helpers/constants'; - -QUnit.test('Math.tanh', assert => { - const { tanh } = Math; - assert.isFunction(tanh); - assert.name(tanh, 'tanh'); - assert.arity(tanh, 1); - assert.looksNative(tanh); - assert.nonEnumerable(Math, 'tanh'); - assert.same(tanh(NaN), NaN); - assert.same(tanh(0), 0); - assert.same(tanh(-0), -0); - assert.strictEqual(tanh(Infinity), 1); - assert.strictEqual(tanh(90), 1); - assert.epsilon(tanh(10), 0.9999999958776927); - if (NATIVE) assert.strictEqual(tanh(710), 1); -}); diff --git a/tests/tests/es.math.trunc.js b/tests/tests/es.math.trunc.js deleted file mode 100644 index 4171dd64d27e..000000000000 --- a/tests/tests/es.math.trunc.js +++ /dev/null @@ -1,23 +0,0 @@ -QUnit.test('Math.trunc', assert => { - const { trunc } = Math; - assert.isFunction(trunc); - assert.name(trunc, 'trunc'); - assert.arity(trunc, 1); - assert.looksNative(trunc); - assert.nonEnumerable(Math, 'trunc'); - assert.same(trunc(NaN), NaN, 'NaN -> NaN'); - assert.same(trunc(-0), -0, '-0 -> -0'); - assert.same(trunc(0), 0, '0 -> 0'); - assert.same(trunc(Infinity), Infinity, 'Infinity -> Infinity'); - assert.same(trunc(-Infinity), -Infinity, '-Infinity -> -Infinity'); - assert.same(trunc(null), 0, 'null -> 0'); - assert.same(trunc({}), NaN, '{} -> NaN'); - assert.strictEqual(trunc([]), 0, '[] -> 0'); - assert.strictEqual(trunc(1.01), 1, '1.01 -> 0'); - assert.strictEqual(trunc(1.99), 1, '1.99 -> 0'); - assert.strictEqual(trunc(-1), -1, '-1 -> -1'); - assert.strictEqual(trunc(-1.99), -1, '-1.99 -> -1'); - assert.strictEqual(trunc(-555.555), -555, '-555.555 -> -555'); - assert.strictEqual(trunc(0x20000000000001), 0x20000000000001, '0x20000000000001 -> 0x20000000000001'); - assert.strictEqual(trunc(-0x20000000000001), -0x20000000000001, '-0x20000000000001 -> -0x20000000000001'); -}); diff --git a/tests/tests/es.number.constructor.js b/tests/tests/es.number.constructor.js deleted file mode 100644 index e5a638fff9e9..000000000000 --- a/tests/tests/es.number.constructor.js +++ /dev/null @@ -1,265 +0,0 @@ -import { nativeSubclass } from '../helpers/helpers'; -const whitespaces = ' \t\u000B\f\u00A0\uFEFF\n\r\u2028\u2029\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'; - -function getCheck(assert) { - return function (a, b) { - assert.same(Number(a), b, `Number ${ typeof a } ${ a } -> ${ b }`); - const x = new Number(a); - assert.ok(x === Object(x), `new Number ${ typeof a } ${ a } is object`); - assert.strictEqual({}.toString.call(x).slice(8, -1), 'Number', `classof new Number ${ typeof a } ${ a } is Number`); - assert.same(x.valueOf(), b, `new Number(${ typeof a } ${ a }).valueOf() -> ${ b }`); - }; -} - -QUnit.test('Number constructor: regression', assert => { - const check = getCheck(assert); - assert.isFunction(Number); - assert.arity(Number, 1); - assert.name(Number, 'Number'); - assert.looksNative(Number); - assert.same(Number.prototype.constructor, Number); - assert.same(1.0.constructor, Number); - const constants = ['MAX_VALUE', 'MIN_VALUE', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY']; - for (const constant of constants) { - assert.ok(constant in Number, `Number.${ constant }`); - assert.nonEnumerable(Number, constant); - } - assert.same(Number(), 0); - assert.same(new Number().valueOf(), 0); - check(42, 42); - check(42.42, 42.42); - check(new Number(42), 42); - check(new Number(42.42), 42.42); - check('42', 42); - check('42.42', 42.42); - check('0x42', 66); - check('0X42', 66); - check('0xzzz', NaN); - check('0x1g', NaN); - check('+0x1', NaN); - check('-0x1', NaN); - check('+0X1', NaN); - check('-0X1', NaN); - check(new String('42'), 42); - check(new String('42.42'), 42.42); - check(new String('0x42'), 66); - check(null, 0); - check(undefined, NaN); - check(false, 0); - check(true, 1); - check(new Boolean(false), 0); - check(new Boolean(true), 1); - check({}, NaN); - check({ - valueOf: '1.1', - }, NaN); - check({ - valueOf: '1.1', - toString() { - return '2.2'; - }, - }, 2.2); - check({ - valueOf() { - return '1.1'; - }, - }, 1.1); - check({ - valueOf() { - return '1.1'; - }, - toString() { - return '2.2'; - }, - }, 1.1); - check({ - valueOf() { - return '-0x1a2b3c'; - }, - }, NaN); - check({ - toString() { - return '-0x1a2b3c'; - }, - }, NaN); - check({ - valueOf() { - return 42; - }, - }, 42); - check({ - valueOf() { - return '42'; - }, - }, 42); - check({ - valueOf() { - return null; - }, - }, 0); - check({ - toString() { - return 42; - }, - }, 42); - check({ - toString() { - return '42'; - }, - }, 42); - check({ - valueOf() { - return 1; - }, - toString() { - return 2; - }, - }, 1); - check({ - valueOf: 1, - toString() { - return 2; - }, - }, 2); - let number = 1; - assert.strictEqual(Number({ - valueOf() { - return ++number; - }, - }), 2, 'Number call valueOf only once #1'); - assert.strictEqual(number, 2, 'Number call valueOf only once #2'); - number = 1; - assert.strictEqual(Number({ - toString() { - return ++number; - }, - }), 2, 'Number call toString only once #1'); - assert.strictEqual(number, 2, 'Number call toString only once #2'); - number = 1; - assert.strictEqual(new Number({ - valueOf() { - return ++number; - }, - }).valueOf(), 2, 'new Number call valueOf only once #1'); - assert.strictEqual(number, 2, 'new Number call valueOf only once #2'); - number = 1; - assert.strictEqual(new Number({ - toString() { - return ++number; - }, - }).valueOf(), 2, 'new Number call toString only once #1'); - assert.strictEqual(number, 2, 'new Number call toString only once #2'); - assert.throws(() => Number(Object.create(null)), TypeError, 'Number assert.throws on object w/o valueOf and toString'); - assert.throws(() => Number({ - valueOf: 1, - toString: 2, - }), TypeError, 'Number assert.throws on object then valueOf and toString are not functions'); - assert.throws(() => new Number(Object.create(null)), TypeError, 'new Number assert.throws on object w/o valueOf and toString'); - assert.throws(() => new Number({ - valueOf: 1, - toString: 2, - }), TypeError, 'new Number assert.throws on object then valueOf and toString are not functions'); - number = new Number(42); - assert.strictEqual(typeof number.constructor(number), 'number'); - check(`${ whitespaces }42`, 42); - check(`42${ whitespaces }`, 42); - check(`${ whitespaces }42${ whitespaces }`, 42); - check(`${ whitespaces }0x42`, 66); - check(`0x42${ whitespaces }`, 66); - check(`${ whitespaces }0x42${ whitespaces }`, 66); - check(`${ whitespaces }0X42`, 66); - check(`0X42${ whitespaces }`, 66); - check(`${ whitespaces }0X42${ whitespaces }`, 66); - if (nativeSubclass) { - const Subclass = nativeSubclass(Number); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof Number, 'correct subclassing with native classes #2'); - assert.same(new Subclass(1).toFixed(2), '1.00', 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('Number constructor: binary', assert => { - const check = getCheck(assert); - check('0b1', 1); - check('0B1', 1); - check('0b12', NaN); - check('0b234', NaN); - check('0b1!', NaN); - check('+0b1', NaN); - check('-0b1', NaN); - check(' 0b1', 1); - check('0b1\n', 1); - check('\n 0b1\n ', 1); - check(' 0B1', 1); - check('0B1\n', 1); - check('\n 0B1\n ', 1); - check({ - valueOf() { - return '0b11'; - }, - }, 3); - check({ - toString() { - return '0b111'; - }, - }, 7); - check({ - valueOf() { - return '0b101010'; - }, - }, 42); - check({ - toString() { - return '0b101010'; - }, - }, 42); - check(`${ whitespaces }0b11`, 3); - check(`0b11${ whitespaces }`, 3); - check(`${ whitespaces }0b11${ whitespaces }`, 3); - check(`${ whitespaces }0B11`, 3); - check(`0B11${ whitespaces }`, 3); - check(`${ whitespaces }0B11${ whitespaces }`, 3); -}); - -QUnit.test('Number constructor: octal', assert => { - const check = getCheck(assert); - check('0o7', 7); - check('0O7', 7); - check('0o18', NaN); - check('0o89a', NaN); - check('0o1!', NaN); - check('+0o1', NaN); - check('-0o1', NaN); - check(' 0o1', 1); - check('0o1\n', 1); - check('\n 0o1\n ', 1); - check(' 0O1', 1); - check('0O1\n', 1); - check('\n 0O1\n ', 1); - check({ - valueOf() { - return '0o77'; - }, - }, 63); - check({ - toString() { - return '0o777'; - }, - }, 511); - check({ - valueOf() { - return '0o12345'; - }, - }, 5349); - check({ - toString() { - return '0o12345'; - }, - }, 5349); - check(`${ whitespaces }0o11`, 9); - check(`0o11${ whitespaces }`, 9); - check(`${ whitespaces }0o11${ whitespaces }`, 9); - check(`${ whitespaces }0O11`, 9); - check(`0O11${ whitespaces }`, 9); - check(`${ whitespaces }0O11${ whitespaces }`, 9); -}); diff --git a/tests/tests/es.number.epsilon.js b/tests/tests/es.number.epsilon.js deleted file mode 100644 index 3d770dbf04fb..000000000000 --- a/tests/tests/es.number.epsilon.js +++ /dev/null @@ -1,8 +0,0 @@ -QUnit.test('Number.EPSILON', assert => { - const { EPSILON } = Number; - assert.ok('EPSILON' in Number, 'EPSILON in Number'); - assert.nonEnumerable(Number, 'EPSILON'); - assert.strictEqual(EPSILON, 2 ** -52, 'Is 2^-52'); - assert.ok(1 !== 1 + EPSILON, '1 isnt 1 + EPSILON'); - assert.strictEqual(1, 1 + EPSILON / 2, '1 is 1 + EPSILON / 2'); -}); diff --git a/tests/tests/es.number.is-finite.js b/tests/tests/es.number.is-finite.js deleted file mode 100644 index 54491a09733a..000000000000 --- a/tests/tests/es.number.is-finite.js +++ /dev/null @@ -1,43 +0,0 @@ -QUnit.test('Number.isFinite', assert => { - const { isFinite } = Number; - const { create } = Object; - assert.isFunction(isFinite); - assert.name(isFinite, 'isFinite'); - assert.arity(isFinite, 1); - assert.looksNative(isFinite); - assert.nonEnumerable(Number, 'isFinite'); - const finite = [ - 1, - 0.1, - -1, - 2 ** 16, - 2 ** 16 - 1, - 2 ** 31, - 2 ** 31 - 1, - 2 ** 32, - 2 ** 32 - 1, - -0, - ]; - for (const value of finite) { - assert.ok(isFinite(value), `isFinite ${ typeof value } ${ value }`); - } - const notFinite = [ - NaN, - Infinity, - 'NaN', - '5', - false, - new Number(NaN), - new Number(Infinity), - new Number(5), - new Number(0.1), - undefined, - null, - {}, - function () { /* empty */ }, - ]; - for (const value of notFinite) { - assert.ok(!isFinite(value), `not isFinite ${ typeof value } ${ value }`); - } - assert.ok(!isFinite(create(null)), 'Number.isFinite(Object.create(null)) -> false'); -}); diff --git a/tests/tests/es.number.is-integer.js b/tests/tests/es.number.is-integer.js deleted file mode 100644 index cbbef04bd7b5..000000000000 --- a/tests/tests/es.number.is-integer.js +++ /dev/null @@ -1,43 +0,0 @@ -QUnit.test('Number.isInteger', assert => { - const { isInteger } = Number; - const { create } = Object; - assert.isFunction(isInteger); - assert.name(isInteger, 'isInteger'); - assert.arity(isInteger, 1); - assert.looksNative(isInteger); - assert.nonEnumerable(Number, 'isInteger'); - const integers = [ - 1, - -1, - 2 ** 16, - 2 ** 16 - 1, - 2 ** 31, - 2 ** 31 - 1, - 2 ** 32, - 2 ** 32 - 1, - -0, - ]; - for (const value of integers) { - assert.ok(isInteger(value), `isInteger ${ typeof value } ${ value }`); - } - const notIntegers = [ - NaN, - 0.1, - Infinity, - 'NaN', - '5', - false, - new Number(NaN), - new Number(Infinity), - new Number(5), - new Number(0.1), - undefined, - null, - {}, - function () { /* empty */ }, - ]; - for (const value of notIntegers) { - assert.ok(!isInteger(value), `not isInteger ${ typeof value } ${ value }`); - } - assert.ok(!isInteger(create(null)), 'Number.isInteger(Object.create(null)) -> false'); -}); diff --git a/tests/tests/es.number.is-nan.js b/tests/tests/es.number.is-nan.js deleted file mode 100644 index a0f80b2e6756..000000000000 --- a/tests/tests/es.number.is-nan.js +++ /dev/null @@ -1,38 +0,0 @@ -QUnit.test('Number.isNaN', assert => { - const { isNaN } = Number; - const { create } = Object; - assert.isFunction(isNaN); - assert.name(isNaN, 'isNaN'); - assert.arity(isNaN, 1); - assert.looksNative(isNaN); - assert.nonEnumerable(Number, 'isNaN'); - assert.ok(isNaN(NaN), 'Number.isNaN NaN'); - const notNaNs = [ - 1, - 0.1, - -1, - 2 ** 16, - 2 ** 16 - 1, - 2 ** 31, - 2 ** 31 - 1, - 2 ** 32, - 2 ** 32 - 1, - -0, - Infinity, - 'NaN', - '5', - false, - new Number(NaN), - new Number(Infinity), - new Number(5), - new Number(0.1), - undefined, - null, - {}, - function () { /* empty */ }, - ]; - for (const value of notNaNs) { - assert.ok(!isNaN(value), `not Number.isNaN ${ typeof value } ${ value }`); - } - assert.ok(!isNaN(create(null)), 'Number.isNaN(Object.create(null)) -> false'); -}); diff --git a/tests/tests/es.number.is-safe-integer.js b/tests/tests/es.number.is-safe-integer.js deleted file mode 100644 index dba40244646d..000000000000 --- a/tests/tests/es.number.is-safe-integer.js +++ /dev/null @@ -1,47 +0,0 @@ -QUnit.test('Number.isSafeInteger', assert => { - const { isSafeInteger } = Number; - const { create } = Object; - assert.isFunction(isSafeInteger); - assert.name(isSafeInteger, 'isSafeInteger'); - assert.arity(isSafeInteger, 1); - assert.looksNative(isSafeInteger); - assert.nonEnumerable(Number, 'isSafeInteger'); - const safeIntegers = [ - 1, - -1, - 2 ** 16, - 2 ** 16 - 1, - 2 ** 31, - 2 ** 31 - 1, - 2 ** 32, - 2 ** 32 - 1, - -0, - 9007199254740991, - -9007199254740991, - ]; - for (const value of safeIntegers) { - assert.ok(isSafeInteger(value), `isSafeInteger ${ typeof value } ${ value }`); - } - const notSafeIntegers = [ - 9007199254740992, - -9007199254740992, - NaN, - 0.1, - Infinity, - 'NaN', - '5', - false, - new Number(NaN), - new Number(Infinity), - new Number(5), - new Number(0.1), - undefined, - null, - {}, - function () { /* empty */ }, - ]; - for (const value of notSafeIntegers) { - assert.ok(!isSafeInteger(value), `not isSafeInteger ${ typeof value } ${ value }`); - } - assert.ok(!isSafeInteger(create(null)), 'Number.isSafeInteger(Object.create(null)) -> false'); -}); diff --git a/tests/tests/es.number.max-safe-integer.js b/tests/tests/es.number.max-safe-integer.js deleted file mode 100644 index 15985ad36ced..000000000000 --- a/tests/tests/es.number.max-safe-integer.js +++ /dev/null @@ -1,5 +0,0 @@ -QUnit.test('Number.MAX_SAFE_INTEGER', assert => { - assert.ok('MAX_SAFE_INTEGER' in Number); - assert.nonEnumerable(Number, 'MAX_SAFE_INTEGER'); - assert.strictEqual(Number.MAX_SAFE_INTEGER, 2 ** 53 - 1, 'Is 2^53 - 1'); -}); diff --git a/tests/tests/es.number.min-safe-integer.js b/tests/tests/es.number.min-safe-integer.js deleted file mode 100644 index 0a664a7add70..000000000000 --- a/tests/tests/es.number.min-safe-integer.js +++ /dev/null @@ -1,5 +0,0 @@ -QUnit.test('Number.MIN_SAFE_INTEGER', assert => { - assert.ok('MIN_SAFE_INTEGER' in Number); - assert.nonEnumerable(Number, 'MIN_SAFE_INTEGER'); - assert.strictEqual(Number.MIN_SAFE_INTEGER, -(2 ** 53) + 1, 'Is -2^53 + 1'); -}); diff --git a/tests/tests/es.number.parse-float.js b/tests/tests/es.number.parse-float.js deleted file mode 100644 index 43f1ce8c35c3..000000000000 --- a/tests/tests/es.number.parse-float.js +++ /dev/null @@ -1,21 +0,0 @@ -import { GLOBAL, WHITESPACES } from '../helpers/constants'; - -QUnit.test('Number.parseFloat', assert => { - const { parseFloat } = Number; - assert.isFunction(parseFloat); - assert.name(parseFloat, 'parseFloat'); - assert.arity(parseFloat, 1); - assert.looksNative(parseFloat); - assert.nonEnumerable(Number, 'parseFloat'); - assert.same(parseFloat, GLOBAL.parseFloat); - assert.same(parseFloat('0'), 0); - assert.same(parseFloat(' 0'), 0); - assert.same(parseFloat('+0'), 0); - assert.same(parseFloat(' +0'), 0); - assert.same(parseFloat('-0'), -0); - assert.same(parseFloat(' -0'), -0); - assert.same(parseFloat(`${ WHITESPACES }+0`), 0); - assert.same(parseFloat(`${ WHITESPACES }-0`), -0); - assert.same(parseFloat(null), NaN); - assert.same(parseFloat(undefined), NaN); -}); diff --git a/tests/tests/es.number.parse-int.js b/tests/tests/es.number.parse-int.js deleted file mode 100644 index fcf692a9ebf5..000000000000 --- a/tests/tests/es.number.parse-int.js +++ /dev/null @@ -1,38 +0,0 @@ -import { GLOBAL, WHITESPACES } from '../helpers/constants'; - -QUnit.test('Number.parseInt', assert => { - const { parseInt } = Number; - assert.isFunction(parseInt); - assert.name(parseInt, 'parseInt'); - assert.arity(parseInt, 2); - assert.looksNative(parseInt); - assert.nonEnumerable(Number, 'parseInt'); - assert.same(parseInt, GLOBAL.parseInt); - for (let radix = 2; radix <= 36; ++radix) { - assert.same(parseInt('10', radix), radix, `radix ${ radix }`); - } - const strings = ['01', '08', '10', '42']; - for (const string of strings) { - assert.same(parseInt(string), parseInt(string, 10), `default radix is 10: ${ string }`); - } - assert.same(parseInt('0x16'), parseInt('0x16', 16), 'default radix is 16: 0x16'); - assert.same(parseInt(' 0x16'), parseInt('0x16', 16), 'ignores leading whitespace #1'); - assert.same(parseInt(' 42'), parseInt('42', 10), 'ignores leading whitespace #2'); - assert.same(parseInt(' 08'), parseInt('08', 10), 'ignores leading whitespace #3'); - assert.same(parseInt(`${ WHITESPACES }08`), parseInt('08', 10), 'ignores leading whitespace #4'); - assert.same(parseInt(`${ WHITESPACES }0x16`), parseInt('0x16', 16), 'ignores leading whitespace #5'); - const fakeZero = { - valueOf() { - return 0; - }, - }; - assert.same(parseInt('08', fakeZero), parseInt('08', 10), 'valueOf #1'); - assert.same(parseInt('0x16', fakeZero), parseInt('0x16', 16), 'valueOf #2'); - assert.same(parseInt('-0xF'), -15, 'signed hex #1'); - assert.same(parseInt('-0xF', 16), -15, 'signed hex #2'); - assert.same(parseInt('+0xF'), 15, 'signed hex #3'); - assert.same(parseInt('+0xF', 16), 15, 'signed hex #4'); - assert.same(parseInt('10', -4294967294), 2, 'radix uses ToUint32'); - assert.same(parseInt(null), NaN); - assert.same(parseInt(undefined), NaN); -}); diff --git a/tests/tests/es.number.to-fixed.js b/tests/tests/es.number.to-fixed.js deleted file mode 100644 index b9082fb80d34..000000000000 --- a/tests/tests/es.number.to-fixed.js +++ /dev/null @@ -1,69 +0,0 @@ -QUnit.test('Number#toFixed', assert => { - const { toFixed } = Number.prototype; - assert.isFunction(toFixed); - assert.name(toFixed, 'toFixed'); - assert.arity(toFixed, 1); - assert.looksNative(toFixed); - assert.nonEnumerable(Number.prototype, 'toFixed'); - assert.same(0.00008.toFixed(3), '0.000'); - assert.same(0.9.toFixed(0), '1'); - assert.same(1.255.toFixed(2), '1.25'); - assert.same(1843654265.0774949.toFixed(5), '1843654265.07749'); - assert.same(1000000000000000128.0.toFixed(0), '1000000000000000128'); - assert.same(toFixed.call(1), '1'); - assert.same(toFixed.call(1, 0), '1'); - assert.same(toFixed.call(1, 1), '1.0'); - assert.same(toFixed.call(1, 1.1), '1.0'); - assert.same(toFixed.call(1, 0.9), '1'); - assert.same(toFixed.call(1, '0'), '1'); - assert.same(toFixed.call(1, '1'), '1.0'); - assert.same(toFixed.call(1, '1.1'), '1.0'); - assert.same(toFixed.call(1, '0.9'), '1'); - assert.same(toFixed.call(1, NaN), '1'); - assert.same(toFixed.call(1, 'some string'), '1'); - assert.notThrows(() => toFixed.call(1, -0.1) === '1'); - assert.same(new Number(1).toFixed(), '1'); - assert.same(new Number(1).toFixed(0), '1'); - assert.same(new Number(1).toFixed(1), '1.0'); - assert.same(new Number(1).toFixed(1.1), '1.0'); - assert.same(new Number(1).toFixed(0.9), '1'); - assert.same(new Number(1).toFixed('0'), '1'); - assert.same(new Number(1).toFixed('1'), '1.0'); - assert.same(new Number(1).toFixed('1.1'), '1.0'); - assert.same(new Number(1).toFixed('0.9'), '1'); - assert.same(new Number(1).toFixed(NaN), '1'); - assert.same(new Number(1).toFixed('some string'), '1'); - assert.notThrows(() => new Number(1).toFixed(-0.1) === '1'); - assert.same(NaN.toFixed(), 'NaN'); - assert.same(NaN.toFixed(0), 'NaN'); - assert.same(NaN.toFixed(1), 'NaN'); - assert.same(NaN.toFixed(1.1), 'NaN'); - assert.same(NaN.toFixed(0.9), 'NaN'); - assert.same(NaN.toFixed('0'), 'NaN'); - assert.same(NaN.toFixed('1'), 'NaN'); - assert.same(NaN.toFixed('1.1'), 'NaN'); - assert.same(NaN.toFixed('0.9'), 'NaN'); - assert.same(NaN.toFixed(NaN), 'NaN'); - assert.same(NaN.toFixed('some string'), 'NaN'); - assert.notThrows(() => NaN.toFixed(-0.1) === 'NaN'); - assert.same(new Number(1e21).toFixed(), String(1e21)); - assert.same(new Number(1e21).toFixed(0), String(1e21)); - assert.same(new Number(1e21).toFixed(1), String(1e21)); - assert.same(new Number(1e21).toFixed(1.1), String(1e21)); - assert.same(new Number(1e21).toFixed(0.9), String(1e21)); - assert.same(new Number(1e21).toFixed('0'), String(1e21)); - assert.same(new Number(1e21).toFixed('1'), String(1e21)); - assert.same(new Number(1e21).toFixed('1.1'), String(1e21)); - assert.same(new Number(1e21).toFixed('0.9'), String(1e21)); - assert.same(new Number(1e21).toFixed(NaN), String(1e21)); - assert.same(new Number(1e21).toFixed('some string'), String(1e21)); - assert.notThrows(() => new Number(1e21).toFixed(-0.1) === String(1e21)); - assert.throws(() => 1.0.toFixed(-101), RangeError, 'If f < 0 or f > 20, throw a RangeError exception.'); - assert.throws(() => 1.0.toFixed(101), RangeError, 'If f < 0 or f > 20, throw a RangeError exception.'); - assert.throws(() => NaN.toFixed(Infinity), RangeError, 'If f < 0 or f > 20, throw a RangeError exception.'); - assert.throws(() => toFixed.call({}, 1), TypeError, '? thisNumberValue(this value)'); - assert.throws(() => toFixed.call('123', 1), TypeError, '? thisNumberValue(this value)'); - assert.throws(() => toFixed.call(false, 1), TypeError, '? thisNumberValue(this value)'); - assert.throws(() => toFixed.call(null, 1), TypeError, '? thisNumberValue(this value)'); - assert.throws(() => toFixed.call(undefined, 1), TypeError, '? thisNumberValue(this value)'); -}); diff --git a/tests/tests/es.object.assign.js b/tests/tests/es.object.assign.js deleted file mode 100644 index 3104ccf2a911..000000000000 --- a/tests/tests/es.object.assign.js +++ /dev/null @@ -1,67 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Object.assign', assert => { - const { assign, keys, defineProperty } = Object; - assert.isFunction(assign); - assert.arity(assign, 2); - assert.name(assign, 'assign'); - assert.looksNative(assign); - assert.nonEnumerable(Object, 'assign'); - let object = { q: 1 }; - assert.strictEqual(object, assign(object, { bar: 2 }), 'assign return target'); - assert.strictEqual(object.bar, 2, 'assign define properties'); - assert.deepEqual(assign({}, { q: 1 }, { w: 2 }), { q: 1, w: 2 }); - assert.deepEqual(assign({}, 'qwe'), { 0: 'q', 1: 'w', 2: 'e' }); - assert.throws(() => assign(null, { q: 1 }), TypeError); - assert.throws(() => assign(undefined, { q: 1 }), TypeError); - let string = assign('qwe', { q: 1 }); - assert.strictEqual(typeof string, 'object'); - assert.strictEqual(String(string), 'qwe'); - assert.strictEqual(string.q, 1); - assert.same(assign({}, { valueOf: 42 }).valueOf, 42, 'IE enum keys bug'); - if (DESCRIPTORS) { - object = { baz: 1 }; - assign(object, defineProperty({}, 'bar', { - get() { - return this.baz + 1; - }, - })); - assert.ok(object.bar === undefined, "assign don't copy descriptors"); - object = { a: 'a' }; - const c = Symbol('c'); - const d = Symbol('d'); - object[c] = 'c'; - defineProperty(object, 'b', { value: 'b' }); - defineProperty(object, d, { value: 'd' }); - const object2 = assign({}, object); - assert.strictEqual(object2.a, 'a', 'a'); - assert.strictEqual(object2.b, undefined, 'b'); - assert.strictEqual(object2[c], 'c', 'c'); - assert.strictEqual(object2[d], undefined, 'd'); - try { - assert.strictEqual(Function('assign', ` - return assign({ b: 1 }, { get a() { - delete this.b; - }, b: 2 }); - `)(assign).b, 1); - } catch { /* empty */ } - try { - assert.strictEqual(Function('assign', ` - return assign({ b: 1 }, { get a() { - Object.defineProperty(this, "b", { - value: 4, - enumerable: false - }); - }, b: 2 }); - `)(assign).b, 1); - } catch { /* empty */ } - } - string = 'abcdefghijklmnopqrst'; - const result = {}; - for (let i = 0, { length } = string; i < length; ++i) { - const char = string.charAt(i); - result[char] = char; - } - assert.strictEqual(keys(assign({}, result)).join(''), string); -}); - diff --git a/tests/tests/es.object.create.js b/tests/tests/es.object.create.js deleted file mode 100644 index 4400b234fa7a..000000000000 --- a/tests/tests/es.object.create.js +++ /dev/null @@ -1,36 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Object.create', assert => { - const { create, getPrototypeOf, getOwnPropertyNames } = Object; - function getPropertyNames(object) { - let result = []; - do { - result = result.concat(getOwnPropertyNames(object)); - } while (object = getPrototypeOf(object)); - return result; - } - assert.isFunction(create); - assert.arity(create, 2); - assert.name(create, 'create'); - assert.looksNative(create); - assert.nonEnumerable(Object, 'create'); - let object = { q: 1 }; - assert.ok({}.isPrototypeOf.call(object, create(object))); - assert.ok(create(object).q === 1); - function F() { - return this.a = 1; - } - assert.ok(create(new F()) instanceof F); - assert.ok(F.prototype === getPrototypeOf(getPrototypeOf(create(new F())))); - assert.ok(create(new F()).a === 1); - assert.ok(create({}, { a: { value: 42 } }).a === 42); - object = create(null, { w: { value: 2 } }); - assert.same(object, Object(object)); - assert.ok(!('toString' in object)); - assert.ok(object.w === 2); - assert.deepEqual(getPropertyNames(create(null)), []); -}); - -QUnit.test('Object.create.sham flag', assert => { - assert.same(Object.create.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/tests/es.object.define-getter.js b/tests/tests/es.object.define-getter.js deleted file mode 100644 index 3347826d71cd..000000000000 --- a/tests/tests/es.object.define-getter.js +++ /dev/null @@ -1,24 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -if (DESCRIPTORS) { - QUnit.test('Object#__defineGetter__', assert => { - const { __defineGetter__ } = Object.prototype; - assert.isFunction(__defineGetter__); - assert.arity(__defineGetter__, 2); - assert.name(__defineGetter__, '__defineGetter__'); - assert.looksNative(__defineGetter__); - assert.nonEnumerable(Object.prototype, '__defineGetter__'); - const object = {}; - assert.same(object.__defineGetter__('key', () => 42), undefined, 'void'); - assert.same(object.key, 42, 'works'); - object.__defineSetter__('key', function () { - this.foo = 43; - }); - object.key = 44; - assert.ok(object.key === 42 && object.foo === 43, 'works with setter'); - if (STRICT) { - assert.throws(() => __defineGetter__.call(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); - assert.throws(() => __defineGetter__.call(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); - } - }); -} diff --git a/tests/tests/es.object.define-properties.js b/tests/tests/es.object.define-properties.js deleted file mode 100644 index 6b9088b16f42..000000000000 --- a/tests/tests/es.object.define-properties.js +++ /dev/null @@ -1,19 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Object.defineProperties', assert => { - const { defineProperties } = Object; - assert.isFunction(defineProperties); - assert.arity(defineProperties, 2); - assert.name(defineProperties, 'defineProperties'); - assert.looksNative(defineProperties); - assert.nonEnumerable(Object, 'defineProperties'); - const source = {}; - const result = defineProperties(source, { q: { value: 42 }, w: { value: 33 } }); - assert.same(result, source); - assert.same(result.q, 42); - assert.same(result.w, 33); -}); - -QUnit.test('Object.defineProperties.sham flag', assert => { - assert.same(Object.defineProperties.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/tests/es.object.define-property.js b/tests/tests/es.object.define-property.js deleted file mode 100644 index 2bc628cc182b..000000000000 --- a/tests/tests/es.object.define-property.js +++ /dev/null @@ -1,23 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Object.defineProperty', assert => { - const { defineProperty, create } = Object; - assert.isFunction(defineProperty); - assert.arity(defineProperty, 3); - assert.name(defineProperty, 'defineProperty'); - assert.looksNative(defineProperty); - assert.nonEnumerable(Object, 'defineProperty'); - const source = {}; - const result = defineProperty(source, 'q', { - value: 42, - }); - assert.same(result, source); - assert.same(result.q, 42); - assert.throws(() => defineProperty(42, 1, {})); - assert.throws(() => defineProperty({}, create(null), {})); - assert.throws(() => defineProperty({}, 1, 1)); -}); - -QUnit.test('Object.defineProperty.sham flag', assert => { - assert.same(Object.defineProperty.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/tests/es.object.define-setter.js b/tests/tests/es.object.define-setter.js deleted file mode 100644 index 8438691bff38..000000000000 --- a/tests/tests/es.object.define-setter.js +++ /dev/null @@ -1,29 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -if (DESCRIPTORS) { - QUnit.test('Object#__defineSetter__', assert => { - const { __defineSetter__ } = Object.prototype; - assert.isFunction(__defineSetter__); - assert.arity(__defineSetter__, 2); - assert.name(__defineSetter__, '__defineSetter__'); - assert.looksNative(__defineSetter__); - assert.nonEnumerable(Object.prototype, '__defineSetter__'); - let object = {}; - assert.same(object.__defineSetter__('key', function () { - this.foo = 43; - }), undefined, 'void'); - object.key = 44; - assert.same(object.foo, 43, 'works'); - object = {}; - object.__defineSetter__('key', function () { - this.foo = 43; - }); - object.__defineGetter__('key', () => 42); - object.key = 44; - assert.ok(object.key === 42 && object.foo === 43, 'works with getter'); - if (STRICT) { - assert.throws(() => __defineSetter__.call(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); - assert.throws(() => __defineSetter__.call(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); - } - }); -} diff --git a/tests/tests/es.object.freeze.js b/tests/tests/es.object.freeze.js deleted file mode 100644 index db8c4c0da941..000000000000 --- a/tests/tests/es.object.freeze.js +++ /dev/null @@ -1,24 +0,0 @@ -import { GLOBAL, NATIVE } from '../helpers/constants'; - -QUnit.test('Object.freeze', assert => { - const { freeze, isFrozen, keys, getOwnPropertyNames, getOwnPropertySymbols } = Object; - const { ownKeys } = GLOBAL.Reflect || {}; - assert.isFunction(freeze); - assert.arity(freeze, 1); - assert.name(freeze, 'freeze'); - assert.looksNative(freeze); - assert.nonEnumerable(Object, 'freeze'); - const data = [42, 'foo', false, null, undefined, {}]; - for (const value of data) { - assert.notThrows(() => freeze(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); - assert.same(freeze(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); - } - if (NATIVE) assert.ok(isFrozen(freeze({}))); - const results = []; - for (const key in freeze({})) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(freeze({})), []); - assert.arrayEqual(getOwnPropertyNames(freeze({})), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(freeze({})), []); - if (ownKeys) assert.arrayEqual(ownKeys(freeze({})), []); -}); diff --git a/tests/tests/es.object.from-entries.js b/tests/tests/es.object.from-entries.js deleted file mode 100644 index 9c797ffb13ff..000000000000 --- a/tests/tests/es.object.from-entries.js +++ /dev/null @@ -1,28 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Object.fromEntries', assert => { - const { fromEntries } = Object; - assert.isFunction(fromEntries); - assert.arity(fromEntries, 1); - assert.name(fromEntries, 'fromEntries'); - assert.looksNative(fromEntries); - assert.nonEnumerable(Object, 'fromEntries'); - - assert.ok(fromEntries([]) instanceof Object); - assert.same(fromEntries([['foo', 1]]).foo, 1); - assert.same(fromEntries(createIterable([['bar', 2]])).bar, 2); - - class Unit { - constructor(id) { - this.id = id; - } - toString() { - return `unit${ this.id }`; - } - } - const units = new Set([new Unit(101), new Unit(102), new Unit(103)]); - const object = fromEntries(units.entries()); - assert.same(object.unit101.id, 101); - assert.same(object.unit102.id, 102); - assert.same(object.unit103.id, 103); -}); diff --git a/tests/tests/es.object.get-own-property-descriptor.js b/tests/tests/es.object.get-own-property-descriptor.js deleted file mode 100644 index 90544958931d..000000000000 --- a/tests/tests/es.object.get-own-property-descriptor.js +++ /dev/null @@ -1,27 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Object.getOwnPropertyDescriptor', assert => { - const { getOwnPropertyDescriptor } = Object; - assert.isFunction(getOwnPropertyDescriptor); - assert.arity(getOwnPropertyDescriptor, 2); - assert.name(getOwnPropertyDescriptor, 'getOwnPropertyDescriptor'); - assert.looksNative(getOwnPropertyDescriptor); - assert.nonEnumerable(Object, 'getOwnPropertyDescriptor'); - assert.deepEqual(getOwnPropertyDescriptor({ q: 42 }, 'q'), { - writable: true, - enumerable: true, - configurable: true, - value: 42, - }); - assert.ok(getOwnPropertyDescriptor({}, 'toString') === undefined); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => getOwnPropertyDescriptor(value) || true, `accept ${ typeof value }`); - } - assert.throws(() => getOwnPropertyDescriptor(null), TypeError, 'throws on null'); - assert.throws(() => getOwnPropertyDescriptor(undefined), TypeError, 'throws on undefined'); -}); - -QUnit.test('Object.getOwnPropertyDescriptor.sham flag', assert => { - assert.same(Object.getOwnPropertyDescriptor.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/tests/es.object.get-own-property-descriptors.js b/tests/tests/es.object.get-own-property-descriptors.js deleted file mode 100644 index c82eaca12701..000000000000 --- a/tests/tests/es.object.get-own-property-descriptors.js +++ /dev/null @@ -1,42 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Object.getOwnPropertyDescriptors', assert => { - const { create, getOwnPropertyDescriptors } = Object; - assert.isFunction(getOwnPropertyDescriptors); - assert.arity(getOwnPropertyDescriptors, 1); - assert.name(getOwnPropertyDescriptors, 'getOwnPropertyDescriptors'); - assert.looksNative(getOwnPropertyDescriptors); - assert.nonEnumerable(Object, 'getOwnPropertyDescriptors'); - const object = create({ q: 1 }, { e: { value: 3 } }); - object.w = 2; - const symbol = Symbol('4'); - object[symbol] = 4; - const descriptors = getOwnPropertyDescriptors(object); - assert.strictEqual(descriptors.q, undefined); - assert.deepEqual(descriptors.w, { - enumerable: true, - configurable: true, - writable: true, - value: 2, - }); - if (DESCRIPTORS) { - assert.deepEqual(descriptors.e, { - enumerable: false, - configurable: false, - writable: false, - value: 3, - }); - } else { - assert.deepEqual(descriptors.e, { - enumerable: true, - configurable: true, - writable: true, - value: 3, - }); - } - assert.strictEqual(descriptors[symbol].value, 4); -}); - -QUnit.test('Object.getOwnPropertyDescriptors.sham flag', assert => { - assert.same(Object.getOwnPropertyDescriptors.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/tests/es.object.get-own-property-names.js b/tests/tests/es.object.get-own-property-names.js deleted file mode 100644 index b0c654c43670..000000000000 --- a/tests/tests/es.object.get-own-property-names.js +++ /dev/null @@ -1,50 +0,0 @@ -import { GLOBAL } from '../helpers/constants'; -import { includes } from '../helpers/helpers'; - -QUnit.test('Object.getOwnPropertyNames', assert => { - const { getOwnPropertyNames } = Object; - assert.isFunction(getOwnPropertyNames); - assert.arity(getOwnPropertyNames, 1); - assert.name(getOwnPropertyNames, 'getOwnPropertyNames'); - assert.looksNative(getOwnPropertyNames); - assert.nonEnumerable(Object, 'getOwnPropertyNames'); - function F1() { - this.w = 1; - } - function F2() { - this.toString = 1; - } - F1.prototype.q = F2.prototype.q = 1; - const names = getOwnPropertyNames([1, 2, 3]); - assert.strictEqual(names.length, 4); - assert.ok(includes(names, '0')); - assert.ok(includes(names, '1')); - assert.ok(includes(names, '2')); - assert.ok(includes(names, 'length')); - assert.deepEqual(getOwnPropertyNames(new F1()), ['w']); - assert.deepEqual(getOwnPropertyNames(new F2()), ['toString']); - assert.ok(includes(getOwnPropertyNames(Array.prototype), 'toString')); - assert.ok(includes(getOwnPropertyNames(Object.prototype), 'toString')); - assert.ok(includes(getOwnPropertyNames(Object.prototype), 'constructor')); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => getOwnPropertyNames(value), `accept ${ typeof value }`); - } - assert.throws(() => { - getOwnPropertyNames(null); - }, TypeError, 'throws on null'); - assert.throws(() => { - getOwnPropertyNames(undefined); - }, TypeError, 'throws on undefined'); - if (GLOBAL.document) { - assert.notThrows(() => { - const iframe = document.createElement('iframe'); - iframe.src = 'http://example.com/'; - document.documentElement.appendChild(iframe); - const window = iframe.contentWindow; - document.documentElement.removeChild(iframe); - return getOwnPropertyNames(window); - }, 'IE11 bug with iframe and window'); - } -}); - diff --git a/tests/tests/es.object.get-prototype-of.js b/tests/tests/es.object.get-prototype-of.js deleted file mode 100644 index 57cab2d61d7d..000000000000 --- a/tests/tests/es.object.get-prototype-of.js +++ /dev/null @@ -1,35 +0,0 @@ -import { CORRECT_PROTOTYPE_GETTER } from '../helpers/constants'; - -QUnit.test('Object.getPrototypeOf', assert => { - const { create, getPrototypeOf } = Object; - assert.isFunction(getPrototypeOf); - assert.arity(getPrototypeOf, 1); - assert.name(getPrototypeOf, 'getPrototypeOf'); - assert.looksNative(getPrototypeOf); - assert.nonEnumerable(Object, 'getPrototypeOf'); - assert.ok(getPrototypeOf({}) === Object.prototype); - assert.ok(getPrototypeOf([]) === Array.prototype); - function F() { /* empty */ } - assert.ok(getPrototypeOf(new F()) === F.prototype); - const object = { q: 1 }; - assert.ok(getPrototypeOf(create(object)) === object); - assert.ok(getPrototypeOf(create(null)) === null); - assert.ok(getPrototypeOf(getPrototypeOf({})) === null); - function Foo() { /* empty */ } - Foo.prototype.foo = 'foo'; - function Bar() { /* empty */ } - Bar.prototype = create(Foo.prototype); - Bar.prototype.constructor = Bar; - assert.strictEqual(getPrototypeOf(Bar.prototype).foo, 'foo'); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => getPrototypeOf(value), `accept ${ typeof value }`); - } - assert.throws(() => getPrototypeOf(null), TypeError, 'throws on null'); - assert.throws(() => getPrototypeOf(undefined), TypeError, 'throws on undefined'); - assert.strictEqual(getPrototypeOf('foo'), String.prototype); -}); - -QUnit.test('Object.getPrototypeOf.sham flag', assert => { - assert.same(Object.getPrototypeOf.sham, CORRECT_PROTOTYPE_GETTER ? undefined : true); -}); diff --git a/tests/tests/es.object.is-extensible.js b/tests/tests/es.object.is-extensible.js deleted file mode 100644 index c5527df96d77..000000000000 --- a/tests/tests/es.object.is-extensible.js +++ /dev/null @@ -1,18 +0,0 @@ -import { NATIVE } from '../helpers/constants'; - -QUnit.test('Object.isExtensible', assert => { - const { preventExtensions, isExtensible } = Object; - assert.isFunction(isExtensible); - assert.arity(isExtensible, 1); - assert.name(isExtensible, 'isExtensible'); - assert.nonEnumerable(Object, 'isExtensible'); - assert.looksNative(isExtensible); - const primitives = [42, 'string', false, null, undefined]; - for (const value of primitives) { - assert.notThrows(() => isExtensible(value) || true, `accept ${ value }`); - assert.same(isExtensible(value), false, `returns true on ${ value }`); - } - assert.same(isExtensible({}), true); - if (NATIVE) assert.ok(!isExtensible(preventExtensions({}))); -}); - diff --git a/tests/tests/es.object.is-frozen.js b/tests/tests/es.object.is-frozen.js deleted file mode 100644 index cacba40291b5..000000000000 --- a/tests/tests/es.object.is-frozen.js +++ /dev/null @@ -1,17 +0,0 @@ -import { NATIVE } from '../helpers/constants'; - -QUnit.test('Object.isFrozen', assert => { - const { freeze, isFrozen } = Object; - assert.isFunction(isFrozen); - assert.arity(isFrozen, 1); - assert.name(isFrozen, 'isFrozen'); - assert.looksNative(isFrozen); - assert.nonEnumerable(Object, 'isFrozen'); - const primitives = [42, 'string', false, null, undefined]; - for (const value of primitives) { - assert.notThrows(() => isFrozen(value) || true, `accept ${ value }`); - assert.same(isFrozen(value), true, `returns true on ${ value }`); - } - assert.same(isFrozen({}), false); - if (NATIVE) assert.ok(isFrozen(freeze({}))); -}); diff --git a/tests/tests/es.object.is-sealed.js b/tests/tests/es.object.is-sealed.js deleted file mode 100644 index 009cab804c4e..000000000000 --- a/tests/tests/es.object.is-sealed.js +++ /dev/null @@ -1,17 +0,0 @@ -import { NATIVE } from '../helpers/constants'; - -QUnit.test('Object.isSealed', assert => { - const { seal, isSealed } = Object; - assert.isFunction(isSealed); - assert.arity(isSealed, 1); - assert.name(isSealed, 'isSealed'); - assert.looksNative(isSealed); - assert.nonEnumerable(Object, 'isSealed'); - const primitives = [42, 'string', false, null, undefined]; - for (const value of primitives) { - assert.notThrows(() => isSealed(value) || true, `accept ${ value }`); - assert.same(isSealed(value), true, `returns true on ${ value }`); - } - assert.same(isSealed({}), false); - if (NATIVE) assert.ok(isSealed(seal({}))); -}); diff --git a/tests/tests/es.object.is.js b/tests/tests/es.object.is.js deleted file mode 100644 index bdf2b017411c..000000000000 --- a/tests/tests/es.object.is.js +++ /dev/null @@ -1,12 +0,0 @@ -QUnit.test('Object.is', assert => { - const { is } = Object; - assert.isFunction(is); - assert.arity(is, 2); - assert.name(is, 'is'); - assert.looksNative(is); - assert.nonEnumerable(Object, 'is'); - assert.ok(is(1, 1), '1 is 1'); - assert.ok(is(NaN, NaN), '1 is 1'); - assert.ok(!is(0, -0), '0 isnt -0'); - assert.ok(!is({}, {}), '{} isnt {}'); -}); diff --git a/tests/tests/es.object.keys.js b/tests/tests/es.object.keys.js deleted file mode 100644 index a756de49a9ca..000000000000 --- a/tests/tests/es.object.keys.js +++ /dev/null @@ -1,28 +0,0 @@ -import { includes } from '../helpers/helpers'; - -QUnit.test('Object.keys', assert => { - const { keys } = Object; - assert.isFunction(keys); - assert.arity(keys, 1); - assert.name(keys, 'keys'); - assert.looksNative(keys); - assert.nonEnumerable(Object, 'keys'); - function F1() { - this.w = 1; - } - function F2() { - this.toString = 1; - } - F1.prototype.q = F2.prototype.q = 1; - assert.deepEqual(keys([1, 2, 3]), ['0', '1', '2']); - assert.deepEqual(keys(new F1()), ['w']); - assert.deepEqual(keys(new F2()), ['toString']); - assert.ok(!includes(keys(Array.prototype), 'push')); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => keys(value), `accept ${ typeof value }`); - } - assert.throws(() => keys(null), TypeError, 'throws on null'); - assert.throws(() => keys(undefined), TypeError, 'throws on undefined'); -}); - diff --git a/tests/tests/es.object.lookup-getter.js b/tests/tests/es.object.lookup-getter.js deleted file mode 100644 index f49451054102..000000000000 --- a/tests/tests/es.object.lookup-getter.js +++ /dev/null @@ -1,25 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -if (DESCRIPTORS) { - QUnit.test('Object#__lookupGetter__', assert => { - const { __lookupGetter__ } = Object.prototype; - const { create } = Object; - assert.isFunction(__lookupGetter__); - assert.arity(__lookupGetter__, 1); - assert.name(__lookupGetter__, '__lookupGetter__'); - assert.looksNative(__lookupGetter__); - assert.nonEnumerable(Object.prototype, '__lookupGetter__'); - assert.same({}.__lookupGetter__('key'), undefined, 'empty object'); - assert.same({ key: 42 }.__lookupGetter__('key'), undefined, 'data descriptor'); - const object = {}; - function setter() { /* empty */ } - object.__defineGetter__('key', setter); - assert.same(object.__lookupGetter__('key'), setter, 'own getter'); - assert.same(create(object).__lookupGetter__('key'), setter, 'proto getter'); - assert.same(create(object).__lookupGetter__('foo'), undefined, 'empty proto'); - if (STRICT) { - assert.throws(() => __lookupGetter__.call(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); - assert.throws(() => __lookupGetter__.call(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); - } - }); -} diff --git a/tests/tests/es.object.lookup-setter.js b/tests/tests/es.object.lookup-setter.js deleted file mode 100644 index 2728f198a988..000000000000 --- a/tests/tests/es.object.lookup-setter.js +++ /dev/null @@ -1,25 +0,0 @@ -import { DESCRIPTORS, STRICT } from '../helpers/constants'; - -if (DESCRIPTORS) { - QUnit.test('Object#__lookupSetter__', assert => { - const { __lookupSetter__ } = Object.prototype; - const { create } = Object; - assert.isFunction(__lookupSetter__); - assert.arity(__lookupSetter__, 1); - assert.name(__lookupSetter__, '__lookupSetter__'); - assert.looksNative(__lookupSetter__); - assert.nonEnumerable(Object.prototype, '__lookupSetter__'); - assert.same({}.__lookupSetter__('key'), undefined, 'empty object'); - assert.same({ key: 42 }.__lookupSetter__('key'), undefined, 'data descriptor'); - const object = {}; - function setter() { /* empty */ } - object.__defineSetter__('key', setter); - assert.same(object.__lookupSetter__('key'), setter, 'own getter'); - assert.same(create(object).__lookupSetter__('key'), setter, 'proto getter'); - assert.same(create(object).__lookupSetter__('foo'), undefined, 'empty proto'); - if (STRICT) { - assert.throws(() => __lookupSetter__.call(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); - assert.throws(() => __lookupSetter__.call(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); - } - }); -} diff --git a/tests/tests/es.object.prevent-extensions.js b/tests/tests/es.object.prevent-extensions.js deleted file mode 100644 index 2dac9a76cb42..000000000000 --- a/tests/tests/es.object.prevent-extensions.js +++ /dev/null @@ -1,24 +0,0 @@ -import { GLOBAL, NATIVE } from '../helpers/constants'; - -QUnit.test('Object.preventExtensions', assert => { - const { preventExtensions, keys, isExtensible, getOwnPropertyNames, getOwnPropertySymbols } = Object; - const { ownKeys } = GLOBAL.Reflect || {}; - assert.isFunction(preventExtensions); - assert.arity(preventExtensions, 1); - assert.name(preventExtensions, 'preventExtensions'); - assert.looksNative(preventExtensions); - assert.nonEnumerable(Object, 'preventExtensions'); - const data = [42, 'foo', false, null, undefined, {}]; - for (const value of data) { - assert.notThrows(() => preventExtensions(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); - assert.same(preventExtensions(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); - } - if (NATIVE) assert.ok(!isExtensible(preventExtensions({}))); - const results = []; - for (const key in preventExtensions({})) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(preventExtensions({})), []); - assert.arrayEqual(getOwnPropertyNames(preventExtensions({})), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(preventExtensions({})), []); - if (ownKeys) assert.arrayEqual(ownKeys(preventExtensions({})), []); -}); diff --git a/tests/tests/es.object.seal.js b/tests/tests/es.object.seal.js deleted file mode 100644 index fc36bd97b732..000000000000 --- a/tests/tests/es.object.seal.js +++ /dev/null @@ -1,24 +0,0 @@ -import { GLOBAL, NATIVE } from '../helpers/constants'; - -QUnit.test('Object.seal', assert => { - const { seal, isSealed, keys, getOwnPropertyNames, getOwnPropertySymbols } = Object; - const { ownKeys } = GLOBAL.Reflect || {}; - assert.isFunction(seal); - assert.arity(seal, 1); - assert.name(seal, 'seal'); - assert.looksNative(seal); - assert.nonEnumerable(Object, 'seal'); - const data = [42, 'foo', false, null, undefined, {}]; - for (const value of data) { - assert.notThrows(() => seal(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); - assert.same(seal(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); - } - if (NATIVE) assert.ok(isSealed(seal({}))); - const results = []; - for (const key in seal({})) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(seal({})), []); - assert.arrayEqual(getOwnPropertyNames(seal({})), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(seal({})), []); - if (ownKeys) assert.arrayEqual(ownKeys(seal({})), []); -}); diff --git a/tests/tests/es.object.set-prototype-of.js b/tests/tests/es.object.set-prototype-of.js deleted file mode 100644 index bb9fc81162ed..000000000000 --- a/tests/tests/es.object.set-prototype-of.js +++ /dev/null @@ -1,19 +0,0 @@ -import { PROTO } from '../helpers/constants'; - -if (PROTO) QUnit.test('Object.setPrototypeOf', assert => { - const { setPrototypeOf } = Object; - assert.isFunction(setPrototypeOf); - assert.arity(setPrototypeOf, 2); - assert.name(setPrototypeOf, 'setPrototypeOf'); - assert.looksNative(setPrototypeOf); - assert.nonEnumerable(Object, 'setPrototypeOf'); - assert.ok('apply' in setPrototypeOf({}, Function.prototype), 'Parent properties in target'); - assert.strictEqual(setPrototypeOf({ a: 2 }, { - b() { - return this.a ** 2; - }, - }).b(), 4, 'Child and parent properties in target'); - const object = {}; - assert.strictEqual(setPrototypeOf(object, { a: 1 }), object, 'setPrototypeOf return target'); - assert.ok(!('toString' in setPrototypeOf({}, null)), 'Can set null as prototype'); -}); diff --git a/tests/tests/es.object.to-string.js b/tests/tests/es.object.to-string.js deleted file mode 100644 index 79a288abee86..000000000000 --- a/tests/tests/es.object.to-string.js +++ /dev/null @@ -1,86 +0,0 @@ -import { GLOBAL, STRICT } from '../helpers/constants'; - -QUnit.test('Object#toString', assert => { - const { toString } = Object.prototype; - const Symbol = GLOBAL.Symbol || {}; - assert.arity(toString, 0); - assert.name(toString, 'toString'); - assert.looksNative(toString); - assert.nonEnumerable(Object.prototype, 'toString'); - if (STRICT) { - assert.strictEqual(toString.call(null), '[object Null]', 'null -> `Null`'); - assert.strictEqual(toString.call(undefined), '[object Undefined]', 'undefined -> `Undefined`'); - } - assert.strictEqual(toString.call(true), '[object Boolean]', 'bool -> `Boolean`'); - assert.strictEqual(toString.call('string'), '[object String]', 'string -> `String`'); - assert.strictEqual(toString.call(7), '[object Number]', 'number -> `Number`'); - assert.strictEqual(`${ {} }`, '[object Object]', '{} -> `Object`'); - assert.strictEqual(toString.call([]), '[object Array]', ' [] -> `Array`'); - assert.strictEqual(toString.call(() => { /* empty */ }), '[object Function]', 'function -> `Function`'); - assert.strictEqual(toString.call(/./), '[object RegExp]', 'regexp -> `RegExp`'); - assert.strictEqual(toString.call(new TypeError()), '[object Error]', 'new TypeError -> `Error`'); - assert.strictEqual(toString.call(function () { - return arguments; - }()), '[object Arguments]', 'arguments -> `Arguments`'); - const constructors = [ - 'Array', - 'RegExp', - 'Boolean', - 'String', - 'Number', - 'Error', - 'Int8Array', - 'Uint8Array', - 'Uint8ClampedArray', - 'Int16Array', - 'Uint16Array', - 'Int32Array', - 'Uint32Array', - 'Float32Array', - 'Float64Array', - 'ArrayBuffer', - ]; - for (const name of constructors) { - const Constructor = GLOBAL[name]; - if (Constructor) { - assert.strictEqual(toString.call(new Constructor(1)), `[object ${ name }]`, `new ${ name }(1) -> \`${ name }\``); - } - } - if (GLOBAL.DataView) { - assert.strictEqual(`${ new DataView(new ArrayBuffer(1)) }`, '[object DataView]', 'dataview -> `DataView`'); - } - if (GLOBAL.Set) { - assert.strictEqual(`${ new Set() }`, '[object Set]', 'set -> `Set`'); - } - if (GLOBAL.Map) { - assert.strictEqual(`${ new Map() }`, '[object Map]', 'map -> `Map`'); - } - if (GLOBAL.WeakSet) { - assert.strictEqual(`${ new WeakSet() }`, '[object WeakSet]', 'weakset -> `WeakSet`'); - } - if (GLOBAL.WeakMap) { - assert.strictEqual(`${ new WeakMap() }`, '[object WeakMap]', 'weakmap -> `WeakMap`'); - } - if (GLOBAL.Promise) { - assert.strictEqual(`${ new Promise((() => { /* empty */ })) }`, '[object Promise]', 'promise -> `Promise`'); - } - if (''[Symbol.iterator]) { - assert.strictEqual(`${ ''[Symbol.iterator]() }`, '[object String Iterator]', 'String Iterator -> `String Iterator`'); - } - if ([].entries) { - assert.strictEqual(`${ [].entries() }`, '[object Array Iterator]', 'Array Iterator -> `Array Iterator`'); - } - if (GLOBAL.Set && Set.entries) { - assert.strictEqual(`${ new Set().entries() }`, '[object Set Iterator]', 'Set Iterator -> `Set Iterator`'); - } - if (GLOBAL.Map && Map.entries) { - assert.strictEqual(`${ new Map().entries() }`, '[object Map Iterator]', 'Map Iterator -> `Map Iterator`'); - } - assert.strictEqual(`${ Math }`, '[object Math]', 'Math -> `Math`'); - if (GLOBAL.JSON) { - assert.strictEqual(`${ JSON }`, '[object JSON]', 'JSON -> `JSON`'); - } - function Class() { /* empty */ } - Class.prototype[Symbol.toStringTag] = 'Class'; - assert.strictEqual(`${ new Class() }`, '[object Class]', 'user class instance -> [Symbol.toStringTag]'); -}); diff --git a/tests/tests/es.parse-float.js b/tests/tests/es.parse-float.js deleted file mode 100644 index 4a20c604ceb7..000000000000 --- a/tests/tests/es.parse-float.js +++ /dev/null @@ -1,18 +0,0 @@ -import { WHITESPACES } from '../helpers/constants'; - -QUnit.test('parseFloat', assert => { - assert.isFunction(parseFloat); - assert.name(parseFloat, 'parseFloat'); - assert.arity(parseFloat, 1); - assert.looksNative(parseFloat); - assert.same(parseFloat('0'), 0); - assert.same(parseFloat(' 0'), 0); - assert.same(parseFloat('+0'), 0); - assert.same(parseFloat(' +0'), 0); - assert.same(parseFloat('-0'), -0); - assert.same(parseFloat(' -0'), -0); - assert.same(parseFloat(`${ WHITESPACES }+0`), 0); - assert.same(parseFloat(`${ WHITESPACES }-0`), -0); - assert.same(parseFloat(null), NaN); - assert.same(parseFloat(undefined), NaN); -}); diff --git a/tests/tests/es.parse-int.js b/tests/tests/es.parse-int.js deleted file mode 100644 index 22c879a54cf6..000000000000 --- a/tests/tests/es.parse-int.js +++ /dev/null @@ -1,37 +0,0 @@ -import { WHITESPACES } from '../helpers/constants'; - -/* eslint-disable radix */ -QUnit.test('parseInt', assert => { - assert.isFunction(parseInt); - assert.name(parseInt, 'parseInt'); - assert.arity(parseInt, 2); - assert.looksNative(parseInt); - for (let radix = 2; radix <= 36; ++radix) { - assert.same(parseInt('10', radix), radix, `radix ${ radix }`); - } - const strings = ['01', '08', '10', '42']; - for (const string of strings) { - assert.same(parseInt(string), parseInt(string, 10), `default radix is 10: ${ string }`); - } - assert.same(parseInt('0x16'), parseInt('0x16', 16), 'default radix is 16: 0x16'); - assert.same(parseInt(' 0x16'), parseInt('0x16', 16), 'ignores leading whitespace #1'); - assert.same(parseInt(' 42'), parseInt('42', 10), 'ignores leading whitespace #2'); - assert.same(parseInt(' 08'), parseInt('08', 10), 'ignores leading whitespace #3'); - assert.same(parseInt(`${ WHITESPACES }08`), parseInt('08', 10), 'ignores leading whitespace #4'); - assert.same(parseInt(`${ WHITESPACES }0x16`), parseInt('0x16', 16), 'ignores leading whitespace #5'); - const fakeZero = { - valueOf() { - return 0; - }, - }; - assert.same(parseInt('08', fakeZero), parseInt('08', 10), 'valueOf #1'); - assert.same(parseInt('0x16', fakeZero), parseInt('0x16', 16), 'valueOf #2'); - assert.same(parseInt('-0xF'), -15, 'signed hex #1'); - assert.same(parseInt('-0xF', 16), -15, 'signed hex #2'); - assert.same(parseInt('+0xF'), 15, 'signed hex #3'); - assert.same(parseInt('+0xF', 16), 15, 'signed hex #4'); - assert.same(parseInt('10', -4294967294), 2, 'radix uses ToUint32'); - assert.same(parseInt(null), NaN); - assert.same(parseInt(undefined), NaN); -}); - diff --git a/tests/tests/es.promise.all-settled.js b/tests/tests/es.promise.all-settled.js deleted file mode 100644 index 6628e03217c8..000000000000 --- a/tests/tests/es.promise.all-settled.js +++ /dev/null @@ -1,33 +0,0 @@ -QUnit.test('Promise.allSettled', assert => { - assert.isFunction(Promise.allSettled); - assert.arity(Promise.allSettled, 1); - assert.looksNative(Promise.allSettled); - assert.nonEnumerable(Promise, 'allSettled'); - assert.ok(Promise.allSettled([1, 2, 3]) instanceof Promise, 'returns a promise'); -}); - -QUnit.test('Promise.allSettled, resolved', assert => { - assert.expect(1); - const async = assert.async(); - Promise.allSettled([ - Promise.resolve(1), - Promise.reject(2), - Promise.resolve(3), - ]).then(it => { - assert.deepEqual(it, [ - { value: 1, status: 'fulfilled' }, - { reason: 2, status: 'rejected' }, - { value: 3, status: 'fulfilled' }, - ], 'resolved with a correct value'); - async(); - }); -}); - -QUnit.test('Promise.allSettled, rejected', assert => { - assert.expect(1); - const async = assert.async(); - Promise.allSettled().catch(() => { - assert.ok(true, 'rejected as expected'); - async(); - }); -}); diff --git a/tests/tests/es.promise.finally.js b/tests/tests/es.promise.finally.js deleted file mode 100644 index 0cb7bc600083..000000000000 --- a/tests/tests/es.promise.finally.js +++ /dev/null @@ -1,55 +0,0 @@ -QUnit.test('Promise#finally', assert => { - assert.isFunction(Promise.prototype.finally); - assert.arity(Promise.prototype.finally, 1); - assert.looksNative(Promise.prototype.finally); - assert.nonEnumerable(Promise.prototype, 'finally'); - assert.ok(Promise.resolve(42).finally(() => { /* empty */ }) instanceof Promise, 'returns a promise'); -}); - -QUnit.test('Promise#finally, resolved', assert => { - assert.expect(3); - const async = assert.async(); - let called = 0; - let argument = null; - Promise.resolve(42).finally(it => { - called++; - argument = it; - }).then(it => { - assert.same(it, 42, 'resolved with a correct value'); - assert.same(called, 1, 'onFinally function called one time'); - assert.same(argument, undefined, 'onFinally function called with a correct argument'); - async(); - }); -}); - -QUnit.test('Promise#finally, rejected', assert => { - assert.expect(2); - const async = assert.async(); - let called = 0; - let argument = null; - Promise.reject(42).finally(it => { - called++; - argument = it; - }).catch(() => { - assert.same(called, 1, 'onFinally function called one time'); - assert.same(argument, undefined, 'onFinally function called with a correct argument'); - async(); - }); -}); - -const promise = (() => { - try { - return Function('return (async function () { /* empty */ })()')(); - } catch { /* empty */ } -})(); - -if (promise && promise.constructor !== Promise) QUnit.test('Native Promise, patched', assert => { - assert.isFunction(promise.finally); - assert.arity(promise.finally, 1); - assert.looksNative(promise.finally); - assert.nonEnumerable(promise.constructor.prototype, 'finally'); - function empty() { /* empty */ } - assert.ok(promise.finally(empty) instanceof Promise, '`.finally` returns `Promise` instance #1'); - assert.ok(new promise.constructor(empty).finally(empty) instanceof Promise, '`.finally` returns `Promise` instance #2'); -}); - diff --git a/tests/tests/es.promise.js b/tests/tests/es.promise.js deleted file mode 100644 index 759ae57303b3..000000000000 --- a/tests/tests/es.promise.js +++ /dev/null @@ -1,483 +0,0 @@ -import { DESCRIPTORS, GLOBAL, NATIVE, PROTO, STRICT } from '../helpers/constants'; -import { createIterable } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; -const { setPrototypeOf, create } = Object; - -QUnit.test('Promise', assert => { - assert.isFunction(Promise); - assert.arity(Promise, 1); - assert.name(Promise, 'Promise'); - assert.looksNative(Promise); - assert.throws(() => { - Promise(); - }, 'throws w/o `new`'); - new Promise(function (resolve, reject) { - assert.isFunction(resolve, 'resolver is function'); - assert.isFunction(reject, 'rejector is function'); - if (STRICT) assert.same(this, undefined, 'correct executor context'); - }); -}); - -if (DESCRIPTORS) QUnit.test('Promise operations order', assert => { - let resolve, resolve2; - assert.expect(1); - const EXPECTED_ORDER = 'DEHAFGBC'; - const async = assert.async(); - let result = ''; - const promise1 = new Promise(r => { - resolve = r; - }); - resolve({ - then() { - result += 'A'; - throw Error(); - }, - }); - promise1.catch(() => { - result += 'B'; - }); - promise1.catch(() => { - result += 'C'; - assert.same(result, EXPECTED_ORDER); - async(); - }); - const promise2 = new Promise(r => { - resolve2 = r; - }); - resolve2(Object.defineProperty({}, 'then', { - get() { - result += 'D'; - throw Error(); - }, - })); - result += 'E'; - promise2.catch(() => { - result += 'F'; - }); - promise2.catch(() => { - result += 'G'; - }); - result += 'H'; - setTimeout(() => { - if (!~result.indexOf('C')) { - assert.same(result, EXPECTED_ORDER); - async(); - } - }, 1e3); -}); - -QUnit.test('Promise#then', assert => { - assert.isFunction(Promise.prototype.then); - if (NATIVE) assert.arity(Promise.prototype.then, 2); - assert.name(Promise.prototype.then, 'then'); - assert.looksNative(Promise.prototype.then); - assert.nonEnumerable(Promise.prototype, 'then'); - let promise = new Promise(resolve => { - resolve(42); - }); - let FakePromise1 = promise.constructor = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - const FakePromise2 = FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(promise.then(() => { /* empty */ }) instanceof FakePromise2, 'subclassing, @@species pattern'); - promise = new Promise(resolve => { - resolve(42); - }); - promise.constructor = FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(promise.then(() => { /* empty */ }) instanceof Promise, 'subclassing, incorrect `this` pattern'); - promise = new Promise(resolve => { - resolve(42); - }); - promise.constructor = FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise1[Symbol.species] = function () { /* empty */ }; - assert.throws(() => { - promise.then(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #1'); - FakePromise1[Symbol.species] = function (executor) { - executor(null, () => { /* empty */ }); - }; - assert.throws(() => { - promise.then(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #2'); - FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, null); - }; - assert.throws(() => { - promise.then(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #3'); -}); - -QUnit.test('Promise#catch', assert => { - assert.isFunction(Promise.prototype.catch); - if (NATIVE) assert.arity(Promise.prototype.catch, 1); - if (NATIVE) assert.name(Promise.prototype.catch, 'catch'); - assert.looksNative(Promise.prototype.catch); - assert.nonEnumerable(Promise.prototype, 'catch'); - let promise = new Promise(resolve => { - resolve(42); - }); - let FakePromise1 = promise.constructor = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - const FakePromise2 = FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(promise.catch(() => { /* empty */ }) instanceof FakePromise2, 'subclassing, @@species pattern'); - promise = new Promise(resolve => { - resolve(42); - }); - promise.constructor = FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(promise.catch(() => { /* empty */ }) instanceof Promise, 'subclassing, incorrect `this` pattern'); - promise = new Promise(resolve => { - resolve(42); - }); - promise.constructor = FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise1[Symbol.species] = function () { /* empty */ }; - assert.throws(() => { - promise.catch(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #1'); - FakePromise1[Symbol.species] = function (executor) { - executor(null, () => { /* empty */ }); - }; - assert.throws(() => { - promise.catch(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #2'); - FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, null); - }; - assert.throws(() => { - promise.catch(() => { /* empty */ }); - }, 'NewPromiseCapability validations, #3'); - assert.same(Promise.prototype.catch.call({ - then(x, y) { - return y; - }, - }, 42), 42, 'calling `.then`'); -}); - -QUnit.test('Promise#@@toStringTag', assert => { - assert.ok(Promise.prototype[Symbol.toStringTag] === 'Promise', 'Promise::@@toStringTag is `Promise`'); - assert.strictEqual(String(new Promise(() => { /* empty */ })), '[object Promise]', 'correct stringification'); -}); - -QUnit.test('Promise.all', assert => { - let FakePromise1, FakePromise2; - const { all, resolve } = Promise; - assert.isFunction(all); - assert.arity(all, 1); - assert.name(all, 'all'); - assert.looksNative(all); - assert.nonEnumerable(Promise, 'all'); - const iterable = createIterable([1, 2, 3]); - Promise.all(iterable).catch(() => { /* empty */ }); - assert.ok(iterable.received, 'works with iterables: iterator received'); - assert.ok(iterable.called, 'works with iterables: next called'); - const array = []; - let done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return [][Symbol.iterator].call(this); - }; - Promise.all(array); - assert.ok(done); - assert.throws(() => { - all.call(null, []).catch(() => { /* empty */ }); - }, TypeError, 'throws without context'); - done = false; - try { - Promise.resolve = function () { - throw new Error(); - }; - Promise.all(createIterable([1, 2, 3], { - return() { - done = true; - }, - })).catch(() => { /* empty */ }); - } catch (error) { /* empty */ } - Promise.resolve = resolve; - assert.ok(done, 'iteration closing'); - FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise2 = FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise1.resolve = FakePromise2.resolve = Promise.resolve.bind(Promise); - assert.ok(all.call(FakePromise1, [1, 2, 3]) instanceof FakePromise1, 'subclassing, `this` pattern'); - FakePromise1 = function () { /* empty */ }; - FakePromise2 = function (executor) { - executor(null, () => { /* empty */ }); - }; - const FakePromise3 = function (executor) { - executor(() => { /* empty */ }, null); - }; - FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = Promise.resolve.bind(Promise); - assert.throws(() => { - all.call(FakePromise1, [1, 2, 3]); - }, 'NewPromiseCapability validations, #1'); - assert.throws(() => { - all.call(FakePromise2, [1, 2, 3]); - }, 'NewPromiseCapability validations, #2'); - assert.throws(() => { - all.call(FakePromise3, [1, 2, 3]); - }, 'NewPromiseCapability validations, #3'); -}); - -QUnit.test('Promise.race', assert => { - let FakePromise1, FakePromise2; - const { race, resolve } = Promise; - assert.isFunction(race); - assert.arity(race, 1); - assert.name(race, 'race'); - assert.looksNative(race); - assert.nonEnumerable(Promise, 'race'); - const iterable = createIterable([1, 2, 3]); - Promise.race(iterable).catch(() => { /* empty */ }); - assert.ok(iterable.received, 'works with iterables: iterator received'); - assert.ok(iterable.called, 'works with iterables: next called'); - const array = []; - let done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return [][Symbol.iterator].call(this); - }; - Promise.race(array); - assert.ok(done); - assert.throws(() => { - race.call(null, []).catch(() => { /* empty */ }); - }, TypeError, 'throws without context'); - done = false; - try { - Promise.resolve = function () { - throw new Error(); - }; - Promise.race(createIterable([1, 2, 3], { - return() { - done = true; - }, - })).catch(() => { /* empty */ }); - } catch (error) { /* empty */ } - Promise.resolve = resolve; - assert.ok(done, 'iteration closing'); - FakePromise1 = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise2 = FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - FakePromise1.resolve = FakePromise2.resolve = Promise.resolve.bind(Promise); - assert.ok(race.call(FakePromise1, [1, 2, 3]) instanceof FakePromise1, 'subclassing, `this` pattern'); - FakePromise1 = function () { /* empty */ }; - FakePromise2 = function (executor) { - executor(null, () => { /* empty */ }); - }; - const FakePromise3 = function (executor) { - executor(() => { /* empty */ }, null); - }; - FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = Promise.resolve.bind(Promise); - assert.throws(() => { - race.call(FakePromise1, [1, 2, 3]); - }, 'NewPromiseCapability validations, #1'); - assert.throws(() => { - race.call(FakePromise2, [1, 2, 3]); - }, 'NewPromiseCapability validations, #2'); - assert.throws(() => { - race.call(FakePromise3, [1, 2, 3]); - }, 'NewPromiseCapability validations, #3'); -}); - -QUnit.test('Promise.resolve', assert => { - const { resolve } = Promise; - assert.isFunction(resolve); - if (NATIVE) assert.arity(resolve, 1); - assert.name(resolve, 'resolve'); - assert.looksNative(resolve); - assert.nonEnumerable(Promise, 'resolve'); - assert.throws(() => { - resolve.call(null, 1).catch(() => { /* empty */ }); - }, TypeError, 'throws without context'); - function FakePromise1(executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - } - FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(resolve.call(FakePromise1, 42) instanceof FakePromise1, 'subclassing, `this` pattern'); - assert.throws(() => { - resolve.call(() => { /* empty */ }, 42); - }, 'NewPromiseCapability validations, #1'); - assert.throws(() => { - resolve.call(executor => { - executor(null, () => { /* empty */ }); - }, 42); - }, 'NewPromiseCapability validations, #2'); - assert.throws(() => { - resolve.call(executor => { - executor(() => { /* empty */ }, null); - }, 42); - }, 'NewPromiseCapability validations, #3'); -}); - -QUnit.test('Promise.reject', assert => { - const { reject } = Promise; - assert.isFunction(reject); - if (NATIVE) assert.arity(reject, 1); - assert.name(reject, 'reject'); - assert.looksNative(reject); - assert.nonEnumerable(Promise, 'reject'); - assert.throws(() => { - reject.call(null, 1).catch(() => { /* empty */ }); - }, TypeError, 'throws without context'); - function FakePromise1(executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - } - FakePromise1[Symbol.species] = function (executor) { - executor(() => { /* empty */ }, () => { /* empty */ }); - }; - assert.ok(reject.call(FakePromise1, 42) instanceof FakePromise1, 'subclassing, `this` pattern'); - assert.throws(() => { - reject.call(() => { /* empty */ }, 42); - }, 'NewPromiseCapability validations, #1'); - assert.throws(() => { - reject.call(executor => { - executor(null, () => { /* empty */ }); - }, 42); - }, 'NewPromiseCapability validations, #2'); - assert.throws(() => { - reject.call(executor => { - executor(() => { /* empty */ }, null); - }, 42); - }, 'NewPromiseCapability validations, #3'); -}); - -if (PROTO) QUnit.test('Promise subclassing', assert => { - function SubPromise(executor) { - const self = new Promise(executor); - setPrototypeOf(self, SubPromise.prototype); - self.mine = 'subclass'; - return self; - } - setPrototypeOf(SubPromise, Promise); - SubPromise.prototype = create(Promise.prototype); - SubPromise.prototype.constructor = SubPromise; - let promise1 = SubPromise.resolve(5); - assert.strictEqual(promise1.mine, 'subclass'); - promise1 = promise1.then(it => { - assert.strictEqual(it, 5); - }); - assert.strictEqual(promise1.mine, 'subclass'); - let promise2 = new SubPromise(resolve => { - resolve(6); - }); - assert.strictEqual(promise2.mine, 'subclass'); - promise2 = promise2.then(it => { - assert.strictEqual(it, 6); - }); - assert.strictEqual(promise2.mine, 'subclass'); - const promise3 = SubPromise.all([promise1, promise2]); - assert.strictEqual(promise3.mine, 'subclass'); - assert.ok(promise3 instanceof Promise); - assert.ok(promise3 instanceof SubPromise); - promise3.then(assert.async(), it => { - assert.ok(it, false); - }); -}); - -// qunit@2.5 strange bug -QUnit.skip('Unhandled rejection tracking', assert => { - let done = false; - const resume = assert.async(); - if (GLOBAL.process) { - assert.expect(3); - function onunhandledrejection(reason, promise) { - process.removeListener('unhandledRejection', onunhandledrejection); - assert.same(promise, $promise, 'unhandledRejection, promise'); - assert.same(reason, 42, 'unhandledRejection, reason'); - $promise.catch(() => { - // empty - }); - } - function onrejectionhandled(promise) { - process.removeListener('rejectionHandled', onrejectionhandled); - assert.same(promise, $promise, 'rejectionHandled, promise'); - done || resume(); - done = true; - } - process.on('unhandledRejection', onunhandledrejection); - process.on('rejectionHandled', onrejectionhandled); - } else { - if (GLOBAL.addEventListener) { - assert.expect(8); - function onunhandledrejection(it) { - assert.same(it.promise, $promise, 'addEventListener(unhandledrejection), promise'); - assert.same(it.reason, 42, 'addEventListener(unhandledrejection), reason'); - GLOBAL.removeEventListener('unhandledrejection', onunhandledrejection); - } - GLOBAL.addEventListener('rejectionhandled', onunhandledrejection); - function onrejectionhandled(it) { - assert.same(it.promise, $promise, 'addEventListener(rejectionhandled), promise'); - assert.same(it.reason, 42, 'addEventListener(rejectionhandled), reason'); - GLOBAL.removeEventListener('rejectionhandled', onrejectionhandled); - } - GLOBAL.addEventListener('rejectionhandled', onrejectionhandled); - } else assert.expect(4); - GLOBAL.onunhandledrejection = function (it) { - assert.same(it.promise, $promise, 'onunhandledrejection, promise'); - assert.same(it.reason, 42, 'onunhandledrejection, reason'); - setTimeout(() => { - $promise.catch(() => { - // empty - }); - }, 1); - GLOBAL.onunhandledrejection = null; - }; - GLOBAL.onrejectionhandled = function (it) { - assert.same(it.promise, $promise, 'onrejectionhandled, promise'); - assert.same(it.reason, 42, 'onrejectionhandled, reason'); - GLOBAL.onrejectionhandled = null; - done || resume(); - done = true; - }; - } - Promise.reject(43).catch(() => { - // empty - }); - const $promise = Promise.reject(42); - setTimeout(() => { - done || resume(); - done = true; - }, 3e3); -}); - -const promise = (() => { - try { - return Function('return (async function () { /* empty */ })()')(); - } catch { /* empty */ } -})(); - -if (promise && promise.constructor !== Promise) QUnit.test('Native Promise, patched', assert => { - assert.isFunction(promise.then); - assert.arity(promise.then, 2); - assert.looksNative(promise.then); - assert.nonEnumerable(promise.constructor.prototype, 'then'); - function empty() { /* empty */ } - assert.ok(promise.then(empty) instanceof Promise, '`.then` returns `Promise` instance #1'); - assert.ok(new promise.constructor(empty).then(empty) instanceof Promise, '`.then` returns `Promise` instance #2'); - assert.ok(promise.catch(empty) instanceof Promise, '`.catch` returns `Promise` instance #1'); - assert.ok(new promise.constructor(empty).catch(empty) instanceof Promise, '`.catch` returns `Promise` instance #2'); - assert.ok(promise.finally(empty) instanceof Promise, '`.finally` returns `Promise` instance #1'); - assert.ok(new promise.constructor(empty).finally(empty) instanceof Promise, '`.finally` returns `Promise` instance #2'); -}); diff --git a/tests/tests/es.reflect.apply.js b/tests/tests/es.reflect.apply.js deleted file mode 100644 index 59a969ab4c2f..000000000000 --- a/tests/tests/es.reflect.apply.js +++ /dev/null @@ -1,17 +0,0 @@ -QUnit.test('Reflect.apply', assert => { - const { apply } = Reflect; - assert.isFunction(apply); - assert.arity(apply, 3); - assert.name(apply, 'apply'); - assert.looksNative(apply); - assert.nonEnumerable(Reflect, 'apply'); - assert.strictEqual(apply(Array.prototype.push, [1, 2], [3, 4, 5]), 5); - function f(a, b, c) { - return a + b + c; - } - f.apply = 42; - assert.strictEqual(apply(f, null, ['foo', 'bar', 'baz']), 'foobarbaz', 'works with redefined apply'); - assert.throws(() => apply(42, null, []), TypeError, 'throws on primitive'); - assert.throws(() => apply(() => { /* empty */ }, null), TypeError, 'throws without third argument'); - assert.throws(() => apply(() => { /* empty */ }, null, '123'), TypeError, 'throws on primitive as third argument'); -}); diff --git a/tests/tests/es.reflect.construct.js b/tests/tests/es.reflect.construct.js deleted file mode 100644 index 2885b6519510..000000000000 --- a/tests/tests/es.reflect.construct.js +++ /dev/null @@ -1,27 +0,0 @@ -QUnit.test('Reflect.construct', assert => { - const { construct } = Reflect; - const { getPrototypeOf } = Object; - assert.isFunction(construct); - assert.arity(construct, 2); - assert.name(construct, 'construct'); - assert.looksNative(construct); - assert.nonEnumerable(Reflect, 'construct'); - function A(a, b, c) { - this.qux = a + b + c; - } - assert.strictEqual(construct(A, ['foo', 'bar', 'baz']).qux, 'foobarbaz', 'basic'); - A.apply = 42; - assert.strictEqual(construct(A, ['foo', 'bar', 'baz']).qux, 'foobarbaz', 'works with redefined apply'); - const instance = construct(function () { - this.x = 42; - }, [], Array); - assert.strictEqual(instance.x, 42, 'constructor with newTarget'); - assert.ok(instance instanceof Array, 'prototype with newTarget'); - assert.throws(() => construct(42, []), TypeError, 'throws on primitive'); - function B() { /* empty */ } - B.prototype = 42; - assert.notThrows(() => getPrototypeOf(construct(B, [])) === Object.prototype); - assert.notThrows(() => typeof construct(Date, []).getTime() == 'number', 'works with native constructors with 2 arguments'); - assert.throws(() => construct(() => { /* empty */ }), 'throws when the second argument is not an object'); -}); - diff --git a/tests/tests/es.reflect.define-property.js b/tests/tests/es.reflect.define-property.js deleted file mode 100644 index cfad2ff2dac5..000000000000 --- a/tests/tests/es.reflect.define-property.js +++ /dev/null @@ -1,40 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Reflect.defineProperty', assert => { - const { defineProperty } = Reflect; - const { getOwnPropertyDescriptor, create } = Object; - assert.isFunction(defineProperty); - assert.arity(defineProperty, 3); - assert.name(defineProperty, 'defineProperty'); - assert.looksNative(defineProperty); - assert.nonEnumerable(Reflect, 'defineProperty'); - let object = {}; - assert.strictEqual(defineProperty(object, 'foo', { value: 123 }), true); - assert.strictEqual(object.foo, 123); - if (DESCRIPTORS) { - object = {}; - defineProperty(object, 'foo', { - value: 123, - enumerable: true, - }); - assert.deepEqual(getOwnPropertyDescriptor(object, 'foo'), { - value: 123, - enumerable: true, - configurable: false, - writable: false, - }); - assert.strictEqual(defineProperty(object, 'foo', { - value: 42, - }), false); - } - assert.throws(() => defineProperty(42, 'foo', { - value: 42, - }), TypeError, 'throws on primitive'); - assert.throws(() => defineProperty(42, 1, {})); - assert.throws(() => defineProperty({}, create(null), {})); - assert.throws(() => defineProperty({}, 1, 1)); -}); - -QUnit.test('Reflect.defineProperty.sham flag', assert => { - assert.same(Reflect.defineProperty.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/tests/es.reflect.delete-property.js b/tests/tests/es.reflect.delete-property.js deleted file mode 100644 index 363428e35c6c..000000000000 --- a/tests/tests/es.reflect.delete-property.js +++ /dev/null @@ -1,20 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Reflect.deleteProperty', assert => { - const { deleteProperty } = Reflect; - const { defineProperty, keys } = Object; - assert.isFunction(deleteProperty); - assert.arity(deleteProperty, 2); - assert.name(deleteProperty, 'deleteProperty'); - assert.looksNative(deleteProperty); - assert.nonEnumerable(Reflect, 'deleteProperty'); - const object = { bar: 456 }; - assert.strictEqual(deleteProperty(object, 'bar'), true); - assert.ok(keys(object).length === 0); - if (DESCRIPTORS) { - assert.strictEqual(deleteProperty(defineProperty({}, 'foo', { - value: 42, - }), 'foo'), false); - } - assert.throws(() => deleteProperty(42, 'foo'), TypeError, 'throws on primitive'); -}); diff --git a/tests/tests/es.reflect.get-own-property-descriptor.js b/tests/tests/es.reflect.get-own-property-descriptor.js deleted file mode 100644 index e420e6ded64c..000000000000 --- a/tests/tests/es.reflect.get-own-property-descriptor.js +++ /dev/null @@ -1,18 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Reflect.getOwnPropertyDescriptor', assert => { - const { getOwnPropertyDescriptor } = Reflect; - assert.isFunction(getOwnPropertyDescriptor); - assert.arity(getOwnPropertyDescriptor, 2); - assert.name(getOwnPropertyDescriptor, 'getOwnPropertyDescriptor'); - assert.looksNative(getOwnPropertyDescriptor); - assert.nonEnumerable(Reflect, 'getOwnPropertyDescriptor'); - const object = { baz: 789 }; - const descriptor = getOwnPropertyDescriptor(object, 'baz'); - assert.strictEqual(descriptor.value, 789); - assert.throws(() => getOwnPropertyDescriptor(42, 'constructor'), TypeError, 'throws on primitive'); -}); - -QUnit.test('Reflect.getOwnPropertyDescriptor.sham flag', assert => { - assert.same(Reflect.getOwnPropertyDescriptor.sham, DESCRIPTORS ? undefined : true); -}); diff --git a/tests/tests/es.reflect.get-prototype-of.js b/tests/tests/es.reflect.get-prototype-of.js deleted file mode 100644 index 94222399ce66..000000000000 --- a/tests/tests/es.reflect.get-prototype-of.js +++ /dev/null @@ -1,16 +0,0 @@ -import { CORRECT_PROTOTYPE_GETTER } from '../helpers/constants'; - -QUnit.test('Reflect.getPrototypeOf', assert => { - const { getPrototypeOf } = Reflect; - assert.isFunction(getPrototypeOf); - assert.arity(getPrototypeOf, 1); - assert.name(getPrototypeOf, 'getPrototypeOf'); - assert.looksNative(getPrototypeOf); - assert.nonEnumerable(Reflect, 'getPrototypeOf'); - assert.strictEqual(getPrototypeOf([]), Array.prototype); - assert.throws(() => getPrototypeOf(42), TypeError, 'throws on primitive'); -}); - -QUnit.test('Reflect.getPrototypeOf.sham flag', assert => { - assert.same(Reflect.getPrototypeOf.sham, CORRECT_PROTOTYPE_GETTER ? undefined : true); -}); diff --git a/tests/tests/es.reflect.get.js b/tests/tests/es.reflect.get.js deleted file mode 100644 index 0684eac2da13..000000000000 --- a/tests/tests/es.reflect.get.js +++ /dev/null @@ -1,36 +0,0 @@ -import { DESCRIPTORS, NATIVE } from '../helpers/constants'; - -QUnit.test('Reflect.get', assert => { - const { defineProperty, create } = Object; - const { get } = Reflect; - assert.isFunction(get); - if (NATIVE) assert.arity(get, 2); - assert.name(get, 'get'); - assert.looksNative(get); - assert.nonEnumerable(Reflect, 'get'); - assert.strictEqual(get({ qux: 987 }, 'qux'), 987); - if (DESCRIPTORS) { - const target = create(defineProperty({ z: 3 }, 'w', { - get() { - return this; - }, - }), { - x: { - value: 1, - }, - y: { - get() { - return this; - }, - }, - }); - const receiver = {}; - assert.strictEqual(get(target, 'x', receiver), 1, 'get x'); - assert.strictEqual(get(target, 'y', receiver), receiver, 'get y'); - assert.strictEqual(get(target, 'z', receiver), 3, 'get z'); - assert.strictEqual(get(target, 'w', receiver), receiver, 'get w'); - assert.strictEqual(get(target, 'u', receiver), undefined, 'get u'); - } - assert.throws(() => get(42, 'constructor'), TypeError, 'throws on primitive'); -}); - diff --git a/tests/tests/es.reflect.has.js b/tests/tests/es.reflect.has.js deleted file mode 100644 index 947846eb30ae..000000000000 --- a/tests/tests/es.reflect.has.js +++ /dev/null @@ -1,13 +0,0 @@ -QUnit.test('Reflect.has', assert => { - const { has } = Reflect; - assert.isFunction(has); - assert.arity(has, 2); - assert.name(has, 'has'); - assert.looksNative(has); - assert.nonEnumerable(Reflect, 'has'); - const object = { qux: 987 }; - assert.strictEqual(has(object, 'qux'), true); - assert.strictEqual(has(object, 'qwe'), false); - assert.strictEqual(has(object, 'toString'), true); - assert.throws(() => has(42, 'constructor'), TypeError, 'throws on primitive'); -}); diff --git a/tests/tests/es.reflect.is-extensible.js b/tests/tests/es.reflect.is-extensible.js deleted file mode 100644 index ea13780b28f1..000000000000 --- a/tests/tests/es.reflect.is-extensible.js +++ /dev/null @@ -1,17 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Reflect.isExtensible', assert => { - const { isExtensible } = Reflect; - const { preventExtensions } = Object; - assert.isFunction(isExtensible); - assert.arity(isExtensible, 1); - assert.name(isExtensible, 'isExtensible'); - assert.looksNative(isExtensible); - assert.nonEnumerable(Reflect, 'isExtensible'); - assert.ok(isExtensible({})); - if (DESCRIPTORS) { - assert.ok(!isExtensible(preventExtensions({}))); - } - assert.throws(() => isExtensible(42), TypeError, 'throws on primitive'); -}); - diff --git a/tests/tests/es.reflect.own-keys.js b/tests/tests/es.reflect.own-keys.js deleted file mode 100644 index 88912c7cfacf..000000000000 --- a/tests/tests/es.reflect.own-keys.js +++ /dev/null @@ -1,25 +0,0 @@ -import { includes } from '../helpers/helpers'; - -QUnit.test('Reflect.ownKeys', assert => { - const { ownKeys } = Reflect; - const { defineProperty, create } = Object; - const symbol = Symbol('c'); - assert.isFunction(ownKeys); - assert.arity(ownKeys, 1); - assert.name(ownKeys, 'ownKeys'); - assert.looksNative(ownKeys); - assert.nonEnumerable(Reflect, 'ownKeys'); - const object = { a: 1 }; - defineProperty(object, 'b', { - value: 2, - }); - object[symbol] = 3; - let keys = ownKeys(object); - assert.strictEqual(keys.length, 3, 'ownKeys return all own keys'); - assert.ok(includes(keys, 'a'), 'ownKeys return all own keys: simple'); - assert.ok(includes(keys, 'b'), 'ownKeys return all own keys: hidden'); - assert.strictEqual(object[keys[2]], 3, 'ownKeys return all own keys: symbol'); - keys = ownKeys(create(object)); - assert.strictEqual(keys.length, 0, 'ownKeys return only own keys'); - assert.throws(() => ownKeys(42), TypeError, 'throws on primitive'); -}); diff --git a/tests/tests/es.reflect.prevent-extensions.js b/tests/tests/es.reflect.prevent-extensions.js deleted file mode 100644 index 24058780955e..000000000000 --- a/tests/tests/es.reflect.prevent-extensions.js +++ /dev/null @@ -1,21 +0,0 @@ -import { DESCRIPTORS, FREEZING } from '../helpers/constants'; - -QUnit.test('Reflect.preventExtensions', assert => { - const { preventExtensions } = Reflect; - const { isExtensible } = Object; - assert.isFunction(preventExtensions); - assert.arity(preventExtensions, 1); - assert.name(preventExtensions, 'preventExtensions'); - assert.looksNative(preventExtensions); - assert.nonEnumerable(Reflect, 'preventExtensions'); - const object = {}; - assert.ok(preventExtensions(object), true); - if (DESCRIPTORS) { - assert.ok(!isExtensible(object)); - } - assert.throws(() => preventExtensions(42), TypeError, 'throws on primitive'); -}); - -QUnit.test('Reflect.preventExtensions.sham flag', assert => { - assert.same(Reflect.preventExtensions.sham, FREEZING ? undefined : true); -}); diff --git a/tests/tests/es.reflect.set-prototype-of.js b/tests/tests/es.reflect.set-prototype-of.js deleted file mode 100644 index f3ce5ed3c3a9..000000000000 --- a/tests/tests/es.reflect.set-prototype-of.js +++ /dev/null @@ -1,17 +0,0 @@ -import { NATIVE, PROTO } from '../helpers/constants'; - -if (PROTO) QUnit.test('Reflect.setPrototypeOf', assert => { - const { setPrototypeOf } = Reflect; - assert.isFunction(setPrototypeOf); - if (NATIVE) assert.arity(setPrototypeOf, 2); - assert.name(setPrototypeOf, 'setPrototypeOf'); - assert.looksNative(setPrototypeOf); - assert.nonEnumerable(Reflect, 'setPrototypeOf'); - let object = {}; - assert.ok(setPrototypeOf(object, Array.prototype), true); - assert.ok(object instanceof Array); - assert.throws(() => setPrototypeOf({}, 42), TypeError); - assert.throws(() => setPrototypeOf(42, {}), TypeError, 'throws on primitive'); - object = {}; - assert.ok(setPrototypeOf(object, object) === false, 'false on recursive __proto__'); -}); diff --git a/tests/tests/es.reflect.set.js b/tests/tests/es.reflect.set.js deleted file mode 100644 index 6d3ec6cd2c8c..000000000000 --- a/tests/tests/es.reflect.set.js +++ /dev/null @@ -1,85 +0,0 @@ -import { DESCRIPTORS, NATIVE } from '../helpers/constants'; - -QUnit.test('Reflect.set', assert => { - const { set } = Reflect; - const { defineProperty, getOwnPropertyDescriptor, create, getPrototypeOf } = Object; - assert.isFunction(set); - if (NATIVE) assert.arity(set, 3); - assert.name(set, 'set'); - assert.looksNative(set); - assert.nonEnumerable(Reflect, 'set'); - const object = {}; - assert.ok(set(object, 'quux', 654), true); - assert.strictEqual(object.quux, 654); - let target = {}; - const receiver = {}; - set(target, 'foo', 1, receiver); - assert.strictEqual(target.foo, undefined, 'target.foo === undefined'); - assert.strictEqual(receiver.foo, 1, 'receiver.foo === 1'); - if (DESCRIPTORS) { - defineProperty(receiver, 'bar', { - value: 0, - writable: true, - enumerable: false, - configurable: true, - }); - set(target, 'bar', 1, receiver); - assert.strictEqual(receiver.bar, 1, 'receiver.bar === 1'); - assert.strictEqual(getOwnPropertyDescriptor(receiver, 'bar').enumerable, false, 'enumerability not overridden'); - let out = null; - target = create(defineProperty({ z: 3 }, 'w', { - set() { - out = this; - }, - }), { - x: { - value: 1, - writable: true, - configurable: true, - }, - y: { - set() { - out = this; - }, - }, - c: { - value: 1, - writable: false, - configurable: false, - }, - }); - assert.strictEqual(set(target, 'x', 2, target), true, 'set x'); - assert.strictEqual(target.x, 2, 'set x'); - out = null; - assert.strictEqual(set(target, 'y', 2, target), true, 'set y'); - assert.strictEqual(out, target, 'set y'); - assert.strictEqual(set(target, 'z', 4, target), true); - assert.strictEqual(target.z, 4, 'set z'); - out = null; - assert.strictEqual(set(target, 'w', 1, target), true, 'set w'); - assert.strictEqual(out, target, 'set w'); - assert.strictEqual(set(target, 'u', 0, target), true, 'set u'); - assert.strictEqual(target.u, 0, 'set u'); - assert.strictEqual(set(target, 'c', 2, target), false, 'set c'); - assert.strictEqual(target.c, 1, 'set c'); - - // https://github.com/zloirock/core-js/issues/392 - let o = defineProperty({}, 'test', { - writable: false, - configurable: true, - }); - assert.strictEqual(set(getPrototypeOf(o), 'test', 1, o), false); - - // https://github.com/zloirock/core-js/issues/393 - o = defineProperty({}, 'test', { - get() { /* empty */ }, - }); - assert.notThrows(() => !set(getPrototypeOf(o), 'test', 1, o)); - o = defineProperty({}, 'test', { - // eslint-disable-next-line no-unused-vars - set(v) { /* empty */ }, - }); - assert.notThrows(() => !set(getPrototypeOf(o), 'test', 1, o)); - } - assert.throws(() => set(42, 'q', 42), TypeError, 'throws on primitive'); -}); diff --git a/tests/tests/es.regexp.constructor.js b/tests/tests/es.regexp.constructor.js deleted file mode 100644 index bd91f5069cc4..000000000000 --- a/tests/tests/es.regexp.constructor.js +++ /dev/null @@ -1,44 +0,0 @@ -import { DESCRIPTORS, GLOBAL } from '../helpers/constants'; -import { nativeSubclass } from '../helpers/helpers'; - -if (DESCRIPTORS) { - QUnit.test('RegExp constructor', assert => { - const Symbol = GLOBAL.Symbol || {}; - assert.isFunction(RegExp); - assert.arity(RegExp, 2); - assert.name(RegExp, 'RegExp'); - assert.looksNative(RegExp); - assert.ok({}.toString.call(RegExp()).slice(8, -1), 'RegExp'); - assert.ok({}.toString.call(new RegExp()).slice(8, -1), 'RegExp'); - const regexp = /a/g; - assert.notStrictEqual(regexp, new RegExp(regexp), 'new RegExp(regexp) isnt regexp'); - assert.strictEqual(regexp, RegExp(regexp), 'RegExp(regexp) is regexp'); - regexp[Symbol.match] = false; - assert.notStrictEqual(regexp, RegExp(regexp), 'RegExp(regexp) isnt regexp, changed Symbol.match'); - const object = {}; - assert.notStrictEqual(object, RegExp(object), 'RegExp(O) isnt O'); - object[Symbol.match] = true; - object.constructor = RegExp; - assert.strictEqual(object, RegExp(object), 'RegExp(O) is O, changed Symbol.match'); - assert.strictEqual(String(regexp), '/a/g', 'b is /a/g'); - assert.strictEqual(String(new RegExp(/a/g, 'mi')), '/a/im', 'Allows a regex with flags'); - assert.ok(new RegExp(/a/g, 'im') instanceof RegExp, 'Works with instanceof'); - assert.strictEqual(new RegExp(/a/g, 'im').constructor, RegExp, 'Has the right constructor'); - /(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)/.exec('abcdefghijklmnopq'); - let result = true; - const characters = 'bcdefghij'; - for (let i = 0, { length } = characters; i < length; ++i) { - const chr = characters[i]; - if (RegExp[`$${ i + 1 }`] !== chr) { - result = false; - } - } - assert.ok(result, 'Updates RegExp globals'); - if (nativeSubclass) { - const Subclass = nativeSubclass(RegExp); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof RegExp, 'correct subclassing with native classes #2'); - assert.ok(new Subclass('^abc$').test('abc'), 'correct subclassing with native classes #3'); - } - }); -} diff --git a/tests/tests/es.regexp.exec.js b/tests/tests/es.regexp.exec.js deleted file mode 100644 index fd9222a01373..000000000000 --- a/tests/tests/es.regexp.exec.js +++ /dev/null @@ -1,28 +0,0 @@ -QUnit.test('RegExp#exec lastIndex updating', assert => { - let re = /b/; - assert.strictEqual(re.lastIndex, 0, '.lastIndex starts at 0 for non-global regexps'); - re.exec('abc'); - assert.strictEqual(re.lastIndex, 0, '.lastIndex isn\'t updated for non-global regexps'); - - re = /b/g; - assert.strictEqual(re.lastIndex, 0, '.lastIndex starts at 0 for global regexps'); - re.exec('abc'); - assert.strictEqual(re.lastIndex, 2, '.lastIndex is updated for global regexps'); - - re = /b*/; - re.exec('a'); - assert.strictEqual(re.lastIndex, 0, '.lastIndex isn\'t updated for non-global regexps if the match is empty'); - - re = /b*/g; - re.exec('a'); - assert.strictEqual(re.lastIndex, 0, '.lastIndex isn\'t updated for global regexps if the match is empty'); -}); - -QUnit.test('RegExp#exec capturing groups', assert => { - assert.deepEqual(/(a?)/.exec('x'), ['', ''], '/(a?)/.exec("x") returns ["", ""]'); - assert.deepEqual(/(a)?/.exec('x'), ['', undefined], '/(a)?/.exec("x") returns ["", undefined]'); - - // @nicolo-ribaudo: I don't know how to fix this in IE8. For the `/(a)?/` case it is fixed using - // #replace, but here also #replace is buggy :( - // assert.deepEqual(/(a?)?/.exec('x'), ['', undefined], '/(a?)?/.exec("x") returns ["", undefined]'); -}); diff --git a/tests/tests/es.regexp.flags.js b/tests/tests/es.regexp.flags.js deleted file mode 100644 index 5098080344b8..000000000000 --- a/tests/tests/es.regexp.flags.js +++ /dev/null @@ -1,15 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -if (DESCRIPTORS) { - QUnit.test('RegExp#flags', assert => { - assert.nonEnumerable(RegExp.prototype, 'flags'); - assert.strictEqual(/./g.flags, 'g', '/./g.flags is "g"'); - assert.strictEqual(/./.flags, '', '/./.flags is ""'); - assert.strictEqual(RegExp('.', 'gim').flags, 'gim', 'RegExp(".", "gim").flags is "gim"'); - assert.strictEqual(RegExp('.').flags, '', 'RegExp(".").flags is ""'); - assert.strictEqual(/./gim.flags, 'gim', '/./gim.flags is "gim"'); - assert.strictEqual(/./gmi.flags, 'gim', '/./gmi.flags is "gim"'); - assert.strictEqual(/./mig.flags, 'gim', '/./mig.flags is "gim"'); - assert.strictEqual(/./mgi.flags, 'gim', '/./mgi.flags is "gim"'); - }); -} diff --git a/tests/tests/es.set.js b/tests/tests/es.set.js deleted file mode 100644 index 2680fe005426..000000000000 --- a/tests/tests/es.set.js +++ /dev/null @@ -1,442 +0,0 @@ -/* eslint-disable sonarjs/no-element-overwrite */ - -import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants'; -import { createIterable, is, nativeSubclass } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; -const { getOwnPropertyDescriptor, keys, getOwnPropertyNames, getOwnPropertySymbols, freeze } = Object; -const { ownKeys } = Reflect || {}; -const { from } = Array; - -QUnit.test('Set', assert => { - assert.isFunction(Set); - assert.name(Set, 'Set'); - assert.arity(Set, 0); - assert.looksNative(Set); - assert.ok('add' in Set.prototype, 'add in Set.prototype'); - assert.ok('clear' in Set.prototype, 'clear in Set.prototype'); - assert.ok('delete' in Set.prototype, 'delete in Set.prototype'); - assert.ok('forEach' in Set.prototype, 'forEach in Set.prototype'); - assert.ok('has' in Set.prototype, 'has in Set.prototype'); - assert.ok(new Set() instanceof Set, 'new Set instanceof Set'); - const set = new Set(); - set.add(1); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - assert.strictEqual(set.size, 3); - const result = []; - set.forEach(val => { - result.push(val); - }); - assert.deepEqual(result, [1, 2, 3]); - assert.strictEqual(new Set(createIterable([1, 2, 3])).size, 3, 'Init from iterable'); - assert.strictEqual(new Set([freeze({}), 1]).size, 2, 'Support frozen objects'); - assert.strictEqual(new Set([NaN, NaN, NaN]).size, 1); - assert.deepEqual(from(new Set([3, 4]).add(2).add(1)), [3, 4, 2, 1]); - let done = false; - const { add } = Set.prototype; - // eslint-disable-next-line no-extend-native - Set.prototype.add = function () { - throw new Error(); - }; - try { - new Set(createIterable([null, 1, 2], { - return() { - return done = true; - }, - })); - } catch { /* empty */ } - // eslint-disable-next-line no-extend-native - Set.prototype.add = add; - assert.ok(done, '.return #throw'); - const array = []; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return [][Symbol.iterator].call(this); - }; - new Set(array); - assert.ok(done); - const object = {}; - new Set().add(object); - if (DESCRIPTORS) { - const results = []; - for (const key in results) keys.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(object), []); - } - assert.arrayEqual(getOwnPropertyNames(object), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); - if (ownKeys) assert.arrayEqual(ownKeys(object), []); - if (nativeSubclass) { - const Subclass = nativeSubclass(Set); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof Set, 'correct subclassing with native classes #2'); - assert.ok(new Subclass().add(2).has(2), 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('Set#add', assert => { - assert.isFunction(Set.prototype.add); - assert.name(Set.prototype.add, 'add'); - assert.arity(Set.prototype.add, 1); - assert.looksNative(Set.prototype.add); - assert.nonEnumerable(Set.prototype, 'add'); - const array = []; - let set = new Set(); - set.add(NaN); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.add(array); - assert.strictEqual(set.size, 5); - const chain = set.add(NaN); - assert.strictEqual(chain, set); - assert.strictEqual(set.size, 5); - set.add(2); - assert.strictEqual(set.size, 5); - set.add(array); - assert.strictEqual(set.size, 5); - set.add([]); - assert.strictEqual(set.size, 6); - set.add(4); - assert.strictEqual(set.size, 7); - const frozen = freeze({}); - set = new Set(); - set.add(frozen); - assert.ok(set.has(frozen)); -}); - -QUnit.test('Set#clear', assert => { - assert.isFunction(Set.prototype.clear); - assert.name(Set.prototype.clear, 'clear'); - assert.arity(Set.prototype.clear, 0); - assert.looksNative(Set.prototype.clear); - assert.nonEnumerable(Set.prototype, 'clear'); - let set = new Set(); - set.clear(); - assert.strictEqual(set.size, 0); - set = new Set(); - set.add(1); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.clear(); - assert.strictEqual(set.size, 0); - assert.ok(!set.has(1)); - assert.ok(!set.has(2)); - assert.ok(!set.has(3)); - const frozen = freeze({}); - set = new Set(); - set.add(1); - set.add(frozen); - set.clear(); - assert.strictEqual(set.size, 0, 'Support frozen objects'); - assert.ok(!set.has(1)); - assert.ok(!set.has(frozen)); -}); - -QUnit.test('Set#delete', assert => { - assert.isFunction(Set.prototype.delete); - if (NATIVE) assert.name(Set.prototype.delete, 'delete'); - assert.arity(Set.prototype.delete, 1); - assert.looksNative(Set.prototype.delete); - assert.nonEnumerable(Set.prototype, 'delete'); - const array = []; - const set = new Set(); - set.add(NaN); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.add(array); - assert.strictEqual(set.size, 5); - assert.strictEqual(set.delete(NaN), true); - assert.strictEqual(set.size, 4); - assert.strictEqual(set.delete(4), false); - assert.strictEqual(set.size, 4); - set.delete([]); - assert.strictEqual(set.size, 4); - set.delete(array); - assert.strictEqual(set.size, 3); - const frozen = freeze({}); - set.add(frozen); - assert.strictEqual(set.size, 4); - set.delete(frozen); - assert.strictEqual(set.size, 3); -}); - -QUnit.test('Set#forEach', assert => { - assert.isFunction(Set.prototype.forEach); - assert.name(Set.prototype.forEach, 'forEach'); - assert.arity(Set.prototype.forEach, 1); - assert.looksNative(Set.prototype.forEach); - assert.nonEnumerable(Set.prototype, 'forEach'); - let result = []; - let count = 0; - let set = new Set(); - set.add(1); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.forEach(value => { - count++; - result.push(value); - }); - assert.strictEqual(count, 3); - assert.deepEqual(result, [1, 2, 3]); - set = new Set(); - set.add('0'); - set.add('1'); - set.add('2'); - set.add('3'); - result = ''; - set.forEach(it => { - result += it; - if (it === '2') { - set.delete('2'); - set.delete('3'); - set.delete('1'); - set.add('4'); - } - }); - assert.strictEqual(result, '0124'); - set = new Set(); - set.add('0'); - result = ''; - set.forEach(it => { - set.delete('0'); - if (result !== '') throw new Error(); - result += it; - }); - assert.strictEqual(result, '0'); - assert.throws(() => { - Set.prototype.forEach.call(new Map(), () => { /* empty */ }); - }, 'non-generic'); -}); - -QUnit.test('Set#has', assert => { - assert.isFunction(Set.prototype.has); - assert.name(Set.prototype.has, 'has'); - assert.arity(Set.prototype.has, 1); - assert.looksNative(Set.prototype.has); - assert.nonEnumerable(Set.prototype, 'has'); - const array = []; - const frozen = freeze({}); - const set = new Set(); - set.add(NaN); - set.add(2); - set.add(3); - set.add(2); - set.add(1); - set.add(frozen); - set.add(array); - assert.ok(set.has(NaN)); - assert.ok(set.has(array)); - assert.ok(set.has(frozen)); - assert.ok(set.has(2)); - assert.ok(!set.has(4)); - assert.ok(!set.has([])); -}); - -QUnit.test('Set#size', assert => { - assert.nonEnumerable(Set.prototype, 'size'); - const set = new Set(); - set.add(1); - const { size } = set; - assert.strictEqual(typeof size, 'number', 'size is number'); - assert.strictEqual(size, 1, 'size is correct'); - if (DESCRIPTORS) { - const sizeDescriptor = getOwnPropertyDescriptor(Set.prototype, 'size'); - assert.ok(sizeDescriptor && sizeDescriptor.get, 'size is getter'); - assert.ok(sizeDescriptor && !sizeDescriptor.set, 'size isnt setter'); - assert.throws(() => Set.prototype.size, TypeError); - } -}); - -QUnit.test('Set & -0', assert => { - let set = new Set(); - set.add(-0); - assert.strictEqual(set.size, 1); - assert.ok(set.has(0)); - assert.ok(set.has(-0)); - set.forEach(it => { - assert.ok(!is(it, -0)); - }); - set.delete(-0); - assert.strictEqual(set.size, 0); - set = new Set([-0]); - set.forEach(key => { - assert.ok(!is(key, -0)); - }); - set = new Set(); - set.add(4); - set.add(3); - set.add(2); - set.add(1); - set.add(0); - assert.ok(set.has(-0)); -}); - -QUnit.test('Set#@@toStringTag', assert => { - assert.strictEqual(Set.prototype[Symbol.toStringTag], 'Set', 'Set::@@toStringTag is `Set`'); - assert.strictEqual(String(new Set()), '[object Set]', 'correct stringification'); -}); - -QUnit.test('Set Iterator', assert => { - const set = new Set(); - set.add('a'); - set.add('b'); - set.add('c'); - set.add('d'); - const results = []; - const iterator = set.keys(); - results.push(iterator.next().value); - assert.ok(set.delete('a')); - assert.ok(set.delete('b')); - assert.ok(set.delete('c')); - set.add('e'); - results.push(iterator.next().value); - results.push(iterator.next().value); - assert.ok(iterator.next().done); - set.add('f'); - assert.ok(iterator.next().done); - assert.deepEqual(results, ['a', 'd', 'e']); -}); - -QUnit.test('Set#keys', assert => { - assert.isFunction(Set.prototype.keys); - assert.name(Set.prototype.keys, 'values'); - assert.arity(Set.prototype.keys, 0); - assert.looksNative(Set.prototype.keys); - assert.strictEqual(Set.prototype.keys, Set.prototype.values); - assert.nonEnumerable(Set.prototype, 'keys'); - const set = new Set(); - set.add('q'); - set.add('w'); - set.add('e'); - const iterator = set.keys(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Set Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Set#values', assert => { - assert.isFunction(Set.prototype.values); - assert.name(Set.prototype.values, 'values'); - assert.arity(Set.prototype.values, 0); - assert.looksNative(Set.prototype.values); - assert.nonEnumerable(Set.prototype, 'values'); - const set = new Set(); - set.add('q'); - set.add('w'); - set.add('e'); - const iterator = set.values(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Set Iterator'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Set#entries', assert => { - assert.isFunction(Set.prototype.entries); - assert.name(Set.prototype.entries, 'entries'); - assert.arity(Set.prototype.entries, 0); - assert.looksNative(Set.prototype.entries); - assert.nonEnumerable(Set.prototype, 'entries'); - const set = new Set(); - set.add('q'); - set.add('w'); - set.add('e'); - const iterator = set.entries(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Set Iterator'); - assert.deepEqual(iterator.next(), { - value: ['q', 'q'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['w', 'w'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: ['e', 'e'], - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); - -QUnit.test('Set#@@iterator', assert => { - assert.isIterable(Set.prototype); - assert.name(Set.prototype[Symbol.iterator], 'values'); - assert.arity(Set.prototype[Symbol.iterator], 0); - assert.looksNative(Set.prototype[Symbol.iterator]); - assert.strictEqual(Set.prototype[Symbol.iterator], Set.prototype.values); - assert.nonEnumerable(Set.prototype, 'values'); - const set = new Set(); - set.add('q'); - set.add('w'); - set.add('e'); - const iterator = set[Symbol.iterator](); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Set Iterator'); - assert.strictEqual(String(iterator), '[object Set Iterator]'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/tests/es.string.anchor.js b/tests/tests/es.string.anchor.js deleted file mode 100644 index 3051de03e5ab..000000000000 --- a/tests/tests/es.string.anchor.js +++ /dev/null @@ -1,10 +0,0 @@ -QUnit.test('String#anchor', assert => { - const { anchor } = String.prototype; - assert.isFunction(anchor); - assert.arity(anchor, 1); - assert.name(anchor, 'anchor'); - assert.looksNative(anchor); - assert.nonEnumerable(String.prototype, 'anchor'); - assert.same('a'.anchor('b'), 'a', 'lower case'); - assert.same('a'.anchor('"'), 'a', 'escape quotes'); -}); diff --git a/tests/tests/es.string.big.js b/tests/tests/es.string.big.js deleted file mode 100644 index b9b35def5023..000000000000 --- a/tests/tests/es.string.big.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#big', assert => { - const { big } = String.prototype; - assert.isFunction(big); - assert.arity(big, 0); - assert.name(big, 'big'); - assert.looksNative(big); - assert.nonEnumerable(String.prototype, 'big'); - assert.same('a'.big(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.blink.js b/tests/tests/es.string.blink.js deleted file mode 100644 index e05e29ba745e..000000000000 --- a/tests/tests/es.string.blink.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#blink', assert => { - const { blink } = String.prototype; - assert.isFunction(blink); - assert.arity(blink, 0); - assert.name(blink, 'blink'); - assert.looksNative(blink); - assert.nonEnumerable(String.prototype, 'blink'); - assert.same('a'.blink(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.bold.js b/tests/tests/es.string.bold.js deleted file mode 100644 index b6db1b702709..000000000000 --- a/tests/tests/es.string.bold.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#bold', assert => { - const { bold } = String.prototype; - assert.isFunction(bold); - assert.arity(bold, 0); - assert.name(bold, 'bold'); - assert.looksNative(bold); - assert.nonEnumerable(String.prototype, 'bold'); - assert.same('a'.bold(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.code-point-at.js b/tests/tests/es.string.code-point-at.js deleted file mode 100644 index fd3ceed28668..000000000000 --- a/tests/tests/es.string.code-point-at.js +++ /dev/null @@ -1,63 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('String#codePointAt', assert => { - const { codePointAt } = String.prototype; - assert.isFunction(codePointAt); - assert.arity(codePointAt, 1); - assert.name(codePointAt, 'codePointAt'); - assert.looksNative(codePointAt); - assert.nonEnumerable(String.prototype, 'codePointAt'); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(''), 0x61); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt('_'), 0x61); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(), 0x61); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(-Infinity), undefined); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(-1), undefined); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(-0), 0x61); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(0), 0x61); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(3), 0x1D306); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(4), 0xDF06); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(5), 0x64); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(42), undefined); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(Infinity), undefined); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(Infinity), undefined); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(NaN), 0x61); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(false), 0x61); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(null), 0x61); - assert.strictEqual('abc\uD834\uDF06def'.codePointAt(undefined), 0x61); - assert.strictEqual('\uD834\uDF06def'.codePointAt(''), 0x1D306); - assert.strictEqual('\uD834\uDF06def'.codePointAt('1'), 0xDF06); - assert.strictEqual('\uD834\uDF06def'.codePointAt('_'), 0x1D306); - assert.strictEqual('\uD834\uDF06def'.codePointAt(), 0x1D306); - assert.strictEqual('\uD834\uDF06def'.codePointAt(-1), undefined); - assert.strictEqual('\uD834\uDF06def'.codePointAt(-0), 0x1D306); - assert.strictEqual('\uD834\uDF06def'.codePointAt(0), 0x1D306); - assert.strictEqual('\uD834\uDF06def'.codePointAt(1), 0xDF06); - assert.strictEqual('\uD834\uDF06def'.codePointAt(42), undefined); - assert.strictEqual('\uD834\uDF06def'.codePointAt(false), 0x1D306); - assert.strictEqual('\uD834\uDF06def'.codePointAt(null), 0x1D306); - assert.strictEqual('\uD834\uDF06def'.codePointAt(undefined), 0x1D306); - assert.strictEqual('\uD834abc'.codePointAt(''), 0xD834); - assert.strictEqual('\uD834abc'.codePointAt('_'), 0xD834); - assert.strictEqual('\uD834abc'.codePointAt(), 0xD834); - assert.strictEqual('\uD834abc'.codePointAt(-1), undefined); - assert.strictEqual('\uD834abc'.codePointAt(-0), 0xD834); - assert.strictEqual('\uD834abc'.codePointAt(0), 0xD834); - assert.strictEqual('\uD834abc'.codePointAt(false), 0xD834); - assert.strictEqual('\uD834abc'.codePointAt(NaN), 0xD834); - assert.strictEqual('\uD834abc'.codePointAt(null), 0xD834); - assert.strictEqual('\uD834abc'.codePointAt(undefined), 0xD834); - assert.strictEqual('\uDF06abc'.codePointAt(''), 0xDF06); - assert.strictEqual('\uDF06abc'.codePointAt('_'), 0xDF06); - assert.strictEqual('\uDF06abc'.codePointAt(), 0xDF06); - assert.strictEqual('\uDF06abc'.codePointAt(-1), undefined); - assert.strictEqual('\uDF06abc'.codePointAt(-0), 0xDF06); - assert.strictEqual('\uDF06abc'.codePointAt(0), 0xDF06); - assert.strictEqual('\uDF06abc'.codePointAt(false), 0xDF06); - assert.strictEqual('\uDF06abc'.codePointAt(NaN), 0xDF06); - assert.strictEqual('\uDF06abc'.codePointAt(null), 0xDF06); - assert.strictEqual('\uDF06abc'.codePointAt(undefined), 0xDF06); - if (STRICT) { - assert.throws(() => codePointAt.call(null, 0), TypeError); - assert.throws(() => codePointAt.call(undefined, 0), TypeError); - } -}); diff --git a/tests/tests/es.string.ends-with.js b/tests/tests/es.string.ends-with.js deleted file mode 100644 index 3569058e60b4..000000000000 --- a/tests/tests/es.string.ends-with.js +++ /dev/null @@ -1,37 +0,0 @@ -import { GLOBAL, STRICT } from '../helpers/constants'; - -const Symbol = GLOBAL.Symbol || {}; - -QUnit.test('String#endsWith', assert => { - const { endsWith } = String.prototype; - assert.isFunction(endsWith); - assert.arity(endsWith, 1); - assert.name(endsWith, 'endsWith'); - assert.looksNative(endsWith); - assert.nonEnumerable(String.prototype, 'endsWith'); - assert.ok('undefined'.endsWith()); - assert.ok(!'undefined'.endsWith(null)); - assert.ok('abc'.endsWith('')); - assert.ok('abc'.endsWith('c')); - assert.ok('abc'.endsWith('bc')); - assert.ok(!'abc'.endsWith('ab')); - assert.ok('abc'.endsWith('', NaN)); - assert.ok(!'abc'.endsWith('c', -1)); - assert.ok('abc'.endsWith('a', 1)); - assert.ok('abc'.endsWith('c', Infinity)); - assert.ok('abc'.endsWith('a', true)); - assert.ok(!'abc'.endsWith('c', 'x')); - assert.ok(!'abc'.endsWith('a', 'x')); - if (STRICT) { - assert.throws(() => endsWith.call(null, '.'), TypeError); - assert.throws(() => endsWith.call(undefined, '.'), TypeError); - } - const regexp = /./; - assert.throws(() => '/./'.endsWith(regexp), TypeError); - regexp[Symbol.match] = false; - assert.notThrows(() => '/./'.endsWith(regexp)); - const object = {}; - assert.notThrows(() => '[object Object]'.endsWith(object)); - object[Symbol.match] = true; - assert.throws(() => '[object Object]'.endsWith(object), TypeError); -}); diff --git a/tests/tests/es.string.fixed.js b/tests/tests/es.string.fixed.js deleted file mode 100644 index 4271ec6d0f30..000000000000 --- a/tests/tests/es.string.fixed.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#fixed', assert => { - const { fixed } = String.prototype; - assert.isFunction(fixed); - assert.arity(fixed, 0); - assert.name(fixed, 'fixed'); - assert.looksNative(fixed); - assert.nonEnumerable(String.prototype, 'fixed'); - assert.same('a'.fixed(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.fontcolor.js b/tests/tests/es.string.fontcolor.js deleted file mode 100644 index 51b845d72b3e..000000000000 --- a/tests/tests/es.string.fontcolor.js +++ /dev/null @@ -1,10 +0,0 @@ -QUnit.test('String#fontcolor', assert => { - const { fontcolor } = String.prototype; - assert.isFunction(fontcolor); - assert.arity(fontcolor, 1); - assert.name(fontcolor, 'fontcolor'); - assert.looksNative(fontcolor); - assert.nonEnumerable(String.prototype, 'fontcolor'); - assert.same('a'.fontcolor('b'), 'a', 'lower case'); - assert.same('a'.fontcolor('"'), 'a', 'escape quotes'); -}); diff --git a/tests/tests/es.string.fontsize.js b/tests/tests/es.string.fontsize.js deleted file mode 100644 index 43d6f4109c05..000000000000 --- a/tests/tests/es.string.fontsize.js +++ /dev/null @@ -1,10 +0,0 @@ -QUnit.test('String#fontsize', assert => { - const { fontsize } = String.prototype; - assert.isFunction(fontsize); - assert.arity(fontsize, 1); - assert.name(fontsize, 'fontsize'); - assert.looksNative(fontsize); - assert.nonEnumerable(String.prototype, 'fontsize'); - assert.same('a'.fontsize('b'), 'a', 'lower case'); - assert.same('a'.fontsize('"'), 'a', 'escape quotes'); -}); diff --git a/tests/tests/es.string.from-code-point.js b/tests/tests/es.string.from-code-point.js deleted file mode 100644 index 80173320934a..000000000000 --- a/tests/tests/es.string.from-code-point.js +++ /dev/null @@ -1,48 +0,0 @@ -QUnit.test('String.fromCodePoint', assert => { - const { fromCodePoint } = String; - assert.isFunction(fromCodePoint); - assert.arity(fromCodePoint, 1); - assert.name(fromCodePoint, 'fromCodePoint'); - assert.looksNative(fromCodePoint); - assert.nonEnumerable(String, 'fromCodePoint'); - assert.strictEqual(fromCodePoint(''), '\0'); - assert.strictEqual(fromCodePoint(), ''); - assert.strictEqual(fromCodePoint(-0), '\0'); - assert.strictEqual(fromCodePoint(0), '\0'); - assert.strictEqual(fromCodePoint(0x1D306), '\uD834\uDF06'); - assert.strictEqual(fromCodePoint(0x1D306, 0x61, 0x1D307), '\uD834\uDF06a\uD834\uDF07'); - assert.strictEqual(fromCodePoint(0x61, 0x62, 0x1D307), 'ab\uD834\uDF07'); - assert.strictEqual(fromCodePoint(false), '\0'); - assert.strictEqual(fromCodePoint(null), '\0'); - assert.throws(() => fromCodePoint('_'), RangeError); - assert.throws(() => fromCodePoint('+Infinity'), RangeError); - assert.throws(() => fromCodePoint('-Infinity'), RangeError); - assert.throws(() => fromCodePoint(-1), RangeError); - assert.throws(() => fromCodePoint(0x10FFFF + 1), RangeError); - assert.throws(() => fromCodePoint(3.14), RangeError); - assert.throws(() => fromCodePoint(3e-2), RangeError); - assert.throws(() => fromCodePoint(-Infinity), RangeError); - assert.throws(() => fromCodePoint(Infinity), RangeError); - assert.throws(() => fromCodePoint(NaN), RangeError); - assert.throws(() => fromCodePoint(undefined), RangeError); - assert.throws(() => fromCodePoint({}), RangeError); - assert.throws(() => fromCodePoint(/./), RangeError); - let number = 0x60; - assert.strictEqual(fromCodePoint({ - valueOf() { - return ++number; - }, - }), 'a'); - assert.strictEqual(number, 0x61); - // one code unit per symbol - let counter = 2 ** 15 * 3 / 2; - let result = []; - while (--counter >= 0) result.push(0); - // should not throw - fromCodePoint.apply(null, result); - counter = 2 ** 15 * 3 / 2; - result = []; - while (--counter >= 0) result.push(0xFFFF + 1); - // should not throw - fromCodePoint.apply(null, result); -}); diff --git a/tests/tests/es.string.includes.js b/tests/tests/es.string.includes.js deleted file mode 100644 index fc462452a28f..000000000000 --- a/tests/tests/es.string.includes.js +++ /dev/null @@ -1,28 +0,0 @@ -import { GLOBAL, STRICT } from '../helpers/constants'; - -const Symbol = GLOBAL.Symbol || {}; - -QUnit.test('String#includes', assert => { - const { includes } = String.prototype; - assert.isFunction(includes); - assert.arity(includes, 1); - assert.name(includes, 'includes'); - assert.looksNative(includes); - assert.nonEnumerable(String.prototype, 'includes'); - assert.ok(!'abc'.includes()); - assert.ok('aundefinedb'.includes()); - assert.ok('abcd'.includes('b', 1)); - assert.ok(!'abcd'.includes('b', 2)); - if (STRICT) { - assert.throws(() => includes.call(null, '.'), TypeError); - assert.throws(() => includes.call(undefined, '.'), TypeError); - } - const regexp = /./; - assert.throws(() => '/./'.includes(regexp), TypeError); - regexp[Symbol.match] = false; - assert.notThrows(() => '/./'.includes(regexp)); - const object = {}; - assert.notThrows(() => '[object Object]'.includes(object)); - object[Symbol.match] = true; - assert.throws(() => '[object Object]'.includes(object), TypeError); -}); diff --git a/tests/tests/es.string.italics.js b/tests/tests/es.string.italics.js deleted file mode 100644 index 06be1b81fe30..000000000000 --- a/tests/tests/es.string.italics.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#italics', assert => { - const { italics } = String.prototype; - assert.isFunction(italics); - assert.arity(italics, 0); - assert.name(italics, 'italics'); - assert.looksNative(italics); - assert.nonEnumerable(String.prototype, 'italics'); - assert.same('a'.italics(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.iterator.js b/tests/tests/es.string.iterator.js deleted file mode 100644 index c265b9e3fc02..000000000000 --- a/tests/tests/es.string.iterator.js +++ /dev/null @@ -1,46 +0,0 @@ -import { GLOBAL } from '../helpers/constants'; - -const Symbol = GLOBAL.Symbol || {}; - -QUnit.test('String#@@iterator', assert => { - assert.isIterable(String.prototype); - let iterator = 'qwe'[Symbol.iterator](); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'String Iterator'); - assert.strictEqual(String(iterator), '[object String Iterator]'); - assert.deepEqual(iterator.next(), { - value: 'q', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'w', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: 'e', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - assert.strictEqual(Array.from('𠮷𠮷𠮷').length, 3); - iterator = '𠮷𠮷𠮷'[Symbol.iterator](); - assert.deepEqual(iterator.next(), { - value: '𠮷', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: '𠮷', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: '𠮷', - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/tests/es.string.link.js b/tests/tests/es.string.link.js deleted file mode 100644 index 253022820fcc..000000000000 --- a/tests/tests/es.string.link.js +++ /dev/null @@ -1,10 +0,0 @@ -QUnit.test('String#link', assert => { - const { link } = String.prototype; - assert.isFunction(link); - assert.arity(link, 1); - assert.name(link, 'link'); - assert.looksNative(link); - assert.nonEnumerable(String.prototype, 'link'); - assert.same('a'.link('b'), 'a', 'lower case'); - assert.same('a'.link('"'), 'a', 'escape quotes'); -}); diff --git a/tests/tests/es.string.match-all.js b/tests/tests/es.string.match-all.js deleted file mode 100644 index 98b3194da9a7..000000000000 --- a/tests/tests/es.string.match-all.js +++ /dev/null @@ -1,132 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('String#matchAll', assert => { - const { matchAll } = String.prototype; - const { assign } = Object; - assert.isFunction(matchAll); - assert.arity(matchAll, 1); - assert.name(matchAll, 'matchAll'); - assert.looksNative(matchAll); - assert.nonEnumerable(String.prototype, 'matchAll'); - let data = ['aabc', { toString() { return 'aabc'; } }]; - for (const target of data) { - const iterator = matchAll.call(target, /[ac]/g); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.deepEqual(iterator.next(), { - value: assign(['a'], { - input: 'aabc', - index: 0, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['a'], { - input: 'aabc', - index: 1, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['c'], { - input: 'aabc', - index: 3, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - } - let iterator = '1111a2b3cccc'.matchAll(/(\d)(\D)/g); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'RegExp String Iterator'); - assert.strictEqual(String(iterator), '[object RegExp String Iterator]'); - assert.deepEqual(iterator.next(), { - value: assign(['1a', '1', 'a'], { - input: '1111a2b3cccc', - index: 3, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['2b', '2', 'b'], { - input: '1111a2b3cccc', - index: 5, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['3c', '3', 'c'], { - input: '1111a2b3cccc', - index: 7, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - assert.throws(() => '1111a2b3cccc'.matchAll(/(\d)(\D)/), TypeError); - iterator = '1111a2b3cccc'.matchAll('(\\d)(\\D)'); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.deepEqual(iterator.next(), { - value: assign(['1a', '1', 'a'], { - input: '1111a2b3cccc', - index: 3, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['2b', '2', 'b'], { - input: '1111a2b3cccc', - index: 5, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign(['3c', '3', 'c'], { - input: '1111a2b3cccc', - index: 7, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - /* IE8- issue - iterator = 'abc'.matchAll(/\B/g); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.deepEqual(iterator.next(), { - value: assign([''], { - input: 'abc', - index: 1, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: assign([''], { - input: 'abc', - index: 2, - }), - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - */ - data = [null, undefined, NaN, 42, {}, []]; - for (const target of data) { - assert.notThrows(() => ''.matchAll(target), `Not throws on ${ target } as the first argument`); - } - if (STRICT) { - assert.throws(() => matchAll.call(null, /./g), TypeError, 'Throws on null as `this`'); - assert.throws(() => matchAll.call(undefined, /./g), TypeError, 'Throws on undefined as `this`'); - } -}); diff --git a/tests/tests/es.string.match.js b/tests/tests/es.string.match.js deleted file mode 100644 index aec1797aa9d7..000000000000 --- a/tests/tests/es.string.match.js +++ /dev/null @@ -1,251 +0,0 @@ -// TODO: fix escaping in regexps -/* eslint-disable no-useless-escape, unicorn/no-unsafe-regex, optimize-regex/optimize-regex */ -import { GLOBAL, NATIVE, STRICT } from '../helpers/constants'; -import { patchRegExp$exec } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; - -const run = assert => { - assert.isFunction(''.match); - assert.arity(''.match, 1); - assert.name(''.match, 'match'); - assert.looksNative(''.match); - assert.nonEnumerable(String.prototype, 'match'); - let instance = Object(true); - instance.match = String.prototype.match; - assert.strictEqual(instance.match(true)[0], 'true', 'S15.5.4.10_A1_T1'); - instance = Object(false); - instance.match = String.prototype.match; - assert.strictEqual(instance.match(false)[0], 'false', 'S15.5.4.10_A1_T2'); - let matched = ''.match(); - let expected = RegExp().exec(''); - assert.strictEqual(matched.length, expected.length, 'S15.5.4.10_A1_T4 #1'); - assert.strictEqual(matched.index, expected.index, 'S15.5.4.10_A1_T4 #2'); - assert.strictEqual(matched.input, expected.input, 'S15.5.4.10_A1_T4 #3'); - assert.strictEqual('gnulluna'.match(null)[0], 'null', 'S15.5.4.10_A1_T5'); - matched = Object('undefined').match(undefined); - expected = RegExp(undefined).exec('undefined'); - assert.strictEqual(matched.length, expected.length, 'S15.5.4.10_A1_T6 #1'); - assert.strictEqual(matched.index, expected.index, 'S15.5.4.10_A1_T6 #2'); - assert.strictEqual(matched.input, expected.input, 'S15.5.4.10_A1_T6 #3'); - let object = { toString() { /* empty */ } }; - matched = String(object).match(undefined); - expected = RegExp(undefined).exec('undefined'); - assert.strictEqual(matched.length, expected.length, 'S15.5.4.10_A1_T8 #1'); - assert.strictEqual(matched.index, expected.index, 'S15.5.4.10_A1_T8 #2'); - assert.strictEqual(matched.input, expected.input, 'S15.5.4.10_A1_T8 #3'); - object = { toString() { return '\u0041B'; } }; - let string = 'ABB\u0041BABAB'; - assert.strictEqual(string.match(object)[0], 'AB', 'S15.5.4.10_A1_T10'); - object = { toString() { throw new Error('intostr'); } }; - string = 'ABB\u0041BABAB'; - try { - string.match(object); - assert.ok(false, 'S15.5.4.10_A1_T11 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'intostr', `S15.5.4.10_A1_T11 #1.1: Exception === "intostr". Actual: ${ error }`); - } - object = { - toString() { - return {}; - }, - valueOf() { - throw new Error('intostr'); - }, - }; - string = 'ABB\u0041BABAB'; - try { - string.match(object); - assert.ok(false, 'S15.5.4.10_A1_T12 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'intostr', `S15.5.4.10_A1_T12 #1.1: Exception === "intostr". Actual: ${ error }`); - } - object = { - toString() { - return {}; - }, - valueOf() { - return 1; - }, - }; - assert.strictEqual('ABB\u0041B\u0031ABAB\u0031BBAA'.match(object)[0], '1', 'S15.5.4.10_A1_T13 #1'); - assert.strictEqual('ABB\u0041B\u0031ABAB\u0031BBAA'.match(object).length, 1, 'S15.5.4.10_A1_T13 #2'); - let regexp = RegExp('77'); - assert.strictEqual('ABB\u0041BABAB\u0037\u0037BBAA'.match(regexp)[0], '77', 'S15.5.4.10_A1_T14'); - string = '1234567890'; - assert.strictEqual(string.match(3)[0], '3', 'S15.5.4.10_A2_T1 #1'); - assert.strictEqual(string.match(3).length, 1, 'S15.5.4.10_A2_T1 #2'); - assert.strictEqual(string.match(3).index, 2, 'S15.5.4.10_A2_T1 #3'); - assert.strictEqual(string.match(3).input, string, 'S15.5.4.10_A2_T1 #4'); - let matches = ['34', '34', '34']; - string = '343443444'; - assert.strictEqual(string.match(/34/g).length, 3, 'S15.5.4.10_A2_T2 #1'); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(string.match(/34/g)[i], matches[i], 'S15.5.4.10_A2_T2 #2'); - } - matches = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']; - string = '123456abcde7890'; - assert.strictEqual(string.match(/\d{1}/g).length, 10, 'S15.5.4.10_A2_T3 #1'); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(string.match(/\d{1}/g)[i], matches[i], 'S15.5.4.10_A2_T3 #2'); - } - matches = ['12', '34', '56', '78', '90']; - string = '123456abcde7890'; - assert.strictEqual(string.match(/\d{2}/g).length, 5, 'S15.5.4.10_A2_T4 #1'); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(string.match(/\d{2}/g)[i], matches[i], 'S15.5.4.10_A2_T4 #2'); - } - matches = ['ab', 'cd']; - string = '123456abcde7890'; - assert.strictEqual(string.match(/\D{2}/g).length, 2, 'S15.5.4.10_A2_T5 #1'); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(string.match(/\D{2}/g)[i], matches[i], 'S15.5.4.10_A2_T5 #2'); - } - string = 'Boston, Mass. 02134'; - assert.strictEqual(string.match(/([\d]{5})([-\ ]?[\d]{4})?$/)[0], '02134', 'S15.5.4.10_A2_T6 #1'); - assert.strictEqual(string.match(/([\d]{5})([-\ ]?[\d]{4})?$/)[1], '02134', 'S15.5.4.10_A2_T6 #2'); - if (NATIVE) assert.strictEqual(string.match(/([\d]{5})([-\ ]?[\d]{4})?$/)[2], undefined, 'S15.5.4.10_A2_T6 #3'); - assert.strictEqual(string.match(/([\d]{5})([-\ ]?[\d]{4})?$/).length, 3, 'S15.5.4.10_A2_T6 #4'); - assert.strictEqual(string.match(/([\d]{5})([-\ ]?[\d]{4})?$/).index, 14, 'S15.5.4.10_A2_T6 #5'); - assert.strictEqual(string.match(/([\d]{5})([-\ ]?[\d]{4})?$/).input, string, 'S15.5.4.10_A2_T6 #6'); - string = 'Boston, Mass. 02134'; - assert.strictEqual(string.match(/([\d]{5})([-\ ]?[\d]{4})?$/g).length, 1, 'S15.5.4.10_A2_T7 #1'); - assert.strictEqual(string.match(/([\d]{5})([-\ ]?[\d]{4})?$/g)[0], '02134', 'S15.5.4.10_A2_T7 #2'); - /* IE8- buggy here (empty string instead of `undefined`), but we don't polyfill base `.match` logic - matches = ['02134', '02134', undefined]; - string = 'Boston, MA 02134'; - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/; - regexp.lastIndex = 0; - assert.strictEqual(string.match(regexp).length, 3, 'S15.5.4.10_A2_T8 #1'); - assert.strictEqual(string.match(regexp).index, string.lastIndexOf('0'), 'S15.5.4.10_A2_T8 #2'); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(string.match(regexp)[i], matches[i], 'S15.5.4.10_A2_T8 #3'); - } - string = 'Boston, MA 02134'; - matches = ['02134', '02134', undefined]; - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/; - regexp.lastIndex = string.length; - assert.strictEqual(string.match(regexp).length, 3, 'S15.5.4.10_A2_T9 #1'); - assert.strictEqual(string.match(regexp).index, string.lastIndexOf('0'), 'S15.5.4.10_A2_T9 #2'); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(string.match(regexp)[i], matches[i], 'S15.5.4.10_A2_T9 #3'); - } - string = 'Boston, MA 02134'; - matches = ['02134', '02134', undefined]; - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/; - regexp.lastIndex = string.lastIndexOf('0'); - assert.strictEqual(string.match(regexp).length, 3, 'S15.5.4.10_A2_T10 #1'); - assert.strictEqual(string.match(regexp).index, string.lastIndexOf('0'), 'S15.5.4.10_A2_T10 #2'); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(string.match(regexp)[i], matches[i], 'S15.5.4.10_A2_T10 #3'); - } - string = 'Boston, MA 02134'; - matches = ['02134', '02134', undefined]; - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/; - regexp.lastIndex = string.lastIndexOf('0') + 1; - assert.strictEqual(string.match(regexp).length, 3, 'S15.5.4.10_A2_T11 #1'); - assert.strictEqual(string.match(regexp).index, string.lastIndexOf('0'), 'S15.5.4.10_A2_T11 #2'); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(string.match(regexp)[i], matches[i], 'S15.5.4.10_A2_T11 #3'); - } - */ - string = 'Boston, MA 02134'; - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/g; - assert.strictEqual(string.match(regexp).length, 1, 'S15.5.4.10_A2_T12 #1'); - assert.strictEqual(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T12 #2'); - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/g; - regexp.lastIndex = 0; - string = 'Boston, MA 02134'; - assert.strictEqual(string.match(regexp).length, 1, 'S15.5.4.10_A2_T13 #1'); - assert.strictEqual(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T13 #2'); - string = 'Boston, MA 02134'; - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/g; - regexp.lastIndex = string.length; - assert.strictEqual(string.match(regexp).length, 1, 'S15.5.4.10_A2_T14 #1'); - assert.strictEqual(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T14 #2'); - string = 'Boston, MA 02134'; - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/g; - regexp.lastIndex = string.lastIndexOf('0'); - assert.strictEqual(string.match(regexp).length, 1, 'S15.5.4.10_A2_T15 #1'); - assert.strictEqual(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T15 #2'); - string = 'Boston, MA 02134'; - regexp = /([\d]{5})([-\ ]?[\d]{4})?$/g; - regexp.lastIndex = string.lastIndexOf('0') + 1; - assert.strictEqual(string.match(regexp).length, 1, 'S15.5.4.10_A2_T16 #1'); - assert.strictEqual(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T16 #2'); - regexp = /0./; - let number = 10203040506070809000; - assert.strictEqual(''.match.call(number, regexp)[0], '02', 'S15.5.4.10_A2_T17 #1'); - assert.strictEqual(''.match.call(number, regexp).length, 1, 'S15.5.4.10_A2_T17 #2'); - assert.strictEqual(''.match.call(number, regexp).index, 1, 'S15.5.4.10_A2_T17 #3'); - assert.strictEqual(''.match.call(number, regexp).input, String(number), 'S15.5.4.10_A2_T17 #4'); - regexp = /0./; - regexp.lastIndex = 0; - number = 10203040506070809000; - assert.strictEqual(''.match.call(number, regexp)[0], '02', 'S15.5.4.10_A2_T18 #1'); - assert.strictEqual(''.match.call(number, regexp).length, 1, 'S15.5.4.10_A2_T18 #2'); - assert.strictEqual(''.match.call(number, regexp).index, 1, 'S15.5.4.10_A2_T18 #3'); - assert.strictEqual(''.match.call(number, regexp).input, String(number), 'S15.5.4.10_A2_T18 #4'); -}; - -QUnit.test('String#match regression', run); - -QUnit.test('RegExp#@@match appearance', assert => { - const match = /./[Symbol.match]; - assert.isFunction(match); - // assert.name(match, '[Symbol.match]'); - assert.arity(match, 1); - assert.looksNative(match); - assert.nonEnumerable(RegExp.prototype, Symbol.match); -}); - -QUnit.test('RegExp#@@match basic behavior', assert => { - const string = '123456abcde7890'; - const matches = ['12', '34', '56', '78', '90']; - assert.strictEqual(/\d{2}/g[Symbol.match](string).length, 5); - for (let i = 0, { length } = matches; i < length; ++i) { - assert.strictEqual(/\d{2}/g[Symbol.match](string)[i], matches[i]); - } -}); - -QUnit.test('String#match delegates to @@match', assert => { - const string = STRICT ? 'string' : Object('string'); - const number = STRICT ? 42 : Object(42); - const object = {}; - object[Symbol.match] = function (it) { - return { value: it }; - }; - assert.strictEqual(string.match(object).value, string); - assert.strictEqual(''.match.call(number, object).value, number); - const regexp = /./; - regexp[Symbol.match] = function (it) { - return { value: it }; - }; - assert.strictEqual(string.match(regexp).value, string); - assert.strictEqual(''.match.call(number, regexp).value, number); -}); - -QUnit.test('RegExp#@@match delegates to exec', assert => { - const exec = function () { - execCalled = true; - return /./.exec.apply(this, arguments); - }; - - let execCalled = false; - let re = /[ac]/; - re.exec = exec; - assert.deepEqual(re[Symbol.match]('abc'), ['a']); - assert.ok(execCalled); - - re = /a/; - // Not a function, should be ignored - re.exec = 3; - assert.deepEqual(re[Symbol.match]('abc'), ['a']); - - re = /a/; - // Does not return an object, should throw - re.exec = () => 3; - assert.throws(() => re[Symbol.match]('abc')); -}); - -QUnit.test('RegExp#@@match implementation', patchRegExp$exec(run)); diff --git a/tests/tests/es.string.pad-end.js b/tests/tests/es.string.pad-end.js deleted file mode 100644 index 791f7b880b3d..000000000000 --- a/tests/tests/es.string.pad-end.js +++ /dev/null @@ -1,21 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('String#padEnd', assert => { - const { padEnd } = String.prototype; - assert.isFunction(padEnd); - assert.arity(padEnd, 1); - assert.name(padEnd, 'padEnd'); - assert.looksNative(padEnd); - assert.nonEnumerable(String.prototype, 'padEnd'); - assert.strictEqual('abc'.padEnd(5), 'abc '); - assert.strictEqual('abc'.padEnd(4, 'de'), 'abcd'); - assert.strictEqual('abc'.padEnd(), 'abc'); - assert.strictEqual('abc'.padEnd(5, '_'), 'abc__'); - assert.strictEqual(''.padEnd(0), ''); - assert.strictEqual('foo'.padEnd(1), 'foo'); - assert.strictEqual('foo'.padEnd(5, ''), 'foo'); - if (STRICT) { - assert.throws(() => padEnd.call(null, 0), TypeError); - assert.throws(() => padEnd.call(undefined, 0), TypeError); - } -}); diff --git a/tests/tests/es.string.pad-start.js b/tests/tests/es.string.pad-start.js deleted file mode 100644 index e3ab7869b7ba..000000000000 --- a/tests/tests/es.string.pad-start.js +++ /dev/null @@ -1,21 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('String#padStart', assert => { - const { padStart } = String.prototype; - assert.isFunction(padStart); - assert.arity(padStart, 1); - assert.name(padStart, 'padStart'); - assert.looksNative(padStart); - assert.nonEnumerable(String.prototype, 'padStart'); - assert.strictEqual('abc'.padStart(5), ' abc'); - assert.strictEqual('abc'.padStart(4, 'de'), 'dabc'); - assert.strictEqual('abc'.padStart(), 'abc'); - assert.strictEqual('abc'.padStart(5, '_'), '__abc'); - assert.strictEqual(''.padStart(0), ''); - assert.strictEqual('foo'.padStart(1), 'foo'); - assert.strictEqual('foo'.padStart(5, ''), 'foo'); - if (STRICT) { - assert.throws(() => padStart.call(null, 0), TypeError); - assert.throws(() => padStart.call(undefined, 0), TypeError); - } -}); diff --git a/tests/tests/es.string.raw.js b/tests/tests/es.string.raw.js deleted file mode 100644 index 89a735f69ed6..000000000000 --- a/tests/tests/es.string.raw.js +++ /dev/null @@ -1,13 +0,0 @@ -QUnit.test('String.raw', assert => { - const { raw } = String; - assert.isFunction(raw); - assert.arity(raw, 1); - assert.name(raw, 'raw'); - assert.looksNative(raw); - assert.nonEnumerable(String, 'raw'); - assert.strictEqual(raw({ raw: ['Hi\\n', '!'] }, 'Bob'), 'Hi\\nBob!', 'raw is array'); - assert.strictEqual(raw({ raw: 'test' }, 0, 1, 2), 't0e1s2t', 'raw is string'); - assert.strictEqual(raw({ raw: 'test' }, 0), 't0est', 'lacks substituting'); - assert.throws(() => raw({}), TypeError); - assert.throws(() => raw({ raw: null }), TypeError); -}); diff --git a/tests/tests/es.string.repeat.js b/tests/tests/es.string.repeat.js deleted file mode 100644 index 8e4fb77a3cb7..000000000000 --- a/tests/tests/es.string.repeat.js +++ /dev/null @@ -1,18 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('String#repeat', assert => { - const { repeat } = String.prototype; - assert.isFunction(repeat); - assert.arity(repeat, 1); - assert.name(repeat, 'repeat'); - assert.looksNative(repeat); - assert.nonEnumerable(String.prototype, 'repeat'); - assert.strictEqual('qwe'.repeat(3), 'qweqweqwe'); - assert.strictEqual('qwe'.repeat(2.5), 'qweqwe'); - assert.throws(() => 'qwe'.repeat(-1), RangeError); - assert.throws(() => 'qwe'.repeat(Infinity), RangeError); - if (STRICT) { - assert.throws(() => repeat.call(null, 1), TypeError); - assert.throws(() => repeat.call(undefined, 1), TypeError); - } -}); diff --git a/tests/tests/es.string.replace.js b/tests/tests/es.string.replace.js deleted file mode 100644 index d327dd1402b3..000000000000 --- a/tests/tests/es.string.replace.js +++ /dev/null @@ -1,219 +0,0 @@ -import { GLOBAL, NATIVE, STRICT } from '../helpers/constants'; -import { patchRegExp$exec } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; - -const run = assert => { - assert.isFunction(''.replace); - assert.arity(''.replace, 2); - assert.name(''.replace, 'replace'); - assert.looksNative(''.replace); - assert.nonEnumerable(String.prototype, 'replace'); - let instance = Object(true); - instance.replace = String.prototype.replace; - assert.strictEqual(instance.replace(true, 1), '1', 'S15.5.4.11_A1_T1'); - instance = Object(false); - instance.replace = String.prototype.replace; - assert.strictEqual(instance.replace(false, undefined), 'undefined', 'S15.5.4.11_A1_T2'); - assert.strictEqual('gnulluna'.replace(null, (a1, a2) => `${ a2 }`), 'g1una', 'S15.5.4.11_A1_T4'); - assert.strictEqual('gnulluna'.replace(null, () => { /* empty */ }), 'gundefineduna', 'S15.5.4.11_A1_T5'); - assert.strictEqual(Object('undefined').replace(undefined, (a1, a2) => a2 + 42), '42', 'S15.5.4.11_A1_T6'); - assert.strictEqual('undefined'.replace('e', undefined), 'undundefinedfined', 'S15.5.4.11_A1_T7'); - assert.strictEqual(String({ - toString() { /* empty */ }, - }).replace(/e/g, undefined), 'undundefinedfinundefinedd', 'S15.5.4.11_A1_T8'); - assert.strictEqual(new String({ - valueOf() { /* empty */ }, - toString: undefined, - }).replace(function () { /* empty */ }(), (a1, a2, a3) => a1 + a2 + a3), 'undefined0undefined', 'S15.5.4.11_A1_T9'); - assert.strictEqual('ABB\u0041BABAB'.replace({ - toString() { - return '\u0041B'; - }, - }, () => { /* empty */ }), 'undefinedBABABAB', 'S15.5.4.11_A1_T10'); - if (NATIVE) { - try { - 'ABB\u0041BABAB'.replace({ - toString() { - throw new Error('insearchValue'); - }, - }, { - toString() { - throw new Error('inreplaceValue'); - }, - }); - assert.ok(false, 'S15.5.4.11_A1_T11 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'insearchValue', 'S15.5.4.11_A1_T11 #2'); - } - try { - Object('ABB\u0041BABAB').replace({ - toString() { - return {}; - }, - valueOf() { - throw new Error('insearchValue'); - }, - }, { - toString() { - throw new Error('inreplaceValue'); - }, - }); - assert.ok(false, 'S15.5.4.11_A1_T12 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'insearchValue', 'S15.5.4.11_A1_T12 #2'); - } - } - try { - 'ABB\u0041BABAB\u0031BBAA'.replace({ - toString() { - return {}; - }, - valueOf() { - throw new Error('insearchValue'); - }, - }, { - toString() { - return 1; - }, - }); - assert.ok(false, 'S15.5.4.11_A1_T13 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'insearchValue', 'S15.5.4.11_A1_T13 #2'); - } - assert.strictEqual('ABB\u0041BABAB\u0037\u0037BBAA'.replace(new RegExp('77'), 1), 'ABBABABAB\u0031BBAA', 'S15.5.4.11_A1_T14'); - instance = Object(1100.00777001); - instance.replace = String.prototype.replace; - try { - instance.replace({ - toString() { - return /77/; - }, - }, 1); - assert.ok(false, 'S15.5.4.11_A1_T15 #1 lead to throwing exception'); - } catch (error) { - assert.ok(error instanceof TypeError, 'S15.5.4.11_A1_T15 #2'); - } - instance = Object(1100.00777001); - instance.replace = String.prototype.replace; - try { - instance.replace(/77/, { - toString() { - return (a1, a2) => `${ a2 }z`; - }, - }); - assert.ok(false, 'S15.5.4.11_A1_T16 #1 lead to throwing exception'); - } catch (error) { - assert.ok(error instanceof TypeError, 'S15.5.4.11_A1_T16 #2'); - } - assert.strictEqual('asdf'.replace(RegExp('', 'g'), '1'), '1a1s1d1f1', 'S15.5.4.11_A1_T17'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/g, 'sch'), 'She sells seaschells by the seaschore.', 'S15.5.4.11_A2_T1'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/g, '$$sch'), 'She sells sea$schells by the sea$schore.', 'S15.5.4.11_A2_T2'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/g, '$&sch'), 'She sells seashschells by the seashschore.', 'S15.5.4.11_A2_T3'); - // eslint-disable-next-line max-len - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/g, '$`sch'), 'She sells seaShe sells seaschells by the seaShe sells seashells by the seaschore.', 'S15.5.4.11_A2_T4'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/g, "$'sch"), 'She sells seaells by the seashore.schells by the seaore.schore.', 'S15.5.4.11_A2_T5'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/, 'sch'), 'She sells seaschells by the seashore.', 'S15.5.4.11_A2_T6'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/, '$$sch'), 'She sells sea$schells by the seashore.', 'S15.5.4.11_A2_T7'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/, '$&sch'), 'She sells seashschells by the seashore.', 'S15.5.4.11_A2_T8'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/, '$`sch'), 'She sells seaShe sells seaschells by the seashore.', 'S15.5.4.11_A2_T9'); - assert.strictEqual('She sells seashells by the seashore.'.replace(/sh/, "$'sch"), 'She sells seaells by the seashore.schells by the seashore.', 'S15.5.4.11_A2_T10'); - assert.strictEqual('uid=31'.replace(/(uid=)(\d+)/, '$1115'), 'uid=115', 'S15.5.4.11_A3_T1'); - assert.strictEqual('uid=31'.replace(/(uid=)(\d+)/, '$11A15'), 'uid=1A15', 'S15.5.4.11_A3_T3'); - assert.strictEqual('abc12 def34'.replace(/([a-z]+)(\d+)/, (a, b, c) => c + b), '12abc def34', 'S15.5.4.11_A4_T1'); - assert.strictEqual('aaaaaaaaaa,aaaaaaaaaaaaaaa'.replace(/^(a+)\1*,\1+$/, '$1'), 'aaaaa', 'S15.5.4.11_A5_T1'); - - // https://github.com/zloirock/core-js/issues/471 - assert.strictEqual('{price} Retail'.replace(/{price}/g, '$25.00'), '$25.00 Retail'); - assert.strictEqual('a'.replace(/(.)/, '$0'), '$0'); -}; - -QUnit.test('String#replace regression', run); - -QUnit.test('RegExp#@@replace appearance', assert => { - const replace = /./[Symbol.replace]; - assert.isFunction(replace); - // assert.name(replace, '[Symbol.replace]'); - assert.arity(replace, 2); - assert.looksNative(replace); - assert.nonEnumerable(RegExp.prototype, Symbol.replace); -}); - -QUnit.test('RegExp#@@replace basic behavior', assert => { - assert.strictEqual(/([a-z]+)(\d+)/[Symbol.replace]('abc12 def34', (a, b, c) => c + b), '12abc def34'); -}); - -QUnit.test('String.replace delegates to @@replace', assert => { - const string = STRICT ? 'string' : Object('string'); - const number = STRICT ? 42 : Object(42); - const object = {}; - object[Symbol.replace] = function (a, b) { - return { a, b }; - }; - assert.strictEqual(string.replace(object, 42).a, string); - assert.strictEqual(string.replace(object, 42).b, 42); - assert.strictEqual(''.replace.call(number, object, 42).a, number); - assert.strictEqual(''.replace.call(number, object, 42).b, 42); - const regexp = /./; - regexp[Symbol.replace] = function (a, b) { - return { a, b }; - }; - assert.strictEqual(string.replace(regexp, 42).a, string); - assert.strictEqual(string.replace(regexp, 42).b, 42); - assert.strictEqual(''.replace.call(number, regexp, 42).a, number); - assert.strictEqual(''.replace.call(number, regexp, 42).b, 42); -}); - -QUnit.test('RegExp#@@replace delegates to exec', assert => { - const exec = function () { - execCalled = true; - return /./.exec.apply(this, arguments); - }; - - let execCalled = false; - let re = /[ac]/; - re.exec = exec; - assert.deepEqual(re[Symbol.replace]('abc', 'f'), 'fbc'); - assert.ok(execCalled); - assert.strictEqual(re.lastIndex, 0); - - execCalled = false; - re = /[ac]/g; - re.exec = exec; - assert.deepEqual(re[Symbol.replace]('abc', 'f'), 'fbf'); - assert.ok(execCalled); - assert.strictEqual(re.lastIndex, 0); - - re = /a/; - // Not a function, should be ignored - re.exec = 3; - assert.deepEqual(re[Symbol.replace]('abc', 'f'), 'fbc'); - - re = /a/; - // Does not return an object, should throw - re.exec = () => 3; - assert.throws(() => re[Symbol.replace]('abc', 'f')); -}); - -QUnit.test('RegExp#@@replace correctly handles substitutions', assert => { - const re = /./; - re.exec = function () { - const result = ['23', '7']; - result.groups = { '!!!': '7' }; - result.index = 1; - return result; - }; - assert.strictEqual('1234'.replace(re, '$1'), '174'); - assert.strictEqual('1234'.replace(re, '$'), '174'); - assert.strictEqual('1234'.replace(re, '$`'), '114'); - assert.strictEqual('1234'.replace(re, '$\''), '144'); - assert.strictEqual('1234'.replace(re, '$$'), '1$4'); - assert.strictEqual('1234'.replace(re, '$&'), '1234'); - assert.strictEqual('1234'.replace(re, '$x'), '1$x4'); - - let args; - assert.strictEqual('1234'.replace(re, (..._args) => { args = _args; return 'x'; }), '1x4'); - assert.deepEqual(args, ['23', '7', 1, '1234', { '!!!': '7' }]); -}); - -QUnit.test('RegExp#@@replace implementation', patchRegExp$exec(run)); diff --git a/tests/tests/es.string.search.js b/tests/tests/es.string.search.js deleted file mode 100644 index 79b0e37c9b3e..000000000000 --- a/tests/tests/es.string.search.js +++ /dev/null @@ -1,132 +0,0 @@ -import { GLOBAL, STRICT } from '../helpers/constants'; -import { patchRegExp$exec } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; - -const run = assert => { - assert.isFunction(''.search); - assert.arity(''.search, 1); - assert.name(''.search, 'search'); - assert.looksNative(''.search); - assert.nonEnumerable(String.prototype, 'search'); - let instance = Object(true); - instance.search = String.prototype.search; - assert.strictEqual(instance.search(true), 0, 'S15.5.4.12_A1_T1'); - instance = Object(false); - instance.search = String.prototype.search; - assert.strictEqual(instance.search(false), 0, 'S15.5.4.12_A1_T2'); - assert.strictEqual(''.search(), 0, 'S15.5.4.12_A1_T4 #1'); - assert.strictEqual('--undefined--'.search(), 0, 'S15.5.4.12_A1_T4 #2'); - assert.strictEqual('gnulluna'.search(null), 1, 'S15.5.4.12_A1_T5'); - assert.strictEqual(Object('undefined').search(undefined), 0, 'S15.5.4.12_A1_T6'); - assert.strictEqual('undefined'.search(undefined), 0, 'S15.5.4.12_A1_T7'); - assert.strictEqual(String({ - toString() { /* empty */ }, - }).search(undefined), 0, 'S15.5.4.12_A1_T8'); - assert.strictEqual('ssABB\u0041BABAB'.search({ - toString() { - return '\u0041B'; - }, - }), 2, 'S15.5.4.12_A1_T10'); - try { - 'ABB\u0041BABAB'.search({ - toString() { - throw new Error('intostr'); - }, - }); - assert.ok(false, 'S15.5.4.12_A1_T11 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'intostr', 'S15.5.4.12_A1_T11 #2'); - } - try { - Object('ABB\u0041BABAB').search({ - toString() { - return {}; - }, - valueOf() { - throw new Error('intostr'); - }, - }); - assert.ok(false, 'S15.5.4.12_A1_T12 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'intostr', 'S15.5.4.12_A1_T12 #2'); - } - assert.strictEqual('ABB\u0041B\u0031ABAB\u0031BBAA'.search({ - toString() { - return {}; - }, - valueOf() { - return 1; - }, - }), 5, 'S15.5.4.12_A1_T13'); - assert.strictEqual('ABB\u0041BABAB\u0037\u0037BBAA'.search(RegExp('77')), 9, 'S15.5.4.12_A1_T14'); - assert.strictEqual(Object('test string').search('string'), 5, 'S15.5.4.12_A2_T1'); - assert.strictEqual(Object('test string').search('String'), -1, 'S15.5.4.12_A2_T2'); - assert.strictEqual(Object('test string').search(/string/i), 5, 'S15.5.4.12_A2_T3'); - assert.strictEqual(Object('test string').search(/Four/), -1, 'S15.5.4.12_A2_T4'); - assert.strictEqual(Object('one two three four five').search(/four/), 14, 'S15.5.4.12_A2_T5'); - assert.strictEqual(Object('test string').search('notexist'), -1, 'S15.5.4.12_A2_T6'); - assert.strictEqual(Object('test string probe').search('string pro'), 5, 'S15.5.4.12_A2_T7'); - let string = Object('power of the power of the power of the power of the power of the power of the great sword'); - assert.strictEqual(string.search(/the/), string.search(/the/g), 'S15.5.4.12_A3_T1'); - string = Object('power \u006F\u0066 the power of the power \u006F\u0066 the power of the power \u006F\u0066 the power of the great sword'); - assert.strictEqual(string.search(/of/), string.search(/of/g), 'S15.5.4.12_A3_T2'); -}; - -QUnit.test('String#search regression', run); - -QUnit.test('RegExp#@@search appearance', assert => { - const search = /./[Symbol.search]; - assert.isFunction(search); - // assert.name(search, '[Symbol.search]'); - assert.arity(search, 1); - assert.looksNative(search); - assert.nonEnumerable(RegExp.prototype, Symbol.search); -}); - -QUnit.test('RegExp#@@search basic behavior', assert => { - assert.strictEqual(/four/[Symbol.search]('one two three four five'), 14); - assert.strictEqual(/Four/[Symbol.search]('one two three four five'), -1); -}); - -QUnit.test('String#search delegates to @@search', assert => { - const string = STRICT ? 'string' : Object('string'); - const number = STRICT ? 42 : Object(42); - const object = {}; - object[Symbol.search] = function (it) { - return { value: it }; - }; - assert.strictEqual(string.search(object).value, string); - assert.strictEqual(''.search.call(number, object).value, number); - const regexp = /./; - regexp[Symbol.search] = function (it) { - return { value: it }; - }; - assert.strictEqual(string.search(regexp).value, string); - assert.strictEqual(''.search.call(number, regexp).value, number); -}); - -QUnit.test('RegExp#@@search delegates to exec', assert => { - let execCalled = false; - let re = /b/; - re.lastIndex = 7; - re.exec = function () { - execCalled = true; - return /./.exec.apply(this, arguments); - }; - assert.deepEqual(re[Symbol.search]('abc'), 1); - assert.ok(execCalled); - assert.strictEqual(re.lastIndex, 7); - - re = /b/; - // Not a function, should be ignored - re.exec = 3; - assert.deepEqual(re[Symbol.search]('abc'), 1); - - re = /b/; - // Does not return an object, should throw - re.exec = () => 3; - assert.throws(() => re[Symbol.search]('abc')); -}); - -QUnit.test('RegExp#@@search implementation', patchRegExp$exec(run)); diff --git a/tests/tests/es.string.small.js b/tests/tests/es.string.small.js deleted file mode 100644 index ed4de7b27294..000000000000 --- a/tests/tests/es.string.small.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#small', assert => { - const { small } = String.prototype; - assert.isFunction(small); - assert.arity(small, 0); - assert.name(small, 'small'); - assert.looksNative(small); - assert.nonEnumerable(String.prototype, 'small'); - assert.same('a'.small(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.split.js b/tests/tests/es.string.split.js deleted file mode 100644 index bcb12cb6d209..000000000000 --- a/tests/tests/es.string.split.js +++ /dev/null @@ -1,780 +0,0 @@ -/* eslint-disable optimize-regex/optimize-regex */ - -import { GLOBAL, NATIVE, STRICT } from '../helpers/constants'; -import { patchRegExp$exec } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; - -const run = assert => { - assert.isFunction(''.split); - assert.arity(''.split, 2); - assert.name(''.split, 'split'); - assert.looksNative(''.split); - assert.nonEnumerable(String.prototype, 'split'); - assert.arrayEqual('ab'.split(), ['ab'], 'If "separator" is undefined must return Array with one String - "this" string'); - assert.arrayEqual('ab'.split(undefined), ['ab'], 'If "separator" is undefined must return Array with one String - "this" string'); - assert.arrayEqual('ab'.split(undefined, 0), [], 'If "separator" is undefined and "limit" set to 0 must return Array[]'); - assert.arrayEqual(''.split(), [''], "''.split() results in ['']"); - assert.arrayEqual(''.split(/./), [''], "''.split(/./) results in ['']"); - assert.arrayEqual(''.split(/.?/), [], "''.split(/.?/) results in []"); - assert.arrayEqual(''.split(/.??/), [], "''.split(/.??/) results in []"); - assert.arrayEqual('ab'.split(/a*/), ['', 'b'], "'ab'.split(/a*/) results in ['', 'b']"); - assert.arrayEqual('ab'.split(/a*?/), ['a', 'b'], "'ab'.split(/a*?/) results in ['a', 'b']"); - assert.arrayEqual('ab'.split(/(?:ab)/), ['', ''], "'ab'.split(/(?:ab)/) results in ['', '']"); - assert.arrayEqual('ab'.split(/(?:ab)*/), ['', ''], "'ab'.split(/(?:ab)*/) results in ['', '']"); - assert.arrayEqual('ab'.split(/(?:ab)*?/), ['a', 'b'], "'ab'.split(/(?:ab)*?/) results in ['a', 'b']"); - assert.arrayEqual('test'.split(''), ['t', 'e', 's', 't'], "'test'.split('') results in ['t', 'e', 's', 't']"); - assert.arrayEqual('test'.split(), ['test'], "'test'.split() results in ['test']"); - assert.arrayEqual('111'.split(1), ['', '', '', ''], "'111'.split(1) results in ['', '', '', '']"); - assert.arrayEqual('test'.split(/(?:)/, 2), ['t', 'e'], "'test'.split(/(?:)/, 2) results in ['t', 'e']"); - assert.arrayEqual('test'.split(/(?:)/, -1), ['t', 'e', 's', 't'], "'test'.split(/(?:)/, -1) results in ['t', 'e', 's', 't']"); - assert.arrayEqual('test'.split(/(?:)/, undefined), ['t', 'e', 's', 't'], "'test'.split(/(?:)/, undefined) results in ['t', 'e', 's', 't']"); - assert.arrayEqual('test'.split(/(?:)/, null), [], "'test'.split(/(?:)/, null) results in []"); - assert.arrayEqual('test'.split(/(?:)/, NaN), [], "'test'.split(/(?:)/, NaN) results in []"); - assert.arrayEqual('test'.split(/(?:)/, true), ['t'], "'test'.split(/(?:)/, true) results in ['t']"); - assert.arrayEqual('test'.split(/(?:)/, '2'), ['t', 'e'], "'test'.split(/(?:)/, '2') results in ['t', 'e']"); - assert.arrayEqual('test'.split(/(?:)/, 'two'), [], "'test'.split(/(?:)/, 'two') results in []"); - assert.arrayEqual('a'.split(/-/), ['a'], "'a'.split(/-/) results in ['a']"); - assert.arrayEqual('a'.split(/-?/), ['a'], "'a'.split(/-?/) results in ['a']"); - assert.arrayEqual('a'.split(/-??/), ['a'], "'a'.split(/-??/) results in ['a']"); - assert.arrayEqual('a'.split(/a/), ['', ''], "'a'.split(/a/) results in ['', '']"); - assert.arrayEqual('a'.split(/a?/), ['', ''], "'a'.split(/a?/) results in ['', '']"); - assert.arrayEqual('a'.split(/a??/), ['a'], "'a'.split(/a??/) results in ['a']"); - assert.arrayEqual('ab'.split(/-/), ['ab'], "'ab'.split(/-/) results in ['ab']"); - assert.arrayEqual('ab'.split(/-?/), ['a', 'b'], "'ab'.split(/-?/) results in ['a', 'b']"); - assert.arrayEqual('ab'.split(/-??/), ['a', 'b'], "'ab'.split(/-??/) results in ['a', 'b']"); - assert.arrayEqual('a-b'.split(/-/), ['a', 'b'], "'a-b'.split(/-/) results in ['a', 'b']"); - assert.arrayEqual('a-b'.split(/-?/), ['a', 'b'], "'a-b'.split(/-?/) results in ['a', 'b']"); - assert.arrayEqual('a-b'.split(/-??/), ['a', '-', 'b'], "'a-b'.split(/-??/) results in ['a', '-', 'b']"); - assert.arrayEqual('a--b'.split(/-/), ['a', '', 'b'], "'a--b'.split(/-/) results in ['a', '', 'b']"); - assert.arrayEqual('a--b'.split(/-?/), ['a', '', 'b'], "'a--b'.split(/-?/) results in ['a', '', 'b']"); - assert.arrayEqual('a--b'.split(/-??/), ['a', '-', '-', 'b'], "'a--b'.split(/-??/) results in ['a', '-', '-', 'b']"); - assert.arrayEqual(''.split(/()()/), [], "''.split(/()()/) results in []"); - assert.arrayEqual('.'.split(/()()/), ['.'], "'.'.split(/()()/) results in ['.']"); - assert.arrayEqual('.'.split(/(.?)(.?)/), ['', '.', '', ''], "'.'.split(/(.?)(.?)/) results in ['', '.', '', '']"); - assert.arrayEqual('.'.split(/(.??)(.??)/), ['.'], "'.'.split(/(.??)(.??)/) results in ['.']"); - assert.arrayEqual('.'.split(/(.)?(.)?/), ['', '.', undefined, ''], "'.'.split(/(.)?(.)?/) results in ['', '.', undefined, '']"); - // eslint-disable-next-line max-len - assert.arrayEqual('Aboldandcoded'.split(/<(\/)?([^<>]+)>/), ['A', undefined, 'B', 'bold', '/', 'B', 'and', undefined, 'CODE', 'coded', '/', 'CODE', ''], "'Aboldandcoded'.split(/<(\\/)?([^<>]+)>/) results in ['A', undefined, 'B', 'bold', '/', 'B', 'and', undefined, 'CODE', 'coded', '/', 'CODE', '']"); - assert.arrayEqual('tesst'.split(/(s)*/), ['t', undefined, 'e', 's', 't'], "'tesst'.split(/(s)*/) results in ['t', undefined, 'e', 's', 't']"); - // eslint-disable-next-line max-len - assert.arrayEqual('tesst'.split(/(s)*?/), ['t', undefined, 'e', undefined, 's', undefined, 's', undefined, 't'], "'tesst'.split(/(s)*?/) results in ['t', undefined, 'e', undefined, 's', undefined, 's', undefined, 't']"); - assert.arrayEqual('tesst'.split(/(s*)/), ['t', '', 'e', 'ss', 't'], "'tesst'.split(/(s*)/) results in ['t', '', 'e', 'ss', 't']"); - assert.arrayEqual('tesst'.split(/(s*?)/), ['t', '', 'e', '', 's', '', 's', '', 't'], "'tesst'.split(/(s*?)/) results in ['t', '', 'e', '', 's', '', 's', '', 't']"); - assert.arrayEqual('tesst'.split(/(?:s)*/), ['t', 'e', 't'], "'tesst'.split(/(?:s)*/) results in ['t', 'e', 't']"); - assert.arrayEqual('tesst'.split(/(?=s+)/), ['te', 's', 'st'], "'tesst'.split(/(?=s+)/) results in ['te', 's', 'st']"); - assert.arrayEqual('test'.split('t'), ['', 'es', ''], "'test'.split('t') results in ['', 'es', '']"); - assert.arrayEqual('test'.split('es'), ['t', 't'], "'test'.split('es') results in ['t', 't']"); - assert.arrayEqual('test'.split(/t/), ['', 'es', ''], "'test'.split(/t/) results in ['', 'es', '']"); - assert.arrayEqual('test'.split(/es/), ['t', 't'], "'test'.split(/es/) results in ['t', 't']"); - assert.arrayEqual('test'.split(/(t)/), ['', 't', 'es', 't', ''], "'test'.split(/(t)/) results in ['', 't', 'es', 't', '']"); - assert.arrayEqual('test'.split(/(es)/), ['t', 'es', 't'], "'test'.split(/(es)/) results in ['t', 'es', 't']"); - assert.arrayEqual('test'.split(/(t)(e)(s)(t)/), ['', 't', 'e', 's', 't', ''], "'test'.split(/(t)(e)(s)(t)/) results in ['', 't', 'e', 's', 't', '']"); - assert.arrayEqual('.'.split(/(((.((.??)))))/), ['', '.', '.', '.', '', '', ''], "'.'.split(/(((.((.??)))))/) results in ['', '.', '.', '.', '', '', '']"); - assert.arrayEqual('.'.split(/(((((.??)))))/), ['.'], "'.'.split(/(((((.??)))))/) results in ['.']"); - assert.arrayEqual('a b c d'.split(/ /, -(2 ** 32) + 1), ['a'], "'a b c d'.split(/ /, -(2 ** 32) + 1) results in ['a']"); - assert.arrayEqual('a b c d'.split(/ /, 2 ** 32 + 1), ['a'], "'a b c d'.split(/ /, 2 ** 32 + 1) results in ['a']"); - assert.arrayEqual('a b c d'.split(/ /, Infinity), [], "'a b c d'.split(/ /, Infinity) results in []"); - let instance = Object(true); - instance.split = String.prototype.split; - let split = instance.split(true, false); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T1 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T1 #2'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A1_T1 #3'); - instance = Object(false); - instance.split = String.prototype.split; - split = instance.split(false, 0, null); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T2 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T2 #2'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A1_T2 #3'); - split = ''.split(); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T4 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T4 #2'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A1_T4 #3'); - assert.strictEqual(split[0], '', 'S15.5.4.14_A1_T4 #4'); - split = 'gnulluna'.split(null); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T5 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T5 #2'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A1_T5 #3'); - assert.strictEqual(split[0], 'g', 'S15.5.4.14_A1_T5 #4'); - assert.strictEqual(split[1], 'una', 'S15.5.4.14_A1_T5 #5'); - if (NATIVE) { - split = Object('1undefined').split(undefined); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T6 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T6 #2'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A1_T6 #3'); - assert.strictEqual(split[0], '1undefined', 'S15.5.4.14_A1_T6 #4'); - split = 'undefinedd'.split(undefined); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T7 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T7 #2'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A1_T7 #3'); - assert.strictEqual(split[0], 'undefinedd', 'S15.5.4.14_A1_T7 #4'); - split = String({ - toString() { /* empty */ }, - }).split(undefined); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T8 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T8 #2'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A1_T8 #3'); - assert.strictEqual(split[0], 'undefined', 'S15.5.4.14_A1_T8 #4'); - } - split = new String({ - valueOf() { /* empty */ }, - toString: undefined, - }).split(() => { /* empty */ }); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T9 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T9 #2'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A1_T9 #3'); - assert.strictEqual(split[0], 'undefined', 'S15.5.4.14_A1_T9 #4'); - split = 'ABB\u0041BABAB'.split({ - toString() { - return '\u0042B'; - }, - }, { - valueOf() { - return true; - }, - }); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T10 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T10 #2'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A1_T10 #3'); - assert.strictEqual(split[0], 'A', 'S15.5.4.14_A1_T10 #4'); - try { - 'ABB\u0041BABAB'.split({ - toString() { - return '\u0041B'; - }, - }, { - valueOf() { - throw new Error('intointeger'); - }, - }); - assert.ok(false, 'S15.5.4.14_A1_T11 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'intointeger', 'S15.5.4.14_A1_T11 #2'); - } - if (NATIVE) { - try { - new String('ABB\u0041BABAB').split({ - toString() { - return '\u0041B'; - }, - }, { - valueOf() { - return {}; - }, - toString() { - throw new Error('intointeger'); - }, - }); - assert.ok(false, 'S15.5.4.14_A1_T12 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'intointeger', 'S15.5.4.14_A1_T12 #2'); - } - } - split = 'ABB\u0041BABAB\u0042cc^^\u0042Bvv%%B\u0042xxx'.split({ - toString() { - return '\u0042\u0042'; - }, - }, { - valueOf() { - return {}; - }, - toString() { - return '2'; - }, - }); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T13 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T13 #2'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A1_T13 #3'); - assert.strictEqual(split[0], 'A', 'S15.5.4.14_A1_T13 #4'); - assert.strictEqual(split[1], 'ABABA', 'S15.5.4.14_A1_T13 #5'); - if (NATIVE) { - try { - instance = Object(10001.10001); - instance.split = String.prototype.split; - instance.split({ - toString() { - throw new Error('intostr'); - }, - }, { - valueOf() { - throw new Error('intoint'); - }, - }); - assert.ok(false, 'S15.5.4.14_A1_T14 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'intoint', 'S15.5.4.14_A1_T14 #2'); - } - try { - class F { - costructor(value) { - this.value = value; - } - valueOf() { - return `${ this.value }`; - } - toString() { - return new Number(); - } - } - F.prototype.split = String.prototype.split; - new F().split({ - toString() { - return {}; - }, - valueOf() { - throw new Error('intostr'); - }, - }, { - valueOf() { - throw new Error('intoint'); - }, - }); - assert.ok(false, 'S15.5.4.14_A1_T15 #1 lead to throwing exception'); - } catch (error) { - assert.strictEqual(error.message, 'intoint', 'S15.5.4.14_A1_T15 #2'); - } - } - try { - String.prototype.split.call(6776767677.006771122677555, { - toString() { - return /77/g; - }, - }); - assert.ok(false, 'S15.5.4.14_A1_T16 #1 lead to throwing exception'); - } catch (error) { - assert.ok(error instanceof TypeError, 'S15.5.4.14_A1_T16 #2'); - } - split = String.prototype.split.call(6776767677.006771122677555, /77/g); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T17 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T17 #2'); - assert.strictEqual(split.length, 4, 'S15.5.4.14_A1_T17 #3'); - assert.strictEqual(split[0], '6', 'S15.5.4.14_A1_T17 #4'); - assert.strictEqual(split[1], '67676', 'S15.5.4.14_A1_T17 #5'); - assert.strictEqual(split[2], '.006', 'S15.5.4.14_A1_T17 #6'); - assert.strictEqual(split[3], '1', 'S15.5.4.14_A1_T17 #7'); - split = String.prototype.split.call(6776767677.006771122677555, /00/, 1); - assert.strictEqual(typeof split, 'object', 'S15.5.4.14_A1_T18 #1'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A1_T18 #2'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A1_T18 #3'); - assert.strictEqual(split[0], '6776767677.', 'S15.5.4.14_A1_T18 #4'); - split = Object('one,two,three,four,five').split(','); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T1 #1'); - assert.strictEqual(split.length, 5, 'S15.5.4.14_A2_T1 #2'); - assert.strictEqual(split[0], 'one', 'S15.5.4.14_A2_T1 #3'); - assert.strictEqual(split[1], 'two', 'S15.5.4.14_A2_T1 #4'); - assert.strictEqual(split[2], 'three', 'S15.5.4.14_A2_T1 #5'); - assert.strictEqual(split[3], 'four', 'S15.5.4.14_A2_T1 #6'); - assert.strictEqual(split[4], 'five', 'S15.5.4.14_A2_T1 #7'); - split = Object('one two three four five').split(' '); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T2 #1'); - assert.strictEqual(split.length, 5, 'S15.5.4.14_A2_T2 #2'); - assert.strictEqual(split[0], 'one', 'S15.5.4.14_A2_T2 #3'); - assert.strictEqual(split[1], 'two', 'S15.5.4.14_A2_T2 #4'); - assert.strictEqual(split[2], 'three', 'S15.5.4.14_A2_T2 #5'); - assert.strictEqual(split[3], 'four', 'S15.5.4.14_A2_T2 #6'); - assert.strictEqual(split[4], 'five', 'S15.5.4.14_A2_T2 #7'); - split = Object('one two three four five').split(RegExp(' '), 2); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T3 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A2_T3 #2'); - assert.strictEqual(split[0], 'one', 'S15.5.4.14_A2_T3 #3'); - assert.strictEqual(split[1], 'two', 'S15.5.4.14_A2_T3 #4'); - split = Object('one two three').split(''); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T4 #1'); - assert.strictEqual(split.length, 'one two three'.length, 'S15.5.4.14_A2_T4 #2'); - assert.strictEqual(split[0], 'o', 'S15.5.4.14_A2_T4 #3'); - assert.strictEqual(split[1], 'n', 'S15.5.4.14_A2_T4 #4'); - assert.strictEqual(split[11], 'e', 'S15.5.4.14_A2_T4 #5'); - assert.strictEqual(split[12], 'e', 'S15.5.4.14_A2_T4 #6'); - split = Object('one-1,two-2,four-4').split(/,/); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T5 #1'); - assert.strictEqual(split.length, 3, 'S15.5.4.14_A2_T5 #2'); - assert.strictEqual(split[0], 'one-1', 'S15.5.4.14_A2_T5 #3'); - assert.strictEqual(split[1], 'two-2', 'S15.5.4.14_A2_T5 #4'); - assert.strictEqual(split[2], 'four-4', 'S15.5.4.14_A2_T5 #5'); - let string = Object('one-1 two-2 three-3'); - split = string.split(''); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T6 #1'); - assert.strictEqual(split.length, string.length, 'S15.5.4.14_A2_T6 #2'); - for (let i = 0, { length } = split; i < length; ++i) { - assert.strictEqual(split[i], string.charAt(i), `S15.5.4.14_A2_T6 #${ i + 3 }`); - } - if (NATIVE) { - string = 'thisundefinedisundefinedaundefinedstringundefinedobject'; - split = string.split(undefined); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T7 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T7 #2'); - assert.strictEqual(split[0], string, 'S15.5.4.14_A2_T7 #3'); - } - string = 'thisnullisnullanullstringnullobject'; - let expected = ['this', 'is', 'a', 'string', 'object']; - split = string.split(null); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T8 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T8 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T8 #${ i + 3 }`); - } - string = 'thistrueistrueatruestringtrueobject'; - expected = ['this', 'is', 'a', 'string', 'object']; - split = string.split(true); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T9 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T9 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T9 #${ i + 3 }`); - } - string = 'this123is123a123string123object'; - expected = ['this', 'is', 'a', 'string', 'object']; - split = string.split(123); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T10 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T10 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T10 #${ i + 3 }`); - } - split = Object('one-1,two-2,four-4').split(':'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T11 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T11 #2'); - assert.strictEqual(split[0], 'one-1,two-2,four-4', 'S15.5.4.14_A2_T11 #3'); - split = Object('one-1 two-2 four-4').split('r-42'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T12 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T12 #2'); - assert.strictEqual(split[0], 'one-1 two-2 four-4', 'S15.5.4.14_A2_T12 #3'); - split = Object('one-1 two-2 four-4').split('-4'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T13 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A2_T13 #2'); - assert.strictEqual(split[0], 'one-1 two-2 four', 'S15.5.4.14_A2_T13 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A2_T13 #4'); - split = Object('one-1 two-2 four-4').split('on'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T14 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A2_T14 #2'); - assert.strictEqual(split[0], '', 'S15.5.4.14_A2_T14 #3'); - assert.strictEqual(split[1], 'e-1 two-2 four-4', 'S15.5.4.14_A2_T14 #4'); - split = new String().split(''); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T15 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A2_T15 #2'); - assert.strictEqual(split[0], undefined, 'S15.5.4.14_A2_T15 #3'); - split = new String().split(' '); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T16 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T16 #2'); - assert.strictEqual(split[0], '', 'S15.5.4.14_A2_T16 #3'); - split = Object(' ').split(''); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T18 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T18 #2'); - assert.strictEqual(split[0], ' ', 'S15.5.4.14_A2_T18 #3'); - split = Object(' ').split(' '); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T19 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A2_T19 #2'); - assert.strictEqual(split[0], '', 'S15.5.4.14_A2_T19 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A2_T19 #4'); - split = ''.split('x'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T19 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T19 #2'); - assert.strictEqual(split[0], '', 'S15.5.4.14_A2_T19 #3'); - string = Object('one-1 two-2 three-3'); - split = string.split(new RegExp()); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T20 #1'); - assert.strictEqual(split.length, string.length, 'S15.5.4.14_A2_T20 #2'); - for (let i = 0, { length } = split; i < length; ++i) { - assert.strictEqual(split[i], string.charAt(i), `S15.5.4.14_A2_T20 #${ i + 3 }`); - } - split = Object('hello').split('ll'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T21 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A2_T21 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A2_T21 #3'); - assert.strictEqual(split[1], 'o', 'S15.5.4.14_A2_T21 #4'); - split = Object('hello').split('l'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T22 #1'); - assert.strictEqual(split.length, 3, 'S15.5.4.14_A2_T22 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A2_T22 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A2_T22 #4'); - assert.strictEqual(split[2], 'o', 'S15.5.4.14_A2_T22 #5'); - split = Object('hello').split('x'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T23 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T23 #2'); - assert.strictEqual(split[0], 'hello', 'S15.5.4.14_A2_T23 #3'); - split = Object('hello').split('h'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T24 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A2_T24 #2'); - assert.strictEqual(split[0], '', 'S15.5.4.14_A2_T24 #3'); - assert.strictEqual(split[1], 'ello', 'S15.5.4.14_A2_T24 #4'); - split = Object('hello').split('o'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T25 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A2_T25 #2'); - assert.strictEqual(split[0], 'hell', 'S15.5.4.14_A2_T25 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A2_T25 #4'); - split = Object('hello').split('hello'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T26 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A2_T26 #2'); - assert.strictEqual(split[0], '', 'S15.5.4.14_A2_T26 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A2_T26 #4'); - split = Object('hello').split(undefined); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T27 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T27 #2'); - assert.strictEqual(split[0], 'hello', 'S15.5.4.14_A2_T27 #3'); - split = Object('hello').split('hellothere'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T28 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T28 #2'); - assert.strictEqual(split[0], 'hello', 'S15.5.4.14_A2_T28 #3'); - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1); - expected = ['', '00', '', '', '', '22', '33', '44', '60']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T29 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T29 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T29 #${ i + 3 }`); - } - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, 1); - expected = ['']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T30 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T30 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T30 #${ i + 3 }`); - } - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, 2); - expected = ['', '00']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T31 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T31 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T31 #${ i + 3 }`); - } - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, 0); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T32 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A2_T32 #2'); - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, 100); - expected = ['', '00', '', '', '', '22', '33', '44', '60']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T33 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T33 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T33 #${ i + 3 }`); - } - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, undefined); - expected = ['', '00', '', '', '', '22', '33', '44', '60']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T34 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T34 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T34 #${ i + 3 }`); - } - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, 2 ** 32 - 1); - expected = ['', '00', '', '', '', '22', '33', '44', '60']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T35 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T35 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T35 #${ i + 3 }`); - } - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, 'boo'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T36 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A2_T36 #2'); - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, -(2 ** 32) + 1); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T37 #1'); - assert.arrayEqual(split, [''], 'S15.5.4.14_A2_T37 #2'); - instance = Object(100111122133144155); - instance.split = String.prototype.split; - split = instance.split(1, NaN); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T38 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A2_T38 #2'); - instance = Object('hello').split('l', 0); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T39 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A2_T39 #2'); - split = Object('hello').split('l', 1); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T40 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A2_T40 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A2_T40 #3'); - split = Object('hello').split('l', 2); - expected = ['he', '']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T41 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T41 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T41 #${ i + 3 }`); - } - split = Object('hello').split('l', 3); - expected = ['he', '', 'o']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T42 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T42 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T42 #${ i + 3 }`); - } - split = Object('hello').split('l', 4); - expected = ['he', '', 'o']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A2_T43 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A2_T43 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A2_T43 #${ i + 3 }`); - } - split = Object('one,two,three,four,five').split(); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T1 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T1 #2'); - assert.strictEqual(split[0], 'one,two,three,four,five', 'S15.5.4.14_A3_T1 #3'); - split = String.prototype.split.call({}); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T2 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T2 #2'); - assert.strictEqual(split[0], '[object Object]', 'S15.5.4.14_A3_T2 #3'); - split = String.prototype.split.call({ - toString() { - return 'function(){}'; - }, - }); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T3 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T3 #2'); - assert.strictEqual(split[0], 'function(){}', 'S15.5.4.14_A3_T3 #3'); - split = String.prototype.split.call(Object(NaN)); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T4 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T4 #2'); - assert.strictEqual(split[0], 'NaN', 'S15.5.4.14_A3_T4 #3'); - split = String.prototype.split.call(Object(-1234567890)); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T5 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T5 #2'); - assert.strictEqual(split[0], '-1234567890', 'S15.5.4.14_A3_T5 #3'); - instance = Object(-1e21); - split = String.prototype.split.call(instance); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T6 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T6 #2'); - assert.strictEqual(split[0], instance.toString(), 'S15.5.4.14_A3_T6 #3'); - split = String.prototype.split.call(Math); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T7 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T7 #2'); - assert.strictEqual(split[0], '[object Math]', 'S15.5.4.14_A3_T7 #3'); - split = String.prototype.split.call([1, 2, 3, 4, 5]); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T8 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T8 #2'); - assert.strictEqual(split[0], '1,2,3,4,5', 'S15.5.4.14_A3_T8 #3'); - split = String.prototype.split.call(Object(false)); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T9 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T9 #2'); - assert.strictEqual(split[0], 'false', 'S15.5.4.14_A3_T9 #3'); - split = String.prototype.split.call(new String()); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T10 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T10 #2'); - assert.strictEqual(split[0], '', 'S15.5.4.14_A3_T10 #3'); - split = String.prototype.split.call(Object(' ')); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A3_T11 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A3_T11 #2'); - assert.strictEqual(split[0], ' ', 'S15.5.4.14_A3_T11 #3'); - if (NATIVE) { - split = Object('hello').split(/l/); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T1 #1'); - assert.strictEqual(split.length, 3, 'S15.5.4.14_A4_T1 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A4_T1 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A4_T1 #4'); - assert.strictEqual(split[2], 'o', 'S15.5.4.14_A4_T1 #5'); - } - split = Object('hello').split(/l/, 0); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T2 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A4_T2 #2'); - split = Object('hello').split(/l/, 1); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T3 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A4_T3 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A4_T3 #3'); - if (NATIVE) { - split = Object('hello').split(/l/, 2); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T4 #1'); - assert.strictEqual(split.length, 2, 'S15.5.4.14_A4_T4 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A4_T4 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A4_T4 #4'); - split = Object('hello').split(/l/, 3); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T5 #1'); - assert.strictEqual(split.length, 3, 'S15.5.4.14_A4_T5 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A4_T5 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A4_T5 #4'); - assert.strictEqual(split[2], 'o', 'S15.5.4.14_A4_T5 #5'); - split = Object('hello').split(/l/, 4); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T6 #1'); - assert.strictEqual(split.length, 3, 'S15.5.4.14_A4_T6 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A4_T6 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A4_T6 #4'); - assert.strictEqual(split[2], 'o', 'S15.5.4.14_A4_T6 #5'); - split = Object('hello').split(/l/, undefined); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T7 #1'); - assert.strictEqual(split.length, 3, 'S15.5.4.14_A4_T7 #2'); - assert.strictEqual(split[0], 'he', 'S15.5.4.14_A4_T7 #3'); - assert.strictEqual(split[1], '', 'S15.5.4.14_A4_T7 #4'); - assert.strictEqual(split[2], 'o', 'S15.5.4.14_A4_T7 #5'); - } - split = Object('hello').split(/l/, 'hi'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T8 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A4_T8 #2'); - split = Object('hello').split(new RegExp()); - expected = ['h', 'e', 'l', 'l', 'o']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T10 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T10 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T10 #${ i + 3 }`); - } - split = Object('hello').split(new RegExp(), 0); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T11 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A4_T11 #2'); - split = Object('hello').split(new RegExp(), 1); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T12 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A4_T12 #2'); - assert.strictEqual(split[0], 'h', 'S15.5.4.14_A4_T12 #3'); - split = Object('hello').split(new RegExp(), 2); - expected = ['h', 'e']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T13 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T13 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T13 #${ i + 3 }`); - } - split = Object('hello').split(new RegExp(), 3); - expected = ['h', 'e', 'l']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T14 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T14 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T14 #${ i + 3 }`); - } - split = Object('hello').split(new RegExp(), 4); - expected = ['h', 'e', 'l', 'l']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T15 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T15 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T15 #${ i + 3 }`); - } - split = Object('hello').split(new RegExp(), undefined); - expected = ['h', 'e', 'l', 'l', 'o']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T16 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T16 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T16 #${ i + 3 }`); - } - split = Object('hello').split(new RegExp(), 'hi'); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T18 #1'); - assert.strictEqual(split.length, 0, 'S15.5.4.14_A4_T18 #2'); - split = Object('a b c de f').split(/\s/); - expected = ['a', 'b', 'c', 'de', 'f']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T19 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T19 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T19 #${ i + 3 }`); - } - split = Object('a b c de f').split(/\s/, 3); - expected = ['a', 'b', 'c']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T20 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T20 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T20 #${ i + 3 }`); - } - split = Object('a b c de f').split(/X/); - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T21 #1'); - assert.strictEqual(split.length, 1, 'S15.5.4.14_A4_T21 #2'); - assert.strictEqual(split[0], 'a b c de f', 'S15.5.4.14_A4_T21 #3'); - split = Object('dfe23iu 34 =+65--').split(/\d+/); - expected = ['dfe', 'iu ', ' =+', '--']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T22 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T22 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T22 #${ i + 3 }`); - } - if (NATIVE) { - split = Object('abc').split(/[a-z]/); - expected = ['', '', '', '']; - assert.strictEqual(split.constructor, Array, 'S15.5.4.14_A4_T24 #1'); - assert.strictEqual(split.length, expected.length, 'S15.5.4.14_A4_T24 #2'); - for (let i = 0, { length } = expected; i < length; ++i) { - assert.strictEqual(expected[i], split[i], `S15.5.4.14_A4_T24 #${ i + 3 }`); - } - } -}; - -QUnit.test('String#split regression', run); - -QUnit.test('RegExp#@@split appearance', assert => { - const split = /./[Symbol.split]; - assert.isFunction(split); - // assert.name(split, '[Symbol.split]'); - assert.arity(split, 2); - assert.looksNative(split); - assert.nonEnumerable(RegExp.prototype, Symbol.split); -}); - -QUnit.test('RegExp#@@split basic behavior', assert => { - assert.strictEqual(/\s/[Symbol.split]('a b c de f').length, 5); - assert.strictEqual(/\s/[Symbol.split]('a b c de f', undefined).length, 5); - assert.strictEqual(/\s/[Symbol.split]('a b c de f', 1).length, 1); - assert.strictEqual(/\s/[Symbol.split]('a b c de f', 10).length, 5); -}); - -QUnit.test('String#split delegates to @@split', assert => { - const string = STRICT ? 'string' : Object('string'); - const number = STRICT ? 42 : Object(42); - const object = {}; - object[Symbol.split] = function (a, b) { - return { a, b }; - }; - assert.strictEqual(string.split(object, 42).a, string); - assert.strictEqual(string.split(object, 42).b, 42); - assert.strictEqual(''.split.call(number, object, 42).a, number); - assert.strictEqual(''.split.call(number, object, 42).b, 42); - const regexp = /./; - regexp[Symbol.split] = function (a, b) { - return { a, b }; - }; - assert.strictEqual(string.split(regexp, 42).a, string); - assert.strictEqual(string.split(regexp, 42).b, 42); - assert.strictEqual(''.split.call(number, regexp, 42).a, number); - assert.strictEqual(''.split.call(number, regexp, 42).b, 42); -}); - -QUnit.test('RegExp#@@split delegates to exec', assert => { - let execCalled = false; - let speciesCalled = false; - let execSpeciesCalled = false; - const re = /[24]/; - re.exec = function () { - execCalled = true; - return /./.exec.apply(this, arguments); - }; - re.constructor = { - // eslint-disable-next-line object-shorthand - [Symbol.species]: function (source, flags) { - const re2 = new RegExp(source, flags); - speciesCalled = true; - re2.exec = function () { - execSpeciesCalled = true; - return /./.exec.apply(this, arguments); - }; - return re2; - }, - }; - assert.deepEqual(re[Symbol.split]('123451234'), ['1', '3', '51', '3', '']); - assert.ok(!execCalled); - assert.ok(speciesCalled); - assert.ok(execSpeciesCalled); - - re.constructor = { - // eslint-disable-next-line object-shorthand - [Symbol.species]: function (source, flags) { - const re2 = new RegExp(source, flags); - // Not a function, should be ignored - re2.exec = 3; - return re2; - }, - }; - assert.deepEqual(re[Symbol.split]('123451234'), ['1', '3', '51', '3', '']); - - re.constructor = { - // eslint-disable-next-line object-shorthand - [Symbol.species]: function (source, flags) { - const re2 = new RegExp(source, flags); - // Does not return an object, should throw - re2.exec = () => 3; - return re2; - }, - }; - assert.throws(() => re[Symbol.split]('123451234')); -}); - -QUnit.test('RegExp#@@split implementation', patchRegExp$exec(run)); diff --git a/tests/tests/es.string.starts-with.js b/tests/tests/es.string.starts-with.js deleted file mode 100644 index 3a278ecb5e12..000000000000 --- a/tests/tests/es.string.starts-with.js +++ /dev/null @@ -1,36 +0,0 @@ -import { GLOBAL, STRICT } from '../helpers/constants'; - -const Symbol = GLOBAL.Symbol || {}; - -QUnit.test('String#startsWith', assert => { - const { startsWith } = String.prototype; - assert.isFunction(startsWith); - assert.arity(startsWith, 1); - assert.name(startsWith, 'startsWith'); - assert.looksNative(startsWith); - assert.nonEnumerable(String.prototype, 'startsWith'); - assert.ok('undefined'.startsWith()); - assert.ok(!'undefined'.startsWith(null)); - assert.ok('abc'.startsWith('')); - assert.ok('abc'.startsWith('a')); - assert.ok('abc'.startsWith('ab')); - assert.ok(!'abc'.startsWith('bc')); - assert.ok('abc'.startsWith('', NaN)); - assert.ok('abc'.startsWith('a', -1)); - assert.ok(!'abc'.startsWith('a', 1)); - assert.ok(!'abc'.startsWith('a', Infinity)); - assert.ok('abc'.startsWith('b', true)); - assert.ok('abc'.startsWith('a', 'x')); - if (STRICT) { - assert.throws(() => startsWith.call(null, '.'), TypeError); - assert.throws(() => startsWith.call(undefined, '.'), TypeError); - } - const regexp = /./; - assert.throws(() => '/./'.startsWith(regexp), TypeError); - regexp[Symbol.match] = false; - assert.notThrows(() => '/./'.startsWith(regexp)); - const object = {}; - assert.notThrows(() => '[object Object]'.startsWith(object)); - object[Symbol.match] = true; - assert.throws(() => '[object Object]'.startsWith(object), TypeError); -}); diff --git a/tests/tests/es.string.strike.js b/tests/tests/es.string.strike.js deleted file mode 100644 index f7f0c60cf9bd..000000000000 --- a/tests/tests/es.string.strike.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#strike', assert => { - const { strike } = String.prototype; - assert.isFunction(strike); - assert.arity(strike, 0); - assert.name(strike, 'strike'); - assert.looksNative(strike); - assert.nonEnumerable(String.prototype, 'strike'); - assert.same('a'.strike(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.sub.js b/tests/tests/es.string.sub.js deleted file mode 100644 index 1014c2454ec2..000000000000 --- a/tests/tests/es.string.sub.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#sub', assert => { - const { sub } = String.prototype; - assert.isFunction(sub); - assert.arity(sub, 0); - assert.name(sub, 'sub'); - assert.looksNative(sub); - assert.nonEnumerable(String.prototype, 'sub'); - assert.same('a'.sub(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.sup.js b/tests/tests/es.string.sup.js deleted file mode 100644 index fae5748cbf48..000000000000 --- a/tests/tests/es.string.sup.js +++ /dev/null @@ -1,9 +0,0 @@ -QUnit.test('String#sup', assert => { - const { sup } = String.prototype; - assert.isFunction(sup); - assert.arity(sup, 0); - assert.name(sup, 'sup'); - assert.looksNative(sup); - assert.nonEnumerable(String.prototype, 'sup'); - assert.same('a'.sup(), 'a', 'lower case'); -}); diff --git a/tests/tests/es.string.trim-end.js b/tests/tests/es.string.trim-end.js deleted file mode 100644 index 11407275bbfa..000000000000 --- a/tests/tests/es.string.trim-end.js +++ /dev/null @@ -1,34 +0,0 @@ -import { STRICT, WHITESPACES } from '../helpers/constants'; - -QUnit.test('String#trimRight', assert => { - const { trimRight } = String.prototype; - assert.isFunction(trimRight); - assert.arity(trimRight, 0); - assert.name(trimRight, 'trimEnd'); - assert.looksNative(trimRight); - assert.nonEnumerable(String.prototype, 'trimRight'); - assert.strictEqual(' \n q w e \n '.trimRight(), ' \n q w e', 'removes whitespaces at right side of string'); - assert.strictEqual(WHITESPACES.trimRight(), '', 'removes all whitespaces'); - assert.strictEqual('\u200B\u0085'.trimRight(), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trimRight.call(null, 0), TypeError); - assert.throws(() => trimRight.call(undefined, 0), TypeError); - } -}); - -QUnit.test('String#trimEnd', assert => { - const { trimEnd } = String.prototype; - assert.isFunction(trimEnd); - assert.arity(trimEnd, 0); - assert.name(trimEnd, 'trimEnd'); - assert.looksNative(trimEnd); - assert.nonEnumerable(String.prototype, 'trimEnd'); - assert.same(trimEnd, String.prototype.trimRight, 'same #trimRight'); - assert.strictEqual(' \n q w e \n '.trimEnd(), ' \n q w e', 'removes whitespaces at right side of string'); - assert.strictEqual(WHITESPACES.trimEnd(), '', 'removes all whitespaces'); - assert.strictEqual('\u200B\u0085'.trimEnd(), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trimEnd.call(null, 0), TypeError); - assert.throws(() => trimEnd.call(undefined, 0), TypeError); - } -}); diff --git a/tests/tests/es.string.trim-start.js b/tests/tests/es.string.trim-start.js deleted file mode 100644 index 2bfd7843f164..000000000000 --- a/tests/tests/es.string.trim-start.js +++ /dev/null @@ -1,34 +0,0 @@ -import { STRICT, WHITESPACES } from '../helpers/constants'; - -QUnit.test('String#trimLeft', assert => { - const { trimLeft } = String.prototype; - assert.isFunction(trimLeft); - assert.arity(trimLeft, 0); - assert.name(trimLeft, 'trimStart'); - assert.looksNative(trimLeft); - assert.nonEnumerable(String.prototype, 'trimLeft'); - assert.strictEqual(' \n q w e \n '.trimLeft(), 'q w e \n ', 'removes whitespaces at left side of string'); - assert.strictEqual(WHITESPACES.trimLeft(), '', 'removes all whitespaces'); - assert.strictEqual('\u200B\u0085'.trimLeft(), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trimLeft.call(null, 0), TypeError); - assert.throws(() => trimLeft.call(undefined, 0), TypeError); - } -}); - -QUnit.test('String#trimStart', assert => { - const { trimStart } = String.prototype; - assert.isFunction(trimStart); - assert.arity(trimStart, 0); - assert.name(trimStart, 'trimStart'); - assert.looksNative(trimStart); - assert.nonEnumerable(String.prototype, 'trimStart'); - assert.same(trimStart, String.prototype.trimLeft, 'same #trimLeft'); - assert.strictEqual(' \n q w e \n '.trimStart(), 'q w e \n ', 'removes whitespaces at left side of string'); - assert.strictEqual(WHITESPACES.trimStart(), '', 'removes all whitespaces'); - assert.strictEqual('\u200B\u0085'.trimStart(), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trimStart.call(null, 0), TypeError); - assert.throws(() => trimStart.call(undefined, 0), TypeError); - } -}); diff --git a/tests/tests/es.string.trim.js b/tests/tests/es.string.trim.js deleted file mode 100644 index 8df5df64f007..000000000000 --- a/tests/tests/es.string.trim.js +++ /dev/null @@ -1,17 +0,0 @@ -import { STRICT, WHITESPACES } from '../helpers/constants'; - -QUnit.test('String#trim', assert => { - const { trim } = String.prototype; - assert.isFunction(''.trim); - assert.arity(trim, 0); - assert.name(trim, 'trim'); - assert.looksNative(trim); - assert.nonEnumerable(String.prototype, 'trim'); - assert.strictEqual(' \n q w e \n '.trim(), 'q w e', 'removes whitespaces at left & right side of string'); - assert.strictEqual(WHITESPACES.trim(), '', 'removes all whitespaces'); - assert.strictEqual('\u200B\u0085'.trim(), '\u200B\u0085', "shouldn't remove this symbols"); - if (STRICT) { - assert.throws(() => trim.call(null, 0), TypeError); - assert.throws(() => trim.call(undefined, 0), TypeError); - } -}); diff --git a/tests/tests/es.symbol.async-iterator.js b/tests/tests/es.symbol.async-iterator.js deleted file mode 100644 index c026fef3e600..000000000000 --- a/tests/tests/es.symbol.async-iterator.js +++ /dev/null @@ -1,13 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Symbol.asyncIterator', assert => { - assert.ok('asyncIterator' in Symbol, 'Symbol.asyncIterator available'); - assert.nonEnumerable(Symbol, 'asyncIterator'); - assert.ok(Object(Symbol.asyncIterator) instanceof Symbol, 'Symbol.asyncIterator is symbol'); - if (DESCRIPTORS) { - const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'asyncIterator'); - assert.ok(!descriptor.enumerble, 'non-enumerable'); - assert.ok(!descriptor.writable, 'non-writable'); - assert.ok(!descriptor.configurable, 'non-configurable'); - } -}); diff --git a/tests/tests/es.symbol.js b/tests/tests/es.symbol.js deleted file mode 100644 index a817e4d06549..000000000000 --- a/tests/tests/es.symbol.js +++ /dev/null @@ -1,305 +0,0 @@ -import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants'; - -const { - defineProperty, - defineProperties, - getOwnPropertyDescriptor, - getOwnPropertyNames, - getOwnPropertySymbols, - keys, - create, -} = Object; -const { ownKeys } = GLOBAL.Reflect || {}; - -QUnit.test('Symbol', assert => { - assert.isFunction(Symbol); - if (NATIVE) assert.strictEqual(Symbol.length, 0, 'arity is 0'); - assert.name(Symbol, 'Symbol'); - assert.looksNative(Symbol); - const symbol1 = Symbol('symbol'); - const symbol2 = Symbol('symbol'); - assert.ok(symbol1 !== symbol2, 'Symbol("symbol") !== Symbol("symbol")'); - const object = {}; - object[symbol1] = 42; - assert.ok(object[symbol1] === 42, 'Symbol() work as key'); - assert.ok(object[symbol2] !== 42, 'Various symbols from one description are various keys'); - if (DESCRIPTORS) { - let count = 0; - // eslint-disable-next-line no-unused-vars - for (const key in object) count++; - assert.ok(count === 0, 'object[Symbol()] is not enumerable'); - } -}); - -QUnit.test('Well-known Symbols', assert => { - const wks = [ - 'hasInstance', - 'isConcatSpreadable', - 'iterator', - 'match', - 'matchAll', - 'replace', - 'search', - 'species', - 'split', - 'toPrimitive', - 'toStringTag', - 'unscopables', - ]; - for (const name of wks) { - assert.ok(name in Symbol, `Symbol.${ name } available`); - assert.ok(Object(Symbol[name]) instanceof Symbol, `Symbol.${ name } is symbol`); - if (DESCRIPTORS) { - const descriptor = getOwnPropertyDescriptor(Symbol, name); - assert.ok(!descriptor.enumerble, 'non-enumerable'); - assert.ok(!descriptor.writable, 'non-writable'); - assert.ok(!descriptor.configurable, 'non-configurable'); - } - } -}); - -QUnit.test('Global symbol registry', assert => { - assert.isFunction(Symbol.for, 'Symbol.for is function'); - assert.nonEnumerable(Symbol, 'for'); - assert.strictEqual(Symbol.for.length, 1, 'Symbol.for arity is 1'); - if (NATIVE) assert.strictEqual(Symbol.for.name, 'for', 'Symbol.for.name is "for"'); - assert.looksNative(Symbol.for, 'Symbol.for looks like native'); - assert.isFunction(Symbol.keyFor, 'Symbol.keyFor is function'); - assert.nonEnumerable(Symbol, 'keyFor'); - assert.strictEqual(Symbol.keyFor.length, 1, 'Symbol.keyFor arity is 1'); - assert.strictEqual(Symbol.keyFor.name, 'keyFor', 'Symbol.keyFor.name is "keyFor"'); - assert.looksNative(Symbol.keyFor, 'Symbol.keyFor looks like native'); - const symbol = Symbol.for('foo'); - assert.strictEqual(Symbol.for('foo'), symbol); - assert.strictEqual(Symbol.keyFor(symbol), 'foo'); - assert.throws(() => Symbol.keyFor('foo'), 'throws on non-symbol'); -}); - -QUnit.test('Symbol#@@toPrimitive', assert => { - const symbol = Symbol(); - assert.isFunction(Symbol.prototype[Symbol.toPrimitive]); - assert.same(symbol, symbol[Symbol.toPrimitive](), 'works'); -}); - -QUnit.test('Symbol#@@toStringTag', assert => { - assert.ok(Symbol.prototype[Symbol.toStringTag] === 'Symbol', 'Symbol::@@toStringTag is `Symbol`'); -}); - -QUnit.test('Object.getOwnPropertySymbols', assert => { - assert.isFunction(getOwnPropertySymbols); - assert.nonEnumerable(Object, 'getOwnPropertySymbols'); - assert.strictEqual(getOwnPropertySymbols.length, 1, 'arity is 1'); - assert.name(getOwnPropertySymbols, 'getOwnPropertySymbols'); - assert.looksNative(getOwnPropertySymbols); - const prototype = { q: 1, w: 2, e: 3 }; - prototype[Symbol()] = 42; - prototype[Symbol()] = 43; - assert.deepEqual(getOwnPropertyNames(prototype).sort(), ['e', 'q', 'w']); - assert.strictEqual(getOwnPropertySymbols(prototype).length, 2); - const object = create(prototype); - object.a = 1; - object.s = 2; - object.d = 3; - object[Symbol()] = 44; - assert.deepEqual(getOwnPropertyNames(object).sort(), ['a', 'd', 's']); - assert.strictEqual(getOwnPropertySymbols(object).length, 1); - assert.strictEqual(getOwnPropertySymbols(Object.prototype).length, 0); - const primitives = [42, 'foo', false]; - for (const value of primitives) { - assert.notThrows(() => getOwnPropertySymbols(value), `accept ${ typeof value }`); - } -}); - -if (JSON) { - QUnit.test('Symbols & JSON.stringify', assert => { - assert.strictEqual(JSON.stringify([ - 1, - Symbol('foo'), - false, - Symbol('bar'), - {}, - ]), '[1,null,false,null,{}]', 'array value'); - assert.strictEqual(JSON.stringify({ - symbol: Symbol('symbol'), - }), '{}', 'object value'); - if (DESCRIPTORS) { - const object = { bar: 2 }; - object[Symbol('symbol')] = 1; - assert.strictEqual(JSON.stringify(object), '{"bar":2}', 'object key'); - } - assert.strictEqual(JSON.stringify(Symbol('symbol')), undefined, 'symbol value'); - if (typeof Symbol() === 'symbol') { - assert.strictEqual(JSON.stringify(Object(Symbol('symbol'))), '{}', 'boxed symbol'); - } - assert.strictEqual(JSON.stringify(undefined, () => 42), '42', 'replacer works with top-level undefined'); - }); -} - -if (DESCRIPTORS) { - QUnit.test('Symbols & descriptors', assert => { - const d = Symbol('d'); - const e = Symbol('e'); - const f = Symbol('f'); - const i = Symbol('i'); - const j = Symbol('j'); - const prototype = { g: 'g' }; - prototype[i] = 'i'; - defineProperty(prototype, 'h', { - value: 'h', - }); - defineProperty(prototype, 'j', { - value: 'j', - }); - const object = create(prototype); - object.a = 'a'; - object[d] = 'd'; - defineProperty(object, 'b', { - value: 'b', - }); - defineProperty(object, 'c', { - value: 'c', - enumerable: true, - }); - defineProperty(object, e, { - configurable: true, - writable: true, - value: 'e', - }); - const descriptor = { - value: 'f', - enumerable: true, - }; - defineProperty(object, f, descriptor); - assert.strictEqual(descriptor.enumerable, true, 'defineProperty not changes descriptor object'); - assert.deepEqual(getOwnPropertyDescriptor(object, 'a'), { - configurable: true, - writable: true, - enumerable: true, - value: 'a', - }, 'getOwnPropertyDescriptor a'); - assert.deepEqual(getOwnPropertyDescriptor(object, 'b'), { - configurable: false, - writable: false, - enumerable: false, - value: 'b', - }, 'getOwnPropertyDescriptor b'); - assert.deepEqual(getOwnPropertyDescriptor(object, 'c'), { - configurable: false, - writable: false, - enumerable: true, - value: 'c', - }, 'getOwnPropertyDescriptor c'); - assert.deepEqual(getOwnPropertyDescriptor(object, d), { - configurable: true, - writable: true, - enumerable: true, - value: 'd', - }, 'getOwnPropertyDescriptor d'); - assert.deepEqual(getOwnPropertyDescriptor(object, e), { - configurable: true, - writable: true, - enumerable: false, - value: 'e', - }, 'getOwnPropertyDescriptor e'); - assert.deepEqual(getOwnPropertyDescriptor(object, f), { - configurable: false, - writable: false, - enumerable: true, - value: 'f', - }, 'getOwnPropertyDescriptor f'); - assert.strictEqual(getOwnPropertyDescriptor(object, 'g'), undefined, 'getOwnPropertyDescriptor g'); - assert.strictEqual(getOwnPropertyDescriptor(object, 'h'), undefined, 'getOwnPropertyDescriptor h'); - assert.strictEqual(getOwnPropertyDescriptor(object, i), undefined, 'getOwnPropertyDescriptor i'); - assert.strictEqual(getOwnPropertyDescriptor(object, j), undefined, 'getOwnPropertyDescriptor j'); - assert.strictEqual(getOwnPropertyDescriptor(object, 'k'), undefined, 'getOwnPropertyDescriptor k'); - assert.strictEqual(getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable, false, 'getOwnPropertyDescriptor on Object.prototype'); - assert.strictEqual(getOwnPropertyDescriptor(Object.prototype, d), undefined, 'getOwnPropertyDescriptor on Object.prototype missed symbol'); - assert.strictEqual(keys(object).length, 2, 'Object.keys'); - assert.strictEqual(getOwnPropertyNames(object).length, 3, 'Object.getOwnPropertyNames'); - assert.strictEqual(getOwnPropertySymbols(object).length, 3, 'Object.getOwnPropertySymbols'); - assert.strictEqual(ownKeys(object).length, 6, 'Reflect.ownKeys'); - delete object[e]; - object[e] = 'e'; - assert.deepEqual(getOwnPropertyDescriptor(object, e), { - configurable: true, - writable: true, - enumerable: true, - value: 'e', - }, 'redefined non-enum key'); - }); - - QUnit.test('Symbols & Object.defineProperties', assert => { - const c = Symbol('c'); - const d = Symbol('d'); - const descriptors = { - a: { - value: 'a', - }, - }; - descriptors[c] = { - value: 'c', - }; - defineProperty(descriptors, 'b', { - value: { - value: 'b', - }, - }); - defineProperty(descriptors, d, { - value: { - value: 'd', - }, - }); - const object = defineProperties({}, descriptors); - assert.strictEqual(object.a, 'a', 'a'); - assert.strictEqual(object.b, undefined, 'b'); - assert.strictEqual(object[c], 'c', 'c'); - assert.strictEqual(object[d], undefined, 'd'); - }); - - QUnit.test('Symbols & Object.create', assert => { - const c = Symbol('c'); - const d = Symbol('d'); - const descriptors = { - a: { - value: 'a', - }, - }; - descriptors[c] = { - value: 'c', - }; - defineProperty(descriptors, 'b', { - value: { - value: 'b', - }, - }); - defineProperty(descriptors, d, { - value: { - value: 'd', - }, - }); - const object = create(null, descriptors); - assert.strictEqual(object.a, 'a', 'a'); - assert.strictEqual(object.b, undefined, 'b'); - assert.strictEqual(object[c], 'c', 'c'); - assert.strictEqual(object[d], undefined, 'd'); - }); - - const constructors = ['Map', 'Set', 'Promise']; - for (const name of constructors) { - QUnit.test(`${ name }@@species`, assert => { - assert.strictEqual(GLOBAL[name][Symbol.species], GLOBAL[name], `${ name }@@species === ${ name }`); - const Subclass = create(GLOBAL[name]); - assert.strictEqual(Subclass[Symbol.species], Subclass, `${ name } subclass`); - }); - } - - QUnit.test('Array@@species', assert => { - assert.strictEqual(Array[Symbol.species], Array, 'Array@@species === Array'); - const Subclass = create(Array); - assert.strictEqual(Subclass[Symbol.species], Subclass, 'Array subclass'); - }); - - QUnit.test('Symbol.sham flag', assert => { - assert.same(Symbol.sham, typeof Symbol() === 'symbol' ? undefined : true); - }); -} diff --git a/tests/tests/es.typed-array.every.js b/tests/tests/es.typed-array.every.js deleted file mode 100644 index c2340b6ca633..000000000000 --- a/tests/tests/es.typed-array.every.js +++ /dev/null @@ -1,39 +0,0 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; - -if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.every', assert => { - // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - const { every } = TypedArray.prototype; - assert.isFunction(every, `${ name }::every is function`); - assert.arity(every, 1, `${ name }::every arity is 1`); - assert.name(every, 'every', `${ name }::every name is 'every'`); - assert.looksNative(every, `${ name }::every looks native`); - const array = new TypedArray([1]); - const context = {}; - array.every(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.ok(new TypedArray([1, 2, 3]).every(it => typeof it === 'number')); - assert.ok(new TypedArray([1, 2, 3]).every(it => it < 4)); - assert.ok(!new TypedArray([1, 2, 3]).every(it => it < 3)); - assert.ok(!new TypedArray([1, 2, 3]).every(it => typeof it === 'string')); - assert.ok(new TypedArray([1, 2, 3]).every(function () { - return +this === 1; - }, 1)); - let values = ''; - let keys = ''; - new TypedArray([1, 2, 3]).every((value, key) => { - values += value; - keys += key; - return true; - }); - assert.same(values, '123'); - assert.same(keys, '012'); - assert.throws(() => every.call([0], () => { /* empty */ }), "isn't generic"); - } -}); diff --git a/tests/tests/es.typed-array.fill.js b/tests/tests/es.typed-array.fill.js deleted file mode 100644 index fc8b6cbb2a56..000000000000 --- a/tests/tests/es.typed-array.fill.js +++ /dev/null @@ -1,21 +0,0 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; - -if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.fill', assert => { - // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - const { fill } = TypedArray.prototype; - assert.isFunction(fill, `${ name }::fill is function`); - assert.arity(fill, 1, `${ name }::fill arity is 1`); - assert.name(fill, 'fill', `${ name }::fill name is 'fill'`); - assert.looksNative(fill, `${ name }::fill looks native`); - const array = new TypedArray(5); - assert.strictEqual(array.fill(5), array, 'return this'); - assert.arrayEqual(new TypedArray(5).fill(5), [5, 5, 5, 5, 5], 'basic'); - assert.arrayEqual(new TypedArray(5).fill(5, 1), [0, 5, 5, 5, 5], 'start index'); - assert.arrayEqual(new TypedArray(5).fill(5, 1, 4), [0, 5, 5, 5, 0], 'end index'); - assert.arrayEqual(new TypedArray(5).fill(5, 6, 1), [0, 0, 0, 0, 0], 'start > end'); - assert.arrayEqual(new TypedArray(5).fill(5, -3, 4), [0, 0, 5, 5, 0], 'negative start index'); - assert.throws(() => fill.call([0], 1), "isn't generic"); - } -}); diff --git a/tests/tests/es.typed-array.from.js b/tests/tests/es.typed-array.from.js deleted file mode 100644 index 2ad84d5c49bf..000000000000 --- a/tests/tests/es.typed-array.from.js +++ /dev/null @@ -1,45 +0,0 @@ -import { DESCRIPTORS, GLOBAL, NATIVE, TYPED_ARRAYS } from '../helpers/constants'; -import { createIterable } from '../helpers/helpers'; - -if (DESCRIPTORS) QUnit.test('%TypedArray%.from', assert => { - // we can't implement %TypedArray% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - assert.isFunction(TypedArray.from, `${ name }.from is function`); - assert.arity(TypedArray.from, 1, `${ name }.from arity is 1`); - assert.name(TypedArray.from, 'from', `${ name }.from name is 'from'`); - assert.looksNative(TypedArray.from, `${ name }.from looks native`); - let instance = TypedArray.from([1, 2, 3]); - assert.ok(instance instanceof TypedArray, 'correct instance with array'); - assert.arrayEqual(instance, [1, 2, 3], 'correct elements with array'); - instance = TypedArray.from({ - 0: 1, - 1: 2, - 2: 3, - length: 3, - }); - assert.ok(instance instanceof TypedArray, 'correct instance with array-like'); - assert.arrayEqual(instance, [1, 2, 3], 'correct elements with array-like'); - instance = TypedArray.from(createIterable([1, 2, 3])); - assert.ok(instance instanceof TypedArray, 'correct instance with iterable'); - assert.arrayEqual(instance, [1, 2, 3], 'correct elements with iterable'); - assert.arrayEqual(TypedArray.from([1, 2, 3], it => it * it), [1, 4, 9], 'accept callback'); - const context = {}; - TypedArray.from([1], function (value, key) { - assert.same(arguments.length, 2, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.throws(() => TypedArray.from.call(undefined, []), "isn't generic #1"); - if (NATIVE) { - assert.throws(() => TypedArray.from.call(Array, []), "isn't generic #2"); - assert.notThrows(() => TypedArray.from({ - length: -1, - 0: 1, - }, () => { - throw new Error(); - }), 'uses ToLength'); - } - } -}); diff --git a/tests/tests/es.typed-array.includes.js b/tests/tests/es.typed-array.includes.js deleted file mode 100644 index b3ba2c9f6b05..000000000000 --- a/tests/tests/es.typed-array.includes.js +++ /dev/null @@ -1,19 +0,0 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; - -if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.includes', assert => { - // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - const { includes } = TypedArray.prototype; - assert.isFunction(includes, `${ name }::includes is function`); - assert.arity(includes, 1, `${ name }::includes arity is 1`); - assert.name(includes, 'includes', `${ name }::includes name is 'includes'`); - assert.looksNative(includes, `${ name }::includes looks native`); - assert.same(new TypedArray([1, 1, 1]).includes(1), true); - assert.same(new TypedArray([1, 2, 3]).includes(1, 1), false); - assert.same(new TypedArray([1, 2, 3]).includes(2, 1), true); - assert.same(new TypedArray([1, 2, 3]).includes(2, -1), false); - assert.same(new TypedArray([1, 2, 3]).includes(2, -2), true); - assert.throws(() => includes.call([1], 1), "isn't generic"); - } -}); diff --git a/tests/tests/es.typed-array.of.js b/tests/tests/es.typed-array.of.js deleted file mode 100644 index b877e3568903..000000000000 --- a/tests/tests/es.typed-array.of.js +++ /dev/null @@ -1,23 +0,0 @@ -import { DESCRIPTORS, GLOBAL, NATIVE, TYPED_ARRAYS } from '../helpers/constants'; - -if (DESCRIPTORS) QUnit.test('%TypedArray%.of', assert => { - // we can't implement %TypedArray% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - assert.isFunction(TypedArray.of, `${ name }.of is function`); - assert.arity(TypedArray.of, 0, `${ name }.of arity is 0`); - assert.name(TypedArray.of, 'of', `${ name }.of name is 'of'`); - assert.looksNative(TypedArray.of, `${ name }.of looks native`); - let instance = TypedArray.of(); - assert.ok(instance instanceof TypedArray, 'correct instance with 0 arguments'); - assert.arrayEqual(instance, [], 'correct elements with 0 arguments'); - instance = TypedArray.of(1); - assert.ok(instance instanceof TypedArray, 'correct instance with 1 argument'); - assert.arrayEqual(instance, [1], 'correct elements with 1 argument'); - instance = TypedArray.of(1, 2, 3); - assert.ok(instance instanceof TypedArray, 'correct instance with several arguments'); - assert.arrayEqual(instance, [1, 2, 3], 'correct elements with several arguments'); - assert.throws(() => TypedArray.of.call(undefined, 1), "isn't generic #1"); - if (NATIVE) assert.throws(() => TypedArray.of.call(Array, 1), "isn't generic #2"); - } -}); diff --git a/tests/tests/es.typed-array.set.js b/tests/tests/es.typed-array.set.js deleted file mode 100644 index 854e9bf688e2..000000000000 --- a/tests/tests/es.typed-array.set.js +++ /dev/null @@ -1,30 +0,0 @@ -import { DESCRIPTORS, GLOBAL, NATIVE, TYPED_ARRAYS } from '../helpers/constants'; - -if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.set', assert => { - // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - const { set } = TypedArray.prototype; - assert.isFunction(set, `${ name }::set is function`); - if (NATIVE) assert.arity(set, 1, `${ name }::set arity is 1`); - assert.name(set, 'set', `${ name }::set name is 'set'`); - assert.looksNative(set, `${ name }::set looks native`); - assert.same(new TypedArray(1).set([1]), undefined, 'void'); - const array1 = new TypedArray([1, 2, 3, 4, 5]); - const array2 = new TypedArray(5); - array2.set(array1); - assert.arrayEqual(array2, [1, 2, 3, 4, 5]); - assert.throws(() => array2.set(array1, 1)); - assert.throws(() => array2.set(array1, -1)); - array2.set(new TypedArray([99, 98]), 2); - assert.arrayEqual(array2, [1, 2, 99, 98, 5]); - array2.set(new TypedArray([99, 98, 97]), 2); - assert.arrayEqual(array2, [1, 2, 99, 98, 97]); - assert.throws(() => array2.set(new TypedArray([99, 98, 97, 96]), 2)); - assert.throws(() => array2.set([101, 102, 103, 104], 4)); - const array3 = new TypedArray(2); - array3.set({ length: 2, 0: 1, 1: 2 }); - assert.arrayEqual(array3, [1, 2]); - assert.throws(() => set.call([1, 2, 3], [1]), "isn't generic"); - } -}); diff --git a/tests/tests/es.typed-array.slice.js b/tests/tests/es.typed-array.slice.js deleted file mode 100644 index 3ec3e561db45..000000000000 --- a/tests/tests/es.typed-array.slice.js +++ /dev/null @@ -1,24 +0,0 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; - -if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.slice', assert => { - // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - const { slice } = TypedArray.prototype; - assert.isFunction(slice, `${ name }::slice is function`); - assert.arity(slice, 2, `${ name }::slice arity is 0`); - assert.name(slice, 'slice', `${ name }::slice name is 'slice'`); - assert.looksNative(slice, `${ name }::slice looks native`); - const array = new TypedArray([1, 2, 3, 4, 5]); - assert.ok(array.slice() !== array, 'returns new array'); - assert.ok(array.slice() instanceof TypedArray, 'correct instance'); - assert.ok(array.slice().buffer !== array.buffer, 'with new buffer'); - assert.arrayEqual(array.slice(), array); - assert.arrayEqual(array.slice(1, 3), [2, 3]); - assert.arrayEqual(array.slice(1, undefined), [2, 3, 4, 5]); - assert.arrayEqual(array.slice(1, -1), [2, 3, 4]); - assert.arrayEqual(array.slice(-2, -1), [4]); - assert.arrayEqual(array.slice(-2, -3), []); - assert.throws(() => slice.call([1, 2], 1), "isn't generic"); - } -}); diff --git a/tests/tests/es.typed-array.some.js b/tests/tests/es.typed-array.some.js deleted file mode 100644 index 282715a6a894..000000000000 --- a/tests/tests/es.typed-array.some.js +++ /dev/null @@ -1,38 +0,0 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; - -if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.some', assert => { - // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - const { some } = TypedArray.prototype; - assert.isFunction(some, `${ name }::some is function`); - assert.arity(some, 1, `${ name }::some arity is 1`); - assert.name(some, 'some', `${ name }::some name is 'some'`); - assert.looksNative(some, `${ name }::some looks native`); - const array = new TypedArray([1]); - const context = {}; - array.some(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 0, 'correct index in callback'); - assert.same(that, array, 'correct link to array in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - assert.ok(new TypedArray([1, 2, 3]).some(it => typeof it === 'number')); - assert.ok(new TypedArray([1, 2, 3]).some(it => it < 3)); - assert.ok(!new TypedArray([1, 2, 3]).some(it => it < 0)); - assert.ok(!new TypedArray([1, 2, 3]).some(it => typeof it === 'string')); - assert.ok(new TypedArray([1, 2, 3]).some(function () { - return +this === 1; - }, 1)); - let values = ''; - let keys = ''; - new TypedArray([1, 2, 3]).some((value, key) => { - values += value; - keys += key; - }); - assert.same(values, '123'); - assert.same(keys, '012'); - assert.throws(() => some.call([0], () => { /* empty */ }), "isn't generic"); - } -}); diff --git a/tests/tests/es.weak-map.js b/tests/tests/es.weak-map.js deleted file mode 100644 index 2e9d19cda4a0..000000000000 --- a/tests/tests/es.weak-map.js +++ /dev/null @@ -1,165 +0,0 @@ -import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants'; -import { createIterable, nativeSubclass } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; -const { freeze, keys, getOwnPropertyNames, getOwnPropertySymbols } = Object; -const { ownKeys } = GLOBAL.Reflect || {}; - -QUnit.test('WeakMap', assert => { - assert.isFunction(WeakMap); - assert.name(WeakMap, 'WeakMap'); - assert.arity(WeakMap, 0); - assert.looksNative(WeakMap); - assert.ok('delete' in WeakMap.prototype, 'delete in WeakMap.prototype'); - assert.ok('get' in WeakMap.prototype, 'get in WeakMap.prototype'); - assert.ok('has' in WeakMap.prototype, 'has in WeakMap.prototype'); - assert.ok('set' in WeakMap.prototype, 'set in WeakMap.prototype'); - assert.ok(new WeakMap() instanceof WeakMap, 'new WeakMap instanceof WeakMap'); - let object = {}; - assert.strictEqual(new WeakMap(createIterable([[object, 42]])).get(object), 42, 'Init from iterable'); - let weakmap = new WeakMap(); - const frozen = freeze({}); - weakmap.set(frozen, 42); - assert.strictEqual(weakmap.get(frozen), 42, 'Support frozen objects'); - weakmap = new WeakMap(); - weakmap.set(frozen, 42); - assert.strictEqual(weakmap.has(frozen), true, 'works with frozen objects, #1'); - assert.strictEqual(weakmap.get(frozen), 42, 'works with frozen objects, #2'); - weakmap.delete(frozen); - assert.strictEqual(weakmap.has(frozen), false, 'works with frozen objects, #3'); - assert.strictEqual(weakmap.get(frozen), undefined, 'works with frozen objects, #4'); - let done = false; - try { - new WeakMap(createIterable([null, 1, 2], { - return() { - return done = true; - }, - })); - } catch { /* empty */ } - assert.ok(done, '.return #throw'); - assert.ok(!('clear' in WeakMap.prototype), 'should not contains `.clear` method'); - const array = []; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return [][Symbol.iterator].call(this); - }; - new WeakMap(array); - assert.ok(done); - object = {}; - new WeakMap().set(object, 1); - if (DESCRIPTORS) { - const results = []; - for (const key in object) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(object), []); - } - assert.arrayEqual(getOwnPropertyNames(object), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); - if (ownKeys) assert.arrayEqual(ownKeys(object), []); - if (nativeSubclass) { - const Subclass = nativeSubclass(WeakMap); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof WeakMap, 'correct subclassing with native classes #2'); - object = {}; - assert.same(new Subclass().set(object, 2).get(object), 2, 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('WeakMap#delete', assert => { - assert.isFunction(WeakMap.prototype.delete); - if (NATIVE) assert.name(WeakMap.prototype.delete, 'delete'); - if (NATIVE) assert.arity(WeakMap.prototype.delete, 1); - assert.looksNative(WeakMap.prototype.delete); - assert.nonEnumerable(WeakMap.prototype, 'delete'); - const a = {}; - const b = {}; - const weakmap = new WeakMap(); - weakmap.set(a, 42); - weakmap.set(b, 21); - assert.ok(weakmap.has(a) && weakmap.has(b), 'WeakMap has values before .delete()'); - weakmap.delete(a); - assert.ok(!weakmap.has(a) && weakmap.has(b), 'WeakMap hasn`t value after .delete()'); - assert.notThrows(() => !weakmap.delete(1), 'return false on primitive'); - const object = {}; - weakmap.set(object, 42); - freeze(object); - assert.ok(weakmap.has(object), 'works with frozen objects #1'); - weakmap.delete(object); - assert.ok(!weakmap.has(object), 'works with frozen objects #2'); -}); - -QUnit.test('WeakMap#get', assert => { - assert.isFunction(WeakMap.prototype.get); - assert.name(WeakMap.prototype.get, 'get'); - if (NATIVE) assert.arity(WeakMap.prototype.get, 1); - assert.looksNative(WeakMap.prototype.get); - assert.nonEnumerable(WeakMap.prototype, 'get'); - const weakmap = new WeakMap(); - assert.strictEqual(weakmap.get({}), undefined, 'WeakMap .get() before .set() return undefined'); - let object = {}; - weakmap.set(object, 42); - assert.strictEqual(weakmap.get(object), 42, 'WeakMap .get() return value'); - weakmap.delete(object); - assert.strictEqual(weakmap.get(object), undefined, 'WeakMap .get() after .delete() return undefined'); - assert.notThrows(() => weakmap.get(1) === undefined, 'return undefined on primitive'); - object = {}; - weakmap.set(object, 42); - freeze(object); - assert.same(weakmap.get(object), 42, 'works with frozen objects #1'); - weakmap.delete(object); - assert.same(weakmap.get(object), undefined, 'works with frozen objects #2'); -}); - -QUnit.test('WeakMap#has', assert => { - assert.isFunction(WeakMap.prototype.has); - assert.name(WeakMap.prototype.has, 'has'); - if (NATIVE) assert.arity(WeakMap.prototype.has, 1); - assert.looksNative(WeakMap.prototype.has); - assert.nonEnumerable(WeakMap.prototype, 'has'); - const weakmap = new WeakMap(); - assert.ok(!weakmap.has({}), 'WeakMap .has() before .set() return false'); - let object = {}; - weakmap.set(object, 42); - assert.ok(weakmap.has(object), 'WeakMap .has() return true'); - weakmap.delete(object); - assert.ok(!weakmap.has(object), 'WeakMap .has() after .delete() return false'); - assert.notThrows(() => !weakmap.has(1), 'return false on primitive'); - object = {}; - weakmap.set(object, 42); - freeze(object); - assert.ok(weakmap.has(object), 'works with frozen objects #1'); - weakmap.delete(object); - assert.ok(!weakmap.has(object), 'works with frozen objects #2'); -}); - -QUnit.test('WeakMap#set', assert => { - assert.isFunction(WeakMap.prototype.set); - assert.name(WeakMap.prototype.set, 'set'); - assert.arity(WeakMap.prototype.set, 2); - assert.looksNative(WeakMap.prototype.set); - assert.nonEnumerable(WeakMap.prototype, 'set'); - const weakmap = new WeakMap(); - const object = {}; - weakmap.set(object, 33); - assert.same(weakmap.get(object), 33, 'works with object as keys'); - assert.ok(weakmap.set({}, 42) === weakmap, 'chaining'); - assert.throws(() => new WeakMap().set(42, 42), 'throws with primitive keys'); - const object1 = freeze({}); - const object2 = {}; - weakmap.set(object1, 42); - weakmap.set(object2, 42); - freeze(object); - assert.same(weakmap.get(object1), 42, 'works with frozen objects #1'); - assert.same(weakmap.get(object2), 42, 'works with frozen objects #2'); - weakmap.delete(object1); - weakmap.delete(object2); - assert.same(weakmap.get(object1), undefined, 'works with frozen objects #3'); - assert.same(weakmap.get(object2), undefined, 'works with frozen objects #4'); -}); - -QUnit.test('WeakMap#@@toStringTag', assert => { - assert.strictEqual(WeakMap.prototype[Symbol.toStringTag], 'WeakMap', 'WeakMap::@@toStringTag is `WeakMap`'); - assert.strictEqual(String(new WeakMap()), '[object WeakMap]', 'correct stringification'); -}); diff --git a/tests/tests/es.weak-set.js b/tests/tests/es.weak-set.js deleted file mode 100644 index cf59f048bb55..000000000000 --- a/tests/tests/es.weak-set.js +++ /dev/null @@ -1,108 +0,0 @@ -import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants'; -import { createIterable, nativeSubclass } from '../helpers/helpers'; - -const Symbol = GLOBAL.Symbol || {}; -const { freeze, keys, getOwnPropertyNames, getOwnPropertySymbols } = Object; -const { ownKeys } = GLOBAL.Reflect || {}; - -QUnit.test('WeakSet', assert => { - assert.isFunction(WeakSet); - assert.name(WeakSet, 'WeakSet'); - assert.arity(WeakSet, 0); - assert.looksNative(WeakSet); - assert.ok('add' in WeakSet.prototype, 'add in WeakSet.prototype'); - assert.ok('delete' in WeakSet.prototype, 'delete in WeakSet.prototype'); - assert.ok('has' in WeakSet.prototype, 'has in WeakSet.prototype'); - assert.ok(new WeakSet() instanceof WeakSet, 'new WeakSet instanceof WeakSet'); - let object = {}; - assert.ok(new WeakSet(createIterable([object])).has(object), 'Init from iterable'); - const weakset = new WeakSet(); - const frozen = freeze({}); - weakset.add(frozen); - assert.strictEqual(weakset.has(frozen), true, 'works with frozen objects, #1'); - weakset.delete(frozen); - assert.strictEqual(weakset.has(frozen), false, 'works with frozen objects, #2'); - let done = false; - try { - new WeakSet(createIterable([null, 1, 2], { - return() { - return done = true; - }, - })); - } catch { /* empty */ } - assert.ok(done, '.return #throw'); - assert.ok(!('clear' in WeakSet.prototype), 'should not contains `.clear` method'); - const array = []; - done = false; - array['@@iterator'] = undefined; - array[Symbol.iterator] = function () { - done = true; - return [][Symbol.iterator].call(this); - }; - new WeakSet(array); - assert.ok(done); - object = {}; - new WeakSet().add(object); - if (DESCRIPTORS) { - const results = []; - for (const key in object) results.push(key); - assert.arrayEqual(results, []); - assert.arrayEqual(keys(object), []); - } - assert.arrayEqual(getOwnPropertyNames(object), []); - if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); - if (ownKeys) assert.arrayEqual(ownKeys(object), []); - if (nativeSubclass) { - const Subclass = nativeSubclass(WeakSet); - assert.ok(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); - assert.ok(new Subclass() instanceof WeakSet, 'correct subclassing with native classes #2'); - object = {}; - assert.ok(new Subclass().add(object).has(object), 'correct subclassing with native classes #3'); - } -}); - -QUnit.test('WeakSet#add', assert => { - assert.isFunction(WeakSet.prototype.add); - assert.name(WeakSet.prototype.add, 'add'); - assert.arity(WeakSet.prototype.add, 1); - assert.looksNative(WeakSet.prototype.add); - assert.nonEnumerable(WeakSet.prototype, 'add'); - const weakset = new WeakSet(); - assert.ok(weakset.add({}) === weakset, 'chaining'); - assert.throws(() => new WeakSet().add(42), 'throws with primitive keys'); -}); - -QUnit.test('WeakSet#delete', assert => { - assert.isFunction(WeakSet.prototype.delete); - if (NATIVE) assert.arity(WeakSet.prototype.delete, 1); - assert.looksNative(WeakSet.prototype.delete); - assert.nonEnumerable(WeakSet.prototype, 'delete'); - const a = {}; - const b = {}; - const weakset = new WeakSet().add(a).add(b); - assert.ok(weakset.has(a) && weakset.has(b), 'WeakSet has values before .delete()'); - weakset.delete(a); - assert.ok(!weakset.has(a) && weakset.has(b), 'WeakSet has`nt value after .delete()'); - assert.notThrows(() => !weakset.delete(1), 'return false on primitive'); -}); - -QUnit.test('WeakSet#has', assert => { - assert.isFunction(WeakSet.prototype.has); - assert.name(WeakSet.prototype.has, 'has'); - assert.arity(WeakSet.prototype.has, 1); - assert.looksNative(WeakSet.prototype.has); - assert.nonEnumerable(WeakSet.prototype, 'has'); - const weakset = new WeakSet(); - assert.ok(!weakset.has({}), 'WeakSet has`nt value'); - const object = {}; - weakset.add(object); - assert.ok(weakset.has(object), 'WeakSet has value after .add()'); - weakset.delete(object); - assert.ok(!weakset.has(object), 'WeakSet hasn`t value after .delete()'); - assert.notThrows(() => !weakset.has(1), 'return false on primitive'); -}); - -QUnit.test('WeakSet::@@toStringTag', assert => { - assert.strictEqual(WeakSet.prototype[Symbol.toStringTag], 'WeakSet', 'WeakSet::@@toStringTag is `WeakSet`'); - assert.strictEqual(String(new WeakSet()), '[object WeakSet]', 'correct stringification'); -}); diff --git a/tests/tests/esnext.aggregate-error.js b/tests/tests/esnext.aggregate-error.js deleted file mode 100644 index c96547d3520b..000000000000 --- a/tests/tests/esnext.aggregate-error.js +++ /dev/null @@ -1,12 +0,0 @@ -QUnit.test('AggregateError', assert => { - assert.isFunction(AggregateError); - assert.arity(AggregateError, 2); - assert.name(AggregateError, 'AggregateError'); - assert.looksNative(AggregateError); - assert.ok(new AggregateError([1]) instanceof AggregateError); - assert.ok(new AggregateError([1]) instanceof Error); - assert.ok(AggregateError([1]) instanceof AggregateError); - assert.ok(AggregateError([1]) instanceof Error); - assert.same(AggregateError([1], 'foo').message, 'foo'); - assert.deepEqual(AggregateError([1, 2, 3]).errors, [1, 2, 3]); -}); diff --git a/tests/tests/esnext.array.is-template-object.js b/tests/tests/esnext.array.is-template-object.js deleted file mode 100644 index c914499c63bf..000000000000 --- a/tests/tests/esnext.array.is-template-object.js +++ /dev/null @@ -1,28 +0,0 @@ -QUnit.test('Array.isTemplateObject', assert => { - const { isTemplateObject } = Array; - const { freeze } = Object; - - assert.isFunction(isTemplateObject); - assert.arity(isTemplateObject, 1); - assert.name(isTemplateObject, 'isTemplateObject'); - assert.looksNative(isTemplateObject); - assert.nonEnumerable(Array, 'isTemplateObject'); - - assert.ok(!isTemplateObject(undefined)); - assert.ok(!isTemplateObject(null)); - assert.ok(!isTemplateObject({})); - assert.ok(!isTemplateObject(function () { - return arguments; - }())); - assert.ok(!isTemplateObject([])); - assert.ok(!isTemplateObject(freeze([]))); - - const template = (() => { - try { - // eslint-disable-next-line no-template-curly-in-string - return Function('return (it => it)`qwe${ 123 }asd`')(); - } catch { /* empty */ } - })(); - - if (template) assert.ok(isTemplateObject(template)); -}); diff --git a/tests/tests/esnext.array.last-index.js b/tests/tests/esnext.array.last-index.js deleted file mode 100644 index e84c771560d3..000000000000 --- a/tests/tests/esnext.array.last-index.js +++ /dev/null @@ -1,10 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -if (DESCRIPTORS) QUnit.test('Array#lastIndex', assert => { - const descriptor = Object.getOwnPropertyDescriptor(Array.prototype, 'lastIndex'); - assert.isFunction(descriptor.get); - assert.same(descriptor.enumerable, false); - assert.same(descriptor.configurable, true); - assert.same([1, 2, 3].lastIndex, 2); - assert.same([].lastIndex, 0); -}); diff --git a/tests/tests/esnext.async-iterator.as-indexed-pairs.js b/tests/tests/esnext.async-iterator.as-indexed-pairs.js deleted file mode 100644 index 1e4dafea7433..000000000000 --- a/tests/tests/esnext.async-iterator.as-indexed-pairs.js +++ /dev/null @@ -1,23 +0,0 @@ -import { createIterator } from '../helpers/helpers'; - -QUnit.test('AsyncIterator#asIndexedPairs', assert => { - assert.expect(10); - const async = assert.async(); - const { asIndexedPairs } = AsyncIterator.prototype; - - assert.isFunction(asIndexedPairs); - assert.arity(asIndexedPairs, 0); - assert.name(asIndexedPairs, 'asIndexedPairs'); - assert.looksNative(asIndexedPairs); - assert.nonEnumerable(AsyncIterator.prototype, 'asIndexedPairs'); - - asIndexedPairs.call(createIterator(['a', 'b', 'c'])).toArray().then(it => { - assert.same(it.toString(), '0,a,1,b,2,c', 'basic functionality'); - async(); - }); - - assert.throws(() => asIndexedPairs.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => asIndexedPairs.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => asIndexedPairs.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => asIndexedPairs.call([], () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.constructor.js b/tests/tests/esnext.async-iterator.constructor.js deleted file mode 100644 index 3d7c0e84c85c..000000000000 --- a/tests/tests/esnext.async-iterator.constructor.js +++ /dev/null @@ -1,29 +0,0 @@ -QUnit.test('AsyncIterator', assert => { - assert.isFunction(AsyncIterator); - assert.arity(AsyncIterator, 0); - assert.name(AsyncIterator, 'AsyncIterator'); - assert.looksNative(AsyncIterator); - - const asyncGenerator = (() => { - try { - return Function('return async function*(){}()')(); - } catch { /* empty */ } - })(); - - if (asyncGenerator) assert.ok(asyncGenerator instanceof AsyncIterator, 'AsyncGenerator'); - - assert.ok(AsyncIterator.from([1, 2, 3]) instanceof AsyncIterator, 'Async From Proxy'); - assert.ok(AsyncIterator.from([1, 2, 3]).drop(1) instanceof AsyncIterator, 'Async Drop Proxy'); - - assert.ok(new AsyncIterator() instanceof AsyncIterator, 'constructor'); - assert.throws(() => AsyncIterator(), 'throws w/o `new`'); -}); - -QUnit.test('AsyncIterator#constructor', assert => { - assert.strictEqual(AsyncIterator.prototype.constructor, AsyncIterator, 'AsyncIterator#constructor is AsyncIterator'); -}); - -QUnit.test('AsyncIterator#@@toStringTag', assert => { - assert.strictEqual(AsyncIterator.prototype[Symbol.toStringTag], 'AsyncIterator', 'AsyncIterator::@@toStringTag is `AsyncIterator`'); - assert.strictEqual(String(AsyncIterator.from([1, 2, 3])), '[object AsyncIterator]', 'correct stringification'); -}); diff --git a/tests/tests/esnext.async-iterator.drop.js b/tests/tests/esnext.async-iterator.drop.js deleted file mode 100644 index 5346d3b1cdf3..000000000000 --- a/tests/tests/esnext.async-iterator.drop.js +++ /dev/null @@ -1,32 +0,0 @@ -import { createIterator } from '../helpers/helpers'; - -QUnit.test('AsyncIterator#drop', assert => { - assert.expect(14); - const async = assert.async(); - const { drop } = AsyncIterator.prototype; - - assert.isFunction(drop); - assert.arity(drop, 1); - assert.name(drop, 'drop'); - assert.looksNative(drop); - assert.nonEnumerable(AsyncIterator.prototype, 'drop'); - - drop.call(createIterator([1, 2, 3]), 1).toArray().then(it => { - assert.arrayEqual(it, [2, 3], 'basic functionality'); - return drop.call(createIterator([1, 2, 3]), 1.5).toArray(); - }).then(it => { - assert.arrayEqual(it, [2, 3], 'float'); - return drop.call(createIterator([1, 2, 3]), 4).toArray(); - }).then(it => { - assert.arrayEqual(it, [], 'big'); - return drop.call(createIterator([1, 2, 3]), 0).toArray(); - }).then(it => { - assert.arrayEqual(it, [1, 2, 3], 'zero'); - }).then(() => async()); - - assert.throws(() => drop.call(undefined, 1), TypeError); - assert.throws(() => drop.call(null, 1), TypeError); - assert.throws(() => drop.call({}, 1), TypeError); - assert.throws(() => drop.call([], 1), TypeError); - assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); -}); diff --git a/tests/tests/esnext.async-iterator.every.js b/tests/tests/esnext.async-iterator.every.js deleted file mode 100644 index d9b865397ef8..000000000000 --- a/tests/tests/esnext.async-iterator.every.js +++ /dev/null @@ -1,38 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#every', assert => { - assert.expect(18); - const async = assert.async(); - const { every } = AsyncIterator.prototype; - - assert.isFunction(every); - assert.arity(every, 1); - assert.name(every, 'every'); - assert.looksNative(every); - assert.nonEnumerable(AsyncIterator.prototype, 'every'); - - every.call(createIterator([1, 2, 3]), it => typeof it === 'number').then(result => { - assert.ok(result, 'basic functionality, +'); - return every.call(createIterator([1, 2, 3]), it => it === 2); - }).then(result => { - assert.ok(!result, 'basic functionality, -'); - return every.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - }).then(() => { - return every.call(createIterator([1]), () => { throw 42; }); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => every.call([], () => { /* empty */ }), TypeError); - assert.throws(() => every.call(createIterator([1]), undefined), TypeError); - assert.throws(() => every.call(createIterator([1]), null), TypeError); - assert.throws(() => every.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.filter.js b/tests/tests/esnext.async-iterator.filter.js deleted file mode 100644 index 1f5c02bff650..000000000000 --- a/tests/tests/esnext.async-iterator.filter.js +++ /dev/null @@ -1,35 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#filter', assert => { - assert.expect(17); - const async = assert.async(); - const { filter } = AsyncIterator.prototype; - - assert.isFunction(filter); - assert.arity(filter, 1); - assert.name(filter, 'filter'); - assert.looksNative(filter); - assert.nonEnumerable(AsyncIterator.prototype, 'filter'); - - filter.call(createIterator([1, 2, 3]), it => it % 2).toArray().then(it => { - assert.arrayEqual(it, [1, 3], 'basic functionality'); - return filter.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - }).then(() => { - return filter.call(createIterator([1]), () => { throw 42; }).toArray(); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call([], () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(createIterator([1]), undefined), TypeError); - assert.throws(() => filter.call(createIterator([1]), null), TypeError); - assert.throws(() => filter.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.find.js b/tests/tests/esnext.async-iterator.find.js deleted file mode 100644 index 2c745ac2e383..000000000000 --- a/tests/tests/esnext.async-iterator.find.js +++ /dev/null @@ -1,38 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#find', assert => { - assert.expect(18); - const async = assert.async(); - const { find } = AsyncIterator.prototype; - - assert.isFunction(find); - assert.arity(find, 1); - assert.name(find, 'find'); - assert.looksNative(find); - assert.nonEnumerable(AsyncIterator.prototype, 'find'); - - find.call(createIterator([2, 3, 4]), it => it % 2).then(result => { - assert.same(result, 3, 'basic functionality, +'); - return find.call(createIterator([1, 2, 3]), it => it === 4); - }).then(result => { - assert.same(result, undefined, 'basic functionality, -'); - return find.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - }).then(() => { - return find.call(createIterator([1]), () => { throw 42; }); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => find.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => find.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => find.call([], () => { /* empty */ }), TypeError); - assert.throws(() => find.call(createIterator([1]), undefined), TypeError); - assert.throws(() => find.call(createIterator([1]), null), TypeError); - assert.throws(() => find.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.flat-map.js b/tests/tests/esnext.async-iterator.flat-map.js deleted file mode 100644 index e2143642eac7..000000000000 --- a/tests/tests/esnext.async-iterator.flat-map.js +++ /dev/null @@ -1,35 +0,0 @@ -import { createIterator, createIterable } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#flatMap', assert => { - assert.expect(17); - const async = assert.async(); - const { flatMap } = AsyncIterator.prototype; - - assert.isFunction(flatMap); - assert.arity(flatMap, 1); - assert.name(flatMap, 'flatMap'); - assert.looksNative(flatMap); - assert.nonEnumerable(AsyncIterator.prototype, 'flatMap'); - - flatMap.call(createIterator([1, [], 2, createIterable([3, 4]), [5, 6], 'ab']), it => typeof it == 'number' ? -it : it).toArray().then(it => { - assert.arrayEqual(it, [-1, -2, 3, 4, 5, 6, 'ab'], 'basic functionality'); - return flatMap.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - }).then(() => { - return flatMap.call(createIterator([1]), () => { throw 42; }).toArray(); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => flatMap.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call([], () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), undefined), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), null), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.for-each.js b/tests/tests/esnext.async-iterator.for-each.js deleted file mode 100644 index db4776e171dc..000000000000 --- a/tests/tests/esnext.async-iterator.for-each.js +++ /dev/null @@ -1,37 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#forEach', assert => { - assert.expect(17); - const async = assert.async(); - const { forEach } = AsyncIterator.prototype; - - assert.isFunction(forEach); - assert.arity(forEach, 1); - assert.name(forEach, 'forEach'); - assert.looksNative(forEach); - assert.nonEnumerable(AsyncIterator.prototype, 'forEach'); - - const array = []; - - forEach.call(createIterator([1, 2, 3]), it => array.push(it)).then(() => { - assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); - return forEach.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - }).then(() => { - return forEach.call(createIterator([1]), () => { throw 42; }); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call([], () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call(createIterator([1]), undefined), TypeError); - assert.throws(() => forEach.call(createIterator([1]), null), TypeError); - assert.throws(() => forEach.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.from.js b/tests/tests/esnext.async-iterator.from.js deleted file mode 100644 index ab8a80f00371..000000000000 --- a/tests/tests/esnext.async-iterator.from.js +++ /dev/null @@ -1,30 +0,0 @@ -QUnit.test('AsyncIterator.from', assert => { - assert.expect(12); - const async = assert.async(); - const { from } = AsyncIterator; - - assert.isFunction(from); - assert.arity(from, 1); - assert.name(from, 'from'); - assert.looksNative(from); - assert.nonEnumerable(AsyncIterator, 'from'); - - assert.ok(AsyncIterator.from([].values()) instanceof AsyncIterator, 'proxy, iterator'); - - assert.ok(AsyncIterator.from([]) instanceof AsyncIterator, 'proxy, iterable'); - - AsyncIterator.from([1, 2, 3]).toArray().then(result => { - assert.arrayEqual(result, [1, 2, 3], 'just a proxy'); - async(); - }); - - const asyncIterator = Object.assign(new AsyncIterator(), { - next: () => { /* empty */ }, - }); - - assert.same(AsyncIterator.from(asyncIterator), asyncIterator, 'does not wrap AsyncIterator instanses'); - - assert.throws(() => from(undefined), TypeError); - assert.throws(() => from(null), TypeError); - assert.throws(() => from({}), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.map.js b/tests/tests/esnext.async-iterator.map.js deleted file mode 100644 index 6e13fab0ff75..000000000000 --- a/tests/tests/esnext.async-iterator.map.js +++ /dev/null @@ -1,35 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#map', assert => { - assert.expect(17); - const async = assert.async(); - const { map } = AsyncIterator.prototype; - - assert.isFunction(map); - assert.arity(map, 1); - assert.name(map, 'map'); - assert.looksNative(map); - assert.nonEnumerable(AsyncIterator.prototype, 'map'); - - map.call(createIterator([1, 2, 3]), it => it ** 2).toArray().then(it => { - assert.arrayEqual(it, [1, 4, 9], 'basic functionality'); - return map.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - }).then(() => { - return map.call(createIterator([1]), () => { throw 42; }).toArray(); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => map.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => map.call([], () => { /* empty */ }), TypeError); - assert.throws(() => map.call(createIterator([1]), undefined), TypeError); - assert.throws(() => map.call(createIterator([1]), null), TypeError); - assert.throws(() => map.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.reduce.js b/tests/tests/esnext.async-iterator.reduce.js deleted file mode 100644 index 57a88d8bff2a..000000000000 --- a/tests/tests/esnext.async-iterator.reduce.js +++ /dev/null @@ -1,42 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#reduce', assert => { - assert.expect(20); - const async = assert.async(); - const { reduce } = AsyncIterator.prototype; - - assert.isFunction(reduce); - assert.arity(reduce, 1); - assert.name(reduce, 'reduce'); - assert.looksNative(reduce); - assert.nonEnumerable(AsyncIterator.prototype, 'reduce'); - - reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1).then(it => { - assert.same(it, 7, 'basic functionality, initial'); - return reduce.call(createIterator([2]), function (a, b) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 2, 'arguments length'); - assert.same(a, 1, 'argument 1'); - assert.same(b, 2, 'argument 2'); - }, 1); - }).then(() => { - return reduce.call(createIterator([1, 2, 3]), (a, b) => a + b); - }).then(it => { - assert.same(it, 6, 'basic functionality, no initial'); - return reduce.call(createIterator([]), (a, b) => a + b); - }).catch(() => { - assert.ok(true, 'reduce an empty interble with no initial'); - return reduce.call(createIterator([1]), () => { throw 42; }, 1); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => reduce.call(undefined, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call(null, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call({}, () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call([], () => { /* empty */ }, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), undefined, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), null, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), {}, 1), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.some.js b/tests/tests/esnext.async-iterator.some.js deleted file mode 100644 index 79cae5921610..000000000000 --- a/tests/tests/esnext.async-iterator.some.js +++ /dev/null @@ -1,38 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('AsyncIterator#some', assert => { - assert.expect(18); - const async = assert.async(); - const { some } = AsyncIterator.prototype; - - assert.isFunction(some); - assert.arity(some, 1); - assert.name(some, 'some'); - assert.looksNative(some); - assert.nonEnumerable(AsyncIterator.prototype, 'some'); - - some.call(createIterator([1, 2, 3]), it => it === 2).then(result => { - assert.ok(result, 'basic functionality, +'); - return some.call(createIterator([1, 2, 3]), it => it === 4); - }).then(result => { - assert.ok(!result, 'basic functionality, -'); - return some.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - }).then(() => { - return some.call(createIterator([1]), () => { throw 42; }); - }).catch(error => { - assert.same(error, 42, 'rejection on a callback error'); - }).then(() => async()); - - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => some.call([], () => { /* empty */ }), TypeError); - assert.throws(() => some.call(createIterator([1]), undefined), TypeError); - assert.throws(() => some.call(createIterator([1]), null), TypeError); - assert.throws(() => some.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.async-iterator.take.js b/tests/tests/esnext.async-iterator.take.js deleted file mode 100644 index a55b51383b3a..000000000000 --- a/tests/tests/esnext.async-iterator.take.js +++ /dev/null @@ -1,32 +0,0 @@ -import { createIterator } from '../helpers/helpers'; - -QUnit.test('AsyncIterator#take', assert => { - assert.expect(14); - const async = assert.async(); - const { take } = AsyncIterator.prototype; - - assert.isFunction(take); - assert.arity(take, 1); - assert.name(take, 'take'); - assert.looksNative(take); - assert.nonEnumerable(AsyncIterator.prototype, 'take'); - - take.call(createIterator([1, 2, 3]), 2).toArray().then(it => { - assert.arrayEqual(it, [1, 2], 'basic functionality'); - return take.call(createIterator([1, 2, 3]), 1.5).toArray(); - }).then(it => { - assert.arrayEqual(it, [1], 'float'); - return take.call(createIterator([1, 2, 3]), 4).toArray(); - }).then(it => { - assert.arrayEqual(it, [1, 2, 3], 'big'); - return take.call(createIterator([1, 2, 3]), 0).toArray(); - }).then(it => { - assert.arrayEqual(it, [], 'zero'); - }).then(() => async()); - - assert.throws(() => take.call(undefined, 1), TypeError); - assert.throws(() => take.call(null, 1), TypeError); - assert.throws(() => take.call({}, 1), TypeError); - assert.throws(() => take.call([], 1), TypeError); - assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); -}); diff --git a/tests/tests/esnext.async-iterator.to-array.js b/tests/tests/esnext.async-iterator.to-array.js deleted file mode 100644 index 7357f50e2a6b..000000000000 --- a/tests/tests/esnext.async-iterator.to-array.js +++ /dev/null @@ -1,23 +0,0 @@ -import { createIterator } from '../helpers/helpers'; - -QUnit.test('AsyncIterator#toArray', assert => { - assert.expect(10); - const async = assert.async(); - const { toArray } = AsyncIterator.prototype; - - assert.isFunction(toArray); - assert.arity(toArray, 0); - assert.name(toArray, 'toArray'); - assert.looksNative(toArray); - assert.nonEnumerable(AsyncIterator.prototype, 'toArray'); - - toArray.call(createIterator([1, 2, 3])).then(it => { - assert.arrayEqual(it, [1, 2, 3]); - async(); - }); - - assert.throws(() => toArray.call(undefined), TypeError); - assert.throws(() => toArray.call(null), TypeError); - assert.throws(() => toArray.call({}), TypeError); - assert.throws(() => toArray.call([]), TypeError); -}); diff --git a/tests/tests/esnext.composite-key.js b/tests/tests/esnext.composite-key.js deleted file mode 100644 index 2b3232e0ceb4..000000000000 --- a/tests/tests/esnext.composite-key.js +++ /dev/null @@ -1,46 +0,0 @@ -/* eslint-disable no-self-compare */ -import { FREEZING } from '../helpers/constants'; - -const { getPrototypeOf, isFrozen } = Object; - -QUnit.test('compositeKey', assert => { - assert.isFunction(compositeKey); - assert.name(compositeKey, 'compositeKey'); - assert.looksNative(compositeKey); - - const key = compositeKey({}); - assert.same(typeof key, 'object'); - assert.same({}.toString.call(key), '[object Object]'); - assert.same(getPrototypeOf(key), null); - if (FREEZING) assert.ok(isFrozen(key)); - - const a = ['a']; - const b = ['b']; - const c = ['c']; - - assert.ok(compositeKey(a) === compositeKey(a)); - assert.ok(compositeKey(a) !== compositeKey(['a'])); - assert.ok(compositeKey(a) !== compositeKey(a, 1)); - assert.ok(compositeKey(a) !== compositeKey(a, b)); - assert.ok(compositeKey(a, 1) === compositeKey(a, 1)); - assert.ok(compositeKey(a, b) === compositeKey(a, b)); - assert.ok(compositeKey(a, b) !== compositeKey(b, a)); - assert.ok(compositeKey(a, b, c) === compositeKey(a, b, c)); - assert.ok(compositeKey(a, b, c) !== compositeKey(c, b, a)); - assert.ok(compositeKey(a, b, c) !== compositeKey(a, c, b)); - assert.ok(compositeKey(a, b, c, 1) !== compositeKey(a, b, c)); - assert.ok(compositeKey(a, b, c, 1) === compositeKey(a, b, c, 1)); - assert.ok(compositeKey(1, a) === compositeKey(1, a)); - assert.ok(compositeKey(1, a) !== compositeKey(a, 1)); - assert.ok(compositeKey(1, a, 2, b) === compositeKey(1, a, 2, b)); - assert.ok(compositeKey(1, a, 2, b) !== compositeKey(1, a, b, 2)); - assert.ok(compositeKey(1, 2, a, b) === compositeKey(1, 2, a, b)); - assert.ok(compositeKey(1, 2, a, b) !== compositeKey(1, a, b, 2)); - assert.ok(compositeKey(a, a) === compositeKey(a, a)); - assert.ok(compositeKey(a, a) !== compositeKey(a, ['a'])); - assert.ok(compositeKey(a, a) !== compositeKey(a, b)); - - assert.throws(() => compositeKey(), TypeError); - assert.throws(() => compositeKey(1, 2), TypeError); - assert.throws(() => compositeKey('foo', null, true), TypeError); -}); diff --git a/tests/tests/esnext.composite-symbol.js b/tests/tests/esnext.composite-symbol.js deleted file mode 100644 index 7dd1c1fc526c..000000000000 --- a/tests/tests/esnext.composite-symbol.js +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint-disable no-self-compare */ -QUnit.test('compositeSymbol', assert => { - assert.isFunction(compositeSymbol); - assert.name(compositeSymbol, 'compositeSymbol'); - assert.looksNative(compositeSymbol); - - assert.ok(Object(compositeSymbol({})) instanceof Symbol); - - const a = ['a']; - const b = ['b']; - const c = ['c']; - - assert.ok(compositeSymbol(a) === compositeSymbol(a)); - assert.ok(compositeSymbol(a) !== compositeSymbol(['a'])); - assert.ok(compositeSymbol(a) !== compositeSymbol(a, 1)); - assert.ok(compositeSymbol(a) !== compositeSymbol(a, b)); - assert.ok(compositeSymbol(a, 1) === compositeSymbol(a, 1)); - assert.ok(compositeSymbol(a, b) === compositeSymbol(a, b)); - assert.ok(compositeSymbol(a, b) !== compositeSymbol(b, a)); - assert.ok(compositeSymbol(a, b, c) === compositeSymbol(a, b, c)); - assert.ok(compositeSymbol(a, b, c) !== compositeSymbol(c, b, a)); - assert.ok(compositeSymbol(a, b, c) !== compositeSymbol(a, c, b)); - assert.ok(compositeSymbol(a, b, c, 1) !== compositeSymbol(a, b, c)); - assert.ok(compositeSymbol(a, b, c, 1) === compositeSymbol(a, b, c, 1)); - assert.ok(compositeSymbol(1, a) === compositeSymbol(1, a)); - assert.ok(compositeSymbol(1, a) !== compositeSymbol(a, 1)); - assert.ok(compositeSymbol(1, a, 2, b) === compositeSymbol(1, a, 2, b)); - assert.ok(compositeSymbol(1, a, 2, b) !== compositeSymbol(1, a, b, 2)); - assert.ok(compositeSymbol(1, 2, a, b) === compositeSymbol(1, 2, a, b)); - assert.ok(compositeSymbol(1, 2, a, b) !== compositeSymbol(1, a, b, 2)); - assert.ok(compositeSymbol(a, a) === compositeSymbol(a, a)); - assert.ok(compositeSymbol(a, a) !== compositeSymbol(a, ['a'])); - assert.ok(compositeSymbol(a, a) !== compositeSymbol(a, b)); - assert.ok(compositeSymbol() === compositeSymbol()); - assert.ok(compositeSymbol(1, 2) === compositeSymbol(1, 2)); - assert.ok(compositeSymbol(1, 2) !== compositeSymbol(2, 1)); - assert.ok(compositeSymbol('foo', null, true) === compositeSymbol('foo', null, true)); - assert.ok(compositeSymbol('string') === Symbol.for('string')); -}); diff --git a/tests/tests/esnext.iterator.as-indexed-pairs.js b/tests/tests/esnext.iterator.as-indexed-pairs.js deleted file mode 100644 index 0917dce5d0aa..000000000000 --- a/tests/tests/esnext.iterator.as-indexed-pairs.js +++ /dev/null @@ -1,18 +0,0 @@ -import { createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator#asIndexedPairs', assert => { - const { asIndexedPairs } = Iterator.prototype; - - assert.isFunction(asIndexedPairs); - assert.arity(asIndexedPairs, 0); - assert.name(asIndexedPairs, 'asIndexedPairs'); - assert.looksNative(asIndexedPairs); - assert.nonEnumerable(Iterator.prototype, 'asIndexedPairs'); - - assert.arrayEqual(asIndexedPairs.call(createIterator(['a', 'b', 'c'])).toArray().toString(), '0,a,1,b,2,c', 'basic functionality'); - - assert.throws(() => asIndexedPairs.call(undefined, TypeError)); - assert.throws(() => asIndexedPairs.call(null, TypeError)); - assert.throws(() => asIndexedPairs.call({}, TypeError)); - assert.throws(() => asIndexedPairs.call([], TypeError)); -}); diff --git a/tests/tests/esnext.iterator.constructor.js b/tests/tests/esnext.iterator.constructor.js deleted file mode 100644 index 14eafce8c0ff..000000000000 --- a/tests/tests/esnext.iterator.constructor.js +++ /dev/null @@ -1,37 +0,0 @@ -import { createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator', assert => { - assert.isFunction(Iterator); - assert.arity(Iterator, 0); - assert.name(Iterator, 'Iterator'); - assert.looksNative(Iterator); - - const generator = (() => { - try { - return Function('return function*(){}()')(); - } catch { /* empty */ } - })(); - - if (generator) assert.ok(generator instanceof Iterator, 'AsyncGenerator'); - - assert.ok(''[Symbol.iterator]() instanceof Iterator, 'String Iterator'); - assert.ok([].values() instanceof Iterator, 'Array Iterator'); - assert.ok(new Set().values() instanceof Iterator, 'Set Iterator'); - assert.ok('abc'.matchAll(/./g) instanceof Iterator, 'MatchAll Iterator'); - assert.ok(Iterator.from(createIterator([1, 2, 3])) instanceof Iterator, 'From Proxy'); - assert.ok([].values().drop(1) instanceof Iterator, 'Drop Proxy'); - - assert.ok(new Iterator() instanceof Iterator, 'constructor'); - assert.throws(() => Iterator(), 'throws w/o `new`'); -}); - -QUnit.test('Iterator#constructor', assert => { - assert.strictEqual(Iterator.prototype.constructor, Iterator, 'Iterator#constructor is AsyncIterator'); -}); - -QUnit.test('Iterator#@@toStringTag', assert => { - assert.strictEqual(Iterator.prototype[Symbol.toStringTag], 'Iterator', 'Iterator::@@toStringTag is `Iterator`'); - assert.strictEqual(String(Iterator.from({ - next: () => ({ done: Math.random() > 0.9, value: Math.random() * 10 | 0 }), - })), '[object Iterator]', 'correct stringification'); -}); diff --git a/tests/tests/esnext.iterator.drop.js b/tests/tests/esnext.iterator.drop.js deleted file mode 100644 index 714918def202..000000000000 --- a/tests/tests/esnext.iterator.drop.js +++ /dev/null @@ -1,22 +0,0 @@ -import { createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator#drop', assert => { - const { drop } = Iterator.prototype; - - assert.isFunction(drop); - assert.arity(drop, 1); - assert.name(drop, 'drop'); - assert.looksNative(drop); - assert.nonEnumerable(Iterator.prototype, 'drop'); - - assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 1).toArray(), [2, 3], 'basic functionality'); - assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 1.5).toArray(), [2, 3], 'float'); - assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 4).toArray(), [], 'big'); - assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 0).toArray(), [1, 2, 3], 'zero'); - - assert.throws(() => drop.call(undefined, 1), TypeError); - assert.throws(() => drop.call(null, 1), TypeError); - assert.throws(() => drop.call({}, 1), TypeError); - assert.throws(() => drop.call([], 1), TypeError); - assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); -}); diff --git a/tests/tests/esnext.iterator.every.js b/tests/tests/esnext.iterator.every.js deleted file mode 100644 index c974c23603c0..000000000000 --- a/tests/tests/esnext.iterator.every.js +++ /dev/null @@ -1,28 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#every', assert => { - const { every } = Iterator.prototype; - - assert.isFunction(every); - assert.arity(every, 1); - assert.name(every, 'every'); - assert.looksNative(every); - assert.nonEnumerable(Iterator.prototype, 'every'); - - assert.ok(every.call(createIterator([1, 2, 3]), it => typeof it == 'number'), 'basic functionality #1'); - assert.ok(!every.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #2'); - every.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => every.call([], () => { /* empty */ }), TypeError); - assert.throws(() => every.call(createIterator([1]), undefined), TypeError); - assert.throws(() => every.call(createIterator([1]), null), TypeError); - assert.throws(() => every.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.iterator.filter.js b/tests/tests/esnext.iterator.filter.js deleted file mode 100644 index 5e2fcb5e8a70..000000000000 --- a/tests/tests/esnext.iterator.filter.js +++ /dev/null @@ -1,27 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#filter', assert => { - const { filter } = Iterator.prototype; - - assert.isFunction(filter); - assert.arity(filter, 1); - assert.name(filter, 'filter'); - assert.looksNative(filter); - assert.nonEnumerable(Iterator.prototype, 'filter'); - - assert.arrayEqual(filter.call(createIterator([1, 2, 3]), it => it % 2).toArray(), [1, 3], 'basic functionality'); - filter.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call([], () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(createIterator([1]), undefined), TypeError); - assert.throws(() => filter.call(createIterator([1]), null), TypeError); - assert.throws(() => filter.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.iterator.find.js b/tests/tests/esnext.iterator.find.js deleted file mode 100644 index 65522b28cb99..000000000000 --- a/tests/tests/esnext.iterator.find.js +++ /dev/null @@ -1,27 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#find', assert => { - const { find } = Iterator.prototype; - - assert.isFunction(find); - assert.arity(find, 1); - assert.name(find, 'find'); - assert.looksNative(find); - assert.nonEnumerable(Iterator.prototype, 'find'); - - assert.same(find.call(createIterator([1, 2, 3]), it => !(it % 2)), 2, 'basic functionality'); - find.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => find.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => find.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => find.call([], () => { /* empty */ }), TypeError); - assert.throws(() => find.call(createIterator([1]), undefined), TypeError); - assert.throws(() => find.call(createIterator([1]), null), TypeError); - assert.throws(() => find.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.iterator.flat-map.js b/tests/tests/esnext.iterator.flat-map.js deleted file mode 100644 index d3c079cc5262..000000000000 --- a/tests/tests/esnext.iterator.flat-map.js +++ /dev/null @@ -1,31 +0,0 @@ -import { createIterator, createIterable } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#flatMap', assert => { - const { flatMap } = Iterator.prototype; - - assert.isFunction(flatMap); - assert.arity(flatMap, 1); - assert.name(flatMap, 'flatMap'); - assert.looksNative(flatMap); - assert.nonEnumerable(Iterator.prototype, 'flatMap'); - - assert.arrayEqual( - flatMap.call(createIterator([1, [], 2, createIterable([3, 4]), [5, 6], 'ab']), it => typeof it == 'number' ? -it : it).toArray(), - [-1, -2, 3, 4, 5, 6, 'ab'], - 'basic functionality', - ); - flatMap.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - - assert.throws(() => flatMap.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call([], () => { /* empty */ }), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), undefined), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), null), TypeError); - assert.throws(() => flatMap.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.iterator.for-each.js b/tests/tests/esnext.iterator.for-each.js deleted file mode 100644 index 8f1905da12ae..000000000000 --- a/tests/tests/esnext.iterator.for-each.js +++ /dev/null @@ -1,32 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#forEach', assert => { - const { forEach } = Iterator.prototype; - - assert.isFunction(forEach); - assert.arity(forEach, 1); - assert.name(forEach, 'forEach'); - assert.looksNative(forEach); - assert.nonEnumerable(Iterator.prototype, 'forEach'); - - const array = []; - - forEach.call(createIterator([1, 2, 3]), it => array.push(it)); - - assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); - - forEach.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call([], () => { /* empty */ }), TypeError); - assert.throws(() => forEach.call(createIterator([1]), undefined), TypeError); - assert.throws(() => forEach.call(createIterator([1]), null), TypeError); - assert.throws(() => forEach.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.iterator.from.js b/tests/tests/esnext.iterator.from.js deleted file mode 100644 index ebbd65417ded..000000000000 --- a/tests/tests/esnext.iterator.from.js +++ /dev/null @@ -1,21 +0,0 @@ -import { createIterable, createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator.from', assert => { - const { from } = Iterator; - - assert.isFunction(from); - assert.arity(from, 1); - assert.name(from, 'from'); - assert.looksNative(from); - assert.nonEnumerable(Iterator, 'from'); - - assert.ok(Iterator.from(createIterator([1, 2, 3])) instanceof Iterator, 'proxy, iterator'); - - assert.ok(Iterator.from(createIterable([1, 2, 3])) instanceof Iterator, 'proxy, iterable'); - - assert.arrayEqual(Iterator.from(createIterable([1, 2, 3])).toArray(), [1, 2, 3], 'just a proxy'); - - assert.throws(() => from(undefined), TypeError); - assert.throws(() => from(null), TypeError); - assert.throws(() => from({}), TypeError); -}); diff --git a/tests/tests/esnext.iterator.map.js b/tests/tests/esnext.iterator.map.js deleted file mode 100644 index b63542f4a366..000000000000 --- a/tests/tests/esnext.iterator.map.js +++ /dev/null @@ -1,27 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#map', assert => { - const { map } = Iterator.prototype; - - assert.isFunction(map); - assert.arity(map, 1); - assert.name(map, 'map'); - assert.looksNative(map); - assert.nonEnumerable(Iterator.prototype, 'map'); - - assert.arrayEqual(map.call(createIterator([1, 2, 3]), it => it ** 2).toArray(), [1, 4, 9], 'basic functionality'); - map.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }).toArray(); - - assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => map.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => map.call([], () => { /* empty */ }), TypeError); - assert.throws(() => map.call(createIterator([1]), undefined), TypeError); - assert.throws(() => map.call(createIterator([1]), null), TypeError); - assert.throws(() => map.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.iterator.reduce.js b/tests/tests/esnext.iterator.reduce.js deleted file mode 100644 index b423232fcf4d..000000000000 --- a/tests/tests/esnext.iterator.reduce.js +++ /dev/null @@ -1,29 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#reduce', assert => { - const { reduce } = Iterator.prototype; - - assert.isFunction(reduce); - assert.arity(reduce, 1); - assert.name(reduce, 'reduce'); - assert.looksNative(reduce); - assert.nonEnumerable(Iterator.prototype, 'reduce'); - - assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1), 7, 'basic functionality'); - assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b), 6, 'basic functionality, no init'); - reduce.call(createIterator([2]), function (a, b) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 2, 'arguments length'); - assert.same(a, 1, 'argument 1'); - assert.same(b, 2, 'argument 2'); - }, 1); - - assert.throws(() => reduce.call(undefined, (a, b) => a + b, 0), TypeError); - assert.throws(() => reduce.call(null, (a, b) => a + b, 0), TypeError); - assert.throws(() => reduce.call({}, (a, b) => a + b, 0), TypeError); - assert.throws(() => reduce.call([], (a, b) => a + b, 0), TypeError); - assert.throws(() => reduce.call(createIterator([1]), undefined, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), null, 1), TypeError); - assert.throws(() => reduce.call(createIterator([1]), {}, 1), TypeError); -}); diff --git a/tests/tests/esnext.iterator.some.js b/tests/tests/esnext.iterator.some.js deleted file mode 100644 index 31db94afdda1..000000000000 --- a/tests/tests/esnext.iterator.some.js +++ /dev/null @@ -1,28 +0,0 @@ -import { createIterator } from '../helpers/helpers'; -import { STRICT_THIS } from '../helpers/constants'; - -QUnit.test('Iterator#some', assert => { - const { some } = Iterator.prototype; - - assert.isFunction(some); - assert.arity(some, 1); - assert.name(some, 'some'); - assert.looksNative(some); - assert.nonEnumerable(Iterator.prototype, 'some'); - - assert.ok(some.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #1'); - assert.ok(!some.call(createIterator([1, 2, 3]), it => typeof it == 'string'), 'basic functionality #2'); - some.call(createIterator([1]), function (arg) { - assert.same(this, STRICT_THIS, 'this'); - assert.same(arguments.length, 1, 'arguments length'); - assert.same(arg, 1, 'argument'); - }); - - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); - assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => some.call([], () => { /* empty */ }), TypeError); - assert.throws(() => some.call(createIterator([1]), undefined), TypeError); - assert.throws(() => some.call(createIterator([1]), null), TypeError); - assert.throws(() => some.call(createIterator([1]), {}), TypeError); -}); diff --git a/tests/tests/esnext.iterator.take.js b/tests/tests/esnext.iterator.take.js deleted file mode 100644 index 1430f73b509c..000000000000 --- a/tests/tests/esnext.iterator.take.js +++ /dev/null @@ -1,22 +0,0 @@ -import { createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator#take', assert => { - const { take } = Iterator.prototype; - - assert.isFunction(take); - assert.arity(take, 1); - assert.name(take, 'take'); - assert.looksNative(take); - assert.nonEnumerable(Iterator.prototype, 'take'); - - assert.arrayEqual(take.call(createIterator([1, 2, 3]), 2).toArray(), [1, 2], 'basic functionality'); - assert.arrayEqual(take.call(createIterator([1, 2, 3]), 1.5).toArray(), [1], 'float'); - assert.arrayEqual(take.call(createIterator([1, 2, 3]), 4).toArray(), [1, 2, 3], 'big'); - assert.arrayEqual(take.call(createIterator([1, 2, 3]), 0).toArray(), [], 'zero'); - - assert.throws(() => take.call(undefined, 1), TypeError); - assert.throws(() => take.call(null, 1), TypeError); - assert.throws(() => take.call({}, 1), TypeError); - assert.throws(() => take.call([], 1), TypeError); - assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); -}); diff --git a/tests/tests/esnext.iterator.to-array.js b/tests/tests/esnext.iterator.to-array.js deleted file mode 100644 index b7257d061c5c..000000000000 --- a/tests/tests/esnext.iterator.to-array.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createIterable, createIterator } from '../helpers/helpers'; - -QUnit.test('Iterator#toArray', assert => { - const { toArray } = Iterator.prototype; - - assert.isFunction(toArray); - assert.arity(toArray, 0); - assert.name(toArray, 'toArray'); - assert.looksNative(toArray); - assert.nonEnumerable(Iterator.prototype, 'toArray'); - - assert.arrayEqual([1, 2, 3].values().toArray(), [1, 2, 3]); - assert.arrayEqual(new Set([1, 2, 3]).values().toArray(), [1, 2, 3]); - - assert.arrayEqual(Iterator.from('123').toArray(), ['1', '2', '3']); - assert.arrayEqual(Iterator.from(createIterable([1, 2, 3])).toArray(), [1, 2, 3]); - - assert.arrayEqual(toArray.call(createIterator([1, 2, 3])), [1, 2, 3]); - - assert.throws(() => toArray.call(undefined), TypeError); - assert.throws(() => toArray.call(null), TypeError); - assert.throws(() => toArray.call({}), TypeError); - assert.throws(() => toArray.call([]), TypeError); -}); diff --git a/tests/tests/esnext.map.delete-all.js b/tests/tests/esnext.map.delete-all.js deleted file mode 100644 index 1f22ec4f315c..000000000000 --- a/tests/tests/esnext.map.delete-all.js +++ /dev/null @@ -1,31 +0,0 @@ -QUnit.test('Map#deleteAll', assert => { - const { deleteAll } = Map.prototype; - const { from } = Array; - - assert.isFunction(deleteAll); - assert.arity(deleteAll, 0); - assert.name(deleteAll, 'deleteAll'); - assert.looksNative(deleteAll); - assert.nonEnumerable(Map.prototype, 'deleteAll'); - - let set = new Map([[1, 2], [2, 3], [3, 4]]); - assert.same(set.deleteAll(1, 2), true); - assert.deepEqual(from(set), [[3, 4]]); - - set = new Map([[1, 2], [2, 3], [3, 4]]); - assert.same(set.deleteAll(3, 4), false); - assert.deepEqual(from(set), [[1, 2], [2, 3]]); - - set = new Map([[1, 2], [2, 3], [3, 4]]); - assert.same(set.deleteAll(4, 5), false); - assert.deepEqual(from(set), [[1, 2], [2, 3], [3, 4]]); - - set = new Map([[1, 2], [2, 3], [3, 4]]); - assert.same(set.deleteAll(), true); - assert.deepEqual(from(set), [[1, 2], [2, 3], [3, 4]]); - - assert.notThrows(() => !deleteAll.call({ delete() { /* empty */ } }, 1, 2, 3)); - assert.throws(() => deleteAll.call({}, 1, 2, 3), TypeError); - assert.throws(() => deleteAll.call(undefined, 1, 2, 3), TypeError); - assert.throws(() => deleteAll.call(null, 1, 2, 3), TypeError); -}); diff --git a/tests/tests/esnext.map.every.js b/tests/tests/esnext.map.every.js deleted file mode 100644 index 6908589b38fd..000000000000 --- a/tests/tests/esnext.map.every.js +++ /dev/null @@ -1,36 +0,0 @@ -QUnit.test('Map#every', assert => { - const { every } = Map.prototype; - assert.isFunction(every); - assert.arity(every, 1); - assert.name(every, 'every'); - assert.looksNative(every); - assert.nonEnumerable(Map.prototype, 'every'); - - let map = new Map([[9, 1]]); - const context = {}; - map.every(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 9, 'correct index in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - map = new Map([[0, 1], [1, 2], [2, 3]]); - assert.ok(map.every(it => typeof it === 'number')); - assert.ok(map.every(it => it < 4)); - assert.ok(!map.every(it => it < 3)); - assert.ok(!map.every(it => typeof it === 'string')); - assert.ok(map.every(function () { - return +this === 1; - }, 1)); - let result = ''; - map.every((value, key) => result += key); - assert.ok(result === '012'); - assert.ok(map.every((value, key, that) => that === map)); - - assert.throws(() => every.call(new Set(), () => { /* empty */ }), TypeError); - assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => every.call([], () => { /* empty */ }), TypeError); - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.map.filter.js b/tests/tests/esnext.map.filter.js deleted file mode 100644 index 367cb726eb7a..000000000000 --- a/tests/tests/esnext.map.filter.js +++ /dev/null @@ -1,45 +0,0 @@ -QUnit.test('Map#filter', assert => { - const { filter } = Map.prototype; - const { from } = Array; - - assert.isFunction(filter); - assert.arity(filter, 1); - assert.name(filter, 'filter'); - assert.looksNative(filter); - assert.nonEnumerable(Map.prototype, 'filter'); - - const map = new Map([[1, 2]]); - const context = {}; - map.filter(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Map().filter(it => it) instanceof Map); - - assert.deepEqual(from(new Map([ - ['a', 1], - [1, 2], - ['b', 3], - [2, 'q'], - ['c', {}], - [3, 4], - ['d', true], - [4, 5], - ]).filter(it => typeof it === 'number')), [ - ['a', 1], - [1, 2], - ['b', 3], - [3, 4], - [4, 5], - ]); - - assert.throws(() => filter.call(new Set(), () => { /* empty */ }), TypeError); - assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call([], () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.map.from.js b/tests/tests/esnext.map.from.js deleted file mode 100644 index 3ebf217c2f57..000000000000 --- a/tests/tests/esnext.map.from.js +++ /dev/null @@ -1,31 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Map.from', assert => { - const { from } = Map; - const toArray = Array.from; - assert.isFunction(from); - assert.arity(from, 1); - assert.name(from, 'from'); - assert.looksNative(from); - assert.nonEnumerable(Map, 'from'); - assert.ok(Map.from() instanceof Map); - assert.deepEqual(toArray(Map.from([])), []); - assert.deepEqual(toArray(Map.from([[1, 2]])), [[1, 2]]); - assert.deepEqual(toArray(Map.from([[1, 2], [2, 3], [1, 4]])), [[1, 4], [2, 3]]); - assert.deepEqual(toArray(Map.from(createIterable([[1, 2], [2, 3], [1, 4]]))), [[1, 4], [2, 3]]); - const pair = [1, 2]; - const context = {}; - Map.from([pair], function (element, index) { - assert.same(element, pair); - assert.same(index, 0); - assert.same(this, context); - return element; - }, context); - assert.throws(() => from([1, 2])); - let arg = null; - function F(it) { - return arg = it; - } - from.call(F, createIterable([1, 2, 3]), it => it ** 2); - assert.deepEqual(arg, [1, 4, 9]); -}); diff --git a/tests/tests/esnext.map.group-by.js b/tests/tests/esnext.map.group-by.js deleted file mode 100644 index 5794745c0065..000000000000 --- a/tests/tests/esnext.map.group-by.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Map.groupBy', assert => { - const { groupBy } = Map; - const toArray = Array.from; - - assert.isFunction(groupBy); - assert.arity(groupBy, 2); - assert.name(groupBy, 'groupBy'); - assert.looksNative(groupBy); - assert.nonEnumerable(Map, 'groupBy'); - - assert.ok(Map.groupBy([], it => it) instanceof Map); - - assert.deepEqual(toArray(Map.groupBy([], it => it)), []); - assert.deepEqual(toArray(Map.groupBy([1, 2], it => it ** 2)), [[1, [1]], [4, [2]]]); - assert.deepEqual(toArray(Map.groupBy([1, 2, 1], it => it ** 2)), [[1, [1, 1]], [4, [2]]]); - assert.deepEqual(toArray(Map.groupBy(createIterable([1, 2]), it => it ** 2)), [[1, [1]], [4, [2]]]); - - const element = {}; - Map.groupBy([element], it => assert.same(it, element)); - - assert.throws(() => groupBy([1, 2], it => it)); -}); diff --git a/tests/tests/esnext.map.includes.js b/tests/tests/esnext.map.includes.js deleted file mode 100644 index bfa590c54039..000000000000 --- a/tests/tests/esnext.map.includes.js +++ /dev/null @@ -1,25 +0,0 @@ -QUnit.test('Map#includes', assert => { - const { includes } = Map.prototype; - assert.isFunction(includes); - assert.name(includes, 'includes'); - assert.arity(includes, 1); - assert.looksNative(includes); - assert.nonEnumerable(Map.prototype, 'includes'); - - const object = {}; - const map = new Map([[1, 1], [2, 2], [3, 3], [4, -0], [5, object], [6, NaN]]); - assert.ok(map.includes(1)); - assert.ok(map.includes(-0)); - assert.ok(map.includes(0)); - assert.ok(map.includes(object)); - assert.ok(!map.includes(4)); - assert.ok(!map.includes(-0.5)); - assert.ok(!map.includes({})); - assert.ok(map.includes(NaN)); - - assert.throws(() => includes.call(new Set(), 1), TypeError); - assert.throws(() => includes.call({}, 1), TypeError); - assert.throws(() => includes.call([], 1), TypeError); - assert.throws(() => includes.call(undefined, 1), TypeError); - assert.throws(() => includes.call(null, 1), TypeError); -}); diff --git a/tests/tests/esnext.map.key-by.js b/tests/tests/esnext.map.key-by.js deleted file mode 100644 index 8135eef41986..000000000000 --- a/tests/tests/esnext.map.key-by.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Map.keyBy', assert => { - const { keyBy } = Map; - const toArray = Array.from; - - assert.isFunction(keyBy); - assert.arity(keyBy, 2); - assert.name(keyBy, 'keyBy'); - assert.looksNative(keyBy); - assert.nonEnumerable(Map, 'keyBy'); - - assert.ok(Map.keyBy([], it => it) instanceof Map); - - assert.deepEqual(toArray(Map.keyBy([], it => it)), []); - assert.deepEqual(toArray(Map.keyBy([1, 2], it => it ** 2)), [[1, 1], [4, 2]]); - assert.deepEqual(toArray(Map.keyBy([1, 2, 1], it => it ** 2)), [[1, 1], [4, 2]]); - assert.deepEqual(toArray(Map.keyBy(createIterable([1, 2]), it => it ** 2)), [[1, 1], [4, 2]]); - - const element = {}; - Map.keyBy([element], it => assert.same(it, element)); - - assert.throws(() => keyBy([1, 2], it => it)); -}); diff --git a/tests/tests/esnext.map.map-keys.js b/tests/tests/esnext.map.map-keys.js deleted file mode 100644 index 7ba34e3e197a..000000000000 --- a/tests/tests/esnext.map.map-keys.js +++ /dev/null @@ -1,48 +0,0 @@ -QUnit.test('Map#mapKeys', assert => { - const { mapKeys } = Map.prototype; - const { from } = Array; - - assert.isFunction(mapKeys); - assert.arity(mapKeys, 1); - assert.name(mapKeys, 'mapKeys'); - assert.looksNative(mapKeys); - assert.nonEnumerable(Map.prototype, 'mapKeys'); - - const map = new Map([[1, 2]]); - const context = {}; - map.mapKeys(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Map().mapKeys(it => it) instanceof Map); - - assert.deepEqual(from(new Map([ - ['a', 1], - [1, 2], - ['b', 3], - [2, 'q'], - ['c', {}], - [3, 4], - ['d', true], - [4, 5], - ]).mapKeys((value, key) => `${ key }${ value }`)), [ - ['a1', 1], - ['12', 2], - ['b3', 3], - ['2q', 'q'], - ['c[object Object]', {}], - ['34', 4], - ['dtrue', true], - ['45', 5], - ]); - - assert.throws(() => mapKeys.call(new Set(), () => { /* empty */ }), TypeError); - assert.throws(() => mapKeys.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => mapKeys.call([], () => { /* empty */ }), TypeError); - assert.throws(() => mapKeys.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => mapKeys.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.map.map-values.js b/tests/tests/esnext.map.map-values.js deleted file mode 100644 index 5d68964c91e1..000000000000 --- a/tests/tests/esnext.map.map-values.js +++ /dev/null @@ -1,48 +0,0 @@ -QUnit.test('Map#mapValues', assert => { - const { mapValues } = Map.prototype; - const { from } = Array; - - assert.isFunction(mapValues); - assert.arity(mapValues, 1); - assert.name(mapValues, 'mapValues'); - assert.looksNative(mapValues); - assert.nonEnumerable(Map.prototype, 'mapValues'); - - const map = new Map([[1, 2]]); - const context = {}; - map.mapValues(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Map().mapValues(it => it) instanceof Map); - - assert.deepEqual(from(new Map([ - ['a', 1], - [1, 2], - ['b', 3], - [2, 'q'], - ['c', {}], - [3, 4], - ['d', true], - [4, 5], - ]).mapValues((value, key) => `${ key }${ value }`)), [ - ['a', 'a1'], - [1, '12'], - ['b', 'b3'], - [2, '2q'], - ['c', 'c[object Object]'], - [3, '34'], - ['d', 'dtrue'], - [4, '45'], - ]); - - assert.throws(() => mapValues.call(new Set(), () => { /* empty */ }), TypeError); - assert.throws(() => mapValues.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => mapValues.call([], () => { /* empty */ }), TypeError); - assert.throws(() => mapValues.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => mapValues.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.map.merge.js b/tests/tests/esnext.map.merge.js deleted file mode 100644 index 7a4b0b4822ab..000000000000 --- a/tests/tests/esnext.map.merge.js +++ /dev/null @@ -1,25 +0,0 @@ -QUnit.test('Map#merge', assert => { - const { merge } = Map.prototype; - const { from } = Array; - - assert.isFunction(merge); - assert.arity(merge, 1); - assert.name(merge, 'merge'); - assert.looksNative(merge); - assert.nonEnumerable(Map.prototype, 'merge'); - - const map = new Map([[1, 2]]); - const result = map.merge([[3, 4]]); - assert.ok(result === map); - assert.ok(result instanceof Map); - - assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[5, 6]])), [[1, 2], [3, 4], [5, 6]]); - assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[3, 5], [5, 6]])), [[1, 2], [3, 5], [5, 6]]); - assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([])), [[1, 2], [3, 4]]); - - assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[3, 5]], [[5, 6]])), [[1, 2], [3, 5], [5, 6]]); - - assert.throws(() => merge.call({}, [[1, 2]]), TypeError); - assert.throws(() => merge.call(undefined, [[1, 2]]), TypeError); - assert.throws(() => merge.call(null, [[1, 2]]), TypeError); -}); diff --git a/tests/tests/esnext.map.of.js b/tests/tests/esnext.map.of.js deleted file mode 100644 index 9458d910d951..000000000000 --- a/tests/tests/esnext.map.of.js +++ /dev/null @@ -1,19 +0,0 @@ -QUnit.test('Map.of', assert => { - const { of } = Map; - const toArray = Array.from; - assert.isFunction(of); - assert.arity(of, 0); - assert.name(of, 'of'); - assert.looksNative(of); - assert.nonEnumerable(Map, 'of'); - assert.ok(Map.of() instanceof Map); - assert.deepEqual(toArray(Map.of([1, 2])), [[1, 2]]); - assert.deepEqual(toArray(Map.of([1, 2], [2, 3], [1, 4])), [[1, 4], [2, 3]]); - assert.throws(() => of(1)); - let arg = null; - function F(it) { - return arg = it; - } - of.call(F, 1, 2, 3); - assert.deepEqual(arg, [1, 2, 3]); -}); diff --git a/tests/tests/esnext.map.some.js b/tests/tests/esnext.map.some.js deleted file mode 100644 index bb2d9b137e47..000000000000 --- a/tests/tests/esnext.map.some.js +++ /dev/null @@ -1,39 +0,0 @@ -QUnit.test('Map#some', assert => { - const { some } = Map.prototype; - assert.isFunction(some); - assert.arity(some, 1); - assert.name(some, 'some'); - assert.looksNative(some); - assert.nonEnumerable(Map.prototype, 'some'); - - let map = new Map([[9, 1]]); - const context = {}; - map.some(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 9, 'correct index in callback'); - assert.same(that, map, 'correct link to map in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - map = new Map([[0, 1], [1, '2'], [2, 3]]); - assert.ok(map.some(it => typeof it === 'number')); - assert.ok(map.some(it => it < 3)); - assert.ok(!map.some(it => it < 0)); - assert.ok(map.some(it => typeof it === 'string')); - assert.ok(!map.some(function () { - return +this !== 1; - }, 1)); - let result = ''; - map.some((value, key) => { - result += key; - return false; - }); - assert.same(result, '012'); - assert.ok(map.some((value, key, that) => that === map)); - - assert.throws(() => some.call(new Set(), () => { /* empty */ }), TypeError); - assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => some.call([], () => { /* empty */ }), TypeError); - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.map.update-or-insert.js b/tests/tests/esnext.map.update-or-insert.js deleted file mode 100644 index b5d286c8468e..000000000000 --- a/tests/tests/esnext.map.update-or-insert.js +++ /dev/null @@ -1,37 +0,0 @@ -QUnit.test('Map#updateOrInsert', assert => { - const { updateOrInsert } = Map.prototype; - assert.isFunction(updateOrInsert); - assert.arity(updateOrInsert, 2); - assert.name(updateOrInsert, 'upsert'); - assert.looksNative(updateOrInsert); - assert.nonEnumerable(Map.prototype, 'upsert'); - - const map = new Map([['a', 2]]); - assert.same(map.updateOrInsert('a', function (value) { - assert.same(arguments.length, 1, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - return value ** 2; - }, () => { - assert.ok(false, 'should not be called'); - return 3; - }), 4, 'returns a correct value'); - assert.same(map.updateOrInsert('b', value => { - assert.ok(false, 'should not be called'); - return value ** 2; - }, function () { - assert.same(arguments.length, 0, 'correct number of callback arguments'); - return 3; - }), 3, 'returns a correct value'); - assert.same(map.size, 2, 'correct size'); - assert.same(map.get('a'), 4, 'correct result #1'); - assert.same(map.get('b'), 3, 'correct result #2'); - - assert.same(new Map([['a', 2]]).updateOrInsert('b', null, () => 3), 3); - assert.same(new Map([['a', 2]]).updateOrInsert('a', value => value ** 2), 4); - - assert.throws(() => new Map().updateOrInsert('a'), TypeError); - assert.throws(() => updateOrInsert.call({}, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => updateOrInsert.call([], 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => updateOrInsert.call(undefined, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => updateOrInsert.call(null, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.map.upsert.js b/tests/tests/esnext.map.upsert.js deleted file mode 100644 index 5c8481e2d611..000000000000 --- a/tests/tests/esnext.map.upsert.js +++ /dev/null @@ -1,37 +0,0 @@ -QUnit.test('Map#upsert', assert => { - const { upsert } = Map.prototype; - assert.isFunction(upsert); - assert.arity(upsert, 2); - assert.name(upsert, 'upsert'); - assert.looksNative(upsert); - assert.nonEnumerable(Map.prototype, 'upsert'); - - const map = new Map([['a', 2]]); - assert.same(map.upsert('a', function (value) { - assert.same(arguments.length, 1, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - return value ** 2; - }, () => { - assert.ok(false, 'should not be called'); - return 3; - }), 4, 'returns a correct value'); - assert.same(map.upsert('b', value => { - assert.ok(false, 'should not be called'); - return value ** 2; - }, function () { - assert.same(arguments.length, 0, 'correct number of callback arguments'); - return 3; - }), 3, 'returns a correct value'); - assert.same(map.size, 2, 'correct size'); - assert.same(map.get('a'), 4, 'correct result #1'); - assert.same(map.get('b'), 3, 'correct result #2'); - - assert.same(new Map([['a', 2]]).upsert('b', null, () => 3), 3); - assert.same(new Map([['a', 2]]).upsert('a', value => value ** 2), 4); - - assert.throws(() => new Map().upsert('a'), TypeError); - assert.throws(() => upsert.call({}, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call([], 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call(undefined, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call(null, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.math.clamp.js b/tests/tests/esnext.math.clamp.js deleted file mode 100644 index a4e66ce738d2..000000000000 --- a/tests/tests/esnext.math.clamp.js +++ /dev/null @@ -1,11 +0,0 @@ -QUnit.test('Math.clamp', assert => { - const { clamp } = Math; - assert.isFunction(clamp); - assert.name(clamp, 'clamp'); - assert.arity(clamp, 3); - assert.looksNative(clamp); - assert.nonEnumerable(Math, 'clamp'); - assert.same(clamp(2, 4, 6), 4); - assert.same(clamp(4, 2, 6), 4); - assert.same(clamp(6, 2, 4), 4); -}); diff --git a/tests/tests/esnext.math.deg-per-rad.js b/tests/tests/esnext.math.deg-per-rad.js deleted file mode 100644 index 96290ef2cc68..000000000000 --- a/tests/tests/esnext.math.deg-per-rad.js +++ /dev/null @@ -1,6 +0,0 @@ -QUnit.test('Math.DEG_PER_RAD', assert => { - const { DEG_PER_RAD } = Math; - assert.ok('DEG_PER_RAD' in Math, 'DEG_PER_RAD in Math'); - assert.nonEnumerable(Math, 'DEG_PER_RAD'); - assert.strictEqual(DEG_PER_RAD, Math.PI / 180, 'Is Math.PI / 180'); -}); diff --git a/tests/tests/esnext.math.degrees.js b/tests/tests/esnext.math.degrees.js deleted file mode 100644 index 38aab5efb86b..000000000000 --- a/tests/tests/esnext.math.degrees.js +++ /dev/null @@ -1,12 +0,0 @@ -QUnit.test('Math.degrees', assert => { - const { degrees } = Math; - assert.isFunction(degrees); - assert.name(degrees, 'degrees'); - assert.arity(degrees, 1); - assert.looksNative(degrees); - assert.nonEnumerable(Math, 'degrees'); - assert.same(degrees(0), 0); - assert.same(degrees(Math.PI / 2), 90); - assert.same(degrees(Math.PI), 180); - assert.same(degrees(3 * Math.PI / 2), 270); -}); diff --git a/tests/tests/esnext.math.fscale.js b/tests/tests/esnext.math.fscale.js deleted file mode 100644 index 8b9a846264a9..000000000000 --- a/tests/tests/esnext.math.fscale.js +++ /dev/null @@ -1,13 +0,0 @@ -QUnit.test('Math.fscale', assert => { - const { fscale, fround, PI } = Math; - assert.isFunction(fscale); - assert.name(fscale, 'fscale'); - assert.arity(fscale, 5); - assert.looksNative(fscale); - assert.nonEnumerable(Math, 'fscale'); - assert.same(fscale(3, 1, 2, 1, 2), 3); - assert.same(fscale(0, 3, 5, 8, 10), 5); - assert.same(fscale(1, 1, 1, 1, 1), NaN); - assert.same(fscale(-1, -1, -1, -1, -1), NaN); - assert.strictEqual(fscale(3, 1, 2, 1, PI), fround((3 - 1) * (PI - 1) / (2 - 1) + 1)); -}); diff --git a/tests/tests/esnext.math.rad-per-deg.js b/tests/tests/esnext.math.rad-per-deg.js deleted file mode 100644 index 56d1f3b249b4..000000000000 --- a/tests/tests/esnext.math.rad-per-deg.js +++ /dev/null @@ -1,6 +0,0 @@ -QUnit.test('Math.RAD_PER_DEG', assert => { - const { RAD_PER_DEG } = Math; - assert.ok('RAD_PER_DEG' in Math, 'RAD_PER_DEG in Math'); - assert.nonEnumerable(Math, 'RAD_PER_DEG'); - assert.strictEqual(RAD_PER_DEG, 180 / Math.PI, 'Is 180 / Math.PI'); -}); diff --git a/tests/tests/esnext.math.radians.js b/tests/tests/esnext.math.radians.js deleted file mode 100644 index 9434cf8735d6..000000000000 --- a/tests/tests/esnext.math.radians.js +++ /dev/null @@ -1,12 +0,0 @@ -QUnit.test('Math.radians', assert => { - const { radians } = Math; - assert.isFunction(radians); - assert.name(radians, 'radians'); - assert.arity(radians, 1); - assert.looksNative(radians); - assert.nonEnumerable(Math, 'radians'); - assert.same(radians(0), 0); - assert.same(radians(90), Math.PI / 2); - assert.same(radians(180), Math.PI); - assert.same(radians(270), 3 * Math.PI / 2); -}); diff --git a/tests/tests/esnext.math.scale.js b/tests/tests/esnext.math.scale.js deleted file mode 100644 index d3f28b8d1032..000000000000 --- a/tests/tests/esnext.math.scale.js +++ /dev/null @@ -1,12 +0,0 @@ -QUnit.test('Math.scale', assert => { - const { scale } = Math; - assert.isFunction(scale); - assert.name(scale, 'scale'); - assert.arity(scale, 5); - assert.looksNative(scale); - assert.nonEnumerable(Math, 'scale'); - assert.same(scale(3, 1, 2, 1, 2), 3); - assert.same(scale(0, 3, 5, 8, 10), 5); - assert.same(scale(1, 1, 1, 1, 1), NaN); - assert.same(scale(-1, -1, -1, -1, -1), NaN); -}); diff --git a/tests/tests/esnext.math.signbit.js b/tests/tests/esnext.math.signbit.js deleted file mode 100644 index 60e913d3dbde..000000000000 --- a/tests/tests/esnext.math.signbit.js +++ /dev/null @@ -1,18 +0,0 @@ -QUnit.test('Math.signbit', assert => { - const { signbit } = Math; - assert.isFunction(signbit); - assert.name(signbit, 'signbit'); - assert.arity(signbit, 1); - assert.looksNative(signbit); - assert.nonEnumerable(Math, 'signbit'); - assert.same(signbit(NaN), NaN); - assert.same(signbit(), NaN); - assert.same(signbit(-0), false); - assert.same(signbit(0), true); - assert.strictEqual(signbit(Infinity), true); - assert.strictEqual(signbit(-Infinity), false); - assert.strictEqual(signbit(13510798882111488), true); - assert.strictEqual(signbit(-13510798882111488), false); - assert.strictEqual(signbit(42.5), true); - assert.strictEqual(signbit(-42.5), false); -}); diff --git a/tests/tests/esnext.number.from-string.js b/tests/tests/esnext.number.from-string.js deleted file mode 100644 index 4303700a64a5..000000000000 --- a/tests/tests/esnext.number.from-string.js +++ /dev/null @@ -1,38 +0,0 @@ -QUnit.test('Number.fromString', assert => { - const { fromString } = Number; - assert.isFunction(fromString); - assert.name(fromString, 'fromString'); - assert.arity(fromString, 2); - assert.looksNative(fromString); - assert.nonEnumerable(Number, 'fromString'); - assert.throws(() => fromString(undefined), TypeError, 'The first argument should be a string #1'); - assert.throws(() => fromString(Object('10')), TypeError, 'The first argument should be a string #1'); - assert.throws(() => fromString(''), SyntaxError, 'Empty string'); - assert.same(fromString('-10', 2), -2, 'Works with negative numbers'); - assert.throws(() => fromString('-'), SyntaxError, '-'); - assert.same(fromString('10'), 10, 'Default radix is 10 #1'); - assert.same(fromString('10', undefined), 10, 'Default radix is 10 #2'); - for (let radix = 2; radix <= 36; ++radix) { - assert.same(fromString('10', radix), radix, `Radix ${ radix }`); - } - assert.throws(() => fromString('10', -4294967294), RangeError, 'Radix uses ToInteger #1'); - assert.same(fromString('10', 2.5), 2, 'Radix uses ToInteger #2'); - assert.same(fromString('42'), 42); - assert.same(fromString('42', 10), 42); - assert.throws(() => fromString('0xc0ffee'), SyntaxError); - assert.throws(() => fromString('0o755'), SyntaxError); - assert.throws(() => fromString('0b00101010'), SyntaxError); - assert.throws(() => fromString('C0FFEE', 16), SyntaxError); - assert.same(fromString('c0ffee', 16), 12648430); - assert.same(fromString('755', 8), 493); - assert.throws(() => fromString(''), SyntaxError); - assert.throws(() => fromString(' '), SyntaxError); - assert.throws(() => fromString(' 1'), SyntaxError); - assert.throws(() => fromString(' \n '), SyntaxError); - assert.throws(() => fromString('x'), SyntaxError); - assert.throws(() => fromString('1234', 0), RangeError); - assert.throws(() => fromString('1234', 1), RangeError); - assert.throws(() => fromString('1234', 37), RangeError); - assert.throws(() => fromString('010'), SyntaxError); - assert.throws(() => fromString('1_000_000_000'), SyntaxError); -}); diff --git a/tests/tests/esnext.observable.js b/tests/tests/esnext.observable.js deleted file mode 100644 index 2276bec56b0a..000000000000 --- a/tests/tests/esnext.observable.js +++ /dev/null @@ -1,61 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('Observable', assert => { - assert.isFunction(Observable); - assert.arity(Observable, 1); - assert.name(Observable, 'Observable'); - assert.looksNative(Observable); - assert.throws(() => Observable(() => { /* empty */ }), 'throws w/o `new`'); - const observable = new Observable(function (subscriptionObserver) { - assert.same(typeof subscriptionObserver, 'object', 'Subscription observer is object'); - assert.same(subscriptionObserver.constructor, Object); - const { next, error, complete } = subscriptionObserver; - assert.isFunction(next); - assert.isFunction(error); - assert.isFunction(complete); - assert.arity(next, 1); - assert.arity(error, 1); - assert.arity(complete, 0); - if (STRICT) { - assert.same(this, undefined, 'correct executor context'); - } - }); - observable.subscribe({}); - assert.ok(observable instanceof Observable); -}); - -QUnit.test('Observable#subscribe', assert => { - assert.isFunction(Observable.prototype.subscribe); - assert.arity(Observable.prototype.subscribe, 1); - assert.name(Observable.prototype.subscribe, 'subscribe'); - assert.looksNative(Observable.prototype.subscribe); - const subscription = new Observable(() => { /* empty */ }).subscribe({}); - assert.same(typeof subscription, 'object', 'Subscription is object'); - assert.same(subscription.constructor, Object); - assert.isFunction(subscription.unsubscribe); - assert.arity(subscription.unsubscribe, 0); -}); - -QUnit.test('Observable#constructor', assert => { - assert.same(Observable.prototype.constructor, Observable); -}); - -QUnit.test('Observable#@@observable', assert => { - assert.isFunction(Observable.prototype[Symbol.observable]); - const observable = new Observable(() => { /* empty*/ }); - assert.same(observable[Symbol.observable](), observable); -}); - -QUnit.test('Observable.of', assert => { - assert.isFunction(Observable.of); - assert.arity(Observable.of, 0); - assert.name(Observable.of, 'of'); - assert.looksNative(Observable.of); -}); - -QUnit.test('Observable.from', assert => { - assert.isFunction(Observable.from); - assert.arity(Observable.from, 1); - assert.name(Observable.from, 'from'); - assert.looksNative(Observable.from); -}); diff --git a/tests/tests/esnext.promise.any.js b/tests/tests/esnext.promise.any.js deleted file mode 100644 index ce9214faa636..000000000000 --- a/tests/tests/esnext.promise.any.js +++ /dev/null @@ -1,53 +0,0 @@ -QUnit.test('Promise.any', assert => { - assert.isFunction(Promise.any); - assert.arity(Promise.any, 1); - assert.looksNative(Promise.any); - assert.nonEnumerable(Promise, 'any'); - assert.ok(Promise.any([1, 2, 3]) instanceof Promise, 'returns a promise'); -}); - -QUnit.test('Promise.any, resolved', assert => { - assert.expect(1); - const async = assert.async(); - Promise.any([ - Promise.resolve(1), - Promise.reject(2), - Promise.resolve(3), - ]).then(it => { - assert.same(it, 1, 'resolved with a correct value'); - async(); - }); -}); - -QUnit.test('Promise.any, rejected #1', assert => { - assert.expect(2); - const async = assert.async(); - Promise.any([ - Promise.reject(1), - Promise.reject(2), - Promise.reject(3), - ]).catch(error => { - assert.ok(error instanceof AggregateError, 'instanceof AggregateError'); - assert.deepEqual(error.errors, [1, 2, 3], 'rejected with a correct value'); - async(); - }); -}); - -QUnit.test('Promise.any, rejected #2', assert => { - assert.expect(1); - const async = assert.async(); - Promise.any().catch(() => { - assert.ok(true, 'rejected as expected'); - async(); - }); -}); - -QUnit.test('Promise.any, rejected #3', assert => { - assert.expect(2); - const async = assert.async(); - Promise.any([]).catch(error => { - assert.ok(error instanceof AggregateError, 'instanceof AggregateError'); - assert.deepEqual(error.errors, [], 'rejected with a correct value'); - async(); - }); -}); diff --git a/tests/tests/esnext.promise.try.js b/tests/tests/esnext.promise.try.js deleted file mode 100644 index 7ed0a317016a..000000000000 --- a/tests/tests/esnext.promise.try.js +++ /dev/null @@ -1,27 +0,0 @@ -QUnit.test('Promise.try', assert => { - assert.isFunction(Promise.try); - assert.arity(Promise.try, 1); - assert.looksNative(Promise.try); - assert.nonEnumerable(Promise, 'try'); - assert.ok(Promise.try(() => 42) instanceof Promise, 'returns a promise'); -}); - -QUnit.test('Promise.try, resolved', assert => { - assert.expect(1); - const async = assert.async(); - Promise.try(() => 42).then(it => { - assert.same(it, 42, 'resolved with a correct value'); - async(); - }); -}); - -QUnit.test('Promise.try, rejected', assert => { - assert.expect(1); - const async = assert.async(); - Promise.try(() => { - throw new Error(); - }).catch(() => { - assert.ok(true, 'rejected as expected'); - async(); - }); -}); diff --git a/tests/tests/esnext.reflect.delete-metadata.js b/tests/tests/esnext.reflect.delete-metadata.js deleted file mode 100644 index a312799aa6da..000000000000 --- a/tests/tests/esnext.reflect.delete-metadata.js +++ /dev/null @@ -1,21 +0,0 @@ -QUnit.test('Reflect.deleteMetadata', assert => { - const { defineMetadata, hasOwnMetadata, deleteMetadata } = Reflect; - const { create } = Object; - assert.isFunction(deleteMetadata); - assert.arity(deleteMetadata, 2); - assert.name(deleteMetadata, 'deleteMetadata'); - assert.looksNative(deleteMetadata); - assert.nonEnumerable(Reflect, 'deleteMetadata'); - assert.throws(() => deleteMetadata('key', undefined, undefined), TypeError); - assert.same(deleteMetadata('key', {}, undefined), false); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.same(deleteMetadata('key', object, undefined), true); - const prototype = {}; - defineMetadata('key', 'value', prototype, undefined); - assert.same(deleteMetadata('key', create(prototype), undefined), false); - object = {}; - defineMetadata('key', 'value', object, undefined); - deleteMetadata('key', object, undefined); - assert.same(hasOwnMetadata('key', object, undefined), false); -}); diff --git a/tests/tests/esnext.reflect.get-metadata-keys.js b/tests/tests/esnext.reflect.get-metadata-keys.js deleted file mode 100644 index b7e02fa8ad4d..000000000000 --- a/tests/tests/esnext.reflect.get-metadata-keys.js +++ /dev/null @@ -1,53 +0,0 @@ -QUnit.test('Reflect.getMetadataKeys', assert => { - const { defineMetadata, getMetadataKeys } = Reflect; - const { create } = Object; - assert.isFunction(getMetadataKeys); - assert.arity(getMetadataKeys, 1); - assert.name(getMetadataKeys, 'getMetadataKeys'); - assert.looksNative(getMetadataKeys); - assert.nonEnumerable(Reflect, 'getMetadataKeys'); - assert.throws(() => getMetadataKeys(undefined, undefined), TypeError); - assert.deepEqual(getMetadataKeys({}, undefined), []); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key']); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key']); - object = {}; - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1']); - object = {}; - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - defineMetadata('key0', 'value', object, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1']); - prototype = {}; - defineMetadata('key2', 'value', prototype, undefined); - object = create(prototype); - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1', 'key2']); - object = {}; - assert.deepEqual(getMetadataKeys({}, 'name'), []); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.deepEqual(getMetadataKeys(object, 'name'), ['key']); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.deepEqual(getMetadataKeys(object, 'name'), ['key']); - object = {}; - defineMetadata('key0', 'value', object, 'name'); - defineMetadata('key1', 'value', object, 'name'); - defineMetadata('key0', 'value', object, 'name'); - assert.deepEqual(getMetadataKeys(object, 'name'), ['key0', 'key1']); - prototype = {}; - defineMetadata('key2', 'value', prototype, 'name'); - object = create(prototype); - defineMetadata('key0', 'value', object, 'name'); - defineMetadata('key1', 'value', object, 'name'); - assert.deepEqual(getMetadataKeys(object, 'name'), ['key0', 'key1', 'key2']); -}); diff --git a/tests/tests/esnext.reflect.get-own-metadata-keys.js b/tests/tests/esnext.reflect.get-own-metadata-keys.js deleted file mode 100644 index 35a53099e400..000000000000 --- a/tests/tests/esnext.reflect.get-own-metadata-keys.js +++ /dev/null @@ -1,53 +0,0 @@ -QUnit.test('Reflect.getOwnMetadataKeys', assert => { - const { defineMetadata, getOwnMetadataKeys } = Reflect; - const { create } = Object; - assert.isFunction(getOwnMetadataKeys); - assert.arity(getOwnMetadataKeys, 1); - assert.name(getOwnMetadataKeys, 'getOwnMetadataKeys'); - assert.looksNative(getOwnMetadataKeys); - assert.nonEnumerable(Reflect, 'getOwnMetadataKeys'); - assert.throws(() => getOwnMetadataKeys(undefined, undefined), TypeError); - assert.deepEqual(getOwnMetadataKeys({}, undefined), []); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key']); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), []); - object = {}; - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); - object = {}; - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - defineMetadata('key0', 'value', object, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); - prototype = {}; - defineMetadata('key2', 'value', prototype, undefined); - object = create(prototype); - defineMetadata('key0', 'value', object, undefined); - defineMetadata('key1', 'value', object, undefined); - assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); - object = {}; - assert.deepEqual(getOwnMetadataKeys({}, 'name'), []); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key']); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.deepEqual(getOwnMetadataKeys(object, 'name'), []); - object = {}; - defineMetadata('key0', 'value', object, 'name'); - defineMetadata('key1', 'value', object, 'name'); - defineMetadata('key0', 'value', object, 'name'); - assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key0', 'key1']); - prototype = {}; - defineMetadata('key2', 'value', prototype, 'name'); - object = create(prototype); - defineMetadata('key0', 'value', object, 'name'); - defineMetadata('key1', 'value', object, 'name'); - assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key0', 'key1']); -}); diff --git a/tests/tests/esnext.reflect.has-metadata.js b/tests/tests/esnext.reflect.has-metadata.js deleted file mode 100644 index cc7b09c62098..000000000000 --- a/tests/tests/esnext.reflect.has-metadata.js +++ /dev/null @@ -1,26 +0,0 @@ -QUnit.test('Reflect.hasMetadata', assert => { - const { defineMetadata, hasMetadata } = Reflect; - const { create } = Object; - assert.isFunction(hasMetadata); - assert.arity(hasMetadata, 2); - assert.name(hasMetadata, 'hasMetadata'); - assert.looksNative(hasMetadata); - assert.nonEnumerable(Reflect, 'hasMetadata'); - assert.throws(() => hasMetadata('key', undefined, undefined), TypeError); - assert.same(hasMetadata('key', {}, undefined), false); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.same(hasMetadata('key', object, undefined), true); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.same(hasMetadata('key', object, undefined), true); - assert.same(hasMetadata('key', {}, 'name'), false); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.same(hasMetadata('key', object, 'name'), true); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.same(hasMetadata('key', object, 'name'), true); -}); diff --git a/tests/tests/esnext.reflect.has-own-metadata.js b/tests/tests/esnext.reflect.has-own-metadata.js deleted file mode 100644 index 6c507db8c05e..000000000000 --- a/tests/tests/esnext.reflect.has-own-metadata.js +++ /dev/null @@ -1,26 +0,0 @@ -QUnit.test('Reflect.hasOwnMetadata', assert => { - const { defineMetadata, hasOwnMetadata } = Reflect; - const { create } = Object; - assert.isFunction(hasOwnMetadata); - assert.arity(hasOwnMetadata, 2); - assert.name(hasOwnMetadata, 'hasOwnMetadata'); - assert.looksNative(hasOwnMetadata); - assert.nonEnumerable(Reflect, 'hasOwnMetadata'); - assert.throws(() => hasOwnMetadata('key', undefined, undefined), TypeError); - assert.same(hasOwnMetadata('key', {}, undefined), false); - let object = {}; - defineMetadata('key', 'value', object, undefined); - assert.same(hasOwnMetadata('key', object, undefined), true); - let prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, undefined); - assert.same(hasOwnMetadata('key', object, undefined), false); - assert.same(hasOwnMetadata('key', {}, 'name'), false); - object = {}; - defineMetadata('key', 'value', object, 'name'); - assert.same(hasOwnMetadata('key', object, 'name'), true); - prototype = {}; - object = create(prototype); - defineMetadata('key', 'value', prototype, 'name'); - assert.same(hasOwnMetadata('key', object, 'name'), false); -}); diff --git a/tests/tests/esnext.reflect.metadata.js b/tests/tests/esnext.reflect.metadata.js deleted file mode 100644 index 8fff46050abf..000000000000 --- a/tests/tests/esnext.reflect.metadata.js +++ /dev/null @@ -1,17 +0,0 @@ -QUnit.test('Reflect.metadata', assert => { - const { metadata, hasOwnMetadata } = Reflect; - assert.isFunction(metadata); - assert.arity(metadata, 2); - assert.name(metadata, 'metadata'); - assert.looksNative(metadata); - assert.isFunction(metadata('key', 'value')); - assert.nonEnumerable(Reflect, 'metadata'); - const decorator = metadata('key', 'value'); - assert.throws(() => decorator(undefined, 'name'), TypeError); - let target = function () { /* empty */ }; - decorator(target); - assert.same(hasOwnMetadata('key', target, undefined), true); - target = {}; - decorator(target, 'name'); - assert.same(hasOwnMetadata('key', target, 'name'), true); -}); diff --git a/tests/tests/esnext.set.add-all.js b/tests/tests/esnext.set.add-all.js deleted file mode 100644 index b5ef4721593c..000000000000 --- a/tests/tests/esnext.set.add-all.js +++ /dev/null @@ -1,22 +0,0 @@ -QUnit.test('Set#addAll', assert => { - const { addAll } = Set.prototype; - const { from } = Array; - - assert.isFunction(addAll); - assert.arity(addAll, 0); - assert.name(addAll, 'addAll'); - assert.looksNative(addAll); - assert.nonEnumerable(Set.prototype, 'addAll'); - - const set = new Set([1]); - assert.same(set.addAll(2), set); - - assert.deepEqual(from(new Set([1, 2, 3]).addAll(4, 5)), [1, 2, 3, 4, 5]); - assert.deepEqual(from(new Set([1, 2, 3]).addAll(3, 4)), [1, 2, 3, 4]); - assert.deepEqual(from(new Set([1, 2, 3]).addAll()), [1, 2, 3]); - - assert.notThrows(() => addAll.call({ add() { /* empty */ } }, 1, 2, 3)); - assert.throws(() => addAll.call({}, 1, 2, 3), TypeError); - assert.throws(() => addAll.call(undefined, 1, 2, 3), TypeError); - assert.throws(() => addAll.call(null, 1, 2, 3), TypeError); -}); diff --git a/tests/tests/esnext.set.delete-all.js b/tests/tests/esnext.set.delete-all.js deleted file mode 100644 index a705ab7abeda..000000000000 --- a/tests/tests/esnext.set.delete-all.js +++ /dev/null @@ -1,31 +0,0 @@ -QUnit.test('Set#deleteAll', assert => { - const { deleteAll } = Set.prototype; - const { from } = Array; - - assert.isFunction(deleteAll); - assert.arity(deleteAll, 0); - assert.name(deleteAll, 'deleteAll'); - assert.looksNative(deleteAll); - assert.nonEnumerable(Set.prototype, 'deleteAll'); - - let set = new Set([1, 2, 3]); - assert.same(set.deleteAll(1, 2), true); - assert.deepEqual(from(set), [3]); - - set = new Set([1, 2, 3]); - assert.same(set.deleteAll(3, 4), false); - assert.deepEqual(from(set), [1, 2]); - - set = new Set([1, 2, 3]); - assert.same(set.deleteAll(4, 5), false); - assert.deepEqual(from(set), [1, 2, 3]); - - set = new Set([1, 2, 3]); - assert.same(set.deleteAll(), true); - assert.deepEqual(from(set), [1, 2, 3]); - - assert.notThrows(() => !deleteAll.call({ delete() { /* empty */ } }, 1, 2, 3)); - assert.throws(() => deleteAll.call({}, 1, 2, 3), TypeError); - assert.throws(() => deleteAll.call(undefined, 1, 2, 3), TypeError); - assert.throws(() => deleteAll.call(null, 1, 2, 3), TypeError); -}); diff --git a/tests/tests/esnext.set.difference.js b/tests/tests/esnext.set.difference.js deleted file mode 100644 index 28a20315604a..000000000000 --- a/tests/tests/esnext.set.difference.js +++ /dev/null @@ -1,25 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Set#difference', assert => { - const { difference } = Set.prototype; - const { from } = Array; - - assert.isFunction(difference); - assert.arity(difference, 1); - assert.name(difference, 'difference'); - assert.looksNative(difference); - assert.nonEnumerable(Set.prototype, 'difference'); - - const set = new Set([1]); - assert.ok(set.difference([2]) !== set); - - assert.deepEqual(from(new Set([1, 2, 3]).difference([4, 5])), [1, 2, 3]); - assert.deepEqual(from(new Set([1, 2, 3]).difference([3, 4])), [1, 2]); - assert.deepEqual(from(new Set([1, 2, 3]).difference(createIterable([3, 4]))), [1, 2]); - - assert.throws(() => new Set([1, 2, 3]).difference(), TypeError); - - assert.throws(() => difference.call({}, [1, 2, 3]), TypeError); - assert.throws(() => difference.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => difference.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/tests/esnext.set.every.js b/tests/tests/esnext.set.every.js deleted file mode 100644 index 2c9d4ce2f49e..000000000000 --- a/tests/tests/esnext.set.every.js +++ /dev/null @@ -1,30 +0,0 @@ -QUnit.test('Set#every', assert => { - const { every } = Set.prototype; - - assert.isFunction(every); - assert.arity(every, 1); - assert.name(every, 'every'); - assert.looksNative(every); - assert.nonEnumerable(Set.prototype, 'every'); - - const set = new Set([1]); - const context = {}; - set.every(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, set, 'correct link to set in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.same(new Set([1, 2, 3]).every(it => typeof it === 'number'), true); - assert.same(new Set(['1', '2', '3']).some(it => typeof it === 'number'), false); - assert.same(new Set([1, '2', 3]).every(it => typeof it === 'number'), false); - assert.same(new Set().every(it => typeof it === 'number'), true); - - assert.throws(() => every.call(new Map(), () => { /* empty */ }), TypeError); - assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => every.call([], () => { /* empty */ }), TypeError); - assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.set.filter.js b/tests/tests/esnext.set.filter.js deleted file mode 100644 index 2d908dd4dfa7..000000000000 --- a/tests/tests/esnext.set.filter.js +++ /dev/null @@ -1,30 +0,0 @@ -QUnit.test('Set#filter', assert => { - const { filter } = Set.prototype; - const { from } = Array; - - assert.isFunction(filter); - assert.arity(filter, 1); - assert.name(filter, 'filter'); - assert.looksNative(filter); - assert.nonEnumerable(Set.prototype, 'filter'); - - const set = new Set([1]); - const context = {}; - set.filter(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, set, 'correct link to set in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Set().filter(it => it) instanceof Set); - - assert.deepEqual(from(new Set([1, 2, 3, 'q', {}, 4, true, 5]).filter(it => typeof it === 'number')), [1, 2, 3, 4, 5]); - - assert.throws(() => filter.call(new Map(), () => { /* empty */ }), TypeError); - assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call([], () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.set.from.js b/tests/tests/esnext.set.from.js deleted file mode 100644 index 6cbaee5a8648..000000000000 --- a/tests/tests/esnext.set.from.js +++ /dev/null @@ -1,30 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Set.from', assert => { - const { from } = Set; - const toArray = Array.from; - assert.isFunction(from); - assert.arity(from, 1); - assert.name(from, 'from'); - assert.looksNative(from); - assert.nonEnumerable(Set, 'from'); - assert.ok(Set.from() instanceof Set); - assert.deepEqual(toArray(Set.from([])), []); - assert.deepEqual(toArray(Set.from([1])), [1]); - assert.deepEqual(toArray(Set.from([1, 2, 3, 2, 1])), [1, 2, 3]); - assert.deepEqual(toArray(Set.from(createIterable([1, 2, 3, 2, 1]))), [1, 2, 3]); - const context = {}; - Set.from([1], function (element, index) { - assert.same(element, 1); - assert.same(index, 0); - assert.same(this, context); - return element; - }, context); - assert.throws(() => from(1)); - let arg = null; - function F(it) { - return arg = it; - } - from.call(F, createIterable([1, 2, 3]), it => it ** 2); - assert.deepEqual(arg, [1, 4, 9]); -}); diff --git a/tests/tests/esnext.set.intersection.js b/tests/tests/esnext.set.intersection.js deleted file mode 100644 index 605e878c1414..000000000000 --- a/tests/tests/esnext.set.intersection.js +++ /dev/null @@ -1,25 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Set#intersection', assert => { - const { intersection } = Set.prototype; - const { from } = Array; - - assert.isFunction(intersection); - assert.arity(intersection, 1); - assert.name(intersection, 'intersection'); - assert.looksNative(intersection); - assert.nonEnumerable(Set.prototype, 'intersection'); - - const set = new Set([1]); - assert.ok(set.intersection([2]) !== set); - - assert.deepEqual(from(new Set([1, 2, 3]).intersection([4, 5])), []); - assert.deepEqual(from(new Set([1, 2, 3]).intersection([2, 3, 4])), [2, 3]); - assert.deepEqual(from(new Set([1, 2, 3]).intersection(createIterable([2, 3, 4]))), [2, 3]); - - assert.throws(() => new Set([1, 2, 3]).intersection(), TypeError); - - assert.throws(() => intersection.call({}, [1, 2, 3]), TypeError); - assert.throws(() => intersection.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => intersection.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/tests/esnext.set.is-disjoint-from.js b/tests/tests/esnext.set.is-disjoint-from.js deleted file mode 100644 index 9cff4fbcd33a..000000000000 --- a/tests/tests/esnext.set.is-disjoint-from.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Set#isDisjointFrom', assert => { - const { isDisjointFrom } = Set.prototype; - - assert.isFunction(isDisjointFrom); - assert.arity(isDisjointFrom, 1); - assert.name(isDisjointFrom, 'isDisjointFrom'); - assert.looksNative(isDisjointFrom); - assert.nonEnumerable(Set.prototype, 'isDisjointFrom'); - - assert.ok(new Set([1]).isDisjointFrom([2])); - assert.ok(!new Set([1]).isDisjointFrom([1])); - assert.ok(new Set([1, 2, 3]).isDisjointFrom([4, 5, 6])); - assert.ok(!new Set([1, 2, 3]).isDisjointFrom([5, 4, 3])); - - assert.ok(new Set([1]).isDisjointFrom(createIterable([2]))); - assert.ok(!new Set([1]).isDisjointFrom(createIterable([1]))); - - assert.throws(() => new Set([1, 2, 3]).isDisjointFrom(), TypeError); - assert.throws(() => isDisjointFrom.call({}, [1, 2, 3]), TypeError); - assert.throws(() => isDisjointFrom.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => isDisjointFrom.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/tests/esnext.set.is-subset-of.js b/tests/tests/esnext.set.is-subset-of.js deleted file mode 100644 index 63ad5d027ac3..000000000000 --- a/tests/tests/esnext.set.is-subset-of.js +++ /dev/null @@ -1,30 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Set#isSubsetOf', assert => { - const { isSubsetOf } = Set.prototype; - - assert.isFunction(isSubsetOf); - assert.arity(isSubsetOf, 1); - assert.name(isSubsetOf, 'isSubsetOf'); - assert.looksNative(isSubsetOf); - assert.nonEnumerable(Set.prototype, 'isSubsetOf'); - - assert.ok(new Set([1]).isSubsetOf([1, 2, 3])); - assert.ok(!new Set([1]).isSubsetOf([2, 3, 4])); - assert.ok(new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2, 1])); - assert.ok(!new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2])); - - assert.ok(new Set([1]).isSubsetOf(createIterable([1, 2, 3]))); - assert.ok(!new Set([1]).isSubsetOf(createIterable([2, 3, 4]))); - - assert.ok(new Set([1]).isSubsetOf({ has: () => true })); - assert.ok(!new Set([1]).isSubsetOf({ has: () => false })); - - assert.ok(isSubsetOf.call('ab', ['a', 'b', 'c'])); - assert.ok(!isSubsetOf.call('ab', ['a'])); - - assert.throws(() => new Set([1, 2, 3]).isSubsetOf(), TypeError); - assert.throws(() => isSubsetOf.call({}, [1, 2, 3]), TypeError); - assert.throws(() => isSubsetOf.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => isSubsetOf.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/tests/esnext.set.is-superset-of.js b/tests/tests/esnext.set.is-superset-of.js deleted file mode 100644 index a37fa47c6f68..000000000000 --- a/tests/tests/esnext.set.is-superset-of.js +++ /dev/null @@ -1,24 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Set#isSupersetOf', assert => { - const { isSupersetOf } = Set.prototype; - - assert.isFunction(isSupersetOf); - assert.arity(isSupersetOf, 1); - assert.name(isSupersetOf, 'isSupersetOf'); - assert.looksNative(isSupersetOf); - assert.nonEnumerable(Set.prototype, 'isSupersetOf'); - - assert.ok(new Set([1, 2, 3]).isSupersetOf([1])); - assert.ok(!new Set([2, 3, 4]).isSupersetOf([1])); - assert.ok(new Set([5, 4, 3, 2, 1]).isSupersetOf([1, 2, 3])); - assert.ok(!new Set([5, 4, 3, 2]).isSupersetOf([1, 2, 3])); - - assert.ok(new Set([1, 2, 3]).isSupersetOf(createIterable([1]))); - assert.ok(!new Set([2, 3, 4]).isSupersetOf(createIterable([1]))); - - assert.throws(() => new Set([1, 2, 3]).isSupersetOf(), TypeError); - assert.throws(() => isSupersetOf.call({}, [1, 2, 3]), TypeError); - assert.throws(() => isSupersetOf.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => isSupersetOf.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/tests/esnext.set.join.js b/tests/tests/esnext.set.join.js deleted file mode 100644 index 65d77668607c..000000000000 --- a/tests/tests/esnext.set.join.js +++ /dev/null @@ -1,19 +0,0 @@ -QUnit.test('Set#join', assert => { - const { join } = Set.prototype; - - assert.isFunction(join); - assert.arity(join, 1); - assert.name(join, 'join'); - assert.looksNative(join); - assert.nonEnumerable(Set.prototype, 'join'); - - assert.strictEqual(new Set([1, 2, 3]).join(), '1,2,3'); - assert.strictEqual(new Set([1, 2, 3]).join(undefined), '1,2,3'); - assert.strictEqual(new Set([1, 2, 3]).join('|'), '1|2|3'); - - assert.throws(() => join.call(new Map()), TypeError); - assert.throws(() => join.call({}), TypeError); - assert.throws(() => join.call([]), TypeError); - assert.throws(() => join.call(undefined), TypeError); - assert.throws(() => join.call(null), TypeError); -}); diff --git a/tests/tests/esnext.set.map.js b/tests/tests/esnext.set.map.js deleted file mode 100644 index 0441d03f3398..000000000000 --- a/tests/tests/esnext.set.map.js +++ /dev/null @@ -1,31 +0,0 @@ -QUnit.test('Set#map', assert => { - const { map } = Set.prototype; - const { from } = Array; - - assert.isFunction(map); - assert.arity(map, 1); - assert.name(map, 'map'); - assert.looksNative(map); - assert.nonEnumerable(Set.prototype, 'map'); - - const set = new Set([1]); - const context = {}; - set.map(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, set, 'correct link to set in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.ok(new Set().map(it => it) instanceof Set); - - assert.deepEqual(from(new Set([1, 2, 3]).map(it => it ** 2)), [1, 4, 9]); - assert.deepEqual(from(new Set([1, 2, 3]).map(it => it % 2)), [1, 0]); - - assert.throws(() => map.call(new Map(), () => { /* empty */ }), TypeError); - assert.throws(() => map.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => map.call([], () => { /* empty */ }), TypeError); - assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.set.of.js b/tests/tests/esnext.set.of.js deleted file mode 100644 index e66854b34ab2..000000000000 --- a/tests/tests/esnext.set.of.js +++ /dev/null @@ -1,19 +0,0 @@ -QUnit.test('Set.of', assert => { - const { of } = Set; - const toArray = Array.from; - assert.isFunction(of); - assert.arity(of, 0); - assert.name(of, 'of'); - assert.looksNative(of); - assert.nonEnumerable(Set, 'of'); - assert.ok(Set.of() instanceof Set); - assert.deepEqual(toArray(Set.of(1)), [1]); - assert.deepEqual(toArray(Set.of(1, 2, 3, 2, 1)), [1, 2, 3]); - assert.throws(() => of(1)); - let arg = null; - function F(it) { - return arg = it; - } - of.call(F, 1, 2, 3); - assert.deepEqual(arg, [1, 2, 3]); -}); diff --git a/tests/tests/esnext.set.some.js b/tests/tests/esnext.set.some.js deleted file mode 100644 index 81022aff629a..000000000000 --- a/tests/tests/esnext.set.some.js +++ /dev/null @@ -1,30 +0,0 @@ -QUnit.test('Set#some', assert => { - const { some } = Set.prototype; - - assert.isFunction(some); - assert.arity(some, 1); - assert.name(some, 'some'); - assert.looksNative(some); - assert.nonEnumerable(Set.prototype, 'some'); - - const set = new Set([1]); - const context = {}; - set.some(function (value, key, that) { - assert.same(arguments.length, 3, 'correct number of callback arguments'); - assert.same(value, 1, 'correct value in callback'); - assert.same(key, 1, 'correct key in callback'); - assert.same(that, set, 'correct link to set in callback'); - assert.same(this, context, 'correct callback context'); - }, context); - - assert.same(new Set([1, 2, 3]).some(it => typeof it === 'number'), true); - assert.same(new Set(['1', '2', '3']).some(it => typeof it === 'number'), false); - assert.same(new Set([1, '2', 3]).some(it => typeof it === 'number'), true); - assert.same(new Set().some(it => typeof it === 'number'), false); - - assert.throws(() => some.call(new Map(), () => { /* empty */ }), TypeError); - assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); - assert.throws(() => some.call([], () => { /* empty */ }), TypeError); - assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); - assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.set.symmetric-difference.js b/tests/tests/esnext.set.symmetric-difference.js deleted file mode 100644 index d32540508791..000000000000 --- a/tests/tests/esnext.set.symmetric-difference.js +++ /dev/null @@ -1,25 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Set#symmetricDifference', assert => { - const { symmetricDifference } = Set.prototype; - const { from } = Array; - - assert.isFunction(symmetricDifference); - assert.arity(symmetricDifference, 1); - assert.name(symmetricDifference, 'symmetricDifference'); - assert.looksNative(symmetricDifference); - assert.nonEnumerable(Set.prototype, 'symmetricDifference'); - - const set = new Set([1]); - assert.ok(set.symmetricDifference([2]) !== set); - - assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference([4, 5])), [1, 2, 3, 4, 5]); - assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference([3, 4])), [1, 2, 4]); - assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createIterable([3, 4]))), [1, 2, 4]); - - assert.throws(() => new Set([1, 2, 3]).symmetricDifference(), TypeError); - - assert.throws(() => symmetricDifference.call({}, [1, 2, 3]), TypeError); - assert.throws(() => symmetricDifference.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => symmetricDifference.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/tests/esnext.set.union.js b/tests/tests/esnext.set.union.js deleted file mode 100644 index bed38ad883e5..000000000000 --- a/tests/tests/esnext.set.union.js +++ /dev/null @@ -1,25 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('Set#union', assert => { - const { union } = Set.prototype; - const { from } = Array; - - assert.isFunction(union); - assert.arity(union, 1); - assert.name(union, 'union'); - assert.looksNative(union); - assert.nonEnumerable(Set.prototype, 'union'); - - const set = new Set([1]); - assert.ok(set.union([2]) !== set); - - assert.deepEqual(from(new Set([1, 2, 3]).union([4, 5])), [1, 2, 3, 4, 5]); - assert.deepEqual(from(new Set([1, 2, 3]).union([3, 4])), [1, 2, 3, 4]); - assert.deepEqual(from(new Set([1, 2, 3]).union(createIterable([3, 4]))), [1, 2, 3, 4]); - - assert.throws(() => new Set([1, 2, 3]).union(), TypeError); - - assert.throws(() => union.call({}, [1, 2, 3]), TypeError); - assert.throws(() => union.call(undefined, [1, 2, 3]), TypeError); - assert.throws(() => union.call(null, [1, 2, 3]), TypeError); -}); diff --git a/tests/tests/esnext.string.at.js b/tests/tests/esnext.string.at.js deleted file mode 100644 index ec3d5f95655a..000000000000 --- a/tests/tests/esnext.string.at.js +++ /dev/null @@ -1,97 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('String#at', assert => { - const { at } = String.prototype; - assert.isFunction(at); - assert.arity(at, 1); - assert.name(at, 'at'); - assert.looksNative(at); - assert.nonEnumerable(String.prototype, 'at'); - // String that starts with a BMP symbol - assert.strictEqual('abc\uD834\uDF06def'.at(-Infinity), ''); - assert.strictEqual('abc\uD834\uDF06def'.at(-1), ''); - assert.strictEqual('abc\uD834\uDF06def'.at(-0), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(+0), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(1), 'b'); - assert.strictEqual('abc\uD834\uDF06def'.at(3), '\uD834\uDF06'); - assert.strictEqual('abc\uD834\uDF06def'.at(4), '\uDF06'); - assert.strictEqual('abc\uD834\uDF06def'.at(5), 'd'); - assert.strictEqual('abc\uD834\uDF06def'.at(42), ''); - assert.strictEqual('abc\uD834\uDF06def'.at(Infinity), ''); - assert.strictEqual('abc\uD834\uDF06def'.at(null), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(undefined), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(false), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(NaN), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(''), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at('_'), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at('1'), 'b'); - assert.strictEqual('abc\uD834\uDF06def'.at([]), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at({}), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(-0.9), 'a'); - assert.strictEqual('abc\uD834\uDF06def'.at(1.9), 'b'); - assert.strictEqual('abc\uD834\uDF06def'.at(7.9), 'f'); - assert.strictEqual('abc\uD834\uDF06def'.at(2 ** 32), ''); - // String that starts with an astral symbol - assert.strictEqual('\uD834\uDF06def'.at(-Infinity), ''); - assert.strictEqual('\uD834\uDF06def'.at(-1), ''); - assert.strictEqual('\uD834\uDF06def'.at(-0), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at(0), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at(1), '\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at(2), 'd'); - assert.strictEqual('\uD834\uDF06def'.at(3), 'e'); - assert.strictEqual('\uD834\uDF06def'.at(4), 'f'); - assert.strictEqual('\uD834\uDF06def'.at(42), ''); - assert.strictEqual('\uD834\uDF06def'.at(Infinity), ''); - assert.strictEqual('\uD834\uDF06def'.at(null), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at(undefined), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at(), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at(false), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at(NaN), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at(''), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at('_'), '\uD834\uDF06'); - assert.strictEqual('\uD834\uDF06def'.at('1'), '\uDF06'); - // Lone high surrogates - assert.strictEqual('\uD834abc'.at(-Infinity), ''); - assert.strictEqual('\uD834abc'.at(-1), ''); - assert.strictEqual('\uD834abc'.at(-0), '\uD834'); - assert.strictEqual('\uD834abc'.at(0), '\uD834'); - assert.strictEqual('\uD834abc'.at(1), 'a'); - assert.strictEqual('\uD834abc'.at(42), ''); - assert.strictEqual('\uD834abc'.at(Infinity), ''); - assert.strictEqual('\uD834abc'.at(null), '\uD834'); - assert.strictEqual('\uD834abc'.at(undefined), '\uD834'); - assert.strictEqual('\uD834abc'.at(), '\uD834'); - assert.strictEqual('\uD834abc'.at(false), '\uD834'); - assert.strictEqual('\uD834abc'.at(NaN), '\uD834'); - assert.strictEqual('\uD834abc'.at(''), '\uD834'); - assert.strictEqual('\uD834abc'.at('_'), '\uD834'); - assert.strictEqual('\uD834abc'.at('1'), 'a'); - // Lone low surrogates - assert.strictEqual('\uDF06abc'.at(-Infinity), ''); - assert.strictEqual('\uDF06abc'.at(-1), ''); - assert.strictEqual('\uDF06abc'.at(-0), '\uDF06'); - assert.strictEqual('\uDF06abc'.at(0), '\uDF06'); - assert.strictEqual('\uDF06abc'.at(1), 'a'); - assert.strictEqual('\uDF06abc'.at(42), ''); - assert.strictEqual('\uDF06abc'.at(Infinity), ''); - assert.strictEqual('\uDF06abc'.at(null), '\uDF06'); - assert.strictEqual('\uDF06abc'.at(undefined), '\uDF06'); - assert.strictEqual('\uDF06abc'.at(), '\uDF06'); - assert.strictEqual('\uDF06abc'.at(false), '\uDF06'); - assert.strictEqual('\uDF06abc'.at(NaN), '\uDF06'); - assert.strictEqual('\uDF06abc'.at(''), '\uDF06'); - assert.strictEqual('\uDF06abc'.at('_'), '\uDF06'); - assert.strictEqual('\uDF06abc'.at('1'), 'a'); - assert.strictEqual(at.call(42, 0), '4'); - assert.strictEqual(at.call(42, 1), '2'); - assert.strictEqual(at.call({ - toString() { - return 'abc'; - }, - }, 2), 'c'); - if (STRICT) { - assert.throws(() => at.call(null, 0), TypeError); - assert.throws(() => at.call(undefined, 0), TypeError); - } -}); diff --git a/tests/tests/esnext.string.code-points.js b/tests/tests/esnext.string.code-points.js deleted file mode 100644 index b51a22bc3d7c..000000000000 --- a/tests/tests/esnext.string.code-points.js +++ /dev/null @@ -1,50 +0,0 @@ -import { GLOBAL } from '../helpers/constants'; - -const Symbol = GLOBAL.Symbol || {}; - -QUnit.test('String#codePoints', assert => { - const { codePoints } = String.prototype; - assert.isFunction(codePoints); - assert.arity(codePoints, 0); - assert.name(codePoints, 'codePoints'); - assert.looksNative(codePoints); - assert.nonEnumerable(String.prototype, 'codePoints'); - let iterator = 'qwe'.codePoints(); - assert.isIterator(iterator); - assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'String Iterator'); - assert.strictEqual(String(iterator), '[object String Iterator]'); - assert.deepEqual(iterator.next(), { - value: { codePoint: 113, position: 0 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: { codePoint: 119, position: 1 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: { codePoint: 101, position: 2 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); - iterator = '𠮷𠮷𠮷'.codePoints(); - assert.deepEqual(iterator.next(), { - value: { codePoint: 134071, position: 0 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: { codePoint: 134071, position: 2 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: { codePoint: 134071, position: 4 }, - done: false, - }); - assert.deepEqual(iterator.next(), { - value: undefined, - done: true, - }); -}); diff --git a/tests/tests/esnext.string.replace-all.js b/tests/tests/esnext.string.replace-all.js deleted file mode 100644 index a3a6e569f38c..000000000000 --- a/tests/tests/esnext.string.replace-all.js +++ /dev/null @@ -1,39 +0,0 @@ -import { STRICT } from '../helpers/constants'; - -QUnit.test('String#replaceAll', assert => { - const { replaceAll } = String.prototype; - assert.isFunction(replaceAll); - assert.arity(replaceAll, 2); - assert.name(replaceAll, 'replaceAll'); - assert.looksNative(replaceAll); - assert.nonEnumerable(String.prototype, 'replaceAll'); - assert.same('q=query+string+parameters'.replaceAll('+', ' '), 'q=query string parameters'); - assert.same('foo'.replaceAll('o', {}), 'f[object Object][object Object]'); - assert.same('[object Object]x[object Object]'.replaceAll({}, 'y'), 'yxy'); - assert.same(replaceAll.call({}, 'bject', 'lolo'), '[ololo Ololo]'); - assert.same('aba'.replaceAll('b', (search, i, string) => { - assert.same(search, 'b', '`search` is `b`'); - assert.same(i, 0, '`i` is 0'); - assert.same(string, 'aba', '`string` is `aba`'); - return 'c'; - }), 'aca'); - const searcher = { - [Symbol.replace](O, replaceValue) { - assert.same(this, searcher, '`this` is `searcher`'); - assert.same(String(O), 'aba', '`O` is `aba`'); - assert.same(String(replaceValue), 'c', '`replaceValue` is `c`'); - return 'foo'; - }, - }; - assert.same('aba'.replaceAll(searcher, 'c'), 'foo'); - assert.same('aba'.replaceAll('b'), 'aundefineda'); - assert.same('xxx'.replaceAll('', '_'), '_x_x_x_'); - if (STRICT) { - assert.throws(() => replaceAll.call(null, 'a', 'b'), TypeError); - assert.throws(() => replaceAll.call(undefined, 'a', 'b'), TypeError); - } - assert.throws(() => 'b.b.b.b.b'.replaceAll(/\./, 'a'), TypeError); - assert.same('b.b.b.b.b'.replaceAll(/\./g, 'a'), 'babababab'); - const object = {}; - assert.same('[object Object]'.replaceAll(object, 'a'), 'a'); -}); diff --git a/tests/tests/esnext.symbol.async-dispose.js b/tests/tests/esnext.symbol.async-dispose.js deleted file mode 100644 index de6a24c66445..000000000000 --- a/tests/tests/esnext.symbol.async-dispose.js +++ /dev/null @@ -1,13 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Symbol.asyncDispose', assert => { - assert.ok('asyncDispose' in Symbol, 'Symbol.asyncDispose available'); - assert.nonEnumerable(Symbol, 'asyncDispose'); - assert.ok(Object(Symbol.asyncDispose) instanceof Symbol, 'Symbol.asyncDispose is symbol'); - if (DESCRIPTORS) { - const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'asyncDispose'); - assert.ok(!descriptor.enumerble, 'non-enumerable'); - assert.ok(!descriptor.writable, 'non-writable'); - assert.ok(!descriptor.configurable, 'non-configurable'); - } -}); diff --git a/tests/tests/esnext.symbol.dispose.js b/tests/tests/esnext.symbol.dispose.js deleted file mode 100644 index 5feb87bb63cd..000000000000 --- a/tests/tests/esnext.symbol.dispose.js +++ /dev/null @@ -1,13 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Symbol.dispose', assert => { - assert.ok('dispose' in Symbol, 'Symbol.dispose available'); - assert.nonEnumerable(Symbol, 'dispose'); - assert.ok(Object(Symbol.dispose) instanceof Symbol, 'Symbol.dispose is symbol'); - if (DESCRIPTORS) { - const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'dispose'); - assert.ok(!descriptor.enumerble, 'non-enumerable'); - assert.ok(!descriptor.writable, 'non-writable'); - assert.ok(!descriptor.configurable, 'non-configurable'); - } -}); diff --git a/tests/tests/esnext.symbol.observable.js b/tests/tests/esnext.symbol.observable.js deleted file mode 100644 index 543a15620bff..000000000000 --- a/tests/tests/esnext.symbol.observable.js +++ /dev/null @@ -1,13 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Symbol.observable', assert => { - assert.ok('observable' in Symbol, 'Symbol.observable available'); - assert.nonEnumerable(Symbol, 'observable'); - assert.ok(Object(Symbol.observable) instanceof Symbol, 'Symbol.observable is symbol'); - if (DESCRIPTORS) { - const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'observable'); - assert.ok(!descriptor.enumerble, 'non-enumerable'); - assert.ok(!descriptor.writable, 'non-writable'); - assert.ok(!descriptor.configurable, 'non-configurable'); - } -}); diff --git a/tests/tests/esnext.symbol.pattern-match.js b/tests/tests/esnext.symbol.pattern-match.js deleted file mode 100644 index 246013e7182a..000000000000 --- a/tests/tests/esnext.symbol.pattern-match.js +++ /dev/null @@ -1,13 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Symbol.patternMatch', assert => { - assert.ok('patternMatch' in Symbol, 'Symbol.patternMatch available'); - assert.nonEnumerable(Symbol, 'patternMatch'); - assert.ok(Object(Symbol.patternMatch) instanceof Symbol, 'Symbol.patternMatch is symbol'); - if (DESCRIPTORS) { - const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'patternMatch'); - assert.ok(!descriptor.enumerble, 'non-enumerable'); - assert.ok(!descriptor.writable, 'non-writable'); - assert.ok(!descriptor.configurable, 'non-configurable'); - } -}); diff --git a/tests/tests/esnext.symbol.replace-all.js b/tests/tests/esnext.symbol.replace-all.js deleted file mode 100644 index d4ab590d89e3..000000000000 --- a/tests/tests/esnext.symbol.replace-all.js +++ /dev/null @@ -1,13 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; - -QUnit.test('Symbol.replaceAll', assert => { - assert.ok('replaceAll' in Symbol, 'Symbol.replaceAll is available'); - assert.nonEnumerable(Symbol, 'replaceAll'); - assert.ok(Object(Symbol.replaceAll) instanceof Symbol, 'Symbol.replaceAll is symbol'); - if (DESCRIPTORS) { - const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'replaceAll'); - assert.ok(!descriptor.enumerble, 'non-enumerable'); - assert.ok(!descriptor.writable, 'non-writable'); - assert.ok(!descriptor.configurable, 'non-configurable'); - } -}); diff --git a/tests/tests/esnext.weak-map.delete-all.js b/tests/tests/esnext.weak-map.delete-all.js deleted file mode 100644 index 0ee9ed2e0708..000000000000 --- a/tests/tests/esnext.weak-map.delete-all.js +++ /dev/null @@ -1,52 +0,0 @@ -QUnit.test('WeakMap#deleteAll', assert => { - const { deleteAll } = WeakMap.prototype; - - assert.isFunction(deleteAll); - assert.arity(deleteAll, 0); - assert.name(deleteAll, 'deleteAll'); - assert.looksNative(deleteAll); - assert.nonEnumerable(WeakMap.prototype, 'deleteAll'); - - const a = []; - const b = []; - const c = []; - const d = []; - const e = []; - - let set = new WeakMap([[a, 1], [b, 2], [c, 3]]); - assert.same(set.deleteAll(a, b), true); - assert.ok(!set.has(a)); - assert.ok(!set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakMap([[a, 1], [b, 2], [c, 3]]); - assert.same(set.deleteAll(c, d), false); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(!set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakMap([[a, 1], [b, 2], [c, 3]]); - assert.same(set.deleteAll(d, e), false); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakMap([[a, 1], [b, 2], [c, 3]]); - assert.same(set.deleteAll(), true); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - assert.notThrows(() => !deleteAll.call({ delete() { /* empty */ } }, a, b, c)); - assert.throws(() => deleteAll.call({}, a, b, c), TypeError); - assert.throws(() => deleteAll.call(undefined, a, b, c), TypeError); - assert.throws(() => deleteAll.call(null, a, b, c), TypeError); -}); diff --git a/tests/tests/esnext.weak-map.from.js b/tests/tests/esnext.weak-map.from.js deleted file mode 100644 index c3b76e05573e..000000000000 --- a/tests/tests/esnext.weak-map.from.js +++ /dev/null @@ -1,29 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('WeakMap.from', assert => { - const { from } = WeakMap; - assert.isFunction(from); - assert.arity(from, 1); - assert.name(from, 'from'); - assert.looksNative(from); - assert.nonEnumerable(WeakMap, 'from'); - assert.ok(WeakMap.from() instanceof WeakMap); - const array = []; - assert.same(WeakMap.from([[array, 2]]).get(array), 2); - assert.same(WeakMap.from(createIterable([[array, 2]])).get(array), 2); - const pair = [{}, 1]; - const context = {}; - WeakMap.from([pair], function (element, index) { - assert.same(element, pair); - assert.same(index, 0); - assert.same(this, context); - return element; - }, context); - assert.throws(() => from([{}, 1])); - let arg = null; - function F(it) { - return arg = it; - } - from.call(F, createIterable([1, 2, 3]), it => it ** 2); - assert.deepEqual(arg, [1, 4, 9]); -}); diff --git a/tests/tests/esnext.weak-map.of.js b/tests/tests/esnext.weak-map.of.js deleted file mode 100644 index 83d9c97d6665..000000000000 --- a/tests/tests/esnext.weak-map.of.js +++ /dev/null @@ -1,18 +0,0 @@ -QUnit.test('WeakMap.of', assert => { - const { of } = WeakMap; - assert.isFunction(of); - assert.arity(of, 0); - assert.name(of, 'of'); - assert.looksNative(of); - assert.nonEnumerable(WeakMap, 'of'); - const array = []; - assert.ok(WeakMap.of() instanceof WeakMap); - assert.same(WeakMap.of([array, 2]).get(array), 2); - assert.throws(() => of(1)); - let arg = null; - function F(it) { - return arg = it; - } - of.call(F, 1, 2, 3); - assert.deepEqual(arg, [1, 2, 3]); -}); diff --git a/tests/tests/esnext.weak-map.upsert.js b/tests/tests/esnext.weak-map.upsert.js deleted file mode 100644 index bfe6d0618455..000000000000 --- a/tests/tests/esnext.weak-map.upsert.js +++ /dev/null @@ -1,39 +0,0 @@ -QUnit.test('WeakMap#upsert', assert => { - const { upsert } = WeakMap.prototype; - assert.isFunction(upsert); - assert.arity(upsert, 2); - assert.name(upsert, 'upsert'); - assert.looksNative(upsert); - assert.nonEnumerable(WeakMap.prototype, 'upsert'); - - const a = {}; - const b = {}; - - const map = new WeakMap([[a, 2]]); - assert.same(map.upsert(a, function (value) { - assert.same(arguments.length, 1, 'correct number of callback arguments'); - assert.same(value, 2, 'correct value in callback'); - return value ** 2; - }, () => { - assert.ok(false, 'should not be called'); - return 3; - }), 4, 'returns a correct value'); - assert.same(map.upsert(b, value => { - assert.ok(false, 'should not be called'); - return value ** 2; - }, function () { - assert.same(arguments.length, 0, 'correct number of callback arguments'); - return 3; - }), 3, 'returns a correct value'); - assert.same(map.get(a), 4, 'correct result #1'); - assert.same(map.get(b), 3, 'correct result #2'); - - assert.same(new WeakMap([[a, 2]]).upsert(b, null, () => 3), 3); - assert.same(new WeakMap([[a, 2]]).upsert(a, value => value ** 2), 4); - - assert.throws(() => new WeakMap().upsert(a), TypeError); - assert.throws(() => upsert.call({}, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call([], a, () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call(undefined, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); - assert.throws(() => upsert.call(null, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); -}); diff --git a/tests/tests/esnext.weak-set.add-all.js b/tests/tests/esnext.weak-set.add-all.js deleted file mode 100644 index c303fc9de656..000000000000 --- a/tests/tests/esnext.weak-set.add-all.js +++ /dev/null @@ -1,33 +0,0 @@ -QUnit.test('WeakSet#addAll', assert => { - const { addAll } = WeakSet.prototype; - - assert.isFunction(addAll); - assert.arity(addAll, 0); - assert.name(addAll, 'addAll'); - assert.looksNative(addAll); - assert.nonEnumerable(WeakSet.prototype, 'addAll'); - - const a = []; - const b = []; - const c = []; - - let set = new WeakSet([a]); - assert.same(set.addAll(b), set); - - set = new WeakSet([a]).addAll(b, c); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - - set = new WeakSet([a]).addAll(a, b); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - - set = new WeakSet([a]).addAll(); - assert.ok(set.has(a)); - - assert.notThrows(() => addAll.call({ add() { /* empty */ } }, a, b, c)); - assert.throws(() => addAll.call({}, a, b, c), TypeError); - assert.throws(() => addAll.call(undefined, a, b, c), TypeError); - assert.throws(() => addAll.call(null, a, b, c), TypeError); -}); diff --git a/tests/tests/esnext.weak-set.delete-all.js b/tests/tests/esnext.weak-set.delete-all.js deleted file mode 100644 index 819e2ed55c93..000000000000 --- a/tests/tests/esnext.weak-set.delete-all.js +++ /dev/null @@ -1,52 +0,0 @@ -QUnit.test('WeakSet#deleteAll', assert => { - const { deleteAll } = WeakSet.prototype; - - assert.isFunction(deleteAll); - assert.arity(deleteAll, 0); - assert.name(deleteAll, 'deleteAll'); - assert.looksNative(deleteAll); - assert.nonEnumerable(WeakSet.prototype, 'deleteAll'); - - const a = []; - const b = []; - const c = []; - const d = []; - const e = []; - - let set = new WeakSet([a, b, c]); - assert.same(set.deleteAll(a, b), true); - assert.ok(!set.has(a)); - assert.ok(!set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakSet([a, b, c]); - assert.same(set.deleteAll(c, d), false); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(!set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakSet([a, b, c]); - assert.same(set.deleteAll(d, e), false); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - set = new WeakSet([a, b, c]); - assert.same(set.deleteAll(), true); - assert.ok(set.has(a)); - assert.ok(set.has(b)); - assert.ok(set.has(c)); - assert.ok(!set.has(d)); - assert.ok(!set.has(e)); - - assert.notThrows(() => !deleteAll.call({ delete() { /* empty */ } }, a, b, c)); - assert.throws(() => deleteAll.call({}, a, b, c), TypeError); - assert.throws(() => deleteAll.call(undefined, a, b, c), TypeError); - assert.throws(() => deleteAll.call(null, a, b, c), TypeError); -}); diff --git a/tests/tests/esnext.weak-set.from.js b/tests/tests/esnext.weak-set.from.js deleted file mode 100644 index 5d3a58f049b3..000000000000 --- a/tests/tests/esnext.weak-set.from.js +++ /dev/null @@ -1,29 +0,0 @@ -import { createIterable } from '../helpers/helpers'; - -QUnit.test('WeakSet.from', assert => { - const { from } = WeakSet; - assert.isFunction(from); - assert.arity(from, 1); - assert.name(from, 'from'); - assert.looksNative(from); - assert.nonEnumerable(WeakSet, 'from'); - assert.ok(WeakSet.from() instanceof WeakSet); - const array = []; - assert.ok(WeakSet.from([array]).has(array)); - assert.ok(WeakSet.from(createIterable([array])).has(array)); - const object = {}; - const context = {}; - WeakSet.from([object], function (element, index) { - assert.same(element, object); - assert.same(index, 0); - assert.same(this, context); - return element; - }, context); - assert.throws(() => from({})); - let arg = null; - function F(it) { - return arg = it; - } - from.call(F, createIterable([1, 2, 3]), it => it ** 2); - assert.deepEqual(arg, [1, 4, 9]); -}); diff --git a/tests/tests/esnext.weak-set.of.js b/tests/tests/esnext.weak-set.of.js deleted file mode 100644 index dab20891e7dc..000000000000 --- a/tests/tests/esnext.weak-set.of.js +++ /dev/null @@ -1,18 +0,0 @@ -QUnit.test('WeakSet.of', assert => { - const { of } = WeakSet; - assert.isFunction(of); - assert.arity(of, 0); - assert.name(of, 'of'); - assert.looksNative(of); - assert.nonEnumerable(WeakSet, 'of'); - const array = []; - assert.ok(WeakSet.of() instanceof WeakSet); - assert.ok(WeakSet.of(array).has(array)); - assert.throws(() => of(1)); - let arg = null; - function F(it) { - arg = it; - } - of.call(F, 1, 2, 3); - assert.deepEqual(arg, [1, 2, 3]); -}); diff --git a/tests/tests/index.js b/tests/tests/index.js deleted file mode 100644 index d5fee30bf517..000000000000 --- a/tests/tests/index.js +++ /dev/null @@ -1,313 +0,0 @@ -/* eslint-disable import/first */ -QUnit.module('ES'); -import './es.array.concat'; -import './es.array.copy-within'; -import './es.array.every'; -import './es.array.fill'; -import './es.array.filter'; -import './es.array.find-index'; -import './es.array.find'; -import './es.array.for-each'; -import './es.array.flat'; -import './es.array.flat-map'; -import './es.array.from'; -import './es.array.includes'; -import './es.array.index-of'; -import './es.array.is-array'; -import './es.array.iterator'; -import './es.array.join'; -import './es.array.last-index-of'; -import './es.array.map'; -import './es.array.of'; -import './es.array.reduce-right'; -import './es.array.reduce'; -import './es.array.reverse'; -import './es.array.slice'; -import './es.array.some'; -import './es.array.sort'; -import './es.array.splice'; -import './es.date.now'; -import './es.date.to-iso-string'; -import './es.date.to-json'; -import './es.date.to-primitive'; -import './es.date.to-string'; -import './es.function.bind'; -import './es.function.has-instance'; -import './es.function.name'; -import './es.global-this'; -import './es.map'; -import './es.math.acosh'; -import './es.math.asinh'; -import './es.math.atanh'; -import './es.math.cbrt'; -import './es.math.clz32'; -import './es.math.cosh'; -import './es.math.expm1'; -import './es.math.fround'; -import './es.math.hypot'; -import './es.math.imul'; -import './es.math.log10'; -import './es.math.log1p'; -import './es.math.log2'; -import './es.math.sign'; -import './es.math.sinh'; -import './es.math.tanh'; -import './es.math.trunc'; -import './es.number.constructor'; -import './es.number.epsilon'; -import './es.number.is-finite'; -import './es.number.is-integer'; -import './es.number.is-nan'; -import './es.number.is-safe-integer'; -import './es.number.max-safe-integer'; -import './es.number.min-safe-integer'; -import './es.number.parse-float'; -import './es.number.parse-int'; -import './es.number.to-fixed'; -import './es.number.to-precision'; -import './es.object.assign'; -import './es.object.create'; -import './es.object.define-getter'; -import './es.object.define-properties'; -import './es.object.define-property'; -import './es.object.define-setter'; -import './es.object.entries'; -import './es.object.from-entries'; -import './es.object.freeze'; -import './es.object.get-own-property-descriptor'; -import './es.object.get-own-property-descriptors'; -import './es.object.get-own-property-names'; -import './es.object.get-prototype-of'; -import './es.object.is-extensible'; -import './es.object.is-frozen'; -import './es.object.is-sealed'; -import './es.object.is'; -import './es.object.keys'; -import './es.object.lookup-getter'; -import './es.object.lookup-setter'; -import './es.object.prevent-extensions'; -import './es.object.seal'; -import './es.object.set-prototype-of'; -import './es.object.to-string'; -import './es.object.values'; -import './es.parse-float'; -import './es.parse-int'; -import './es.promise'; -import './es.promise.all-settled'; -import './es.promise.finally'; -import './es.reflect.apply'; -import './es.reflect.construct'; -import './es.reflect.define-property'; -import './es.reflect.delete-property'; -import './es.reflect.get-own-property-descriptor'; -import './es.reflect.get-prototype-of'; -import './es.reflect.get'; -import './es.reflect.has'; -import './es.reflect.is-extensible'; -import './es.reflect.own-keys'; -import './es.reflect.prevent-extensions'; -import './es.reflect.set-prototype-of'; -import './es.reflect.set'; -import './es.regexp.constructor'; -import './es.regexp.exec'; -import './es.regexp.flags'; -import './es.regexp.to-string'; -import './es.set'; -import './es.string.anchor'; -import './es.string.big'; -import './es.string.blink'; -import './es.string.bold'; -import './es.string.code-point-at'; -import './es.string.ends-with'; -import './es.string.fixed'; -import './es.string.fontcolor'; -import './es.string.fontsize'; -import './es.string.from-code-point'; -import './es.string.includes'; -import './es.string.italics'; -import './es.string.iterator'; -import './es.string.link'; -import './es.string.match'; -import './es.string.match-all'; -import './es.string.pad-end'; -import './es.string.pad-start'; -import './es.string.raw'; -import './es.string.repeat'; -import './es.string.replace'; -import './es.string.search'; -import './es.string.small'; -import './es.string.split'; -import './es.string.starts-with'; -import './es.string.strike'; -import './es.string.sub'; -import './es.string.sup'; -import './es.string.trim'; -import './es.string.trim-start'; -import './es.string.trim-end'; -import './es.symbol'; -import './es.symbol.async-iterator'; -import './es.symbol.description'; -import './es.array-buffer.constructor'; -import './es.array-buffer.is-view'; -import './es.array-buffer.slice'; -import './es.data-view'; -import './es.typed.conversions.float32'; -import './es.typed.conversions.float64'; -import './es.typed.conversions.int16'; -import './es.typed.conversions.int32'; -import './es.typed.conversions.int8'; -import './es.typed.conversions.uint16'; -import './es.typed.conversions.uint32'; -import './es.typed.conversions.uint8-clamped'; -import './es.typed.conversions.uint8'; -import './es.typed-array.constructors'; -import './es.typed-array.copy-within'; -import './es.typed-array.every'; -import './es.typed-array.fill'; -import './es.typed-array.filter'; -import './es.typed-array.find-index'; -import './es.typed-array.find'; -import './es.typed-array.for-each'; -import './es.typed-array.from'; -import './es.typed-array.includes'; -import './es.typed-array.index-of'; -import './es.typed-array.iterator'; -import './es.typed-array.join'; -import './es.typed-array.last-index-of'; -import './es.typed-array.map'; -import './es.typed-array.of'; -import './es.typed-array.reduce-right'; -import './es.typed-array.reduce'; -import './es.typed-array.reverse'; -import './es.typed-array.set'; -import './es.typed-array.slice'; -import './es.typed-array.some'; -import './es.typed-array.subarray'; -import './es.typed-array.to-locale-string'; -import './es.typed-array.to-string'; -import './es.weak-map'; -import './es.weak-set'; - -QUnit.module('ESNext'); -import './esnext.aggregate-error'; -import './esnext.array.is-template-object'; -import './esnext.array.last-item'; -import './esnext.array.last-index'; -import './esnext.async-iterator.constructor'; -import './esnext.async-iterator.as-indexed-pairs'; -import './esnext.async-iterator.drop'; -import './esnext.async-iterator.every'; -import './esnext.async-iterator.filter'; -import './esnext.async-iterator.find'; -import './esnext.async-iterator.flat-map'; -import './esnext.async-iterator.for-each'; -import './esnext.async-iterator.from'; -import './esnext.async-iterator.map'; -import './esnext.async-iterator.reduce'; -import './esnext.async-iterator.some'; -import './esnext.async-iterator.take'; -import './esnext.async-iterator.to-array'; -import './esnext.composite-key'; -import './esnext.composite-symbol'; -import './esnext.iterator.constructor'; -import './esnext.iterator.as-indexed-pairs'; -import './esnext.iterator.drop'; -import './esnext.iterator.every'; -import './esnext.iterator.filter'; -import './esnext.iterator.find'; -import './esnext.iterator.flat-map'; -import './esnext.iterator.for-each'; -import './esnext.iterator.from'; -import './esnext.iterator.map'; -import './esnext.iterator.reduce'; -import './esnext.iterator.some'; -import './esnext.iterator.take'; -import './esnext.iterator.to-array'; -import './esnext.map.from'; -import './esnext.map.of'; -import './esnext.math.clamp'; -import './esnext.math.deg-per-rad'; -import './esnext.math.degrees'; -import './esnext.math.fscale'; -import './esnext.math.iaddh'; -import './esnext.math.imulh'; -import './esnext.math.isubh'; -import './esnext.math.rad-per-deg'; -import './esnext.math.radians'; -import './esnext.math.scale'; -import './esnext.math.signbit'; -import './esnext.math.umulh'; -import './esnext.math.seeded-prng'; -import './esnext.number.from-string'; -import './esnext.observable'; -import './esnext.promise.any'; -import './esnext.promise.try'; -import './esnext.reflect.define-metadata'; -import './esnext.reflect.delete-metadata'; -import './esnext.reflect.get-metadata-keys'; -import './esnext.reflect.get-metadata'; -import './esnext.reflect.get-own-matadata'; -import './esnext.reflect.get-own-metadata-keys'; -import './esnext.reflect.has-metadata'; -import './esnext.reflect.has-own-metadata'; -import './esnext.reflect.metadata'; -import './esnext.map.delete-all'; -import './esnext.map.every'; -import './esnext.map.filter'; -import './esnext.map.find'; -import './esnext.map.find-key'; -import './esnext.map.group-by'; -import './esnext.map.includes'; -import './esnext.map.key-by'; -import './esnext.map.key-of'; -import './esnext.map.map-keys'; -import './esnext.map.map-values'; -import './esnext.map.merge'; -import './esnext.map.reduce'; -import './esnext.map.some'; -import './esnext.map.update'; -import './esnext.map.update-or-insert'; -import './esnext.map.upsert'; -import './esnext.set.add-all'; -import './esnext.set.delete-all'; -import './esnext.set.difference'; -import './esnext.set.every'; -import './esnext.set.filter'; -import './esnext.set.find'; -import './esnext.set.from'; -import './esnext.set.intersection'; -import './esnext.set.is-disjoint-from'; -import './esnext.set.is-subset-of'; -import './esnext.set.is-superset-of'; -import './esnext.set.join'; -import './esnext.set.map'; -import './esnext.set.of'; -import './esnext.set.reduce'; -import './esnext.set.some'; -import './esnext.set.symmetric-difference'; -import './esnext.set.union'; -import './esnext.string.at'; -import './esnext.string.code-points'; -import './esnext.string.replace-all'; -import './esnext.symbol.async-dispose'; -import './esnext.symbol.dispose'; -import './esnext.symbol.observable'; -import './esnext.symbol.pattern-match'; -import './esnext.symbol.replace-all'; -import './esnext.weak-map.delete-all'; -import './esnext.weak-map.from'; -import './esnext.weak-map.of'; -import './esnext.weak-map.upsert'; -import './esnext.weak-set.add-all'; -import './esnext.weak-set.delete-all'; -import './esnext.weak-set.from'; -import './esnext.weak-set.of'; - -QUnit.module('Web'); -import './web.dom-collections.for-each'; -import './web.dom-collections.iterator'; -import './web.immediate'; -import './web.queue-microtask'; -import './web.timers'; -import './web.url'; -import './web.url-search-params'; diff --git a/tests/tests/web.dom-collections.iterator.js b/tests/tests/web.dom-collections.iterator.js deleted file mode 100644 index ac8051610aec..000000000000 --- a/tests/tests/web.dom-collections.iterator.js +++ /dev/null @@ -1,74 +0,0 @@ -import { GLOBAL } from '../helpers/constants'; - -const Symbol = GLOBAL.Symbol || {}; - -QUnit.test('Iterable DOM collections', assert => { - let absent = true; - let collections = [ - 'CSSRuleList', - 'CSSStyleDeclaration', - 'CSSValueList', - 'ClientRectList', - 'DOMRectList', - 'DOMStringList', - 'DOMTokenList', - 'DataTransferItemList', - 'FileList', - 'HTMLAllCollection', - 'HTMLCollection', - 'HTMLFormElement', - 'HTMLSelectElement', - 'MediaList', - 'MimeTypeArray', - 'NamedNodeMap', - 'NodeList', - 'PaintRequestList', - 'Plugin', - 'PluginArray', - 'SVGLengthList', - 'SVGNumberList', - 'SVGPathSegList', - 'SVGPointList', - 'SVGStringList', - 'SVGTransformList', - 'SourceBufferList', - 'StyleSheetList', - 'TextTrackCueList', - 'TextTrackList', - 'TouchList', - ]; - - for (const name of collections) { - const Collection = GLOBAL[name]; - if (Collection) { - assert.same(Collection.prototype[Symbol.toStringTag], name, `${ name }::@@toStringTag is '${ name }'`); - assert.isFunction(Collection.prototype[Symbol.iterator], `${ name }::@@iterator is function`); - absent = false; - } - } - - if (GLOBAL.NodeList && GLOBAL.document && document.querySelectorAll && document.querySelectorAll('div') instanceof NodeList) { - assert.isFunction(document.querySelectorAll('div')[Symbol.iterator], 'works with document.querySelectorAll'); - } - - collections = [ - 'NodeList', - 'DOMTokenList', - ]; - - for (const name of collections) { - const Collection = GLOBAL[name]; - if (Collection) { - assert.isFunction(Collection.prototype.values, `${ name }::values is function`); - assert.same(Collection.prototype.values, Array.prototype.values, `${ name }::values is equal of Array::values`); - assert.isFunction(Collection.prototype.keys, `${ name }::keys is function`); - assert.same(Collection.prototype.keys, Array.prototype.keys, `${ name }::keys is equal of Array::keys`); - assert.isFunction(Collection.prototype.entries, `${ name }::entries is function`); - assert.same(Collection.prototype.entries, Array.prototype.entries, `${ name }::entries is equal of Array::entries`); - } - } - - if (absent) { - assert.ok(true, 'DOM collections are absent'); - } -}); diff --git a/tests/tests/web.immediate.js b/tests/tests/web.immediate.js deleted file mode 100644 index 00b4411f8e3b..000000000000 --- a/tests/tests/web.immediate.js +++ /dev/null @@ -1,37 +0,0 @@ -import { timeLimitedPromise } from '../helpers/helpers'; - -QUnit.test('setImmediate / clearImmediate', assert => { - let called = false; - assert.expect(8); - assert.isFunction(setImmediate, 'setImmediate is function'); - assert.isFunction(clearImmediate, 'clearImmediate is function'); - assert.name(setImmediate, 'setImmediate'); - assert.name(clearImmediate, 'clearImmediate'); - timeLimitedPromise(1e3, resolve => { - setImmediate(() => { - called = true; - resolve(); - }); - }).then(() => { - assert.ok(true, 'setImmediate works'); - }).catch(() => { - assert.ok(false, 'setImmediate works'); - }).then(assert.async()); - assert.strictEqual(called, false, 'setImmediate is async'); - timeLimitedPromise(1e3, resolve => { - setImmediate((a, b) => { - resolve(a + b); - }, 'a', 'b'); - }).then(it => { - assert.strictEqual(it, 'ab', 'setImmediate works with additional args'); - }).catch(() => { - assert.ok(false, 'setImmediate works with additional args'); - }).then(assert.async()); - timeLimitedPromise(50, resolve => { - clearImmediate(setImmediate(resolve)); - }).then(() => { - assert.ok(false, 'clearImmediate works'); - }).catch(() => { - assert.ok(true, 'clearImmediate works'); - }).then(assert.async()); -}); diff --git a/tests/tests/web.queue-microtask.js b/tests/tests/web.queue-microtask.js deleted file mode 100644 index e17adc8aabb9..000000000000 --- a/tests/tests/web.queue-microtask.js +++ /dev/null @@ -1,25 +0,0 @@ -QUnit.test('queueMicrotask', assert => { - assert.expect(5); - assert.isFunction(queueMicrotask); - assert.arity(queueMicrotask, 1); - assert.name(queueMicrotask, 'queueMicrotask'); - assert.looksNative(queueMicrotask); - const async = assert.async(); - let done = false; - let after = false; - queueMicrotask(() => { - if (!done) { - done = true; - assert.ok(after, 'works'); - async(); - } - }); - setTimeout(() => { - if (!done) { - done = true; - assert.ok(false, 'fails'); - async(); - } - }, 3e3); - after = true; -}); diff --git a/tests/tests/web.timers.js b/tests/tests/web.timers.js deleted file mode 100644 index 0dd4ccc0676b..000000000000 --- a/tests/tests/web.timers.js +++ /dev/null @@ -1,41 +0,0 @@ -import { timeLimitedPromise } from '../helpers/helpers'; - -QUnit.test('setTimeout / clearTimeout', assert => { - assert.expect(2); - - timeLimitedPromise(1e3, resolve => { - setTimeout((a, b) => { resolve(a + b); }, 10, 'a', 'b'); - }).then(it => { - assert.strictEqual(it, 'ab', 'setTimeout works with additional args'); - }).catch(() => { - assert.ok(false, 'setTimeout works with additional args'); - }).then(assert.async()); - - timeLimitedPromise(50, resolve => { - clearTimeout(setTimeout(resolve, 10)); - }).then(() => { - assert.ok(false, 'clearImmediate works with wraped setTimeout'); - }).catch(() => { - assert.ok(true, 'clearImmediate works with wraped setTimeout'); - }).then(assert.async()); -}); - -QUnit.test('setInterval / clearInterval', assert => { - assert.expect(1); - - timeLimitedPromise(1e4, (resolve, reject) => { - let i = 0; - const interval = setInterval((a, b) => { - if (a + b !== 'ab' || i > 2) reject({ a, b, i }); - if (i++ === 2) { - clearInterval(interval); - setTimeout(resolve, 30); - } - }, 5, 'a', 'b'); - }).then(() => { - assert.ok(true, 'setInterval & clearInterval works with additional args'); - }).catch(error => { - if (!error) error = {}; - assert.ok(false, `setInterval & clearInterval works with additional args: ${ error.a }, ${ error.b }, times: ${ error.i }`); - }).then(assert.async()); -}); diff --git a/tests/tests/web.url-search-params.js b/tests/tests/web.url-search-params.js deleted file mode 100644 index 763dec38b2d1..000000000000 --- a/tests/tests/web.url-search-params.js +++ /dev/null @@ -1,832 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; -import { createIterable } from '../helpers/helpers'; - -QUnit.test('URLSearchParams', assert => { - assert.isFunction(URLSearchParams); - assert.arity(URLSearchParams, 0); - assert.name(URLSearchParams, 'URLSearchParams'); - assert.looksNative(URLSearchParams); - - assert.same(String(new URLSearchParams()), ''); - assert.same(String(new URLSearchParams('')), ''); - assert.same(String(new URLSearchParams('a=b')), 'a=b'); - assert.same(String(new URLSearchParams(new URLSearchParams('a=b'))), 'a=b'); - assert.same(String(new URLSearchParams([])), ''); - assert.same(String(new URLSearchParams([[1, 2], ['a', 'b']])), '1=2&a=b'); - assert.same(String(new URLSearchParams(createIterable([createIterable(['a', 'b']), createIterable(['c', 'd'])]))), 'a=b&c=d'); - assert.same(String(new URLSearchParams({})), ''); - assert.same(String(new URLSearchParams({ 1: 2, a: 'b' })), '1=2&a=b'); - - assert.same(String(new URLSearchParams('?a=b')), 'a=b', 'leading ? should be ignored'); - assert.same(String(new URLSearchParams('??a=b')), '%3Fa=b'); - assert.same(String(new URLSearchParams('?')), ''); - assert.same(String(new URLSearchParams('??')), '%3F='); - - assert.same(String(new URLSearchParams('a=b c')), 'a=b+c'); - assert.same(String(new URLSearchParams('a=b&b=c&a=d')), 'a=b&b=c&a=d'); - - assert.same(String(new URLSearchParams('a==')), 'a=%3D'); - assert.same(String(new URLSearchParams('a=b=')), 'a=b%3D'); - assert.same(String(new URLSearchParams('a=b=c')), 'a=b%3Dc'); - assert.same(String(new URLSearchParams('a==b')), 'a=%3Db'); - - let params = new URLSearchParams('a=b'); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.has('b'), false, 'search params object has not got name "b"'); - - params = new URLSearchParams('a=b&c'); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.has('c'), true, 'search params object has name "c"'); - - params = new URLSearchParams('&a&&& &&&&&a+b=& c&m%c3%b8%c3%b8'); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.has('a b'), true, 'search params object has name "a b"'); - assert.same(params.has(' '), true, 'search params object has name " "'); - assert.same(params.has('c'), false, 'search params object did not have the name "c"'); - assert.same(params.has(' c'), true, 'search params object has name " c"'); - assert.same(params.has('møø'), true, 'search params object has name "møø"'); - - params = new URLSearchParams('a=b+c'); - assert.same(params.get('a'), 'b c', 'parse +'); - params = new URLSearchParams('a+b=c'); - assert.same(params.get('a b'), 'c', 'parse +'); - - params = new URLSearchParams('a=b c'); - assert.same(params.get('a'), 'b c', 'parse " "'); - params = new URLSearchParams('a b=c'); - assert.same(params.get('a b'), 'c', 'parse " "'); - - params = new URLSearchParams('a=b%20c'); - assert.same(params.get('a'), 'b c', 'parse %20'); - params = new URLSearchParams('a%20b=c'); - assert.same(params.get('a b'), 'c', 'parse %20'); - - params = new URLSearchParams('a=b\0c'); - assert.same(params.get('a'), 'b\0c', 'parse \\0'); - params = new URLSearchParams('a\0b=c'); - assert.same(params.get('a\0b'), 'c', 'parse \\0'); - - params = new URLSearchParams('a=b%00c'); - assert.same(params.get('a'), 'b\0c', 'parse %00'); - params = new URLSearchParams('a%00b=c'); - assert.same(params.get('a\0b'), 'c', 'parse %00'); - - params = new URLSearchParams('a=b\u2384'); - assert.same(params.get('a'), 'b\u2384', 'parse \u2384'); - params = new URLSearchParams('a\u2384b=c'); - assert.same(params.get('a\u2384b'), 'c', 'parse \u2384'); - - params = new URLSearchParams('a=b%e2%8e%84'); - assert.same(params.get('a'), 'b\u2384', 'parse %e2%8e%84'); - params = new URLSearchParams('a%e2%8e%84b=c'); - assert.same(params.get('a\u2384b'), 'c', 'parse %e2%8e%84'); - - params = new URLSearchParams('a=b\uD83D\uDCA9c'); - assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse \uD83D\uDCA9'); - params = new URLSearchParams('a\uD83D\uDCA9b=c'); - assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse \uD83D\uDCA9'); - - params = new URLSearchParams('a=b%f0%9f%92%a9c'); - assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); - params = new URLSearchParams('a%f0%9f%92%a9b=c'); - assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); - - params = new URLSearchParams(); - params.set('query', '+15555555555'); - assert.same(params.toString(), 'query=%2B15555555555'); - assert.same(params.get('query'), '+15555555555', 'parse encoded +'); - params = new URLSearchParams(params.toString()); - assert.same(params.get('query'), '+15555555555', 'parse encoded +'); - - const testData = [ - { input: '?a=%', output: [['a', '%']], name: 'handling %' }, - { input: { '+': '%C2' }, output: [['+', '%C2']], name: 'object with +' }, - { input: { c: 'x', a: '?' }, output: [['c', 'x'], ['a', '?']], name: 'object with two keys' }, - { input: [['c', 'x'], ['a', '?']], output: [['c', 'x'], ['a', '?']], name: 'array with two keys' }, - // eslint-disable-next-line max-len - // !!! { input: { 'a\0b': '42', 'c\uD83D': '23', dሴ: 'foo' }, output: [['a\0b', '42'], ['c\uFFFD', '23'], ['d\u1234', 'foo']], name: 'object with NULL, non-ASCII, and surrogate keys' }, - ]; - - for (const { input, output, name } of testData) { - params = new URLSearchParams(input); - let i = 0; - params.forEach((value, key) => { - const [reqKey, reqValue] = output[i++]; - assert.same(key, reqKey, `construct with ${ name }`); - assert.same(value, reqValue, `construct with ${ name }`); - }); - } - - assert.throws(() => { - URLSearchParams(''); - }, 'throws w/o `new`'); - - assert.throws(() => { - new URLSearchParams([[1, 2, 3]]); - }, 'sequence elements must be pairs #1'); - - assert.throws(() => { - new URLSearchParams([createIterable([createIterable([1, 2, 3])])]); - }, 'sequence elements must be pairs #2'); - - assert.throws(() => { - new URLSearchParams([[1]]); - }, 'sequence elements must be pairs #3'); - - assert.throws(() => { - new URLSearchParams([createIterable([createIterable([1])])]); - }, 'sequence elements must be pairs #4'); -}); - -QUnit.test('URLSearchParams#append', assert => { - const { append } = URLSearchParams.prototype; - assert.isFunction(append); - assert.arity(append, 2); - assert.name(append, 'append'); - assert.enumerable(URLSearchParams.prototype, 'append'); - assert.looksNative(append); - - assert.same(new URLSearchParams().append('a', 'b'), undefined, 'void'); - - let params = new URLSearchParams(); - params.append('a', 'b'); - assert.same(String(params), 'a=b'); - params.append('a', 'b'); - assert.same(String(params), 'a=b&a=b'); - params.append('a', 'c'); - assert.same(String(params), 'a=b&a=b&a=c'); - - params = new URLSearchParams(); - params.append('', ''); - assert.same(String(params), '='); - params.append('', ''); - assert.same(String(params), '=&='); - - params = new URLSearchParams(); - params.append(undefined, undefined); - assert.same(String(params), 'undefined=undefined'); - params.append(undefined, undefined); - assert.same(String(params), 'undefined=undefined&undefined=undefined'); - - params = new URLSearchParams(); - params.append(null, null); - assert.same(String(params), 'null=null'); - params.append(null, null); - assert.same(String(params), 'null=null&null=null'); - - params = new URLSearchParams(); - params.append('first', 1); - params.append('second', 2); - params.append('third', ''); - params.append('first', 10); - assert.ok(params.has('first'), 'search params object has name "first"'); - assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); - assert.same(params.get('second'), '2', 'search params object has name "second" with value "2"'); - assert.same(params.get('third'), '', 'search params object has name "third" with value ""'); - params.append('first', 10); - assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); - - assert.throws(() => { - return new URLSearchParams('').append(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#delete', assert => { - const $delete = URLSearchParams.prototype.delete; - assert.isFunction($delete); - assert.arity($delete, 1); - assert.enumerable(URLSearchParams.prototype, 'delete'); - assert.looksNative($delete); - - let params = new URLSearchParams('a=b&c=d'); - params.delete('a'); - assert.same(String(params), 'c=d'); - - params = new URLSearchParams('a=a&b=b&a=a&c=c'); - params.delete('a'); - assert.same(String(params), 'b=b&c=c'); - - params = new URLSearchParams('a=a&=&b=b&c=c'); - params.delete(''); - assert.same(String(params), 'a=a&b=b&c=c'); - - params = new URLSearchParams('a=a&null=null&b=b'); - params.delete(null); - assert.same(String(params), 'a=a&b=b'); - - params = new URLSearchParams('a=a&undefined=undefined&b=b'); - params.delete(undefined); - assert.same(String(params), 'a=a&b=b'); - - params = new URLSearchParams(); - params.append('first', 1); - assert.same(params.has('first'), true, 'search params object has name "first"'); - assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); - params.delete('first'); - assert.same(params.has('first'), false, 'search params object has no "first" name'); - params.append('first', 1); - params.append('first', 10); - params.delete('first'); - assert.same(params.has('first'), false, 'search params object has no "first" name'); - - if (DESCRIPTORS) { - let url = new URL('http://example.com/?param1¶m2'); - url.searchParams.delete('param1'); - url.searchParams.delete('param2'); - assert.same(String(url), 'http://example.com/', 'url.href does not have ?'); - assert.same(url.search, '', 'url.search does not have ?'); - - url = new URL('http://example.com/?'); - url.searchParams.delete('param1'); - // assert.same(String(url), 'http://example.com/', 'url.href does not have ?'); // Safari bug - assert.same(url.search, '', 'url.search does not have ?'); - } - - assert.throws(() => { - return new URLSearchParams('').delete(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#get', assert => { - const { get } = URLSearchParams.prototype; - assert.isFunction(get); - assert.arity(get, 1); - assert.name(get, 'get'); - assert.enumerable(URLSearchParams.prototype, 'get'); - assert.looksNative(get); - - let params = new URLSearchParams('a=b&c=d'); - assert.same(params.get('a'), 'b'); - assert.same(params.get('c'), 'd'); - assert.same(params.get('e'), null); - - params = new URLSearchParams('a=b&c=d&a=e'); - assert.same(params.get('a'), 'b'); - - params = new URLSearchParams('=b&c=d'); - assert.same(params.get(''), 'b'); - - params = new URLSearchParams('a=&c=d&a=e'); - assert.same(params.get('a'), ''); - - params = new URLSearchParams('first=second&third&&'); - assert.same(params.has('first'), true, 'Search params object has name "first"'); - assert.same(params.get('first'), 'second', 'Search params object has name "first" with value "second"'); - assert.same(params.get('third'), '', 'Search params object has name "third" with the empty value.'); - assert.same(params.get('fourth'), null, 'Search params object has no "fourth" name and value.'); - - assert.same(new URLSearchParams('a=b c').get('a'), 'b c'); - assert.same(new URLSearchParams('a b=c').get('a b'), 'c'); - - assert.same(new URLSearchParams('a=b%20c').get('a'), 'b c', 'parse %20'); - assert.same(new URLSearchParams('a%20b=c').get('a b'), 'c', 'parse %20'); - - assert.same(new URLSearchParams('a=b\0c').get('a'), 'b\0c', 'parse \\0'); - assert.same(new URLSearchParams('a\0b=c').get('a\0b'), 'c', 'parse \\0'); - - assert.same(new URLSearchParams('a=b%2Bc').get('a'), 'b+c', 'parse %2B'); - assert.same(new URLSearchParams('a%2Bb=c').get('a+b'), 'c', 'parse %2B'); - - assert.same(new URLSearchParams('a=b%00c').get('a'), 'b\0c', 'parse %00'); - assert.same(new URLSearchParams('a%00b=c').get('a\0b'), 'c', 'parse %00'); - - assert.same(new URLSearchParams('a==').get('a'), '=', 'parse ='); - assert.same(new URLSearchParams('a=b=').get('a'), 'b=', 'parse ='); - assert.same(new URLSearchParams('a=b=c').get('a'), 'b=c', 'parse ='); - assert.same(new URLSearchParams('a==b').get('a'), '=b', 'parse ='); - - assert.same(new URLSearchParams('a=b\u2384').get('a'), 'b\u2384', 'parse \\u2384'); - assert.same(new URLSearchParams('a\u2384b=c').get('a\u2384b'), 'c', 'parse \\u2384'); - - assert.same(new URLSearchParams('a=b%e2%8e%84').get('a'), 'b\u2384', 'parse %e2%8e%84'); - assert.same(new URLSearchParams('a%e2%8e%84b=c').get('a\u2384b'), 'c', 'parse %e2%8e%84'); - - assert.same(new URLSearchParams('a=b\uD83D\uDCA9c').get('a'), 'b\uD83D\uDCA9c', 'parse \\uD83D\\uDCA9'); - assert.same(new URLSearchParams('a\uD83D\uDCA9b=c').get('a\uD83D\uDCA9b'), 'c', 'parse \\uD83D\\uDCA9'); - - assert.same(new URLSearchParams('a=b%f0%9f%92%a9c').get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); - assert.same(new URLSearchParams('a%f0%9f%92%a9b=c').get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); - - assert.same(new URLSearchParams('=').get(''), '', 'parse ='); - - assert.throws(() => { - return new URLSearchParams('').get(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#getAll', assert => { - const { getAll } = URLSearchParams.prototype; - assert.isFunction(getAll); - assert.arity(getAll, 1); - assert.name(getAll, 'getAll'); - assert.enumerable(URLSearchParams.prototype, 'getAll'); - assert.looksNative(getAll); - - let params = new URLSearchParams('a=b&c=d'); - assert.arrayEqual(params.getAll('a'), ['b']); - assert.arrayEqual(params.getAll('c'), ['d']); - assert.arrayEqual(params.getAll('e'), []); - - params = new URLSearchParams('a=b&c=d&a=e'); - assert.arrayEqual(params.getAll('a'), ['b', 'e']); - - params = new URLSearchParams('=b&c=d'); - assert.arrayEqual(params.getAll(''), ['b']); - - params = new URLSearchParams('a=&c=d&a=e'); - assert.arrayEqual(params.getAll('a'), ['', 'e']); - - params = new URLSearchParams('a=1&a=2&a=3&a'); - assert.arrayEqual(params.getAll('a'), ['1', '2', '3', ''], 'search params object has expected name "a" values'); - params.set('a', 'one'); - assert.arrayEqual(params.getAll('a'), ['one'], 'search params object has expected name "a" values'); - - assert.throws(() => { - return new URLSearchParams('').getAll(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#has', assert => { - const { has } = URLSearchParams.prototype; - assert.isFunction(has); - assert.arity(has, 1); - assert.name(has, 'has'); - assert.enumerable(URLSearchParams.prototype, 'has'); - assert.looksNative(has); - - let params = new URLSearchParams('a=b&c=d'); - assert.same(params.has('a'), true); - assert.same(params.has('c'), true); - assert.same(params.has('e'), false); - - params = new URLSearchParams('a=b&c=d&a=e'); - assert.same(params.has('a'), true); - - params = new URLSearchParams('=b&c=d'); - assert.same(params.has(''), true); - - params = new URLSearchParams('null=a'); - assert.same(params.has(null), true); - - params = new URLSearchParams('a=b&c=d&&'); - params.append('first', 1); - params.append('first', 2); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.has('c'), true, 'search params object has name "c"'); - assert.same(params.has('first'), true, 'search params object has name "first"'); - assert.same(params.has('d'), false, 'search params object has no name "d"'); - params.delete('first'); - assert.same(params.has('first'), false, 'search params object has no name "first"'); - - assert.throws(() => { - return new URLSearchParams('').has(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#set', assert => { - const { set } = URLSearchParams.prototype; - assert.isFunction(set); - assert.arity(set, 2); - assert.name(set, 'set'); - assert.enumerable(URLSearchParams.prototype, 'set'); - assert.looksNative(set); - - let params = new URLSearchParams('a=b&c=d'); - params.set('a', 'B'); - assert.same(String(params), 'a=B&c=d'); - - params = new URLSearchParams('a=b&c=d&a=e'); - params.set('a', 'B'); - assert.same(String(params), 'a=B&c=d'); - params.set('e', 'f'); - assert.same(String(params), 'a=B&c=d&e=f'); - - params = new URLSearchParams('a=1&a=2&a=3'); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.get('a'), '1', 'search params object has name "a" with value "1"'); - params.set('first', 4); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.get('a'), '1', 'search params object has name "a" with value "1"'); - assert.same(String(params), 'a=1&a=2&a=3&first=4'); - params.set('a', 4); - assert.same(params.has('a'), true, 'search params object has name "a"'); - assert.same(params.get('a'), '4', 'search params object has name "a" with value "4"'); - assert.same(String(params), 'a=4&first=4'); - - assert.throws(() => { - return new URLSearchParams('').set(); - }, 'throws w/o arguments'); -}); - -QUnit.test('URLSearchParams#sort', assert => { - const { sort } = URLSearchParams.prototype; - assert.isFunction(sort); - assert.arity(sort, 0); - assert.name(sort, 'sort'); - assert.enumerable(URLSearchParams.prototype, 'sort'); - assert.looksNative(sort); - - let params = new URLSearchParams('a=1&b=4&a=3&b=2'); - params.sort(); - assert.same(String(params), 'a=1&a=3&b=4&b=2'); - params.delete('a'); - params.append('a', '0'); - params.append('b', '0'); - params.sort(); - assert.same(String(params), 'a=0&b=4&b=2&b=0'); - - const testData = [ - { - input: 'z=b&a=b&z=a&a=a', - output: [['a', 'b'], ['a', 'a'], ['z', 'b'], ['z', 'a']], - }, - { - input: '\uFFFD=x&\uFFFC&\uFFFD=a', - output: [['\uFFFC', ''], ['\uFFFD', 'x'], ['\uFFFD', 'a']], - }, - { - input: 'ffi&🌈', // 🌈 > code point, but < code unit because two code units - output: [['🌈', ''], ['ffi', '']], - }, - { - input: 'é&e\uFFFD&e\u0301', - output: [['e\u0301', ''], ['e\uFFFD', ''], ['é', '']], - }, - { - input: 'z=z&a=a&z=y&a=b&z=x&a=c&z=w&a=d&z=v&a=e&z=u&a=f&z=t&a=g', - // eslint-disable-next-line max-len - output: [['a', 'a'], ['a', 'b'], ['a', 'c'], ['a', 'd'], ['a', 'e'], ['a', 'f'], ['a', 'g'], ['z', 'z'], ['z', 'y'], ['z', 'x'], ['z', 'w'], ['z', 'v'], ['z', 'u'], ['z', 't']], - }, - { - input: 'bbb&bb&aaa&aa=x&aa=y', - output: [['aa', 'x'], ['aa', 'y'], ['aaa', ''], ['bb', ''], ['bbb', '']], - }, - { - input: 'z=z&=f&=t&=x', - output: [['', 'f'], ['', 't'], ['', 'x'], ['z', 'z']], - }, - { - input: 'a🌈&a💩', - output: [['a🌈', ''], ['a💩', '']], - }, - ]; - - for (const { input, output } of testData) { - let i = 0; - params = new URLSearchParams(input); - params.sort(); - params.forEach((value, key) => { - const [reqKey, reqValue] = output[i++]; - assert.same(key, reqKey); - assert.same(value, reqValue); - }); - - i = 0; - const url = new URL(`?${ input }`, 'https://example/'); - params = url.searchParams; - params.sort(); - params.forEach((value, key) => { - const [reqKey, reqValue] = output[i++]; - assert.same(key, reqKey); - assert.same(value, reqValue); - }); - } - - if (DESCRIPTORS) { - const url = new URL('http://example.com/?'); - url.searchParams.sort(); - assert.same(url.href, 'http://example.com/', 'Sorting non-existent params removes ? from URL'); - assert.same(url.search, '', 'Sorting non-existent params removes ? from URL'); - } -}); - -QUnit.test('URLSearchParams#toString', assert => { - const { toString } = URLSearchParams.prototype; - assert.isFunction(toString); - assert.arity(toString, 0); - assert.name(toString, 'toString'); - assert.looksNative(toString); - - let params = new URLSearchParams(); - params.append('a', 'b c'); - assert.same(String(params), 'a=b+c'); - params.delete('a'); - params.append('a b', 'c'); - assert.same(String(params), 'a+b=c'); - - params = new URLSearchParams(); - params.append('a', ''); - assert.same(String(params), 'a='); - params.append('a', ''); - assert.same(String(params), 'a=&a='); - params.append('', 'b'); - assert.same(String(params), 'a=&a=&=b'); - params.append('', ''); - assert.same(String(params), 'a=&a=&=b&='); - params.append('', ''); - assert.same(String(params), 'a=&a=&=b&=&='); - - params = new URLSearchParams(); - params.append('', 'b'); - assert.same(String(params), '=b'); - params.append('', 'b'); - assert.same(String(params), '=b&=b'); - - params = new URLSearchParams(); - params.append('', ''); - assert.same(String(params), '='); - params.append('', ''); - assert.same(String(params), '=&='); - - params = new URLSearchParams(); - params.append('a', 'b+c'); - assert.same(String(params), 'a=b%2Bc'); - params.delete('a'); - params.append('a+b', 'c'); - assert.same(String(params), 'a%2Bb=c'); - - params = new URLSearchParams(); - params.append('=', 'a'); - assert.same(String(params), '%3D=a'); - params.append('b', '='); - assert.same(String(params), '%3D=a&b=%3D'); - - params = new URLSearchParams(); - params.append('&', 'a'); - assert.same(String(params), '%26=a'); - params.append('b', '&'); - assert.same(String(params), '%26=a&b=%26'); - - params = new URLSearchParams(); - params.append('a', '\r'); - assert.same(String(params), 'a=%0D'); - - params = new URLSearchParams(); - params.append('a', '\n'); - assert.same(String(params), 'a=%0A'); - - params = new URLSearchParams(); - params.append('a', '\r\n'); - assert.same(String(params), 'a=%0D%0A'); - - params = new URLSearchParams(); - params.append('a', 'b%c'); - assert.same(String(params), 'a=b%25c'); - params.delete('a'); - params.append('a%b', 'c'); - assert.same(String(params), 'a%25b=c'); - - params = new URLSearchParams(); - params.append('a', 'b\0c'); - assert.same(String(params), 'a=b%00c'); - params.delete('a'); - params.append('a\0b', 'c'); - assert.same(String(params), 'a%00b=c'); - - params = new URLSearchParams(); - params.append('a', 'b\uD83D\uDCA9c'); - assert.same(String(params), 'a=b%F0%9F%92%A9c'); - params.delete('a'); - params.append('a\uD83D\uDCA9b', 'c'); - assert.same(String(params), 'a%F0%9F%92%A9b=c'); - - params = new URLSearchParams('a=b&c=d&&e&&'); - assert.same(String(params), 'a=b&c=d&e='); - params = new URLSearchParams('a = b &a=b&c=d%20'); - assert.same(String(params), 'a+=+b+&a=b&c=d+'); - params = new URLSearchParams('a=&a=b'); - assert.same(String(params), 'a=&a=b'); -}); - -QUnit.test('URLSearchParams#forEach', assert => { - const { forEach } = URLSearchParams.prototype; - assert.isFunction(forEach); - assert.arity(forEach, 1); - assert.name(forEach, 'forEach'); - assert.enumerable(URLSearchParams.prototype, 'forEach'); - assert.looksNative(forEach); - - const expectedValues = { a: '1', b: '2', c: '3' }; - let params = new URLSearchParams('a=1&b=2&c=3'); - let result = ''; - params.forEach((value, key, that) => { - assert.same(params.get(key), expectedValues[key]); - assert.same(value, expectedValues[key]); - assert.same(that, params); - result += key; - }); - assert.same(result, 'abc'); - - new URL('http://a.b/c').searchParams.forEach(() => { - assert.ok(false, 'should not be called'); - }); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); - params = url.searchParams; - result = ''; - params.forEach((val, key) => { - url.search = 'x=1&y=2&z=3'; - result += key + val; - }); - assert.same(result, 'a1y2z3'); - } - - // fails in Chrome 66- - params = new URLSearchParams('a=1&b=2&c=3'); - result = ''; - params.forEach((value, key) => { - params.delete('b'); - result += key + value; - }); - assert.same(result, 'a1c3'); -}); - -QUnit.test('URLSearchParams#entries', assert => { - const { entries } = URLSearchParams.prototype; - assert.isFunction(entries); - assert.arity(entries, 0); - assert.name(entries, 'entries'); - assert.enumerable(URLSearchParams.prototype, 'entries'); - assert.looksNative(entries); - - const expectedValues = { a: '1', b: '2', c: '3' }; - let params = new URLSearchParams('a=1&b=2&c=3'); - let iterator = params.entries(); - let result = ''; - let entry; - while (!(entry = iterator.next()).done) { - const [key, value] = entry.value; - assert.same(params.get(key), expectedValues[key]); - assert.same(value, expectedValues[key]); - result += key; - } - assert.same(result, 'abc'); - - assert.ok(new URL('http://a.b/c').searchParams.entries().next().done, 'should be finished'); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); - iterator = url.searchParams.entries(); - result = ''; - while (!(entry = iterator.next()).done) { - const [key, value] = entry.value; - url.search = 'x=1&y=2&z=3'; - result += key + value; - } - assert.same(result, 'a1y2z3'); - } - - // fails in Chrome 66- - params = new URLSearchParams('a=1&b=2&c=3'); - iterator = params.entries(); - result = ''; - while (!(entry = iterator.next()).done) { - params.delete('b'); - const [key, value] = entry.value; - result += key + value; - } - assert.same(result, 'a1c3'); -}); - -QUnit.test('URLSearchParams#keys', assert => { - const { keys } = URLSearchParams.prototype; - assert.isFunction(keys); - assert.arity(keys, 0); - assert.name(keys, 'keys'); - assert.enumerable(URLSearchParams.prototype, 'keys'); - assert.looksNative(keys); - - let iterator = new URLSearchParams('a=1&b=2&c=3').keys(); - let result = ''; - let entry; - while (!(entry = iterator.next()).done) { - result += entry.value; - } - assert.same(result, 'abc'); - - assert.ok(new URL('http://a.b/c').searchParams.keys().next().done, 'should be finished'); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); - iterator = url.searchParams.keys(); - result = ''; - while (!(entry = iterator.next()).done) { - const key = entry.value; - url.search = 'x=1&y=2&z=3'; - result += key; - } - assert.same(result, 'ayz'); - } - - // fails in Chrome 66- - const params = new URLSearchParams('a=1&b=2&c=3'); - iterator = params.keys(); - result = ''; - while (!(entry = iterator.next()).done) { - params.delete('b'); - const key = entry.value; - result += key; - } - assert.same(result, 'ac'); -}); - -QUnit.test('URLSearchParams#values', assert => { - const { values } = URLSearchParams.prototype; - assert.isFunction(values); - assert.arity(values, 0); - assert.name(values, 'values'); - assert.enumerable(URLSearchParams.prototype, 'values'); - assert.looksNative(values); - - let iterator = new URLSearchParams('a=1&b=2&c=3').values(); - let result = ''; - let entry; - while (!(entry = iterator.next()).done) { - result += entry.value; - } - assert.same(result, '123'); - - assert.ok(new URL('http://a.b/c').searchParams.values().next().done, 'should be finished'); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=a&b=b&c=c&d=d'); - iterator = url.searchParams.keys(); - result = ''; - while (!(entry = iterator.next()).done) { - const { value } = entry; - url.search = 'x=x&y=y&z=z'; - result += value; - } - assert.same(result, 'ayz'); - } - - // fails in Chrome 66- - const params = new URLSearchParams('a=1&b=2&c=3'); - iterator = params.values(); - result = ''; - while (!(entry = iterator.next()).done) { - params.delete('b'); - const key = entry.value; - result += key; - } - assert.same(result, '13'); -}); - -QUnit.test('URLSearchParams#@@iterator', assert => { - const entries = URLSearchParams.prototype[Symbol.iterator]; - assert.isFunction(entries); - assert.arity(entries, 0); - assert.name(entries, 'entries'); - assert.looksNative(entries); - - assert.same(entries, URLSearchParams.prototype.entries); - - const expectedValues = { a: '1', b: '2', c: '3' }; - let params = new URLSearchParams('a=1&b=2&c=3'); - let iterator = params[Symbol.iterator](); - let result = ''; - let entry; - while (!(entry = iterator.next()).done) { - const [key, value] = entry.value; - assert.same(params.get(key), expectedValues[key]); - assert.same(value, expectedValues[key]); - result += key; - } - assert.same(result, 'abc'); - - assert.ok(new URL('http://a.b/c').searchParams[Symbol.iterator]().next().done, 'should be finished'); - - // fails in Chrome 66- - if (DESCRIPTORS) { - const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); - iterator = url.searchParams[Symbol.iterator](); - result = ''; - while (!(entry = iterator.next()).done) { - const [key, value] = entry.value; - url.search = 'x=1&y=2&z=3'; - result += key + value; - } - assert.same(result, 'a1y2z3'); - } - - // fails in Chrome 66- - params = new URLSearchParams('a=1&b=2&c=3'); - iterator = params[Symbol.iterator](); - result = ''; - while (!(entry = iterator.next()).done) { - params.delete('b'); - const [key, value] = entry.value; - result += key + value; - } - assert.same(result, 'a1c3'); -}); - -QUnit.test('URLSearchParams#@@toStringTag', assert => { - const params = new URLSearchParams('a=b'); - assert.same(({}).toString.call(params), '[object URLSearchParams]'); -}); diff --git a/tests/tests/web.url.js b/tests/tests/web.url.js deleted file mode 100644 index aa52b277f8f8..000000000000 --- a/tests/tests/web.url.js +++ /dev/null @@ -1,669 +0,0 @@ -import { DESCRIPTORS } from '../helpers/constants'; -import urlTestData from '../wpt-url-resources/urltestdata'; -import settersTestData from '../wpt-url-resources/setters'; -import toASCIITestData from '../wpt-url-resources/toascii'; - -const { hasOwnProperty } = Object.prototype; - -QUnit.test('URL constructor', assert => { - assert.isFunction(URL); - assert.arity(URL, 1); - assert.name(URL, 'URL'); - assert.looksNative(URL); - - assert.same(String(new URL('http://www.domain.com/a/b')), 'http://www.domain.com/a/b'); - assert.same(String(new URL('/c/d', 'http://www.domain.com/a/b')), 'http://www.domain.com/c/d'); - assert.same(String(new URL('b/c', 'http://www.domain.com/a/b')), 'http://www.domain.com/a/b/c'); - assert.same(String(new URL('b/c', new URL('http://www.domain.com/a/b'))), 'http://www.domain.com/a/b/c'); - assert.same(String(new URL({ toString: () => 'https://example.org/' })), 'https://example.org/'); - - assert.same(String(new URL('nonspecial://example.com/')), 'nonspecial://example.com/'); - - assert.same(String(new URL('https://xn--g6w251d/')), 'https://xn--g6w251d/', 'unicode parsing'); - assert.same(String(new URL('https://xn--xx-flcmn5bht.xn--e1aybc/')), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - assert.same(String(new URL('https://xn--xx-flcmn5bht.xn--e1aybc/')), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - assert.same(String(new URL('http://example.com/', 'https://example.org/')), 'http://example.com/'); - assert.same(String(new URL('https://example.com/', 'https://example.org/')), 'https://example.com/'); - assert.same(String(new URL('nonspecial://Example.com/', 'https://example.org/')), 'nonspecial://Example.com/'); - assert.same(String(new URL('http:Example.com/', 'https://example.org/')), 'http://example.com/'); - assert.same(String(new URL('https:Example.com/', 'https://example.org/')), 'https://example.org/Example.com/'); - assert.same(String(new URL('nonspecial:Example.com/', 'https://example.org/')), 'nonspecial:Example.com/'); - - assert.same(String(new URL('http://192.168.0.240/')), 'http://192.168.0.240/'); - assert.same(String(new URL('http://[20:0:0:1::ff]/')), 'http://[20:0:0:1::ff]/'); - // assert.same(String(new URL('http://257.168.0xF0')), 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // TypeError in Chrome and Safari - assert.same(String(new URL('http://0300.168.0xg0/')), 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); - - assert.same(String(new URL('file:///var/log/system.log')), 'file:///var/log/system.log', 'file scheme'); - // assert.same(String(new URL('file://nnsc.nsf.net/bar/baz')), 'file://nnsc.nsf.net/bar/baz', 'file scheme'); // 'file:///bar/baz' in FF - // assert.same(String(new URL('file://localhost/bar/baz')), 'file:///bar/baz', 'file scheme'); // 'file://localhost/bar/baz' in Chrome - - assert.throws(() => new URL(), 'TypeError: Failed to construct \'URL\': 1 argument required, but only 0 present.'); - assert.throws(() => new URL(''), 'TypeError: Failed to construct \'URL\': Invalid URL'); - assert.throws(() => new URL('', 'about:blank'), 'TypeError: Failed to construct \'URL\': Invalid URL'); - assert.throws(() => new URL('abc'), 'TypeError: Failed to construct \'URL\': Invalid URL'); - assert.throws(() => new URL('//abc'), 'TypeError: Failed to construct \'URL\': Invalid URL'); - assert.throws(() => new URL('http://www.domain.com/', 'abc'), 'TypeError: Failed to construct \'URL\': Invalid base URL'); - assert.throws(() => new URL('http://www.domain.com/', null), 'TypeError: Failed to construct \'URL\': Invalid base URL'); - assert.throws(() => new URL('//abc', null), 'TypeError: Failed to construct \'URL\': Invalid base URL'); - assert.throws(() => new URL('http://[20:0:0:1:0:0:0:ff'), 'incorrect IPv6'); - assert.throws(() => new URL('http://[20:0:0:1:0:0:0:fg]'), 'incorrect IPv6'); - // assert.throws(() => new URL('http://a%b'), 'forbidden host code point'); // no error in FF - assert.throws(() => new URL('1http://zloirock.ru'), 'incorrect scheme'); -}); - -QUnit.test('URL#href', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'href')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'href'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.href, 'http://zloirock.ru/'); - - if (DESCRIPTORS) { - url.searchParams.append('foo', 'bar'); - assert.same(url.href, 'http://zloirock.ru/?foo=bar'); - - url = new URL('http://zloirock.ru/foo'); - url.href = 'https://xn--g6w251d/'; - assert.same(url.href, 'https://xn--g6w251d/', 'unicode parsing'); - assert.same(String(url), 'https://xn--g6w251d/', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.href = 'https://xn--xx-flcmn5bht.xn--e1aybc/'; - assert.same(url.href, 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - assert.same(String(url), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.href = 'https://xn--xx-flcmn5bht.xn--e1aybc/'; - assert.same(url.href, 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - assert.same(String(url), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); - - url = new URL('http://zloirock.ru/'); - url.href = 'http://192.168.0.240/'; - assert.same(url.href, 'http://192.168.0.240/'); - assert.same(String(url), 'http://192.168.0.240/'); - - url = new URL('http://zloirock.ru/'); - url.href = 'http://[20:0:0:1::ff]/'; - assert.same(url.href, 'http://[20:0:0:1::ff]/'); - assert.same(String(url), 'http://[20:0:0:1::ff]/'); - - // url = new URL('http://zloirock.ru/'); - // url.href = 'http://257.168.0xF0'; // TypeError and Safari - // assert.same(url.href, 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // `F` instead of `f` in Chrome - // assert.same(String(url), 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // `F` instead of `f` in Chrome - - url = new URL('http://zloirock.ru/'); - url.href = 'http://0300.168.0xg0/'; - assert.same(url.href, 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); - assert.same(String(url), 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); - - url = new URL('http://192.168.0.240/'); - url.href = 'file:///var/log/system.log'; - assert.same(url.href, 'file:///var/log/system.log', 'file -> ip'); - assert.same(String(url), 'file:///var/log/system.log', 'file -> ip'); - - url = new URL('file:///var/log/system.log'); - url.href = 'http://192.168.0.240/'; - assert.same(url.href, 'http://192.168.0.240/', 'file -> http'); - assert.same(String(url), 'http://192.168.0.240/', 'file -> http'); - - // assert.throws(() => new URL('http://zloirock.ru/').href = undefined, 'incorrect URL'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = '', 'incorrect URL'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = 'abc', 'incorrect URL'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = '//abc', 'incorrect URL'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://[20:0:0:1:0:0:0:ff', 'incorrect IPv6'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://[20:0:0:1:0:0:0:fg]', 'incorrect IPv6'); // no error in Chrome - // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://a%b', 'forbidden host code point'); // no error in Chrome and FF - // assert.throws(() => new URL('http://zloirock.ru/').href = '1http://zloirock.ru', 'incorrect scheme'); // no error in Chrome - } -}); - -QUnit.test('URL#origin', assert => { - const url = new URL('http://es6.zloirock.ru/tests.html'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'origin')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'origin'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - } - - assert.same(url.origin, 'http://es6.zloirock.ru/'); - - assert.same(new URL('https://xn--g6w251d/tests').origin, 'https://xn--g6w251d/'); -}); - -QUnit.test('URL#protocol', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'protocol')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'protocol'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.protocol, 'http:'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.protocol = 'https'; - assert.same(url.protocol, 'https:'); - assert.same(String(url), 'https://zloirock.ru/'); - - // https://nodejs.org/api/url.html#url_special_schemes - // url = new URL('http://zloirock.ru/'); - // url.protocol = 'fish'; - // assert.same(url.protocol, 'http:'); - // assert.same(url.href, 'http://zloirock.ru/'); - // assert.same(String(url), 'http://zloirock.ru/'); - - url = new URL('http://zloirock.ru/'); - url.protocol = '1http'; - assert.same(url.protocol, 'http:'); - assert.same(url.href, 'http://zloirock.ru/', 'incorrect scheme'); - assert.same(String(url), 'http://zloirock.ru/', 'incorrect scheme'); - } -}); - -QUnit.test('URL#username', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'username')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'username'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.username, ''); - - url = new URL('http://username@zloirock.ru/'); - assert.same(url.username, 'username'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.username = 'username'; - assert.same(url.username, 'username'); - assert.same(String(url), 'http://username@zloirock.ru/'); - } -}); - -QUnit.test('URL#password', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'password')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'password'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.password, ''); - - url = new URL('http://username:password@zloirock.ru/'); - assert.same(url.password, 'password'); - - // url = new URL('http://:password@zloirock.ru/'); // TypeError in FF - // assert.same(url.password, 'password'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.username = 'username'; - url.password = 'password'; - assert.same(url.password, 'password'); - assert.same(String(url), 'http://username:password@zloirock.ru/'); - - // url = new URL('http://zloirock.ru/'); - // url.password = 'password'; - // assert.same(url.password, 'password'); // '' in FF - // assert.same(String(url), 'http://:password@zloirock.ru/'); // 'http://zloirock.ru/' in FF - } -}); - -QUnit.test('URL#host', assert => { - let url = new URL('http://zloirock.ru:81/path'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'host')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'host'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.host, 'zloirock.ru:81'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru:81/path'); - url.host = 'example.com:82'; - assert.same(url.host, 'example.com:82'); - assert.same(String(url), 'http://example.com:82/path'); - - // url = new URL('http://zloirock.ru:81/path'); - // url.host = 'other?domain.com'; - // assert.same(String(url), 'http://other:81/path'); // 'http://other/?domain.com/path' in Safari - - url = new URL('https://www.mydomain.com:8080/path/'); - url.host = 'www.otherdomain.com:80'; - assert.same(url.href, 'https://www.otherdomain.com:80/path/', 'set default port for another protocol'); - - // url = new URL('https://www.mydomain.com:8080/path/'); - // url.host = 'www.otherdomain.com:443'; - // assert.same(url.href, 'https://www.otherdomain.com/path/', 'set default port'); - - url = new URL('http://zloirock.ru/foo'); - url.host = '測試'; - assert.same(url.host, 'xn--g6w251d', 'unicode parsing'); - assert.same(String(url), 'http://xn--g6w251d/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.host = 'xxпривет.тест'; - assert.same(url.host, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); - assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.host = 'xxПРИВЕТ.тест'; - assert.same(url.host, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); - assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.host = '0300.168.0xF0'; - assert.same(url.host, '192.168.0.240'); - assert.same(String(url), 'http://192.168.0.240/foo'); - - // url = new URL('http://zloirock.ru/foo'); - // url.host = '[20:0:0:1:0:0:0:ff]'; - // assert.same(url.host, '[20:0:0:1::ff]'); // ':0' in Chrome, 'zloirock.ru' in Safari - // assert.same(String(url), 'http://[20:0:0:1::ff]/foo'); // 'http://[20:0/foo' in Chrome, 'http://zloirock.ru/foo' in Safari - - // url = new URL('file:///var/log/system.log'); - // url.host = 'nnsc.nsf.net'; // does not work in FF - // assert.same(url.hostname, 'nnsc.nsf.net', 'file'); - // assert.same(String(url), 'file://nnsc.nsf.net/var/log/system.log', 'file'); - - // url = new URL('http://zloirock.ru/'); - // url.host = '[20:0:0:1:0:0:0:ff'; - // assert.same(url.host, 'zloirock.ru', 'incorrect IPv6'); // ':0' in Chrome - // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0/' in Chrome - - // url = new URL('http://zloirock.ru/'); - // url.host = '[20:0:0:1:0:0:0:fg]'; - // assert.same(url.host, 'zloirock.ru', 'incorrect IPv6'); // ':0' in Chrome - // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0/' in Chrome - - // url = new URL('http://zloirock.ru/'); - // url.host = 'a%b'; - // assert.same(url.host, 'zloirock.ru', 'forbidden host code point'); // '' in Chrome, 'a%b' in FF - // assert.same(String(url), 'http://zloirock.ru/', 'forbidden host code point'); // 'http://a%25b/' in Chrome, 'http://a%b/' in FF - } -}); - -QUnit.test('URL#hostname', assert => { - let url = new URL('http://zloirock.ru:81/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'hostname')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'hostname'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.hostname, 'zloirock.ru'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru:81/'); - url.hostname = 'example.com'; - assert.same(url.hostname, 'example.com'); - assert.same(String(url), 'http://example.com:81/'); - - // url = new URL('http://zloirock.ru:81/'); - // url.hostname = 'example.com:82'; - // assert.same(url.hostname, 'example.com'); // '' in Chrome - // assert.same(String(url), 'http://example.com:81/'); // 'ttp://example.com:82:81/' in Chrome - - url = new URL('http://zloirock.ru/foo'); - url.hostname = '測試'; - assert.same(url.hostname, 'xn--g6w251d', 'unicode parsing'); - assert.same(String(url), 'http://xn--g6w251d/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.hostname = 'xxпривет.тест'; - assert.same(url.hostname, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); - assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.hostname = 'xxПРИВЕТ.тест'; - assert.same(url.hostname, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); - assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); - - url = new URL('http://zloirock.ru/foo'); - url.hostname = '0300.168.0xF0'; - assert.same(url.hostname, '192.168.0.240'); - assert.same(String(url), 'http://192.168.0.240/foo'); - - // url = new URL('http://zloirock.ru/foo'); - // url.hostname = '[20:0:0:1:0:0:0:ff]'; - // assert.same(url.hostname, '[20:0:0:1::ff]'); // 'zloirock.ru' in Safari - // assert.same(String(url), 'http://[20:0:0:1::ff]/foo'); // 'http://zloirock.ru/foo' in Safari - - // url = new URL('file:///var/log/system.log'); - // url.hostname = 'nnsc.nsf.net'; // does not work in FF - // assert.same(url.hostname, 'nnsc.nsf.net', 'file'); - // assert.same(String(url), 'file://nnsc.nsf.net/var/log/system.log', 'file'); - - // url = new URL('http://zloirock.ru/'); - // url.hostname = '[20:0:0:1:0:0:0:ff'; - // assert.same(url.hostname, 'zloirock.ru', 'incorrect IPv6'); // '' in Chrome - // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0:0:1:0:0:0:ff' in Chrome - - // url = new URL('http://zloirock.ru/'); - // url.hostname = '[20:0:0:1:0:0:0:fg]'; - // assert.same(url.hostname, 'zloirock.ru', 'incorrect IPv6'); // '' in Chrome - // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0:0:1:0:0:0:ff/' in Chrome - - // url = new URL('http://zloirock.ru/'); - // url.hostname = 'a%b'; - // assert.same(url.hostname, 'zloirock.ru', 'forbidden host code point'); // '' in Chrome, 'a%b' in FF - // assert.same(String(url), 'http://zloirock.ru/', 'forbidden host code point'); // 'http://a%25b/' in Chrome, 'http://a%b/' in FF - } -}); - -QUnit.test('URL#port', assert => { - let url = new URL('http://zloirock.ru:1337/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'port')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'port'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.port, '1337'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.port = 80; - assert.same(url.port, ''); - assert.same(String(url), 'http://zloirock.ru/'); - url.port = 1337; - assert.same(url.port, '1337'); - assert.same(String(url), 'http://zloirock.ru:1337/'); - // url.port = 'abcd'; - // assert.same(url.port, '1337'); // '0' in Chrome - // assert.same(String(url), 'http://zloirock.ru:1337/'); // 'http://zloirock.ru:0/' in Chrome - // url.port = '5678abcd'; - // assert.same(url.port, '5678'); // '1337' in FF - // assert.same(String(url), 'http://zloirock.ru:5678/'); // 'http://zloirock.ru:1337/"' in FF - url.port = 1234.5678; - assert.same(url.port, '1234'); - assert.same(String(url), 'http://zloirock.ru:1234/'); - // url.port = 1e10; - // assert.same(url.port, '1234'); // '0' in Chrome - // assert.same(String(url), 'http://zloirock.ru:1234/'); // 'http://zloirock.ru:0/' in Chrome - } -}); - -QUnit.test('URL#pathname', assert => { - let url = new URL('http://zloirock.ru/foo/bar'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'pathname')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'pathname'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.pathname, '/foo/bar'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.pathname = 'bar/baz'; - assert.same(url.pathname, '/bar/baz'); - assert.same(String(url), 'http://zloirock.ru/bar/baz'); - } -}); - -QUnit.test('URL#search', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'search')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'search'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.search, ''); - - url = new URL('http://zloirock.ru/?foo=bar'); - assert.same(url.search, '?foo=bar'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/?'); - assert.same(url.search, ''); - assert.same(String(url), 'http://zloirock.ru/?'); - url.search = 'foo=bar'; - assert.same(url.search, '?foo=bar'); - assert.same(String(url), 'http://zloirock.ru/?foo=bar'); - url.search = '?bar=baz'; - assert.same(url.search, '?bar=baz'); - assert.same(String(url), 'http://zloirock.ru/?bar=baz'); - url.search = ''; - assert.same(url.search, ''); - assert.same(String(url), 'http://zloirock.ru/'); - } -}); - -QUnit.test('URL#searchParams', assert => { - let url = new URL('http://zloirock.ru/?foo=bar&bar=baz'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'searchParams')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'searchParams'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - } - - assert.ok(url.searchParams instanceof URLSearchParams); - assert.same(url.searchParams.get('foo'), 'bar'); - assert.same(url.searchParams.get('bar'), 'baz'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/'); - url.searchParams.append('foo', 'bar'); - assert.same(String(url), 'http://zloirock.ru/?foo=bar'); - - url = new URL('http://zloirock.ru/'); - url.search = 'foo=bar'; - assert.same(url.searchParams.get('foo'), 'bar'); - - url = new URL('http://zloirock.ru/?foo=bar&bar=baz'); - url.search = ''; - assert.same(url.searchParams.has('foo'), false); - } -}); - -QUnit.test('URL#hash', assert => { - let url = new URL('http://zloirock.ru/'); - - if (DESCRIPTORS) { - assert.ok(!hasOwnProperty.call(url, 'hash')); - const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'hash'); - assert.same(descriptor.enumerable, true); - assert.same(descriptor.configurable, true); - assert.same(typeof descriptor.get, 'function'); - assert.same(typeof descriptor.set, 'function'); - } - - assert.same(url.hash, ''); - - url = new URL('http://zloirock.ru/#foo'); - assert.same(url.hash, '#foo'); - - url = new URL('http://zloirock.ru/#'); - assert.same(url.hash, ''); - assert.same(String(url), 'http://zloirock.ru/#'); - - if (DESCRIPTORS) { - url = new URL('http://zloirock.ru/#'); - url.hash = 'foo'; - assert.same(url.hash, '#foo'); - assert.same(String(url), 'http://zloirock.ru/#foo'); - url.hash = ''; - assert.same(url.hash, ''); - assert.same(String(url), 'http://zloirock.ru/'); - // url.hash = '#'; - // assert.same(url.hash, ''); - // assert.same(String(url), 'http://zloirock.ru/'); // 'http://zloirock.ru/#' in FF - url.hash = '#foo'; - assert.same(url.hash, '#foo'); - assert.same(String(url), 'http://zloirock.ru/#foo'); - url.hash = '#foo#bar'; - assert.same(url.hash, '#foo#bar'); - assert.same(String(url), 'http://zloirock.ru/#foo#bar'); - - url = new URL('http://zloirock.ru/'); - url.hash = 'абa'; - assert.same(url.hash, '#%D0%B0%D0%B1a'); - - // url = new URL('http://zloirock.ru/'); - // url.hash = '\udc01\ud802a'; - // assert.same(url.hash, '#%EF%BF%BD%EF%BF%BDa', 'unmatched surrogates'); - } -}); - -QUnit.test('URL#toJSON', assert => { - const { toJSON } = URL.prototype; - assert.isFunction(toJSON); - assert.arity(toJSON, 0); - assert.name(toJSON, 'toJSON'); - assert.enumerable(URL.prototype, 'toJSON'); - assert.looksNative(toJSON); - - const url = new URL('http://zloirock.ru/'); - assert.same(url.toJSON(), 'http://zloirock.ru/'); - - if (DESCRIPTORS) { - url.searchParams.append('foo', 'bar'); - assert.same(url.toJSON(), 'http://zloirock.ru/?foo=bar'); - } -}); - -QUnit.test('URL#toString', assert => { - const { toString } = URL.prototype; - assert.isFunction(toString); - assert.arity(toString, 0); - assert.name(toString, 'toString'); - assert.enumerable(URL.prototype, 'toString'); - assert.looksNative(toString); - - const url = new URL('http://zloirock.ru/'); - assert.same(url.toString(), 'http://zloirock.ru/'); - - if (DESCRIPTORS) { - url.searchParams.append('foo', 'bar'); - assert.same(url.toString(), 'http://zloirock.ru/?foo=bar'); - } -}); - -QUnit.test('URL#@@toStringTag', assert => { - const url = new URL('http://zloirock.ru/'); - assert.same(({}).toString.call(url), '[object URL]'); -}); - -QUnit.test('URL.sham', assert => { - assert.same(URL.sham, DESCRIPTORS ? undefined : true); -}); - -// `core-js` URL implementation pass all (exclude some encoding-ralated) tests -// from the next 3 test cases, but URLs from all of popular browsers fail a serious part of tests. -// Replacing all of them does not looks like a good idea, so next test cases disabled by default. - -// see https://github.com/web-platform-tests/wpt/blob/master/url -QUnit.skip('WPT URL constructor tests', assert => { - for (const expected of urlTestData) { - if (typeof expected == 'string') continue; - const name = `Parsing: <${ expected.input }> against <${ expected.base }>`; - if (expected.failure) { - assert.throws(() => new URL(expected.input, expected.base || 'about:blank'), name); - } else { - const url = new URL(expected.input, expected.base || 'about:blank'); - assert.same(url.href, expected.href, `${ name }: href`); - assert.same(url.protocol, expected.protocol, `${ name }: protocol`); - assert.same(url.username, expected.username, `${ name }: username`); - assert.same(url.password, expected.password, `${ name }: password`); - assert.same(url.host, expected.host, `${ name }: host`); - assert.same(url.hostname, expected.hostname, `${ name }: hostname`); - assert.same(url.port, expected.port, `${ name }: port`); - assert.same(url.pathname, expected.pathname, `${ name }: pathname`); - assert.same(url.search, expected.search, `${ name }: search`); - if ('searchParams' in expected) { - assert.same(url.searchParams.toString(), expected.searchParams, `${ name }: searchParams`); - } - assert.same(url.hash, expected.hash, `${ name }: hash`); - if ('origin' in expected) { - assert.same(url.origin, expected.origin, `${ name }: origin`); - } - } - } -}); - -// see https://github.com/web-platform-tests/wpt/blob/master/url -if (DESCRIPTORS) QUnit.skip('WPT URL setters tests', assert => { - for (const setter in settersTestData) { - const testCases = settersTestData[setter]; - for (const { href, newValue, comment, expected } of testCases) { - let name = `Setting <${ href }>.${ setter } = '${ newValue }'.`; - if (comment) name += ` ${ comment }`; - - const url = new URL(href); - url[setter] = newValue; - for (const attribute in expected) { - assert.same(url[attribute], expected[attribute], name); - } - } - } -}); - -// see https://github.com/web-platform-tests/wpt/blob/master/url -QUnit.skip('WPT conversion to ASCII tests', assert => { - for (const { comment, input, output } of toASCIITestData) { - let name = `Parsing: <${ input }>`; - if (comment) name += ` ${ comment }`; - if (output === null) { - assert.throws(() => new URL(`https://${ input }/x`), name); - } else { - const url = new URL(`https://${ input }/x`); - assert.same(url.host, output, name); - assert.same(url.hostname, output, name); - assert.same(url.pathname, '/x', name); - assert.same(url.href, `https://${ output }/x`, name); - } - } -}); diff --git a/tests/type-definitions/builder.ts b/tests/type-definitions/builder.ts new file mode 100644 index 000000000000..432f0c243e7f --- /dev/null +++ b/tests/type-definitions/builder.ts @@ -0,0 +1,68 @@ +import builder from 'core-js-builder'; + +const a: Promise = builder({ targets: { node: 17 } }); +const b: string = await builder({ targets: { node: 17 } }); + +await builder(); +await builder({}); +await builder({ modules: 'core-js/actual' }); +await builder({ modules: 'es.array.push' }); +await builder({ modules: /^es\.array\./ }); +await builder({ modules: ['core-js/actual', /^es\.array\./] }); +await builder({ exclude: 'core-js/actual' }); +await builder({ exclude: 'es.array.push' }); +await builder({ exclude: /^es\.array\./ }); +await builder({ exclude: ['core-js/actual', /^es\.array\./] }); +await builder({ modules: 'core-js/actual', exclude: /^es\.array\./ }); +await builder({ targets: '> 1%' }); +await builder({ targets: ['defaults', 'last 5 versions'] }); +await builder({ targets: { esmodules: true, node: 'current', browsers: ['> 1%'] } }); +await builder({ targets: { chrome: '26', firefox: 4 } }); +await builder({ targets: { browsers: { chrome: '26', firefox: 4 } } }); +await builder({ targets: { chrome: '26', firefox: 4, esmodules: true, node: 'current', browsers: ['> 1%'] } }); +await builder({ format: 'bundle' }); +await builder({ format: 'esm' }); +await builder({ format: 'cjs' }); +await builder({ filename: '/foo/bar/baz.js' }); +await builder({ summary: { comment: true } }); +await builder({ summary: { comment: { size: true } } }); +await builder({ summary: { comment: { size: false, modules: true } } }); +await builder({ summary: { console: true } }); +await builder({ summary: { console: { size: true } } }); +await builder({ summary: { console: { size: false, modules: true } } }); +await builder({ summary: { console: { size: false, modules: true }, comment: { size: false, modules: true } } }); +await builder({ + modules: 'core-js/actual', + exclude: /^es\.array\./, + targets: { + android: 1, + bun: '1', + chrome: 1, + 'chrome-android': '1', + deno: 1, + edge: '1', + electron: 1, + firefox: '1', + 'firefox-android': 1, + hermes: '1', + ie: 1, + ios: '1', + opera: 1, + 'opera-android': '1', + phantom: 1, + quest: '1', + 'react-native': 1, + rhino: '1', + safari: 1, + samsung: '1', + node: 'current', + esmodules: true, + browsers: ['> 1%'], + }, + format: 'bundle', + filename: '/foo/bar/baz.js', + summary: { + console: { size: false, modules: true }, + comment: { size: false, modules: true }, + }, +}); diff --git a/tests/type-definitions/compat.ts b/tests/type-definitions/compat.ts new file mode 100644 index 000000000000..340961ca3014 --- /dev/null +++ b/tests/type-definitions/compat.ts @@ -0,0 +1,77 @@ +import compat from 'core-js-compat'; +import compat2 from 'core-js-compat/compat'; +import getModulesListForTargetVersion from 'core-js-compat/get-modules-list-for-target-version'; + +getModulesListForTargetVersion('3.0'); +compat.getModulesListForTargetVersion('3.0'); + +compat.data['es.array.push'].android +compat.data['es.array.push'].firefox + +if (typeof compat.modules[0] !== 'string') { + console.error('Invalid'); +} + +if (!compat.entries['core-js'].includes('es.array.from')) { + console.error('Invalid') +} + +compat(); +compat({}); +compat({ modules: 'core-js/actual' }); +compat({ modules: 'es.array.push' }); +compat({ modules: /^es\.array\./ }); +compat({ modules: ['core-js/actual', /^es\.array\./] }); +compat({ exclude: 'core-js/actual' }); +compat({ exclude: 'es.array.push' }); +compat({ exclude: /^es\.array\./ }); +compat({ exclude: ['core-js/actual', /^es\.array\./] }); +compat({ modules: 'core-js/actual', exclude: /^es\.array\./ }); +compat({ targets: '> 1%' }); +compat({ targets: ['defaults', 'last 5 versions'] }); +compat({ targets: { esmodules: true, node: 'current', browsers: ['> 1%'] } }); +compat({ targets: { chrome: '26', firefox: 4 } }); +compat({ targets: { browsers: { chrome: '26', firefox: 4 } } }); +compat({ targets: { chrome: '26', firefox: 4, esmodules: true, node: 'current', browsers: ['> 1%'] } }); +compat({ version: '3.0' }); +compat({ inverse: true }); + +compat.compat(); +compat.compat({}); +compat.compat({ modules: 'core-js/actual' }); +compat.compat({ modules: 'es.array.push' }); +compat.compat({ modules: /^es\.array\./ }); +compat.compat({ modules: ['core-js/actual', /^es\.array\./] }); +compat.compat({ exclude: 'core-js/actual' }); +compat.compat({ exclude: 'es.array.push' }); +compat.compat({ exclude: /^es\.array\./ }); +compat.compat({ exclude: ['core-js/actual', /^es\.array\./] }); +compat.compat({ modules: 'core-js/actual', exclude: /^es\.array\./ }); +compat.compat({ targets: '> 1%' }); +compat.compat({ targets: ['defaults', 'last 5 versions'] }); +compat.compat({ targets: { esmodules: true, node: 'current', browsers: ['> 1%'] } }); +compat.compat({ targets: { chrome: '26', firefox: 4 } }); +compat.compat({ targets: { browsers: { chrome: '26', firefox: 4 } } }); +compat.compat({ targets: { chrome: '26', firefox: 4, esmodules: true, node: 'current', browsers: ['> 1%'] } }); +compat.compat({ version: '3.0' }); +compat.compat({ inverse: true }); + +compat2(); +compat2({}); +compat2({ modules: 'core-js/actual' }); +compat2({ modules: 'es.array.push' }); +compat2({ modules: /^es\.array\./ }); +compat2({ modules: ['core-js/actual', /^es\.array\./] }); +compat2({ exclude: 'core-js/actual' }); +compat2({ exclude: 'es.array.push' }); +compat2({ exclude: /^es\.array\./ }); +compat2({ exclude: ['core-js/actual', /^es\.array\./] }); +compat2({ modules: 'core-js/actual', exclude: /^es\.array\./ }); +compat2({ targets: '> 1%' }); +compat2({ targets: ['defaults', 'last 5 versions'] }); +compat2({ targets: { esmodules: true, node: 'current', browsers: ['> 1%'] } }); +compat2({ targets: { chrome: '26', firefox: 4 } }); +compat2({ targets: { browsers: { chrome: '26', firefox: 4 } } }); +compat2({ targets: { chrome: '26', firefox: 4, esmodules: true, node: 'current', browsers: ['> 1%'] } }); +compat2({ version: '3.0' }); +compat2({ inverse: true }); diff --git a/tests/type-definitions/package-lock.json b/tests/type-definitions/package-lock.json new file mode 100644 index 000000000000..f5989ce6d385 --- /dev/null +++ b/tests/type-definitions/package-lock.json @@ -0,0 +1,27 @@ +{ + "name": "tests/type-definitions", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests/type-definitions", + "devDependencies": { + "typescript": "^5.9.3" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + } + } +} diff --git a/tests/type-definitions/package.json b/tests/type-definitions/package.json new file mode 100644 index 000000000000..dffa3cb452e1 --- /dev/null +++ b/tests/type-definitions/package.json @@ -0,0 +1,6 @@ +{ + "name": "tests/type-definitions", + "devDependencies": { + "typescript": "^5.9.3" + } +} diff --git a/tests/type-definitions/runner.mjs b/tests/type-definitions/runner.mjs new file mode 100644 index 000000000000..280f0863e94b --- /dev/null +++ b/tests/type-definitions/runner.mjs @@ -0,0 +1 @@ +await $`tsc`; diff --git a/tests/type-definitions/tsconfig.json b/tests/type-definitions/tsconfig.json new file mode 100644 index 000000000000..8809cf496f3e --- /dev/null +++ b/tests/type-definitions/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "esModuleInterop": true, + "noEmit": true + }, + "include": [ + "*.ts" + ] +} diff --git a/tests/unit-browser/global.html b/tests/unit-browser/global.html new file mode 100644 index 000000000000..17aa1e109fd2 --- /dev/null +++ b/tests/unit-browser/global.html @@ -0,0 +1,15 @@ + + +core-js + +
+
+ + + + + diff --git a/tests/unit-browser/pure.html b/tests/unit-browser/pure.html new file mode 100644 index 000000000000..fd34f603afd2 --- /dev/null +++ b/tests/unit-browser/pure.html @@ -0,0 +1,11 @@ + + +core-js-pure + +
+
+ + + diff --git a/tests/unit-bun/package-lock.json b/tests/unit-bun/package-lock.json new file mode 100644 index 000000000000..7b4410497920 --- /dev/null +++ b/tests/unit-bun/package-lock.json @@ -0,0 +1,76 @@ +{ + "name": "tests/unit-bun", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests/unit-bun", + "devDependencies": { + "qunit": "^2.24.3" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-watch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qunit": { + "version": "2.24.3", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.24.3.tgz", + "integrity": "sha512-JTHwSfHf2Cw8TqusZo2tT4F9d+XA/pp/veoxUDiPNHtB1Wc1VPctiHHIv6HA3vrXNOBu9LSzFM7YU2OV9Gz4vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "7.2.0", + "node-watch": "0.7.3", + "tiny-glob": "0.2.9" + }, + "bin": { + "qunit": "bin/qunit.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + } + } +} diff --git a/tests/unit-bun/package.json b/tests/unit-bun/package.json new file mode 100644 index 000000000000..3be57ad8fe34 --- /dev/null +++ b/tests/unit-bun/package.json @@ -0,0 +1,6 @@ +{ + "name": "tests/unit-bun", + "devDependencies": { + "qunit": "^2.24.3" + } +} diff --git a/tests/unit-bun/runner.mjs b/tests/unit-bun/runner.mjs new file mode 100644 index 000000000000..f69d30e45bb9 --- /dev/null +++ b/tests/unit-bun/runner.mjs @@ -0,0 +1,8 @@ +if (await which('bun', { nothrow: true })) { + await Promise.all([ + // some cases loading from modules works incorrectly in Bun, so test only bundled core-js version + // ['packages/core-js/index', 'tests/bundles/unit-global'], + ['packages/core-js-bundle/index', 'tests/bundles/unit-global'], + ['tests/bundles/unit-pure'], + ].map(files => $`bun qunit ${ files.map(file => `../../${ file }.js`) }`)); +} else echo(chalk.cyan('bun is not found')); diff --git a/tests/unit-global/es.aggregate-error.js b/tests/unit-global/es.aggregate-error.js new file mode 100644 index 000000000000..cfc159aa3168 --- /dev/null +++ b/tests/unit-global/es.aggregate-error.js @@ -0,0 +1,53 @@ +/* eslint-disable unicorn/throw-new-error -- testing */ +const { create } = Object; + +QUnit.test('AggregateError', assert => { + assert.isFunction(AggregateError); + assert.arity(AggregateError, 2); + assert.name(AggregateError, 'AggregateError'); + assert.looksNative(AggregateError); + assert.true(new AggregateError([1]) instanceof AggregateError); + assert.true(new AggregateError([1]) instanceof Error); + assert.true(AggregateError([1]) instanceof AggregateError); + assert.true(AggregateError([1]) instanceof Error); + assert.same(AggregateError([1], 'foo').message, 'foo'); + assert.same(AggregateError([1], 123).message, '123'); + assert.same(AggregateError([1]).message, ''); + assert.deepEqual(AggregateError([1, 2, 3]).errors, [1, 2, 3]); + assert.throws(() => AggregateError([1], Symbol('AggregateError test')), 'throws on symbol as a message'); + assert.same(({}).toString.call(AggregateError([1])), '[object Error]', 'Object#toString'); + + assert.same(AggregateError.prototype.constructor, AggregateError, 'prototype constructor'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.false(AggregateError.prototype.hasOwnProperty('cause'), 'prototype has not cause'); + + assert.true(AggregateError([1], 1) instanceof AggregateError, 'no cause, without new'); + assert.true(new AggregateError([1], 1) instanceof AggregateError, 'no cause, with new'); + + assert.true(AggregateError([1], 1, {}) instanceof AggregateError, 'with options, without new'); + assert.true(new AggregateError([1], 1, {}) instanceof AggregateError, 'with options, with new'); + + assert.true(AggregateError([1], 1, 'foo') instanceof AggregateError, 'non-object options, without new'); + assert.true(new AggregateError([1], 1, 'foo') instanceof AggregateError, 'non-object options, with new'); + + assert.same(AggregateError([1], 1, { cause: 7 }).cause, 7, 'cause, without new'); + assert.same(new AggregateError([1], 1, { cause: 7 }).cause, 7, 'cause, with new'); + + assert.same(AggregateError([1], 1, create({ cause: 7 })).cause, 7, 'prototype cause, without new'); + assert.same(new AggregateError([1], 1, create({ cause: 7 })).cause, 7, 'prototype cause, with new'); + + let error = AggregateError([1], 1, { cause: 7 }); + assert.deepEqual(error.errors, [1]); + assert.same(error.name, 'AggregateError', 'instance name'); + assert.same(error.message, '1', 'instance message'); + assert.same(error.cause, 7, 'instance cause'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.true(error.hasOwnProperty('cause'), 'cause is own'); + + error = AggregateError([1]); + assert.deepEqual(error.errors, [1]); + assert.same(error.message, '', 'default instance message'); + assert.same(error.cause, undefined, 'default instance cause undefined'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.false(error.hasOwnProperty('cause'), 'default instance cause missed'); +}); diff --git a/tests/tests/es.array-buffer.constructor.js b/tests/unit-global/es.array-buffer.constructor.js similarity index 99% rename from tests/tests/es.array-buffer.constructor.js rename to tests/unit-global/es.array-buffer.constructor.js index 4fd002e222da..c432c6189ab1 100644 --- a/tests/tests/es.array-buffer.constructor.js +++ b/tests/unit-global/es.array-buffer.constructor.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants'; +import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants.js'; QUnit.test('ArrayBuffer', assert => { const Symbol = GLOBAL.Symbol || {}; diff --git a/tests/unit-global/es.array-buffer.detached.js b/tests/unit-global/es.array-buffer.detached.js new file mode 100644 index 000000000000..62b54664f3bd --- /dev/null +++ b/tests/unit-global/es.array-buffer.detached.js @@ -0,0 +1,33 @@ +/* eslint-disable es/no-shared-array-buffer -- testing */ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('ArrayBuffer#detached', assert => { + assert.same(new ArrayBuffer(8).detached, false, 'default'); + + const detached = new ArrayBuffer(8); + try { + structuredClone(detached, { transfer: [detached] }); + } catch { /* empty */ } + + if (detached.byteLength === 0) { + // works incorrectly in ancient WebKit + assert.skip.true(detached.detached, true, 'detached'); + } + + if (DESCRIPTORS) { + const { get, configurable, enumerable } = Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'detached'); + assert.same(configurable, true, 'configurable'); + assert.same(enumerable, false, 'non-enumerable'); + assert.isFunction(get); + assert.looksNative(get); + assert.throws(() => get.call(null), TypeError, 'non-generic-1'); + assert.throws(() => get(), TypeError, 'non-generic-2'); + assert.throws(() => get.call(1), TypeError, 'non-generic-3'); + assert.throws(() => get.call(true), TypeError, 'non-generic-4'); + assert.throws(() => get.call(''), TypeError, 'non-generic-5'); + assert.throws(() => get.call({}), TypeError, 'non-generic-6'); + if (typeof SharedArrayBuffer == 'function') { + assert.throws(() => get.call(new SharedArrayBuffer(8)), TypeError, 'non-generic-7'); + } + } +}); diff --git a/tests/unit-global/es.array-buffer.is-view.js b/tests/unit-global/es.array-buffer.is-view.js new file mode 100644 index 000000000000..6e3d0c68b413 --- /dev/null +++ b/tests/unit-global/es.array-buffer.is-view.js @@ -0,0 +1,21 @@ +import { TYPED_ARRAYS } from '../helpers/constants.js'; + +QUnit.test('ArrayBuffer.isView', assert => { + const { isView } = ArrayBuffer; + assert.isFunction(isView); + assert.arity(isView, 1); + assert.name(isView, 'isView'); + assert.looksNative(isView); + assert.nonEnumerable(ArrayBuffer, 'isView'); + for (const { name, TypedArray } of TYPED_ARRAYS) { + if (TypedArray) { + assert.true(isView(new TypedArray([1])), `${ name } - true`); + } + } + assert.true(isView(new DataView(new ArrayBuffer(1))), 'DataView - true'); + assert.false(isView(new ArrayBuffer(1)), 'ArrayBuffer - false'); + const examples = [undefined, null, false, true, 0, 1, '', 'qwe', {}, [], function () { /* empty */ }]; + for (const example of examples) { + assert.false(isView(example), `${ example } - false`); + } +}); diff --git a/tests/unit-global/es.array-buffer.slice.js b/tests/unit-global/es.array-buffer.slice.js new file mode 100644 index 000000000000..dcc8cddee7b6 --- /dev/null +++ b/tests/unit-global/es.array-buffer.slice.js @@ -0,0 +1,21 @@ +import { arrayToBuffer, bufferToArray } from '../helpers/helpers.js'; + +QUnit.test('ArrayBuffer#slice', assert => { + const { slice } = ArrayBuffer.prototype; + + assert.isFunction(slice); + assert.arity(slice, 2); + assert.name(slice, 'slice'); + assert.looksNative(slice); + // assert.nonEnumerable(ArrayBuffer.prototype, 'slice'); + const buffer = arrayToBuffer([1, 2, 3, 4, 5]); + assert.true(buffer instanceof ArrayBuffer, 'correct buffer'); + assert.notSame(buffer.slice(), buffer, 'returns new buffer'); + assert.true(buffer.slice() instanceof ArrayBuffer, 'correct instance'); + assert.arrayEqual(bufferToArray(buffer.slice()), [1, 2, 3, 4, 5]); + assert.arrayEqual(bufferToArray(buffer.slice(1, 3)), [2, 3]); + assert.arrayEqual(bufferToArray(buffer.slice(1, undefined)), [2, 3, 4, 5]); + assert.arrayEqual(bufferToArray(buffer.slice(1, -1)), [2, 3, 4]); + assert.arrayEqual(bufferToArray(buffer.slice(-2, -1)), [4]); + assert.arrayEqual(bufferToArray(buffer.slice(-2, -3)), []); +}); diff --git a/tests/unit-global/es.array-buffer.transfer-to-fixed-length.js b/tests/unit-global/es.array-buffer.transfer-to-fixed-length.js new file mode 100644 index 000000000000..123ae980b7d3 --- /dev/null +++ b/tests/unit-global/es.array-buffer.transfer-to-fixed-length.js @@ -0,0 +1,70 @@ +/* eslint-disable es/no-shared-array-buffer -- testing */ +import { GLOBAL } from '../helpers/constants.js'; +import { arrayToBuffer, bufferToArray } from '../helpers/helpers.js'; + +const transferToFixedLength = GLOBAL?.ArrayBuffer?.prototype?.transferToFixedLength; + +if (transferToFixedLength) QUnit.test('ArrayBuffer#transferToFixedLength', assert => { + assert.isFunction(transferToFixedLength); + assert.arity(transferToFixedLength, 0); + assert.name(transferToFixedLength, 'transferToFixedLength'); + assert.looksNative(transferToFixedLength); + assert.nonEnumerable(ArrayBuffer.prototype, 'transferToFixedLength'); + + const DETACHED = 'detached' in ArrayBuffer.prototype; + + const array = [0, 1, 2, 3, 4, 5, 6, 7]; + + let buffer = arrayToBuffer(array); + let transferred = buffer.transferToFixedLength(); + assert.notSame(transferred, buffer, 'returns new buffer 1'); + assert.true(transferred instanceof ArrayBuffer, 'returns ArrayBuffer 1'); + assert.same(buffer.byteLength, 0, 'original array length 1'); + // works incorrectly in ancient WebKit + if (DETACHED) assert.skip.true(buffer.detached, 'original array detached 1'); + assert.same(transferred.byteLength, 8, 'proper transferred byteLength 1'); + assert.arrayEqual(bufferToArray(transferred), array, 'properly copied 1'); + + buffer = arrayToBuffer(array); + transferred = buffer.transferToFixedLength(5); + assert.notSame(transferred, buffer, 'returns new buffer 2'); + assert.true(transferred instanceof ArrayBuffer, 'returns ArrayBuffer 2'); + assert.same(buffer.byteLength, 0, 'original array length 2'); + // works incorrectly in ancient WebKit + if (DETACHED) assert.skip.true(buffer.detached, 'original array detached 2'); + assert.same(transferred.byteLength, 5, 'proper transferred byteLength 2'); + assert.arrayEqual(bufferToArray(transferred), array.slice(0, 5), 'properly copied 2'); + + buffer = arrayToBuffer(array); + transferred = buffer.transferToFixedLength(16.7); + assert.notSame(transferred, buffer, 'returns new buffer 3'); + assert.true(transferred instanceof ArrayBuffer, 'returns ArrayBuffer 3'); + assert.same(buffer.byteLength, 0, 'original array length 3'); + // works incorrectly in ancient WebKit + if (DETACHED) assert.skip.true(buffer.detached, 'original array detached 3'); + assert.same(transferred.byteLength, 16, 'proper transferred byteLength 3'); + assert.arrayEqual(bufferToArray(transferred), [...array, 0, 0, 0, 0, 0, 0, 0, 0], 'properly copied 3'); + + assert.throws(() => arrayToBuffer(array).transferToFixedLength(-1), RangeError, 'negative length'); + assert.throws(() => transferToFixedLength.call({}), TypeError, 'non-generic-1'); + if (typeof SharedArrayBuffer == 'function') { + assert.throws(() => transferToFixedLength.call(new SharedArrayBuffer(8)), TypeError, 'non-generic-2'); + } + + if ('resizable' in ArrayBuffer.prototype) { + assert.false(arrayToBuffer(array).transferToFixedLength().resizable, 'non-resizable-1'); + assert.false(arrayToBuffer(array).transferToFixedLength(5).resizable, 'non-resizable-2'); + + buffer = new ArrayBuffer(8, { maxByteLength: 16 }); + new Int8Array(buffer).set(array); + transferred = buffer.transferToFixedLength(); + assert.arrayEqual(bufferToArray(transferred), array, 'resizable-1'); + assert.false(transferred.resizable, 'resizable-2'); + + buffer = new ArrayBuffer(8, { maxByteLength: 16 }); + new Int8Array(buffer).set(array); + transferred = buffer.transferToFixedLength(5); + assert.arrayEqual(bufferToArray(transferred), array.slice(0, 5), 'resizable-3'); + assert.false(transferred.resizable, 'resizable-4'); + } +}); diff --git a/tests/unit-global/es.array-buffer.transfer.js b/tests/unit-global/es.array-buffer.transfer.js new file mode 100644 index 000000000000..a98b7c4c7526 --- /dev/null +++ b/tests/unit-global/es.array-buffer.transfer.js @@ -0,0 +1,70 @@ +/* eslint-disable es/no-shared-array-buffer -- testing */ +import { GLOBAL } from '../helpers/constants.js'; +import { arrayToBuffer, bufferToArray } from '../helpers/helpers.js'; + +const transfer = GLOBAL?.ArrayBuffer?.prototype?.transfer; + +if (transfer) QUnit.test('ArrayBuffer#transfer', assert => { + assert.isFunction(transfer); + assert.arity(transfer, 0); + assert.name(transfer, 'transfer'); + assert.looksNative(transfer); + assert.nonEnumerable(ArrayBuffer.prototype, 'transfer'); + + const DETACHED = 'detached' in ArrayBuffer.prototype; + + const array = [0, 1, 2, 3, 4, 5, 6, 7]; + + let buffer = arrayToBuffer(array); + let transferred = buffer.transfer(); + assert.notSame(transferred, buffer, 'returns new buffer 1'); + assert.true(transferred instanceof ArrayBuffer, 'returns ArrayBuffer 1'); + assert.same(buffer.byteLength, 0, 'original array length 1'); + // works incorrectly in ancient WebKit + if (DETACHED) assert.skip.true(buffer.detached, 'original array detached 1'); + assert.same(transferred.byteLength, 8, 'proper transferred byteLength 1'); + assert.arrayEqual(bufferToArray(transferred), array, 'properly copied 1'); + + buffer = arrayToBuffer(array); + transferred = buffer.transfer(5); + assert.notSame(transferred, buffer, 'returns new buffer 2'); + assert.true(transferred instanceof ArrayBuffer, 'returns ArrayBuffer 2'); + assert.same(buffer.byteLength, 0, 'original array length 2'); + // works incorrectly in ancient WebKit + if (DETACHED) assert.skip.true(buffer.detached, 'original array detached 2'); + assert.same(transferred.byteLength, 5, 'proper transferred byteLength 2'); + assert.arrayEqual(bufferToArray(transferred), array.slice(0, 5), 'properly copied 2'); + + buffer = arrayToBuffer(array); + transferred = buffer.transfer(16.7); + assert.notSame(transferred, buffer, 'returns new buffer 3'); + assert.true(transferred instanceof ArrayBuffer, 'returns ArrayBuffer 3'); + assert.same(buffer.byteLength, 0, 'original array length 3'); + // works incorrectly in ancient WebKit + if (DETACHED) assert.skip.true(buffer.detached, 'original array detached 3'); + assert.same(transferred.byteLength, 16, 'proper transferred byteLength 3'); + assert.arrayEqual(bufferToArray(transferred), [...array, 0, 0, 0, 0, 0, 0, 0, 0], 'properly copied 3'); + + assert.throws(() => arrayToBuffer(array).transfer(-1), RangeError, 'negative length'); + assert.throws(() => transfer.call({}), TypeError, 'non-generic-1'); + if (typeof SharedArrayBuffer == 'function') { + assert.throws(() => transfer.call(new SharedArrayBuffer(8)), TypeError, 'non-generic-2'); + } + + if ('resizable' in ArrayBuffer.prototype) { + assert.false(arrayToBuffer(array).transfer().resizable, 'non-resizable-1'); + assert.false(arrayToBuffer(array).transfer(5).resizable, 'non-resizable-2'); + + buffer = new ArrayBuffer(8, { maxByteLength: 16 }); + new Int8Array(buffer).set(array); + transferred = buffer.transfer(); + assert.arrayEqual(bufferToArray(transferred), array, 'resizable-1'); + assert.true(transferred.resizable, 'resizable-2'); + + buffer = new ArrayBuffer(8, { maxByteLength: 16 }); + new Int8Array(buffer).set(array); + transferred = buffer.transfer(5); + assert.arrayEqual(bufferToArray(transferred), array.slice(0, 5), 'resizable-3'); + assert.true(transferred.resizable, 'resizable-4'); + } +}); diff --git a/tests/unit-global/es.array.at.js b/tests/unit-global/es.array.at.js new file mode 100644 index 000000000000..ff2e963aef52 --- /dev/null +++ b/tests/unit-global/es.array.at.js @@ -0,0 +1,30 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#at', assert => { + const { at } = Array.prototype; + assert.isFunction(at); + assert.arity(at, 1); + assert.name(at, 'at'); + assert.looksNative(at); + assert.nonEnumerable(Array.prototype, 'at'); + assert.same(1, [1, 2, 3].at(0)); + assert.same(2, [1, 2, 3].at(1)); + assert.same(3, [1, 2, 3].at(2)); + assert.same(undefined, [1, 2, 3].at(3)); + assert.same(3, [1, 2, 3].at(-1)); + assert.same(2, [1, 2, 3].at(-2)); + assert.same(1, [1, 2, 3].at(-3)); + assert.same(undefined, [1, 2, 3].at(-4)); + assert.same(1, [1, 2, 3].at(0.4)); + assert.same(1, [1, 2, 3].at(0.5)); + assert.same(1, [1, 2, 3].at(0.6)); + assert.same(1, [1].at(NaN)); + assert.same(1, [1].at()); + assert.same(1, [1, 2, 3].at(-0)); + assert.same(undefined, Array(1).at(0)); + assert.same(1, at.call({ 0: 1, length: 1 }, 0)); + if (STRICT) { + assert.throws(() => at.call(null, 0), TypeError); + assert.throws(() => at.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.array.concat.js b/tests/unit-global/es.array.concat.js new file mode 100644 index 000000000000..eca9b7a1d911 --- /dev/null +++ b/tests/unit-global/es.array.concat.js @@ -0,0 +1,36 @@ +/* eslint-disable no-sparse-arrays, unicorn/prefer-array-flat -- required for testing */ +QUnit.test('Array#concat', assert => { + const { concat } = Array.prototype; + assert.isFunction(concat); + assert.arity(concat, 1); + assert.name(concat, 'concat'); + assert.looksNative(concat); + assert.nonEnumerable(Array.prototype, 'concat'); + let array = [1, 2]; + const sparseArray = [1, , 2]; + const nonSpreadableArray = [1, 2]; + nonSpreadableArray[Symbol.isConcatSpreadable] = false; + const arrayLike = { 0: 1, 1: 2, length: 2 }; + const spreadableArrayLike = { 0: 1, 1: 2, length: 2, [Symbol.isConcatSpreadable]: true }; + assert.deepEqual(array.concat(), [1, 2], '#1'); + assert.deepEqual(sparseArray.concat(), [1, , 2], '#2'); + assert.deepEqual(nonSpreadableArray.concat(), [[1, 2]], '#3'); + assert.deepEqual(concat.call(arrayLike), [{ 0: 1, 1: 2, length: 2 }], '#4'); + assert.deepEqual(concat.call(spreadableArrayLike), [1, 2], '#5'); + assert.deepEqual([].concat(array), [1, 2], '#6'); + assert.deepEqual([].concat(sparseArray), [1, , 2], '#7'); + assert.deepEqual([].concat(nonSpreadableArray), [[1, 2]], '#8'); + assert.deepEqual([].concat(arrayLike), [{ 0: 1, 1: 2, length: 2 }], '#9'); + assert.deepEqual([].concat(spreadableArrayLike), [1, 2], '#10'); + assert.deepEqual(array.concat(sparseArray, nonSpreadableArray, arrayLike, spreadableArrayLike), [ + 1, 2, 1, , 2, [1, 2], { 0: 1, 1: 2, length: 2 }, 1, 2, + ], '#11'); + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + // https://bugs.webkit.org/show_bug.cgi?id=281061 + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species + assert.same(array.concat().foo, 1, '@@species'); +}); diff --git a/tests/unit-global/es.array.copy-within.js b/tests/unit-global/es.array.copy-within.js new file mode 100644 index 000000000000..5ee106697349 --- /dev/null +++ b/tests/unit-global/es.array.copy-within.js @@ -0,0 +1,29 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#copyWithin', assert => { + const { copyWithin } = Array.prototype; + assert.isFunction(copyWithin); + assert.arity(copyWithin, 2); + assert.name(copyWithin, 'copyWithin'); + assert.looksNative(copyWithin); + const array = [1]; + assert.same(array.copyWithin(0), array); + assert.nonEnumerable(Array.prototype, 'copyWithin'); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(0, 3), [4, 5, 3, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(1, 3), [1, 4, 5, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(1, 2), [1, 3, 4, 5, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(2, 2), [1, 2, 3, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(0, 3, 4), [4, 2, 3, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(1, 3, 4), [1, 4, 3, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(1, 2, 4), [1, 3, 4, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(0, -2), [4, 5, 3, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(0, -2, -1), [4, 2, 3, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(-4, -3, -2), [1, 3, 3, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(-4, -3, -1), [1, 3, 4, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].copyWithin(-4, -3), [1, 3, 4, 5, 5]); + if (STRICT) { + assert.throws(() => copyWithin.call(null, 0), TypeError); + assert.throws(() => copyWithin.call(undefined, 0), TypeError); + } + assert.true('copyWithin' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.every.js b/tests/unit-global/es.array.every.js new file mode 100644 index 000000000000..6319246eec7a --- /dev/null +++ b/tests/unit-global/es.array.every.js @@ -0,0 +1,35 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#every', assert => { + const { every } = Array.prototype; + assert.isFunction(every); + assert.arity(every, 1); + assert.name(every, 'every'); + assert.looksNative(every); + assert.nonEnumerable(Array.prototype, 'every'); + let array = [1]; + const context = {}; + array.every(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true([1, 2, 3].every(it => typeof it == 'number')); + assert.true([1, 2, 3].every(it => it < 4)); + assert.false([1, 2, 3].every(it => it < 3)); + assert.false([1, 2, 3].every(it => typeof it == 'string')); + assert.true([1, 2, 3].every(function () { + return +this === 1; + }, 1)); + let result = ''; + [1, 2, 3].every((value, key) => result += key); + assert.same(result, '012'); + array = [1, 2, 3]; + assert.true(array.every((value, key, that) => that === array)); + if (STRICT) { + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + } +}); diff --git a/tests/unit-global/es.array.fill.js b/tests/unit-global/es.array.fill.js new file mode 100644 index 000000000000..22178cddb4d2 --- /dev/null +++ b/tests/unit-global/es.array.fill.js @@ -0,0 +1,32 @@ +import { DESCRIPTORS, NATIVE, STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#fill', assert => { + const { fill } = Array.prototype; + assert.isFunction(fill); + assert.arity(fill, 1); + assert.name(fill, 'fill'); + assert.looksNative(fill); + assert.nonEnumerable(Array.prototype, 'fill'); + const array = new Array(5); + assert.same(array.fill(5), array); + assert.deepEqual(Array(5).fill(5), [5, 5, 5, 5, 5]); + assert.deepEqual(Array(5).fill(5, 1), [undefined, 5, 5, 5, 5]); + assert.deepEqual(Array(5).fill(5, 1, 4), [undefined, 5, 5, 5, undefined]); + assert.deepEqual(Array(5).fill(5, 6, 1), [undefined, undefined, undefined, undefined, undefined]); + assert.deepEqual(Array(5).fill(5, -3, 4), [undefined, undefined, 5, 5, undefined]); + assert.arrayEqual(fill.call({ length: 5 }, 5), [5, 5, 5, 5, 5]); + if (STRICT) { + assert.throws(() => fill.call(null, 0), TypeError); + assert.throws(() => fill.call(undefined, 0), TypeError); + } + if (NATIVE && DESCRIPTORS) { + assert.notThrows(() => fill.call(Object.defineProperty({ + length: -1, + }, 0, { + set() { + throw new Error(); + }, + })), 'uses ToLength'); + } + assert.true('fill' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.filter.js b/tests/unit-global/es.array.filter.js new file mode 100644 index 000000000000..ac68c3ad008e --- /dev/null +++ b/tests/unit-global/es.array.filter.js @@ -0,0 +1,31 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#filter', assert => { + const { filter } = Array.prototype; + assert.isFunction(filter); + assert.arity(filter, 1); + assert.name(filter, 'filter'); + assert.looksNative(filter); + assert.nonEnumerable(Array.prototype, 'filter'); + let array = [1]; + const context = {}; + array.filter(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.deepEqual([1, 2, 3, 4, 5], [1, 2, 3, 'q', {}, 4, true, 5].filter(it => typeof it == 'number')); + if (STRICT) { + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species + assert.same(array.filter(Boolean).foo, 1, '@@species'); +}); diff --git a/tests/unit-global/es.array.find-index.js b/tests/unit-global/es.array.find-index.js new file mode 100644 index 000000000000..535f11a3a271 --- /dev/null +++ b/tests/unit-global/es.array.find-index.js @@ -0,0 +1,34 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#findIndex', assert => { + const { findIndex } = Array.prototype; + assert.isFunction(findIndex); + assert.arity(findIndex, 1); + assert.name(findIndex, 'findIndex'); + assert.looksNative(findIndex); + assert.nonEnumerable(Array.prototype, 'findIndex'); + const array = [1]; + const context = {}; + array.findIndex(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + // eslint-disable-next-line unicorn/prefer-array-index-of -- ignore + assert.same([1, 3, NaN, 42, {}].findIndex(it => it === 42), 3); + // eslint-disable-next-line unicorn/prefer-array-index-of -- ignore + assert.same([1, 3, NaN, 42, {}].findIndex(it => it === 43), -1); + if (STRICT) { + assert.throws(() => findIndex.call(null, 0), TypeError); + assert.throws(() => findIndex.call(undefined, 0), TypeError); + } + assert.notThrows(() => findIndex.call({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }) === -1, 'uses ToLength'); + assert.true('findIndex' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.find-last-index.js b/tests/unit-global/es.array.find-last-index.js new file mode 100644 index 000000000000..46a2a1d5d83d --- /dev/null +++ b/tests/unit-global/es.array.find-last-index.js @@ -0,0 +1,40 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#findLastIndex', assert => { + const { findLastIndex } = Array.prototype; + assert.isFunction(findLastIndex); + assert.arity(findLastIndex, 1); + assert.name(findLastIndex, 'findLastIndex'); + assert.looksNative(findLastIndex); + assert.nonEnumerable(Array.prototype, 'findLastIndex'); + const array = [1]; + const context = {}; + array.findLastIndex(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same([{}, 2, NaN, 42, 1].findLastIndex(it => !(it % 2)), 3); + assert.same([{}, 2, NaN, 42, 1].findLastIndex(it => it > 42), -1); + let values = ''; + let keys = ''; + [1, 2, 3].findLastIndex((value, key) => { + values += value; + keys += key; + }); + assert.same(values, '321'); + assert.same(keys, '210'); + if (STRICT) { + assert.throws(() => findLastIndex.call(null, 0), TypeError); + assert.throws(() => findLastIndex.call(undefined, 0), TypeError); + } + assert.notThrows(() => findLastIndex.call({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }) === -1, 'uses ToLength'); + assert.true('findLastIndex' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.find-last.js b/tests/unit-global/es.array.find-last.js new file mode 100644 index 000000000000..4a2ca2c611bc --- /dev/null +++ b/tests/unit-global/es.array.find-last.js @@ -0,0 +1,40 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#findLast', assert => { + const { findLast } = Array.prototype; + assert.isFunction(findLast); + assert.arity(findLast, 1); + assert.name(findLast, 'findLast'); + assert.looksNative(findLast); + assert.nonEnumerable(Array.prototype, 'findLast'); + const array = [1]; + const context = {}; + array.findLast(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same([{}, 2, NaN, 42, 1].findLast(it => !(it % 2)), 42); + assert.same([{}, 2, NaN, 42, 1].findLast(it => it === 43), undefined); + let values = ''; + let keys = ''; + [1, 2, 3].findLast((value, key) => { + values += value; + keys += key; + }); + assert.same(values, '321'); + assert.same(keys, '210'); + if (STRICT) { + assert.throws(() => findLast.call(null, 0), TypeError); + assert.throws(() => findLast.call(undefined, 0), TypeError); + } + assert.notThrows(() => findLast.call({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }) === undefined, 'uses ToLength'); + assert.true('find' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.find.js b/tests/unit-global/es.array.find.js new file mode 100644 index 000000000000..70b05f51d3f7 --- /dev/null +++ b/tests/unit-global/es.array.find.js @@ -0,0 +1,32 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#find', assert => { + const { find } = Array.prototype; + assert.isFunction(find); + assert.arity(find, 1); + assert.name(find, 'find'); + assert.looksNative(find); + assert.nonEnumerable(Array.prototype, 'find'); + const array = [1]; + const context = {}; + array.find(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same([1, 3, NaN, 42, {}].find(it => it === 42), 42); + assert.same([1, 3, NaN, 42, {}].find(it => it === 43), undefined); + if (STRICT) { + assert.throws(() => find.call(null, 0), TypeError); + assert.throws(() => find.call(undefined, 0), TypeError); + } + assert.notThrows(() => find.call({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }) === undefined, 'uses ToLength'); + assert.true('find' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.flat-map.js b/tests/unit-global/es.array.flat-map.js new file mode 100644 index 000000000000..680b2c324ef5 --- /dev/null +++ b/tests/unit-global/es.array.flat-map.js @@ -0,0 +1,33 @@ +/* eslint-disable unicorn/prefer-array-flat -- required for testing */ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#flatMap', assert => { + const { flatMap } = Array.prototype; + assert.isFunction(flatMap); + assert.name(flatMap, 'flatMap'); + assert.arity(flatMap, 1); + assert.looksNative(flatMap); + assert.nonEnumerable(Array.prototype, 'flatMap'); + assert.deepEqual([].flatMap(it => it), []); + assert.deepEqual([1, 2, 3].flatMap(it => it), [1, 2, 3]); + assert.deepEqual([1, 2, 3].flatMap(it => [it, it]), [1, 1, 2, 2, 3, 3]); + assert.deepEqual([1, 2, 3].flatMap(it => [[it], [it]]), [[1], [1], [2], [2], [3], [3]]); + assert.deepEqual([1, [2, 3]].flatMap(() => 1), [1, 1]); + const array = [1]; + const context = {}; + array.flatMap(function (value, key, that) { + assert.same(value, 1); + assert.same(key, 0); + assert.same(that, array); + assert.same(this, context); + return value; + }, context); + if (STRICT) { + assert.throws(() => flatMap.call(null, it => it), TypeError); + assert.throws(() => flatMap.call(undefined, it => it), TypeError); + } + assert.notThrows(() => flatMap.call({ length: -1 }, () => { + throw new Error(); + }).length === 0, 'uses ToLength'); + assert.true('flatMap' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.flat.js b/tests/unit-global/es.array.flat.js new file mode 100644 index 000000000000..a1c83a5b3328 --- /dev/null +++ b/tests/unit-global/es.array.flat.js @@ -0,0 +1,34 @@ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#flat', assert => { + const { flat } = Array.prototype; + const { defineProperty } = Object; + assert.isFunction(flat); + assert.name(flat, 'flat'); + assert.arity(flat, 0); + assert.looksNative(flat); + assert.nonEnumerable(Array.prototype, 'flat'); + assert.deepEqual([].flat(), []); + const array = [1, [2, 3], [4, [5, 6]]]; + assert.deepEqual(array.flat(0), array); + // eslint-disable-next-line unicorn/no-unnecessary-array-flat-depth -- testing + assert.deepEqual(array.flat(1), [1, 2, 3, 4, [5, 6]]); + assert.deepEqual(array.flat(), [1, 2, 3, 4, [5, 6]]); + assert.deepEqual(array.flat(2), [1, 2, 3, 4, 5, 6]); + assert.deepEqual(array.flat(3), [1, 2, 3, 4, 5, 6]); + assert.deepEqual(array.flat(-1), array); + assert.deepEqual(array.flat(Infinity), [1, 2, 3, 4, 5, 6]); + if (STRICT) { + assert.throws(() => flat.call(null), TypeError); + assert.throws(() => flat.call(undefined), TypeError); + } + if (DESCRIPTORS) { + assert.notThrows(() => flat.call(defineProperty({ length: -1 }, 0, { + enumerable: true, + get() { + throw new Error(); + }, + })).length === 0, 'uses ToLength'); + } + assert.true('flat' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.for-each.js b/tests/unit-global/es.array.for-each.js new file mode 100644 index 000000000000..a2f1f185a2a5 --- /dev/null +++ b/tests/unit-global/es.array.for-each.js @@ -0,0 +1,54 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#forEach', assert => { + const { forEach } = Array.prototype; + assert.isFunction(forEach); + assert.arity(forEach, 1); + assert.name(forEach, 'forEach'); + assert.looksNative(forEach); + assert.nonEnumerable(Array.prototype, 'forEach'); + let array = [1]; + const context = {}; + array.forEach(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + let result = ''; + [1, 2, 3].forEach(value => { + result += value; + }); + assert.same(result, '123'); + result = ''; + [1, 2, 3].forEach((value, key) => { + result += key; + }); + assert.same(result, '012'); + result = ''; + [1, 2, 3].forEach((value, key, that) => { + result += that; + }); + assert.same(result, '1,2,31,2,31,2,3'); + result = ''; + [1, 2, 3].forEach(function () { + result += this; + }, 1); + assert.same(result, '111'); + result = ''; + array = []; + array[5] = ''; + array.forEach((value, key) => { + result += key; + }); + assert.same(result, '5'); + if (STRICT) { + assert.throws(() => { + forEach.call(null, () => { /* empty */ }); + }, TypeError); + assert.throws(() => { + forEach.call(undefined, () => { /* empty */ }); + }, TypeError); + } +}); diff --git a/tests/unit-global/es.array.from-async.js b/tests/unit-global/es.array.from-async.js new file mode 100644 index 000000000000..8e0b4d2367ec --- /dev/null +++ b/tests/unit-global/es.array.from-async.js @@ -0,0 +1,103 @@ +import { createAsyncIterable, createIterable/* , createIterator */ } from '../helpers/helpers.js'; +import { STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Array.fromAsync', assert => { + const { fromAsync } = Array; + + assert.isFunction(fromAsync); + assert.arity(fromAsync, 1); + assert.name(fromAsync, 'fromAsync'); + assert.looksNative(fromAsync); + assert.nonEnumerable(Array, 'fromAsync'); + + let counter = 0; + // eslint-disable-next-line prefer-arrow-callback -- constructor + fromAsync.call(function () { + counter++; + return []; + }, { length: 0 }); + + assert.same(counter, 1, 'proper number of constructor calling'); + + function C() { /* empty */ } + + // const closableIterator = createIterator([1], { + // return() { this.closed = true; return { value: undefined, done: true }; }, + // }); + + return fromAsync(createAsyncIterable([1, 2, 3]), it => it ** 2).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'async iterable and mapfn'); + return fromAsync(createAsyncIterable([1]), function (arg, index) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(index, 0, 'index'); + }); + }).then(() => { + return fromAsync(createAsyncIterable([1, 2, 3])); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'async iterable without mapfn'); + return fromAsync(createIterable([1, 2, 3]), arg => arg ** 2); + }).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'iterable and mapfn'); + return fromAsync(createIterable([1, 2, 3]), arg => Promise.resolve(arg ** 2)); + }).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'iterable and async mapfn'); + return fromAsync(createIterable([1]), function (arg, index) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(index, 0, 'index'); + }); + }).then(() => { + return fromAsync(createIterable([1, 2, 3])); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'iterable and without mapfn'); + return fromAsync([1, Promise.resolve(2), 3]); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'array'); + return fromAsync('123'); + }).then(it => { + assert.arrayEqual(it, ['1', '2', '3'], 'string'); + return fromAsync.call(C, [1]); + }).then(it => { + assert.true(it instanceof C, 'subclassable'); + return fromAsync({ length: 1, 0: 1 }); + }).then(it => { + assert.arrayEqual(it, [1], 'non-iterable'); + return fromAsync(createIterable([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + return fromAsync(undefined, () => { /* empty */ }); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return fromAsync(null, () => { /* empty */ }); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return fromAsync([1], null); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return fromAsync([1], {}); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + }); + /* Tests are temporarily disabled due to the lack of proper async feature detection in native implementations. + .then(() => { + return fromAsync(Iterator.from(closableIterator), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + assert.true(closableIterator.closed, 'doesn\'t close sync iterator on promise rejection'); + }); */ +}); diff --git a/tests/unit-global/es.array.from.js b/tests/unit-global/es.array.from.js new file mode 100644 index 000000000000..4c958c0d4720 --- /dev/null +++ b/tests/unit-global/es.array.from.js @@ -0,0 +1,127 @@ +/* eslint-disable prefer-rest-params -- required for testing */ +import { DESCRIPTORS, GLOBAL } from '../helpers/constants.js'; +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Array.from', assert => { + const Symbol = GLOBAL.Symbol || {}; + const { from } = Array; + const { defineProperty } = Object; + assert.isFunction(from); + assert.arity(from, 1); + assert.name(from, 'from'); + assert.looksNative(from); + assert.nonEnumerable(Array, 'from'); + let types = { + 'array-like': { + length: '3', + 0: '1', + 1: '2', + 2: '3', + }, + arguments: function () { + return arguments; + }('1', '2', '3'), + array: ['1', '2', '3'], + iterable: createIterable(['1', '2', '3']), + string: '123', + }; + for (const type in types) { + const data = types[type]; + assert.arrayEqual(from(data), ['1', '2', '3'], `Works with ${ type }`); + assert.arrayEqual(from(data, it => it ** 2), [1, 4, 9], `Works with ${ type } + mapFn`); + } + types = { + 'array-like': { + length: 1, + 0: 1, + }, + arguments: function () { + return arguments; + }(1), + array: [1], + iterable: createIterable([1]), + string: '1', + }; + for (const type in types) { + const data = types[type]; + const context = {}; + assert.arrayEqual(from(data, function (value, key) { + assert.same(this, context, `Works with ${ type }, correct callback context`); + assert.same(value, type === 'string' ? '1' : 1, `Works with ${ type }, correct callback key`); + assert.same(key, 0, `Works with ${ type }, correct callback value`); + assert.same(arguments.length, 2, `Works with ${ type }, correct callback arguments number`); + return 42; + }, context), [42], `Works with ${ type }, correct result`); + } + const primitives = [false, true, 0]; + for (const primitive of primitives) { + assert.arrayEqual(from(primitive), [], `Works with ${ primitive }`); + } + assert.throws(() => from(null), TypeError, 'Throws on null'); + assert.throws(() => from(undefined), TypeError, 'Throws on undefined'); + assert.arrayEqual(from('𠮷𠮷𠮷'), ['𠮷', '𠮷', '𠮷'], 'Uses correct string iterator'); + let done = true; + from(createIterable([1, 2, 3], { + return() { + return done = false; + }, + }), () => false); + assert.true(done, '.return #default'); + done = false; + try { + from(createIterable([1, 2, 3], { + return() { + return done = true; + }, + }), () => { + throw new Error(); + }); + } catch { /* empty */ } + assert.true(done, '.return #throw'); + class C { /* empty */ } + let instance = from.call(C, createIterable([1, 2])); + assert.true(instance instanceof C, 'generic, iterable case, instanceof'); + assert.arrayEqual(instance, [1, 2], 'generic, iterable case, elements'); + instance = from.call(C, { + 0: 1, + 1: 2, + length: 2, + }); + assert.true(instance instanceof C, 'generic, array-like case, instanceof'); + assert.arrayEqual(instance, [1, 2], 'generic, array-like case, elements'); + let array = [1, 2, 3]; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + assert.arrayEqual(from(array), [1, 2, 3], 'Array with custom iterator, elements'); + assert.true(done, 'call @@iterator in Array with custom iterator'); + array = [1, 2, 3]; + delete array[1]; + assert.arrayEqual(from(array, String), ['1', 'undefined', '3'], 'Ignores holes'); + assert.notThrows(() => from({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }).length === 0, 'Uses ToLength'); + assert.arrayEqual(from([], undefined), [], 'Works with undefined as second argument'); + assert.throws(() => from([], null), TypeError, 'Throws with null as second argument'); + assert.throws(() => from([], 0), TypeError, 'Throws with 0 as second argument'); + assert.throws(() => from([], ''), TypeError, 'Throws with "" as second argument'); + assert.throws(() => from([], false), TypeError, 'Throws with false as second argument'); + assert.throws(() => from([], {}), TypeError, 'Throws with {} as second argument'); + if (DESCRIPTORS) { + let called = false; + defineProperty(C.prototype, 0, { + set() { + called = true; + }, + }); + from.call(C, [1, 2, 3]); + assert.false(called, 'Should not call prototype accessors'); + } +}); diff --git a/tests/unit-global/es.array.includes.js b/tests/unit-global/es.array.includes.js new file mode 100644 index 000000000000..7889fefdd151 --- /dev/null +++ b/tests/unit-global/es.array.includes.js @@ -0,0 +1,26 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#includes', assert => { + const { includes } = Array.prototype; + assert.isFunction(includes); + assert.name(includes, 'includes'); + assert.arity(includes, 1); + assert.looksNative(includes); + assert.nonEnumerable(Array.prototype, 'includes'); + const object = {}; + const array = [1, 2, 3, -0, object]; + assert.true(array.includes(1)); + assert.true(array.includes(-0)); + assert.true(array.includes(0)); + assert.true(array.includes(object)); + assert.false(array.includes(4)); + assert.false(array.includes(-0.5)); + assert.false(array.includes({})); + assert.true(Array(1).includes(undefined)); + assert.true([NaN].includes(NaN)); + if (STRICT) { + assert.throws(() => includes.call(null, 0), TypeError); + assert.throws(() => includes.call(undefined, 0), TypeError); + } + assert.true('includes' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.index-of.js b/tests/unit-global/es.array.index-of.js new file mode 100644 index 000000000000..2111ff5bfc0b --- /dev/null +++ b/tests/unit-global/es.array.index-of.js @@ -0,0 +1,23 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#indexOf', assert => { + const { indexOf } = Array.prototype; + assert.isFunction(indexOf); + assert.arity(indexOf, 1); + assert.name(indexOf, 'indexOf'); + assert.looksNative(indexOf); + assert.nonEnumerable(Array.prototype, 'indexOf'); + assert.same(0, [1, 1, 1].indexOf(1)); + assert.same(-1, [1, 2, 3].indexOf(1, 1)); + assert.same(1, [1, 2, 3].indexOf(2, 1)); + assert.same(-1, [1, 2, 3].indexOf(2, -1)); + assert.same(1, [1, 2, 3].indexOf(2, -2)); + assert.same(-1, [NaN].indexOf(NaN)); + assert.same(3, Array(2).concat([1, 2, 3]).indexOf(2)); + assert.same(-1, Array(1).indexOf(undefined)); + assert.same(0, [1].indexOf(1, -0), "shouldn't return negative zero"); + if (STRICT) { + assert.throws(() => indexOf.call(null, 0), TypeError); + assert.throws(() => indexOf.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.array.is-array.js b/tests/unit-global/es.array.is-array.js new file mode 100644 index 000000000000..16bb98774ac6 --- /dev/null +++ b/tests/unit-global/es.array.is-array.js @@ -0,0 +1,14 @@ +QUnit.test('Array.isArray', assert => { + const { isArray } = Array; + assert.isFunction(isArray); + assert.arity(isArray, 1); + assert.name(isArray, 'isArray'); + assert.looksNative(isArray); + assert.nonEnumerable(Array, 'isArray'); + assert.false(isArray({})); + assert.false(isArray(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }())); + assert.true(isArray([])); +}); diff --git a/tests/unit-global/es.array.iterator.js b/tests/unit-global/es.array.iterator.js new file mode 100644 index 000000000000..c0e2707f3bea --- /dev/null +++ b/tests/unit-global/es.array.iterator.js @@ -0,0 +1,155 @@ +import { GLOBAL } from '../helpers/constants.js'; + +const Symbol = GLOBAL.Symbol || {}; + +QUnit.test('Array#keys', assert => { + const { keys } = Array.prototype; + assert.isFunction(keys); + assert.arity(keys, 0); + assert.name(keys, 'keys'); + assert.looksNative(keys); + assert.nonEnumerable(Array.prototype, 'keys'); + const iterator = ['q', 'w', 'e'].keys(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.same(String(iterator), '[object Array Iterator]'); + assert.deepEqual(iterator.next(), { + value: 0, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 1, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 2, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + /* still not fixed even in modern WebKit + assert.deepEqual(keys.call({ + length: -1, + }).next(), { + value: undefined, + done: true, + }, 'uses ToLength'); + */ + assert.true('keys' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); + +QUnit.test('Array#values', assert => { + const { values } = Array.prototype; + assert.isFunction(values); + assert.arity(values, 0); + assert.name(values, 'values'); + assert.looksNative(values); + assert.nonEnumerable(Array.prototype, 'values'); + const iterator = ['q', 'w', 'e'].values(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + /* still not fixed even in modern WebKit + assert.deepEqual(values.call({ + length: -1, + }).next(), { + value: undefined, + done: true, + }, 'uses ToLength'); + */ + assert.true('values' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); + +QUnit.test('Array#entries', assert => { + const { entries } = Array.prototype; + assert.isFunction(entries); + assert.arity(entries, 0); + assert.name(entries, 'entries'); + assert.looksNative(entries); + assert.nonEnumerable(Array.prototype, 'entries'); + const iterator = ['q', 'w', 'e'].entries(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.deepEqual(iterator.next(), { + value: [0, 'q'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: [1, 'w'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: [2, 'e'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + /* still not fixed even in modern WebKit + assert.deepEqual(entries.call({ + length: -1, + }).next(), { + value: undefined, + done: true, + }, 'uses ToLength'); + */ + assert.true('entries' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); + +QUnit.test('Array#@@iterator', assert => { + assert.isIterable(Array.prototype); + assert.arity(Array.prototype[Symbol.iterator], 0); + assert.name(Array.prototype[Symbol.iterator], 'values'); + assert.looksNative(Array.prototype[Symbol.iterator]); + assert.nonEnumerable(Array.prototype, Symbol.iterator); + assert.same(Array.prototype[Symbol.iterator], Array.prototype.values); + const iterator = ['q', 'w', 'e'][Symbol.iterator](); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + /* still not fixed even in modern WebKit + assert.deepEqual(Array.prototype[Symbol.iterator].call({ + length: -1, + }).next(), { + value: undefined, + done: true, + }, 'uses ToLength'); + */ +}); diff --git a/tests/unit-global/es.array.join.js b/tests/unit-global/es.array.join.js new file mode 100644 index 000000000000..735a2ab99777 --- /dev/null +++ b/tests/unit-global/es.array.join.js @@ -0,0 +1,17 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#join', assert => { + const { join } = Array.prototype; + assert.isFunction(join); + assert.arity(join, 1); + assert.name(join, 'join'); + assert.looksNative(join); + assert.nonEnumerable(Array.prototype, 'join'); + assert.same(join.call([1, 2, 3], undefined), '1,2,3'); + assert.same(join.call('123'), '1,2,3'); + assert.same(join.call('123', '|'), '1|2|3'); + if (STRICT) { + assert.throws(() => join.call(null, 0), TypeError); + assert.throws(() => join.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.array.last-index-of.js b/tests/unit-global/es.array.last-index-of.js new file mode 100644 index 000000000000..93f5ad5acce3 --- /dev/null +++ b/tests/unit-global/es.array.last-index-of.js @@ -0,0 +1,23 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#lastIndexOf', assert => { + const { lastIndexOf } = Array.prototype; + assert.isFunction(lastIndexOf); + assert.arity(lastIndexOf, 1); + assert.name(lastIndexOf, 'lastIndexOf'); + assert.looksNative(lastIndexOf); + assert.nonEnumerable(Array.prototype, 'lastIndexOf'); + assert.same(2, [1, 1, 1].lastIndexOf(1)); + assert.same(-1, [1, 2, 3].lastIndexOf(3, 1)); + assert.same(1, [1, 2, 3].lastIndexOf(2, 1)); + assert.same(-1, [1, 2, 3].lastIndexOf(2, -3)); + assert.same(-1, [1, 2, 3].lastIndexOf(1, -4)); + assert.same(1, [1, 2, 3].lastIndexOf(2, -2)); + assert.same(-1, [NaN].lastIndexOf(NaN)); + assert.same(1, [1, 2, 3].concat(Array(2)).lastIndexOf(2)); + assert.same(0, [1].lastIndexOf(1, -0), "shouldn't return negative zero"); + if (STRICT) { + assert.throws(() => lastIndexOf.call(null, 0), TypeError); + assert.throws(() => lastIndexOf.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.array.map.js b/tests/unit-global/es.array.map.js new file mode 100644 index 000000000000..2e2d049c71a7 --- /dev/null +++ b/tests/unit-global/es.array.map.js @@ -0,0 +1,35 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#map', assert => { + const { map } = Array.prototype; + assert.isFunction(map); + assert.arity(map, 1); + assert.name(map, 'map'); + assert.looksNative(map); + assert.nonEnumerable(Array.prototype, 'map'); + let array = [1]; + const context = {}; + array.map(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.deepEqual([2, 3, 4], [1, 2, 3].map(value => value + 1)); + assert.deepEqual([1, 3, 5], [1, 2, 3].map((value, key) => value + key)); + assert.deepEqual([2, 2, 2], [1, 2, 3].map(function () { + return +this; + }, 2)); + if (STRICT) { + assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species + assert.same(array.map(Boolean).foo, 1, '@@species'); +}); diff --git a/tests/unit-global/es.array.of.js b/tests/unit-global/es.array.of.js new file mode 100644 index 000000000000..1018e2f8a283 --- /dev/null +++ b/tests/unit-global/es.array.of.js @@ -0,0 +1,28 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Array.of', assert => { + const { defineProperty } = Object; + assert.isFunction(Array.of); + assert.arity(Array.of, 0); + assert.name(Array.of, 'of'); + assert.looksNative(Array.of); + assert.nonEnumerable(Array, 'of'); + assert.deepEqual(Array.of(1), [1]); + assert.deepEqual(Array.of(1, 2, 3), [1, 2, 3]); + class C { /* empty */ } + const instance = Array.of.call(C, 1, 2); + assert.true(instance instanceof C); + assert.same(instance[0], 1); + assert.same(instance[1], 2); + assert.same(instance.length, 2); + if (DESCRIPTORS) { + let called = false; + defineProperty(C.prototype, 0, { + set() { + called = true; + }, + }); + Array.of.call(C, 1, 2, 3); + assert.false(called, 'Should not call prototype accessors'); + } +}); diff --git a/tests/unit-global/es.array.push.js b/tests/unit-global/es.array.push.js new file mode 100644 index 000000000000..3e51ed6537ff --- /dev/null +++ b/tests/unit-global/es.array.push.js @@ -0,0 +1,26 @@ +import { REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR, STRICT } from '../helpers/constants.js'; + +const { defineProperty } = Object; + +QUnit.test('Array#push', assert => { + const { push } = Array.prototype; + assert.isFunction(push); + assert.arity(push, 1); + assert.name(push, 'push'); + assert.looksNative(push); + assert.nonEnumerable(Array.prototype, 'push'); + + const object = { length: 0x100000000 }; + assert.same(push.call(object, 1), 0x100000001, 'proper ToLength #1'); + assert.same(object[0x100000000], 1, 'proper ToLength #2'); + + if (STRICT) { + if (REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR) { + assert.throws(() => push.call(defineProperty([], 'length', { writable: false }), 1), TypeError, 'non-writable length, with arg'); + assert.throws(() => push.call(defineProperty([], 'length', { writable: false })), TypeError, 'non-writable length, without arg'); + } + + assert.throws(() => push.call(null), TypeError); + assert.throws(() => push.call(undefined), TypeError); + } +}); diff --git a/tests/unit-global/es.array.reduce-right.js b/tests/unit-global/es.array.reduce-right.js new file mode 100644 index 000000000000..ab69fc6925b0 --- /dev/null +++ b/tests/unit-global/es.array.reduce-right.js @@ -0,0 +1,45 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#reduceRight', assert => { + const { reduceRight } = Array.prototype; + assert.isFunction(reduceRight); + assert.arity(reduceRight, 1); + assert.name(reduceRight, 'reduceRight'); + assert.looksNative(reduceRight); + assert.nonEnumerable(Array.prototype, 'reduceRight'); + const array = [1]; + const accumulator = {}; + array.reduceRight(function (memo, value, key, that) { + assert.same(arguments.length, 4, 'correct number of callback arguments'); + assert.same(memo, accumulator, 'correct callback accumulator'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + }, accumulator); + assert.same([1, 2, 3].reduceRight(((a, b) => a + b), 1), 7, 'works with initial accumulator'); + [1, 2].reduceRight((memo, value, key) => { + assert.same(memo, 2, 'correct default accumulator'); + assert.same(value, 1, 'correct start value without initial accumulator'); + assert.same(key, 0, 'correct start index without initial accumulator'); + }); + assert.same([1, 2, 3].reduceRight((a, b) => a + b), 6, 'works without initial accumulator'); + let values = ''; + let keys = ''; + [1, 2, 3].reduceRight((memo, value, key) => { + values += value; + keys += key; + }, 0); + assert.same(values, '321', 'correct order #1'); + assert.same(keys, '210', 'correct order #2'); + assert.same(reduceRight.call({ + 0: 1, + 1: 2, + length: 2, + }, (a, b) => a + b), 3, 'generic'); + assert.throws(() => reduceRight.call([], () => { /* empty */ }), TypeError); + assert.throws(() => reduceRight.call(Array(5), () => { /* empty */ }), TypeError); + if (STRICT) { + assert.throws(() => reduceRight.call(null, () => { /* empty */ }, 1), TypeError); + assert.throws(() => reduceRight.call(undefined, () => { /* empty */ }, 1), TypeError); + } +}); diff --git a/tests/unit-global/es.array.reduce.js b/tests/unit-global/es.array.reduce.js new file mode 100644 index 000000000000..bde1e27830f6 --- /dev/null +++ b/tests/unit-global/es.array.reduce.js @@ -0,0 +1,45 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#reduce', assert => { + const { reduce } = Array.prototype; + assert.isFunction(reduce); + assert.arity(reduce, 1); + assert.name(reduce, 'reduce'); + assert.looksNative(reduce); + assert.nonEnumerable(Array.prototype, 'reduce'); + const array = [1]; + const accumulator = {}; + array.reduce(function (memo, value, key, that) { + assert.same(arguments.length, 4, 'correct number of callback arguments'); + assert.same(memo, accumulator, 'correct callback accumulator'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + }, accumulator); + assert.same([1, 2, 3].reduce(((a, b) => a + b), 1), 7, 'works with initial accumulator'); + [1, 2].reduce((memo, value, key) => { + assert.same(memo, 1, 'correct default accumulator'); + assert.same(value, 2, 'correct start value without initial accumulator'); + assert.same(key, 1, 'correct start index without initial accumulator'); + }); + assert.same([1, 2, 3].reduce((a, b) => a + b), 6, 'works without initial accumulator'); + let values = ''; + let keys = ''; + [1, 2, 3].reduce((memo, value, key) => { + values += value; + keys += key; + }, 0); + assert.same(values, '123', 'correct order #1'); + assert.same(keys, '012', 'correct order #2'); + assert.same(reduce.call({ + 0: 1, + 1: 2, + length: 2, + }, (a, b) => a + b), 3, 'generic'); + assert.throws(() => reduce.call([], () => { /* empty */ }), TypeError); + assert.throws(() => reduce.call(Array(5), () => { /* empty */ }), TypeError); + if (STRICT) { + assert.throws(() => reduce.call(null, () => { /* empty */ }, 1), TypeError); + assert.throws(() => reduce.call(undefined, () => { /* empty */ }, 1), TypeError); + } +}); diff --git a/tests/unit-global/es.array.reverse.js b/tests/unit-global/es.array.reverse.js new file mode 100644 index 000000000000..3ef53c58e9ff --- /dev/null +++ b/tests/unit-global/es.array.reverse.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#reverse', assert => { + const { reverse } = Array.prototype; + assert.isFunction(reverse); + assert.arity(reverse, 0); + assert.name(reverse, 'reverse'); + assert.looksNative(reverse); + assert.nonEnumerable(Array.prototype, 'reverse'); + const a = [1, 2.2, 3.3]; + function fn() { + +a; + a.reverse(); + } + fn(); + assert.arrayEqual(a, [3.3, 2.2, 1]); + if (STRICT) { + assert.throws(() => reverse.call(null, () => { /* empty */ }, 1), TypeError); + assert.throws(() => reverse.call(undefined, () => { /* empty */ }, 1), TypeError); + } +}); diff --git a/tests/unit-global/es.array.slice.js b/tests/unit-global/es.array.slice.js new file mode 100644 index 000000000000..66de6ab2e880 --- /dev/null +++ b/tests/unit-global/es.array.slice.js @@ -0,0 +1,40 @@ +import { GLOBAL, STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#slice', assert => { + const { slice } = Array.prototype; + const { isArray } = Array; + assert.isFunction(slice); + assert.arity(slice, 2); + assert.name(slice, 'slice'); + assert.looksNative(slice); + assert.nonEnumerable(Array.prototype, 'slice'); + let array = ['1', '2', '3', '4', '5']; + assert.deepEqual(array.slice(), array); + assert.deepEqual(array.slice(1, 3), ['2', '3']); + assert.deepEqual(array.slice(1, undefined), ['2', '3', '4', '5']); + assert.deepEqual(array.slice(1, -1), ['2', '3', '4']); + assert.deepEqual(array.slice(-2, -1), ['4']); + assert.deepEqual(array.slice(-2, -3), []); + const string = '12345'; + assert.deepEqual(slice.call(string), array); + assert.deepEqual(slice.call(string, 1, 3), ['2', '3']); + assert.deepEqual(slice.call(string, 1, undefined), ['2', '3', '4', '5']); + assert.deepEqual(slice.call(string, 1, -1), ['2', '3', '4']); + assert.deepEqual(slice.call(string, -2, -1), ['4']); + assert.deepEqual(slice.call(string, -2, -3), []); + const list = GLOBAL.document && document.body && document.body.childNodes; + if (list) { + assert.notThrows(() => isArray(slice.call(list)), 'works on NodeList'); + } + if (STRICT) { + assert.throws(() => slice.call(null), TypeError); + assert.throws(() => slice.call(undefined), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species + assert.same(array.slice().foo, 1, '@@species'); +}); diff --git a/tests/unit-global/es.array.some.js b/tests/unit-global/es.array.some.js new file mode 100644 index 000000000000..e845f14d6544 --- /dev/null +++ b/tests/unit-global/es.array.some.js @@ -0,0 +1,38 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#some', assert => { + const { some } = Array.prototype; + assert.isFunction(some); + assert.arity(some, 1); + assert.name(some, 'some'); + assert.looksNative(some); + assert.nonEnumerable(Array.prototype, 'some'); + let array = [1]; + const context = {}; + array.some(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true([1, '2', 3].some(value => typeof value == 'number')); + assert.true([1, 2, 3].some(value => value < 3)); + assert.false([1, 2, 3].some(value => value < 0)); + assert.false([1, 2, 3].some(value => typeof value == 'string')); + assert.false([1, 2, 3].some(function () { + return +this !== 1; + }, 1)); + let result = ''; + [1, 2, 3].some((value, key) => { + result += key; + return false; + }); + assert.same(result, '012'); + array = [1, 2, 3]; + assert.false(array.some((value, key, that) => that !== array)); + if (STRICT) { + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + } +}); diff --git a/tests/unit-global/es.array.sort.js b/tests/unit-global/es.array.sort.js new file mode 100644 index 000000000000..1c67061c93c7 --- /dev/null +++ b/tests/unit-global/es.array.sort.js @@ -0,0 +1,129 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#sort', assert => { + const { sort } = Array.prototype; + assert.isFunction(sort); + assert.arity(sort, 1); + assert.name(sort, 'sort'); + assert.looksNative(sort); + assert.nonEnumerable(Array.prototype, 'sort'); + + assert.deepEqual([1, 3, 2].sort(), [1, 2, 3], '#1'); + assert.deepEqual([1, 3, 2, 11].sort(), [1, 11, 2, 3], '#2'); + assert.deepEqual([1, -1, 3, NaN, 2, 0, 11, -0].sort(), [-1, 0, -0, 1, 11, 2, 3, NaN], '#1'); + + let array = Array(5); + array[0] = 1; + array[2] = 3; + array[4] = 2; + let expected = Array(5); + expected[0] = 1; + expected[1] = 2; + expected[2] = 3; + assert.deepEqual(array.sort(), expected, 'holes'); + + array = 'zyxwvutsrqponMLKJIHGFEDCBA'.split(''); + expected = 'ABCDEFGHIJKLMnopqrstuvwxyz'.split(''); + assert.deepEqual(array.sort(), expected, 'alpha #1'); + + array = 'ёяюэьыъщшчцхфутсрПОНМЛКЙИЗЖЕДГВБА'.split(''); + expected = 'АБВГДЕЖЗИЙКЛМНОПрстуфхцчшщъыьэюяё'.split(''); + assert.deepEqual(array.sort(), expected, 'alpha #2'); + + array = [undefined, 1]; + assert.notThrows(() => array.sort(() => { throw 1; }), 'undefined #1'); + assert.deepEqual(array, [1, undefined], 'undefined #2'); + + /* Safari TP ~ 17.6 issue + const object = { + valueOf: () => 1, + toString: () => -1, + }; + + array = { + 0: undefined, + 1: 2, + 2: 1, + 3: 'X', + 4: -1, + 5: 'a', + 6: true, + 7: object, + 8: NaN, + 10: Infinity, + length: 11, + }; + + expected = { + 0: -1, + 1: object, + 2: 1, + 3: 2, + 4: Infinity, + 5: NaN, + 6: 'X', + 7: 'a', + 8: true, + 9: undefined, + length: 11, + }; + + assert.deepEqual(sort.call(array), expected, 'custom generic'); + */ + + let index, mod, code, chr, value; + expected = Array(516); + array = Array(516); + + for (index = 0; index < 516; index++) { + mod = index % 4; + array[index] = 515 - index; + expected[index] = index - 2 * mod + 3; + } + + array.sort((a, b) => (a / 4 | 0) - (b / 4 | 0)); + + assert.true(1 / [0, -0].sort()[0] > 0, '-0'); + + assert.arrayEqual(array, expected, 'stable #1'); + + let result = ''; + array = []; + + // generate an array with more 512 elements (Chakra and old V8 fails only in this case) + for (code = 65; code < 76; code++) { + chr = String.fromCharCode(code); + + switch (code) { + case 66: case 69: case 70: case 72: value = 3; break; + case 68: case 71: value = 4; break; + default: value = 2; + } + + for (index = 0; index < 47; index++) { + array.push({ k: chr + index, v: value }); + } + } + + array.sort((a, b) => b.v - a.v); + + for (index = 0; index < array.length; index++) { + chr = array[index].k.charAt(0); + if (result.charAt(result.length - 1) !== chr) result += chr; + } + + assert.same(result, 'DGBEFHACIJK', 'stable #2'); + + assert.notThrows(() => [1, 2, 3].sort(undefined).length === 3, 'works with undefined'); + assert.throws(() => [1, 2, 3].sort(null), 'throws on null'); + assert.throws(() => [1, 2, 3].sort({}), 'throws on {}'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => [Symbol(1), Symbol(2)].sort(), 'w/o cmp throws on symbols'); + } + + if (STRICT) { + assert.throws(() => sort.call(null), TypeError, 'ToObject(this)'); + assert.throws(() => sort.call(undefined), TypeError, 'ToObject(this)'); + } +}); diff --git a/tests/unit-global/es.array.splice.js b/tests/unit-global/es.array.splice.js new file mode 100644 index 000000000000..16a39a72373a --- /dev/null +++ b/tests/unit-global/es.array.splice.js @@ -0,0 +1,48 @@ +import { REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR, STRICT } from '../helpers/constants.js'; + +const { defineProperty } = Object; + +QUnit.test('Array#splice', assert => { + const { splice } = Array.prototype; + assert.isFunction(splice); + assert.arity(splice, 2); + assert.name(splice, 'splice'); + assert.looksNative(splice); + assert.nonEnumerable(Array.prototype, 'splice'); + let array = [1, 2, 3, 4, 5]; + assert.deepEqual(array.splice(2), [3, 4, 5]); + assert.deepEqual(array, [1, 2]); + array = [1, 2, 3, 4, 5]; + assert.deepEqual(array.splice(-2), [4, 5]); + assert.deepEqual(array, [1, 2, 3]); + array = [1, 2, 3, 4, 5]; + assert.deepEqual(array.splice(2, 2), [3, 4]); + assert.deepEqual(array, [1, 2, 5]); + array = [1, 2, 3, 4, 5]; + assert.deepEqual(array.splice(2, -2), []); + assert.deepEqual(array, [1, 2, 3, 4, 5]); + array = [1, 2, 3, 4, 5]; + assert.deepEqual(array.splice(2, 2, 6, 7), [3, 4]); + assert.deepEqual(array, [1, 2, 6, 7, 5]); + // ES6 semantics + array = [0, 1, 2]; + assert.deepEqual(array.splice(0), [0, 1, 2]); + array = [0, 1, 2]; + assert.deepEqual(array.splice(1), [1, 2]); + array = [0, 1, 2]; + assert.deepEqual(array.splice(2), [2]); + if (STRICT) { + if (REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR) { + assert.throws(() => splice.call(defineProperty([1, 2, 3], 'length', { writable: false }), 1, 1), TypeError, 'non-writable length'); + } + assert.throws(() => splice.call(null), TypeError); + assert.throws(() => splice.call(undefined), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- @@species + assert.same(array.splice().foo, 1, '@@species'); +}); diff --git a/tests/unit-global/es.array.to-reversed.js b/tests/unit-global/es.array.to-reversed.js new file mode 100644 index 000000000000..4235426c3d96 --- /dev/null +++ b/tests/unit-global/es.array.to-reversed.js @@ -0,0 +1,62 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#toReversed', assert => { + const { toReversed } = Array.prototype; + + assert.isFunction(toReversed); + assert.arity(toReversed, 0); + assert.name(toReversed, 'toReversed'); + assert.looksNative(toReversed); + assert.nonEnumerable(Array.prototype, 'toReversed'); + + let array = [1, 2]; + assert.notSame(array.toReversed(), array, 'immutable'); + + assert.deepEqual([1, 2.2, 3.3].toReversed(), [3.3, 2.2, 1], 'basic'); + + const object = {}; + + array = { + 0: undefined, + 1: 2, + 2: 1, + 3: 'X', + 4: -1, + 5: 'a', + 6: true, + 7: object, + 8: NaN, + 10: Infinity, + length: 11, + }; + + const expected = [ + Infinity, + undefined, + NaN, + object, + true, + 'a', + -1, + 'X', + 1, + 2, + undefined, + ]; + + assert.deepEqual(toReversed.call(array), expected, 'non-array target'); + + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.true(array.toReversed() instanceof Array, 'non-generic'); + + if (STRICT) { + assert.throws(() => toReversed.call(null, () => { /* empty */ }, 1), TypeError); + assert.throws(() => toReversed.call(undefined, () => { /* empty */ }, 1), TypeError); + } + + assert.true('toReversed' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.to-sorted.js b/tests/unit-global/es.array.to-sorted.js new file mode 100644 index 000000000000..21cc5a4e7415 --- /dev/null +++ b/tests/unit-global/es.array.to-sorted.js @@ -0,0 +1,140 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#toSorted', assert => { + const { toSorted } = Array.prototype; + + assert.isFunction(toSorted); + assert.arity(toSorted, 1); + assert.name(toSorted, 'toSorted'); + assert.looksNative(toSorted); + assert.nonEnumerable(Array.prototype, 'toSorted'); + + let array = [1]; + assert.notSame(array.toSorted(), array, 'immutable'); + + assert.deepEqual([1, 3, 2].toSorted(), [1, 2, 3], '#1'); + assert.deepEqual([1, 3, 2, 11].toSorted(), [1, 11, 2, 3], '#2'); + assert.deepEqual([1, -1, 3, NaN, 2, 0, 11, -0].toSorted(), [-1, 0, -0, 1, 11, 2, 3, NaN], '#1'); + + array = Array(5); + array[0] = 1; + array[2] = 3; + array[4] = 2; + let expected = Array(5); + expected[0] = 1; + expected[1] = 2; + expected[2] = 3; + assert.deepEqual(array.toSorted(), expected, 'holes'); + + array = 'zyxwvutsrqponMLKJIHGFEDCBA'.split(''); + expected = 'ABCDEFGHIJKLMnopqrstuvwxyz'.split(''); + assert.deepEqual(array.toSorted(), expected, 'alpha #1'); + + array = 'ёяюэьыъщшчцхфутсрПОНМЛКЙИЗЖЕДГВБА'.split(''); + expected = 'АБВГДЕЖЗИЙКЛМНОПрстуфхцчшщъыьэюяё'.split(''); + assert.deepEqual(array.toSorted(), expected, 'alpha #2'); + + array = [undefined, 1]; + assert.notThrows(() => array = array.toSorted(() => { throw 1; }), 'undefined #1'); + assert.deepEqual(array, [1, undefined], 'undefined #2'); + + /* Safari TP ~ 17.6 issue + const object = { + valueOf: () => 1, + toString: () => -1, + }; + + array = { + 0: undefined, + 1: 2, + 2: 1, + 3: 'X', + 4: -1, + 5: 'a', + 6: true, + 7: object, + 8: NaN, + 10: Infinity, + length: 11, + }; + + expected = [ + -1, + object, + 1, + 2, + Infinity, + NaN, + 'X', + 'a', + true, + undefined, + undefined, + ]; + + assert.deepEqual(toSorted.call(array), expected, 'non-array target'); + */ + + let index, mod, code, chr, value; + expected = Array(516); + array = Array(516); + + for (index = 0; index < 516; index++) { + mod = index % 4; + array[index] = 515 - index; + expected[index] = index - 2 * mod + 3; + } + + assert.arrayEqual(array.toSorted((a, b) => (a / 4 | 0) - (b / 4 | 0)), expected, 'stable #1'); + + assert.true(1 / [0, -0].toSorted()[0] > 0, '-0'); + + let result = ''; + array = []; + + // generate an array with more 512 elements (Chakra and old V8 fails only in this case) + for (code = 65; code < 76; code++) { + chr = String.fromCharCode(code); + + switch (code) { + case 66: case 69: case 70: case 72: value = 3; break; + case 68: case 71: value = 4; break; + default: value = 2; + } + + for (index = 0; index < 47; index++) { + array.push({ k: chr + index, v: value }); + } + } + + array = array.toSorted((a, b) => b.v - a.v); + + for (index = 0; index < array.length; index++) { + chr = array[index].k.charAt(0); + if (result.charAt(result.length - 1) !== chr) result += chr; + } + + assert.same(result, 'DGBEFHACIJK', 'stable #2'); + + assert.notThrows(() => [1, 2, 3].toSorted(undefined).length === 3, 'works with undefined'); + assert.throws(() => [1, 2, 3].toSorted(null), 'throws on null'); + assert.throws(() => [1, 2, 3].toSorted({}), 'throws on {}'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => [Symbol(1), Symbol(2)].toSorted(), 'w/o cmp throws on symbols'); + } + + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.true(array.toSorted() instanceof Array, 'non-generic'); + + if (STRICT) { + assert.throws(() => toSorted.call(null), TypeError, 'ToObject(this)'); + assert.throws(() => toSorted.call(undefined), TypeError, 'ToObject(this)'); + } + + assert.true('toSorted' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.to-spliced.js b/tests/unit-global/es.array.to-spliced.js new file mode 100644 index 000000000000..e40a1d60c1d3 --- /dev/null +++ b/tests/unit-global/es.array.to-spliced.js @@ -0,0 +1,34 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#toSpliced', assert => { + const { toSpliced } = Array.prototype; + + assert.isFunction(toSpliced); + assert.arity(toSpliced, 2); + assert.name(toSpliced, 'toSpliced'); + assert.looksNative(toSpliced); + assert.nonEnumerable(Array.prototype, 'toSpliced'); + + let array = [1, 2, 3, 4, 5]; + assert.notSame(array.toSpliced(2), array, 'immutable'); + + assert.deepEqual([1, 2, 3, 4, 5].toSpliced(2), [1, 2]); + assert.deepEqual([1, 2, 3, 4, 5].toSpliced(-2), [1, 2, 3]); + assert.deepEqual([1, 2, 3, 4, 5].toSpliced(2, 2), [1, 2, 5]); + assert.deepEqual([1, 2, 3, 4, 5].toSpliced(2, -2), [1, 2, 3, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].toSpliced(2, 2, 6, 7), [1, 2, 6, 7, 5]); + + if (STRICT) { + assert.throws(() => toSpliced.call(null), TypeError); + assert.throws(() => toSpliced.call(undefined), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + + assert.true(array.toSpliced() instanceof Array, 'non-generic'); + + assert.true('toSpliced' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/es.array.unshift.js b/tests/unit-global/es.array.unshift.js new file mode 100644 index 000000000000..ee7505782477 --- /dev/null +++ b/tests/unit-global/es.array.unshift.js @@ -0,0 +1,24 @@ +import { REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR, STRICT } from '../helpers/constants.js'; + +const { defineProperty } = Object; + +QUnit.test('Array#unshift', assert => { + const { unshift } = Array.prototype; + assert.isFunction(unshift); + assert.arity(unshift, 1); + assert.name(unshift, 'unshift'); + assert.looksNative(unshift); + assert.nonEnumerable(Array.prototype, 'unshift'); + + assert.same(unshift.call([1], 0), 2, 'proper result'); + + if (STRICT) { + if (REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR) { + assert.throws(() => unshift.call(defineProperty([], 'length', { writable: false }), 1), TypeError, 'non-writable length, with arg'); + assert.throws(() => unshift.call(defineProperty([], 'length', { writable: false })), TypeError, 'non-writable length, without arg'); + } + + assert.throws(() => unshift.call(null), TypeError); + assert.throws(() => unshift.call(undefined), TypeError); + } +}); diff --git a/tests/unit-global/es.array.with.js b/tests/unit-global/es.array.with.js new file mode 100644 index 000000000000..29823aba6acb --- /dev/null +++ b/tests/unit-global/es.array.with.js @@ -0,0 +1,38 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#with', assert => { + const { with: withAt } = Array.prototype; + + assert.isFunction(withAt); + assert.arity(withAt, 2); + // assert.name(withAt, 'with'); + assert.looksNative(withAt); + assert.nonEnumerable(Array.prototype, 'with'); + + let array = [1, 2, 3, 4, 5]; + assert.notSame(array.with(2, 1), array, 'immutable'); + + assert.deepEqual([1, 2, 3, 4, 5].with(2, 6), [1, 2, 6, 4, 5]); + assert.deepEqual([1, 2, 3, 4, 5].with(-2, 6), [1, 2, 3, 6, 5]); + assert.deepEqual([1, 2, 3, 4, 5].with('1', 6), [1, 6, 3, 4, 5]); + + assert.throws(() => [1, 2, 3, 4, 5].with(5, 6), RangeError); + assert.throws(() => [1, 2, 3, 4, 5].with(-6, 6), RangeError); + + if (STRICT) { + assert.throws(() => withAt.call(null, 1, 2), TypeError); + assert.throws(() => withAt.call(undefined, 1, 2), TypeError); + } + + array = [1, 2]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.true(array.with(1, 2) instanceof Array, 'non-generic'); + + // Incorrect exception thrown when index coercion fails in Firefox + function CustomError() { /* empty */ } + const index = { valueOf() { throw new CustomError(); } }; + assert.throws(() => withAt.call([], index, null), CustomError, 'incorrect error'); +}); diff --git a/tests/unit-global/es.async-disposable-stack.constructor.js b/tests/unit-global/es.async-disposable-stack.constructor.js new file mode 100644 index 000000000000..9aff7b55bfc2 --- /dev/null +++ b/tests/unit-global/es.async-disposable-stack.constructor.js @@ -0,0 +1,202 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('AsyncDisposableStack constructor', assert => { + assert.isFunction(AsyncDisposableStack); + assert.arity(AsyncDisposableStack, 0); + assert.name(AsyncDisposableStack, 'AsyncDisposableStack'); + assert.looksNative(AsyncDisposableStack); + + assert.throws(() => AsyncDisposableStack(), 'throws w/o `new`'); + assert.true(new AsyncDisposableStack() instanceof AsyncDisposableStack); + + assert.same(AsyncDisposableStack.prototype.constructor, AsyncDisposableStack); +}); + +QUnit.test('AsyncDisposableStack#disposeAsync', assert => { + assert.isFunction(AsyncDisposableStack.prototype.disposeAsync); + assert.arity(AsyncDisposableStack.prototype.disposeAsync, 0); + assert.name(AsyncDisposableStack.prototype.disposeAsync, 'disposeAsync'); + assert.looksNative(AsyncDisposableStack.prototype.disposeAsync); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'disposeAsync'); +}); + +QUnit.test('AsyncDisposableStack#use', assert => { + assert.isFunction(AsyncDisposableStack.prototype.use); + assert.arity(AsyncDisposableStack.prototype.use, 1); + assert.name(AsyncDisposableStack.prototype.use, 'use'); + assert.looksNative(AsyncDisposableStack.prototype.use); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'use'); + + let result = ''; + const stack = new AsyncDisposableStack(); + const resource = { + [Symbol.asyncDispose]() { + result += '1'; + assert.same(this, resource); + assert.same(arguments.length, 0); + }, + }; + + assert.same(stack.use(resource), resource); + + return stack.disposeAsync().then(it => { + assert.same(it, undefined); + assert.same(result, '1'); + }); +}); + +QUnit.test('AsyncDisposableStack#adopt', assert => { + assert.isFunction(AsyncDisposableStack.prototype.adopt); + assert.arity(AsyncDisposableStack.prototype.adopt, 2); + assert.name(AsyncDisposableStack.prototype.adopt, 'adopt'); + assert.looksNative(AsyncDisposableStack.prototype.adopt); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'adopt'); + + let result = ''; + const stack = new AsyncDisposableStack(); + const resource = {}; + + assert.same(stack.adopt(resource, function (arg) { + result += '1'; + if (STRICT) assert.same(this, undefined); + assert.same(arguments.length, 1); + assert.same(arg, resource); + }), resource); + + return stack.disposeAsync().then(it => { + assert.same(it, undefined); + assert.same(result, '1'); + }); +}); + +QUnit.test('AsyncDisposableStack#defer', assert => { + assert.isFunction(AsyncDisposableStack.prototype.defer); + assert.arity(AsyncDisposableStack.prototype.defer, 1); + assert.name(AsyncDisposableStack.prototype.defer, 'defer'); + assert.looksNative(AsyncDisposableStack.prototype.defer); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'defer'); + + let result = ''; + const stack = new AsyncDisposableStack(); + + assert.same(stack.defer(function () { + result += '1'; + if (STRICT) assert.same(this, undefined); + assert.same(arguments.length, 0); + }), undefined); + + return stack.disposeAsync().then(it => { + assert.same(it, undefined); + assert.same(result, '1'); + }); +}); + +QUnit.test('AsyncDisposableStack#move', assert => { + assert.isFunction(AsyncDisposableStack.prototype.move); + assert.arity(AsyncDisposableStack.prototype.move, 0); + assert.name(AsyncDisposableStack.prototype.move, 'move'); + assert.looksNative(AsyncDisposableStack.prototype.move); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'move'); + + let result = ''; + const stack1 = new AsyncDisposableStack(); + + stack1.defer(() => result += '2'); + stack1.defer(() => result += '1'); + + const stack2 = stack1.move(); + + assert.true(stack1.disposed); + + return stack2.disposeAsync().then(() => { + assert.same(result, '12'); + }); +}); + +QUnit.test('AsyncDisposableStack#@@asyncDispose', assert => { + assert.same(AsyncDisposableStack.prototype[Symbol.asyncDispose], AsyncDisposableStack.prototype.disposeAsync); +}); + +QUnit.test('AsyncDisposableStack#@@toStringTag', assert => { + assert.same(AsyncDisposableStack.prototype[Symbol.toStringTag], 'AsyncDisposableStack', '@@toStringTag'); +}); + +QUnit.test('AsyncDisposableStack#1', assert => { + let result = ''; + const stack = new AsyncDisposableStack(); + + stack.use({ [Symbol.asyncDispose]: () => result += '6' }); + stack.adopt({}, () => result += '5'); + stack.defer(() => result += '4'); + stack.use({ [Symbol.asyncDispose]: () => Promise.resolve(result += '3') }); + stack.adopt({}, () => Promise.resolve(result += '2')); + stack.defer(() => Promise.resolve(result += '1')); + + assert.false(stack.disposed); + + return stack.disposeAsync().then(it => { + assert.same(it, undefined); + assert.same(result, '123456'); + assert.true(stack.disposed); + return stack.disposeAsync(); + }).then(it => { + assert.same(it, undefined); + }); +}); + +QUnit.test('AsyncDisposableStack#2', assert => { + let result = ''; + const stack = new AsyncDisposableStack(); + + stack.use({ [Symbol.asyncDispose]: () => result += '6' }); + stack.adopt({}, () => { throw new Error(5); }); + stack.defer(() => result += '4'); + stack.use({ [Symbol.asyncDispose]: () => Promise.resolve(result += '3') }); + stack.adopt({}, () => Promise.resolve(result += '2')); + stack.defer(() => Promise.resolve(result += '1')); + + return stack.disposeAsync().then(() => { + assert.avoid(); + }, error => { + assert.same(result, '12346'); + assert.true(error instanceof Error); + assert.same(error.message, '5'); + }); +}); + +QUnit.test('AsyncDisposableStack#3', assert => { + let result = ''; + const stack = new AsyncDisposableStack(); + + stack.use({ [Symbol.asyncDispose]: () => result += '6' }); + stack.adopt({}, () => { throw new Error(5); }); + stack.defer(() => result += '4'); + stack.use({ [Symbol.asyncDispose]: () => Promise.reject(new Error(3)) }); + stack.adopt({}, () => Promise.resolve(result += '2')); + stack.defer(() => Promise.resolve(result += '1')); + + return stack.disposeAsync().then(() => { + assert.avoid(); + }, error => { + assert.same(result, '1246'); + assert.true(error instanceof SuppressedError); + assert.same(error.error.message, '5'); + assert.same(error.suppressed.message, '3'); + }); +}); + +// https://github.com/tc39/proposal-explicit-resource-management/issues/256 +QUnit.test('AsyncDisposableStack#256', assert => { + const resume = assert.async(); + assert.expect(1); + let called = false; + const stack = new AsyncDisposableStack(); + const neverResolves = new Promise(() => { /* empty */ }); + stack.use({ [Symbol.dispose]() { return neverResolves; } }); + stack.disposeAsync().then(() => { + called = true; + assert.required('It should be called'); + resume(); + }); + setTimeout(() => called || resume(), 3e3); +}); diff --git a/tests/unit-global/es.async-iterator.async-dispose.js b/tests/unit-global/es.async-iterator.async-dispose.js new file mode 100644 index 000000000000..a785baba31bc --- /dev/null +++ b/tests/unit-global/es.async-iterator.async-dispose.js @@ -0,0 +1,25 @@ +const { create } = Object; + +QUnit.test('AsyncIterator#@@asyncDispose', assert => { + const asyncDispose = AsyncIterator.prototype[Symbol.asyncDispose]; + assert.isFunction(asyncDispose); + assert.arity(asyncDispose, 0); + assert.looksNative(asyncDispose); + + return create(AsyncIterator.prototype)[Symbol.asyncDispose]().then(result => { + assert.same(result, undefined); + }).then(() => { + let called = false; + const iterator2 = create(AsyncIterator.prototype); + iterator2.return = function () { + called = true; + assert.same(this, iterator2); + return 7; + }; + + return iterator2[Symbol.asyncDispose]().then(result => { + assert.same(result, undefined); + assert.true(called); + }); + }); +}); diff --git a/tests/tests/es.data-view.js b/tests/unit-global/es.data-view.js similarity index 99% rename from tests/tests/es.data-view.js rename to tests/unit-global/es.data-view.js index 18601e44c22e..b921dcb2dc8a 100644 --- a/tests/tests/es.data-view.js +++ b/tests/unit-global/es.data-view.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, NATIVE } from '../helpers/constants'; +import { DESCRIPTORS, NATIVE } from '../helpers/constants.js'; QUnit.test('DataView', assert => { assert.same(DataView, Object(DataView), 'is object'); // in Safari 5 typeof DataView is 'object' diff --git a/tests/unit-global/es.data-view.set-float16.js b/tests/unit-global/es.data-view.set-float16.js new file mode 100644 index 000000000000..55d20a124813 --- /dev/null +++ b/tests/unit-global/es.data-view.set-float16.js @@ -0,0 +1,66 @@ +QUnit.test('DataView.prototype.{ getFloat16, setFloat16 }', assert => { + const { getFloat16, setFloat16 } = DataView.prototype; + + assert.isFunction(getFloat16); + assert.arity(getFloat16, 1); + assert.name(getFloat16, 'getFloat16'); + + assert.isFunction(setFloat16); + assert.arity(setFloat16, 2); + assert.name(setFloat16, 'setFloat16'); + + assert.same(new DataView(new ArrayBuffer(8)).setFloat16(0, 0), undefined, 'void'); + + function toString(it) { + return it === 0 && 1 / it === -Infinity ? '-0' : it; + } + + const data = [ + [0b0000000000000000, 0], + [0b1000000000000000, -0], + [0b0011110000000000, 1], + [0b1011110000000000, -1], + [0b0100001001001000, 3.140625], + [0b0000001000000000, 0.000030517578125], + [0b0111101111111111, 65504], + [0b1111101111111111, -65504], + [0b0000000000000001, 2 ** -24], + [0b1000000000000001, -(2 ** -24)], + // [0b0111110000000001, NaN], <- what NaN representation should be used? + [0b0111110000000000, Infinity], + [0b1111110000000000, -Infinity], + ]; + + const buffer = new ArrayBuffer(2); + const view = new DataView(buffer); + + for (const [bin, f16] of data) for (const LE of [false, true]) { + view.setUint16(0, bin, LE); + assert.same(view.getFloat16(0, LE), f16, `DataView.prototype.setUint16 + DataView.prototype.getFloat16, LE: ${ LE }, ${ toString(bin) } -> ${ toString(f16) }`); + view.setFloat16(0, f16, LE); + assert.same(view.getUint16(0, LE), bin, `DataView.prototype.setFloat16 + DataView.prototype.getUint16, LE: ${ LE }, ${ toString(f16) } -> ${ toString(bin) }`); + assert.same(view.getFloat16(0, LE), f16, `DataView.prototype.setFloat16 + DataView.prototype.getFloat16, LE: ${ LE }, ${ toString(f16) }`); + } + + const MAX_FLOAT16 = 65504; + const MIN_FLOAT16 = 2 ** -24; + + const conversions = [ + [1.337, 1.3369140625], + [0.499994, 0.5], + [7.9999999, 8], + [MAX_FLOAT16, MAX_FLOAT16], + [-MAX_FLOAT16, -MAX_FLOAT16], + [MIN_FLOAT16, MIN_FLOAT16], + [-MIN_FLOAT16, -MIN_FLOAT16], + [MIN_FLOAT16 / 2, 0], + [-MIN_FLOAT16 / 2, -0], + [2.980232238769531911744490042422139897126953655970282852649688720703125e-8, MIN_FLOAT16], + [-2.980232238769531911744490042422139897126953655970282852649688720703125e-8, -MIN_FLOAT16], + ]; + + for (const [from, to] of conversions) for (const LE of [false, true]) { + view.setFloat16(0, from, LE); + assert.same(view.getFloat16(0, LE), to, `DataView.prototype.setFloat16 + DataView.prototype.getFloat16, LE: ${ LE }, ${ toString(from) } -> ${ toString(to) }`); + } +}); diff --git a/tests/unit-global/es.date.get-year.js b/tests/unit-global/es.date.get-year.js new file mode 100644 index 000000000000..466c6434e9c0 --- /dev/null +++ b/tests/unit-global/es.date.get-year.js @@ -0,0 +1,10 @@ +QUnit.test('Date#getYear', assert => { + const { getYear } = Date.prototype; + assert.isFunction(getYear); + assert.arity(getYear, 0); + assert.name(getYear, 'getYear'); + assert.looksNative(getYear); + assert.nonEnumerable(Date.prototype, 'getYear'); + const date = new Date(); + assert.same(date.getYear(), date.getFullYear() - 1900); +}); diff --git a/tests/unit-global/es.date.now.js b/tests/unit-global/es.date.now.js new file mode 100644 index 000000000000..f566bea2c89b --- /dev/null +++ b/tests/unit-global/es.date.now.js @@ -0,0 +1,9 @@ +QUnit.test('Date.now', assert => { + const { now } = Date; + assert.isFunction(now); + assert.arity(now, 0); + assert.name(now, 'now'); + assert.looksNative(now); + assert.nonEnumerable(Date, 'now'); + assert.same(typeof now(), 'number', 'typeof'); +}); diff --git a/tests/unit-global/es.date.set-year.js b/tests/unit-global/es.date.set-year.js new file mode 100644 index 000000000000..850c554d0320 --- /dev/null +++ b/tests/unit-global/es.date.set-year.js @@ -0,0 +1,11 @@ +QUnit.test('Date#setYear', assert => { + const { setYear } = Date.prototype; + assert.isFunction(setYear); + assert.arity(setYear, 1); + assert.name(setYear, 'setYear'); + assert.looksNative(setYear); + assert.nonEnumerable(Date.prototype, 'setYear'); + const date = new Date(); + date.setYear(1); + assert.same(date.getFullYear(), 1901); +}); diff --git a/tests/unit-global/es.date.to-gmt-string.js b/tests/unit-global/es.date.to-gmt-string.js new file mode 100644 index 000000000000..a64b1d94223f --- /dev/null +++ b/tests/unit-global/es.date.to-gmt-string.js @@ -0,0 +1,11 @@ +QUnit.test('Date#toGMTString', assert => { + const { toGMTString } = Date.prototype; + assert.isFunction(toGMTString); + assert.arity(toGMTString, 0); + // assert.name(toGMTString, 'toUTCString'); // at least old WebKit + assert.looksNative(toGMTString); + assert.nonEnumerable(Date.prototype, 'toGMTString'); + // assert.same(toGMTString, Date.prototype.toUTCString); // at least old WebKit + const date = new Date(); + assert.same(date.toGMTString(), date.toUTCString()); +}); diff --git a/tests/unit-global/es.date.to-iso-string.js b/tests/unit-global/es.date.to-iso-string.js new file mode 100644 index 000000000000..24269c7f7647 --- /dev/null +++ b/tests/unit-global/es.date.to-iso-string.js @@ -0,0 +1,18 @@ +QUnit.test('Date#toISOString', assert => { + const { toISOString } = Date.prototype; + assert.isFunction(toISOString); + assert.arity(toISOString, 0); + assert.name(toISOString, 'toISOString'); + assert.looksNative(toISOString); + assert.nonEnumerable(Date.prototype, 'toISOString'); + assert.same(new Date(0).toISOString(), '1970-01-01T00:00:00.000Z'); + assert.same(new Date(1e12 + 1).toISOString(), '2001-09-09T01:46:40.001Z'); + assert.same(new Date(-5e13 - 1).toISOString(), '0385-07-25T07:06:39.999Z'); + const future = new Date(1e15 + 1).toISOString(); + const properFuture = future === '+033658-09-27T01:46:40.001Z' || future === '33658-09-27T01:46:40.001Z'; + assert.true(properFuture); + const prehistoric = new Date(-1e15 + 1).toISOString(); + const properPrehistoric = prehistoric === '-029719-04-05T22:13:20.001Z' || prehistoric === '-29719-04-05T22:13:20.001Z'; + assert.true(properPrehistoric); + assert.throws(() => new Date(NaN).toISOString(), RangeError); +}); diff --git a/tests/tests/es.date.to-json.js b/tests/unit-global/es.date.to-json.js similarity index 100% rename from tests/tests/es.date.to-json.js rename to tests/unit-global/es.date.to-json.js diff --git a/tests/tests/es.date.to-primitive.js b/tests/unit-global/es.date.to-primitive.js similarity index 96% rename from tests/tests/es.date.to-primitive.js rename to tests/unit-global/es.date.to-primitive.js index 109f785d7523..7afa8e1a0fea 100644 --- a/tests/tests/es.date.to-primitive.js +++ b/tests/unit-global/es.date.to-primitive.js @@ -1,4 +1,4 @@ -import { STRICT } from '../helpers/constants'; +import { STRICT } from '../helpers/constants.js'; QUnit.test('Date#@@toPrimitive', assert => { const toPrimitive = Date.prototype[Symbol.toPrimitive]; diff --git a/tests/tests/es.date.to-string.js b/tests/unit-global/es.date.to-string.js similarity index 100% rename from tests/tests/es.date.to-string.js rename to tests/unit-global/es.date.to-string.js diff --git a/tests/unit-global/es.disposable-stack.constructor.js b/tests/unit-global/es.disposable-stack.constructor.js new file mode 100644 index 000000000000..2178bb72bf2f --- /dev/null +++ b/tests/unit-global/es.disposable-stack.constructor.js @@ -0,0 +1,176 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('DisposableStack constructor', assert => { + assert.isFunction(DisposableStack); + assert.arity(DisposableStack, 0); + assert.name(DisposableStack, 'DisposableStack'); + assert.looksNative(DisposableStack); + + assert.throws(() => DisposableStack(), 'throws w/o `new`'); + assert.true(new DisposableStack() instanceof DisposableStack); + + assert.same(DisposableStack.prototype.constructor, DisposableStack); +}); + +QUnit.test('DisposableStack#dispose', assert => { + assert.isFunction(DisposableStack.prototype.dispose); + assert.arity(DisposableStack.prototype.dispose, 0); + assert.name(DisposableStack.prototype.dispose, 'dispose'); + assert.looksNative(DisposableStack.prototype.dispose); + assert.nonEnumerable(DisposableStack.prototype, 'dispose'); +}); + +QUnit.test('DisposableStack#use', assert => { + assert.isFunction(DisposableStack.prototype.use); + assert.arity(DisposableStack.prototype.use, 1); + assert.name(DisposableStack.prototype.use, 'use'); + assert.looksNative(DisposableStack.prototype.use); + assert.nonEnumerable(DisposableStack.prototype, 'use'); + + let result = ''; + const stack1 = new DisposableStack(); + const resource = { + [Symbol.dispose]() { + result += '1'; + assert.same(this, resource); + assert.same(arguments.length, 0); + }, + }; + + assert.same(stack1.use(resource), resource); + assert.same(stack1.dispose(), undefined); + assert.same(result, '1'); +}); + +QUnit.test('DisposableStack#adopt', assert => { + assert.isFunction(DisposableStack.prototype.adopt); + assert.arity(DisposableStack.prototype.adopt, 2); + assert.name(DisposableStack.prototype.adopt, 'adopt'); + assert.looksNative(DisposableStack.prototype.adopt); + assert.nonEnumerable(DisposableStack.prototype, 'adopt'); + + let result = ''; + const stack = new DisposableStack(); + const resource = {}; + + assert.same(stack.adopt(resource, function (arg) { + result += '1'; + if (STRICT) assert.same(this, undefined); + assert.same(arguments.length, 1); + assert.same(arg, resource); + }), resource); + + assert.same(stack.dispose(), undefined); + assert.same(result, '1'); +}); + +QUnit.test('DisposableStack#defer', assert => { + assert.isFunction(DisposableStack.prototype.defer); + assert.arity(DisposableStack.prototype.defer, 1); + assert.name(DisposableStack.prototype.defer, 'defer'); + assert.looksNative(DisposableStack.prototype.defer); + assert.nonEnumerable(DisposableStack.prototype, 'defer'); + + let result = ''; + const stack = new DisposableStack(); + + assert.same(stack.defer(function () { + result += '1'; + if (STRICT) assert.same(this, undefined); + assert.same(arguments.length, 0); + }), undefined); + + assert.same(stack.dispose(), undefined); + assert.same(result, '1'); +}); + +QUnit.test('DisposableStack#move', assert => { + assert.isFunction(DisposableStack.prototype.move); + assert.arity(DisposableStack.prototype.move, 0); + assert.name(DisposableStack.prototype.move, 'move'); + assert.looksNative(DisposableStack.prototype.move); + assert.nonEnumerable(DisposableStack.prototype, 'move'); + + let result = ''; + const stack = new DisposableStack(); + + stack.defer(() => result += '2'); + stack.defer(() => result += '1'); + + const stack2 = stack.move(); + + assert.true(stack.disposed); + + stack2.dispose(); + + assert.same(result, '12'); +}); + +QUnit.test('DisposableStack#@@dispose', assert => { + assert.same(DisposableStack.prototype[Symbol.dispose], DisposableStack.prototype.dispose); +}); + +QUnit.test('DisposableStack#@@toStringTag', assert => { + assert.same(DisposableStack.prototype[Symbol.toStringTag], 'DisposableStack', '@@toStringTag'); +}); + +QUnit.test('DisposableStack', assert => { + let result1 = ''; + const stack1 = new DisposableStack(); + + stack1.use({ [Symbol.dispose]: () => result1 += '6' }); + stack1.adopt({}, () => result1 += '5'); + stack1.defer(() => result1 += '4'); + stack1.use({ [Symbol.dispose]: () => result1 += '3' }); + stack1.adopt({}, () => result1 += '2'); + stack1.defer(() => result1 += '1'); + + assert.false(stack1.disposed); + assert.same(stack1.dispose(), undefined); + assert.same(result1, '123456'); + assert.true(stack1.disposed); + assert.same(stack1.dispose(), undefined); + + let result2 = ''; + const stack2 = new DisposableStack(); + let error2; + + stack2.use({ [Symbol.dispose]: () => result2 += '6' }); + stack2.adopt({}, () => { throw new Error(5); }); + stack2.defer(() => result2 += '4'); + stack2.use({ [Symbol.dispose]: () => result2 += '3' }); + stack2.adopt({}, () => result2 += '2'); + stack2.defer(() => result2 += '1'); + + try { + stack2.dispose(); + } catch (error2$) { + error2 = error2$; + } + + assert.same(result2, '12346'); + assert.true(error2 instanceof Error); + assert.same(error2.message, '5'); + + let result3 = ''; + const stack3 = new DisposableStack(); + let error3; + + stack3.use({ [Symbol.dispose]: () => result3 += '6' }); + stack3.adopt({}, () => { throw new Error(5); }); + stack3.defer(() => result3 += '4'); + stack3.use({ [Symbol.dispose]: () => { throw new Error(3); } }); + stack3.adopt({}, () => result3 += '2'); + stack3.defer(() => result3 += '1'); + + try { + stack3.dispose(); + } catch (error3$) { + error3 = error3$; + } + + assert.same(result3, '1246'); + assert.true(error3 instanceof SuppressedError); + assert.same(error3.error.message, '5'); + assert.same(error3.suppressed.message, '3'); +}); diff --git a/tests/unit-global/es.error.cause.js b/tests/unit-global/es.error.cause.js new file mode 100644 index 000000000000..a8899429335f --- /dev/null +++ b/tests/unit-global/es.error.cause.js @@ -0,0 +1,58 @@ +/* eslint-disable sonarjs/inconsistent-function-call -- required for testing */ +import { GLOBAL, PROTO } from '../helpers/constants.js'; + +const { create } = Object; + +function runErrorTestCase($Error, ERROR_NAME) { + QUnit.test(`${ ERROR_NAME } constructor with 'cause' param`, assert => { + assert.isFunction($Error); + assert.arity($Error, 1); + assert.name($Error, ERROR_NAME); + assert.looksNative($Error); + + if (PROTO && $Error !== Error) { + // eslint-disable-next-line no-prototype-builtins -- safe + assert.true(Error.isPrototypeOf($Error), 'constructor has `Error` in the prototype chain'); + } + + assert.same($Error.prototype.constructor, $Error, 'prototype constructor'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.false($Error.prototype.hasOwnProperty('cause'), 'prototype has not cause'); + + assert.true($Error(1) instanceof $Error, 'no cause, without new'); + assert.true(new $Error(1) instanceof $Error, 'no cause, with new'); + + assert.true($Error(1, {}) instanceof $Error, 'with options, without new'); + assert.true(new $Error(1, {}) instanceof $Error, 'with options, with new'); + + assert.true($Error(1, 'foo') instanceof $Error, 'non-object options, without new'); + assert.true(new $Error(1, 'foo') instanceof $Error, 'non-object options, with new'); + + assert.same($Error(1, { cause: 7 }).cause, 7, 'cause, without new'); + assert.same(new $Error(1, { cause: 7 }).cause, 7, 'cause, with new'); + + assert.same($Error(1, create({ cause: 7 })).cause, 7, 'prototype cause, without new'); + assert.same(new $Error(1, create({ cause: 7 })).cause, 7, 'prototype cause, with new'); + + let error = $Error(1, { cause: 7 }); + assert.same(error.name, ERROR_NAME, 'instance name'); + assert.same(error.message, '1', 'instance message'); + assert.same(error.cause, 7, 'instance cause'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.true(error.hasOwnProperty('cause'), 'cause is own'); + + error = $Error(); + assert.same(error.message, '', 'default instance message'); + assert.same(error.cause, undefined, 'default instance cause undefined'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.false(error.hasOwnProperty('cause'), 'default instance cause missed'); + }); +} + +for (const ERROR_NAME of ['Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError']) { + runErrorTestCase(GLOBAL[ERROR_NAME], ERROR_NAME); +} + +if (GLOBAL.WebAssembly) for (const ERROR_NAME of ['CompileError', 'LinkError', 'RuntimeError']) { + if (GLOBAL.WebAssembly[ERROR_NAME]) runErrorTestCase(GLOBAL.WebAssembly[ERROR_NAME], ERROR_NAME); +} diff --git a/tests/unit-global/es.error.is-error.js b/tests/unit-global/es.error.is-error.js new file mode 100644 index 000000000000..e28dde6d27af --- /dev/null +++ b/tests/unit-global/es.error.is-error.js @@ -0,0 +1,18 @@ +QUnit.test('Error.isError', assert => { + const { isError } = Error; + assert.isFunction(isError); + assert.arity(isError, 1); + assert.name(isError, 'isError'); + assert.looksNative(isError); + assert.nonEnumerable(Error, 'isError'); + + assert.true(isError(new Error('error'))); + assert.true(isError(new TypeError('error'))); + assert.true(isError(new AggregateError([1, 2, 3], 'error'))); + assert.true(isError(new SuppressedError(1, 2, 'error'))); + assert.true(isError(new DOMException('error'))); + + assert.false(isError(null)); + assert.false(isError({})); + assert.false(isError(Object.create(Error.prototype))); +}); diff --git a/tests/unit-global/es.error.to-string.js b/tests/unit-global/es.error.to-string.js new file mode 100644 index 000000000000..9eedddb82eb3 --- /dev/null +++ b/tests/unit-global/es.error.to-string.js @@ -0,0 +1,30 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Error#toString', assert => { + const { toString } = Error.prototype; + assert.isFunction(toString); + assert.arity(toString, 0); + assert.name(toString, 'toString'); + assert.looksNative(toString); + assert.nonEnumerable(Error.prototype, 'toString'); + assert.same(String(new Error('something')), 'Error: something'); + assert.same(String(new TypeError('something')), 'TypeError: something'); + assert.same(String(new Error()), 'Error'); + assert.same(toString.call({}), 'Error'); + assert.same(toString.call({ name: 'foo' }), 'foo'); + assert.same(toString.call({ message: 'bar' }), 'Error: bar'); + assert.same(toString.call({ name: '', message: 'bar' }), 'bar'); + assert.same(toString.call({ name: 'foo', message: 'bar' }), 'foo: bar'); + assert.same(toString.call({ name: 1, message: 2 }), '1: 2'); + + if (STRICT) { + assert.throws(() => toString.call(7)); + assert.throws(() => toString.call('a')); + assert.throws(() => toString.call(false)); + assert.throws(() => toString.call(null)); + assert.throws(() => toString.call(undefined)); + } + + // assert.throws(() => toString.call({ name: Symbol() }), 'throws on symbol #1'); + // assert.throws(() => toString.call({ name: Symbol() }), 'throws on symbol #2'); +}); diff --git a/tests/unit-global/es.escape.js b/tests/unit-global/es.escape.js new file mode 100644 index 000000000000..aa79bc6504f7 --- /dev/null +++ b/tests/unit-global/es.escape.js @@ -0,0 +1,13 @@ +QUnit.test('escape', assert => { + assert.isFunction(escape); + assert.name(escape, 'escape'); + assert.arity(escape, 1); + assert.looksNative(escape); + assert.same(escape('!q2ф'), '%21q2%u0444'); + assert.same(escape(null), 'null'); + assert.same(escape(undefined), 'undefined'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => unescape(Symbol('escape test')), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-global/es.function.bind.js b/tests/unit-global/es.function.bind.js new file mode 100644 index 000000000000..56076c3b6ccd --- /dev/null +++ b/tests/unit-global/es.function.bind.js @@ -0,0 +1,28 @@ +QUnit.test('Function#bind', assert => { + const { bind } = Function.prototype; + assert.isFunction(bind); + assert.arity(bind, 1); + assert.name(bind, 'bind'); + assert.looksNative(bind); + assert.nonEnumerable(Function.prototype, 'bind'); + assert.same(function () { + return this.a; + }.bind({ a: 42 })(), 42); + assert.same(new (function () { /* empty */ })().a, undefined); + function A(a, b) { + this.a = a; + this.b = b; + } + const instance = new (A.bind(null, 1))(2); + assert.true(instance instanceof A); + assert.same(instance.a, 1); + assert.same(instance.b, 2); + assert.same((it => it).bind(null, 42)(), 42); + const regExpTest = RegExp.prototype.test.bind(/a/); + assert.true(regExpTest('a')); + const Date2017 = Date.bind(null, 2017); + const date = new Date2017(11); + assert.true(date instanceof Date); + assert.same(date.getFullYear(), 2017); + assert.same(date.getMonth(), 11); +}); diff --git a/tests/unit-global/es.function.has-instance.js b/tests/unit-global/es.function.has-instance.js new file mode 100644 index 000000000000..925294ef7a69 --- /dev/null +++ b/tests/unit-global/es.function.has-instance.js @@ -0,0 +1,6 @@ +QUnit.test('Function#@@hasInstance', assert => { + assert.true(Symbol.hasInstance in Function.prototype); + assert.nonEnumerable(Function.prototype, Symbol.hasInstance); + assert.true(Function[Symbol.hasInstance](() => { /* empty */ })); + assert.false(Function[Symbol.hasInstance]({})); +}); diff --git a/tests/unit-global/es.function.name.js b/tests/unit-global/es.function.name.js new file mode 100644 index 000000000000..a461d77e5333 --- /dev/null +++ b/tests/unit-global/es.function.name.js @@ -0,0 +1,42 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + QUnit.test('Function#name', assert => { + assert.true('name' in Function.prototype); + assert.nonEnumerable(Function.prototype, 'name'); + function foo() { /* empty */ } + assert.same(foo.name, 'foo'); + assert.same(function () { /* empty */ }.name, ''); + if (Object.freeze) { + assert.same(Object.freeze(() => { /* empty */ }).name, ''); + } + function bar() { /* empty */ } + bar.toString = function () { + throw new Error(); + }; + assert.notThrows(() => bar.name === 'bar', 'works with redefined `.toString`'); + const baz = Object(() => { /* empty */ }); + baz.toString = function () { + return ''; + }; + assert.same(baz.name, ''); + + assert.same(function /* + multi-line comment */() { /* empty */ }.name, ''); + + function /* + multi-line comment */ + foobar() { /* empty */ } + assert.same(foobar.name, 'foobar'); + + function // simple-line comment + foobaz() { /* empty */ } + assert.same(foobaz.name, 'foobaz'); + + function // simple-line comment + /* multi-line comment */quux/* + multi-line comment + */() { /* empty */ } + assert.same(quux.name, 'quux'); + }); +} diff --git a/tests/tests/es.global-this.js b/tests/unit-global/es.global-this.js similarity index 100% rename from tests/tests/es.global-this.js rename to tests/unit-global/es.global-this.js diff --git a/tests/unit-global/es.iterator.concat.js b/tests/unit-global/es.iterator.concat.js new file mode 100644 index 000000000000..6aa47a982790 --- /dev/null +++ b/tests/unit-global/es.iterator.concat.js @@ -0,0 +1,99 @@ +import { createIterable, createIterator } from '../helpers/helpers.js'; + +const { from } = Array; + +QUnit.test('Iterator.concat', assert => { + const { concat } = Iterator; + + assert.isFunction(concat); + assert.arity(concat, 0); + assert.name(concat, 'concat'); + assert.looksNative(concat); + assert.nonEnumerable(Iterator, 'concat'); + + let iterator = concat(); + assert.isIterable(iterator, 'iterable, no args'); + assert.isIterator(iterator, 'iterator, no args'); + assert.true(iterator instanceof Iterator, 'iterator instance, no args'); + assert.arrayEqual(from(iterator), [], 'proper values, no args'); + + iterator = concat([1, 2, 3]); + assert.isIterable(iterator, 'iterable, array'); + assert.isIterator(iterator, 'iterator, array'); + assert.true(iterator instanceof Iterator, 'iterator instance, array'); + assert.arrayEqual(from(iterator), [1, 2, 3], 'proper values, array'); + + iterator = concat([]); + assert.isIterable(iterator, 'iterable, empty array'); + assert.isIterator(iterator, 'iterator, empty array'); + assert.true(iterator instanceof Iterator, 'iterator instance, empty array'); + assert.arrayEqual(from(iterator), [], 'proper values, empty array'); + + iterator = concat(createIterable([1, 2, 3])); + assert.isIterable(iterator, 'iterable, custom iterable'); + assert.isIterator(iterator, 'iterator, custom iterable'); + assert.true(iterator instanceof Iterator, 'iterator instance, custom iterable'); + assert.arrayEqual(from(iterator), [1, 2, 3], 'proper values, custom iterable'); + + iterator = concat([1, 2, 3], [], createIterable([4, 5, 6]), createIterable([])); + assert.isIterable(iterator, 'iterable, mixed'); + assert.isIterator(iterator, 'iterator, mixed'); + assert.true(iterator instanceof Iterator, 'iterator instance, mixed'); + assert.arrayEqual(from(iterator), [1, 2, 3, 4, 5, 6], 'proper values, mixed'); + + iterator = concat(createIterable([1, 2, 3])); + iterator.next(); + assert.deepEqual(iterator.return(), { done: true, value: undefined }, '.return with no active inner iterator result'); + assert.deepEqual(iterator.next(), { done: true, value: undefined }, '.return with no active inner iterator result on closed iterator'); + + iterator = concat(createIterable([1, 2, 3])); + assert.deepEqual(iterator.next(), { done: false, value: 1 }, '.next with active inner iterator result'); + assert.deepEqual(iterator.return(), { done: true, value: undefined }, '.return with active inner iterator result'); + assert.deepEqual(iterator.next(), { done: true, value: undefined }, '.return with active inner iterator result on closed iterator'); + + let called = false; + iterator = concat(createIterable([1, 2, 3], { + return() { + called = true; + return {}; + }, + })); + iterator.next(); + assert.deepEqual(iterator.return(), { done: true, value: undefined }, '.return with active inner iterator with return result'); + assert.true(called, 'inner .return called'); + + // https://github.com/tc39/proposal-iterator-sequencing/issues/17 + const oldIterResult = { + done: false, + value: 123, + }; + const testIterator = { + next() { + return oldIterResult; + }, + }; + const iterable = { + [Symbol.iterator]() { + return testIterator; + }, + }; + iterator = concat(iterable); + const iterResult = iterator.next(); + assert.same(iterResult.done, false); + assert.same(iterResult.value, 123); + // https://github.com/tc39/proposal-iterator-sequencing/pull/26 + assert.notSame(iterResult, oldIterResult); + + assert.throws(() => concat(createIterator([1, 2, 3])), TypeError, 'non-iterable iterator #1'); + assert.throws(() => concat([], createIterator([1, 2, 3])), TypeError, 'non-iterable iterator #2'); + assert.throws(() => concat(''), TypeError, 'iterable non-object argument #1'); + assert.throws(() => concat([], ''), TypeError, 'iterable non-object argument #2'); + assert.throws(() => concat(undefined), TypeError, 'non-iterable-object argument #1'); + assert.throws(() => concat(null), TypeError, 'non-iterable-object argument #2'); + assert.throws(() => concat(1), TypeError, 'non-iterable-object argument #3'); + assert.throws(() => concat({}), TypeError, 'non-iterable-object argument #4'); + assert.throws(() => concat([], undefined), TypeError, 'non-iterable-object argument #5'); + assert.throws(() => concat([], null), TypeError, 'non-iterable-object argument #6'); + assert.throws(() => concat([], 1), TypeError, 'non-iterable-object argument #7'); + assert.throws(() => concat([], {}), TypeError, 'non-iterable-object argument #8'); +}); diff --git a/tests/unit-global/es.iterator.constructor.js b/tests/unit-global/es.iterator.constructor.js new file mode 100644 index 000000000000..053cc48356c1 --- /dev/null +++ b/tests/unit-global/es.iterator.constructor.js @@ -0,0 +1,49 @@ +import { createIterator, nativeSubclass } from '../helpers/helpers.js'; + +const { getPrototypeOf } = Object; + +QUnit.test('Iterator', assert => { + assert.isFunction(Iterator); + assert.arity(Iterator, 0); + assert.name(Iterator, 'Iterator'); + assert.looksNative(Iterator); + + const generator = (() => { + try { + return Function('return function*(){}()')(); + } catch { /* empty */ } + })(); + + if (generator) { + const proto = getPrototypeOf(getPrototypeOf(getPrototypeOf(generator))); + if (proto !== Object.prototype && proto !== null) { + assert.true(generator instanceof Iterator, 'Generator'); + } + } + + assert.true(''[Symbol.iterator]() instanceof Iterator, 'String Iterator'); + assert.true([].values() instanceof Iterator, 'Array Iterator'); + assert.true(new Set().values() instanceof Iterator, 'Set Iterator'); + assert.true('abc'.matchAll(/./g) instanceof Iterator, 'MatchAll Iterator'); + assert.true(Iterator.from(createIterator([1, 2, 3])) instanceof Iterator, 'From Proxy'); + assert.true([].values().drop(1) instanceof Iterator, 'Drop Proxy'); + + if (nativeSubclass) { + const Sub = nativeSubclass(Iterator); + assert.true(new Sub() instanceof Iterator, 'abstract constructor'); + } + + assert.throws(() => new Iterator(), 'direct constructor throws'); + assert.throws(() => Iterator(), 'throws w/o `new`'); +}); + +QUnit.test('Iterator#constructor', assert => { + assert.same(Iterator.prototype.constructor, Iterator, 'Iterator#constructor is Iterator'); +}); + +QUnit.test('Iterator#@@toStringTag', assert => { + assert.same(Iterator.prototype[Symbol.toStringTag], 'Iterator', 'Iterator::@@toStringTag is `Iterator`'); + assert.same(String(Iterator.from({ + next: () => ({ done: Math.random() > 0.9, value: Math.random() * 10 | 0 }), + })), '[object Iterator]', 'correct stringification'); +}); diff --git a/tests/unit-global/es.iterator.dispose.js b/tests/unit-global/es.iterator.dispose.js new file mode 100644 index 000000000000..ebafc338f61a --- /dev/null +++ b/tests/unit-global/es.iterator.dispose.js @@ -0,0 +1,20 @@ +const { create } = Object; + +QUnit.test('Iterator#@@dispose', assert => { + const dispose = Iterator.prototype[Symbol.dispose]; + assert.isFunction(dispose); + assert.arity(dispose, 0); + assert.looksNative(dispose); + + assert.same(create(Iterator.prototype)[Symbol.dispose](), undefined); + + let called = false; + const iterator2 = create(Iterator.prototype); + iterator2.return = function () { + called = true; + assert.same(this, iterator2); + return 7; + }; + assert.same(iterator2[Symbol.dispose](), undefined); + assert.true(called); +}); diff --git a/tests/unit-global/es.iterator.drop.js b/tests/unit-global/es.iterator.drop.js new file mode 100644 index 000000000000..5d63e347cc17 --- /dev/null +++ b/tests/unit-global/es.iterator.drop.js @@ -0,0 +1,31 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('Iterator#drop', assert => { + const { drop } = Iterator.prototype; + + assert.isFunction(drop); + assert.arity(drop, 1); + assert.name(drop, 'drop'); + assert.looksNative(drop); + assert.nonEnumerable(Iterator.prototype, 'drop'); + + assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 1).toArray(), [2, 3], 'basic functionality'); + assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 1.5).toArray(), [2, 3], 'float'); + assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 4).toArray(), [], 'big'); + assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 0).toArray(), [1, 2, 3], 'zero'); + + if (STRICT) { + assert.throws(() => drop.call(undefined, 1), TypeError); + assert.throws(() => drop.call(null, 1), TypeError); + } + + assert.throws(() => drop.call({}, 1).next(), TypeError); + assert.throws(() => drop.call([], 1).next(), TypeError); + assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => drop.call(it, NaN), RangeError, 'NaN'); + assert.true(it.closed, "drop doesn't close iterator on validation error"); + // https://issues.chromium.org/issues/336839115 + assert.throws(() => drop.call({ next: null }, 0).next(), TypeError); +}); diff --git a/tests/unit-global/es.iterator.every.js b/tests/unit-global/es.iterator.every.js new file mode 100644 index 000000000000..ce73439388bb --- /dev/null +++ b/tests/unit-global/es.iterator.every.js @@ -0,0 +1,34 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Iterator#every', assert => { + const { every } = Iterator.prototype; + + assert.isFunction(every); + assert.arity(every, 1); + assert.name(every, 'every'); + assert.looksNative(every); + assert.nonEnumerable(Iterator.prototype, 'every'); + + assert.true(every.call(createIterator([1, 2, 3]), it => typeof it == 'number'), 'basic functionality #1'); + assert.false(every.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #2'); + every.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => every.call([], () => { /* empty */ }), TypeError); + assert.throws(() => every.call(createIterator([1]), undefined), TypeError); + assert.throws(() => every.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => every.call(it, {}), TypeError); + assert.true(it.closed, "every doesn't close iterator on validation error"); +}); diff --git a/tests/unit-global/es.iterator.filter.js b/tests/unit-global/es.iterator.filter.js new file mode 100644 index 000000000000..12d0b2844619 --- /dev/null +++ b/tests/unit-global/es.iterator.filter.js @@ -0,0 +1,35 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Iterator#filter', assert => { + const { filter } = Iterator.prototype; + + assert.isFunction(filter); + assert.arity(filter, 1); + assert.name(filter, 'filter'); + assert.looksNative(filter); + assert.nonEnumerable(Iterator.prototype, 'filter'); + + assert.arrayEqual(filter.call(createIterator([1, 2, 3]), it => it % 2).toArray(), [1, 3], 'basic functionality'); + filter.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => filter.call({}, () => { /* empty */ }).next(), TypeError); + assert.throws(() => filter.call([], () => { /* empty */ }).next(), TypeError); + assert.throws(() => filter.call(createIterator([1]), undefined), TypeError); + assert.throws(() => filter.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => filter.call(it, {}), TypeError); + assert.true(it.closed, "filter doesn't close iterator on validation error"); + // https://issues.chromium.org/issues/336839115 + assert.throws(() => filter.call({ next: null }, () => { /* empty */ }).next(), TypeError); +}); diff --git a/tests/unit-global/es.iterator.find.js b/tests/unit-global/es.iterator.find.js new file mode 100644 index 000000000000..f0684d7f8708 --- /dev/null +++ b/tests/unit-global/es.iterator.find.js @@ -0,0 +1,33 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Iterator#find', assert => { + const { find } = Iterator.prototype; + + assert.isFunction(find); + assert.arity(find, 1); + assert.name(find, 'find'); + assert.looksNative(find); + assert.nonEnumerable(Iterator.prototype, 'find'); + + assert.same(find.call(createIterator([1, 2, 3]), it => !(it % 2)), 2, 'basic functionality'); + find.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => find.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => find.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => find.call([], () => { /* empty */ }), TypeError); + assert.throws(() => find.call(createIterator([1]), undefined), TypeError); + assert.throws(() => find.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => find.call(it, {}), TypeError); + assert.true(it.closed, "find doesn't close iterator on validation error"); +}); diff --git a/tests/unit-global/es.iterator.flat-map.js b/tests/unit-global/es.iterator.flat-map.js new file mode 100644 index 000000000000..cbdae680becd --- /dev/null +++ b/tests/unit-global/es.iterator.flat-map.js @@ -0,0 +1,41 @@ +import { createIterator, createIterable } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Iterator#flatMap', assert => { + const { flatMap } = Iterator.prototype; + + assert.isFunction(flatMap); + assert.arity(flatMap, 1); + assert.name(flatMap, 'flatMap'); + assert.looksNative(flatMap); + assert.nonEnumerable(Iterator.prototype, 'flatMap'); + + assert.arrayEqual( + flatMap.call(createIterator([1, [], 2, createIterable([3, 4]), [5, 6]]), it => typeof it == 'number' ? [-it] : it).toArray(), + [-1, -2, 3, 4, 5, 6], + 'basic functionality', + ); + flatMap.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + return [arg]; + }).toArray(); + + if (STRICT) { + assert.throws(() => flatMap.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => flatMap.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => flatMap.call({}, () => { /* empty */ }).next(), TypeError); + assert.throws(() => flatMap.call([], () => { /* empty */ }).next(), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), it => it).next(), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), undefined), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => flatMap.call(it, {}), TypeError); + assert.true(it.closed, "flatMap doesn't close iterator on validation error"); + // https://issues.chromium.org/issues/336839115 + assert.throws(() => flatMap.call({ next: null }, () => { /* empty */ }).next(), TypeError); +}); diff --git a/tests/unit-global/es.iterator.for-each.js b/tests/unit-global/es.iterator.for-each.js new file mode 100644 index 000000000000..6bbe58720374 --- /dev/null +++ b/tests/unit-global/es.iterator.for-each.js @@ -0,0 +1,38 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Iterator#forEach', assert => { + const { forEach } = Iterator.prototype; + + assert.isFunction(forEach); + assert.arity(forEach, 1); + assert.name(forEach, 'forEach'); + assert.looksNative(forEach); + assert.nonEnumerable(Iterator.prototype, 'forEach'); + + const array = []; + + forEach.call(createIterator([1, 2, 3]), it => array.push(it)); + + assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); + + forEach.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => forEach.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => forEach.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => forEach.call([], () => { /* empty */ }), TypeError); + assert.throws(() => forEach.call(createIterator([1]), undefined), TypeError); + assert.throws(() => forEach.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => forEach.call(it, {}), TypeError); + assert.true(it.closed, "forEach doesn't close iterator on validation error"); +}); diff --git a/tests/unit-global/es.iterator.from.js b/tests/unit-global/es.iterator.from.js new file mode 100644 index 000000000000..9992637c5261 --- /dev/null +++ b/tests/unit-global/es.iterator.from.js @@ -0,0 +1,31 @@ +import { createIterable, createIterator } from '../helpers/helpers.js'; + +const { assign } = Object; + +QUnit.test('Iterator.from', assert => { + const { from } = Iterator; + + assert.isFunction(from); + assert.arity(from, 1); + assert.name(from, 'from'); + assert.looksNative(from); + assert.nonEnumerable(Iterator, 'from'); + + assert.true(Iterator.from(createIterator([1, 2, 3])) instanceof Iterator, 'proxy, iterator'); + + assert.true(Iterator.from(createIterable([1, 2, 3])) instanceof Iterator, 'proxy, iterable'); + + assert.arrayEqual(Iterator.from(createIterable([1, 2, 3])).toArray(), [1, 2, 3], 'just a proxy'); + + assert.throws(() => from(undefined), TypeError); + assert.throws(() => from(null), TypeError); + assert.throws(() => from({}).next(), TypeError); + assert.throws(() => from(assign(new Iterator(), { next: 42 })).next(), TypeError); + + // Should not throw when an underlying iterator's `return` method is null + // https://bugs.webkit.org/show_bug.cgi?id=288714 + const iterator = createIterator([], { return: null }); + const result = from(iterator).return('ignored'); + assert.true(result.done, 'iterator with null next #1'); + assert.strictEqual(result.value, undefined, 'iterator with null next #2'); +}); diff --git a/tests/unit-global/es.iterator.map.js b/tests/unit-global/es.iterator.map.js new file mode 100644 index 000000000000..b2ba6344d01d --- /dev/null +++ b/tests/unit-global/es.iterator.map.js @@ -0,0 +1,35 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Iterator#map', assert => { + const { map } = Iterator.prototype; + + assert.isFunction(map); + assert.arity(map, 1); + assert.name(map, 'map'); + assert.looksNative(map); + assert.nonEnumerable(Iterator.prototype, 'map'); + + assert.arrayEqual(map.call(createIterator([1, 2, 3]), it => it ** 2).toArray(), [1, 4, 9], 'basic functionality'); + map.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }).toArray(); + + if (STRICT) { + assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => map.call({}, () => { /* empty */ }).next(), TypeError); + assert.throws(() => map.call([], () => { /* empty */ }).next(), TypeError); + assert.throws(() => map.call(createIterator([1]), undefined), TypeError); + assert.throws(() => map.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => map.call(it, {}), TypeError); + assert.true(it.closed, "map doesn't close iterator on validation error"); + // https://issues.chromium.org/issues/336839115 + assert.throws(() => map.call({ next: null }, () => { /* empty */ }).next(), TypeError); +}); diff --git a/tests/unit-global/es.iterator.reduce.js b/tests/unit-global/es.iterator.reduce.js new file mode 100644 index 000000000000..392391586344 --- /dev/null +++ b/tests/unit-global/es.iterator.reduce.js @@ -0,0 +1,37 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Iterator#reduce', assert => { + const { reduce } = Iterator.prototype; + + assert.isFunction(reduce); + assert.arity(reduce, 1); + assert.name(reduce, 'reduce'); + assert.looksNative(reduce); + assert.nonEnumerable(Iterator.prototype, 'reduce'); + + assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1), 7, 'basic functionality'); + assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b), 6, 'basic functionality, no init'); + reduce.call(createIterator([2]), function (a, b, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 3, 'arguments length'); + assert.same(a, 1, 'argument 1'); + assert.same(b, 2, 'argument 2'); + assert.same(counter, 0, 'counter'); + }, 1); + + if (STRICT) { + assert.throws(() => reduce.call(undefined, (a, b) => a + b, 0), TypeError); + assert.throws(() => reduce.call(null, (a, b) => a + b, 0), TypeError); + } + + assert.throws(() => reduce.call({}, (a, b) => a + b, 0), TypeError); + assert.throws(() => reduce.call([], (a, b) => a + b, 0), TypeError); + assert.throws(() => reduce.call(createIterator([1]), undefined, 1), TypeError); + assert.throws(() => reduce.call(createIterator([1]), null, 1), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => reduce.call(it, {}, 1), TypeError); + assert.true(it.closed, "reduce doesn't close iterator on validation error"); + assert.notThrows(() => reduce.call(createIterator([]), () => false, undefined), 'fails on undefined initial parameter'); + assert.same(reduce.call(createIterator([]), () => false, undefined), undefined, 'incorrect result on undefined initial parameter'); +}); diff --git a/tests/unit-global/es.iterator.some.js b/tests/unit-global/es.iterator.some.js new file mode 100644 index 000000000000..6eeb1825da5c --- /dev/null +++ b/tests/unit-global/es.iterator.some.js @@ -0,0 +1,34 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('Iterator#some', assert => { + const { some } = Iterator.prototype; + + assert.isFunction(some); + assert.arity(some, 1); + assert.name(some, 'some'); + assert.looksNative(some); + assert.nonEnumerable(Iterator.prototype, 'some'); + + assert.true(some.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #1'); + assert.false(some.call(createIterator([1, 2, 3]), it => typeof it == 'string'), 'basic functionality #2'); + some.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => some.call([], () => { /* empty */ }), TypeError); + assert.throws(() => some.call(createIterator([1]), undefined), TypeError); + assert.throws(() => some.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => some.call(it, {}), TypeError); + assert.true(it.closed, "some doesn't close iterator on validation error"); +}); diff --git a/tests/unit-global/es.iterator.take.js b/tests/unit-global/es.iterator.take.js new file mode 100644 index 000000000000..f9fc5a3f2562 --- /dev/null +++ b/tests/unit-global/es.iterator.take.js @@ -0,0 +1,29 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('Iterator#take', assert => { + const { take } = Iterator.prototype; + + assert.isFunction(take); + assert.arity(take, 1); + assert.name(take, 'take'); + assert.looksNative(take); + assert.nonEnumerable(Iterator.prototype, 'take'); + + assert.arrayEqual(take.call(createIterator([1, 2, 3]), 2).toArray(), [1, 2], 'basic functionality'); + assert.arrayEqual(take.call(createIterator([1, 2, 3]), 1.5).toArray(), [1], 'float'); + assert.arrayEqual(take.call(createIterator([1, 2, 3]), 4).toArray(), [1, 2, 3], 'big'); + assert.arrayEqual(take.call(createIterator([1, 2, 3]), 0).toArray(), [], 'zero'); + + if (STRICT) { + assert.throws(() => take.call(undefined, 1), TypeError); + assert.throws(() => take.call(null, 1), TypeError); + } + + assert.throws(() => take.call({}, 1).next(), TypeError); + assert.throws(() => take.call([], 1).next(), TypeError); + assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => take.call(it, NaN), RangeError, 'NaN'); + assert.true(it.closed, "take doesn't close iterator on validation error"); +}); diff --git a/tests/unit-global/es.iterator.to-array.js b/tests/unit-global/es.iterator.to-array.js new file mode 100644 index 000000000000..61c173901b5d --- /dev/null +++ b/tests/unit-global/es.iterator.to-array.js @@ -0,0 +1,28 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterable, createIterator } from '../helpers/helpers.js'; + +QUnit.test('Iterator#toArray', assert => { + const { toArray } = Iterator.prototype; + + assert.isFunction(toArray); + assert.arity(toArray, 0); + assert.name(toArray, 'toArray'); + assert.looksNative(toArray); + assert.nonEnumerable(Iterator.prototype, 'toArray'); + + assert.arrayEqual([1, 2, 3].values().toArray(), [1, 2, 3]); + assert.arrayEqual(new Set([1, 2, 3]).values().toArray(), [1, 2, 3]); + + assert.arrayEqual(Iterator.from('123').toArray(), ['1', '2', '3']); + assert.arrayEqual(Iterator.from(createIterable([1, 2, 3])).toArray(), [1, 2, 3]); + + assert.arrayEqual(toArray.call(createIterator([1, 2, 3])), [1, 2, 3]); + + if (STRICT) { + assert.throws(() => toArray.call(undefined), TypeError); + assert.throws(() => toArray.call(null), TypeError); + } + + assert.throws(() => toArray.call({}), TypeError); + assert.throws(() => toArray.call([]), TypeError); +}); diff --git a/tests/unit-global/es.json.is-raw-json.js b/tests/unit-global/es.json.is-raw-json.js new file mode 100644 index 000000000000..13a6cf722e18 --- /dev/null +++ b/tests/unit-global/es.json.is-raw-json.js @@ -0,0 +1,21 @@ +QUnit.test('JSON.rawJSON', assert => { + const { isRawJSON, rawJSON } = JSON; + const { freeze } = Object; + + assert.isFunction(isRawJSON); + assert.arity(isRawJSON, 1); + assert.name(isRawJSON, 'isRawJSON'); + assert.looksNative(isRawJSON); + + assert.true(isRawJSON(rawJSON(1)), 'raw1'); + assert.true(isRawJSON(rawJSON(null)), 'raw2'); + assert.false(isRawJSON(freeze({ rawJSON: '123' })), 'fake'); + assert.false(isRawJSON(undefined), 'undefined'); + assert.false(isRawJSON(null), 'null'); + assert.false(isRawJSON(1), 'number'); + assert.false(isRawJSON('qwe'), 'string'); + assert.false(isRawJSON(true), 'bool'); + assert.false(isRawJSON(Symbol('JSON.isRawJSON test')), 'sym'); + assert.false(isRawJSON({}), 'object'); + assert.false(isRawJSON([]), 'array'); +}); diff --git a/tests/unit-global/es.json.parse.js b/tests/unit-global/es.json.parse.js new file mode 100644 index 000000000000..1eaf51d50910 --- /dev/null +++ b/tests/unit-global/es.json.parse.js @@ -0,0 +1,258 @@ +// Some tests adopted from Test262 project and governed by the BSD license. +// Copyright (c) 2012 Ecma International. All rights reserved. +/* eslint-disable unicorn/escape-case -- testing */ +import { DESCRIPTORS, REDEFINABLE_PROTO } from '../helpers/constants.js'; + +QUnit.test('JSON.parse', assert => { + const { parse } = JSON; + const { defineProperty, hasOwn, keys } = Object; + assert.isFunction(parse); + assert.arity(parse, 2); + assert.name(parse, 'parse'); + assert.looksNative(parse); + + for (const [reviver, note] of [[undefined, 'without reviver'], [(key, value) => value, 'with reviver']]) { + assert.throws(() => parse('12\t\r\n 34', reviver), SyntaxError, `15.12.1.1-0-1 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.throws(() => parse('\u000b1234', reviver), SyntaxError, `15.12.1.1-0-2 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\u000c1234', reviver), SyntaxError, `15.12.1.1-0-3 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\u00a01234', reviver), SyntaxError, `15.12.1.1-0-4 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\u200b1234', reviver), SyntaxError, `15.12.1.1-0-5 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\ufeff1234', reviver), SyntaxError, `15.12.1.1-0-6 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\u2028\u20291234', reviver), SyntaxError, `15.12.1.1-0-8 ${ note }`); // should produce a syntax error + assert.notThrows(() => parse('\t\r \n{\t\r \n"property"\t\r \n:\t\r \n{\t\r \n}\t\r \n,\t\r \n"prop2"\t\r \n:\t\r \n' + + '[\t\r \ntrue\t\r \n,\t\r \nnull\t\r \n,123.456\t\r \n]\t\r \n}\t\r \n', reviver), SyntaxError, `15.12.1.1-0-9 ${ note }`); // should JSON parse without error + assert.same(parse('\t1234', reviver), 1234, `15.12.1.1-g1-1-1 ${ note }`); // ' should be ignored' + assert.throws(() => parse('12\t34', reviver), SyntaxError, `15.12.1.1-g1-1-2 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.same(parse('\r1234', reviver), 1234, `15.12.1.1-g1-2-1 ${ note }`); // ' should be ignored' + assert.throws(() => parse('12\r34', reviver), SyntaxError, `15.12.1.1-g1-2-2 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.same(parse('\n1234', reviver), 1234, `15.12.1.1-g1-3-1 ${ note }`); // ' should be ignored' + assert.throws(() => parse('12\n34', reviver), SyntaxError, `15.12.1.1-g1-3-2 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.same(parse(' 1234', reviver), 1234, `15.12.1.1-g1-4-1 ${ note }`); // ' should be ignored' + assert.throws(() => parse('12 34', reviver), SyntaxError, `15.12.1.1-g1-4-2 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.same(parse('"abc"', reviver), 'abc', `15.12.1.1-g2-1 ${ note }`); + assert.throws(() => parse("'abc'", reviver), SyntaxError, `15.12.1.1-g2-2 ${ note }`); + assert.throws(() => parse('\\u0022abc\\u0022', reviver), SyntaxError, `15.12.1.1-g2-3 ${ note }`); + assert.throws(() => parse('"abc\'', reviver), SyntaxError, `15.12.1.1-g2-4 ${ note }`); + assert.same(parse('""', reviver), '', `15.12.1.1-g2-5 ${ note }`); + // invalid string characters should produce a syntax error + assert.throws(() => parse('"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007"', reviver), SyntaxError, `15.12.1.1-g4-1 ${ note }`); + assert.throws(() => parse('"\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f"', reviver), SyntaxError, `15.12.1.1-g4-2 ${ note }`); + assert.throws(() => parse('"\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017"', reviver), SyntaxError, `15.12.1.1-g4-3 ${ note }`); + assert.throws(() => parse('"\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f"', reviver), SyntaxError, `15.12.1.1-g4-4 ${ note }`); + assert.same(parse('"\\u0058"', reviver), 'X', `15.12.1.1-g5-1 ${ note }`); + assert.throws(() => parse('"\\u005"', reviver), SyntaxError, `15.12.1.1-g5-2 ${ note }`); + assert.throws(() => parse('"\\u0X50"', reviver), SyntaxError, `15.12.1.1-g5-3 ${ note }`); + assert.same(parse('"\\/"', reviver), '/', `15.12.1.1-g6-1 ${ note }`); + assert.same(parse('"\\\\"', reviver), '\\', `15.12.1.1-g6-2 ${ note }`); + assert.same(parse('"\\b"', reviver), '\b', `15.12.1.1-g6-3 ${ note }`); + assert.same(parse('"\\f"', reviver), '\f', `15.12.1.1-g6-4 ${ note }`); + assert.same(parse('"\\n"', reviver), '\n', `15.12.1.1-g6-5 ${ note }`); + assert.same(parse('"\\r"', reviver), '\r', `15.12.1.1-g6-6 ${ note }`); + assert.same(parse('"\\t"', reviver), '\t', `15.12.1.1-g6-7 ${ note }`); + + const nullChars = [ + '"\u0000"', + '"\u0001"', + '"\u0002"', + '"\u0003"', + '"\u0004"', + '"\u0005"', + '"\u0006"', + '"\u0007"', + '"\u0008"', + '"\u0009"', + '"\u000A"', + '"\u000B"', + '"\u000C"', + '"\u000D"', + '"\u000E"', + '"\u000F"', + '"\u0010"', + '"\u0011"', + '"\u0012"', + '"\u0013"', + '"\u0014"', + '"\u0015"', + '"\u0016"', + '"\u0017"', + '"\u0018"', + '"\u0019"', + '"\u001A"', + '"\u001B"', + '"\u001C"', + '"\u001D"', + '"\u001E"', + '"\u001F"', + ]; + + for (let i = 0; i < nullChars.length; i++) { + assert.throws(() => parse(`{${ nullChars[i] } : "John" }`, reviver), SyntaxError, `15.12.2-2-1-${ i } ${ note }`); + assert.throws(() => parse(`{${ nullChars[i] }name : "John" }`, reviver), SyntaxError, `15.12.2-2-2-${ i } ${ note }`); + assert.throws(() => parse(`{name${ nullChars[i] } : "John" }`, reviver), SyntaxError, `15.12.2-2-3-${ i } ${ note }`); + assert.throws(() => parse(`{${ nullChars[i] }name${ nullChars[i] } : "John" }`, reviver), SyntaxError, `15.12.2-2-4-${ i } ${ note }`); + assert.throws(() => parse(`{na${ nullChars[i] }me : "John" }`, reviver), SyntaxError, `15.12.2-2-5-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : ${ nullChars[i] } }`, reviver), SyntaxError, `15.12.2-2-6-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : ${ nullChars[i] }John }`, reviver), SyntaxError, `15.12.2-2-7-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : John${ nullChars[i] } }`, reviver), SyntaxError, `15.12.2-2-8-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : ${ nullChars[i] }John${ nullChars[i] } }`, reviver), SyntaxError, `15.12.2-2-9-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : Jo${ nullChars[i] }hn }`, reviver), SyntaxError, `15.12.2-2-10-${ i } ${ note }`); + } + + if (REDEFINABLE_PROTO) { + // eslint-disable-next-line no-proto -- testing + assert.same(parse('{ "__proto__": 1, "__proto__": 2 }', reviver).__proto__, 2, `duplicate proto ${ note }`); + } + + assert.throws(() => parse('\u16801', reviver), SyntaxError, `15.12.1.1-0-7-1 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u180e1', reviver), SyntaxError, `15.12.1.1-0-7-2 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20001', reviver), SyntaxError, `15.12.1.1-0-7-3 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20011', reviver), SyntaxError, `15.12.1.1-0-7-4 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20021', reviver), SyntaxError, `15.12.1.1-0-7-5 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20031', reviver), SyntaxError, `15.12.1.1-0-7-6 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20041', reviver), SyntaxError, `15.12.1.1-0-7-7 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20051', reviver), SyntaxError, `15.12.1.1-0-7-8 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20061', reviver), SyntaxError, `15.12.1.1-0-7-9 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20071', reviver), SyntaxError, `15.12.1.1-0-7-10 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20081', reviver), SyntaxError, `15.12.1.1-0-7-11 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20091', reviver), SyntaxError, `15.12.1.1-0-7-12 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u200a1', reviver), SyntaxError, `15.12.1.1-0-7-13 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u202f1', reviver), SyntaxError, `15.12.1.1-0-7-14 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u205f1', reviver), SyntaxError, `15.12.1.1-0-7-15 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u30001', reviver), SyntaxError, `15.12.1.1-0-7-16 ${ note }`); // invalid whitespace + + assert.same(parse('-0', reviver), -0, `negative-zero-1 ${ note }`); + assert.same(parse(' \n-0', reviver), -0, `negative-zero-2 ${ note }`); + assert.same(parse('-0 \t', reviver), -0, `negative-zero-3 ${ note }`); + assert.same(parse('\n\t -0\n ', reviver), -0, `negative-zero-4 ${ note }`); + assert.same(parse(-0, reviver), 0, `negative-zero-5 ${ note }`); + + assert.throws(() => parse(undefined, reviver), SyntaxError, `undefined ${ note }`); + assert.throws(() => parse(Symbol('JSON.parse test'), reviver), TypeError, `symbol ${ note }`); + assert.same(parse(null, reviver), null, `null ${ note }`); + assert.same(parse(false, reviver), false, `false ${ note }`); + assert.same(parse(true, reviver), true, `true ${ note }`); + assert.same(parse(0, reviver), 0, `0 ${ note }`); + assert.same(parse(3.14, reviver), 3.14, `3.14 ${ note }`); + + assert.same(parse({ + toString() { + return '"string"'; + }, + valueOf() { + return '"default_or_number"'; + }, + }, reviver), 'string', `text-object ${ note }`); + + assert.throws(() => parse({ + toString: null, + valueOf() { + throw new EvalError('t262'); + }, + }, reviver), EvalError, `text-object-abrupt-1 ${ note }`); + + assert.throws(() => parse({ + toString() { + throw new EvalError('t262'); + }, + }, reviver), EvalError, `text-object-abrupt-2 ${ note }`); + } + + // eslint-disable-next-line no-extend-native -- testing + Array.prototype[1] = 3; + const arr1 = parse('[1, 2]', function (key, value) { + if (key === '0') delete this[1]; + return value; + }); + delete Array.prototype[1]; + assert.same(arr1[0], 1, 'reviver-array-get-prop-from-prototype-1'); + assert.true(hasOwn(arr1, '1'), 'reviver-array-get-prop-from-prototype-2'); + assert.same(arr1[1], 3, 'reviver-array-get-prop-from-prototype-3'); + + // eslint-disable-next-line no-extend-native -- testing + Object.prototype.b = 3; + const obj1 = parse('{"a": 1, "b": 2}', function (key, value) { + if (key === 'a') delete this.b; + return value; + }); + delete Object.prototype.b; + assert.same(obj1.a, 1, 'reviver-object-get-prop-from-prototype-1'); + assert.true(hasOwn(obj1, 'b'), 'reviver-object-get-prop-from-prototype-2'); + assert.same(obj1.b, 3, 'reviver-object-get-prop-from-prototype-3'); + + if (DESCRIPTORS) { + const arr2 = parse('[1, 2]', function (key, value) { + if (key === '0') defineProperty(this, '1', { configurable: false }); + if (key === '1') return 22; + return value; + }); + assert.same(arr2[0], 1, 'reviver-array-non-configurable-prop-create-1'); + assert.same(arr2[1], 2, 'reviver-array-non-configurable-prop-create-2'); + + const arr3 = parse('[1, 2]', function (key, value) { + if (key === '0') defineProperty(this, '1', { configurable: false }); + if (key === '1') return; + return value; + }); + assert.same(arr3[0], 1, 'reviver-array-non-configurable-prop-delete-1'); + assert.true(hasOwn(arr3, '1'), 'reviver-array-non-configurable-prop-delete-2'); + assert.same(arr3[1], 2, 'reviver-array-non-configurable-prop-delete-3'); + + const obj2 = parse('{"a": 1, "b": 2}', function (key, value) { + if (key === 'a') defineProperty(this, 'b', { configurable: false }); + if (key === 'b') return 22; + return value; + }); + assert.same(obj2.a, 1, 'reviver-object-non-configurable-prop-create-1'); + assert.same(obj2.b, 2, 'reviver-object-non-configurable-prop-create-2'); + + const obj3 = parse('{"a": 1, "b": 2}', function (key, value) { + if (key === 'a') defineProperty(this, 'b', { configurable: false }); + if (key === 'b') return; + return value; + }); + assert.same(obj3.a, 1, 'reviver-object-non-configurable-prop-delete-1'); + assert.true(hasOwn(obj3, 'b'), 'reviver-object-non-configurable-prop-delete-2'); + assert.same(obj3.b, 2, 'reviver-object-non-configurable-prop-delete-3'); + + assert.throws(() => parse('[0,0]', function () { + defineProperty(this, '1', { get: () => { throw new EvalError('t262'); } }); + }), EvalError, 'reviver-get-name-err'); + } + + assert.throws(() => parse('0', () => { throw new EvalError('t262'); }), EvalError, 'reviver-call-err'); + + // FF20- enumeration order issue + if (keys({ k: 1, 2: 3 })[0] === '2') { + const calls = []; + parse('{"p1":0,"p2":0,"p1":0,"2":0,"1":0}', (name, val) => { + calls.push(name); + return val; + }); + // The empty string is the _rootName_ in JSON.parse + assert.arrayEqual(calls, ['1', '2', 'p1', 'p2', ''], 'reviver-call-order'); + } + + assert.throws(() => parse(), SyntaxError, 'no args'); +}); + +QUnit.test('JSON.parse source access', assert => { + const { parse } = JSON; + const spy = (k, v, { source: $source }) => source = $source; + let source; + parse('1234', spy); + assert.same(source, '1234', '1234'); + parse('"1234"', spy); + assert.same(source, '"1234"', '"1234"'); + parse('null', spy); + assert.same(source, 'null', 'null'); + parse('true', spy); + assert.same(source, 'true', 'true'); + parse('false', spy); + assert.same(source, 'false', 'false'); + parse('{}', spy); + assert.same(source, undefined, '{}'); + parse('[]', spy); + assert.same(source, undefined, '[]'); + parse('9007199254740993', spy); + assert.same(source, '9007199254740993', '9007199254740993'); +}); diff --git a/tests/unit-global/es.json.raw-json.js b/tests/unit-global/es.json.raw-json.js new file mode 100644 index 000000000000..f7b261805c62 --- /dev/null +++ b/tests/unit-global/es.json.raw-json.js @@ -0,0 +1,27 @@ +import { FREEZING } from '../helpers/constants.js'; + +QUnit.test('JSON.rawJSON', assert => { + const { rawJSON, stringify } = JSON; + const { isFrozen, hasOwn } = Object; + + assert.isFunction(rawJSON); + assert.arity(rawJSON, 1); + assert.name(rawJSON, 'rawJSON'); + assert.looksNative(rawJSON); + + const raw = rawJSON(1); + assert.true(hasOwn(raw, 'rawJSON'), 'own rawJSON'); + assert.same(raw.rawJSON, '1', 'is string 1'); + if (FREEZING) assert.true(isFrozen(raw), 'frozen'); + + assert.same(stringify(rawJSON('"qwe"')), '"qwe"'); + assert.same(stringify(rawJSON('null')), 'null'); + assert.same(stringify(rawJSON('true')), 'true'); + assert.same(stringify(rawJSON('9007199254740993')), '9007199254740993'); + assert.same(stringify({ key: rawJSON('9007199254740993') }), '{"key":9007199254740993}'); + assert.same(stringify([rawJSON('9007199254740993')]), '[9007199254740993]'); + + assert.throws(() => rawJSON('"qwe'), SyntaxError, 'invalid 1'); + assert.throws(() => rawJSON({}), SyntaxError, 'invalid 2'); + assert.throws(() => rawJSON(''), SyntaxError, 'invalid 3'); +}); diff --git a/tests/unit-global/es.json.stringify.js b/tests/unit-global/es.json.stringify.js new file mode 100644 index 000000000000..e97a414849c0 --- /dev/null +++ b/tests/unit-global/es.json.stringify.js @@ -0,0 +1,531 @@ +// Some tests adopted from Test262 project and governed by the BSD license. +// Copyright (c) 2012 Ecma International. All rights reserved. +/* eslint-disable es/no-bigint,unicorn/no-hex-escape -- testing */ +import { DESCRIPTORS, GLOBAL } from '../helpers/constants.js'; + +if (GLOBAL.JSON?.stringify) { + QUnit.test('JSON.stringify', assert => { + const { stringify } = JSON; + const { defineProperty, keys, values } = Object; + + assert.isFunction(stringify); + assert.arity(stringify, 3); + assert.name(stringify, 'stringify'); + assert.looksNative(stringify); + + assert.same(stringify({ a: 1, b: 2 }, []), '{}', 'replacer-array-empty-1'); + assert.same(stringify({ a: 1, b: { c: 2 } }, []), '{}', 'replacer-array-empty-2'); + assert.same(stringify([1, { a: 2 }], []), '[1,{}]', 'replacer-array-empty-3'); + + const num1 = new Number(10); + num1.toString = () => 'toString'; + num1.valueOf = () => { throw new EvalError('should not be called'); }; + assert.same(stringify({ + 10: 1, + toString: 2, + valueOf: 3, + }, [num1]), '{"toString":2}', 'replacer-array-number-object'); + + const obj1 = { + 0: 0, + 1: 1, + '-4': 2, + 0.3: 3, + '-Infinity': 4, + NaN: 5, + }; + assert.same(stringify(obj1, [ + -0, + 1, + -4, + 0.3, + -Infinity, + NaN, + ]), stringify(obj1), 'replacer-array-number'); + + const str1 = new String('str'); + str1.toString = () => 'toString'; + str1.valueOf = () => { throw new EvalError('should not be called'); }; + assert.same(stringify({ + str: 1, + toString: 2, + valueOf: 3, + }, [str1]), '{"toString":2}', 'replacer-array-string-object'); + + assert.same(stringify({ undefined: 1 }, [undefined]), '{}', 'replacer-array-undefined-1'); + // eslint-disable-next-line no-sparse-arrays -- testing + assert.same(stringify({ key: 1, undefined: 2 }, [,,,]), '{}', 'replacer-array-undefined-2'); + const sparse = Array(3); + sparse[1] = 'key'; + assert.same(stringify({ undefined: 1, key: 2 }, sparse), '{"key":2}', 'replacer-array-undefined-3'); + + assert.throws(() => stringify({}, () => { throw new EvalError('should not be called'); }), EvalError, 'replacer-function-abrupt'); + + const calls = []; + const b1 = [1, 2]; + const b2 = { c1: true, c2: false }; + const a1 = { + b1, + b2: { + toJSON() { return b2; }, + }, + }; + const obj2 = { a1, a2: 'a2' }; + assert.same(stringify(obj2, function (key, value) { + if (key !== '') calls.push([this, key, value]); + return value; + }), stringify(obj2), 'replacer-function-arguments-1'); + assert.arrayEqual(calls[0], [obj2, 'a1', a1], 'replacer-function-arguments-2'); + assert.arrayEqual(calls[1], [a1, 'b1', b1], 'replacer-function-arguments-3'); + assert.arrayEqual(calls[2], [b1, '0', 1], 'replacer-function-arguments-4'); + assert.arrayEqual(calls[3], [b1, '1', 2], 'replacer-function-arguments-5'); + assert.arrayEqual(calls[4], [a1, 'b2', b2], 'replacer-function-arguments-6'); + assert.arrayEqual(calls[5], [b2, 'c1', true], 'replacer-function-arguments-7'); + assert.arrayEqual(calls[6], [b2, 'c2', false], 'replacer-function-arguments-8'); + assert.arrayEqual(calls[7], [obj2, 'a2', 'a2'], 'replacer-function-arguments-9'); + + const circular1 = [{}]; + assert.throws(() => stringify(circular1, () => circular1), TypeError, 'replacer-function-array-circular'); + + const direct1 = { prop: {} }; + assert.throws(() => stringify(direct1, () => direct1), TypeError, 'replacer-function-object-circular-1'); + const indirect1 = { p1: { p2: {} } }; + assert.throws(() => stringify(indirect1, (key, value) => key === 'p2' ? indirect1 : value), TypeError, 'replacer-function-object-circular-2'); + + assert.same(stringify(1, () => { /* empty */ }), undefined, 'replacer-function-result-undefined-1'); + assert.same(stringify([1], () => { /* empty */ }), undefined, 'replacer-function-result-undefined-2'); + assert.same(stringify({ prop: 1 }, () => { /* empty */ }), undefined, 'replacer-function-result-undefined-3'); + assert.same(stringify([1], (key, value) => value === 1 ? undefined : value), '[null]', 'replacer-function-result-undefined-4'); + assert.same(stringify({ prop: 1 }, (key, value) => value === 1 ? undefined : value), '{}', 'replacer-function-result-undefined-5'); + assert.same(stringify({ a: { b: [1] } }, (key, value) => value === 1 ? undefined : value), '{"a":{"b":[null]}}', 'replacer-function-result-undefined-6'); + + assert.same(stringify(null, (key, value) => { + assert.same(value, null); + switch (key) { + case '': return { a1: null, a2: null }; + case 'a1': return { b1: null, b2: null }; + case 'a2': return 'a2'; + case 'b1': return [null, null]; + case 'b2': return { c1: null, c2: null }; + case '0': return 1; + case '1': return 2; + case 'c1': return true; + case 'c2': return false; + } throw new EvalError('unreachable'); + }), stringify({ + a1: { + b1: [1, 2], + b2: { + c1: true, + c2: false, + }, + }, + a2: 'a2', + }), 'replacer-function-result'); + + assert.same(stringify({ + toJSON() { return 'toJSON'; }, + }, (_key, value) => `${ value }|replacer`), '"toJSON|replacer"', 'replacer-function-tojson-1'); + + assert.same(stringify({ + toJSON() { return { calls: 'toJSON' }; }, + }, (_key, value) => { + if (value && value.calls) value.calls += '|replacer'; + return value; + }), '{"calls":"toJSON|replacer"}', 'replacer-function-tojson-2'); + + const obj4 = { key: [1] }; + const json1 = '{"key":[1]}'; + assert.same(stringify(obj4, {}), json1, 'replacer-wrong-type-1'); + assert.same(stringify(obj4, new String('str')), json1, 'replacer-wrong-type-2'); + assert.same(stringify(obj4, new Number(6.1)), json1, 'replacer-wrong-type-3'); + assert.same(stringify(obj4, null), json1, 'replacer-wrong-type-4'); + assert.same(stringify(obj4, ''), json1, 'replacer-wrong-type-5'); + assert.same(stringify(obj4, 0), json1, 'replacer-wrong-type-6'); + assert.same(stringify(obj4, Symbol('stringify replacer test')), json1, 'replacer-wrong-type-7'); + assert.same(stringify(obj4, true), json1, 'replacer-wrong-type-8'); + + const obj5 = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', + }; + + assert.same(stringify(obj5, null, -1.99999), stringify(obj5, null, -1), 'space-number-float-1'); + assert.same(stringify(obj5, null, new Number(5.11111)), stringify(obj5, null, 5), 'space-number-float-2'); + assert.same(stringify(obj5, null, 6.99999), stringify(obj5, null, 6), 'space-number-float-3'); + + assert.same(stringify(obj5, null, new Number(1)), stringify(obj5, null, 1), 'space-number-object-1'); + const num2 = new Number(1); + num2.toString = () => { throw new EvalError('should not be called'); }; + num2.valueOf = () => 3; + assert.same(stringify(obj5, null, num2), stringify(obj5, null, 3), 'space-number-object-2'); + const abrupt1 = new Number(4); + abrupt1.toString = () => { throw new EvalError('t262'); }; + abrupt1.valueOf = () => { throw new EvalError('t262'); }; + assert.throws(() => stringify(obj5, null, abrupt1), EvalError, 'space-number-object-3'); + + assert.same(stringify(obj5, null, new Number(-5)), stringify(obj5, null, 0), 'space-number-range-1'); + assert.same(stringify(obj5, null, 10), stringify(obj5, null, 100), 'space-number-range-2'); + + assert.same(stringify(obj5, null, 0), stringify(obj5, null, ''), 'space-number-1'); + assert.same(stringify(obj5, null, 4), stringify(obj5, null, ' '), 'space-number-2'); + + assert.same(stringify(obj5, null, new String('xxx')), stringify(obj5, null, 'xxx'), 'space-string-object-1'); + const str2 = new String('xxx'); + str2.toString = () => '---'; + str2.valueOf = () => { throw new EvalError('should not be called'); }; + assert.same(stringify(obj5, null, str2), stringify(obj5, null, '---'), 'space-string-object-2'); + const abrupt2 = new String('xxx'); + abrupt2.toString = () => { throw new EvalError('t262'); }; + abrupt2.valueOf = () => { throw new EvalError('t262'); }; + assert.throws(() => stringify(obj5, null, abrupt2), EvalError, 'space-string-object-3'); + + assert.same(stringify(obj5, null, '0123456789xxxxxxxxx'), stringify(obj5, null, '0123456789'), 'space-string-range'); + + assert.same(stringify(obj5, null, ''), stringify(obj5), 'space-string-1'); + assert.same(stringify(obj5, null, ' '), `{ + "a1": { + "b1": [ + 1, + 2, + 3, + 4 + ], + "b2": { + "c1": 1, + "c2": 2 + } + }, + "a2": "a2" +}`, 'space-string-2'); + + assert.same(stringify(obj5), stringify(obj5, null, null), 'space-wrong-type-1'); + assert.same(stringify(obj5), stringify(obj5, null, true), 'space-wrong-type-2'); + assert.same(stringify(obj5), stringify(obj5, null, new Boolean(false)), 'space-wrong-type-3'); + assert.same(stringify(obj5), stringify(obj5, null, Symbol('stringify space test')), 'space-wrong-type-4'); + assert.same(stringify(obj5), stringify(obj5, null, {}), 'space-wrong-type-5'); + + const direct2 = []; + direct2.push(direct2); + assert.throws(() => stringify(direct2), TypeError, 'value-array-circular-1'); + const indirect2 = []; + indirect2.push([[indirect2]]); + assert.throws(() => stringify(indirect2), TypeError, 'value-array-circular-2'); + + if (typeof BigInt == 'function') { + assert.same(stringify(BigInt(0), (k, v) => typeof v === 'bigint' ? 'bigint' : v), '"bigint"', 'value-bigint-replacer-1'); + assert.same(stringify({ x: BigInt(0) }, (k, v) => typeof v === 'bigint' ? 'bigint' : v), '{"x":"bigint"}', 'value-bigint-replacer-2'); + assert.throws(() => stringify(BigInt(0)), TypeError, 'value-bigint-1'); + assert.throws(() => stringify(Object(BigInt(0))), TypeError, 'value-bigint-2'); + assert.throws(() => stringify({ x: BigInt(0) }), TypeError, 'value-bigint-3'); + } + + assert.same(stringify(new Boolean(true)), 'true', 'value-boolean-object-1'); + assert.same(stringify({ + toJSON() { + return { key: new Boolean(false) }; + }, + }), '{"key":false}', 'value-boolean-object-2'); + assert.same(stringify([1], (k, v) => v === 1 ? new Boolean(true) : v), '[true]', 'value-boolean-object-3'); + + assert.same(stringify(() => { /* empty */ }), undefined, 'value-function-1'); + assert.same(stringify([() => { /* empty */ }]), '[null]', 'value-function-2'); + assert.same(stringify({ key() { /* empty */ } }), '{}', 'value-function-3'); + + assert.same(stringify(-0), '0', 'value-number-negative-zero-1'); + assert.same(stringify(['-0', 0, -0]), '["-0",0,0]', 'value-number-negative-zero-2'); + assert.same(stringify({ key: -0 }), '{"key":0}', 'value-number-negative-zero-3'); + + assert.same(stringify(Infinity), 'null', 'value-number-non-finite-1'); + assert.same(stringify({ key: -Infinity }), '{"key":null}', 'value-number-non-finite-2'); + assert.same(stringify([NaN]), '[null]', 'value-number-non-finite-3'); + + assert.same(stringify(new Number(8.5)), '8.5', 'value-number-object-1'); + assert.same(stringify(['str'], (key, value) => { + if (value === 'str') { + const num = new Number(42); + num.toString = () => { throw new EvalError('should not be called'); }; + num.valueOf = () => 2; + return num; + } return value; + }), '[2]', 'value-number-object-2'); + assert.throws(() => stringify({ + key: { + toJSON() { + const num = new Number(3.14); + num.toString = () => { throw new EvalError('t262'); }; + num.valueOf = () => { throw new EvalError('t262'); }; + return num; + }, + }, + }), EvalError, 'value-number-object-3'); + + const direct3 = { prop: null }; + direct3.prop = direct3; + assert.throws(() => stringify(direct3), TypeError, 'value-object-circular-1'); + const indirect3 = { p1: { p2: {} } }; + indirect3.p1.p2.p3 = indirect3; + assert.throws(() => stringify(indirect3), TypeError, 'value-object-circular-2'); + + assert.same(stringify(null), 'null', 'null'); + assert.same(stringify(true), 'true', 'true'); + assert.same(stringify(false), 'false', 'false'); + assert.same(stringify('str'), '"str"', '"str"'); + assert.same(stringify(123), '123', '123'); + assert.same(stringify(undefined), undefined, 'undefined'); + + const charToJson = { + '"': '\\"', + '\\': '\\\\', + '\x00': '\\u0000', + '\x01': '\\u0001', + '\x02': '\\u0002', + '\x03': '\\u0003', + '\x04': '\\u0004', + '\x05': '\\u0005', + '\x06': '\\u0006', + '\x07': '\\u0007', + '\x08': '\\b', + '\x09': '\\t', + '\x0A': '\\n', + '\x0B': '\\u000b', + '\x0C': '\\f', + '\x0D': '\\r', + '\x0E': '\\u000e', + '\x0F': '\\u000f', + '\x10': '\\u0010', + '\x11': '\\u0011', + '\x12': '\\u0012', + '\x13': '\\u0013', + '\x14': '\\u0014', + '\x15': '\\u0015', + '\x16': '\\u0016', + '\x17': '\\u0017', + '\x18': '\\u0018', + '\x19': '\\u0019', + '\x1A': '\\u001a', + '\x1B': '\\u001b', + '\x1C': '\\u001c', + '\x1D': '\\u001d', + '\x1E': '\\u001e', + '\x1F': '\\u001f', + }; + const chars = keys(charToJson).join(''); + const charsReversed = keys(charToJson).reverse().join(''); + const jsonChars = values(charToJson).join(''); + const jsonCharsReversed = values(charToJson).reverse().join(''); + const json = stringify({ [`name${ chars }${ charsReversed }`]: `${ charsReversed }${ chars }value` }); + for (const chr in charToJson) { + const count = json.split(charToJson[chr]).length - 1; + assert.same(count, 4, `Every ASCII 0x${ chr.charCodeAt(0).toString(16) } serializes to ${ charToJson[chr] }`); + } + assert.same( + json, + `{"name${ jsonChars }${ jsonCharsReversed }":"${ jsonCharsReversed }${ jsonChars }value"}`, + 'JSON.stringify(objectUsingControlCharacters)', + ); + + assert.same(stringify('\uD834'), '"\\ud834"', 'JSON.stringify("\\uD834")'); + assert.same(stringify('\uDF06'), '"\\udf06"', 'JSON.stringify("\\uDF06")'); + assert.same(stringify('\uD834\uDF06'), '"𝌆"', 'JSON.stringify("\\uD834\\uDF06")'); + assert.same(stringify('\uD834\uD834\uDF06\uD834'), '"\\ud834𝌆\\ud834"', 'JSON.stringify("\\uD834\\uD834\\uDF06\\uD834")'); + assert.same(stringify('\uD834\uD834\uDF06\uDF06'), '"\\ud834𝌆\\udf06"', 'JSON.stringify("\\uD834\\uD834\\uDF06\\uDF06")'); + assert.same(stringify('\uDF06\uD834\uDF06\uD834'), '"\\udf06𝌆\\ud834"', 'JSON.stringify("\\uDF06\\uD834\\uDF06\\uD834")'); + assert.same(stringify('\uDF06\uD834\uDF06\uDF06'), '"\\udf06𝌆\\udf06"', 'JSON.stringify("\\uDF06\\uD834\\uDF06\\uDF06")'); + assert.same(stringify('\uDF06\uD834'), '"\\udf06\\ud834"', 'JSON.stringify("\\uDF06\\uD834")'); + assert.same(stringify('\uD834\uDF06\uD834\uD834'), '"𝌆\\ud834\\ud834"', 'JSON.stringify("\\uD834\\uDF06\\uD834\\uD834")'); + assert.same(stringify('\uD834\uDF06\uD834\uDF06'), '"𝌆𝌆"', 'JSON.stringify("\\uD834\\uDF06\\uD834\\uDF06")'); + assert.same(stringify('\uDF06\uDF06\uD834\uD834'), '"\\udf06\\udf06\\ud834\\ud834"', 'JSON.stringify("\\uDF06\\uDF06\\uD834\\uD834")'); + assert.same(stringify('\uDF06\uDF06\uD834\uDF06'), '"\\udf06\\udf06𝌆"', 'JSON.stringify("\\uDF06\\uDF06\\uD834\\uDF06")'); + + assert.same(stringify(new String('str')), '"str"', 'value-string-object-1'); + assert.same(stringify({ + key: { + toJSON() { + const str = new String('str'); + str.toString = () => 'toString'; + str.valueOf = () => { throw new EvalError('should not be called'); }; + return str; + }, + }, + }), '{"key":"toString"}', 'value-string-object-2'); + assert.throws(() => stringify([true], (key, value) => { + if (value === true) { + const str = new String('str'); + str.toString = () => { throw new EvalError('t262'); }; + str.valueOf = () => { throw new EvalError('t262'); }; + return str; + } return value; + }), 'value-string-object-3'); + + assert.throws(() => stringify({ + toJSON() { throw new EvalError('t262'); }, + }), EvalError, 'value-tojson-abrupt-1'); + + let callCount = 0; + let $this, $key; + const obj6 = { + toJSON(key) { + callCount += 1; + $this = this; + $key = key; + }, + }; + assert.same(stringify(obj6), undefined, 'value-tojson-arguments-1'); + assert.same(callCount, 1, 'value-tojson-arguments-2'); + assert.same($this, obj6, 'value-tojson-arguments-3'); + assert.same($key, '', 'value-tojson-arguments-4'); + assert.same(stringify([1, obj6, 3]), '[1,null,3]', 'value-tojson-arguments-5'); + assert.same(callCount, 2, 'value-tojson-arguments-6'); + assert.same($this, obj6, 'value-tojson-arguments-7'); + // some old implementations (like WebKit) could pass numbers as keys + // assert.same($key, '1', 'value-tojson-arguments-8'); + assert.same(stringify({ key: obj6 }), '{}', 'value-tojson-arguments-9'); + assert.same(callCount, 3, 'value-tojson-arguments-10'); + assert.same($this, obj6, 'value-tojson-arguments-11'); + assert.same($key, 'key', 'value-tojson-arguments-12'); + + const arr1 = []; + const circular2 = [arr1]; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- testing + arr1.toJSON = () => circular2; + assert.throws(() => stringify(circular2), TypeError, 'value-tojson-array-circular'); + + assert.same(stringify({ toJSON: null }), '{"toJSON":null}', 'value-tojson-not-function-1'); + assert.same(stringify({ toJSON: false }), '{"toJSON":false}', 'value-tojson-not-function-2'); + assert.same(stringify({ toJSON: [] }), '{"toJSON":[]}', 'value-tojson-not-function-3'); + assert.same(stringify({ toJSON: /re/ }), '{"toJSON":{}}', 'value-tojson-not-function-4'); + + const obj7 = {}; + const circular3 = { prop: obj7 }; + obj7.toJSON = () => circular3; + assert.throws(() => stringify(circular3), TypeError, 'value-tojson-object-circular'); + + assert.same(stringify({ toJSON() { return [false]; } }), '[false]', 'value-tojson-result-1'); + const arr2 = [true]; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- testing + arr2.toJSON = () => { /* empty */ }; + assert.same(stringify(arr2), undefined, 'value-tojson-result-2'); + const str3 = new String('str'); + // eslint-disable-next-line es/no-nonstandard-string-prototype-properties -- testing + str3.toJSON = () => null; + assert.same(stringify({ key: str3 }), '{"key":null}', 'value-tojson-result-3'); + const num3 = new Number(14); + // eslint-disable-next-line es/no-nonstandard-number-prototype-properties -- testing + num3.toJSON = () => ({ key: 7 }); + assert.same(stringify([num3]), '[{"key":7}]', 'value-tojson-result-4'); + + if (DESCRIPTORS) { + // This getter will be triggered during enumeration, but the property it adds should not be enumerated. + /* IE issue + const o = defineProperty({ + p1: 'p1', + p2: 'p2', + p3: 'p3', + }, 'add', { + enumerable: true, + get() { + o.extra = 'extra'; + return 'add'; + }, + }); + o.p4 = 'p4'; + o[2] = '2'; + o[0] = '0'; + o[1] = '1'; + delete o.p1; + delete o.p3; + o.p1 = 'p1'; + assert.same(stringify(o), '{"0":"0","1":"1","2":"2","p2":"p2","add":"add","p4":"p4","p1":"p1"}', 'property-order'); + */ + + let getCalls = 0; + assert.same(stringify(defineProperty({}, 'key', { + enumerable: true, + get() { + getCalls += 1; + return true; + }, + }), ['key', 'key']), '{"key":true}', 'replacer-array-duplicates-1'); + assert.same(getCalls, 1, 'replacer-array-duplicates-2'); + + /* old WebKit bug - however, fixing of this is not in priority + const obj3 = defineProperty({}, 'a', { + enumerable: true, + get() { + delete this.b; + return 1; + }, + }); + obj3.b = 2; + assert.same(stringify(obj3, (key, value) => { + if (key === 'b') { + assert.same(value, undefined, 'replacer-function-object-deleted-property-1'); + return ''; + } return value; + }), '{"a":1,"b":""}', 'replacer-function-object-deleted-property-2'); + */ + + assert.throws(() => stringify({ key: defineProperty(Array(1), '0', { + get() { throw new EvalError('t262'); }, + }) }), EvalError, 'value-array-abrupt'); + + assert.throws(() => stringify(defineProperty({}, 'key', { + enumerable: true, + get() { throw new EvalError('t262'); }, + })), EvalError, 'value-object-abrupt'); + + assert.throws(() => stringify(defineProperty({}, 'toJSON', { + get() { throw new EvalError('t262'); }, + })), EvalError, 'value-tojson-abrupt-2'); + } + }); + + QUnit.test('Symbols & JSON.stringify', assert => { + const { stringify } = JSON; + + const symbol1 = Symbol('symbol & stringify test 1'); + const symbol2 = Symbol('symbol & stringify test 2'); + + assert.same(stringify([ + 1, + symbol1, + false, + symbol2, + {}, + ]), '[1,null,false,null,{}]', 'array value'); + assert.same(stringify({ + symbol: symbol1, + }), '{}', 'object value'); + if (DESCRIPTORS) { + const object = { bar: 2 }; + object[symbol1] = 1; + assert.same(stringify(object), '{"bar":2}', 'object key'); + } + assert.same(stringify(symbol1), undefined, 'symbol value'); + if (typeof symbol1 == 'symbol') { + assert.same(stringify(Object(symbol1)), '{}', 'boxed symbol'); + } + assert.same(stringify(undefined, () => 42), '42', 'replacer works with top-level undefined'); + }); + + QUnit.test('Well‑formed JSON.stringify', assert => { + const { stringify } = JSON; + + assert.same(stringify({ foo: 'bar' }), '{"foo":"bar"}', 'basic'); + assert.same(stringify('\uDEAD'), '"\\udead"', 'r1'); + assert.same(stringify('\uDF06\uD834'), '"\\udf06\\ud834"', 'r2'); + assert.same(stringify('\uDF06ab\uD834'), '"\\udf06ab\\ud834"', 'r3'); + assert.same(stringify('𠮷'), '"𠮷"', 'r4'); + assert.same(stringify('\uD834\uDF06'), '"𝌆"', 'r5'); + assert.same(stringify('\uD834\uD834\uDF06'), '"\\ud834𝌆"', 'r6'); + assert.same(stringify('\uD834\uDF06\uDF06'), '"𝌆\\udf06"', 'r7'); + assert.same(stringify({ '𠮷': ['\uDF06\uD834'] }), '{"𠮷":["\\udf06\\ud834"]}', 'r8'); + }); +} diff --git a/tests/unit-global/es.map.group-by.js b/tests/unit-global/es.map.group-by.js new file mode 100644 index 000000000000..0c40c50d3cc0 --- /dev/null +++ b/tests/unit-global/es.map.group-by.js @@ -0,0 +1,27 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Map.groupBy', assert => { + const { groupBy } = Map; + const toArray = Array.from; + + assert.isFunction(groupBy); + assert.arity(groupBy, 2); + assert.name(groupBy, 'groupBy'); + assert.looksNative(groupBy); + assert.nonEnumerable(Map, 'groupBy'); + + assert.true(Map.groupBy([], it => it) instanceof Map); + + assert.deepEqual(toArray(groupBy([], it => it)), []); + assert.deepEqual(toArray(groupBy([1, 2], it => it ** 2)), [[1, [1]], [4, [2]]]); + assert.deepEqual(toArray(groupBy([1, 2, 1], it => it ** 2)), [[1, [1, 1]], [4, [2]]]); + assert.deepEqual(toArray(groupBy(createIterable([1, 2]), it => it ** 2)), [[1, [1]], [4, [2]]]); + assert.deepEqual(toArray(groupBy('qwe', it => it)), [['q', ['q']], ['w', ['w']], ['e', ['e']]], 'iterable string'); + + const element = {}; + groupBy([element], function (it, i) { + assert.same(arguments.length, 2); + assert.same(it, element); + assert.same(i, 0); + }); +}); diff --git a/tests/unit-global/es.map.js b/tests/unit-global/es.map.js new file mode 100644 index 000000000000..3bba3cd4726a --- /dev/null +++ b/tests/unit-global/es.map.js @@ -0,0 +1,467 @@ +/* eslint-disable sonarjs/no-element-overwrite -- required for testing */ + +import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants.js'; +import { createIterable, is, nativeSubclass } from '../helpers/helpers.js'; + +const Symbol = GLOBAL.Symbol || {}; +const { getOwnPropertyDescriptor, keys, getOwnPropertyNames, getOwnPropertySymbols, freeze } = Object; +const { ownKeys } = GLOBAL.Reflect || {}; + +QUnit.test('Map', assert => { + assert.isFunction(Map); + assert.arity(Map, 0); + assert.name(Map, 'Map'); + assert.looksNative(Map); + assert.true('clear' in Map.prototype, 'clear in Map.prototype'); + assert.true('delete' in Map.prototype, 'delete in Map.prototype'); + assert.true('forEach' in Map.prototype, 'forEach in Map.prototype'); + assert.true('get' in Map.prototype, 'get in Map.prototype'); + assert.true('has' in Map.prototype, 'has in Map.prototype'); + assert.true('set' in Map.prototype, 'set in Map.prototype'); + assert.true(new Map() instanceof Map, 'new Map instanceof Map'); + assert.same(new Map(createIterable([[1, 1], [2, 2], [3, 3]])).size, 3, 'Init from iterable'); + assert.same(new Map([[freeze({}), 1], [2, 3]]).size, 2, 'Support frozen objects'); + let done = false; + try { + new Map(createIterable([null, 1, 2], { + return() { + return done = true; + }, + })); + } catch { /* empty */ } + assert.true(done, '.return #throw'); + const array = []; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + new Map(array); + assert.true(done); + const object = {}; + new Map().set(object, 1); + if (DESCRIPTORS) { + const results = []; + for (const key in object) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(object), []); + } + assert.arrayEqual(getOwnPropertyNames(object), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); + if (ownKeys) assert.arrayEqual(ownKeys(object), []); + if (nativeSubclass) { + const Subclass = nativeSubclass(Map); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof Map, 'correct subclassing with native classes #2'); + assert.same(new Subclass().set(1, 2).get(1), 2, 'correct subclassing with native classes #3'); + } + + const buffer = new ArrayBuffer(8); + const map = new Map([[buffer, 8]]); + assert.true(map.has(buffer), 'works with ArrayBuffer keys'); +}); + +QUnit.test('Map#clear', assert => { + assert.isFunction(Map.prototype.clear); + assert.arity(Map.prototype.clear, 0); + assert.name(Map.prototype.clear, 'clear'); + assert.looksNative(Map.prototype.clear); + assert.nonEnumerable(Map.prototype, 'clear'); + let map = new Map(); + map.clear(); + assert.same(map.size, 0); + map = new Map(); + map.set(1, 2); + map.set(2, 3); + map.set(1, 4); + map.clear(); + assert.same(map.size, 0); + assert.false(map.has(1)); + assert.false(map.has(2)); + const frozen = freeze({}); + map = new Map(); + map.set(1, 2); + map.set(frozen, 3); + map.clear(); + assert.same(map.size, 0, 'Support frozen objects'); + assert.false(map.has(1)); + assert.false(map.has(frozen)); +}); + +QUnit.test('Map#delete', assert => { + assert.isFunction(Map.prototype.delete); + assert.arity(Map.prototype.delete, 1); + if (NATIVE) assert.name(Map.prototype.delete, 'delete'); + assert.looksNative(Map.prototype.delete); + assert.nonEnumerable(Map.prototype, 'delete'); + const object = {}; + const map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 7); + map.set(2, 5); + map.set(1, 4); + map.set(object, 9); + assert.same(map.size, 5); + assert.true(map.delete(NaN)); + assert.same(map.size, 4); + assert.false(map.delete(4)); + assert.same(map.size, 4); + map.delete([]); + assert.same(map.size, 4); + map.delete(object); + assert.same(map.size, 3); + const frozen = freeze({}); + map.set(frozen, 42); + assert.same(map.size, 4); + map.delete(frozen); + assert.same(map.size, 3); +}); + +QUnit.test('Map#forEach', assert => { + assert.isFunction(Map.prototype.forEach); + assert.arity(Map.prototype.forEach, 1); + assert.name(Map.prototype.forEach, 'forEach'); + assert.looksNative(Map.prototype.forEach); + assert.nonEnumerable(Map.prototype, 'forEach'); + let result = {}; + let count = 0; + const object = {}; + let map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 7); + map.set(2, 5); + map.set(1, 4); + map.set(object, 9); + map.forEach((value, key) => { + count++; + result[value] = key; + }); + assert.same(count, 5); + assert.deepEqual(result, { + 1: NaN, + 7: 3, + 5: 2, + 4: 1, + 9: object, + }); + map = new Map(); + map.set('0', 9); + map.set('1', 9); + map.set('2', 9); + map.set('3', 9); + result = ''; + map.forEach((value, key) => { + result += key; + if (key === '2') { + map.delete('2'); + map.delete('3'); + map.delete('1'); + map.set('4', 9); + } + }); + assert.same(result, '0124'); + map = new Map([['0', 1]]); + result = ''; + map.forEach(it => { + map.delete('0'); + if (result !== '') throw new Error(); + result += it; + }); + assert.same(result, '1'); + assert.throws(() => { + Map.prototype.forEach.call(new Set(), () => { /* empty */ }); + }, 'non-generic'); +}); + +QUnit.test('Map#get', assert => { + assert.isFunction(Map.prototype.get); + assert.name(Map.prototype.get, 'get'); + assert.arity(Map.prototype.get, 1); + assert.looksNative(Map.prototype.get); + assert.nonEnumerable(Map.prototype, 'get'); + const object = {}; + const frozen = freeze({}); + const map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 1); + map.set(2, 5); + map.set(1, 4); + map.set(frozen, 42); + map.set(object, object); + assert.same(map.get(NaN), 1); + assert.same(map.get(4), undefined); + assert.same(map.get({}), undefined); + assert.same(map.get(object), object); + assert.same(map.get(frozen), 42); + assert.same(map.get(2), 5); +}); + +QUnit.test('Map#has', assert => { + assert.isFunction(Map.prototype.has); + assert.name(Map.prototype.has, 'has'); + assert.arity(Map.prototype.has, 1); + assert.looksNative(Map.prototype.has); + assert.nonEnumerable(Map.prototype, 'has'); + const object = {}; + const frozen = freeze({}); + const map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 1); + map.set(2, 5); + map.set(1, 4); + map.set(frozen, 42); + map.set(object, object); + assert.true(map.has(NaN)); + assert.true(map.has(object)); + assert.true(map.has(2)); + assert.true(map.has(frozen)); + assert.false(map.has(4)); + assert.false(map.has({})); +}); + +QUnit.test('Map#set', assert => { + assert.isFunction(Map.prototype.set); + assert.name(Map.prototype.set, 'set'); + assert.arity(Map.prototype.set, 2); + assert.looksNative(Map.prototype.set); + assert.nonEnumerable(Map.prototype, 'set'); + const object = {}; + let map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 1); + map.set(2, 5); + map.set(1, 4); + map.set(object, object); + assert.same(map.size, 5); + const chain = map.set(7, 2); + assert.same(chain, map); + map.set(7, 2); + assert.same(map.size, 6); + assert.same(map.get(7), 2); + assert.same(map.get(NaN), 1); + map.set(NaN, 42); + assert.same(map.size, 6); + assert.same(map.get(NaN), 42); + map.set({}, 11); + assert.same(map.size, 7); + assert.same(map.get(object), object); + map.set(object, 27); + assert.same(map.size, 7); + assert.same(map.get(object), 27); + map = new Map(); + map.set(NaN, 2); + map.set(NaN, 3); + map.set(NaN, 4); + assert.same(map.size, 1); + const frozen = freeze({}); + map = new Map().set(frozen, 42); + assert.same(map.get(frozen), 42); +}); + +QUnit.test('Map#size', assert => { + assert.nonEnumerable(Map.prototype, 'size'); + const map = new Map(); + map.set(2, 1); + const { size } = map; + assert.same(typeof size, 'number', 'size is number'); + assert.same(size, 1, 'size is correct'); + if (DESCRIPTORS) { + const sizeDescriptor = getOwnPropertyDescriptor(Map.prototype, 'size'); + const getter = sizeDescriptor && sizeDescriptor.get; + const setter = sizeDescriptor && sizeDescriptor.set; + assert.same(typeof getter, 'function', 'size is getter'); + assert.same(typeof setter, 'undefined', 'size is not setter'); + assert.throws(() => Map.prototype.size, TypeError); + } +}); + +QUnit.test('Map & -0', assert => { + let map = new Map(); + map.set(-0, 1); + assert.same(map.size, 1); + assert.true(map.has(0)); + assert.true(map.has(-0)); + assert.same(map.get(0), 1); + assert.same(map.get(-0), 1); + map.forEach((val, key) => { + assert.false(is(key, -0)); + }); + map.delete(-0); + assert.same(map.size, 0); + map = new Map([[-0, 1]]); + map.forEach((val, key) => { + assert.false(is(key, -0)); + }); + map = new Map(); + map.set(4, 4); + map.set(3, 3); + map.set(2, 2); + map.set(1, 1); + map.set(0, 0); + assert.true(map.has(-0)); +}); + +QUnit.test('Map#@@toStringTag', assert => { + assert.same(Map.prototype[Symbol.toStringTag], 'Map', 'Map::@@toStringTag is `Map`'); + assert.same(String(new Map()), '[object Map]', 'correct stringification'); +}); + +QUnit.test('Map Iterator', assert => { + const map = new Map(); + map.set('a', 1); + map.set('b', 2); + map.set('c', 3); + map.set('d', 4); + const results = []; + const iterator = map.keys(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.nonEnumerable(iterator, 'next'); + assert.nonEnumerable(iterator, Symbol.iterator); + results.push(iterator.next().value); + assert.true(map.delete('a')); + assert.true(map.delete('b')); + assert.true(map.delete('c')); + map.set('e'); + results.push(iterator.next().value, iterator.next().value); + assert.true(iterator.next().done); + map.set('f'); + assert.true(iterator.next().done); + assert.deepEqual(results, ['a', 'd', 'e']); +}); + +QUnit.test('Map#keys', assert => { + assert.isFunction(Map.prototype.keys); + assert.name(Map.prototype.keys, 'keys'); + assert.arity(Map.prototype.keys, 0); + assert.looksNative(Map.prototype.keys); + assert.nonEnumerable(Map.prototype, 'keys'); + const map = new Map(); + map.set('a', 'q'); + map.set('s', 'w'); + map.set('d', 'e'); + const iterator = map.keys(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Map Iterator'); + assert.deepEqual(iterator.next(), { + value: 'a', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 's', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'd', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Map#values', assert => { + assert.isFunction(Map.prototype.values); + assert.name(Map.prototype.values, 'values'); + assert.arity(Map.prototype.values, 0); + assert.looksNative(Map.prototype.values); + assert.nonEnumerable(Map.prototype, 'values'); + const map = new Map(); + map.set('a', 'q'); + map.set('s', 'w'); + map.set('d', 'e'); + const iterator = map.values(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Map Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Map#entries', assert => { + assert.isFunction(Map.prototype.entries); + assert.name(Map.prototype.entries, 'entries'); + assert.arity(Map.prototype.entries, 0); + assert.looksNative(Map.prototype.entries); + assert.nonEnumerable(Map.prototype, 'entries'); + const map = new Map(); + map.set('a', 'q'); + map.set('s', 'w'); + map.set('d', 'e'); + const iterator = map.entries(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Map Iterator'); + assert.deepEqual(iterator.next(), { + value: ['a', 'q'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['s', 'w'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['d', 'e'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Map#@@iterator', assert => { + assert.isIterable(Map.prototype); + assert.name(Map.prototype.entries, 'entries'); + assert.arity(Map.prototype.entries, 0); + assert.looksNative(Map.prototype[Symbol.iterator]); + assert.same(Map.prototype[Symbol.iterator], Map.prototype.entries); + const map = new Map(); + map.set('a', 'q'); + map.set('s', 'w'); + map.set('d', 'e'); + const iterator = map[Symbol.iterator](); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Map Iterator'); + assert.same(String(iterator), '[object Map Iterator]'); + assert.deepEqual(iterator.next(), { + value: ['a', 'q'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['s', 'w'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['d', 'e'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-global/es.math.acosh.js b/tests/unit-global/es.math.acosh.js new file mode 100644 index 000000000000..6537077c6f20 --- /dev/null +++ b/tests/unit-global/es.math.acosh.js @@ -0,0 +1,26 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.acosh', assert => { + const { acosh } = Math; + assert.isFunction(acosh); + assert.name(acosh, 'acosh'); + assert.arity(acosh, 1); + assert.looksNative(acosh); + assert.nonEnumerable(Math, 'acosh'); + assert.same(acosh(NaN), NaN); + assert.same(acosh(0.5), NaN); + assert.same(acosh(-1), NaN); + assert.same(acosh(-1e300), NaN); + assert.same(acosh(1), 0); + assert.same(acosh(Infinity), Infinity); + assert.closeTo(acosh(1234), 7.811163220849231, 1e-11); + assert.closeTo(acosh(8.88), 2.8737631531629235, 1e-11); + assert.closeTo(acosh(1e+160), 369.10676205960726, 1e-11); + assert.closeTo(acosh(Number.MAX_VALUE), 710.475860073944, 1e-11); + assert.closeTo(acosh(1 + Number.EPSILON), 2.1073424255447017e-8, 1e-11); + + const checker = createConversionChecker(1234); + assert.closeTo(acosh(checker), 7.811163220849231, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.asinh.js b/tests/unit-global/es.math.asinh.js new file mode 100644 index 000000000000..56b3aa14db29 --- /dev/null +++ b/tests/unit-global/es.math.asinh.js @@ -0,0 +1,25 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.asinh', assert => { + const { asinh } = Math; + assert.isFunction(asinh); + assert.name(asinh, 'asinh'); + assert.arity(asinh, 1); + assert.looksNative(asinh); + assert.nonEnumerable(Math, 'asinh'); + assert.same(asinh(NaN), NaN); + assert.same(asinh(0), 0); + assert.same(asinh(-0), -0); + assert.same(asinh(Infinity), Infinity); + assert.same(asinh(-Infinity), -Infinity); + assert.closeTo(asinh(1234), 7.811163549201245, 1e-11); + assert.closeTo(asinh(9.99), 2.997227420191335, 1e-11); + assert.closeTo(asinh(1e150), 346.0809111296668, 1e-11); + assert.closeTo(asinh(1e7), 16.811242831518268, 1e-11); + assert.closeTo(asinh(-1e7), -16.811242831518268, 1e-11); + + const checker = createConversionChecker(1234); + assert.closeTo(asinh(checker), 7.811163549201245, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.atanh.js b/tests/unit-global/es.math.atanh.js new file mode 100644 index 000000000000..336996b13060 --- /dev/null +++ b/tests/unit-global/es.math.atanh.js @@ -0,0 +1,29 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.atanh', assert => { + const { atanh } = Math; + assert.isFunction(atanh); + assert.name(atanh, 'atanh'); + assert.arity(atanh, 1); + assert.looksNative(atanh); + assert.nonEnumerable(Math, 'atanh'); + assert.same(atanh(NaN), NaN); + assert.same(atanh(-2), NaN); + assert.same(atanh(-1.5), NaN); + assert.same(atanh(2), NaN); + assert.same(atanh(1.5), NaN); + assert.same(atanh(-1), -Infinity); + assert.same(atanh(1), Infinity); + assert.same(atanh(0), 0); + assert.same(atanh(-0), -0); + assert.same(atanh(-1e300), NaN); + assert.same(atanh(1e300), NaN); + assert.closeTo(atanh(0.5), 0.5493061443340549, 1e-11); + assert.closeTo(atanh(-0.5), -0.5493061443340549, 1e-11); + assert.closeTo(atanh(0.444), 0.47720201260109457, 1e-11); + + const checker = createConversionChecker(0.5); + assert.closeTo(atanh(checker), 0.5493061443340549, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.cbrt.js b/tests/unit-global/es.math.cbrt.js new file mode 100644 index 000000000000..11e94e5d37d9 --- /dev/null +++ b/tests/unit-global/es.math.cbrt.js @@ -0,0 +1,24 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.cbrt', assert => { + const { cbrt } = Math; + assert.isFunction(cbrt); + assert.name(cbrt, 'cbrt'); + assert.arity(cbrt, 1); + assert.looksNative(cbrt); + assert.nonEnumerable(Math, 'cbrt'); + assert.same(cbrt(NaN), NaN); + assert.same(cbrt(0), 0); + assert.same(cbrt(-0), -0); + assert.same(cbrt(Infinity), Infinity); + assert.same(cbrt(-Infinity), -Infinity); + assert.same(cbrt(-8), -2); + assert.same(cbrt(8), 2); + assert.closeTo(cbrt(-1000), -10, 1e-11); + assert.closeTo(cbrt(1000), 10, 1e-11); + + const checker = createConversionChecker(1000); + assert.closeTo(cbrt(checker), 10, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.clz32.js b/tests/unit-global/es.math.clz32.js new file mode 100644 index 000000000000..23eabedf3eef --- /dev/null +++ b/tests/unit-global/es.math.clz32.js @@ -0,0 +1,21 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.clz32', assert => { + const { clz32 } = Math; + assert.isFunction(clz32); + assert.name(clz32, 'clz32'); + assert.arity(clz32, 1); + assert.looksNative(clz32); + assert.nonEnumerable(Math, 'clz32'); + assert.same(clz32(0), 32); + assert.same(clz32(1), 31); + assert.same(clz32(-1), 0); + assert.same(clz32(0.6), 32); + assert.same(clz32(2 ** 32 - 1), 0); + assert.same(clz32(2 ** 32), 32); + + const checker = createConversionChecker(1); + assert.same(clz32(checker), 31, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.cosh.js b/tests/unit-global/es.math.cosh.js new file mode 100644 index 000000000000..adb788e6bfd0 --- /dev/null +++ b/tests/unit-global/es.math.cosh.js @@ -0,0 +1,25 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.cosh', assert => { + const { cosh } = Math; + assert.isFunction(cosh); + assert.name(cosh, 'cosh'); + assert.arity(cosh, 1); + assert.looksNative(cosh); + assert.nonEnumerable(Math, 'cosh'); + assert.same(cosh(NaN), NaN); + assert.same(cosh(0), 1); + assert.same(cosh(-0), 1); + assert.same(cosh(Infinity), Infinity); + assert.same(cosh(-Infinity), Infinity); + assert.closeTo(cosh(12), 81377.395712574, 1e-9); + assert.closeTo(cosh(22), 1792456423.065796, 1e-5); + assert.closeTo(cosh(-10), 11013.232920103323, 1e-11); + assert.closeTo(cosh(-23), 4872401723.124452, 1e-5); + assert.closeTo(cosh(710), 1.1169973830808557e+308, 1e+295); + + const checker = createConversionChecker(12); + assert.closeTo(cosh(checker), 81377.395712574, 1e-9, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.expm1.js b/tests/unit-global/es.math.expm1.js new file mode 100644 index 000000000000..32489852ff60 --- /dev/null +++ b/tests/unit-global/es.math.expm1.js @@ -0,0 +1,22 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.expm1', assert => { + const { expm1 } = Math; + assert.isFunction(expm1); + assert.name(expm1, 'expm1'); + assert.arity(expm1, 1); + assert.looksNative(expm1); + assert.nonEnumerable(Math, 'expm1'); + assert.same(expm1(NaN), NaN); + assert.same(expm1(0), 0); + assert.same(expm1(-0), -0); + assert.same(expm1(Infinity), Infinity); + assert.same(expm1(-Infinity), -1); + assert.closeTo(expm1(10), 22025.465794806718, 1e-11); + assert.closeTo(expm1(-10), -0.9999546000702375, 1e-11); + + const checker = createConversionChecker(10); + assert.closeTo(expm1(checker), 22025.465794806718, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.f16round.js b/tests/unit-global/es.math.f16round.js new file mode 100644 index 000000000000..cdd603bb3f15 --- /dev/null +++ b/tests/unit-global/es.math.f16round.js @@ -0,0 +1,46 @@ +// some asserts based on https://github.com/petamoriken/float16/blob/master/test/f16round.js +import { createConversionChecker } from '../helpers/helpers.js'; + +const { MAX_VALUE, MIN_VALUE } = Number; + +QUnit.test('Math.f16round', assert => { + const { f16round } = Math; + assert.isFunction(f16round); + assert.name(f16round, 'f16round'); + assert.arity(f16round, 1); + assert.looksNative(f16round); + assert.nonEnumerable(Math, 'f16round'); + assert.same(f16round(), NaN); + assert.same(f16round(undefined), NaN); + assert.same(f16round(NaN), NaN); + assert.same(f16round(null), 0); + assert.same(f16round(0), 0); + assert.same(f16round(-0), -0); + assert.same(f16round(MIN_VALUE), 0); + assert.same(f16round(-MIN_VALUE), -0); + assert.same(f16round(Infinity), Infinity); + assert.same(f16round(-Infinity), -Infinity); + assert.same(f16round(MAX_VALUE), Infinity); + assert.same(f16round(-MAX_VALUE), -Infinity); + + const MAX_FLOAT16 = 65504; + const MIN_FLOAT16 = 2 ** -24; + + assert.same(f16round(MAX_FLOAT16), MAX_FLOAT16); + assert.same(f16round(-MAX_FLOAT16), -MAX_FLOAT16); + assert.same(f16round(MIN_FLOAT16), MIN_FLOAT16); + assert.same(f16round(-MIN_FLOAT16), -MIN_FLOAT16); + assert.same(f16round(MIN_FLOAT16 / 2), 0); + assert.same(f16round(-MIN_FLOAT16 / 2), -0); + assert.same(f16round(2.980232238769531911744490042422139897126953655970282852649688720703125e-8), MIN_FLOAT16); + assert.same(f16round(-2.980232238769531911744490042422139897126953655970282852649688720703125e-8), -MIN_FLOAT16); + + assert.same(f16round(1.337), 1.3369140625); + assert.same(f16round(0.499994), 0.5); + assert.same(f16round(7.9999999), 8); + + const checker = createConversionChecker(1.1); + assert.same(f16round(checker), 1.099609375, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.fround.js b/tests/unit-global/es.math.fround.js new file mode 100644 index 000000000000..ebc061fce664 --- /dev/null +++ b/tests/unit-global/es.math.fround.js @@ -0,0 +1,52 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +const { MAX_VALUE, MIN_VALUE } = Number; + +QUnit.test('Math.fround', assert => { + const { fround } = Math; + assert.isFunction(fround); + assert.name(fround, 'fround'); + assert.arity(fround, 1); + assert.looksNative(fround); + assert.nonEnumerable(Math, 'fround'); + assert.same(fround(), NaN); + assert.same(fround(undefined), NaN); + assert.same(fround(NaN), NaN); + assert.same(fround(null), 0); + assert.same(fround(0), 0); + assert.same(fround(-0), -0); + assert.same(fround(MIN_VALUE), 0); + assert.same(fround(-MIN_VALUE), -0); + assert.same(fround(Infinity), Infinity); + assert.same(fround(-Infinity), -Infinity); + assert.same(fround(MAX_VALUE), Infinity); + assert.same(fround(-MAX_VALUE), -Infinity); + assert.same(fround(3.4028235677973366e+38), Infinity); + assert.same(fround(3), 3); + assert.same(fround(-3), -3); + const maxFloat32 = 3.4028234663852886e+38; + const minFloat32 = 1.401298464324817e-45; + assert.same(fround(maxFloat32), maxFloat32); + assert.same(fround(-maxFloat32), -maxFloat32); + assert.same(fround(maxFloat32 + 2 ** 102), maxFloat32); + assert.same(fround(minFloat32), minFloat32); + assert.same(fround(-minFloat32), -minFloat32); + assert.same(fround(minFloat32 / 2), 0); + assert.same(fround(-minFloat32 / 2), -0); + assert.same(fround(minFloat32 / 2 + 2 ** -202), minFloat32); + assert.same(fround(-minFloat32 / 2 - 2 ** -202), -minFloat32); + + const maxSubnormal32 = 1.1754942106924411e-38; + const minNormal32 = 1.1754943508222875e-38; + assert.same(fround(1.1754942807573642e-38), maxSubnormal32, 'fround(1.1754942807573642e-38)'); + assert.same(fround(1.1754942807573643e-38), minNormal32, 'fround(1.1754942807573643e-38)'); + assert.same(fround(1.1754942807573644e-38), minNormal32, 'fround(1.1754942807573644e-38)'); + assert.same(fround(-1.1754942807573642e-38), -maxSubnormal32, 'fround(-1.1754942807573642e-38)'); + assert.same(fround(-1.1754942807573643e-38), -minNormal32, 'fround(-1.1754942807573643e-38)'); + assert.same(fround(-1.1754942807573644e-38), -minNormal32, 'fround(-1.1754942807573644e-38)'); + + const checker = createConversionChecker(1.1754942807573642e-38); + assert.same(fround(checker), maxSubnormal32, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.hypot.js b/tests/unit-global/es.math.hypot.js new file mode 100644 index 000000000000..2f7530fcb185 --- /dev/null +++ b/tests/unit-global/es.math.hypot.js @@ -0,0 +1,59 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.hypot', assert => { + const { hypot, sqrt } = Math; + assert.isFunction(hypot); + assert.name(hypot, 'hypot'); + assert.arity(hypot, 2); + assert.looksNative(hypot); + assert.nonEnumerable(Math, 'hypot'); + assert.same(hypot(), 0); + assert.same(hypot(1), 1); + assert.same(hypot('', 0), 0); + assert.same(hypot(0, ''), 0); + assert.same(hypot(Infinity, 0), Infinity, 'Infinity, 0'); + assert.same(hypot(-Infinity, 0), Infinity, '-Infinity, 0'); + assert.same(hypot(0, Infinity), Infinity, '0, Infinity'); + assert.same(hypot(0, -Infinity), Infinity, '0, -Infinity'); + assert.same(hypot(Infinity, NaN), Infinity, 'Infinity, NaN'); + assert.same(hypot(NaN, -Infinity), Infinity, 'NaN, -Infinity'); + assert.same(hypot(NaN, 0), NaN, 'NaN, 0'); + assert.same(hypot(0, NaN), NaN, '0, NaN'); + assert.same(hypot(0, -0), 0); + assert.same(hypot(0, 0), 0); + assert.same(hypot(-0, -0), 0); + assert.same(hypot(-0, 0), 0); + assert.same(hypot(0, 1), 1); + assert.same(hypot(0, -1), 1); + assert.same(hypot(-0, 1), 1); + assert.same(hypot(-0, -1), 1); + assert.same(hypot(0), 0); + assert.same(hypot(1), 1); + assert.same(hypot(2), 2); + assert.same(hypot(0, 0, 1), 1); + assert.same(hypot(0, 1, 0), 1); + assert.same(hypot(1, 0, 0), 1); + assert.same(hypot(2, 3, 4), sqrt(2 ** 2 + 3 ** 2 + 4 ** 2)); + assert.same(hypot(2, 3, 4, 5), sqrt(2 ** 2 + 3 ** 2 + 4 ** 2 + 5 ** 2)); + assert.closeTo(hypot(66, 66), 93.33809511662427, 1e-11); + assert.closeTo(hypot(0.1, 100), 100.0000499999875, 1e-11); + assert.same(hypot(1e+300, 1e+300), 1.4142135623730952e+300); + assert.same(Math.floor(hypot(1e-300, 1e-300) * 1e308), 141421356); + assert.same(hypot(1e+300, 1e+300, 2, 3), 1.4142135623730952e+300); + assert.same(hypot(-3, 4), 5); + assert.same(hypot(3, -4), 5); + + const checker1 = createConversionChecker(2); + const checker2 = createConversionChecker(3); + const checker3 = createConversionChecker(4); + const checker4 = createConversionChecker(5); + assert.same(hypot(checker1, checker2, checker3, checker4), sqrt(2 ** 2 + 3 ** 2 + 4 ** 2 + 5 ** 2), 'object wrapper'); + assert.same(checker1.$valueOf, 1, 'checker1 valueOf calls'); + assert.same(checker1.$toString, 0, 'checker1 toString calls'); + assert.same(checker2.$valueOf, 1, 'checker2 valueOf calls'); + assert.same(checker2.$toString, 0, 'checker2 toString calls'); + assert.same(checker3.$valueOf, 1, 'checker3 valueOf calls'); + assert.same(checker3.$toString, 0, 'checker3 toString calls'); + assert.same(checker4.$valueOf, 1, 'checker4 valueOf calls'); + assert.same(checker4.$toString, 0, 'checker4 toString calls'); +}); diff --git a/tests/unit-global/es.math.imul.js b/tests/unit-global/es.math.imul.js new file mode 100644 index 000000000000..8111004b1069 --- /dev/null +++ b/tests/unit-global/es.math.imul.js @@ -0,0 +1,53 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.imul', assert => { + const { imul } = Math; + assert.isFunction(imul); + assert.name(imul, 'imul'); + assert.arity(imul, 2); + assert.looksNative(imul); + assert.nonEnumerable(Math, 'imul'); + assert.same(imul(0, 0), 0); + assert.same(imul(123, 456), 56088); + assert.same(imul(-123, 456), -56088); + assert.same(imul(123, -456), -56088); + assert.same(imul(19088743, 4275878552), 602016552); + assert.same(imul(false, 7), 0); + assert.same(imul(7, false), 0); + assert.same(imul(false, false), 0); + assert.same(imul(true, 7), 7); + assert.same(imul(7, true), 7); + assert.same(imul(true, true), 1); + assert.same(imul(undefined, 7), 0); + assert.same(imul(7, undefined), 0); + assert.same(imul(undefined, undefined), 0); + assert.same(imul('str', 7), 0); + assert.same(imul(7, 'str'), 0); + assert.same(imul({}, 7), 0); + assert.same(imul(7, {}), 0); + assert.same(imul([], 7), 0); + assert.same(imul(7, []), 0); + assert.same(imul(0xFFFFFFFF, 5), -5); + assert.same(imul(0xFFFFFFFE, 5), -10); + assert.same(imul(2, 4), 8); + assert.same(imul(-1, 8), -8); + assert.same(imul(-2, -2), 4); + assert.same(imul(-0, 7), 0); + assert.same(imul(7, -0), 0); + assert.same(imul(0.1, 7), 0); + assert.same(imul(7, 0.1), 0); + assert.same(imul(0.9, 7), 0); + assert.same(imul(7, 0.9), 0); + assert.same(imul(1.1, 7), 7); + assert.same(imul(7, 1.1), 7); + assert.same(imul(1.9, 7), 7); + assert.same(imul(7, 1.9), 7); + + const checker1 = createConversionChecker(-123); + const checker2 = createConversionChecker(456); + assert.same(imul(checker1, checker2), -56088, 'object wrapper'); + assert.same(checker1.$valueOf, 1, 'checker1 valueOf calls'); + assert.same(checker1.$toString, 0, 'checker1 toString calls'); + assert.same(checker2.$valueOf, 1, 'checker2 valueOf calls'); + assert.same(checker2.$toString, 0, 'checker2 toString calls'); +}); diff --git a/tests/unit-global/es.math.log10.js b/tests/unit-global/es.math.log10.js new file mode 100644 index 000000000000..e39da32b9f1a --- /dev/null +++ b/tests/unit-global/es.math.log10.js @@ -0,0 +1,28 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.log10', assert => { + const { log10 } = Math; + assert.isFunction(log10); + assert.name(log10, 'log10'); + assert.arity(log10, 1); + assert.looksNative(log10); + assert.nonEnumerable(Math, 'log10'); + assert.same(log10(''), log10(0)); + assert.same(log10(NaN), NaN); + assert.same(log10(-1), NaN); + assert.same(log10(0), -Infinity); + assert.same(log10(-0), -Infinity); + assert.same(log10(1), 0); + assert.same(log10(Infinity), Infinity); + assert.closeTo(log10(0.1), -1, 1e-11); + assert.closeTo(log10(0.5), -0.3010299956639812, 1e-11); + assert.closeTo(log10(1.5), 0.17609125905568124, 1e-11); + assert.closeTo(log10(5), 0.6989700043360189, 1e-11); + assert.closeTo(log10(50), 1.6989700043360187, 1e-11); + assert.closeTo(log10(1000), 3, 1e-11); + + const checker = createConversionChecker(0.5); + assert.closeTo(log10(checker), -0.3010299956639812, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.log1p.js b/tests/unit-global/es.math.log1p.js new file mode 100644 index 000000000000..3a54c5c80ddf --- /dev/null +++ b/tests/unit-global/es.math.log1p.js @@ -0,0 +1,24 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.log1p', assert => { + const { log1p } = Math; + assert.isFunction(log1p); + assert.name(log1p, 'log1p'); + assert.arity(log1p, 1); + assert.looksNative(log1p); + assert.nonEnumerable(Math, 'log1p'); + assert.same(log1p(''), log1p(0)); + assert.same(log1p(NaN), NaN); + assert.same(log1p(-2), NaN); + assert.same(log1p(-1), -Infinity); + assert.same(log1p(0), 0); + assert.same(log1p(-0), -0); + assert.same(log1p(Infinity), Infinity); + assert.closeTo(log1p(5), 1.791759469228055, 1e-11); + assert.closeTo(log1p(50), 3.9318256327243257, 1e-11); + + const checker = createConversionChecker(5); + assert.closeTo(log1p(checker), 1.791759469228055, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.log2.js b/tests/unit-global/es.math.log2.js new file mode 100644 index 000000000000..0c52d20d0f35 --- /dev/null +++ b/tests/unit-global/es.math.log2.js @@ -0,0 +1,25 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.log2', assert => { + const { log2 } = Math; + assert.isFunction(log2); + assert.name(log2, 'log2'); + assert.arity(log2, 1); + assert.looksNative(log2); + assert.nonEnumerable(Math, 'log2'); + assert.same(log2(''), log2(0)); + assert.same(log2(NaN), NaN); + assert.same(log2(-1), NaN); + assert.same(log2(0), -Infinity); + assert.same(log2(-0), -Infinity); + assert.same(log2(1), 0); + assert.same(log2(Infinity), Infinity); + assert.same(log2(0.5), -1); + assert.same(log2(32), 5); + assert.closeTo(log2(5), 2.321928094887362, 1e-11); + + const checker = createConversionChecker(5); + assert.closeTo(log2(checker), 2.321928094887362, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.sign.js b/tests/unit-global/es.math.sign.js new file mode 100644 index 000000000000..7cd0399bbe1a --- /dev/null +++ b/tests/unit-global/es.math.sign.js @@ -0,0 +1,25 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.sign', assert => { + const { sign } = Math; + assert.isFunction(sign); + assert.name(sign, 'sign'); + assert.arity(sign, 1); + assert.looksNative(sign); + assert.nonEnumerable(Math, 'sign'); + assert.same(sign(NaN), NaN); + assert.same(sign(), NaN); + assert.same(sign(-0), -0); + assert.same(sign(0), 0); + assert.same(sign(Infinity), 1); + assert.same(sign(-Infinity), -1); + assert.same(sign(13510798882111488), 1); + assert.same(sign(-13510798882111488), -1); + assert.same(sign(42.5), 1); + assert.same(sign(-42.5), -1); + + const checker = createConversionChecker(-42.5); + assert.same(sign(checker), -1, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.sinh.js b/tests/unit-global/es.math.sinh.js new file mode 100644 index 000000000000..c88b0d1475a2 --- /dev/null +++ b/tests/unit-global/es.math.sinh.js @@ -0,0 +1,23 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.sinh', assert => { + const { sinh } = Math; + assert.isFunction(sinh); + assert.name(sinh, 'sinh'); + assert.arity(sinh, 1); + assert.looksNative(sinh); + assert.nonEnumerable(Math, 'sinh'); + assert.same(sinh(NaN), NaN); + assert.same(sinh(0), 0); + assert.same(sinh(-0), -0); + assert.same(sinh(Infinity), Infinity); + assert.same(sinh(-Infinity), -Infinity); + assert.closeTo(sinh(-5), -74.20321057778875, 1e-11); + assert.closeTo(sinh(2), 3.6268604078470186, 1e-11); + assert.same(sinh(-2e-17), -2e-17); + + const checker = createConversionChecker(-5); + assert.closeTo(sinh(checker), -74.20321057778875, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.sum-precise.js b/tests/unit-global/es.math.sum-precise.js new file mode 100644 index 000000000000..17487285ee97 --- /dev/null +++ b/tests/unit-global/es.math.sum-precise.js @@ -0,0 +1,59 @@ +/* eslint-disable @stylistic/max-len -- ok */ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Math.sumPrecise', assert => { + const { sumPrecise } = Math; + assert.isFunction(sumPrecise); + assert.name(sumPrecise, 'sumPrecise'); + assert.arity(sumPrecise, 1); + assert.looksNative(sumPrecise); + assert.nonEnumerable(Math, 'sumPrecise'); + + assert.same(sumPrecise([1, 2, 3]), 6, 'basic'); + assert.same(sumPrecise(createIterable([1, 2, 3])), 6, 'custom iterable'); + + assert.throws(() => sumPrecise(undefined), TypeError, 'undefined'); + assert.throws(() => sumPrecise(null), TypeError, 'null'); + assert.throws(() => sumPrecise({ 0: 1 }), TypeError, 'non-iterable'); + assert.throws(() => sumPrecise(1, 2), TypeError, 'non-iterable #2'); + assert.throws(() => sumPrecise([1, '2']), TypeError, 'non-number elements'); + + // Adapted from https://github.com/tc39/test262 + // Copyright (C) 2024 Kevin Gibbons. All rights reserved. + // This code is governed by the BSD license + assert.same(sumPrecise([NaN]), NaN, '[NaN]'); + assert.same(sumPrecise([Infinity, -Infinity]), NaN, '[Infinity, -Infinity]'); + assert.same(sumPrecise([-Infinity, Infinity]), NaN, '[-Infinity, Infinity]'); + assert.same(sumPrecise([Infinity]), Infinity, '[Infinity]'); + assert.same(sumPrecise([Infinity, Infinity]), Infinity, '[Infinity, Infinity]'); + assert.same(sumPrecise([-Infinity]), -Infinity, '[-Infinity]'); + assert.same(sumPrecise([-Infinity, -Infinity]), -Infinity, '[-Infinity, -Infinity]'); + assert.same(sumPrecise([]), -0, '[]'); + assert.same(sumPrecise([-0]), -0, '[-0]'); + assert.same(sumPrecise([-0, -0]), -0, '[-0, -0]'); + assert.same(sumPrecise([-0, 0]), 0, '[-0, 0]'); + assert.same(sumPrecise([1e308]), 1e308, '[1e308]'); + assert.same(sumPrecise([1e308, -1e308]), 0, '[1e308, -1e308]'); + assert.same(sumPrecise([0.1]), 0.1, '[0.1]'); + assert.same(sumPrecise([0.1, 0.1]), 0.2, '[0.1, 0.1]'); + assert.same(sumPrecise([0.1, -0.1]), 0, '[0.1, -0.1]'); + assert.same(sumPrecise([1e308, 1e308, 0.1, 0.1, 1e30, 0.1, -1e30, -1e308, -1e308]), 0.30000000000000004, '[1e308, 1e308, 0.1, 0.1, 1e30, 0.1, -1e30, -1e308, -1e308]'); + assert.same(sumPrecise([1e30, 0.1, -1e30]), 0.1, '[1e30, 0.1, -1e30]'); + assert.same(sumPrecise([8.98846567431158e+307, 8.988465674311579e+307, -Number.MAX_VALUE]), 9.9792015476736e+291, '[8.98846567431158e+307, 8.988465674311579e+307, -Number.MAX_VALUE]'); + assert.same(sumPrecise([-5.630637621603525e+255, 9.565271205476345e+307, 2.9937604643020797e+292]), 9.565271205476347e+307, '[-5.630637621603525e+255, 9.565271205476345e+307, 2.9937604643020797e+292]'); + assert.same(sumPrecise([6.739986666787661e+66, 2, -1.2689709186578243e-116, 1.7046015739467354e+308, -9.979201547673601e+291, 6.160926733208294e+307, -3.179557053031852e+234, -7.027282978772846e+307, -0.7500000000000001]), 1.61796594939028e+308, '[6.739986666787661e+66, 2, -1.2689709186578243e-116, 1.7046015739467354e+308, -9.979201547673601e+291, 6.160926733208294e+307, -3.179557053031852e+234, -7.027282978772846e+307, -0.7500000000000001]'); + assert.same(sumPrecise([0.31150493246968836, -8.988465674311582e+307, 1.8315037361673755e-270, -15.999999999999996, 2.9999999999999996, 7.345200721499384e+164, -2.033582473639399, -8.98846567431158e+307, -3.5737295155405993e+292, 4.13894772383715e-124, -3.6111186457260667e-35, 2.387234887098013e+180, 7.645295562778372e-298, 3.395189016861822e-103, -2.6331611115768973e-149]), -Infinity, '[0.31150493246968836, -8.988465674311582e+307, 1.8315037361673755e-270, -15.999999999999996, 2.9999999999999996, 7.345200721499384e+164, -2.033582473639399, -8.98846567431158e+307, -3.5737295155405993e+292, 4.13894772383715e-124, -3.6111186457260667e-35, 2.387234887098013e+180, 7.645295562778372e-298, 3.395189016861822e-103, -2.6331611115768973e-149]'); + assert.same(sumPrecise([-1.1442589134409902e+308, 9.593842098384855e+138, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565685e+308, '[-1.1442589134409902e+308, 9.593842098384855e+138, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]'); + assert.same(sumPrecise([-1.1442589134409902e+308, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565687e+308, '[-1.1442589134409902e+308, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]'); + assert.same(sumPrecise([9.593842098384855e+138, -6.948356297254111e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565685e+308, '[9.593842098384855e+138, -6.948356297254111e+307, -1.3482698511467367e+308, 4.494232837155792e+307]'); + assert.same(sumPrecise([-2.534858246857893e+115, 8.988465674311579e+307, 8.98846567431158e+307]), Number.MAX_VALUE, '[-2.534858246857893e+115, 8.988465674311579e+307, 8.98846567431158e+307]'); + assert.same(sumPrecise([1.3588124894186193e+308, 1.4803986201152006e+223, 6.741349255733684e+307]), Infinity, '[1.3588124894186193e+308, 1.4803986201152006e+223, 6.741349255733684e+307]'); + assert.same(sumPrecise([6.741349255733684e+307, 1.7976931348623155e+308, -7.388327292663961e+41]), Infinity, '[6.741349255733684e+307, 1.7976931348623155e+308, -7.388327292663961e+41]'); + assert.same(sumPrecise([-1.9807040628566093e+28, Number.MAX_VALUE, 9.9792015476736e+291]), Number.MAX_VALUE, '[-1.9807040628566093e+28, Number.MAX_VALUE, 9.9792015476736e+291]'); + assert.same(sumPrecise([-1.0214557991173964e+61, Number.MAX_VALUE, 8.98846567431158e+307, -8.988465674311579e+307]), Number.MAX_VALUE, '[-1.0214557991173964e+61, Number.MAX_VALUE, 8.98846567431158e+307, -8.988465674311579e+307]'); + assert.same(sumPrecise([Number.MAX_VALUE, 7.999999999999999, -1.908963895403937e-230, 1.6445950082320264e+292, 2.0734856707605806e+205]), Infinity, '[Number.MAX_VALUE, 7.999999999999999, -1.908963895403937e-230, 1.6445950082320264e+292, 2.0734856707605806e+205]'); + assert.same(sumPrecise([6.197409167220438e-223, -9.979201547673601e+291, -Number.MAX_VALUE]), -Infinity, '[6.197409167220438e-223, -9.979201547673601e+291, -Number.MAX_VALUE]'); + assert.same(sumPrecise([4.49423283715579e+307, 8.944251746776101e+307, -0.0002441406250000001, 1.1752060710043817e+308, 4.940846717201632e+292, -1.6836699406454528e+308]), 8.353845887521184e+307, '[4.49423283715579e+307, 8.944251746776101e+307, -0.0002441406250000001, 1.1752060710043817e+308, 4.940846717201632e+292, -1.6836699406454528e+308]'); + assert.same(sumPrecise([8.988465674311579e+307, 7.999999999999998, 7.029158107234023e-308, -2.2303483759420562e-172, -Number.MAX_VALUE, -8.98846567431158e+307]), -Number.MAX_VALUE, '8.988465674311579e+307, 7.999999999999998, 7.029158107234023e-308, -2.2303483759420562e-172, -Number.MAX_VALUE, -8.98846567431158e+307]'); + assert.same(sumPrecise([8.98846567431158e+307, 8.98846567431158e+307]), Infinity, '[8.98846567431158e+307, 8.98846567431158e+307]'); +}); diff --git a/tests/unit-global/es.math.tanh.js b/tests/unit-global/es.math.tanh.js new file mode 100644 index 000000000000..9b65291b35ac --- /dev/null +++ b/tests/unit-global/es.math.tanh.js @@ -0,0 +1,23 @@ +import { NATIVE } from '../helpers/constants.js'; +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.tanh', assert => { + const { tanh } = Math; + assert.isFunction(tanh); + assert.name(tanh, 'tanh'); + assert.arity(tanh, 1); + assert.looksNative(tanh); + assert.nonEnumerable(Math, 'tanh'); + assert.same(tanh(NaN), NaN); + assert.same(tanh(0), 0); + assert.same(tanh(-0), -0); + assert.same(tanh(Infinity), 1); + assert.same(tanh(90), 1); + assert.closeTo(tanh(10), 0.9999999958776927, 1e-11); + if (NATIVE) assert.same(tanh(710), 1); + + const checker = createConversionChecker(10); + assert.closeTo(tanh(checker), 0.9999999958776927, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.math.to-string-tag.js b/tests/unit-global/es.math.to-string-tag.js new file mode 100644 index 000000000000..b2196987d611 --- /dev/null +++ b/tests/unit-global/es.math.to-string-tag.js @@ -0,0 +1,3 @@ +QUnit.test('Math[@@toStringTag]', assert => { + assert.same(Math[Symbol.toStringTag], 'Math', 'Math[@@toStringTag] is `Math`'); +}); diff --git a/tests/unit-global/es.math.trunc.js b/tests/unit-global/es.math.trunc.js new file mode 100644 index 000000000000..39f516ab73a9 --- /dev/null +++ b/tests/unit-global/es.math.trunc.js @@ -0,0 +1,30 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.trunc', assert => { + const { trunc } = Math; + assert.isFunction(trunc); + assert.name(trunc, 'trunc'); + assert.arity(trunc, 1); + assert.looksNative(trunc); + assert.nonEnumerable(Math, 'trunc'); + assert.same(trunc(NaN), NaN, 'NaN -> NaN'); + assert.same(trunc(-0), -0, '-0 -> -0'); + assert.same(trunc(0), 0, '0 -> 0'); + assert.same(trunc(Infinity), Infinity, 'Infinity -> Infinity'); + assert.same(trunc(-Infinity), -Infinity, '-Infinity -> -Infinity'); + assert.same(trunc(null), 0, 'null -> 0'); + assert.same(trunc({}), NaN, '{} -> NaN'); + assert.same(trunc([]), 0, '[] -> 0'); + assert.same(trunc(1.01), 1, '1.01 -> 0'); + assert.same(trunc(1.99), 1, '1.99 -> 0'); + assert.same(trunc(-1), -1, '-1 -> -1'); + assert.same(trunc(-1.99), -1, '-1.99 -> -1'); + assert.same(trunc(-555.555), -555, '-555.555 -> -555'); + assert.same(trunc(9007199254740992), 9007199254740992, '9007199254740992 -> 9007199254740992'); + assert.same(trunc(-9007199254740992), -9007199254740992, '-9007199254740992 -> -9007199254740992'); + + const checker = createConversionChecker(-1.99); + assert.same(trunc(checker), -1, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/es.number.constructor.js b/tests/unit-global/es.number.constructor.js new file mode 100644 index 000000000000..6b69f4fa13c2 --- /dev/null +++ b/tests/unit-global/es.number.constructor.js @@ -0,0 +1,272 @@ +import { WHITESPACES } from '../helpers/constants.js'; +import { nativeSubclass } from '../helpers/helpers.js'; + +function getCheck(assert) { + return function (a, b) { + assert.same(Number(a), b, `Number ${ typeof a } ${ a } -> ${ b }`); + const x = new Number(a); + assert.same(x, Object(x), `new Number ${ typeof a } ${ a } is object`); + assert.same({}.toString.call(x).slice(8, -1), 'Number', `classof new Number ${ typeof a } ${ a } is Number`); + assert.same(x.valueOf(), b, `new Number(${ typeof a } ${ a }).valueOf() -> ${ b }`); + }; +} + +QUnit.test('Number constructor: regression', assert => { + const check = getCheck(assert); + assert.isFunction(Number); + assert.arity(Number, 1); + assert.name(Number, 'Number'); + assert.looksNative(Number); + assert.same(Number.prototype.constructor, Number); + assert.same(1.0.constructor, Number); + const constants = ['MAX_VALUE', 'MIN_VALUE', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY']; + for (const constant of constants) { + assert.true(constant in Number, `Number.${ constant }`); + assert.nonEnumerable(Number, constant); + } + assert.same(Number(), 0); + assert.same(new Number().valueOf(), 0); + check(42, 42); + check(42.42, 42.42); + check(new Number(42), 42); + check(new Number(42.42), 42.42); + check('42', 42); + check('42.42', 42.42); + check('0x42', 66); + check('0X42', 66); + check('0xzzz', NaN); + check('0x1g', NaN); + check('+0x1', NaN); + check('-0x1', NaN); + check('+0X1', NaN); + check('-0X1', NaN); + check(new String('42'), 42); + check(new String('42.42'), 42.42); + check(new String('0x42'), 66); + check(null, 0); + check(undefined, NaN); + check(false, 0); + check(true, 1); + check(new Boolean(false), 0); + check(new Boolean(true), 1); + check({}, NaN); + check({ + valueOf: '1.1', + }, NaN); + check({ + valueOf: '1.1', + toString() { + return '2.2'; + }, + }, 2.2); + check({ + valueOf() { + return '1.1'; + }, + }, 1.1); + check({ + valueOf() { + return '1.1'; + }, + toString() { + return '2.2'; + }, + }, 1.1); + check({ + valueOf() { + return '-0x1a2b3c'; + }, + }, NaN); + check({ + toString() { + return '-0x1a2b3c'; + }, + }, NaN); + check({ + valueOf() { + return 42; + }, + }, 42); + check({ + valueOf() { + return '42'; + }, + }, 42); + check({ + valueOf() { + return null; + }, + }, 0); + check({ + toString() { + return 42; + }, + }, 42); + check({ + toString() { + return '42'; + }, + }, 42); + check({ + valueOf() { + return 1; + }, + toString() { + return 2; + }, + }, 1); + check({ + valueOf: 1, + toString() { + return 2; + }, + }, 2); + let number = 1; + assert.same(Number({ + valueOf() { + return ++number; + }, + }), 2, 'Number call valueOf only once #1'); + assert.same(number, 2, 'Number call valueOf only once #2'); + number = 1; + assert.same(Number({ + toString() { + return ++number; + }, + }), 2, 'Number call toString only once #1'); + assert.same(number, 2, 'Number call toString only once #2'); + number = 1; + assert.same(new Number({ + valueOf() { + return ++number; + }, + }).valueOf(), 2, 'new Number call valueOf only once #1'); + assert.same(number, 2, 'new Number call valueOf only once #2'); + number = 1; + assert.same(new Number({ + toString() { + return ++number; + }, + }).valueOf(), 2, 'new Number call toString only once #1'); + assert.same(number, 2, 'new Number call toString only once #2'); + assert.throws(() => Number(Object.create(null)), TypeError, 'Number assert.throws on object w/o valueOf and toString'); + assert.throws(() => Number({ + valueOf: 1, + toString: 2, + }), TypeError, 'Number assert.throws on object then valueOf and toString are not functions'); + assert.throws(() => new Number(Object.create(null)), TypeError, 'new Number assert.throws on object w/o valueOf and toString'); + assert.throws(() => new Number({ + valueOf: 1, + toString: 2, + }), TypeError, 'new Number assert.throws on object then valueOf and toString are not functions'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('Number constructor test'); + assert.throws(() => Number(symbol), 'throws on symbol argument'); + assert.throws(() => new Number(symbol), 'throws on symbol argument, new'); + } + + number = new Number(42); + assert.same(typeof number.constructor(number), 'number'); + check(`${ WHITESPACES }42`, 42); + check(`42${ WHITESPACES }`, 42); + check(`${ WHITESPACES }42${ WHITESPACES }`, 42); + check(`${ WHITESPACES }0x42`, 66); + check(`0x42${ WHITESPACES }`, 66); + check(`${ WHITESPACES }0x42${ WHITESPACES }`, 66); + check(`${ WHITESPACES }0X42`, 66); + check(`0X42${ WHITESPACES }`, 66); + check(`${ WHITESPACES }0X42${ WHITESPACES }`, 66); + if (nativeSubclass) { + const Subclass = nativeSubclass(Number); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof Number, 'correct subclassing with native classes #2'); + assert.same(new Subclass(1).toFixed(2), '1.00', 'correct subclassing with native classes #3'); + } +}); + +QUnit.test('Number constructor: binary', assert => { + const check = getCheck(assert); + check('0b1', 1); + check('0B1', 1); + check('0b12', NaN); + check('0b234', NaN); + check('0b1!', NaN); + check('+0b1', NaN); + check('-0b1', NaN); + check(' 0b1', 1); + check('0b1\n', 1); + check('\n 0b1\n ', 1); + check(' 0B1', 1); + check('0B1\n', 1); + check('\n 0B1\n ', 1); + check({ + valueOf() { + return '0b11'; + }, + }, 3); + check({ + toString() { + return '0b111'; + }, + }, 7); + check({ + valueOf() { + return '0b101010'; + }, + }, 42); + check({ + toString() { + return '0b101010'; + }, + }, 42); + check(`${ WHITESPACES }0b11`, 3); + check(`0b11${ WHITESPACES }`, 3); + check(`${ WHITESPACES }0b11${ WHITESPACES }`, 3); + check(`${ WHITESPACES }0B11`, 3); + check(`0B11${ WHITESPACES }`, 3); + check(`${ WHITESPACES }0B11${ WHITESPACES }`, 3); +}); + +QUnit.test('Number constructor: octal', assert => { + const check = getCheck(assert); + check('0o7', 7); + check('0O7', 7); + check('0o18', NaN); + check('0o89a', NaN); + check('0o1!', NaN); + check('+0o1', NaN); + check('-0o1', NaN); + check(' 0o1', 1); + check('0o1\n', 1); + check('\n 0o1\n ', 1); + check(' 0O1', 1); + check('0O1\n', 1); + check('\n 0O1\n ', 1); + check({ + valueOf() { + return '0o77'; + }, + }, 63); + check({ + toString() { + return '0o777'; + }, + }, 511); + check({ + valueOf() { + return '0o12345'; + }, + }, 5349); + check({ + toString() { + return '0o12345'; + }, + }, 5349); + check(`${ WHITESPACES }0o11`, 9); + check(`0o11${ WHITESPACES }`, 9); + check(`${ WHITESPACES }0o11${ WHITESPACES }`, 9); + check(`${ WHITESPACES }0O11`, 9); + check(`0O11${ WHITESPACES }`, 9); + check(`${ WHITESPACES }0O11${ WHITESPACES }`, 9); +}); diff --git a/tests/unit-global/es.number.epsilon.js b/tests/unit-global/es.number.epsilon.js new file mode 100644 index 000000000000..a5bb673c11eb --- /dev/null +++ b/tests/unit-global/es.number.epsilon.js @@ -0,0 +1,11 @@ +QUnit.test('Number.EPSILON', assert => { + const { EPSILON } = Number; + assert.true('EPSILON' in Number, 'EPSILON in Number'); + assert.nonEnumerable(Number, 'EPSILON'); + assert.nonConfigurable(Number, 'EPSILON'); + assert.nonWritable(Number, 'EPSILON'); + // eslint-disable-next-line math/prefer-number-epsilon -- testing + assert.same(EPSILON, 2 ** -52, 'Is 2^-52'); + assert.notSame(1, 1 + EPSILON, '1 is not 1 + EPSILON'); + assert.same(1, 1 + EPSILON / 2, '1 is 1 + EPSILON / 2'); +}); diff --git a/tests/unit-global/es.number.is-finite.js b/tests/unit-global/es.number.is-finite.js new file mode 100644 index 000000000000..47eb46cbb22d --- /dev/null +++ b/tests/unit-global/es.number.is-finite.js @@ -0,0 +1,43 @@ +QUnit.test('Number.isFinite', assert => { + const { isFinite } = Number; + const { create } = Object; + assert.isFunction(isFinite); + assert.name(isFinite, 'isFinite'); + assert.arity(isFinite, 1); + assert.looksNative(isFinite); + assert.nonEnumerable(Number, 'isFinite'); + const finite = [ + 1, + 0.1, + -1, + 2 ** 16, + 2 ** 16 - 1, + 2 ** 31, + 2 ** 31 - 1, + 2 ** 32, + 2 ** 32 - 1, + -0, + ]; + for (const value of finite) { + assert.true(isFinite(value), `isFinite ${ typeof value } ${ value }`); + } + const notFinite = [ + NaN, + Infinity, + 'NaN', + '5', + false, + new Number(NaN), + new Number(Infinity), + new Number(5), + new Number(0.1), + undefined, + null, + {}, + function () { /* empty */ }, + ]; + for (const value of notFinite) { + assert.false(isFinite(value), `not isFinite ${ typeof value } ${ value }`); + } + assert.false(isFinite(create(null)), 'Number.isFinite(Object.create(null)) -> false'); +}); diff --git a/tests/unit-global/es.number.is-integer.js b/tests/unit-global/es.number.is-integer.js new file mode 100644 index 000000000000..178717af9eb6 --- /dev/null +++ b/tests/unit-global/es.number.is-integer.js @@ -0,0 +1,43 @@ +QUnit.test('Number.isInteger', assert => { + const { isInteger } = Number; + const { create } = Object; + assert.isFunction(isInteger); + assert.name(isInteger, 'isInteger'); + assert.arity(isInteger, 1); + assert.looksNative(isInteger); + assert.nonEnumerable(Number, 'isInteger'); + const integers = [ + 1, + -1, + 2 ** 16, + 2 ** 16 - 1, + 2 ** 31, + 2 ** 31 - 1, + 2 ** 32, + 2 ** 32 - 1, + -0, + ]; + for (const value of integers) { + assert.true(isInteger(value), `isInteger ${ typeof value } ${ value }`); + } + const notIntegers = [ + NaN, + 0.1, + Infinity, + 'NaN', + '5', + false, + new Number(NaN), + new Number(Infinity), + new Number(5), + new Number(0.1), + undefined, + null, + {}, + function () { /* empty */ }, + ]; + for (const value of notIntegers) { + assert.false(isInteger(value), `not isInteger ${ typeof value } ${ value }`); + } + assert.false(isInteger(create(null)), 'Number.isInteger(Object.create(null)) -> false'); +}); diff --git a/tests/unit-global/es.number.is-nan.js b/tests/unit-global/es.number.is-nan.js new file mode 100644 index 000000000000..2f9613b8534d --- /dev/null +++ b/tests/unit-global/es.number.is-nan.js @@ -0,0 +1,38 @@ +QUnit.test('Number.isNaN', assert => { + const { isNaN } = Number; + const { create } = Object; + assert.isFunction(isNaN); + assert.name(isNaN, 'isNaN'); + assert.arity(isNaN, 1); + assert.looksNative(isNaN); + assert.nonEnumerable(Number, 'isNaN'); + assert.true(isNaN(NaN), 'Number.isNaN NaN'); + const notNaNs = [ + 1, + 0.1, + -1, + 2 ** 16, + 2 ** 16 - 1, + 2 ** 31, + 2 ** 31 - 1, + 2 ** 32, + 2 ** 32 - 1, + -0, + Infinity, + 'NaN', + '5', + false, + new Number(NaN), + new Number(Infinity), + new Number(5), + new Number(0.1), + undefined, + null, + {}, + function () { /* empty */ }, + ]; + for (const value of notNaNs) { + assert.false(isNaN(value), `not Number.isNaN ${ typeof value } ${ value }`); + } + assert.false(isNaN(create(null)), 'Number.isNaN(Object.create(null)) -> false'); +}); diff --git a/tests/unit-global/es.number.is-safe-integer.js b/tests/unit-global/es.number.is-safe-integer.js new file mode 100644 index 000000000000..96deed3117a3 --- /dev/null +++ b/tests/unit-global/es.number.is-safe-integer.js @@ -0,0 +1,49 @@ +import { MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../helpers/constants.js'; + +QUnit.test('Number.isSafeInteger', assert => { + const { isSafeInteger } = Number; + const { create } = Object; + assert.isFunction(isSafeInteger); + assert.name(isSafeInteger, 'isSafeInteger'); + assert.arity(isSafeInteger, 1); + assert.looksNative(isSafeInteger); + assert.nonEnumerable(Number, 'isSafeInteger'); + const safeIntegers = [ + 1, + -1, + 2 ** 16, + 2 ** 16 - 1, + 2 ** 31, + 2 ** 31 - 1, + 2 ** 32, + 2 ** 32 - 1, + -0, + MAX_SAFE_INTEGER, + MIN_SAFE_INTEGER, + ]; + for (const value of safeIntegers) { + assert.true(isSafeInteger(value), `isSafeInteger ${ typeof value } ${ value }`); + } + const notSafeIntegers = [ + MAX_SAFE_INTEGER + 1, + MIN_SAFE_INTEGER - 1, + NaN, + 0.1, + Infinity, + 'NaN', + '5', + false, + new Number(NaN), + new Number(Infinity), + new Number(5), + new Number(0.1), + undefined, + null, + {}, + function () { /* empty */ }, + ]; + for (const value of notSafeIntegers) { + assert.false(isSafeInteger(value), `not isSafeInteger ${ typeof value } ${ value }`); + } + assert.false(isSafeInteger(create(null)), 'Number.isSafeInteger(Object.create(null)) -> false'); +}); diff --git a/tests/unit-global/es.number.max-safe-integer.js b/tests/unit-global/es.number.max-safe-integer.js new file mode 100644 index 000000000000..274bd13bd4fc --- /dev/null +++ b/tests/unit-global/es.number.max-safe-integer.js @@ -0,0 +1,8 @@ +QUnit.test('Number.MAX_SAFE_INTEGER', assert => { + assert.true('MAX_SAFE_INTEGER' in Number); + assert.nonEnumerable(Number, 'MAX_SAFE_INTEGER'); + assert.nonConfigurable(Number, 'MAX_SAFE_INTEGER'); + assert.nonWritable(Number, 'MAX_SAFE_INTEGER'); + // eslint-disable-next-line math/prefer-number-max-safe-integer -- testing + assert.same(Number.MAX_SAFE_INTEGER, 2 ** 53 - 1, 'Is 2^53 - 1'); +}); diff --git a/tests/unit-global/es.number.min-safe-integer.js b/tests/unit-global/es.number.min-safe-integer.js new file mode 100644 index 000000000000..0db7b6c21af6 --- /dev/null +++ b/tests/unit-global/es.number.min-safe-integer.js @@ -0,0 +1,8 @@ +QUnit.test('Number.MIN_SAFE_INTEGER', assert => { + assert.true('MIN_SAFE_INTEGER' in Number); + assert.nonEnumerable(Number, 'MIN_SAFE_INTEGER'); + assert.nonConfigurable(Number, 'MIN_SAFE_INTEGER'); + assert.nonWritable(Number, 'MIN_SAFE_INTEGER'); + // eslint-disable-next-line math/prefer-number-min-safe-integer -- testing + assert.same(Number.MIN_SAFE_INTEGER, -(2 ** 53) + 1, 'Is -2^53 + 1'); +}); diff --git a/tests/unit-global/es.number.parse-float.js b/tests/unit-global/es.number.parse-float.js new file mode 100644 index 000000000000..89631bf913a8 --- /dev/null +++ b/tests/unit-global/es.number.parse-float.js @@ -0,0 +1,27 @@ +import { GLOBAL, WHITESPACES } from '../helpers/constants.js'; + +QUnit.test('Number.parseFloat', assert => { + const { parseFloat } = Number; + assert.isFunction(parseFloat); + assert.name(parseFloat, 'parseFloat'); + assert.arity(parseFloat, 1); + assert.looksNative(parseFloat); + assert.nonEnumerable(Number, 'parseFloat'); + assert.same(parseFloat, GLOBAL.parseFloat); + assert.same(parseFloat('0'), 0); + assert.same(parseFloat(' 0'), 0); + assert.same(parseFloat('+0'), 0); + assert.same(parseFloat(' +0'), 0); + assert.same(parseFloat('-0'), -0); + assert.same(parseFloat(' -0'), -0); + assert.same(parseFloat(`${ WHITESPACES }+0`), 0); + assert.same(parseFloat(`${ WHITESPACES }-0`), -0); + assert.same(parseFloat(null), NaN); + assert.same(parseFloat(undefined), NaN); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('Number.parseFloat test'); + assert.throws(() => parseFloat(symbol), 'throws on symbol argument'); + assert.throws(() => parseFloat(Object(symbol)), 'throws on boxed symbol argument'); + } +}); diff --git a/tests/unit-global/es.number.parse-int.js b/tests/unit-global/es.number.parse-int.js new file mode 100644 index 000000000000..cebe05ab49f2 --- /dev/null +++ b/tests/unit-global/es.number.parse-int.js @@ -0,0 +1,45 @@ +/* eslint-disable prefer-numeric-literals -- required for testing */ +import { GLOBAL, WHITESPACES } from '../helpers/constants.js'; + +QUnit.test('Number.parseInt', assert => { + const { parseInt } = Number; + assert.isFunction(parseInt); + assert.name(parseInt, 'parseInt'); + assert.arity(parseInt, 2); + assert.looksNative(parseInt); + assert.nonEnumerable(Number, 'parseInt'); + assert.same(parseInt, GLOBAL.parseInt); + for (let radix = 2; radix <= 36; ++radix) { + assert.same(parseInt('10', radix), radix, `radix ${ radix }`); + } + const strings = ['01', '08', '10', '42']; + for (const string of strings) { + assert.same(parseInt(string), parseInt(string, 10), `default radix is 10: ${ string }`); + } + assert.same(parseInt('0x16'), parseInt('0x16', 16), 'default radix is 16: 0x16'); + assert.same(parseInt(' 0x16'), parseInt('0x16', 16), 'ignores leading whitespace #1'); + assert.same(parseInt(' 42'), parseInt('42', 10), 'ignores leading whitespace #2'); + assert.same(parseInt(' 08'), parseInt('08', 10), 'ignores leading whitespace #3'); + assert.same(parseInt(`${ WHITESPACES }08`), parseInt('08', 10), 'ignores leading whitespace #4'); + assert.same(parseInt(`${ WHITESPACES }0x16`), parseInt('0x16', 16), 'ignores leading whitespace #5'); + const fakeZero = { + valueOf() { + return 0; + }, + }; + assert.same(parseInt('08', fakeZero), parseInt('08', 10), 'valueOf #1'); + assert.same(parseInt('0x16', fakeZero), parseInt('0x16', 16), 'valueOf #2'); + assert.same(parseInt('-0xF'), -15, 'signed hex #1'); + assert.same(parseInt('-0xF', 16), -15, 'signed hex #2'); + assert.same(parseInt('+0xF'), 15, 'signed hex #3'); + assert.same(parseInt('+0xF', 16), 15, 'signed hex #4'); + assert.same(parseInt('10', -4294967294), 2, 'radix uses ToUint32'); + assert.same(parseInt(null), NaN); + assert.same(parseInt(undefined), NaN); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('Number.parseInt test'); + assert.throws(() => parseInt(symbol), 'throws on symbol argument'); + assert.throws(() => parseInt(Object(symbol)), 'throws on boxed symbol argument'); + } +}); diff --git a/tests/unit-global/es.number.to-exponential.js b/tests/unit-global/es.number.to-exponential.js new file mode 100644 index 000000000000..23acdb058816 --- /dev/null +++ b/tests/unit-global/es.number.to-exponential.js @@ -0,0 +1,139 @@ +QUnit.test('Number#toExponential', assert => { + const { toExponential } = Number.prototype; + assert.isFunction(toExponential); + assert.name(toExponential, 'toExponential'); + assert.arity(toExponential, 1); + assert.looksNative(toExponential); + assert.nonEnumerable(Number.prototype, 'toExponential'); + + assert.same(toExponential.call(0.00008, 3), '8.000e-5'); + assert.same(toExponential.call(0.9, 0), '9e-1'); + assert.same(toExponential.call(1.255, 2), '1.25e+0'); // Chakra Edge 14- / IE11- bug + assert.same(toExponential.call(1843654265.0774949, 5), '1.84365e+9'); + assert.same(toExponential.call(1000000000000000128.0, 0), '1e+18'); + + assert.same(toExponential.call(1), '1e+0'); + assert.same(toExponential.call(1, 0), '1e+0'); + assert.same(toExponential.call(1, 1), '1.0e+0'); + assert.same(toExponential.call(1, 1.1), '1.0e+0'); + assert.same(toExponential.call(1, 0.9), '1e+0'); + assert.same(toExponential.call(1, '0'), '1e+0'); + assert.same(toExponential.call(1, '1'), '1.0e+0'); + assert.same(toExponential.call(1, '1.1'), '1.0e+0'); + assert.same(toExponential.call(1, '0.9'), '1e+0'); + assert.same(toExponential.call(1, NaN), '1e+0'); + assert.same(toExponential.call(1, 'some string'), '1e+0'); + assert.notThrows(() => toExponential.call(1, -0.1) === '1e+0'); + assert.same(toExponential.call(new Number(1)), '1e+0'); + assert.same(toExponential.call(new Number(1), 0), '1e+0'); + assert.same(toExponential.call(new Number(1), 1), '1.0e+0'); + assert.same(toExponential.call(new Number(1), 1.1), '1.0e+0'); + assert.same(toExponential.call(new Number(1), 0.9), '1e+0'); + assert.same(toExponential.call(new Number(1), '0'), '1e+0'); + assert.same(toExponential.call(new Number(1), '1'), '1.0e+0'); + assert.same(toExponential.call(new Number(1), '1.1'), '1.0e+0'); + assert.same(toExponential.call(new Number(1), '0.9'), '1e+0'); + assert.same(toExponential.call(new Number(1), NaN), '1e+0'); + assert.same(toExponential.call(new Number(1), 'some string'), '1e+0'); + assert.notThrows(() => toExponential.call(new Number(1), -0.1) === '1e+0'); + assert.same(toExponential.call(NaN), 'NaN'); + assert.same(toExponential.call(NaN, 0), 'NaN'); + assert.same(toExponential.call(NaN, 1), 'NaN'); + assert.same(toExponential.call(NaN, 1.1), 'NaN'); + assert.same(toExponential.call(NaN, 0.9), 'NaN'); + assert.same(toExponential.call(NaN, '0'), 'NaN'); + assert.same(toExponential.call(NaN, '1'), 'NaN'); + assert.same(toExponential.call(NaN, '1.1'), 'NaN'); + assert.same(toExponential.call(NaN, '0.9'), 'NaN'); + assert.same(toExponential.call(NaN, NaN), 'NaN'); + assert.same(toExponential.call(NaN, 'some string'), 'NaN'); + assert.notThrows(() => toExponential.call(NaN, -0.1) === 'NaN'); + + assert.same(toExponential.call(new Number(1e21)), '1e+21'); + assert.same(toExponential.call(new Number(1e21), 0), '1e+21'); + assert.same(toExponential.call(new Number(1e21), 1), '1.0e+21'); + assert.same(toExponential.call(new Number(1e21), 1.1), '1.0e+21'); + assert.same(toExponential.call(new Number(1e21), 0.9), '1e+21'); + assert.same(toExponential.call(new Number(1e21), '0'), '1e+21'); + assert.same(toExponential.call(new Number(1e21), '1'), '1.0e+21'); + assert.same(toExponential.call(new Number(1e21), '1.1'), '1.0e+21'); + assert.same(toExponential.call(new Number(1e21), '0.9'), '1e+21'); + assert.same(toExponential.call(new Number(1e21), NaN), '1e+21'); + assert.same(toExponential.call(new Number(1e21), 'some string'), '1e+21'); + + // somehow that randomly fails in FF16- on Linux + assert.same(toExponential.call(5, 19), '5.0000000000000000000e+0', '5, 19'); + + // ported from tests262, the license: https://github.com/tc39/test262/blob/main/LICENSE + assert.same(toExponential.call(123.456, 0), '1e+2'); + assert.same(toExponential.call(123.456, 1), '1.2e+2'); + assert.same(toExponential.call(123.456, 2), '1.23e+2'); + assert.same(toExponential.call(123.456, 3), '1.235e+2'); + assert.same(toExponential.call(123.456, 4), '1.2346e+2'); + assert.same(toExponential.call(123.456, 5), '1.23456e+2'); + assert.same(toExponential.call(123.456, 6), '1.234560e+2'); + assert.same(toExponential.call(123.456, 7), '1.2345600e+2'); + // assert.same(toExponential.call(123.456, 17), '1.23456000000000003e+2'); + // assert.same(toExponential.call(123.456, 20), '1.23456000000000003070e+2'); + + assert.same(toExponential.call(-123.456, 0), '-1e+2'); + assert.same(toExponential.call(-123.456, 1), '-1.2e+2'); + assert.same(toExponential.call(-123.456, 2), '-1.23e+2'); + assert.same(toExponential.call(-123.456, 3), '-1.235e+2'); + assert.same(toExponential.call(-123.456, 4), '-1.2346e+2'); + assert.same(toExponential.call(-123.456, 5), '-1.23456e+2'); + assert.same(toExponential.call(-123.456, 6), '-1.234560e+2'); + assert.same(toExponential.call(-123.456, 7), '-1.2345600e+2'); + // assert.same(toExponential.call(-123.456, 17), '-1.23456000000000003e+2'); + // assert.same(toExponential.call(-123.456, 20), '-1.23456000000000003070e+2'); + + assert.same(toExponential.call(0.0001, 0), '1e-4'); + assert.same(toExponential.call(0.0001, 1), '1.0e-4'); + assert.same(toExponential.call(0.0001, 2), '1.00e-4'); + assert.same(toExponential.call(0.0001, 3), '1.000e-4'); + assert.same(toExponential.call(0.0001, 4), '1.0000e-4'); + // assert.same(toExponential.call(0.0001, 16), '1.0000000000000000e-4'); + // assert.same(toExponential.call(0.0001, 17), '1.00000000000000005e-4'); + // assert.same(toExponential.call(0.0001, 18), '1.000000000000000048e-4'); + // assert.same(toExponential.call(0.0001, 19), '1.0000000000000000479e-4'); + // assert.same(toExponential.call(0.0001, 20), '1.00000000000000004792e-4'); + + assert.same(toExponential.call(0.9999, 0), '1e+0'); + assert.same(toExponential.call(0.9999, 1), '1.0e+0'); + assert.same(toExponential.call(0.9999, 2), '1.00e+0'); + assert.same(toExponential.call(0.9999, 3), '9.999e-1'); + assert.same(toExponential.call(0.9999, 4), '9.9990e-1'); + // assert.same(toExponential.call(0.9999, 16), '9.9990000000000001e-1'); + // assert.same(toExponential.call(0.9999, 17), '9.99900000000000011e-1'); + // assert.same(toExponential.call(0.9999, 18), '9.999000000000000110e-1'); + // assert.same(toExponential.call(0.9999, 19), '9.9990000000000001101e-1'); + // assert.same(toExponential.call(0.9999, 20), '9.99900000000000011013e-1'); + + assert.same(toExponential.call(25, 0), '3e+1'); // FF86- and Chrome 49-50 bugs + assert.same(toExponential.call(12345, 3), '1.235e+4'); // FF86- and Chrome 49-50 bugs + + assert.same(toExponential.call(Number.prototype, 0), '0e+0', 'Number.prototype, 0'); + assert.same(toExponential.call(0, 0), '0e+0', '0, 0'); + assert.same(toExponential.call(-0, 0), '0e+0', '-0, 0'); + assert.same(toExponential.call(0, -0), '0e+0', '0, -0'); + assert.same(toExponential.call(-0, -0), '0e+0', '-0, -0'); + assert.same(toExponential.call(0, 1), '0.0e+0', '0 and 1'); + assert.same(toExponential.call(0, 2), '0.00e+0', '0 and 2'); + assert.same(toExponential.call(0, 7), '0.0000000e+0', '0 and 7'); + assert.same(toExponential.call(0, 20), '0.00000000000000000000e+0', '0 and 20'); + assert.same(toExponential.call(-0, 1), '0.0e+0', '-0 and 1'); + assert.same(toExponential.call(-0, 2), '0.00e+0', '-0 and 2'); + assert.same(toExponential.call(-0, 7), '0.0000000e+0', '-0 and 7'); + assert.same(toExponential.call(-0, 20), '0.00000000000000000000e+0', '-0 and 20'); + + assert.same(toExponential.call(NaN, 1000), 'NaN', 'NaN check before fractionDigits check'); + assert.same(toExponential.call(Infinity, 1000), 'Infinity', 'Infinity check before fractionDigits check'); + assert.notThrows(() => toExponential.call(new Number(1e21), -0.1) === '1e+21'); + assert.throws(() => toExponential.call(1.0, -101), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => toExponential.call(1.0, 101), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => toExponential.call({}, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toExponential.call('123', 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toExponential.call(false, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toExponential.call(null, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toExponential.call(undefined, 1), TypeError, '? thisNumberValue(this value)'); +}); diff --git a/tests/unit-global/es.number.to-fixed.js b/tests/unit-global/es.number.to-fixed.js new file mode 100644 index 000000000000..e3ce82a64977 --- /dev/null +++ b/tests/unit-global/es.number.to-fixed.js @@ -0,0 +1,70 @@ +/* eslint-disable unicorn/require-number-to-fixed-digits-argument -- required for testing */ +QUnit.test('Number#toFixed', assert => { + const { toFixed } = Number.prototype; + assert.isFunction(toFixed); + assert.name(toFixed, 'toFixed'); + assert.arity(toFixed, 1); + assert.looksNative(toFixed); + assert.nonEnumerable(Number.prototype, 'toFixed'); + assert.same(0.00008.toFixed(3), '0.000'); + assert.same(0.9.toFixed(0), '1'); + assert.same(1.255.toFixed(2), '1.25'); + assert.same(1843654265.0774949.toFixed(5), '1843654265.07749'); + assert.same(1000000000000000128.0.toFixed(0), '1000000000000000128'); + assert.same(toFixed.call(1), '1'); + assert.same(toFixed.call(1, 0), '1'); + assert.same(toFixed.call(1, 1), '1.0'); + assert.same(toFixed.call(1, 1.1), '1.0'); + assert.same(toFixed.call(1, 0.9), '1'); + assert.same(toFixed.call(1, '0'), '1'); + assert.same(toFixed.call(1, '1'), '1.0'); + assert.same(toFixed.call(1, '1.1'), '1.0'); + assert.same(toFixed.call(1, '0.9'), '1'); + assert.same(toFixed.call(1, NaN), '1'); + assert.same(toFixed.call(1, 'some string'), '1'); + assert.notThrows(() => toFixed.call(1, -0.1) === '1'); + assert.same(new Number(1).toFixed(), '1'); + assert.same(new Number(1).toFixed(0), '1'); + assert.same(new Number(1).toFixed(1), '1.0'); + assert.same(new Number(1).toFixed(1.1), '1.0'); + assert.same(new Number(1).toFixed(0.9), '1'); + assert.same(new Number(1).toFixed('0'), '1'); + assert.same(new Number(1).toFixed('1'), '1.0'); + assert.same(new Number(1).toFixed('1.1'), '1.0'); + assert.same(new Number(1).toFixed('0.9'), '1'); + assert.same(new Number(1).toFixed(NaN), '1'); + assert.same(new Number(1).toFixed('some string'), '1'); + assert.notThrows(() => new Number(1).toFixed(-0.1) === '1'); + assert.same(NaN.toFixed(), 'NaN'); + assert.same(NaN.toFixed(0), 'NaN'); + assert.same(NaN.toFixed(1), 'NaN'); + assert.same(NaN.toFixed(1.1), 'NaN'); + assert.same(NaN.toFixed(0.9), 'NaN'); + assert.same(NaN.toFixed('0'), 'NaN'); + assert.same(NaN.toFixed('1'), 'NaN'); + assert.same(NaN.toFixed('1.1'), 'NaN'); + assert.same(NaN.toFixed('0.9'), 'NaN'); + assert.same(NaN.toFixed(NaN), 'NaN'); + assert.same(NaN.toFixed('some string'), 'NaN'); + assert.notThrows(() => NaN.toFixed(-0.1) === 'NaN'); + assert.same(new Number(1e21).toFixed(), String(1e21)); + assert.same(new Number(1e21).toFixed(0), String(1e21)); + assert.same(new Number(1e21).toFixed(1), String(1e21)); + assert.same(new Number(1e21).toFixed(1.1), String(1e21)); + assert.same(new Number(1e21).toFixed(0.9), String(1e21)); + assert.same(new Number(1e21).toFixed('0'), String(1e21)); + assert.same(new Number(1e21).toFixed('1'), String(1e21)); + assert.same(new Number(1e21).toFixed('1.1'), String(1e21)); + assert.same(new Number(1e21).toFixed('0.9'), String(1e21)); + assert.same(new Number(1e21).toFixed(NaN), String(1e21)); + assert.same(new Number(1e21).toFixed('some string'), String(1e21)); + assert.notThrows(() => new Number(1e21).toFixed(-0.1) === String(1e21)); + assert.throws(() => 1.0.toFixed(-101), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => 1.0.toFixed(101), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => NaN.toFixed(Infinity), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => toFixed.call({}, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toFixed.call('123', 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toFixed.call(false, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toFixed.call(null, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toFixed.call(undefined, 1), TypeError, '? thisNumberValue(this value)'); +}); diff --git a/tests/tests/es.number.to-precision.js b/tests/unit-global/es.number.to-precision.js similarity index 100% rename from tests/tests/es.number.to-precision.js rename to tests/unit-global/es.number.to-precision.js diff --git a/tests/unit-global/es.object.assign.js b/tests/unit-global/es.object.assign.js new file mode 100644 index 000000000000..2537f297e125 --- /dev/null +++ b/tests/unit-global/es.object.assign.js @@ -0,0 +1,67 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Object.assign', assert => { + const { assign, keys, defineProperty } = Object; + assert.isFunction(assign); + assert.arity(assign, 2); + assert.name(assign, 'assign'); + assert.looksNative(assign); + assert.nonEnumerable(Object, 'assign'); + let object = { q: 1 }; + assert.same(object, assign(object, { bar: 2 }), 'assign return target'); + assert.same(object.bar, 2, 'assign define properties'); + assert.deepEqual(assign({}, { q: 1 }, { w: 2 }), { q: 1, w: 2 }); + assert.deepEqual(assign({}, 'qwe'), { 0: 'q', 1: 'w', 2: 'e' }); + assert.throws(() => assign(null, { q: 1 }), TypeError); + assert.throws(() => assign(undefined, { q: 1 }), TypeError); + let string = assign('qwe', { q: 1 }); + assert.same(typeof string, 'object'); + assert.same(String(string), 'qwe'); + assert.same(string.q, 1); + assert.same(assign({}, { valueOf: 42 }).valueOf, 42, 'IE enum keys bug'); + if (DESCRIPTORS) { + object = { baz: 1 }; + assign(object, defineProperty({}, 'bar', { + get() { + return this.baz + 1; + }, + })); + assert.same(object.bar, undefined, "assign don't copy descriptors"); + object = { a: 'a' }; + const c = Symbol('c'); + const d = Symbol('d'); + object[c] = 'c'; + defineProperty(object, 'b', { value: 'b' }); + defineProperty(object, d, { value: 'd' }); + const object2 = assign({}, object); + assert.same(object2.a, 'a', 'a'); + assert.same(object2.b, undefined, 'b'); + assert.same(object2[c], 'c', 'c'); + assert.same(object2[d], undefined, 'd'); + try { + assert.same(Function('assign', ` + return assign({ b: 1 }, { get a() { + delete this.b; + }, b: 2 }); + `)(assign).b, 1); + } catch { /* empty */ } + try { + assert.same(Function('assign', ` + return assign({ b: 1 }, { get a() { + Object.defineProperty(this, "b", { + value: 3, + enumerable: false + }); + }, b: 2 }); + `)(assign).b, 1); + } catch { /* empty */ } + } + string = 'abcdefghijklmnopqrst'; + const result = {}; + for (let i = 0, { length } = string; i < length; ++i) { + const chr = string.charAt(i); + result[chr] = chr; + } + assert.same(keys(assign({}, result)).join(''), string); +}); + diff --git a/tests/unit-global/es.object.create.js b/tests/unit-global/es.object.create.js new file mode 100644 index 000000000000..12d00d07f925 --- /dev/null +++ b/tests/unit-global/es.object.create.js @@ -0,0 +1,36 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Object.create', assert => { + const { create, getPrototypeOf, getOwnPropertyNames } = Object; + function getPropertyNames(object) { + let result = []; + do { + result = result.concat(getOwnPropertyNames(object)); + } while (object = getPrototypeOf(object)); + return result; + } + assert.isFunction(create); + assert.arity(create, 2); + assert.name(create, 'create'); + assert.looksNative(create); + assert.nonEnumerable(Object, 'create'); + let object = { q: 1 }; + assert.true({}.isPrototypeOf.call(object, create(object))); + assert.same(create(object).q, 1); + function F() { + return this.a = 1; + } + assert.true(create(new F()) instanceof F); + assert.same(F.prototype, getPrototypeOf(getPrototypeOf(create(new F())))); + assert.same(create(new F()).a, 1); + assert.same(create({}, { a: { value: 42 } }).a, 42); + object = create(null, { w: { value: 2 } }); + assert.same(object, Object(object)); + assert.false(('toString' in object)); + assert.same(object.w, 2); + assert.deepEqual(getPropertyNames(create(null)), []); +}); + +QUnit.test('Object.create.sham flag', assert => { + assert.same(Object.create.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-global/es.object.define-getter.js b/tests/unit-global/es.object.define-getter.js new file mode 100644 index 000000000000..0966c81ef450 --- /dev/null +++ b/tests/unit-global/es.object.define-getter.js @@ -0,0 +1,25 @@ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + QUnit.test('Object#__defineGetter__', assert => { + const { __defineGetter__ } = Object.prototype; + assert.isFunction(__defineGetter__); + assert.arity(__defineGetter__, 2); + assert.name(__defineGetter__, '__defineGetter__'); + assert.looksNative(__defineGetter__); + assert.nonEnumerable(Object.prototype, '__defineGetter__'); + const object = {}; + assert.same(object.__defineGetter__('key', () => 42), undefined, 'void'); + assert.same(object.key, 42, 'works'); + object.__defineSetter__('key', function () { + this.foo = 43; + }); + object.key = 44; + assert.same(object.key, 42, 'works with getter #1'); + assert.same(object.foo, 43, 'works with getter #2'); + if (STRICT) { + assert.throws(() => __defineGetter__.call(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); + assert.throws(() => __defineGetter__.call(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); + } + }); +} diff --git a/tests/unit-global/es.object.define-properties.js b/tests/unit-global/es.object.define-properties.js new file mode 100644 index 000000000000..8e88034d2bd9 --- /dev/null +++ b/tests/unit-global/es.object.define-properties.js @@ -0,0 +1,27 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Object.defineProperties', assert => { + const { defineProperties } = Object; + assert.isFunction(defineProperties); + assert.arity(defineProperties, 2); + assert.name(defineProperties, 'defineProperties'); + assert.looksNative(defineProperties); + assert.nonEnumerable(Object, 'defineProperties'); + const source = {}; + const result = defineProperties(source, { q: { value: 42 }, w: { value: 33 } }); + assert.same(result, source); + assert.same(result.q, 42); + assert.same(result.w, 33); + + if (DESCRIPTORS) { + // eslint-disable-next-line prefer-arrow-callback -- required for testing + assert.same(defineProperties(function () { /* empty */ }, { prototype: { + value: 42, + writable: false, + } }).prototype, 42, 'function prototype with non-writable descriptor'); + } +}); + +QUnit.test('Object.defineProperties.sham flag', assert => { + assert.same(Object.defineProperties.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-global/es.object.define-property.js b/tests/unit-global/es.object.define-property.js new file mode 100644 index 000000000000..255708032aba --- /dev/null +++ b/tests/unit-global/es.object.define-property.js @@ -0,0 +1,32 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Object.defineProperty', assert => { + const { defineProperty, create } = Object; + assert.isFunction(defineProperty); + assert.arity(defineProperty, 3); + assert.name(defineProperty, 'defineProperty'); + assert.looksNative(defineProperty); + assert.nonEnumerable(Object, 'defineProperty'); + const source = {}; + const result = defineProperty(source, 'q', { + value: 42, + }); + assert.same(result, source); + assert.same(result.q, 42); + + if (DESCRIPTORS) { + // eslint-disable-next-line prefer-arrow-callback -- required for testing + assert.same(defineProperty(function () { /* empty */ }, 'prototype', { + value: 42, + writable: false, + }).prototype, 42, 'function prototype with non-writable descriptor'); + } + + assert.throws(() => defineProperty(42, 1, {})); + assert.throws(() => defineProperty({}, create(null), {})); + assert.throws(() => defineProperty({}, 1, 1)); +}); + +QUnit.test('Object.defineProperty.sham flag', assert => { + assert.same(Object.defineProperty.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-global/es.object.define-setter.js b/tests/unit-global/es.object.define-setter.js new file mode 100644 index 000000000000..00322a259d02 --- /dev/null +++ b/tests/unit-global/es.object.define-setter.js @@ -0,0 +1,30 @@ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + QUnit.test('Object#__defineSetter__', assert => { + const { __defineSetter__ } = Object.prototype; + assert.isFunction(__defineSetter__); + assert.arity(__defineSetter__, 2); + assert.name(__defineSetter__, '__defineSetter__'); + assert.looksNative(__defineSetter__); + assert.nonEnumerable(Object.prototype, '__defineSetter__'); + let object = {}; + assert.same(object.__defineSetter__('key', function () { + this.foo = 43; + }), undefined, 'void'); + object.key = 44; + assert.same(object.foo, 43, 'works'); + object = {}; + object.__defineSetter__('key', function () { + this.foo = 43; + }); + object.__defineGetter__('key', () => 42); + object.key = 44; + assert.same(object.key, 42, 'works with setter #1'); + assert.same(object.foo, 43, 'works with setter #2'); + if (STRICT) { + assert.throws(() => __defineSetter__.call(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); + assert.throws(() => __defineSetter__.call(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); + } + }); +} diff --git a/tests/tests/es.object.entries.js b/tests/unit-global/es.object.entries.js similarity index 100% rename from tests/tests/es.object.entries.js rename to tests/unit-global/es.object.entries.js diff --git a/tests/unit-global/es.object.freeze.js b/tests/unit-global/es.object.freeze.js new file mode 100644 index 000000000000..d2bb37b6ed08 --- /dev/null +++ b/tests/unit-global/es.object.freeze.js @@ -0,0 +1,24 @@ +import { GLOBAL, NATIVE } from '../helpers/constants.js'; + +QUnit.test('Object.freeze', assert => { + const { freeze, isFrozen, keys, getOwnPropertyNames, getOwnPropertySymbols } = Object; + const { ownKeys } = GLOBAL.Reflect || {}; + assert.isFunction(freeze); + assert.arity(freeze, 1); + assert.name(freeze, 'freeze'); + assert.looksNative(freeze); + assert.nonEnumerable(Object, 'freeze'); + const data = [42, 'foo', false, null, undefined, {}]; + for (const value of data) { + assert.notThrows(() => freeze(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); + assert.same(freeze(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); + } + if (NATIVE) assert.true(isFrozen(freeze({}))); + const results = []; + for (const key in freeze({})) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(freeze({})), []); + assert.arrayEqual(getOwnPropertyNames(freeze({})), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(freeze({})), []); + if (ownKeys) assert.arrayEqual(ownKeys(freeze({})), []); +}); diff --git a/tests/unit-global/es.object.from-entries.js b/tests/unit-global/es.object.from-entries.js new file mode 100644 index 000000000000..60c2d7958bcc --- /dev/null +++ b/tests/unit-global/es.object.from-entries.js @@ -0,0 +1,28 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Object.fromEntries', assert => { + const { fromEntries } = Object; + assert.isFunction(fromEntries); + assert.arity(fromEntries, 1); + assert.name(fromEntries, 'fromEntries'); + assert.looksNative(fromEntries); + assert.nonEnumerable(Object, 'fromEntries'); + + assert.true(fromEntries([]) instanceof Object); + assert.same(fromEntries([['foo', 1]]).foo, 1); + assert.same(fromEntries(createIterable([['bar', 2]])).bar, 2); + + class Unit { + constructor(id) { + this.id = id; + } + toString() { + return `unit${ this.id }`; + } + } + const units = new Set([new Unit(101), new Unit(102), new Unit(103)]); + const object = fromEntries(units.entries()); + assert.same(object.unit101.id, 101); + assert.same(object.unit102.id, 102); + assert.same(object.unit103.id, 103); +}); diff --git a/tests/unit-global/es.object.get-own-property-descriptor.js b/tests/unit-global/es.object.get-own-property-descriptor.js new file mode 100644 index 000000000000..8d9f6e539876 --- /dev/null +++ b/tests/unit-global/es.object.get-own-property-descriptor.js @@ -0,0 +1,27 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Object.getOwnPropertyDescriptor', assert => { + const { getOwnPropertyDescriptor } = Object; + assert.isFunction(getOwnPropertyDescriptor); + assert.arity(getOwnPropertyDescriptor, 2); + assert.name(getOwnPropertyDescriptor, 'getOwnPropertyDescriptor'); + assert.looksNative(getOwnPropertyDescriptor); + assert.nonEnumerable(Object, 'getOwnPropertyDescriptor'); + assert.deepEqual(getOwnPropertyDescriptor({ q: 42 }, 'q'), { + writable: true, + enumerable: true, + configurable: true, + value: 42, + }); + assert.same(getOwnPropertyDescriptor({}, 'toString'), undefined); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => getOwnPropertyDescriptor(value) || true, `accept ${ typeof value }`); + } + assert.throws(() => getOwnPropertyDescriptor(null), TypeError, 'throws on null'); + assert.throws(() => getOwnPropertyDescriptor(undefined), TypeError, 'throws on undefined'); +}); + +QUnit.test('Object.getOwnPropertyDescriptor.sham flag', assert => { + assert.same(Object.getOwnPropertyDescriptor.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-global/es.object.get-own-property-descriptors.js b/tests/unit-global/es.object.get-own-property-descriptors.js new file mode 100644 index 000000000000..8b8b9e4653db --- /dev/null +++ b/tests/unit-global/es.object.get-own-property-descriptors.js @@ -0,0 +1,42 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Object.getOwnPropertyDescriptors', assert => { + const { create, getOwnPropertyDescriptors } = Object; + assert.isFunction(getOwnPropertyDescriptors); + assert.arity(getOwnPropertyDescriptors, 1); + assert.name(getOwnPropertyDescriptors, 'getOwnPropertyDescriptors'); + assert.looksNative(getOwnPropertyDescriptors); + assert.nonEnumerable(Object, 'getOwnPropertyDescriptors'); + const object = create({ q: 1 }, { e: { value: 3 } }); + object.w = 2; + const symbol = Symbol('4'); + object[symbol] = 4; + const descriptors = getOwnPropertyDescriptors(object); + assert.same(descriptors.q, undefined); + assert.deepEqual(descriptors.w, { + enumerable: true, + configurable: true, + writable: true, + value: 2, + }); + if (DESCRIPTORS) { + assert.deepEqual(descriptors.e, { + enumerable: false, + configurable: false, + writable: false, + value: 3, + }); + } else { + assert.deepEqual(descriptors.e, { + enumerable: true, + configurable: true, + writable: true, + value: 3, + }); + } + assert.same(descriptors[symbol].value, 4); +}); + +QUnit.test('Object.getOwnPropertyDescriptors.sham flag', assert => { + assert.same(Object.getOwnPropertyDescriptors.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-global/es.object.get-own-property-names.js b/tests/unit-global/es.object.get-own-property-names.js new file mode 100644 index 000000000000..da18ee6374fc --- /dev/null +++ b/tests/unit-global/es.object.get-own-property-names.js @@ -0,0 +1,52 @@ +import { includes } from '../helpers/helpers.js'; + +QUnit.test('Object.getOwnPropertyNames', assert => { + const { freeze, getOwnPropertyNames } = Object; + assert.isFunction(getOwnPropertyNames); + assert.arity(getOwnPropertyNames, 1); + assert.name(getOwnPropertyNames, 'getOwnPropertyNames'); + assert.looksNative(getOwnPropertyNames); + assert.nonEnumerable(Object, 'getOwnPropertyNames'); + function F1() { + this.w = 1; + } + function F2() { + this.toString = 1; + } + F1.prototype.q = F2.prototype.q = 1; + const names = getOwnPropertyNames([1, 2, 3]); + assert.same(names.length, 4); + assert.true(includes(names, '0')); + assert.true(includes(names, '1')); + assert.true(includes(names, '2')); + assert.true(includes(names, 'length')); + assert.deepEqual(getOwnPropertyNames(new F1()), ['w']); + assert.deepEqual(getOwnPropertyNames(new F2()), ['toString']); + assert.true(includes(getOwnPropertyNames(Array.prototype), 'toString')); + assert.true(includes(getOwnPropertyNames(Object.prototype), 'toString')); + assert.true(includes(getOwnPropertyNames(Object.prototype), 'constructor')); + assert.deepEqual(getOwnPropertyNames(freeze({})), [], 'frozen'); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => getOwnPropertyNames(value), `accept ${ typeof value }`); + } + assert.throws(() => { + getOwnPropertyNames(null); + }, TypeError, 'throws on null'); + assert.throws(() => { + getOwnPropertyNames(undefined); + }, TypeError, 'throws on undefined'); + /* Chakra bug + if (typeof document != 'undefined' && document.createElement) { + assert.notThrows(() => { + const iframe = document.createElement('iframe'); + iframe.src = 'http://example.com/'; + document.documentElement.appendChild(iframe); + const window = iframe.contentWindow; + document.documentElement.removeChild(iframe); + return getOwnPropertyNames(window); + }, 'IE11 bug with iframe and window'); + } + */ +}); + diff --git a/tests/unit-global/es.object.get-own-property-symbols.js b/tests/unit-global/es.object.get-own-property-symbols.js new file mode 100644 index 000000000000..a7e7a3b0fadb --- /dev/null +++ b/tests/unit-global/es.object.get-own-property-symbols.js @@ -0,0 +1,30 @@ +const { + getOwnPropertyNames, + getOwnPropertySymbols, + create, +} = Object; + +QUnit.test('Object.getOwnPropertySymbols', assert => { + assert.isFunction(getOwnPropertySymbols); + assert.nonEnumerable(Object, 'getOwnPropertySymbols'); + assert.same(getOwnPropertySymbols.length, 1, 'arity is 1'); + assert.name(getOwnPropertySymbols, 'getOwnPropertySymbols'); + assert.looksNative(getOwnPropertySymbols); + const prototype = { q: 1, w: 2, e: 3 }; + prototype[Symbol('getOwnPropertySymbols test 1')] = 42; + prototype[Symbol('getOwnPropertySymbols test 2')] = 43; + assert.deepEqual(getOwnPropertyNames(prototype).sort(), ['e', 'q', 'w']); + assert.same(getOwnPropertySymbols(prototype).length, 2); + const object = create(prototype); + object.a = 1; + object.s = 2; + object.d = 3; + object[Symbol('getOwnPropertySymbols test 3')] = 44; + assert.deepEqual(getOwnPropertyNames(object).sort(), ['a', 'd', 's']); + assert.same(getOwnPropertySymbols(object).length, 1); + assert.same(getOwnPropertySymbols(Object.prototype).length, 0); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => getOwnPropertySymbols(value), `accept ${ typeof value }`); + } +}); diff --git a/tests/unit-global/es.object.get-prototype-of.js b/tests/unit-global/es.object.get-prototype-of.js new file mode 100644 index 000000000000..43edc1983227 --- /dev/null +++ b/tests/unit-global/es.object.get-prototype-of.js @@ -0,0 +1,35 @@ +import { CORRECT_PROTOTYPE_GETTER } from '../helpers/constants.js'; + +QUnit.test('Object.getPrototypeOf', assert => { + const { create, getPrototypeOf } = Object; + assert.isFunction(getPrototypeOf); + assert.arity(getPrototypeOf, 1); + assert.name(getPrototypeOf, 'getPrototypeOf'); + assert.looksNative(getPrototypeOf); + assert.nonEnumerable(Object, 'getPrototypeOf'); + assert.same(getPrototypeOf({}), Object.prototype); + assert.same(getPrototypeOf([]), Array.prototype); + function F() { /* empty */ } + assert.same(getPrototypeOf(new F()), F.prototype); + const object = { q: 1 }; + assert.same(getPrototypeOf(create(object)), object); + assert.same(getPrototypeOf(create(null)), null); + assert.same(getPrototypeOf(getPrototypeOf({})), null); + function Foo() { /* empty */ } + Foo.prototype.foo = 'foo'; + function Bar() { /* empty */ } + Bar.prototype = create(Foo.prototype); + Bar.prototype.constructor = Bar; + assert.same(getPrototypeOf(Bar.prototype).foo, 'foo'); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => getPrototypeOf(value), `accept ${ typeof value }`); + } + assert.throws(() => getPrototypeOf(null), TypeError, 'throws on null'); + assert.throws(() => getPrototypeOf(undefined), TypeError, 'throws on undefined'); + assert.same(getPrototypeOf('foo'), String.prototype); +}); + +QUnit.test('Object.getPrototypeOf.sham flag', assert => { + assert.same(Object.getPrototypeOf.sham, CORRECT_PROTOTYPE_GETTER ? undefined : true); +}); diff --git a/tests/unit-global/es.object.group-by.js b/tests/unit-global/es.object.group-by.js new file mode 100644 index 000000000000..36ac5a6197e0 --- /dev/null +++ b/tests/unit-global/es.object.group-by.js @@ -0,0 +1,35 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Object.groupBy', assert => { + const { groupBy, getPrototypeOf, entries } = Object; + + assert.isFunction(groupBy); + assert.arity(groupBy, 2); + assert.name(groupBy, 'groupBy'); + assert.looksNative(groupBy); + assert.nonEnumerable(Object, 'groupBy'); + + assert.same(getPrototypeOf(groupBy([], it => it)), null); + + assert.deepEqual(entries(groupBy([], it => it)), []); + assert.deepEqual(entries(groupBy([1, 2], it => it ** 2)), [['1', [1]], ['4', [2]]]); + assert.deepEqual(entries(groupBy([1, 2, 1], it => it ** 2)), [['1', [1, 1]], ['4', [2]]]); + assert.deepEqual(entries(groupBy(createIterable([1, 2]), it => it ** 2)), [['1', [1]], ['4', [2]]]); + assert.deepEqual(entries(groupBy('qwe', it => it)), [['q', ['q']], ['w', ['w']], ['e', ['e']]], 'iterable string'); + + const element = {}; + groupBy([element], function (it, i) { + assert.same(arguments.length, 2); + assert.same(it, element); + assert.same(i, 0); + }); + + const even = Symbol('even'); + const odd = Symbol('odd'); + const grouped = Object.groupBy([1, 2, 3, 4, 5, 6], num => { + if (num % 2 === 0) return even; + return odd; + }); + assert.deepEqual(grouped[even], [2, 4, 6]); + assert.deepEqual(grouped[odd], [1, 3, 5]); +}); diff --git a/tests/unit-global/es.object.has-own.js b/tests/unit-global/es.object.has-own.js new file mode 100644 index 000000000000..6a457cb0b733 --- /dev/null +++ b/tests/unit-global/es.object.has-own.js @@ -0,0 +1,19 @@ +QUnit.test('Object.hasOwn', assert => { + const { create, hasOwn } = Object; + assert.isFunction(hasOwn); + assert.arity(hasOwn, 2); + assert.name(hasOwn, 'hasOwn'); + assert.looksNative(hasOwn); + assert.nonEnumerable(Object, 'hasOwn'); + assert.true(hasOwn({ q: 42 }, 'q')); + assert.false(hasOwn({ q: 42 }, 'w')); + assert.false(hasOwn(create({ q: 42 }), 'q')); + assert.true(hasOwn(Object.prototype, 'hasOwnProperty')); + let called = false; + try { + hasOwn(null, { toString() { called = true; } }); + } catch { /* empty */ } + assert.false(called, 'modern behaviour'); + assert.throws(() => hasOwn(null, 'foo'), TypeError, 'throws on null'); + assert.throws(() => hasOwn(undefined, 'foo'), TypeError, 'throws on undefined'); +}); diff --git a/tests/unit-global/es.object.is-extensible.js b/tests/unit-global/es.object.is-extensible.js new file mode 100644 index 000000000000..70ee72dee95b --- /dev/null +++ b/tests/unit-global/es.object.is-extensible.js @@ -0,0 +1,18 @@ +import { NATIVE } from '../helpers/constants.js'; + +QUnit.test('Object.isExtensible', assert => { + const { preventExtensions, isExtensible } = Object; + assert.isFunction(isExtensible); + assert.arity(isExtensible, 1); + assert.name(isExtensible, 'isExtensible'); + assert.nonEnumerable(Object, 'isExtensible'); + assert.looksNative(isExtensible); + const primitives = [42, 'string', false, null, undefined]; + for (const value of primitives) { + assert.notThrows(() => isExtensible(value) || true, `accept ${ value }`); + assert.false(isExtensible(value), `returns true on ${ value }`); + } + assert.true(isExtensible({})); + if (NATIVE) assert.false(isExtensible(preventExtensions({}))); +}); + diff --git a/tests/unit-global/es.object.is-frozen.js b/tests/unit-global/es.object.is-frozen.js new file mode 100644 index 000000000000..47669dfd52a1 --- /dev/null +++ b/tests/unit-global/es.object.is-frozen.js @@ -0,0 +1,17 @@ +import { NATIVE } from '../helpers/constants.js'; + +QUnit.test('Object.isFrozen', assert => { + const { freeze, isFrozen } = Object; + assert.isFunction(isFrozen); + assert.arity(isFrozen, 1); + assert.name(isFrozen, 'isFrozen'); + assert.looksNative(isFrozen); + assert.nonEnumerable(Object, 'isFrozen'); + const primitives = [42, 'string', false, null, undefined]; + for (const value of primitives) { + assert.notThrows(() => isFrozen(value) || true, `accept ${ value }`); + assert.true(isFrozen(value), `returns true on ${ value }`); + } + assert.false(isFrozen({})); + if (NATIVE) assert.true(isFrozen(freeze({}))); +}); diff --git a/tests/unit-global/es.object.is-sealed.js b/tests/unit-global/es.object.is-sealed.js new file mode 100644 index 000000000000..a282a5cedd3e --- /dev/null +++ b/tests/unit-global/es.object.is-sealed.js @@ -0,0 +1,17 @@ +import { NATIVE } from '../helpers/constants.js'; + +QUnit.test('Object.isSealed', assert => { + const { seal, isSealed } = Object; + assert.isFunction(isSealed); + assert.arity(isSealed, 1); + assert.name(isSealed, 'isSealed'); + assert.looksNative(isSealed); + assert.nonEnumerable(Object, 'isSealed'); + const primitives = [42, 'string', false, null, undefined]; + for (const value of primitives) { + assert.notThrows(() => isSealed(value) || true, `accept ${ value }`); + assert.true(isSealed(value), `returns true on ${ value }`); + } + assert.false(isSealed({})); + if (NATIVE) assert.true(isSealed(seal({}))); +}); diff --git a/tests/unit-global/es.object.is.js b/tests/unit-global/es.object.is.js new file mode 100644 index 000000000000..ef8f3daecaf9 --- /dev/null +++ b/tests/unit-global/es.object.is.js @@ -0,0 +1,12 @@ +QUnit.test('Object.is', assert => { + const { is } = Object; + assert.isFunction(is); + assert.arity(is, 2); + assert.name(is, 'is'); + assert.looksNative(is); + assert.nonEnumerable(Object, 'is'); + assert.true(is(1, 1), '1 is 1'); + assert.true(is(NaN, NaN), '1 is 1'); + assert.false(is(0, -0), '0 is not -0'); + assert.false(is({}, {}), '{} is not {}'); +}); diff --git a/tests/unit-global/es.object.keys.js b/tests/unit-global/es.object.keys.js new file mode 100644 index 000000000000..8616e5453d41 --- /dev/null +++ b/tests/unit-global/es.object.keys.js @@ -0,0 +1,28 @@ +import { includes } from '../helpers/helpers.js'; + +QUnit.test('Object.keys', assert => { + const { keys } = Object; + assert.isFunction(keys); + assert.arity(keys, 1); + assert.name(keys, 'keys'); + assert.looksNative(keys); + assert.nonEnumerable(Object, 'keys'); + function F1() { + this.w = 1; + } + function F2() { + this.toString = 1; + } + F1.prototype.q = F2.prototype.q = 1; + assert.deepEqual(keys([1, 2, 3]), ['0', '1', '2']); + assert.deepEqual(keys(new F1()), ['w']); + assert.deepEqual(keys(new F2()), ['toString']); + assert.false(includes(keys(Array.prototype), 'push')); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => keys(value), `accept ${ typeof value }`); + } + assert.throws(() => keys(null), TypeError, 'throws on null'); + assert.throws(() => keys(undefined), TypeError, 'throws on undefined'); +}); + diff --git a/tests/unit-global/es.object.lookup-getter.js b/tests/unit-global/es.object.lookup-getter.js new file mode 100644 index 000000000000..8930bc2a5de6 --- /dev/null +++ b/tests/unit-global/es.object.lookup-getter.js @@ -0,0 +1,25 @@ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + QUnit.test('Object#__lookupGetter__', assert => { + const { __lookupGetter__ } = Object.prototype; + const { create } = Object; + assert.isFunction(__lookupGetter__); + assert.arity(__lookupGetter__, 1); + assert.name(__lookupGetter__, '__lookupGetter__'); + assert.looksNative(__lookupGetter__); + assert.nonEnumerable(Object.prototype, '__lookupGetter__'); + assert.same({}.__lookupGetter__('key'), undefined, 'empty object'); + assert.same({ key: 42 }.__lookupGetter__('key'), undefined, 'data descriptor'); + const object = {}; + function setter() { /* empty */ } + object.__defineGetter__('key', setter); + assert.same(object.__lookupGetter__('key'), setter, 'own getter'); + assert.same(create(object).__lookupGetter__('key'), setter, 'proto getter'); + assert.same(create(object).__lookupGetter__('foo'), undefined, 'empty proto'); + if (STRICT) { + assert.throws(() => __lookupGetter__.call(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); + assert.throws(() => __lookupGetter__.call(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); + } + }); +} diff --git a/tests/unit-global/es.object.lookup-setter.js b/tests/unit-global/es.object.lookup-setter.js new file mode 100644 index 000000000000..3a3afdac0271 --- /dev/null +++ b/tests/unit-global/es.object.lookup-setter.js @@ -0,0 +1,25 @@ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + QUnit.test('Object#__lookupSetter__', assert => { + const { __lookupSetter__ } = Object.prototype; + const { create } = Object; + assert.isFunction(__lookupSetter__); + assert.arity(__lookupSetter__, 1); + assert.name(__lookupSetter__, '__lookupSetter__'); + assert.looksNative(__lookupSetter__); + assert.nonEnumerable(Object.prototype, '__lookupSetter__'); + assert.same({}.__lookupSetter__('key'), undefined, 'empty object'); + assert.same({ key: 42 }.__lookupSetter__('key'), undefined, 'data descriptor'); + const object = {}; + function setter() { /* empty */ } + object.__defineSetter__('key', setter); + assert.same(object.__lookupSetter__('key'), setter, 'own getter'); + assert.same(create(object).__lookupSetter__('key'), setter, 'proto getter'); + assert.same(create(object).__lookupSetter__('foo'), undefined, 'empty proto'); + if (STRICT) { + assert.throws(() => __lookupSetter__.call(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); + assert.throws(() => __lookupSetter__.call(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); + } + }); +} diff --git a/tests/unit-global/es.object.prevent-extensions.js b/tests/unit-global/es.object.prevent-extensions.js new file mode 100644 index 000000000000..35a86c0c24fd --- /dev/null +++ b/tests/unit-global/es.object.prevent-extensions.js @@ -0,0 +1,24 @@ +import { GLOBAL, NATIVE } from '../helpers/constants.js'; + +QUnit.test('Object.preventExtensions', assert => { + const { preventExtensions, keys, isExtensible, getOwnPropertyNames, getOwnPropertySymbols } = Object; + const { ownKeys } = GLOBAL.Reflect || {}; + assert.isFunction(preventExtensions); + assert.arity(preventExtensions, 1); + assert.name(preventExtensions, 'preventExtensions'); + assert.looksNative(preventExtensions); + assert.nonEnumerable(Object, 'preventExtensions'); + const data = [42, 'foo', false, null, undefined, {}]; + for (const value of data) { + assert.notThrows(() => preventExtensions(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); + assert.same(preventExtensions(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); + } + if (NATIVE) assert.false(isExtensible(preventExtensions({}))); + const results = []; + for (const key in preventExtensions({})) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(preventExtensions({})), []); + assert.arrayEqual(getOwnPropertyNames(preventExtensions({})), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(preventExtensions({})), []); + if (ownKeys) assert.arrayEqual(ownKeys(preventExtensions({})), []); +}); diff --git a/tests/unit-global/es.object.proto.js b/tests/unit-global/es.object.proto.js new file mode 100644 index 000000000000..9ce53247dd25 --- /dev/null +++ b/tests/unit-global/es.object.proto.js @@ -0,0 +1,14 @@ +/* eslint-disable no-proto -- required for testing */ +import { DESCRIPTORS, PROTO } from '../helpers/constants.js'; + +if (PROTO && DESCRIPTORS) QUnit.test('Object.prototype.__proto__', assert => { + assert.true('__proto__' in Object.prototype, 'in Object.prototype'); + const O = {}; + assert.same(O.__proto__, Object.prototype); + O.__proto__ = Array.prototype; + assert.same(O.__proto__, Array.prototype); + assert.same(Object.getPrototypeOf(O), Array.prototype); + assert.true(O instanceof Array); + O.__proto__ = null; + assert.same(Object.getPrototypeOf(O), null); +}); diff --git a/tests/unit-global/es.object.seal.js b/tests/unit-global/es.object.seal.js new file mode 100644 index 000000000000..75ffc2daf33f --- /dev/null +++ b/tests/unit-global/es.object.seal.js @@ -0,0 +1,24 @@ +import { GLOBAL, NATIVE } from '../helpers/constants.js'; + +QUnit.test('Object.seal', assert => { + const { seal, isSealed, keys, getOwnPropertyNames, getOwnPropertySymbols } = Object; + const { ownKeys } = GLOBAL.Reflect || {}; + assert.isFunction(seal); + assert.arity(seal, 1); + assert.name(seal, 'seal'); + assert.looksNative(seal); + assert.nonEnumerable(Object, 'seal'); + const data = [42, 'foo', false, null, undefined, {}]; + for (const value of data) { + assert.notThrows(() => seal(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); + assert.same(seal(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); + } + if (NATIVE) assert.true(isSealed(seal({}))); + const results = []; + for (const key in seal({})) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(seal({})), []); + assert.arrayEqual(getOwnPropertyNames(seal({})), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(seal({})), []); + if (ownKeys) assert.arrayEqual(ownKeys(seal({})), []); +}); diff --git a/tests/unit-global/es.object.set-prototype-of.js b/tests/unit-global/es.object.set-prototype-of.js new file mode 100644 index 000000000000..4f9680c65652 --- /dev/null +++ b/tests/unit-global/es.object.set-prototype-of.js @@ -0,0 +1,19 @@ +import { PROTO } from '../helpers/constants.js'; + +if (PROTO) QUnit.test('Object.setPrototypeOf', assert => { + const { setPrototypeOf } = Object; + assert.isFunction(setPrototypeOf); + assert.arity(setPrototypeOf, 2); + assert.name(setPrototypeOf, 'setPrototypeOf'); + assert.looksNative(setPrototypeOf); + assert.nonEnumerable(Object, 'setPrototypeOf'); + assert.true('apply' in setPrototypeOf({}, Function.prototype), 'Parent properties in target'); + assert.same(setPrototypeOf({ a: 2 }, { + b() { + return this.a ** 2; + }, + }).b(), 4, 'Child and parent properties in target'); + const object = {}; + assert.same(setPrototypeOf(object, { a: 1 }), object, 'setPrototypeOf return target'); + assert.false(('toString' in setPrototypeOf({}, null)), 'Can set null as prototype'); +}); diff --git a/tests/unit-global/es.object.to-string.js b/tests/unit-global/es.object.to-string.js new file mode 100644 index 000000000000..7b1d1507beff --- /dev/null +++ b/tests/unit-global/es.object.to-string.js @@ -0,0 +1,87 @@ +import { GLOBAL, STRICT } from '../helpers/constants.js'; + +QUnit.test('Object#toString', assert => { + const { toString } = Object.prototype; + const Symbol = GLOBAL.Symbol || {}; + assert.arity(toString, 0); + assert.name(toString, 'toString'); + assert.looksNative(toString); + assert.nonEnumerable(Object.prototype, 'toString'); + if (STRICT) { + assert.same(toString.call(null), '[object Null]', 'null -> `Null`'); + assert.same(toString.call(undefined), '[object Undefined]', 'undefined -> `Undefined`'); + } + assert.same(toString.call(true), '[object Boolean]', 'bool -> `Boolean`'); + assert.same(toString.call('string'), '[object String]', 'string -> `String`'); + assert.same(toString.call(7), '[object Number]', 'number -> `Number`'); + assert.same(`${ {} }`, '[object Object]', '{} -> `Object`'); + assert.same(toString.call([]), '[object Array]', ' [] -> `Array`'); + assert.same(toString.call(() => { /* empty */ }), '[object Function]', 'function -> `Function`'); + assert.same(toString.call(/./), '[object RegExp]', 'regexp -> `RegExp`'); + assert.same(toString.call(new TypeError()), '[object Error]', 'new TypeError -> `Error`'); + assert.same(toString.call(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }()), '[object Arguments]', 'arguments -> `Arguments`'); + const constructors = [ + 'Array', + 'RegExp', + 'Boolean', + 'String', + 'Number', + 'Error', + 'Int8Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'Int16Array', + 'Uint16Array', + 'Int32Array', + 'Uint32Array', + 'Float32Array', + 'Float64Array', + 'ArrayBuffer', + ]; + for (const name of constructors) { + const Constructor = GLOBAL[name]; + if (Constructor) { + assert.same(toString.call(new Constructor(1)), `[object ${ name }]`, `new ${ name }(1) -> \`${ name }\``); + } + } + if (GLOBAL.DataView) { + assert.same(`${ new DataView(new ArrayBuffer(1)) }`, '[object DataView]', 'dataview -> `DataView`'); + } + if (GLOBAL.Set) { + assert.same(`${ new Set() }`, '[object Set]', 'set -> `Set`'); + } + if (GLOBAL.Map) { + assert.same(`${ new Map() }`, '[object Map]', 'map -> `Map`'); + } + if (GLOBAL.WeakSet) { + assert.same(`${ new WeakSet() }`, '[object WeakSet]', 'weakset -> `WeakSet`'); + } + if (GLOBAL.WeakMap) { + assert.same(`${ new WeakMap() }`, '[object WeakMap]', 'weakmap -> `WeakMap`'); + } + if (GLOBAL.Promise) { + assert.same(`${ new Promise((() => { /* empty */ })) }`, '[object Promise]', 'promise -> `Promise`'); + } + if (''[Symbol.iterator]) { + assert.same(`${ ''[Symbol.iterator]() }`, '[object String Iterator]', 'String Iterator -> `String Iterator`'); + } + if ([].entries) { + assert.same(`${ [].entries() }`, '[object Array Iterator]', 'Array Iterator -> `Array Iterator`'); + } + if (GLOBAL.Set && Set.prototype.entries) { + assert.same(`${ new Set().entries() }`, '[object Set Iterator]', 'Set Iterator -> `Set Iterator`'); + } + if (GLOBAL.Map && Map.prototype.entries) { + assert.same(`${ new Map().entries() }`, '[object Map Iterator]', 'Map Iterator -> `Map Iterator`'); + } + assert.same(`${ Math }`, '[object Math]', 'Math -> `Math`'); + if (GLOBAL.JSON) { + assert.same(`${ JSON }`, '[object JSON]', 'JSON -> `JSON`'); + } + function Class() { /* empty */ } + Class.prototype[Symbol.toStringTag] = 'Class'; + assert.same(`${ new Class() }`, '[object Class]', 'user class instance -> [Symbol.toStringTag]'); +}); diff --git a/tests/tests/es.object.values.js b/tests/unit-global/es.object.values.js similarity index 100% rename from tests/tests/es.object.values.js rename to tests/unit-global/es.object.values.js diff --git a/tests/unit-global/es.parse-float.js b/tests/unit-global/es.parse-float.js new file mode 100644 index 000000000000..e78e04acfcce --- /dev/null +++ b/tests/unit-global/es.parse-float.js @@ -0,0 +1,26 @@ +import { WHITESPACES } from '../helpers/constants.js'; + +QUnit.test('parseFloat', assert => { + assert.isFunction(parseFloat); + assert.name(parseFloat, 'parseFloat'); + assert.arity(parseFloat, 1); + assert.looksNative(parseFloat); + assert.same(parseFloat('0'), 0); + assert.same(parseFloat(' 0'), 0); + assert.same(parseFloat('+0'), 0); + assert.same(parseFloat(' +0'), 0); + assert.same(parseFloat('-0'), -0); + assert.same(parseFloat(' -0'), -0); + assert.same(parseFloat(`${ WHITESPACES }+0`), 0); + assert.same(parseFloat(`${ WHITESPACES }-0`), -0); + // eslint-disable-next-line math/no-static-nan-calculations -- feature detection + assert.same(parseFloat(null), NaN); + // eslint-disable-next-line math/no-static-nan-calculations -- feature detection + assert.same(parseFloat(undefined), NaN); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('parseFloat test'); + assert.throws(() => parseFloat(symbol), 'throws on symbol argument'); + assert.throws(() => parseFloat(Object(symbol)), 'throws on boxed symbol argument'); + } +}); diff --git a/tests/unit-global/es.parse-int.js b/tests/unit-global/es.parse-int.js new file mode 100644 index 000000000000..f8441d8ff03e --- /dev/null +++ b/tests/unit-global/es.parse-int.js @@ -0,0 +1,46 @@ +/* eslint-disable prefer-numeric-literals -- required for testing */ +import { WHITESPACES } from '../helpers/constants.js'; + +/* eslint-disable radix -- required for testing */ +QUnit.test('parseInt', assert => { + assert.isFunction(parseInt); + assert.name(parseInt, 'parseInt'); + assert.arity(parseInt, 2); + assert.looksNative(parseInt); + for (let radix = 2; radix <= 36; ++radix) { + assert.same(parseInt('10', radix), radix, `radix ${ radix }`); + } + const strings = ['01', '08', '10', '42']; + for (const string of strings) { + assert.same(parseInt(string), parseInt(string, 10), `default radix is 10: ${ string }`); + } + assert.same(parseInt('0x16'), parseInt('0x16', 16), 'default radix is 16: 0x16'); + assert.same(parseInt(' 0x16'), parseInt('0x16', 16), 'ignores leading whitespace #1'); + assert.same(parseInt(' 42'), parseInt('42', 10), 'ignores leading whitespace #2'); + assert.same(parseInt(' 08'), parseInt('08', 10), 'ignores leading whitespace #3'); + assert.same(parseInt(`${ WHITESPACES }08`), parseInt('08', 10), 'ignores leading whitespace #4'); + assert.same(parseInt(`${ WHITESPACES }0x16`), parseInt('0x16', 16), 'ignores leading whitespace #5'); + const fakeZero = { + valueOf() { + return 0; + }, + }; + assert.same(parseInt('08', fakeZero), parseInt('08', 10), 'valueOf #1'); + assert.same(parseInt('0x16', fakeZero), parseInt('0x16', 16), 'valueOf #2'); + assert.same(parseInt('-0xF'), -15, 'signed hex #1'); + assert.same(parseInt('-0xF', 16), -15, 'signed hex #2'); + assert.same(parseInt('+0xF'), 15, 'signed hex #3'); + assert.same(parseInt('+0xF', 16), 15, 'signed hex #4'); + assert.same(parseInt('10', -4294967294), 2, 'radix uses ToUint32'); + // eslint-disable-next-line math/no-static-nan-calculations -- feature detection + assert.same(parseInt(null), NaN); + // eslint-disable-next-line math/no-static-nan-calculations -- feature detection + assert.same(parseInt(undefined), NaN); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('parseInt test'); + assert.throws(() => parseInt(symbol), 'throws on symbol argument'); + assert.throws(() => parseInt(Object(symbol)), 'throws on boxed symbol argument'); + } +}); + diff --git a/tests/unit-global/es.promise.all-settled.js b/tests/unit-global/es.promise.all-settled.js new file mode 100644 index 000000000000..37ad7d41dfdd --- /dev/null +++ b/tests/unit-global/es.promise.all-settled.js @@ -0,0 +1,130 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Promise.allSettled', assert => { + assert.isFunction(Promise.allSettled); + assert.arity(Promise.allSettled, 1); + assert.looksNative(Promise.allSettled); + assert.nonEnumerable(Promise, 'allSettled'); + assert.true(Promise.allSettled([1, 2, 3]) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.allSettled, resolved', assert => { + return Promise.allSettled([ + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [ + { value: 1, status: 'fulfilled' }, + { value: 2, status: 'fulfilled' }, + { value: 3, status: 'fulfilled' }, + ], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.allSettled, resolved with rejection', assert => { + return Promise.allSettled([ + Promise.resolve(1), + Promise.reject(2), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [ + { value: 1, status: 'fulfilled' }, + { reason: 2, status: 'rejected' }, + { value: 3, status: 'fulfilled' }, + ], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.allSettled, rejected', assert => { + // eslint-disable-next-line promise/valid-params -- required for testing + return Promise.allSettled().then(() => { + assert.avoid(); + }, () => { + assert.required('rejected as expected'); + }); +}); + +QUnit.test('Promise.allSettled, resolved with timeouts', assert => { + return Promise.allSettled([ + Promise.resolve(1), + new Promise(resolve => setTimeout(() => resolve(2), 10)), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [ + { value: 1, status: 'fulfilled' }, + { value: 2, status: 'fulfilled' }, + { value: 3, status: 'fulfilled' }, + ], 'keeps correct mapping, even with delays'); + }); +}); + +QUnit.test('Promise.allSettled, subclassing', assert => { + const { allSettled, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = resolve.bind(Promise); + assert.true(allSettled.call(SubPromise, [1, 2, 3]) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise); + assert.throws(() => { + allSettled.call(FakePromise1, [1, 2, 3]); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + allSettled.call(FakePromise2, [1, 2, 3]); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + allSettled.call(FakePromise3, [1, 2, 3]); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.allSettled, iterables', assert => { + const iterable = createIterable([1, 2, 3]); + Promise.allSettled(iterable).catch(() => { /* empty */ }); + assert.true(iterable.received, 'works with iterables: iterator received'); + assert.true(iterable.called, 'works with iterables: next called'); +}); + +QUnit.test('Promise.allSettled, iterables 2', assert => { + const array = []; + let done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + Promise.allSettled(array); + assert.true(done); +}); + +QUnit.test('Promise.allSettled, iterator closing', assert => { + const { resolve } = Promise; + let done = false; + try { + Promise.resolve = function () { + throw new Error(); + }; + Promise.allSettled(createIterable([1, 2, 3], { + return() { + done = true; + }, + })).catch(() => { /* empty */ }); + } catch { /* empty */ } + Promise.resolve = resolve; + assert.true(done, 'iteration closing'); +}); + +QUnit.test('Promise.allSettled, without constructor context', assert => { + const { allSettled } = Promise; + assert.throws(() => allSettled([]), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => allSettled.call(null, []), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-global/es.promise.all.js b/tests/unit-global/es.promise.all.js new file mode 100644 index 000000000000..1e24a1866581 --- /dev/null +++ b/tests/unit-global/es.promise.all.js @@ -0,0 +1,119 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Promise.all', assert => { + const { all } = Promise; + assert.isFunction(all); + assert.arity(all, 1); + assert.name(all, 'all'); + assert.looksNative(all); + assert.nonEnumerable(Promise, 'all'); + assert.true(Promise.all([]) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.all, resolved', assert => { + return Promise.all([ + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [1, 2, 3], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.all, resolved with rejection', assert => { + return Promise.all([ + Promise.resolve(1), + Promise.reject(2), + Promise.resolve(3), + ]).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 2, 'rejected with a correct value'); + }); +}); + +QUnit.test('Promise.all, resolved with empty array', assert => { + return Promise.all([]).then(it => { + assert.deepEqual(it, [], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.all, resolved with timeouts', assert => { + return Promise.all([ + Promise.resolve(1), + new Promise(resolve => setTimeout(() => resolve(2), 10)), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [1, 2, 3], 'keeps correct mapping, even with delays'); + }); +}); + +QUnit.test('Promise.all, subclassing', assert => { + const { all, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = resolve.bind(Promise); + assert.true(all.call(SubPromise, [1, 2, 3]) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise); + assert.throws(() => { + all.call(FakePromise1, [1, 2, 3]); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + all.call(FakePromise2, [1, 2, 3]); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + all.call(FakePromise3, [1, 2, 3]); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.all, iterables', assert => { + const iterable = createIterable([1, 2, 3]); + Promise.all(iterable).catch(() => { /* empty */ }); + assert.true(iterable.received, 'works with iterables: iterator received'); + assert.true(iterable.called, 'works with iterables: next called'); +}); + +QUnit.test('Promise.all, iterables 2', assert => { + const array = []; + let done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + Promise.all(array); + assert.true(done); +}); + +QUnit.test('Promise.all, iterator closing', assert => { + const { resolve } = Promise; + let done = false; + try { + Promise.resolve = function () { + throw new Error(); + }; + Promise.all(createIterable([1, 2, 3], { + return() { + done = true; + }, + })).catch(() => { /* empty */ }); + } catch { /* empty */ } + Promise.resolve = resolve; + assert.true(done, 'iteration closing'); +}); + +QUnit.test('Promise.all, without constructor context', assert => { + const { all } = Promise; + assert.throws(() => all([]), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => all.call(null, []), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-global/es.promise.any.js b/tests/unit-global/es.promise.any.js new file mode 100644 index 000000000000..2660051e46f5 --- /dev/null +++ b/tests/unit-global/es.promise.any.js @@ -0,0 +1,133 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Promise.any', assert => { + assert.isFunction(Promise.any); + assert.arity(Promise.any, 1); + assert.looksNative(Promise.any); + assert.nonEnumerable(Promise, 'any'); + assert.true(Promise.any([1, 2, 3]) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.any, resolved', assert => { + return Promise.any([ + Promise.resolve(1), + Promise.reject(2), + Promise.resolve(3), + ]).then(it => { + assert.same(it, 1, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.any, rejected #1', assert => { + return Promise.any([ + Promise.reject(1), + Promise.reject(2), + Promise.reject(3), + ]).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof AggregateError, 'instanceof AggregateError'); + assert.deepEqual(error.errors, [1, 2, 3], 'rejected with a correct value'); + }); +}); + +QUnit.test('Promise.any, rejected #2', assert => { + // eslint-disable-next-line promise/valid-params -- required for testing + return Promise.any().then(() => { + assert.avoid(); + }, () => { + assert.required('rejected as expected'); + }); +}); + +QUnit.test('Promise.any, rejected #3', assert => { + return Promise.any([]).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof AggregateError, 'instanceof AggregateError'); + assert.deepEqual(error.errors, [], 'rejected with a correct value'); + }); +}); + +QUnit.test('Promise.any, resolved with timeout', assert => { + return Promise.any([ + new Promise(resolve => setTimeout(() => resolve(1), 50)), + Promise.resolve(2), + ]).then(it => { + assert.same(it, 2, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.any, subclassing', assert => { + const { any, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = resolve.bind(Promise); + assert.true(any.call(SubPromise, [1, 2, 3]) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise); + assert.throws(() => { + any.call(FakePromise1, [1, 2, 3]); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + any.call(FakePromise2, [1, 2, 3]); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + any.call(FakePromise3, [1, 2, 3]); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.any, iterables', assert => { + const iterable = createIterable([1, 2, 3]); + Promise.any(iterable).catch(() => { /* empty */ }); + assert.true(iterable.received, 'works with iterables: iterator received'); + assert.true(iterable.called, 'works with iterables: next called'); +}); + +QUnit.test('Promise.any, empty iterables', assert => { + const array = []; + let done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + return Promise.any(array).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof AggregateError, 'instanceof AggregateError'); + assert.true(done, 'iterator called'); + }); +}); + +QUnit.test('Promise.any, iterator closing', assert => { + const { resolve } = Promise; + let done = false; + try { + Promise.resolve = function () { + throw new Error(); + }; + Promise.any(createIterable([1, 2, 3], { + return() { + done = true; + }, + })).catch(() => { /* empty */ }); + } catch { /* empty */ } + Promise.resolve = resolve; + assert.true(done, 'iteration closing'); +}); + +QUnit.test('Promise.any, without constructor context', assert => { + const { any } = Promise; + assert.throws(() => any([]), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => any.call(null, []), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-global/es.promise.catch.js b/tests/unit-global/es.promise.catch.js new file mode 100644 index 000000000000..bf9106c1ce6a --- /dev/null +++ b/tests/unit-global/es.promise.catch.js @@ -0,0 +1,54 @@ +import { NATIVE } from '../helpers/constants.js'; + +QUnit.test('Promise#catch', assert => { + assert.isFunction(Promise.prototype.catch); + if (NATIVE) assert.arity(Promise.prototype.catch, 1); + if (NATIVE) assert.name(Promise.prototype.catch, 'catch'); + assert.looksNative(Promise.prototype.catch); + assert.nonEnumerable(Promise.prototype, 'catch'); + let promise = new Promise(resolve => { + resolve(42); + }); + const FakePromise1 = promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + const FakePromise2 = FakePromise1[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(promise.catch(() => { /* empty */ }) instanceof FakePromise2, 'subclassing, @@species pattern'); + promise = new Promise(resolve => { + resolve(42); + }); + promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(promise.catch(() => { /* empty */ }) instanceof Promise, 'subclassing, incorrect `this` pattern'); + promise = new Promise(resolve => { + resolve(42); + }); + const FakePromise3 = promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + FakePromise3[Symbol.species] = function () { /* empty */ }; + assert.throws(() => { + promise.catch(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #1'); + FakePromise3[Symbol.species] = function (executor) { + executor(null, () => { /* empty */ }); + }; + assert.throws(() => { + promise.catch(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #2'); + FakePromise3[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, null); + }; + assert.throws(() => { + promise.catch(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #3'); + assert.same(Promise.prototype.catch.call({ + // eslint-disable-next-line unicorn/no-thenable -- required for testing + then(x, y) { + return y; + }, + }, 42), 42, 'calling `.then`'); +}); diff --git a/tests/unit-global/es.promise.constructor.js b/tests/unit-global/es.promise.constructor.js new file mode 100644 index 000000000000..9c18e84b9743 --- /dev/null +++ b/tests/unit-global/es.promise.constructor.js @@ -0,0 +1,241 @@ +import { DESCRIPTORS, GLOBAL, NATIVE, PROTO, STRICT } from '../helpers/constants.js'; + +const Symbol = GLOBAL.Symbol || {}; +const { setPrototypeOf, create } = Object; + +QUnit.test('Promise', assert => { + assert.isFunction(Promise); + assert.arity(Promise, 1); + assert.name(Promise, 'Promise'); + assert.looksNative(Promise); + assert.throws(() => { + Promise(); + }, 'throws w/o `new`'); + new Promise(function (resolve, reject) { + assert.isFunction(resolve, 'resolver is function'); + assert.isFunction(reject, 'rejector is function'); + if (STRICT) assert.same(this, undefined, 'correct executor context'); + }); +}); + +if (DESCRIPTORS) QUnit.test('Promise operations order', assert => { + let $resolve, $resolve2; + assert.expect(1); + const EXPECTED_ORDER = 'DEHAFGBC'; + const async = assert.async(); + let result = ''; + const promise1 = new Promise(resolve => { + $resolve = resolve; + }); + $resolve({ + // eslint-disable-next-line unicorn/no-thenable -- required for testing + then() { + result += 'A'; + throw new Error(); + }, + }); + promise1.catch(() => { + result += 'B'; + }); + promise1.catch(() => { + result += 'C'; + assert.same(result, EXPECTED_ORDER); + async(); + }); + const promise2 = new Promise(resolve => { + $resolve2 = resolve; + }); + // eslint-disable-next-line unicorn/no-thenable -- required for testing + $resolve2(Object.defineProperty({}, 'then', { + get() { + result += 'D'; + throw new Error(); + }, + })); + result += 'E'; + promise2.catch(() => { + result += 'F'; + }); + promise2.catch(() => { + result += 'G'; + }); + result += 'H'; + setTimeout(() => { + if (!~result.indexOf('C')) { + assert.same(result, EXPECTED_ORDER); + async(); + } + }, 1e3); +}); + +QUnit.test('Promise#then', assert => { + assert.isFunction(Promise.prototype.then); + if (NATIVE) assert.arity(Promise.prototype.then, 2); + assert.name(Promise.prototype.then, 'then'); + assert.looksNative(Promise.prototype.then); + assert.nonEnumerable(Promise.prototype, 'then'); + let promise = new Promise(resolve => { + resolve(42); + }); + const FakePromise1 = promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + const FakePromise2 = FakePromise1[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(promise.then(() => { /* empty */ }) instanceof FakePromise2, 'subclassing, @@species pattern'); + promise = new Promise(resolve => { + resolve(42); + }); + promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(promise.then(() => { /* empty */ }) instanceof Promise, 'subclassing, incorrect `this` pattern'); + promise = new Promise(resolve => { + resolve(42); + }); + const FakePromise3 = promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + FakePromise3[Symbol.species] = function () { /* empty */ }; + assert.throws(() => { + promise.then(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #1'); + FakePromise3[Symbol.species] = function (executor) { + executor(null, () => { /* empty */ }); + }; + assert.throws(() => { + promise.then(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #2'); + FakePromise3[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, null); + }; + assert.throws(() => { + promise.then(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise#@@toStringTag', assert => { + assert.same(Promise.prototype[Symbol.toStringTag], 'Promise', 'Promise::@@toStringTag is `Promise`'); + assert.same(String(new Promise(() => { /* empty */ })), '[object Promise]', 'correct stringification'); +}); + +if (PROTO) QUnit.test('Promise subclassing', assert => { + function SubPromise(executor) { + const self = new Promise(executor); + setPrototypeOf(self, SubPromise.prototype); + // eslint-disable-next-line es/no-nonstandard-promise-prototype-properties -- safe + self.mine = 'subclass'; + return self; + } + setPrototypeOf(SubPromise, Promise); + SubPromise.prototype = create(Promise.prototype); + SubPromise.prototype.constructor = SubPromise; + let promise1 = SubPromise.resolve(5); + assert.same(promise1.mine, 'subclass'); + promise1 = promise1.then(it => { + assert.same(it, 5); + }); + assert.same(promise1.mine, 'subclass'); + let promise2 = new SubPromise(resolve => { + resolve(6); + }); + assert.same(promise2.mine, 'subclass'); + promise2 = promise2.then(it => { + assert.same(it, 6); + }); + assert.same(promise2.mine, 'subclass'); + const promise3 = SubPromise.all([promise1, promise2]); + assert.same(promise3.mine, 'subclass'); + assert.true(promise3 instanceof Promise); + assert.true(promise3 instanceof SubPromise); + promise3.then(assert.async(), error => { + assert.avoid(error); + }); +}); + +// qunit@2.5 strange bug +QUnit.skip('Unhandled rejection tracking', assert => { + let done = false; + const resume = assert.async(); + if (GLOBAL.process) { + assert.expect(3); + function onunhandledrejection(reason, promise) { + process.removeListener('unhandledRejection', onunhandledrejection); + assert.same(promise, $promise, 'unhandledRejection, promise'); + assert.same(reason, 42, 'unhandledRejection, reason'); + $promise.catch(() => { + // empty + }); + } + function onrejectionhandled(promise) { + process.removeListener('rejectionHandled', onrejectionhandled); + assert.same(promise, $promise, 'rejectionHandled, promise'); + done || resume(); + done = true; + } + process.on('unhandledRejection', onunhandledrejection); + process.on('rejectionHandled', onrejectionhandled); + } else { + if (GLOBAL.addEventListener) { + assert.expect(8); + function onunhandledrejection(it) { + assert.same(it.promise, $promise, 'addEventListener(unhandledrejection), promise'); + assert.same(it.reason, 42, 'addEventListener(unhandledrejection), reason'); + GLOBAL.removeEventListener('unhandledrejection', onunhandledrejection); + } + GLOBAL.addEventListener('rejectionhandled', onunhandledrejection); + function onrejectionhandled(it) { + assert.same(it.promise, $promise, 'addEventListener(rejectionhandled), promise'); + assert.same(it.reason, 42, 'addEventListener(rejectionhandled), reason'); + GLOBAL.removeEventListener('rejectionhandled', onrejectionhandled); + } + GLOBAL.addEventListener('rejectionhandled', onrejectionhandled); + } else assert.expect(4); + GLOBAL.onunhandledrejection = function (it) { + assert.same(it.promise, $promise, 'onunhandledrejection, promise'); + assert.same(it.reason, 42, 'onunhandledrejection, reason'); + setTimeout(() => { + $promise.catch(() => { + // empty + }); + }, 1); + GLOBAL.onunhandledrejection = null; + }; + GLOBAL.onrejectionhandled = function (it) { + assert.same(it.promise, $promise, 'onrejectionhandled, promise'); + assert.same(it.reason, 42, 'onrejectionhandled, reason'); + GLOBAL.onrejectionhandled = null; + done || resume(); + done = true; + }; + } + Promise.reject(43).catch(() => { + // empty + }); + const $promise = Promise.reject(42); + setTimeout(() => { + done || resume(); + done = true; + }, 3e3); +}); + +const promise = (() => { + try { + return Function('return (async function () { /* empty */ })()')(); + } catch { /* empty */ } +})(); + +if (promise) QUnit.test('Native Promise, maybe patched', assert => { + assert.isFunction(promise.then); + assert.arity(promise.then, 2); + assert.looksNative(promise.then); + assert.nonEnumerable(promise.constructor.prototype, 'then'); + function empty() { /* empty */ } + assert.true(promise.then(empty) instanceof Promise, '`.then` returns `Promise` instance #1'); + assert.true(new promise.constructor(empty).then(empty) instanceof Promise, '`.then` returns `Promise` instance #2'); + assert.true(promise.catch(empty) instanceof Promise, '`.catch` returns `Promise` instance #1'); + assert.true(new promise.constructor(empty).catch(empty) instanceof Promise, '`.catch` returns `Promise` instance #2'); + assert.true(promise.finally(empty) instanceof Promise, '`.finally` returns `Promise` instance #1'); + assert.true(new promise.constructor(empty).finally(empty) instanceof Promise, '`.finally` returns `Promise` instance #2'); +}); diff --git a/tests/unit-global/es.promise.finally.js b/tests/unit-global/es.promise.finally.js new file mode 100644 index 000000000000..2faf6f1df7d9 --- /dev/null +++ b/tests/unit-global/es.promise.finally.js @@ -0,0 +1,51 @@ +QUnit.test('Promise#finally', assert => { + assert.isFunction(Promise.prototype.finally); + assert.arity(Promise.prototype.finally, 1); + assert.looksNative(Promise.prototype.finally); + assert.nonEnumerable(Promise.prototype, 'finally'); + assert.true(Promise.resolve(42).finally(() => { /* empty */ }) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise#finally, resolved', assert => { + let called = 0; + let argument = null; + return Promise.resolve(42).finally(it => { + called++; + argument = it; + }).then(it => { + assert.same(it, 42, 'resolved with a correct value'); + assert.same(called, 1, 'onFinally function called one time'); + assert.same(argument, undefined, 'onFinally function called with a correct argument'); + }); +}); + +QUnit.test('Promise#finally, rejected', assert => { + let called = 0; + let argument = null; + return Promise.reject(42).finally(it => { + called++; + argument = it; + }).then(() => { + assert.avoid(); + }, () => { + assert.same(called, 1, 'onFinally function called one time'); + assert.same(argument, undefined, 'onFinally function called with a correct argument'); + }); +}); + +const promise = (() => { + try { + return Function('return (async function () { /* empty */ })()')(); + } catch { /* empty */ } +})(); + +if (promise && promise.constructor !== Promise) QUnit.test('Native Promise, patched', assert => { + assert.isFunction(promise.finally); + assert.arity(promise.finally, 1); + assert.looksNative(promise.finally); + assert.nonEnumerable(promise.constructor.prototype, 'finally'); + function empty() { /* empty */ } + assert.true(promise.finally(empty) instanceof Promise, '`.finally` returns `Promise` instance #1'); + assert.true(new promise.constructor(empty).finally(empty) instanceof Promise, '`.finally` returns `Promise` instance #2'); +}); + diff --git a/tests/unit-global/es.promise.race.js b/tests/unit-global/es.promise.race.js new file mode 100644 index 000000000000..8ae610c8d81f --- /dev/null +++ b/tests/unit-global/es.promise.race.js @@ -0,0 +1,110 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Promise.race', assert => { + const { race } = Promise; + assert.isFunction(race); + assert.arity(race, 1); + assert.name(race, 'race'); + assert.looksNative(race); + assert.nonEnumerable(Promise, 'race'); + assert.true(Promise.race([]) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.race, resolved', assert => { + return Promise.race([ + Promise.resolve(1), + Promise.resolve(2), + ]).then(it => { + assert.same(it, 1, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.race, resolved with rejection', assert => { + return Promise.race([ + Promise.reject(1), + Promise.resolve(2), + ]).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 1, 'rejected with a correct value'); + }); +}); + +QUnit.test('Promise.race, resolved with timeouts', assert => { + return Promise.race([ + new Promise(resolve => setTimeout(() => resolve(1), 50)), + Promise.resolve(2), + ]).then(it => { + assert.same(it, 2, 'keeps correct mapping, even with delays'); + }); +}); + +QUnit.test('Promise.race, subclassing', assert => { + const { race, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = resolve.bind(Promise); + assert.true(race.call(SubPromise, [1, 2, 3]) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise); + assert.throws(() => { + race.call(FakePromise1, [1, 2, 3]); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + race.call(FakePromise2, [1, 2, 3]); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + race.call(FakePromise3, [1, 2, 3]); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.race, iterables', assert => { + const iterable = createIterable([1, 2, 3]); + Promise.race(iterable).catch(() => { /* empty */ }); + assert.true(iterable.received, 'works with iterables: iterator received'); + assert.true(iterable.called, 'works with iterables: next called'); +}); + +QUnit.test('Promise.race, iterables 2', assert => { + const array = []; + let done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + Promise.race(array); + assert.true(done); +}); + +QUnit.test('Promise.race, iterator closing', assert => { + const { resolve } = Promise; + let done = false; + try { + Promise.resolve = function () { + throw new Error(); + }; + Promise.race(createIterable([1, 2, 3], { + return() { + done = true; + }, + })).catch(() => { /* empty */ }); + } catch { /* empty */ } + Promise.resolve = resolve; + assert.true(done, 'iteration closing'); +}); + +QUnit.test('Promise.race, without constructor context', assert => { + const { race } = Promise; + assert.throws(() => race([]), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => race.call(null, []), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-global/es.promise.reject.js b/tests/unit-global/es.promise.reject.js new file mode 100644 index 000000000000..01b771317705 --- /dev/null +++ b/tests/unit-global/es.promise.reject.js @@ -0,0 +1,59 @@ +import { NATIVE } from '../helpers/constants.js'; + +QUnit.test('Promise.reject', assert => { + const { reject } = Promise; + assert.isFunction(reject); + if (NATIVE) assert.arity(reject, 1); + assert.name(reject, 'reject'); + assert.looksNative(reject); + assert.nonEnumerable(Promise, 'reject'); +}); + +QUnit.test('Promise.reject, rejects with value', assert => { + return Promise.reject(42) + .then(() => { + assert.avoid('Should not resolve'); + }, error => { + assert.same(error, 42, 'rejected with correct reason'); + }); +}); + +QUnit.test('Promise.reject, rejects with undefined', assert => { + return Promise.reject() + .then(() => { + assert.avoid('Should not resolve'); + }, error => { + assert.same(error, undefined, 'rejected with correct reason'); + }); +}); + +QUnit.test('Promise.reject, subclassing', assert => { + const { reject } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + assert.true(reject.call(SubPromise, 42) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + assert.throws(() => { + reject.call(FakePromise1, 42); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + reject.call(FakePromise2, 42); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + reject.call(FakePromise3, 42); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.reject, without constructor context', assert => { + const { reject } = Promise; + assert.throws(() => reject(''), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => reject.call(null, ''), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-global/es.promise.resolve.js b/tests/unit-global/es.promise.resolve.js new file mode 100644 index 000000000000..5cfe3a7f8dbf --- /dev/null +++ b/tests/unit-global/es.promise.resolve.js @@ -0,0 +1,70 @@ +QUnit.test('Promise.resolve', assert => { + const { resolve } = Promise; + assert.isFunction(resolve); + assert.arity(resolve, 1); + assert.name(resolve, 'resolve'); + assert.looksNative(resolve); + assert.nonEnumerable(Promise, 'resolve'); + assert.true(Promise.resolve(42) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.resolve, resolves with value', assert => { + return Promise.resolve(42).then(result => { + assert.same(result, 42, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.resolve, resolves with thenable', assert => { + const thenable = { + // eslint-disable-next-line unicorn/no-thenable -- safe + then(resolve) { resolve('foo'); }, + }; + return Promise.resolve(thenable).then(result => { + assert.same(result, 'foo', 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.resolve, returns input if input is already promise', assert => { + const p = Promise.resolve('ok'); + assert.same(Promise.resolve(p), p, 'resolved with a correct value'); +}); + +QUnit.test('Promise.resolve, resolves with undefined', assert => { + return Promise.resolve().then(result => { + assert.same(result, undefined, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.resolve, subclassing', assert => { + const { resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(resolve.call(SubPromise, 42) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + assert.throws(() => { + resolve.call(FakePromise1, 42); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + resolve.call(FakePromise2, 42); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + resolve.call(FakePromise3, 42); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.resolve, without constructor context', assert => { + const { resolve } = Promise; + assert.throws(() => resolve(''), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => resolve.call(null, ''), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-global/es.promise.try.js b/tests/unit-global/es.promise.try.js new file mode 100644 index 000000000000..448ee659a613 --- /dev/null +++ b/tests/unit-global/es.promise.try.js @@ -0,0 +1,64 @@ +import Promise from 'core-js-pure/es/promise'; + +QUnit.test('Promise.try', assert => { + assert.isFunction(Promise.try); + assert.arity(Promise.try, 1); + assert.looksNative(Promise.try); + assert.nonEnumerable(Promise, 'try'); + assert.true(Promise.try(() => 42) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.try, resolved', assert => { + return Promise.try(() => 42).then(it => { + assert.same(it, 42, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.try, resolved, with args', assert => { + return Promise.try((a, b) => Promise.resolve(a + b), 1, 2).then(it => { + assert.same(it, 3, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.try, rejected', assert => { + return Promise.try(() => { + throw new Error(); + }).then(() => { + assert.avoid(); + }, () => { + assert.required('rejected as expected'); + }); +}); + +QUnit.test('Promise.try, subclassing', assert => { + const { try: promiseTry, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = resolve.bind(Promise); + assert.true(promiseTry.call(SubPromise, () => 42) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = resolve.bind(Promise); + assert.throws(() => { + promiseTry.call(FakePromise1, () => 42); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + promiseTry.call(FakePromise2, () => 42); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + promiseTry.call(FakePromise3, () => 42); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.try, without constructor context', assert => { + const { try: promiseTry } = Promise; + assert.throws(() => promiseTry(() => 42), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => promiseTry.call(null, () => 42), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-global/es.promise.with-resolvers.js b/tests/unit-global/es.promise.with-resolvers.js new file mode 100644 index 000000000000..b786a6bcbcd9 --- /dev/null +++ b/tests/unit-global/es.promise.with-resolvers.js @@ -0,0 +1,56 @@ +const { getPrototypeOf } = Object; + +QUnit.test('Promise.withResolvers', assert => { + const { withResolvers } = Promise; + assert.isFunction(withResolvers); + assert.arity(withResolvers, 0); + assert.name(withResolvers, 'withResolvers'); + assert.nonEnumerable(Promise, 'withResolvers'); + assert.looksNative(withResolvers); + + const d1 = Promise.withResolvers(); + assert.same(getPrototypeOf(d1), Object.prototype, 'proto is Object.prototype'); + assert.true(d1.promise instanceof Promise, 'promise is promise'); + assert.isFunction(d1.resolve, 'resolve is function'); + assert.isFunction(d1.reject, 'reject is function'); + + const promise = {}; + const resolve = () => { /* empty */ }; + let reject = () => { /* empty */ }; + + function P(exec) { + exec(resolve, reject); + return promise; + } + + const d2 = withResolvers.call(P); + assert.same(d2.promise, promise, 'promise is promise #2'); + assert.same(d2.resolve, resolve, 'resolve is resolve #2'); + assert.same(d2.reject, reject, 'reject is reject #2'); + + reject = {}; + + assert.throws(() => withResolvers.call(P), TypeError, 'broken resolver'); + assert.throws(() => withResolvers.call({}), TypeError, 'broken constructor #1'); + assert.throws(() => withResolvers.call(null), TypeError, 'broken constructor #2'); +}); + +QUnit.test('Promise.withResolvers, resolve', assert => { + const d = Promise.withResolvers(); + d.resolve(42); + return d.promise.then(it => { + assert.same(it, 42, 'resolved as expected'); + }, () => { + assert.avoid(); + }); +}); + +QUnit.test('Promise.withResolvers, reject', assert => { + const d = Promise.withResolvers(); + d.reject(42); + return d.promise.then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejected as expected'); + }); +}); diff --git a/tests/unit-global/es.reflect.apply.js b/tests/unit-global/es.reflect.apply.js new file mode 100644 index 000000000000..5e7e77dc0558 --- /dev/null +++ b/tests/unit-global/es.reflect.apply.js @@ -0,0 +1,17 @@ +QUnit.test('Reflect.apply', assert => { + const { apply } = Reflect; + assert.isFunction(apply); + assert.arity(apply, 3); + assert.name(apply, 'apply'); + assert.looksNative(apply); + assert.nonEnumerable(Reflect, 'apply'); + assert.same(apply(Array.prototype.push, [1, 2], [3, 4, 5]), 5); + function f(a, b, c) { + return a + b + c; + } + f.apply = 42; + assert.same(apply(f, null, ['foo', 'bar', 'baz']), 'foobarbaz', 'works with redefined apply'); + assert.throws(() => apply(42, null, []), TypeError, 'throws on primitive'); + assert.throws(() => apply(() => { /* empty */ }, null), TypeError, 'throws without third argument'); + assert.throws(() => apply(() => { /* empty */ }, null, '123'), TypeError, 'throws on primitive as third argument'); +}); diff --git a/tests/unit-global/es.reflect.construct.js b/tests/unit-global/es.reflect.construct.js new file mode 100644 index 000000000000..6a5550f28260 --- /dev/null +++ b/tests/unit-global/es.reflect.construct.js @@ -0,0 +1,27 @@ +QUnit.test('Reflect.construct', assert => { + const { construct } = Reflect; + const { getPrototypeOf } = Object; + assert.isFunction(construct); + assert.arity(construct, 2); + assert.name(construct, 'construct'); + assert.looksNative(construct); + assert.nonEnumerable(Reflect, 'construct'); + function A(a, b, c) { + this.qux = a + b + c; + } + assert.same(construct(A, ['foo', 'bar', 'baz']).qux, 'foobarbaz', 'basic'); + A.apply = 42; + assert.same(construct(A, ['foo', 'bar', 'baz']).qux, 'foobarbaz', 'works with redefined apply'); + const instance = construct(function () { + this.x = 42; + }, [], Array); + assert.same(instance.x, 42, 'constructor with newTarget'); + assert.true(instance instanceof Array, 'prototype with newTarget'); + assert.throws(() => construct(42, []), TypeError, 'throws on primitive'); + function B() { /* empty */ } + B.prototype = 42; + assert.notThrows(() => getPrototypeOf(construct(B, [])) === Object.prototype); + assert.notThrows(() => typeof construct(Date, []).getTime() == 'number', 'works with native constructors with 2 arguments'); + assert.throws(() => construct(() => { /* empty */ }), 'throws when the second argument is not an object'); +}); + diff --git a/tests/unit-global/es.reflect.define-property.js b/tests/unit-global/es.reflect.define-property.js new file mode 100644 index 000000000000..275e908d8428 --- /dev/null +++ b/tests/unit-global/es.reflect.define-property.js @@ -0,0 +1,40 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Reflect.defineProperty', assert => { + const { defineProperty } = Reflect; + const { getOwnPropertyDescriptor, create } = Object; + assert.isFunction(defineProperty); + assert.arity(defineProperty, 3); + assert.name(defineProperty, 'defineProperty'); + assert.looksNative(defineProperty); + assert.nonEnumerable(Reflect, 'defineProperty'); + let object = {}; + assert.true(defineProperty(object, 'foo', { value: 123 })); + assert.same(object.foo, 123); + if (DESCRIPTORS) { + object = {}; + defineProperty(object, 'foo', { + value: 123, + enumerable: true, + }); + assert.deepEqual(getOwnPropertyDescriptor(object, 'foo'), { + value: 123, + enumerable: true, + configurable: false, + writable: false, + }); + assert.false(defineProperty(object, 'foo', { + value: 42, + })); + } + assert.throws(() => defineProperty(42, 'foo', { + value: 42, + }), TypeError, 'throws on primitive'); + assert.throws(() => defineProperty(42, 1, {})); + assert.throws(() => defineProperty({}, create(null), {})); + assert.throws(() => defineProperty({}, 1, 1)); +}); + +QUnit.test('Reflect.defineProperty.sham flag', assert => { + assert.same(Reflect.defineProperty.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-global/es.reflect.delete-property.js b/tests/unit-global/es.reflect.delete-property.js new file mode 100644 index 000000000000..e0a9816c441c --- /dev/null +++ b/tests/unit-global/es.reflect.delete-property.js @@ -0,0 +1,20 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Reflect.deleteProperty', assert => { + const { deleteProperty } = Reflect; + const { defineProperty, keys } = Object; + assert.isFunction(deleteProperty); + assert.arity(deleteProperty, 2); + assert.name(deleteProperty, 'deleteProperty'); + assert.looksNative(deleteProperty); + assert.nonEnumerable(Reflect, 'deleteProperty'); + const object = { bar: 456 }; + assert.true(deleteProperty(object, 'bar')); + assert.same(keys(object).length, 0); + if (DESCRIPTORS) { + assert.false(deleteProperty(defineProperty({}, 'foo', { + value: 42, + }), 'foo')); + } + assert.throws(() => deleteProperty(42, 'foo'), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-global/es.reflect.get-own-property-descriptor.js b/tests/unit-global/es.reflect.get-own-property-descriptor.js new file mode 100644 index 000000000000..8a3c321b5429 --- /dev/null +++ b/tests/unit-global/es.reflect.get-own-property-descriptor.js @@ -0,0 +1,18 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Reflect.getOwnPropertyDescriptor', assert => { + const { getOwnPropertyDescriptor } = Reflect; + assert.isFunction(getOwnPropertyDescriptor); + assert.arity(getOwnPropertyDescriptor, 2); + assert.name(getOwnPropertyDescriptor, 'getOwnPropertyDescriptor'); + assert.looksNative(getOwnPropertyDescriptor); + assert.nonEnumerable(Reflect, 'getOwnPropertyDescriptor'); + const object = { baz: 789 }; + const descriptor = getOwnPropertyDescriptor(object, 'baz'); + assert.same(descriptor.value, 789); + assert.throws(() => getOwnPropertyDescriptor(42, 'constructor'), TypeError, 'throws on primitive'); +}); + +QUnit.test('Reflect.getOwnPropertyDescriptor.sham flag', assert => { + assert.same(Reflect.getOwnPropertyDescriptor.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-global/es.reflect.get-prototype-of.js b/tests/unit-global/es.reflect.get-prototype-of.js new file mode 100644 index 000000000000..f5fd23cd3505 --- /dev/null +++ b/tests/unit-global/es.reflect.get-prototype-of.js @@ -0,0 +1,16 @@ +import { CORRECT_PROTOTYPE_GETTER } from '../helpers/constants.js'; + +QUnit.test('Reflect.getPrototypeOf', assert => { + const { getPrototypeOf } = Reflect; + assert.isFunction(getPrototypeOf); + assert.arity(getPrototypeOf, 1); + assert.name(getPrototypeOf, 'getPrototypeOf'); + assert.looksNative(getPrototypeOf); + assert.nonEnumerable(Reflect, 'getPrototypeOf'); + assert.same(getPrototypeOf([]), Array.prototype); + assert.throws(() => getPrototypeOf(42), TypeError, 'throws on primitive'); +}); + +QUnit.test('Reflect.getPrototypeOf.sham flag', assert => { + assert.same(Reflect.getPrototypeOf.sham, CORRECT_PROTOTYPE_GETTER ? undefined : true); +}); diff --git a/tests/unit-global/es.reflect.get.js b/tests/unit-global/es.reflect.get.js new file mode 100644 index 000000000000..7b368dfd93f4 --- /dev/null +++ b/tests/unit-global/es.reflect.get.js @@ -0,0 +1,36 @@ +import { DESCRIPTORS, NATIVE } from '../helpers/constants.js'; + +QUnit.test('Reflect.get', assert => { + const { defineProperty, create } = Object; + const { get } = Reflect; + assert.isFunction(get); + if (NATIVE) assert.arity(get, 2); + assert.name(get, 'get'); + assert.looksNative(get); + assert.nonEnumerable(Reflect, 'get'); + assert.same(get({ qux: 987 }, 'qux'), 987); + if (DESCRIPTORS) { + const target = create(defineProperty({ z: 3 }, 'w', { + get() { + return this; + }, + }), { + x: { + value: 1, + }, + y: { + get() { + return this; + }, + }, + }); + const receiver = {}; + assert.same(get(target, 'x', receiver), 1, 'get x'); + assert.same(get(target, 'y', receiver), receiver, 'get y'); + assert.same(get(target, 'z', receiver), 3, 'get z'); + assert.same(get(target, 'w', receiver), receiver, 'get w'); + assert.same(get(target, 'u', receiver), undefined, 'get u'); + } + assert.throws(() => get(42, 'constructor'), TypeError, 'throws on primitive'); +}); + diff --git a/tests/unit-global/es.reflect.has.js b/tests/unit-global/es.reflect.has.js new file mode 100644 index 000000000000..406fb46c3b44 --- /dev/null +++ b/tests/unit-global/es.reflect.has.js @@ -0,0 +1,13 @@ +QUnit.test('Reflect.has', assert => { + const { has } = Reflect; + assert.isFunction(has); + assert.arity(has, 2); + assert.name(has, 'has'); + assert.looksNative(has); + assert.nonEnumerable(Reflect, 'has'); + const object = { qux: 987 }; + assert.true(has(object, 'qux')); + assert.false(has(object, 'qwe')); + assert.true(has(object, 'toString')); + assert.throws(() => has(42, 'constructor'), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-global/es.reflect.is-extensible.js b/tests/unit-global/es.reflect.is-extensible.js new file mode 100644 index 000000000000..c8f3499ba844 --- /dev/null +++ b/tests/unit-global/es.reflect.is-extensible.js @@ -0,0 +1,17 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Reflect.isExtensible', assert => { + const { isExtensible } = Reflect; + const { preventExtensions } = Object; + assert.isFunction(isExtensible); + assert.arity(isExtensible, 1); + assert.name(isExtensible, 'isExtensible'); + assert.looksNative(isExtensible); + assert.nonEnumerable(Reflect, 'isExtensible'); + assert.true(isExtensible({})); + if (DESCRIPTORS) { + assert.false(isExtensible(preventExtensions({}))); + } + assert.throws(() => isExtensible(42), TypeError, 'throws on primitive'); +}); + diff --git a/tests/unit-global/es.reflect.own-keys.js b/tests/unit-global/es.reflect.own-keys.js new file mode 100644 index 000000000000..4931df11639d --- /dev/null +++ b/tests/unit-global/es.reflect.own-keys.js @@ -0,0 +1,25 @@ +import { includes } from '../helpers/helpers.js'; + +QUnit.test('Reflect.ownKeys', assert => { + const { ownKeys } = Reflect; + const { defineProperty, create } = Object; + const symbol = Symbol('c'); + assert.isFunction(ownKeys); + assert.arity(ownKeys, 1); + assert.name(ownKeys, 'ownKeys'); + assert.looksNative(ownKeys); + assert.nonEnumerable(Reflect, 'ownKeys'); + const object = { a: 1 }; + defineProperty(object, 'b', { + value: 2, + }); + object[symbol] = 3; + let keys = ownKeys(object); + assert.same(keys.length, 3, 'ownKeys return all own keys'); + assert.true(includes(keys, 'a'), 'ownKeys return all own keys: simple'); + assert.true(includes(keys, 'b'), 'ownKeys return all own keys: hidden'); + assert.same(object[keys[2]], 3, 'ownKeys return all own keys: symbol'); + keys = ownKeys(create(object)); + assert.same(keys.length, 0, 'ownKeys return only own keys'); + assert.throws(() => ownKeys(42), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-global/es.reflect.prevent-extensions.js b/tests/unit-global/es.reflect.prevent-extensions.js new file mode 100644 index 000000000000..53dae0d9d0b1 --- /dev/null +++ b/tests/unit-global/es.reflect.prevent-extensions.js @@ -0,0 +1,21 @@ +import { DESCRIPTORS, FREEZING } from '../helpers/constants.js'; + +QUnit.test('Reflect.preventExtensions', assert => { + const { preventExtensions } = Reflect; + const { isExtensible } = Object; + assert.isFunction(preventExtensions); + assert.arity(preventExtensions, 1); + assert.name(preventExtensions, 'preventExtensions'); + assert.looksNative(preventExtensions); + assert.nonEnumerable(Reflect, 'preventExtensions'); + const object = {}; + assert.true(preventExtensions(object)); + if (DESCRIPTORS) { + assert.false(isExtensible(object)); + } + assert.throws(() => preventExtensions(42), TypeError, 'throws on primitive'); +}); + +QUnit.test('Reflect.preventExtensions.sham flag', assert => { + assert.same(Reflect.preventExtensions.sham, FREEZING ? undefined : true); +}); diff --git a/tests/unit-global/es.reflect.set-prototype-of.js b/tests/unit-global/es.reflect.set-prototype-of.js new file mode 100644 index 000000000000..7f708e863cc6 --- /dev/null +++ b/tests/unit-global/es.reflect.set-prototype-of.js @@ -0,0 +1,17 @@ +import { NATIVE, PROTO } from '../helpers/constants.js'; + +if (PROTO) QUnit.test('Reflect.setPrototypeOf', assert => { + const { setPrototypeOf } = Reflect; + assert.isFunction(setPrototypeOf); + if (NATIVE) assert.arity(setPrototypeOf, 2); + assert.name(setPrototypeOf, 'setPrototypeOf'); + assert.looksNative(setPrototypeOf); + assert.nonEnumerable(Reflect, 'setPrototypeOf'); + let object = {}; + assert.true(setPrototypeOf(object, Array.prototype)); + assert.true(object instanceof Array); + assert.throws(() => setPrototypeOf({}, 42), TypeError); + assert.throws(() => setPrototypeOf(42, {}), TypeError, 'throws on primitive'); + object = {}; + assert.false(setPrototypeOf(object, object), 'false on recursive __proto__'); +}); diff --git a/tests/unit-global/es.reflect.set.js b/tests/unit-global/es.reflect.set.js new file mode 100644 index 000000000000..072143c12b59 --- /dev/null +++ b/tests/unit-global/es.reflect.set.js @@ -0,0 +1,85 @@ +import { DESCRIPTORS, NATIVE } from '../helpers/constants.js'; + +QUnit.test('Reflect.set', assert => { + const { set } = Reflect; + const { defineProperty, getOwnPropertyDescriptor, create, getPrototypeOf } = Object; + assert.isFunction(set); + if (NATIVE) assert.arity(set, 3); + assert.name(set, 'set'); + assert.looksNative(set); + assert.nonEnumerable(Reflect, 'set'); + const object = {}; + assert.true(set(object, 'quux', 654)); + assert.same(object.quux, 654); + let target = {}; + const receiver = {}; + set(target, 'foo', 1, receiver); + assert.same(target.foo, undefined, 'target.foo === undefined'); + assert.same(receiver.foo, 1, 'receiver.foo === 1'); + if (DESCRIPTORS) { + defineProperty(receiver, 'bar', { + value: 0, + writable: true, + enumerable: false, + configurable: true, + }); + set(target, 'bar', 1, receiver); + assert.same(receiver.bar, 1, 'receiver.bar === 1'); + assert.false(getOwnPropertyDescriptor(receiver, 'bar').enumerable, 'enumerability not overridden'); + let out; + target = create(defineProperty({ z: 3 }, 'w', { + set() { + out = this; + }, + }), { + x: { + value: 1, + writable: true, + configurable: true, + }, + y: { + set() { + out = this; + }, + }, + c: { + value: 1, + writable: false, + configurable: false, + }, + }); + assert.true(set(target, 'x', 2, target), 'set x'); + assert.same(target.x, 2, 'set x'); + out = null; + assert.true(set(target, 'y', 2, target), 'set y'); + assert.same(out, target, 'set y'); + assert.true(set(target, 'z', 4, target)); + assert.same(target.z, 4, 'set z'); + out = null; + assert.true(set(target, 'w', 1, target), 'set w'); + assert.same(out, target, 'set w'); + assert.true(set(target, 'u', 0, target), 'set u'); + assert.same(target.u, 0, 'set u'); + assert.false(set(target, 'c', 2, target), 'set c'); + assert.same(target.c, 1, 'set c'); + + // https://github.com/zloirock/core-js/issues/392 + let o = defineProperty({}, 'test', { + writable: false, + configurable: true, + }); + assert.false(set(getPrototypeOf(o), 'test', 1, o)); + + // https://github.com/zloirock/core-js/issues/393 + o = defineProperty({}, 'test', { + get() { /* empty */ }, + }); + assert.notThrows(() => !set(getPrototypeOf(o), 'test', 1, o)); + o = defineProperty({}, 'test', { + // eslint-disable-next-line no-unused-vars -- required for testing + set(v) { /* empty */ }, + }); + assert.notThrows(() => !set(getPrototypeOf(o), 'test', 1, o)); + } + assert.throws(() => set(42, 'q', 42), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-global/es.reflect.to-string-tag.js b/tests/unit-global/es.reflect.to-string-tag.js new file mode 100644 index 000000000000..4db6093737e3 --- /dev/null +++ b/tests/unit-global/es.reflect.to-string-tag.js @@ -0,0 +1,3 @@ +QUnit.test('Reflect[@@toStringTag]', assert => { + assert.same(Reflect[Symbol.toStringTag], 'Reflect', 'Reflect[@@toStringTag] is `Reflect`'); +}); diff --git a/tests/unit-global/es.regexp.constructor.js b/tests/unit-global/es.regexp.constructor.js new file mode 100644 index 000000000000..d22e0ce562f6 --- /dev/null +++ b/tests/unit-global/es.regexp.constructor.js @@ -0,0 +1,108 @@ +/* eslint-disable prefer-regex-literals, regexp/no-invalid-regexp, regexp/sort-flags -- required for testing */ +/* eslint-disable regexp/no-useless-character-class, regexp/no-useless-flag -- required for testing */ +import { DESCRIPTORS, GLOBAL } from '../helpers/constants.js'; +import { nativeSubclass } from '../helpers/helpers.js'; + +const { getPrototypeOf } = Object; + +if (DESCRIPTORS) { + QUnit.test('RegExp constructor', assert => { + const Symbol = GLOBAL.Symbol || {}; + assert.isFunction(RegExp); + assert.arity(RegExp, 2); + assert.name(RegExp, 'RegExp'); + assert.looksNative(RegExp); + assert.same({}.toString.call(RegExp()).slice(8, -1), 'RegExp'); + assert.same({}.toString.call(new RegExp()).slice(8, -1), 'RegExp'); + let regexp = /a/g; + assert.notSame(regexp, new RegExp(regexp), 'new RegExp(regexp) is not regexp'); + assert.same(regexp, RegExp(regexp), 'RegExp(regexp) is regexp'); + regexp[Symbol.match] = false; + assert.notSame(regexp, RegExp(regexp), 'RegExp(regexp) is not regexp, changed Symbol.match'); + const object = {}; + assert.notSame(object, RegExp(object), 'RegExp(O) is not O'); + object[Symbol.match] = true; + object.constructor = RegExp; + assert.same(object, RegExp(object), 'RegExp(O) is O, changed Symbol.match'); + assert.same(String(regexp), '/a/g', 'b is /a/g'); + assert.same(String(new RegExp(/a/g, 'mi')), '/a/im', 'Allows a regex with flags'); + assert.true(new RegExp(/a/g, 'im') instanceof RegExp, 'Works with instanceof'); + assert.same(new RegExp(/a/g, 'im').constructor, RegExp, 'Has the right constructor'); + + const orig = /^https?:\/\//i; + regexp = new RegExp(orig); + assert.notSame(regexp, orig, 'new + re + no flags #1'); + assert.same(String(regexp), '/^https?:\\/\\//i', 'new + re + no flags #2'); + let result = regexp.exec('http://github.com/'); + assert.deepEqual(result, ['http://'], 'new + re + no flags #3'); + + /(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)/.exec('abcdefghijklmnopq'); + result = true; + const characters = 'bcdefghij'; + for (let i = 0, { length } = characters; i < length; ++i) { + const chr = characters[i]; + if (RegExp[`$${ i + 1 }`] !== chr) { + result = false; + } + } + assert.true(result, 'Updates RegExp globals'); + if (nativeSubclass) { + const Subclass = nativeSubclass(RegExp); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof RegExp, 'correct subclassing with native classes #2'); + assert.true(new Subclass('^abc$').test('abc'), 'correct subclassing with native classes #3'); + } + + assert.throws(() => RegExp(Symbol(1)), 'throws on symbol argument'); + }); + + QUnit.test('RegExp dotAll', assert => { + assert.false(RegExp('.', '').test('\n'), 'dotAll missed'); + assert.true(RegExp('.', 's').test('\n'), 'dotAll basic'); + assert.false(RegExp('[.]', 's').test('\n'), 'dotAll brackets #1'); + assert.false(RegExp('[.].', '').test('.\n'), 'dotAll brackets #2'); + assert.true(RegExp('[.].', 's').test('.\n'), 'dotAll brackets #3'); + assert.true(RegExp('[[].', 's').test('[\n'), 'dotAll brackets #4'); + assert.same(RegExp('.[.[].\\..', 's').source, '.[.[].\\..', 'dotAll correct source'); + + const string = '123\n456789\n012'; + const re = RegExp('(\\d{3}).\\d{3}', 'sy'); + + let match = re.exec(string); + assert.same(match[1], '123', 's with y #1'); + assert.same(re.lastIndex, 7, 's with y #2'); + + match = re.exec(string); + assert.same(match[1], '789', 's with y #3'); + assert.same(re.lastIndex, 14, 's with y #4'); + }); + + QUnit.test('RegExp NCG', assert => { + assert.same(RegExp('(?b)').exec('b').groups?.a, 'b', 'NCG #1'); + // eslint-disable-next-line regexp/no-unused-capturing-group -- required for testing + assert.same(RegExp('(b)').exec('b').groups, undefined, 'NCG #2'); + const { groups } = RegExp('foo:(?\\w+),bar:(?\\w+)').exec('foo:abc,bar:def'); + assert.same(getPrototypeOf(groups), null, 'null prototype'); + assert.deepEqual(groups, { foo: 'abc', bar: 'def' }, 'NCG #3'); + // eslint-disable-next-line regexp/no-useless-non-capturing-group -- required for testing + const { groups: nonCaptured, length } = RegExp('foo:(?:value=(?\\w+)),bar:(?:value=(?\\w+))').exec('foo:value=abc,bar:value=def'); + assert.deepEqual(nonCaptured, { foo: 'abc', bar: 'def' }, 'NCG #4'); + assert.same(length, 3, 'incorrect number of matched entries #1'); + + // eslint-disable-next-line regexp/no-unused-capturing-group -- required for testing + const { groups: skipBar } = RegExp('foo:(?\\w+),bar:(\\w+),buz:(?\\w+)').exec('foo:abc,bar:def,buz:ghi'); + assert.deepEqual(skipBar, { foo: 'abc', buz: 'ghi' }, 'NCG #5'); + + // fails in Safari + // assert.same(Object.getPrototypeOf(groups), null, 'NCG #4'); + assert.same('foo:abc,bar:def'.replace(RegExp('foo:(?\\w+),bar:(?\\w+)'), '$,$'), 'def,abc', 'replace #1'); + assert.same('foo:abc,bar:def'.replace(RegExp('foo:(?\\w+),bar:(?\\w+)'), (...args) => { + const { foo, bar } = args.pop(); + return `${ bar },${ foo }`; + }), 'def,abc', 'replace #2'); + assert.same('12345'.replaceAll(RegExp('(?[2-4])', 'g'), '$$'), '12233445', 'replaceAll'); + assert.throws(() => RegExp('(?<1a>b)'), SyntaxError, 'incorrect group name #1'); + assert.throws(() => RegExp('(?b)'), SyntaxError, 'incorrect group name #2'); + assert.throws(() => RegExp('(?< a >b)'), SyntaxError, 'incorrect group name #3'); + }); +} diff --git a/tests/unit-global/es.regexp.dot-all.js b/tests/unit-global/es.regexp.dot-all.js new file mode 100644 index 000000000000..7f7e1b071027 --- /dev/null +++ b/tests/unit-global/es.regexp.dot-all.js @@ -0,0 +1,33 @@ +/* eslint-disable prefer-regex-literals -- required for testing */ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + QUnit.test('RegExp#dotAll', assert => { + const re = RegExp('.', 's'); + assert.true(re.dotAll, '.dotAll is true'); + assert.same(re.flags, 's', '.flags contains s'); + assert.false(RegExp('.').dotAll, 'no'); + assert.false(/a/.dotAll, 'no in literal'); + + const dotAllGetter = Object.getOwnPropertyDescriptor(RegExp.prototype, 'dotAll').get; + if (typeof dotAllGetter == 'function') { + assert.throws(() => { + dotAllGetter.call({}); + }, undefined, '.dotAll getter can only be called on RegExp instances'); + try { + dotAllGetter.call(/a/); + assert.required('.dotAll getter works on literals'); + } catch { + assert.avoid('.dotAll getter works on literals'); + } + try { + dotAllGetter.call(new RegExp('a')); + assert.required('.dotAll getter works on instances'); + } catch { + assert.avoid('.dotAll getter works on instances'); + } + + assert.true(Object.hasOwn(RegExp.prototype, 'dotAll'), 'prototype has .dotAll property'); + } + }); +} diff --git a/tests/unit-global/es.regexp.escape.js b/tests/unit-global/es.regexp.escape.js new file mode 100644 index 000000000000..fd249ce56b17 --- /dev/null +++ b/tests/unit-global/es.regexp.escape.js @@ -0,0 +1,325 @@ +/* eslint-disable @stylistic/max-len -- ok*/ +QUnit.test('RegExp.escape', assert => { + const { escape } = RegExp; + assert.isFunction(escape); + assert.arity(escape, 1); + assert.name(escape, 'escape'); + assert.looksNative(escape); + assert.nonEnumerable(RegExp, 'escape'); + + assert.same(escape('10$'), '\\x310\\$', '10$'); + assert.same(escape('abcdefg_123456'), '\\x61bcdefg_123456', 'abcdefg_123456'); + assert.same(escape('Привет'), 'Привет', 'Привет'); + assert.same( + escape('(){}[]|,.?*+-^$=<>\\/#&!%:;@~\'"`'), + '\\(\\)\\{\\}\\[\\]\\|\\x2c\\.\\?\\*\\+\\x2d\\^\\$\\x3d\\x3c\\x3e\\\\\\/\\x23\\x26\\x21\\x25\\x3a\\x3b\\x40\\x7e\\x27\\x22\\x60', + '(){}[]|,.?*+-^$=<>\\/#&!%:;@~\'"`', + ); + assert.same( + escape('\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'), + '\\t\\n\\v\\f\\r\\x20\\xa0\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029\\ufeff', + 'whitespaces and control', + ); + + assert.throws(() => escape(42), TypeError, 'throws on non-string #1'); + assert.throws(() => escape({}), TypeError, 'throws on non-string #2'); + + // Test262 + // Copyright 2024 Leo Balter. All rights reserved. + // This code is governed by the BSD license found in the https://github.com/tc39/test262/blob/main/LICENSE file. + assert.same(escape('\u2028'), '\\u2028', 'line terminator \\u2028 is escaped correctly to \\\\u2028'); + assert.same(escape('\u2029'), '\\u2029', 'line terminator \\u2029 is escaped correctly to \\\\u2029'); + assert.same(escape('\u2028\u2029'), '\\u2028\\u2029', 'line terminators are escaped correctly'); + assert.same(escape('\u2028a\u2029a'), '\\u2028a\\u2029a', 'mixed line terminators are escaped correctly'); + + assert.same(escape('.a/b'), '\\.a\\/b', 'mixed string with solidus character is escaped correctly'); + assert.same(escape('/./'), '\\/\\.\\/', 'solidus character is escaped correctly - regexp similar'); + assert.same(escape('./a\\/*b+c?d^e$f|g{2}h[i]j\\k'), '\\.\\/a\\\\\\/\\*b\\+c\\?d\\^e\\$f\\|g\\{2\\}h\\[i\\]j\\\\k', 'complex string with multiple special characters is escaped correctly'); + + assert.same(escape('/'), '\\/', 'solidus character is escaped correctly'); + assert.same(escape('//'), '\\/\\/', 'solidus character is escaped correctly - multiple occurrences 1'); + assert.same(escape('///'), '\\/\\/\\/', 'solidus character is escaped correctly - multiple occurrences 2'); + assert.same(escape('////'), '\\/\\/\\/\\/', 'solidus character is escaped correctly - multiple occurrences 3'); + + assert.same(escape('.'), '\\.', 'dot character is escaped correctly'); + assert.same(escape('*'), '\\*', 'asterisk character is escaped correctly'); + assert.same(escape('+'), '\\+', 'plus character is escaped correctly'); + assert.same(escape('?'), '\\?', 'question mark character is escaped correctly'); + assert.same(escape('^'), '\\^', 'caret character is escaped correctly'); + assert.same(escape('$'), '\\$', 'dollar character is escaped correctly'); + assert.same(escape('|'), '\\|', 'pipe character is escaped correctly'); + assert.same(escape('('), '\\(', 'open parenthesis character is escaped correctly'); + assert.same(escape(')'), '\\)', 'close parenthesis character is escaped correctly'); + assert.same(escape('['), '\\[', 'open bracket character is escaped correctly'); + assert.same(escape(']'), '\\]', 'close bracket character is escaped correctly'); + assert.same(escape('{'), '\\{', 'open brace character is escaped correctly'); + assert.same(escape('}'), '\\}', 'close brace character is escaped correctly'); + assert.same(escape('\\'), '\\\\', 'backslash character is escaped correctly'); + + const codePoints = String.fromCharCode(0x100, 0x200, 0x300); + assert.same(escape(codePoints), codePoints, 'characters are correctly not escaped'); + + assert.same(escape('你好'), '你好', 'Chinese characters are correctly not escaped'); + assert.same(escape('こんにちは'), 'こんにちは', 'Japanese characters are correctly not escaped'); + assert.same(escape('안녕하세요'), '안녕하세요', 'Korean characters are correctly not escaped'); + assert.same(escape('Привет'), 'Привет', 'Cyrillic characters are correctly not escaped'); + assert.same(escape('مرحبا'), 'مرحبا', 'Arabic characters are correctly not escaped'); + assert.same(escape('हेलो'), 'हेलो', 'Devanagari characters are correctly not escaped'); + assert.same(escape('Γειά σου'), 'Γειά\\x20σου', 'Greek characters are correctly not escaped'); + assert.same(escape('שלום'), 'שלום', 'Hebrew characters are correctly not escaped'); + assert.same(escape('สวัสดี'), 'สวัสดี', 'Thai characters are correctly not escaped'); + assert.same(escape('नमस्ते'), 'नमस्ते', 'Hindi characters are correctly not escaped'); + assert.same(escape('ሰላም'), 'ሰላም', 'Amharic characters are correctly not escaped'); + assert.same(escape('हैलो'), 'हैलो', 'Hindi characters with diacritics are correctly not escaped'); + assert.same(escape('안녕!'), '안녕\\x21', 'Korean character with special character is correctly escaped'); + assert.same(escape('.hello\uD7FFworld'), '\\.hello\uD7FFworld', 'Mixed ASCII and Unicode characters are correctly escaped'); + + assert.same(escape('\uFEFF'), '\\ufeff', 'whitespace \\uFEFF is escaped correctly to \\uFEFF'); + assert.same(escape('\u0020'), '\\x20', 'whitespace \\u0020 is escaped correctly to \\x20'); + assert.same(escape('\u00A0'), '\\xa0', 'whitespace \\u00A0 is escaped correctly to \\xA0'); + assert.same(escape('\u202F'), '\\u202f', 'whitespace \\u202F is escaped correctly to \\u202F'); + assert.same(escape('\u0009'), '\\t', 'whitespace \\u0009 is escaped correctly to \\t'); + assert.same(escape('\u000B'), '\\v', 'whitespace \\u000B is escaped correctly to \\v'); + assert.same(escape('\u000C'), '\\f', 'whitespace \\u000C is escaped correctly to \\f'); + assert.same(escape('\uFEFF\u0020\u00A0\u202F\u0009\u000B\u000C'), '\\ufeff\\x20\\xa0\\u202f\\t\\v\\f', 'whitespaces are escaped correctly'); + + // Escaping initial digits + assert.same(escape('1111'), '\\x31111', 'Initial decimal digit 1 is escaped'); + assert.same(escape('2222'), '\\x32222', 'Initial decimal digit 2 is escaped'); + assert.same(escape('3333'), '\\x33333', 'Initial decimal digit 3 is escaped'); + assert.same(escape('4444'), '\\x34444', 'Initial decimal digit 4 is escaped'); + assert.same(escape('5555'), '\\x35555', 'Initial decimal digit 5 is escaped'); + assert.same(escape('6666'), '\\x36666', 'Initial decimal digit 6 is escaped'); + assert.same(escape('7777'), '\\x37777', 'Initial decimal digit 7 is escaped'); + assert.same(escape('8888'), '\\x38888', 'Initial decimal digit 8 is escaped'); + assert.same(escape('9999'), '\\x39999', 'Initial decimal digit 9 is escaped'); + assert.same(escape('0000'), '\\x30000', 'Initial decimal digit 0 is escaped'); + + // Escaping initial ASCII letters + assert.same(escape('aaa'), '\\x61aa', 'Initial ASCII letter a is escaped'); + assert.same(escape('bbb'), '\\x62bb', 'Initial ASCII letter b is escaped'); + assert.same(escape('ccc'), '\\x63cc', 'Initial ASCII letter c is escaped'); + assert.same(escape('ddd'), '\\x64dd', 'Initial ASCII letter d is escaped'); + assert.same(escape('eee'), '\\x65ee', 'Initial ASCII letter e is escaped'); + assert.same(escape('fff'), '\\x66ff', 'Initial ASCII letter f is escaped'); + assert.same(escape('ggg'), '\\x67gg', 'Initial ASCII letter g is escaped'); + assert.same(escape('hhh'), '\\x68hh', 'Initial ASCII letter h is escaped'); + assert.same(escape('iii'), '\\x69ii', 'Initial ASCII letter i is escaped'); + assert.same(escape('jjj'), '\\x6ajj', 'Initial ASCII letter j is escaped'); + assert.same(escape('kkk'), '\\x6bkk', 'Initial ASCII letter k is escaped'); + assert.same(escape('lll'), '\\x6cll', 'Initial ASCII letter l is escaped'); + assert.same(escape('mmm'), '\\x6dmm', 'Initial ASCII letter m is escaped'); + assert.same(escape('nnn'), '\\x6enn', 'Initial ASCII letter n is escaped'); + assert.same(escape('ooo'), '\\x6foo', 'Initial ASCII letter o is escaped'); + assert.same(escape('ppp'), '\\x70pp', 'Initial ASCII letter p is escaped'); + assert.same(escape('qqq'), '\\x71qq', 'Initial ASCII letter q is escaped'); + assert.same(escape('rrr'), '\\x72rr', 'Initial ASCII letter r is escaped'); + assert.same(escape('sss'), '\\x73ss', 'Initial ASCII letter s is escaped'); + assert.same(escape('ttt'), '\\x74tt', 'Initial ASCII letter t is escaped'); + assert.same(escape('uuu'), '\\x75uu', 'Initial ASCII letter u is escaped'); + assert.same(escape('vvv'), '\\x76vv', 'Initial ASCII letter v is escaped'); + assert.same(escape('www'), '\\x77ww', 'Initial ASCII letter w is escaped'); + assert.same(escape('xxx'), '\\x78xx', 'Initial ASCII letter x is escaped'); + assert.same(escape('yyy'), '\\x79yy', 'Initial ASCII letter y is escaped'); + assert.same(escape('zzz'), '\\x7azz', 'Initial ASCII letter z is escaped'); + assert.same(escape('AAA'), '\\x41AA', 'Initial ASCII letter A is escaped'); + assert.same(escape('BBB'), '\\x42BB', 'Initial ASCII letter B is escaped'); + assert.same(escape('CCC'), '\\x43CC', 'Initial ASCII letter C is escaped'); + assert.same(escape('DDD'), '\\x44DD', 'Initial ASCII letter D is escaped'); + assert.same(escape('EEE'), '\\x45EE', 'Initial ASCII letter E is escaped'); + assert.same(escape('FFF'), '\\x46FF', 'Initial ASCII letter F is escaped'); + assert.same(escape('GGG'), '\\x47GG', 'Initial ASCII letter G is escaped'); + assert.same(escape('HHH'), '\\x48HH', 'Initial ASCII letter H is escaped'); + assert.same(escape('III'), '\\x49II', 'Initial ASCII letter I is escaped'); + assert.same(escape('JJJ'), '\\x4aJJ', 'Initial ASCII letter J is escaped'); + assert.same(escape('KKK'), '\\x4bKK', 'Initial ASCII letter K is escaped'); + assert.same(escape('LLL'), '\\x4cLL', 'Initial ASCII letter L is escaped'); + assert.same(escape('MMM'), '\\x4dMM', 'Initial ASCII letter M is escaped'); + assert.same(escape('NNN'), '\\x4eNN', 'Initial ASCII letter N is escaped'); + assert.same(escape('OOO'), '\\x4fOO', 'Initial ASCII letter O is escaped'); + assert.same(escape('PPP'), '\\x50PP', 'Initial ASCII letter P is escaped'); + assert.same(escape('QQQ'), '\\x51QQ', 'Initial ASCII letter Q is escaped'); + assert.same(escape('RRR'), '\\x52RR', 'Initial ASCII letter R is escaped'); + assert.same(escape('SSS'), '\\x53SS', 'Initial ASCII letter S is escaped'); + assert.same(escape('TTT'), '\\x54TT', 'Initial ASCII letter T is escaped'); + assert.same(escape('UUU'), '\\x55UU', 'Initial ASCII letter U is escaped'); + assert.same(escape('VVV'), '\\x56VV', 'Initial ASCII letter V is escaped'); + assert.same(escape('WWW'), '\\x57WW', 'Initial ASCII letter W is escaped'); + assert.same(escape('XXX'), '\\x58XX', 'Initial ASCII letter X is escaped'); + assert.same(escape('YYY'), '\\x59YY', 'Initial ASCII letter Y is escaped'); + assert.same(escape('ZZZ'), '\\x5aZZ', 'Initial ASCII letter Z is escaped'); + + // Mixed case with special characters + assert.same(escape('1+1'), '\\x31\\+1', 'Initial decimal digit 1 with special character is escaped'); + assert.same(escape('2+2'), '\\x32\\+2', 'Initial decimal digit 2 with special character is escaped'); + assert.same(escape('3+3'), '\\x33\\+3', 'Initial decimal digit 3 with special character is escaped'); + assert.same(escape('4+4'), '\\x34\\+4', 'Initial decimal digit 4 with special character is escaped'); + assert.same(escape('5+5'), '\\x35\\+5', 'Initial decimal digit 5 with special character is escaped'); + assert.same(escape('6+6'), '\\x36\\+6', 'Initial decimal digit 6 with special character is escaped'); + assert.same(escape('7+7'), '\\x37\\+7', 'Initial decimal digit 7 with special character is escaped'); + assert.same(escape('8+8'), '\\x38\\+8', 'Initial decimal digit 8 with special character is escaped'); + assert.same(escape('9+9'), '\\x39\\+9', 'Initial decimal digit 9 with special character is escaped'); + assert.same(escape('0+0'), '\\x30\\+0', 'Initial decimal digit 0 with special character is escaped'); + + assert.same(escape('a*a'), '\\x61\\*a', 'Initial ASCII letter a with special character is escaped'); + assert.same(escape('b*b'), '\\x62\\*b', 'Initial ASCII letter b with special character is escaped'); + assert.same(escape('c*c'), '\\x63\\*c', 'Initial ASCII letter c with special character is escaped'); + assert.same(escape('d*d'), '\\x64\\*d', 'Initial ASCII letter d with special character is escaped'); + assert.same(escape('e*e'), '\\x65\\*e', 'Initial ASCII letter e with special character is escaped'); + assert.same(escape('f*f'), '\\x66\\*f', 'Initial ASCII letter f with special character is escaped'); + assert.same(escape('g*g'), '\\x67\\*g', 'Initial ASCII letter g with special character is escaped'); + assert.same(escape('h*h'), '\\x68\\*h', 'Initial ASCII letter h with special character is escaped'); + assert.same(escape('i*i'), '\\x69\\*i', 'Initial ASCII letter i with special character is escaped'); + assert.same(escape('j*j'), '\\x6a\\*j', 'Initial ASCII letter j with special character is escaped'); + assert.same(escape('k*k'), '\\x6b\\*k', 'Initial ASCII letter k with special character is escaped'); + assert.same(escape('l*l'), '\\x6c\\*l', 'Initial ASCII letter l with special character is escaped'); + assert.same(escape('m*m'), '\\x6d\\*m', 'Initial ASCII letter m with special character is escaped'); + assert.same(escape('n*n'), '\\x6e\\*n', 'Initial ASCII letter n with special character is escaped'); + assert.same(escape('o*o'), '\\x6f\\*o', 'Initial ASCII letter o with special character is escaped'); + assert.same(escape('p*p'), '\\x70\\*p', 'Initial ASCII letter p with special character is escaped'); + assert.same(escape('q*q'), '\\x71\\*q', 'Initial ASCII letter q with special character is escaped'); + assert.same(escape('r*r'), '\\x72\\*r', 'Initial ASCII letter r with special character is escaped'); + assert.same(escape('s*s'), '\\x73\\*s', 'Initial ASCII letter s with special character is escaped'); + assert.same(escape('t*t'), '\\x74\\*t', 'Initial ASCII letter t with special character is escaped'); + assert.same(escape('u*u'), '\\x75\\*u', 'Initial ASCII letter u with special character is escaped'); + assert.same(escape('v*v'), '\\x76\\*v', 'Initial ASCII letter v with special character is escaped'); + assert.same(escape('w*w'), '\\x77\\*w', 'Initial ASCII letter w with special character is escaped'); + assert.same(escape('x*x'), '\\x78\\*x', 'Initial ASCII letter x with special character is escaped'); + assert.same(escape('y*y'), '\\x79\\*y', 'Initial ASCII letter y with special character is escaped'); + assert.same(escape('z*z'), '\\x7a\\*z', 'Initial ASCII letter z with special character is escaped'); + assert.same(escape('A*A'), '\\x41\\*A', 'Initial ASCII letter A with special character is escaped'); + assert.same(escape('B*B'), '\\x42\\*B', 'Initial ASCII letter B with special character is escaped'); + assert.same(escape('C*C'), '\\x43\\*C', 'Initial ASCII letter C with special character is escaped'); + assert.same(escape('D*D'), '\\x44\\*D', 'Initial ASCII letter D with special character is escaped'); + assert.same(escape('E*E'), '\\x45\\*E', 'Initial ASCII letter E with special character is escaped'); + assert.same(escape('F*F'), '\\x46\\*F', 'Initial ASCII letter F with special character is escaped'); + assert.same(escape('G*G'), '\\x47\\*G', 'Initial ASCII letter G with special character is escaped'); + assert.same(escape('H*H'), '\\x48\\*H', 'Initial ASCII letter H with special character is escaped'); + assert.same(escape('I*I'), '\\x49\\*I', 'Initial ASCII letter I with special character is escaped'); + assert.same(escape('J*J'), '\\x4a\\*J', 'Initial ASCII letter J with special character is escaped'); + assert.same(escape('K*K'), '\\x4b\\*K', 'Initial ASCII letter K with special character is escaped'); + assert.same(escape('L*L'), '\\x4c\\*L', 'Initial ASCII letter L with special character is escaped'); + assert.same(escape('M*M'), '\\x4d\\*M', 'Initial ASCII letter M with special character is escaped'); + assert.same(escape('N*N'), '\\x4e\\*N', 'Initial ASCII letter N with special character is escaped'); + assert.same(escape('O*O'), '\\x4f\\*O', 'Initial ASCII letter O with special character is escaped'); + assert.same(escape('P*P'), '\\x50\\*P', 'Initial ASCII letter P with special character is escaped'); + assert.same(escape('Q*Q'), '\\x51\\*Q', 'Initial ASCII letter Q with special character is escaped'); + assert.same(escape('R*R'), '\\x52\\*R', 'Initial ASCII letter R with special character is escaped'); + assert.same(escape('S*S'), '\\x53\\*S', 'Initial ASCII letter S with special character is escaped'); + assert.same(escape('T*T'), '\\x54\\*T', 'Initial ASCII letter T with special character is escaped'); + assert.same(escape('U*U'), '\\x55\\*U', 'Initial ASCII letter U with special character is escaped'); + assert.same(escape('V*V'), '\\x56\\*V', 'Initial ASCII letter V with special character is escaped'); + assert.same(escape('W*W'), '\\x57\\*W', 'Initial ASCII letter W with special character is escaped'); + assert.same(escape('X*X'), '\\x58\\*X', 'Initial ASCII letter X with special character is escaped'); + assert.same(escape('Y*Y'), '\\x59\\*Y', 'Initial ASCII letter Y with special character is escaped'); + assert.same(escape('Z*Z'), '\\x5a\\*Z', 'Initial ASCII letter Z with special character is escaped'); + + assert.same(escape('_'), '_', 'Single underscore character is not escaped'); + assert.same(escape('__'), '__', 'Thunderscore character is not escaped'); + assert.same(escape('hello_world'), '\\x68ello_world', 'String starting with ASCII letter and containing underscore is not escaped'); + assert.same(escape('1_hello_world'), '\\x31_hello_world', 'String starting with digit and containing underscore is correctly escaped'); + assert.same(escape('a_b_c'), '\\x61_b_c', 'String starting with ASCII letter and containing multiple underscores is correctly escaped'); + assert.same(escape('3_b_4'), '\\x33_b_4', 'String starting with digit and containing multiple underscores is correctly escaped'); + assert.same(escape('_hello'), '_hello', 'String starting with underscore and containing other characters is not escaped'); + assert.same(escape('_1hello'), '_1hello', 'String starting with underscore and digit is not escaped'); + assert.same(escape('_a_1_2'), '_a_1_2', 'String starting with underscore and mixed characters is not escaped'); + + // Specific surrogate points + assert.same(escape('\uD800'), '\\ud800', 'High surrogate \\uD800 is correctly escaped'); + assert.same(escape('\uDBFF'), '\\udbff', 'High surrogate \\uDBFF is correctly escaped'); + assert.same(escape('\uDC00'), '\\udc00', 'Low surrogate \\uDC00 is correctly escaped'); + assert.same(escape('\uDFFF'), '\\udfff', 'Low surrogate \\uDFFF is correctly escaped'); + + // Leading Surrogates + const highSurrogatesGroup1 = '\uD800\uD801\uD802\uD803\uD804\uD805\uD806\uD807\uD808\uD809\uD80A\uD80B\uD80C\uD80D\uD80E\uD80F'; + const highSurrogatesGroup2 = '\uD810\uD811\uD812\uD813\uD814\uD815\uD816\uD817\uD818\uD819\uD81A\uD81B\uD81C\uD81D\uD81E\uD81F'; + const highSurrogatesGroup3 = '\uD820\uD821\uD822\uD823\uD824\uD825\uD826\uD827\uD828\uD829\uD82A\uD82B\uD82C\uD82D\uD82E\uD82F'; + const highSurrogatesGroup4 = '\uD830\uD831\uD832\uD833\uD834\uD835\uD836\uD837\uD838\uD839\uD83A\uD83B\uD83C\uD83D\uD83E\uD83F'; + const highSurrogatesGroup5 = '\uD840\uD841\uD842\uD843\uD844\uD845\uD846\uD847\uD848\uD849\uD84A\uD84B\uD84C\uD84D\uD84E\uD84F'; + const highSurrogatesGroup6 = '\uD850\uD851\uD852\uD853\uD854\uD855\uD856\uD857\uD858\uD859\uD85A\uD85B\uD85C\uD85D\uD85E\uD85F'; + const highSurrogatesGroup7 = '\uD860\uD861\uD862\uD863\uD864\uD865\uD866\uD867\uD868\uD869\uD86A\uD86B\uD86C\uD86D\uD86E\uD86F'; + const highSurrogatesGroup8 = '\uD870\uD871\uD872\uD873\uD874\uD875\uD876\uD877\uD878\uD879\uD87A\uD87B\uD87C\uD87D\uD87E\uD87F'; + const highSurrogatesGroup9 = '\uD880\uD881\uD882\uD883\uD884\uD885\uD886\uD887\uD888\uD889\uD88A\uD88B\uD88C\uD88D\uD88E\uD88F'; + const highSurrogatesGroup10 = '\uD890\uD891\uD892\uD893\uD894\uD895\uD896\uD897\uD898\uD899\uD89A\uD89B\uD89C\uD89D\uD89E\uD89F'; + const highSurrogatesGroup11 = '\uD8A0\uD8A1\uD8A2\uD8A3\uD8A4\uD8A5\uD8A6\uD8A7\uD8A8\uD8A9\uD8AA\uD8AB\uD8AC\uD8AD\uD8AE\uD8AF'; + const highSurrogatesGroup12 = '\uD8B0\uD8B1\uD8B2\uD8B3\uD8B4\uD8B5\uD8B6\uD8B7\uD8B8\uD8B9\uD8BA\uD8BB\uD8BC\uD8BD\uD8BE\uD8BF'; + const highSurrogatesGroup13 = '\uD8C0\uD8C1\uD8C2\uD8C3\uD8C4\uD8C5\uD8C6\uD8C7\uD8C8\uD8C9\uD8CA\uD8CB\uD8CC\uD8CD\uD8CE\uD8CF'; + const highSurrogatesGroup14 = '\uD8D0\uD8D1\uD8D2\uD8D3\uD8D4\uD8D5\uD8D6\uD8D7\uD8D8\uD8D9\uD8DA\uD8DB\uD8DC\uD8DD\uD8DE\uD8DF'; + const highSurrogatesGroup15 = '\uD8E0\uD8E1\uD8E2\uD8E3\uD8E4\uD8E5\uD8E6\uD8E7\uD8E8\uD8E9\uD8EA\uD8EB\uD8EC\uD8ED\uD8EE\uD8EF'; + const highSurrogatesGroup16 = '\uD8F0\uD8F1\uD8F2\uD8F3\uD8F4\uD8F5\uD8F6\uD8F7\uD8F8\uD8F9\uD8FA\uD8FB\uD8FC\uD8FD\uD8FE\uD8FF'; + + assert.same(escape(highSurrogatesGroup1), '\\ud800\\ud801\\ud802\\ud803\\ud804\\ud805\\ud806\\ud807\\ud808\\ud809\\ud80a\\ud80b\\ud80c\\ud80d\\ud80e\\ud80f', 'High surrogates group 1 are correctly escaped'); + assert.same(escape(highSurrogatesGroup2), '\\ud810\\ud811\\ud812\\ud813\\ud814\\ud815\\ud816\\ud817\\ud818\\ud819\\ud81a\\ud81b\\ud81c\\ud81d\\ud81e\\ud81f', 'High surrogates group 2 are correctly escaped'); + assert.same(escape(highSurrogatesGroup3), '\\ud820\\ud821\\ud822\\ud823\\ud824\\ud825\\ud826\\ud827\\ud828\\ud829\\ud82a\\ud82b\\ud82c\\ud82d\\ud82e\\ud82f', 'High surrogates group 3 are correctly escaped'); + assert.same(escape(highSurrogatesGroup4), '\\ud830\\ud831\\ud832\\ud833\\ud834\\ud835\\ud836\\ud837\\ud838\\ud839\\ud83a\\ud83b\\ud83c\\ud83d\\ud83e\\ud83f', 'High surrogates group 4 are correctly escaped'); + assert.same(escape(highSurrogatesGroup5), '\\ud840\\ud841\\ud842\\ud843\\ud844\\ud845\\ud846\\ud847\\ud848\\ud849\\ud84a\\ud84b\\ud84c\\ud84d\\ud84e\\ud84f', 'High surrogates group 5 are correctly escaped'); + assert.same(escape(highSurrogatesGroup6), '\\ud850\\ud851\\ud852\\ud853\\ud854\\ud855\\ud856\\ud857\\ud858\\ud859\\ud85a\\ud85b\\ud85c\\ud85d\\ud85e\\ud85f', 'High surrogates group 6 are correctly escaped'); + assert.same(escape(highSurrogatesGroup7), '\\ud860\\ud861\\ud862\\ud863\\ud864\\ud865\\ud866\\ud867\\ud868\\ud869\\ud86a\\ud86b\\ud86c\\ud86d\\ud86e\\ud86f', 'High surrogates group 7 are correctly escaped'); + assert.same(escape(highSurrogatesGroup8), '\\ud870\\ud871\\ud872\\ud873\\ud874\\ud875\\ud876\\ud877\\ud878\\ud879\\ud87a\\ud87b\\ud87c\\ud87d\\ud87e\\ud87f', 'High surrogates group 8 are correctly escaped'); + assert.same(escape(highSurrogatesGroup9), '\\ud880\\ud881\\ud882\\ud883\\ud884\\ud885\\ud886\\ud887\\ud888\\ud889\\ud88a\\ud88b\\ud88c\\ud88d\\ud88e\\ud88f', 'High surrogates group 9 are correctly escaped'); + assert.same(escape(highSurrogatesGroup10), '\\ud890\\ud891\\ud892\\ud893\\ud894\\ud895\\ud896\\ud897\\ud898\\ud899\\ud89a\\ud89b\\ud89c\\ud89d\\ud89e\\ud89f', 'High surrogates group 10 are correctly escaped'); + assert.same(escape(highSurrogatesGroup11), '\\ud8a0\\ud8a1\\ud8a2\\ud8a3\\ud8a4\\ud8a5\\ud8a6\\ud8a7\\ud8a8\\ud8a9\\ud8aa\\ud8ab\\ud8ac\\ud8ad\\ud8ae\\ud8af', 'High surrogates group 11 are correctly escaped'); + assert.same(escape(highSurrogatesGroup12), '\\ud8b0\\ud8b1\\ud8b2\\ud8b3\\ud8b4\\ud8b5\\ud8b6\\ud8b7\\ud8b8\\ud8b9\\ud8ba\\ud8bb\\ud8bc\\ud8bd\\ud8be\\ud8bf', 'High surrogates group 12 are correctly escaped'); + assert.same(escape(highSurrogatesGroup13), '\\ud8c0\\ud8c1\\ud8c2\\ud8c3\\ud8c4\\ud8c5\\ud8c6\\ud8c7\\ud8c8\\ud8c9\\ud8ca\\ud8cb\\ud8cc\\ud8cd\\ud8ce\\ud8cf', 'High surrogates group 13 are correctly escaped'); + assert.same(escape(highSurrogatesGroup14), '\\ud8d0\\ud8d1\\ud8d2\\ud8d3\\ud8d4\\ud8d5\\ud8d6\\ud8d7\\ud8d8\\ud8d9\\ud8da\\ud8db\\ud8dc\\ud8dd\\ud8de\\ud8df', 'High surrogates group 14 are correctly escaped'); + assert.same(escape(highSurrogatesGroup15), '\\ud8e0\\ud8e1\\ud8e2\\ud8e3\\ud8e4\\ud8e5\\ud8e6\\ud8e7\\ud8e8\\ud8e9\\ud8ea\\ud8eb\\ud8ec\\ud8ed\\ud8ee\\ud8ef', 'High surrogates group 15 are correctly escaped'); + assert.same(escape(highSurrogatesGroup16), '\\ud8f0\\ud8f1\\ud8f2\\ud8f3\\ud8f4\\ud8f5\\ud8f6\\ud8f7\\ud8f8\\ud8f9\\ud8fa\\ud8fb\\ud8fc\\ud8fd\\ud8fe\\ud8ff', 'High surrogates group 16 are correctly escaped'); + + // Trailing Surrogates + const lowSurrogatesGroup1 = '\uDC00\uDC01\uDC02\uDC03\uDC04\uDC05\uDC06\uDC07\uDC08\uDC09\uDC0A\uDC0B\uDC0C\uDC0D\uDC0E\uDC0F'; + const lowSurrogatesGroup2 = '\uDC10\uDC11\uDC12\uDC13\uDC14\uDC15\uDC16\uDC17\uDC18\uDC19\uDC1A\uDC1B\uDC1C\uDC1D\uDC1E\uDC1F'; + const lowSurrogatesGroup3 = '\uDC20\uDC21\uDC22\uDC23\uDC24\uDC25\uDC26\uDC27\uDC28\uDC29\uDC2A\uDC2B\uDC2C\uDC2D\uDC2E\uDC2F'; + const lowSurrogatesGroup4 = '\uDC30\uDC31\uDC32\uDC33\uDC34\uDC35\uDC36\uDC37\uDC38\uDC39\uDC3A\uDC3B\uDC3C\uDC3D\uDC3E\uDC3F'; + const lowSurrogatesGroup5 = '\uDC40\uDC41\uDC42\uDC43\uDC44\uDC45\uDC46\uDC47\uDC48\uDC49\uDC4A\uDC4B\uDC4C\uDC4D\uDC4E\uDC4F'; + const lowSurrogatesGroup6 = '\uDC50\uDC51\uDC52\uDC53\uDC54\uDC55\uDC56\uDC57\uDC58\uDC59\uDC5A\uDC5B\uDC5C\uDC5D\uDC5E\uDC5F'; + const lowSurrogatesGroup7 = '\uDC60\uDC61\uDC62\uDC63\uDC64\uDC65\uDC66\uDC67\uDC68\uDC69\uDC6A\uDC6B\uDC6C\uDC6D\uDC6E\uDC6F'; + const lowSurrogatesGroup8 = '\uDC70\uDC71\uDC72\uDC73\uDC74\uDC75\uDC76\uDC77\uDC78\uDC79\uDC7A\uDC7B\uDC7C\uDC7D\uDC7E\uDC7F'; + const lowSurrogatesGroup9 = '\uDC80\uDC81\uDC82\uDC83\uDC84\uDC85\uDC86\uDC87\uDC88\uDC89\uDC8A\uDC8B\uDC8C\uDC8D\uDC8E\uDC8F'; + const lowSurrogatesGroup10 = '\uDC90\uDC91\uDC92\uDC93\uDC94\uDC95\uDC96\uDC97\uDC98\uDC99\uDC9A\uDC9B\uDC9C\uDC9D\uDC9E\uDC9F'; + const lowSurrogatesGroup11 = '\uDCA0\uDCA1\uDCA2\uDCA3\uDCA4\uDCA5\uDCA6\uDCA7\uDCA8\uDCA9\uDCAA\uDCAB\uDCAC\uDCAD\uDCAE\uDCAF'; + const lowSurrogatesGroup12 = '\uDCB0\uDCB1\uDCB2\uDCB3\uDCB4\uDCB5\uDCB6\uDCB7\uDCB8\uDCB9\uDCBA\uDCBB\uDCBC\uDCBD\uDCBE\uDCBF'; + const lowSurrogatesGroup13 = '\uDCC0\uDCC1\uDCC2\uDCC3\uDCC4\uDCC5\uDCC6\uDCC7\uDCC8\uDCC9\uDCCA\uDCCB\uDCCC\uDCCD\uDCCE\uDCCF'; + const lowSurrogatesGroup14 = '\uDCD0\uDCD1\uDCD2\uDCD3\uDCD4\uDCD5\uDCD6\uDCD7\uDCD8\uDCD9\uDCDA\uDCDB\uDCDC\uDCDD\uDCDE\uDCDF'; + const lowSurrogatesGroup15 = '\uDCE0\uDCE1\uDCE2\uDCE3\uDCE4\uDCE5\uDCE6\uDCE7\uDCE8\uDCE9\uDCEA\uDCEB\uDCEC\uDCED\uDCEE\uDCEF'; + const lowSurrogatesGroup16 = '\uDCF0\uDCF1\uDCF2\uDCF3\uDCF4\uDCF5\uDCF6\uDCF7\uDCF8\uDCF9\uDCFA\uDCFB\uDCFC\uDCFD\uDCFE\uDCFF'; + + assert.same(escape(lowSurrogatesGroup1), '\\udc00\\udc01\\udc02\\udc03\\udc04\\udc05\\udc06\\udc07\\udc08\\udc09\\udc0a\\udc0b\\udc0c\\udc0d\\udc0e\\udc0f', 'Low surrogates group 1 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup2), '\\udc10\\udc11\\udc12\\udc13\\udc14\\udc15\\udc16\\udc17\\udc18\\udc19\\udc1a\\udc1b\\udc1c\\udc1d\\udc1e\\udc1f', 'Low surrogates group 2 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup3), '\\udc20\\udc21\\udc22\\udc23\\udc24\\udc25\\udc26\\udc27\\udc28\\udc29\\udc2a\\udc2b\\udc2c\\udc2d\\udc2e\\udc2f', 'Low surrogates group 3 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup4), '\\udc30\\udc31\\udc32\\udc33\\udc34\\udc35\\udc36\\udc37\\udc38\\udc39\\udc3a\\udc3b\\udc3c\\udc3d\\udc3e\\udc3f', 'Low surrogates group 4 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup5), '\\udc40\\udc41\\udc42\\udc43\\udc44\\udc45\\udc46\\udc47\\udc48\\udc49\\udc4a\\udc4b\\udc4c\\udc4d\\udc4e\\udc4f', 'Low surrogates group 5 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup6), '\\udc50\\udc51\\udc52\\udc53\\udc54\\udc55\\udc56\\udc57\\udc58\\udc59\\udc5a\\udc5b\\udc5c\\udc5d\\udc5e\\udc5f', 'Low surrogates group 6 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup7), '\\udc60\\udc61\\udc62\\udc63\\udc64\\udc65\\udc66\\udc67\\udc68\\udc69\\udc6a\\udc6b\\udc6c\\udc6d\\udc6e\\udc6f', 'Low surrogates group 7 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup8), '\\udc70\\udc71\\udc72\\udc73\\udc74\\udc75\\udc76\\udc77\\udc78\\udc79\\udc7a\\udc7b\\udc7c\\udc7d\\udc7e\\udc7f', 'Low surrogates group 8 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup9), '\\udc80\\udc81\\udc82\\udc83\\udc84\\udc85\\udc86\\udc87\\udc88\\udc89\\udc8a\\udc8b\\udc8c\\udc8d\\udc8e\\udc8f', 'Low surrogates group 9 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup10), '\\udc90\\udc91\\udc92\\udc93\\udc94\\udc95\\udc96\\udc97\\udc98\\udc99\\udc9a\\udc9b\\udc9c\\udc9d\\udc9e\\udc9f', 'Low surrogates group 10 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup11), '\\udca0\\udca1\\udca2\\udca3\\udca4\\udca5\\udca6\\udca7\\udca8\\udca9\\udcaa\\udcab\\udcac\\udcad\\udcae\\udcaf', 'Low surrogates group 11 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup12), '\\udcb0\\udcb1\\udcb2\\udcb3\\udcb4\\udcb5\\udcb6\\udcb7\\udcb8\\udcb9\\udcba\\udcbb\\udcbc\\udcbd\\udcbe\\udcbf', 'Low surrogates group 12 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup13), '\\udcc0\\udcc1\\udcc2\\udcc3\\udcc4\\udcc5\\udcc6\\udcc7\\udcc8\\udcc9\\udcca\\udccb\\udccc\\udccd\\udcce\\udccf', 'Low surrogates group 13 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup14), '\\udcd0\\udcd1\\udcd2\\udcd3\\udcd4\\udcd5\\udcd6\\udcd7\\udcd8\\udcd9\\udcda\\udcdb\\udcdc\\udcdd\\udcde\\udcdf', 'Low surrogates group 14 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup15), '\\udce0\\udce1\\udce2\\udce3\\udce4\\udce5\\udce6\\udce7\\udce8\\udce9\\udcea\\udceb\\udcec\\udced\\udcee\\udcef', 'Low surrogates group 15 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup16), '\\udcf0\\udcf1\\udcf2\\udcf3\\udcf4\\udcf5\\udcf6\\udcf7\\udcf8\\udcf9\\udcfa\\udcfb\\udcfc\\udcfd\\udcfe\\udcff', 'Low surrogates group 16 are correctly escaped'); + + assert.same(escape('.a.b'), '\\.a\\.b', 'mixed string with dot character is escaped correctly'); + assert.same(escape('.1+2'), '\\.1\\+2', 'mixed string with plus character is escaped correctly'); + assert.same(escape('.a(b)c'), '\\.a\\(b\\)c', 'mixed string with parentheses is escaped correctly'); + assert.same(escape('.a*b+c'), '\\.a\\*b\\+c', 'mixed string with asterisk and plus characters is escaped correctly'); + assert.same(escape('.a?b^c'), '\\.a\\?b\\^c', 'mixed string with question mark and caret characters is escaped correctly'); + assert.same(escape('.a{2}'), '\\.a\\{2\\}', 'mixed string with curly braces is escaped correctly'); + assert.same(escape('.a|b'), '\\.a\\|b', 'mixed string with pipe character is escaped correctly'); + assert.same(escape('.a\\b'), '\\.a\\\\b', 'mixed string with backslash is escaped correctly'); + assert.same(escape('.a\\\\b'), '\\.a\\\\\\\\b', 'mixed string with backslash is escaped correctly'); + assert.same(escape('.a^b'), '\\.a\\^b', 'mixed string with caret character is escaped correctly'); + assert.same(escape('.a$b'), '\\.a\\$b', 'mixed string with dollar sign is escaped correctly'); + assert.same(escape('.a[b]'), '\\.a\\[b\\]', 'mixed string with square brackets is escaped correctly'); + assert.same(escape('.a.b(c)'), '\\.a\\.b\\(c\\)', 'mixed string with dot and parentheses is escaped correctly'); + assert.same(escape('.a*b+c?d^e$f|g{2}h[i]j\\k'), '\\.a\\*b\\+c\\?d\\^e\\$f\\|g\\{2\\}h\\[i\\]j\\\\k', 'complex string with multiple special characters is escaped correctly'); + + assert.same(escape('^$\\.*+?()[]{}|'), '\\^\\$\\\\\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|', 'Syntax characters are correctly escaped'); + + assert.throws(() => escape(123), TypeError, 'non-string input (number) throws TypeError'); + assert.throws(() => escape({}), TypeError, 'non-string input (object) throws TypeError'); + assert.throws(() => escape([]), TypeError, 'non-string input (array) throws TypeError'); + assert.throws(() => escape(null), TypeError, 'non-string input (null) throws TypeError'); + assert.throws(() => escape(undefined), TypeError, 'non-string input (undefined) throws TypeError'); +}); diff --git a/tests/unit-global/es.regexp.exec.js b/tests/unit-global/es.regexp.exec.js new file mode 100644 index 000000000000..c466e8520846 --- /dev/null +++ b/tests/unit-global/es.regexp.exec.js @@ -0,0 +1,85 @@ +/* eslint-disable prefer-regex-literals -- required for testing */ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('RegExp#exec lastIndex updating', assert => { + let re = /b/; + assert.same(re.lastIndex, 0, '.lastIndex starts at 0 for non-global regexps'); + re.exec('abc'); + assert.same(re.lastIndex, 0, '.lastIndex is not updated for non-global regexps'); + + re = /b/g; + assert.same(re.lastIndex, 0, '.lastIndex starts at 0 for global regexps'); + re.exec('abc'); + assert.same(re.lastIndex, 2, '.lastIndex is updated for global regexps'); + + re = /b*/; + re.exec('a'); + assert.same(re.lastIndex, 0, '.lastIndex is not updated for non-global regexps if the match is empty'); + + re = /b*/g; + re.exec('a'); + assert.same(re.lastIndex, 0, '.lastIndex is not updated for global regexps if the match is empty'); +}); + +QUnit.test('RegExp#exec capturing groups', assert => { + assert.deepEqual(/(a?)/.exec('x'), ['', ''], '/(a?)/.exec("x") returns ["", ""]'); + assert.deepEqual(/(a)?/.exec('x'), ['', undefined], '/(a)?/.exec("x") returns ["", undefined]'); + + // @nicolo-ribaudo: I don't know how to fix this in IE8. For the `/(a)?/` case it is fixed using + // #replace, but here also #replace is buggy :( + // assert.deepEqual(/(a?)?/.exec('x'), ['', undefined], '/(a?)?/.exec("x") returns ["", undefined]'); +}); + +if (DESCRIPTORS) { + QUnit.test('RegExp#exec regression', assert => { + assert.throws(() => /l/.exec(Symbol('RegExp#exec test')), 'throws on symbol argument'); + }); + + QUnit.test('RegExp#exec sticky', assert => { + const re = new RegExp('a', 'y'); + const str = 'bbabaab'; + assert.same(re.lastIndex, 0, '#1'); + + assert.same(re.exec(str), null, '#2'); + assert.same(re.lastIndex, 0, '#3'); + + re.lastIndex = 1; + assert.same(re.exec(str), null, '#4'); + assert.same(re.lastIndex, 0, '#5'); + + re.lastIndex = 2; + const result = re.exec(str); + assert.deepEqual(result, ['a'], '#6'); + assert.same(result.index, 2, '#7'); + assert.same(re.lastIndex, 3, '#8'); + + assert.same(re.exec(str), null, '#9'); + assert.same(re.lastIndex, 0, '#10'); + + re.lastIndex = 4; + assert.deepEqual(re.exec(str), ['a'], '#11'); + assert.same(re.lastIndex, 5, '#12'); + + assert.deepEqual(re.exec(str), ['a'], '#13'); + assert.same(re.lastIndex, 6, '#14'); + + assert.same(re.exec(str), null, '#15'); + assert.same(re.lastIndex, 0, '#16'); + }); + + QUnit.test('RegExp#exec sticky anchored', assert => { + const regex = new RegExp('^foo', 'y'); + assert.deepEqual(regex.exec('foo'), ['foo'], '#1'); + regex.lastIndex = 2; + assert.same(regex.exec('..foo'), null, '#2'); + regex.lastIndex = 2; + assert.same(regex.exec('.\nfoo'), null, '#3'); + + const regex2 = new RegExp('^foo', 'my'); + regex2.lastIndex = 2; + assert.same(regex2.exec('..foo'), null, '#4'); + regex2.lastIndex = 2; + assert.deepEqual(regex2.exec('.\nfoo'), ['foo'], '#5'); + assert.same(regex2.lastIndex, 5, '#6'); + }); +} diff --git a/tests/unit-global/es.regexp.flags.js b/tests/unit-global/es.regexp.flags.js new file mode 100644 index 000000000000..21c9bb26c338 --- /dev/null +++ b/tests/unit-global/es.regexp.flags.js @@ -0,0 +1,52 @@ +/* eslint-disable prefer-regex-literals, regexp/sort-flags, regexp/no-useless-flag -- required for testing */ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + QUnit.test('RegExp#flags', assert => { + assert.nonEnumerable(RegExp.prototype, 'flags'); + assert.same(/./g.flags, 'g', '/./g.flags is "g"'); + assert.same(/./.flags, '', '/./.flags is ""'); + assert.same(RegExp('.', 'gim').flags, 'gim', 'RegExp(".", "gim").flags is "gim"'); + assert.same(RegExp('.').flags, '', 'RegExp(".").flags is ""'); + assert.same(/./gim.flags, 'gim', '/./gim.flags is "gim"'); + assert.same(/./gmi.flags, 'gim', '/./gmi.flags is "gim"'); + assert.same(/./mig.flags, 'gim', '/./mig.flags is "gim"'); + assert.same(/./mgi.flags, 'gim', '/./mgi.flags is "gim"'); + + let INDICES_SUPPORT = true; + try { + RegExp('.', 'd'); + } catch { + INDICES_SUPPORT = false; + } + + const O = {}; + // modern V8 bug + let calls = ''; + const expected = INDICES_SUPPORT ? 'dgimsy' : 'gimsy'; + + function addGetter(key, chr) { + Object.defineProperty(O, key, { get() { + calls += chr; + return true; + } }); + } + + const pairs = { + dotAll: 's', + global: 'g', + ignoreCase: 'i', + multiline: 'm', + sticky: 'y', + }; + + if (INDICES_SUPPORT) pairs.hasIndices = 'd'; + + for (const key in pairs) addGetter(key, pairs[key]); + + const result = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call(O); + + assert.same(result, expected, 'proper order, result'); + assert.same(calls, expected, 'proper order, calls'); + }); +} diff --git a/tests/unit-global/es.regexp.sticky.js b/tests/unit-global/es.regexp.sticky.js new file mode 100644 index 000000000000..faa611f9ac55 --- /dev/null +++ b/tests/unit-global/es.regexp.sticky.js @@ -0,0 +1,38 @@ +/* eslint-disable prefer-regex-literals -- required for testing */ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + QUnit.test('RegExp#sticky', assert => { + const re = new RegExp('a', 'y'); + assert.true(re.sticky, '.sticky is true'); + assert.same(re.flags, 'y', '.flags contains y'); + assert.false(/a/.sticky); + + const stickyGetter = Object.getOwnPropertyDescriptor(RegExp.prototype, 'sticky').get; + if (typeof stickyGetter == 'function') { + // Old firefox versions set a non-configurable non-writable .sticky property + // It works correctly, but it isn't a getter and it can't be polyfilled. + // We need to skip these tests. + + assert.throws(() => { + stickyGetter.call({}); + }, undefined, '.sticky getter can only be called on RegExp instances'); + try { + stickyGetter.call(/a/); + assert.required('.sticky getter works on literals'); + } catch { + assert.avoid('.sticky getter works on literals'); + } + try { + stickyGetter.call(new RegExp('a')); + assert.required('.sticky getter works on instances'); + } catch { + assert.avoid('.sticky getter works on instances'); + } + + assert.true(Object.hasOwn(RegExp.prototype, 'sticky'), 'prototype has .sticky property'); + // relaxed for early implementations + // assert.same(RegExp.prototype.sticky, undefined, '.sticky is undefined on prototype'); + } + }); +} diff --git a/tests/unit-global/es.regexp.test.js b/tests/unit-global/es.regexp.test.js new file mode 100644 index 000000000000..81efbad5f0f5 --- /dev/null +++ b/tests/unit-global/es.regexp.test.js @@ -0,0 +1,23 @@ + +QUnit.test('RegExp#test delegates to exec', assert => { + const exec = function (...args) { + execCalled = true; + return /./.exec.apply(this, args); + }; + + let execCalled = false; + let re = /[ac]/; + re.exec = exec; + assert.true(re.test('abc'), '#1'); + assert.true(execCalled, '#2'); + + re = /a/; + // Not a function, should be ignored + re.exec = 3; + assert.true(re.test('abc'), '#3'); + + re = /a/; + // Does not return an object, should throw + re.exec = () => 3; + assert.throws(() => re.test('abc', '#4')); +}); diff --git a/tests/tests/es.regexp.to-string.js b/tests/unit-global/es.regexp.to-string.js similarity index 81% rename from tests/tests/es.regexp.to-string.js rename to tests/unit-global/es.regexp.to-string.js index 57c406a7844c..dd4338463dcb 100644 --- a/tests/tests/es.regexp.to-string.js +++ b/tests/unit-global/es.regexp.to-string.js @@ -1,4 +1,5 @@ -import { STRICT } from '../helpers/constants'; +/* eslint-disable prefer-regex-literals, regexp/sort-flags, regexp/no-useless-flag -- required for testing */ +import { STRICT } from '../helpers/constants.js'; QUnit.test('RegExp#toString', assert => { const { toString } = RegExp.prototype; @@ -29,4 +30,9 @@ QUnit.test('RegExp#toString', assert => { assert.throws(() => toString.call(null)); assert.throws(() => toString.call(undefined)); } + + assert.throws(() => toString.call({ + source: Symbol('RegExp#toString test'), + flags: 'g', + }), 'throws on symbol'); }); diff --git a/tests/unit-global/es.set.difference.js b/tests/unit-global/es.set.difference.js new file mode 100644 index 000000000000..56800021c95d --- /dev/null +++ b/tests/unit-global/es.set.difference.js @@ -0,0 +1,73 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +QUnit.test('Set#difference', assert => { + const { difference } = Set.prototype; + const { from } = Array; + + assert.isFunction(difference); + assert.arity(difference, 1); + assert.name(difference, 'difference'); + assert.looksNative(difference); + assert.nonEnumerable(Set.prototype, 'difference'); + + const set = new Set([1]); + assert.notSame(set.difference(new Set()), set); + + assert.deepEqual(from(new Set([1, 2, 3]).difference(new Set([4, 5]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).difference(new Set([3, 4]))), [1, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).difference(createSetLike([4, 5]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).difference(createSetLike([3, 4]))), [1, 2]); + + // TODO: drop from core-js@4 + assert.deepEqual(from(new Set([1, 2, 3]).difference([4, 5])), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).difference([3, 4])), [1, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).difference(createIterable([3, 4]))), [1, 2]); + + assert.same(new Set([42, 43]).difference({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + }).size, 0); + + assert.throws(() => new Set().difference({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).difference(), TypeError); + + assert.throws(() => difference.call({}, [1, 2, 3]), TypeError); + assert.throws(() => difference.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => difference.call(null, [1, 2, 3]), TypeError); + + // A WebKit bug occurs when `this` is updated while Set.prototype.difference is being executed + // https://bugs.webkit.org/show_bug.cgi?id=288595 + const values = [2]; + const setLike = { + size: values.length, + has() { return true; }, + keys() { + let index = 0; + return { + next() { + const done = index >= values.length; + if (baseSet.has(1)) baseSet.clear(); + return { done, value: values[index++] }; + }, + }; + }, + }; + + const baseSet = new Set([1, 2, 3, 4]); + const result = baseSet.difference(setLike); + assert.deepEqual(from(result), [1, 3, 4], 'incorrect behavior when this updated while Set#difference is being executed'); +}); diff --git a/tests/unit-global/es.set.intersection.js b/tests/unit-global/es.set.intersection.js new file mode 100644 index 000000000000..64f84283b33e --- /dev/null +++ b/tests/unit-global/es.set.intersection.js @@ -0,0 +1,58 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +QUnit.test('Set#intersection', assert => { + const { intersection } = Set.prototype; + const { from } = Array; + + assert.isFunction(intersection); + assert.arity(intersection, 1); + assert.name(intersection, 'intersection'); + assert.looksNative(intersection); + assert.nonEnumerable(Set.prototype, 'intersection'); + + const set = new Set([1]); + assert.notSame(set.intersection(new Set()), set); + + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([4, 5]))), []); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([2, 3, 4]))), [2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([4, 5]))), []); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([2, 3, 4]))), [2, 3]); + + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2]))), [3, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2, 1]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2, 1, 0]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2]))), [3, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2, 1]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2, 1, 0]))), [1, 2, 3]); + + // TODO: drop from core-js@4 + assert.deepEqual(from(new Set([1, 2, 3]).intersection([4, 5])), []); + assert.deepEqual(from(new Set([1, 2, 3]).intersection([2, 3, 4])), [2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createIterable([2, 3, 4]))), [2, 3]); + + assert.deepEqual(from(new Set([42, 43]).intersection({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })), [42, 43]); + + assert.throws(() => new Set().intersection({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).intersection(), TypeError); + + assert.throws(() => intersection.call({}, [1, 2, 3]), TypeError); + assert.throws(() => intersection.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => intersection.call(null, [1, 2, 3]), TypeError); +}); diff --git a/tests/unit-global/es.set.is-disjoint-from.js b/tests/unit-global/es.set.is-disjoint-from.js new file mode 100644 index 000000000000..09015f0c2c93 --- /dev/null +++ b/tests/unit-global/es.set.is-disjoint-from.js @@ -0,0 +1,53 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +QUnit.test('Set#isDisjointFrom', assert => { + const { isDisjointFrom } = Set.prototype; + + assert.isFunction(isDisjointFrom); + assert.arity(isDisjointFrom, 1); + assert.name(isDisjointFrom, 'isDisjointFrom'); + assert.looksNative(isDisjointFrom); + assert.nonEnumerable(Set.prototype, 'isDisjointFrom'); + + assert.true(new Set([1]).isDisjointFrom(new Set([2]))); + assert.false(new Set([1]).isDisjointFrom(new Set([1]))); + assert.true(new Set([1, 2, 3]).isDisjointFrom(new Set([4, 5, 6]))); + assert.false(new Set([1, 2, 3]).isDisjointFrom(new Set([5, 4, 3]))); + assert.true(new Set([1]).isDisjointFrom(createSetLike([2]))); + assert.false(new Set([1]).isDisjointFrom(createSetLike([1]))); + assert.true(new Set([1, 2, 3]).isDisjointFrom(createSetLike([4, 5, 6]))); + assert.false(new Set([1, 2, 3]).isDisjointFrom(createSetLike([5, 4, 3]))); + + // TODO: drop from core-js@4 + assert.true(new Set([1]).isDisjointFrom([2])); + assert.false(new Set([1]).isDisjointFrom([1])); + assert.true(new Set([1, 2, 3]).isDisjointFrom([4, 5, 6])); + assert.false(new Set([1, 2, 3]).isDisjointFrom([5, 4, 3])); + assert.true(new Set([1]).isDisjointFrom(createIterable([2]))); + assert.false(new Set([1]).isDisjointFrom(createIterable([1]))); + + assert.false(new Set([42, 43]).isDisjointFrom({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set().isDisjointFrom({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).isDisjointFrom(), TypeError); + assert.throws(() => isDisjointFrom.call({}, [1, 2, 3]), TypeError); + assert.throws(() => isDisjointFrom.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => isDisjointFrom.call(null, [1, 2, 3]), TypeError); +}); diff --git a/tests/unit-global/es.set.is-subset-of.js b/tests/unit-global/es.set.is-subset-of.js new file mode 100644 index 000000000000..7728a78f9e5b --- /dev/null +++ b/tests/unit-global/es.set.is-subset-of.js @@ -0,0 +1,53 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +QUnit.test('Set#isSubsetOf', assert => { + const { isSubsetOf } = Set.prototype; + + assert.isFunction(isSubsetOf); + assert.arity(isSubsetOf, 1); + assert.name(isSubsetOf, 'isSubsetOf'); + assert.looksNative(isSubsetOf); + assert.nonEnumerable(Set.prototype, 'isSubsetOf'); + + assert.true(new Set([1]).isSubsetOf(new Set([1, 2, 3]))); + assert.false(new Set([1]).isSubsetOf(new Set([2, 3, 4]))); + assert.true(new Set([1, 2, 3]).isSubsetOf(new Set([5, 4, 3, 2, 1]))); + assert.false(new Set([1, 2, 3]).isSubsetOf(new Set([5, 4, 3, 2]))); + assert.true(new Set([1]).isSubsetOf(createSetLike([1, 2, 3]))); + assert.false(new Set([1]).isSubsetOf(createSetLike([2, 3, 4]))); + assert.true(new Set([1, 2, 3]).isSubsetOf(createSetLike([5, 4, 3, 2, 1]))); + assert.false(new Set([1, 2, 3]).isSubsetOf(createSetLike([5, 4, 3, 2]))); + + // TODO: drop from core-js@4 + assert.true(new Set([1]).isSubsetOf([1, 2, 3])); + assert.false(new Set([1]).isSubsetOf([2, 3, 4])); + assert.true(new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2, 1])); + assert.false(new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2])); + assert.true(new Set([1]).isSubsetOf(createIterable([1, 2, 3]))); + assert.false(new Set([1]).isSubsetOf(createIterable([2, 3, 4]))); + + assert.true(new Set([42, 43]).isSubsetOf({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set().isSubsetOf({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).isSubsetOf(), TypeError); + assert.throws(() => isSubsetOf.call({}, [1, 2, 3]), TypeError); + assert.throws(() => isSubsetOf.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => isSubsetOf.call(null, [1, 2, 3]), TypeError); +}); diff --git a/tests/unit-global/es.set.is-superset-of.js b/tests/unit-global/es.set.is-superset-of.js new file mode 100644 index 000000000000..bd6cb3256013 --- /dev/null +++ b/tests/unit-global/es.set.is-superset-of.js @@ -0,0 +1,53 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +QUnit.test('Set#isSupersetOf', assert => { + const { isSupersetOf } = Set.prototype; + + assert.isFunction(isSupersetOf); + assert.arity(isSupersetOf, 1); + assert.name(isSupersetOf, 'isSupersetOf'); + assert.looksNative(isSupersetOf); + assert.nonEnumerable(Set.prototype, 'isSupersetOf'); + + assert.true(new Set([1, 2, 3]).isSupersetOf(new Set([1]))); + assert.false(new Set([2, 3, 4]).isSupersetOf(new Set([1]))); + assert.true(new Set([5, 4, 3, 2, 1]).isSupersetOf(new Set([1, 2, 3]))); + assert.false(new Set([5, 4, 3, 2]).isSupersetOf(new Set([1, 2, 3]))); + assert.true(new Set([1, 2, 3]).isSupersetOf(createSetLike([1]))); + assert.false(new Set([2, 3, 4]).isSupersetOf(createSetLike([1]))); + assert.true(new Set([5, 4, 3, 2, 1]).isSupersetOf(createSetLike([1, 2, 3]))); + assert.false(new Set([5, 4, 3, 2]).isSupersetOf(createSetLike([1, 2, 3]))); + + // TODO: drop from core-js@4 + assert.true(new Set([1, 2, 3]).isSupersetOf([1])); + assert.false(new Set([2, 3, 4]).isSupersetOf([1])); + assert.true(new Set([5, 4, 3, 2, 1]).isSupersetOf([1, 2, 3])); + assert.false(new Set([5, 4, 3, 2]).isSupersetOf([1, 2, 3])); + assert.true(new Set([1, 2, 3]).isSupersetOf(createIterable([1]))); + assert.false(new Set([2, 3, 4]).isSupersetOf(createIterable([1]))); + + assert.false(new Set([42, 43]).isSupersetOf({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set().isSupersetOf({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).isSupersetOf(), TypeError); + assert.throws(() => isSupersetOf.call({}, [1, 2, 3]), TypeError); + assert.throws(() => isSupersetOf.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => isSupersetOf.call(null, [1, 2, 3]), TypeError); +}); diff --git a/tests/unit-global/es.set.js b/tests/unit-global/es.set.js new file mode 100644 index 000000000000..9ee14d1e3183 --- /dev/null +++ b/tests/unit-global/es.set.js @@ -0,0 +1,448 @@ +/* eslint-disable sonarjs/no-element-overwrite -- required for testing */ + +import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants.js'; +import { createIterable, is, nativeSubclass } from '../helpers/helpers.js'; + +const Symbol = GLOBAL.Symbol || {}; +const { getOwnPropertyDescriptor, keys, getOwnPropertyNames, getOwnPropertySymbols, freeze } = Object; +const { ownKeys } = GLOBAL.Reflect || {}; +const { from } = Array; + +QUnit.test('Set', assert => { + assert.isFunction(Set); + assert.name(Set, 'Set'); + assert.arity(Set, 0); + assert.looksNative(Set); + assert.true('add' in Set.prototype, 'add in Set.prototype'); + assert.true('clear' in Set.prototype, 'clear in Set.prototype'); + assert.true('delete' in Set.prototype, 'delete in Set.prototype'); + assert.true('forEach' in Set.prototype, 'forEach in Set.prototype'); + assert.true('has' in Set.prototype, 'has in Set.prototype'); + assert.true(new Set() instanceof Set, 'new Set instanceof Set'); + let set = new Set(); + set.add(1); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + assert.same(set.size, 3); + const result = []; + set.forEach(val => { + result.push(val); + }); + assert.deepEqual(result, [1, 2, 3]); + assert.same(new Set(createIterable([1, 2, 3])).size, 3, 'Init from iterable'); + assert.same(new Set([freeze({}), 1]).size, 2, 'Support frozen objects'); + assert.same(new Set([NaN, NaN, NaN]).size, 1); + assert.deepEqual(from(new Set([3, 4]).add(2).add(1)), [3, 4, 2, 1]); + let done = false; + const { add } = Set.prototype; + // eslint-disable-next-line no-extend-native -- required for testing + Set.prototype.add = function () { + throw new Error(); + }; + try { + new Set(createIterable([null, 1, 2], { + return() { + return done = true; + }, + })); + } catch { /* empty */ } + // eslint-disable-next-line no-extend-native -- required for testing + Set.prototype.add = add; + assert.true(done, '.return #throw'); + const array = []; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + new Set(array); + assert.true(done); + const object = {}; + new Set().add(object); + if (DESCRIPTORS) { + const results = []; + for (const key in results) keys.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(object), []); + } + assert.arrayEqual(getOwnPropertyNames(object), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); + if (ownKeys) assert.arrayEqual(ownKeys(object), []); + if (nativeSubclass) { + const Subclass = nativeSubclass(Set); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof Set, 'correct subclassing with native classes #2'); + assert.true(new Subclass().add(2).has(2), 'correct subclassing with native classes #3'); + } + + const buffer = new ArrayBuffer(8); + set = new Set([buffer]); + assert.true(set.has(buffer), 'works with ArrayBuffer keys'); +}); + +QUnit.test('Set#add', assert => { + assert.isFunction(Set.prototype.add); + assert.name(Set.prototype.add, 'add'); + assert.arity(Set.prototype.add, 1); + assert.looksNative(Set.prototype.add); + assert.nonEnumerable(Set.prototype, 'add'); + const array = []; + let set = new Set(); + set.add(NaN); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.add(array); + assert.same(set.size, 5); + const chain = set.add(NaN); + assert.same(chain, set); + assert.same(set.size, 5); + set.add(2); + assert.same(set.size, 5); + set.add(array); + assert.same(set.size, 5); + set.add([]); + assert.same(set.size, 6); + set.add(4); + assert.same(set.size, 7); + const frozen = freeze({}); + set = new Set(); + set.add(frozen); + assert.true(set.has(frozen)); +}); + +QUnit.test('Set#clear', assert => { + assert.isFunction(Set.prototype.clear); + assert.name(Set.prototype.clear, 'clear'); + assert.arity(Set.prototype.clear, 0); + assert.looksNative(Set.prototype.clear); + assert.nonEnumerable(Set.prototype, 'clear'); + let set = new Set(); + set.clear(); + assert.same(set.size, 0); + set = new Set(); + set.add(1); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.clear(); + assert.same(set.size, 0); + assert.false(set.has(1)); + assert.false(set.has(2)); + assert.false(set.has(3)); + const frozen = freeze({}); + set = new Set(); + set.add(1); + set.add(frozen); + set.clear(); + assert.same(set.size, 0, 'Support frozen objects'); + assert.false(set.has(1)); + assert.false(set.has(frozen)); +}); + +QUnit.test('Set#delete', assert => { + assert.isFunction(Set.prototype.delete); + if (NATIVE) assert.name(Set.prototype.delete, 'delete'); + assert.arity(Set.prototype.delete, 1); + assert.looksNative(Set.prototype.delete); + assert.nonEnumerable(Set.prototype, 'delete'); + const array = []; + const set = new Set(); + set.add(NaN); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.add(array); + assert.same(set.size, 5); + assert.true(set.delete(NaN)); + assert.same(set.size, 4); + assert.false(set.delete(4)); + assert.same(set.size, 4); + set.delete([]); + assert.same(set.size, 4); + set.delete(array); + assert.same(set.size, 3); + const frozen = freeze({}); + set.add(frozen); + assert.same(set.size, 4); + set.delete(frozen); + assert.same(set.size, 3); +}); + +QUnit.test('Set#forEach', assert => { + assert.isFunction(Set.prototype.forEach); + assert.name(Set.prototype.forEach, 'forEach'); + assert.arity(Set.prototype.forEach, 1); + assert.looksNative(Set.prototype.forEach); + assert.nonEnumerable(Set.prototype, 'forEach'); + let result = []; + let count = 0; + let set = new Set(); + set.add(1); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.forEach(value => { + count++; + result.push(value); + }); + assert.same(count, 3); + assert.deepEqual(result, [1, 2, 3]); + set = new Set(); + set.add('0'); + set.add('1'); + set.add('2'); + set.add('3'); + result = ''; + set.forEach(it => { + result += it; + if (it === '2') { + set.delete('2'); + set.delete('3'); + set.delete('1'); + set.add('4'); + } + }); + assert.same(result, '0124'); + set = new Set(); + set.add('0'); + result = ''; + set.forEach(it => { + set.delete('0'); + if (result !== '') throw new Error(); + result += it; + }); + assert.same(result, '0'); + assert.throws(() => { + Set.prototype.forEach.call(new Map(), () => { /* empty */ }); + }, 'non-generic'); +}); + +QUnit.test('Set#has', assert => { + assert.isFunction(Set.prototype.has); + assert.name(Set.prototype.has, 'has'); + assert.arity(Set.prototype.has, 1); + assert.looksNative(Set.prototype.has); + assert.nonEnumerable(Set.prototype, 'has'); + const array = []; + const frozen = freeze({}); + const set = new Set(); + set.add(NaN); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.add(frozen); + set.add(array); + assert.true(set.has(NaN)); + assert.true(set.has(array)); + assert.true(set.has(frozen)); + assert.true(set.has(2)); + assert.false(set.has(4)); + assert.false(set.has([])); +}); + +QUnit.test('Set#size', assert => { + assert.nonEnumerable(Set.prototype, 'size'); + const set = new Set(); + set.add(1); + const { size } = set; + assert.same(typeof size, 'number', 'size is number'); + assert.same(size, 1, 'size is correct'); + if (DESCRIPTORS) { + const sizeDescriptor = getOwnPropertyDescriptor(Set.prototype, 'size'); + const getter = sizeDescriptor && sizeDescriptor.get; + const setter = sizeDescriptor && sizeDescriptor.set; + assert.same(typeof getter, 'function', 'size is getter'); + assert.same(typeof setter, 'undefined', 'size is not setter'); + assert.throws(() => Set.prototype.size, TypeError); + } +}); + +QUnit.test('Set & -0', assert => { + let set = new Set(); + set.add(-0); + assert.same(set.size, 1); + assert.true(set.has(0)); + assert.true(set.has(-0)); + set.forEach(it => { + assert.false(is(it, -0)); + }); + set.delete(-0); + assert.same(set.size, 0); + set = new Set([-0]); + set.forEach(key => { + assert.false(is(key, -0)); + }); + set = new Set(); + set.add(4); + set.add(3); + set.add(2); + set.add(1); + set.add(0); + assert.true(set.has(-0)); +}); + +QUnit.test('Set#@@toStringTag', assert => { + assert.same(Set.prototype[Symbol.toStringTag], 'Set', 'Set::@@toStringTag is `Set`'); + assert.same(String(new Set()), '[object Set]', 'correct stringification'); +}); + +QUnit.test('Set Iterator', assert => { + const set = new Set(); + set.add('a'); + set.add('b'); + set.add('c'); + set.add('d'); + const results = []; + const iterator = set.keys(); + results.push(iterator.next().value); + assert.true(set.delete('a')); + assert.true(set.delete('b')); + assert.true(set.delete('c')); + set.add('e'); + results.push(iterator.next().value, iterator.next().value); + assert.true(iterator.next().done); + set.add('f'); + assert.true(iterator.next().done); + assert.deepEqual(results, ['a', 'd', 'e']); +}); + +QUnit.test('Set#keys', assert => { + assert.isFunction(Set.prototype.keys); + assert.name(Set.prototype.keys, 'values'); + assert.arity(Set.prototype.keys, 0); + assert.looksNative(Set.prototype.keys); + assert.same(Set.prototype.keys, Set.prototype.values); + assert.nonEnumerable(Set.prototype, 'keys'); + const set = new Set(); + set.add('q'); + set.add('w'); + set.add('e'); + const iterator = set.keys(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Set Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Set#values', assert => { + assert.isFunction(Set.prototype.values); + assert.name(Set.prototype.values, 'values'); + assert.arity(Set.prototype.values, 0); + assert.looksNative(Set.prototype.values); + assert.nonEnumerable(Set.prototype, 'values'); + const set = new Set(); + set.add('q'); + set.add('w'); + set.add('e'); + const iterator = set.values(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Set Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Set#entries', assert => { + assert.isFunction(Set.prototype.entries); + assert.name(Set.prototype.entries, 'entries'); + assert.arity(Set.prototype.entries, 0); + assert.looksNative(Set.prototype.entries); + assert.nonEnumerable(Set.prototype, 'entries'); + const set = new Set(); + set.add('q'); + set.add('w'); + set.add('e'); + const iterator = set.entries(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Set Iterator'); + assert.deepEqual(iterator.next(), { + value: ['q', 'q'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['w', 'w'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['e', 'e'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Set#@@iterator', assert => { + assert.isIterable(Set.prototype); + assert.name(Set.prototype[Symbol.iterator], 'values'); + assert.arity(Set.prototype[Symbol.iterator], 0); + assert.looksNative(Set.prototype[Symbol.iterator]); + assert.same(Set.prototype[Symbol.iterator], Set.prototype.values); + assert.nonEnumerable(Set.prototype, 'values'); + const set = new Set(); + set.add('q'); + set.add('w'); + set.add('e'); + const iterator = set[Symbol.iterator](); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Set Iterator'); + assert.same(String(iterator), '[object Set Iterator]'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-global/es.set.symmetric-difference.js b/tests/unit-global/es.set.symmetric-difference.js new file mode 100644 index 000000000000..66e55e07629f --- /dev/null +++ b/tests/unit-global/es.set.symmetric-difference.js @@ -0,0 +1,75 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +QUnit.test('Set#symmetricDifference', assert => { + const { symmetricDifference } = Set.prototype; + const { from } = Array; + const { defineProperty } = Object; + + assert.isFunction(symmetricDifference); + assert.arity(symmetricDifference, 1); + assert.name(symmetricDifference, 'symmetricDifference'); + assert.looksNative(symmetricDifference); + assert.nonEnumerable(Set.prototype, 'symmetricDifference'); + + const set = new Set([1]); + assert.notSame(set.symmetricDifference(new Set()), set); + + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(new Set([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(new Set([3, 4]))), [1, 2, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createSetLike([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createSetLike([3, 4]))), [1, 2, 4]); + + // TODO: drop from core-js@4 + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference([4, 5])), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference([3, 4])), [1, 2, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createIterable([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createIterable([3, 4]))), [1, 2, 4]); + + assert.throws(() => new Set([1, 2, 3]).symmetricDifference(), TypeError); + + assert.throws(() => symmetricDifference.call({}, [1, 2, 3]), TypeError); + assert.throws(() => symmetricDifference.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => symmetricDifference.call(null, [1, 2, 3]), TypeError); + + { + // https://github.com/WebKit/WebKit/pull/27264/files#diff-7bdbbad7ceaa222787994f2db702dd45403fa98e14d6270aa65aaf09754dcfe0R8 + const baseSet = new Set(['a', 'b', 'c', 'd', 'e']); + const values = ['f', 'g', 'h', 'i', 'j']; + const setLike = { + size: values.length, + has() { return true; }, + keys() { + let index = 0; + return { + next() { + const done = index >= values.length; + if (!baseSet.has('f')) baseSet.add('f'); + return { done, value: values[index++] }; + }, + }; + }, + }; + assert.deepEqual(from(baseSet.symmetricDifference(setLike)), ['a', 'b', 'c', 'd', 'e', 'g', 'h', 'i', 'j']); + } + + if (DESCRIPTORS) { + // Should get iterator record of a set-like object before cloning this + // https://bugs.webkit.org/show_bug.cgi?id=289430 + const baseSet = new Set(); + const setLike = { + size: 0, + has() { return true; }, + keys() { + return defineProperty({}, 'next', { get() { + baseSet.clear(); + baseSet.add(4); + return function () { + return { done: true }; + }; + } }); + }, + }; + assert.deepEqual(from(baseSet.symmetricDifference(setLike)), [4]); + } +}); diff --git a/tests/unit-global/es.set.union.js b/tests/unit-global/es.set.union.js new file mode 100644 index 000000000000..b81e2a445668 --- /dev/null +++ b/tests/unit-global/es.set.union.js @@ -0,0 +1,53 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +QUnit.test('Set#union', assert => { + const { union } = Set.prototype; + const { from } = Array; + const { defineProperty } = Object; + + assert.isFunction(union); + assert.arity(union, 1); + assert.name(union, 'union'); + assert.looksNative(union); + assert.nonEnumerable(Set.prototype, 'union'); + + const set = new Set([1]); + assert.notSame(set.union(new Set()), set); + + assert.deepEqual(from(new Set([1, 2, 3]).union(new Set([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).union(new Set([3, 4]))), [1, 2, 3, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).union(createSetLike([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).union(createSetLike([3, 4]))), [1, 2, 3, 4]); + + // TODO: drop from core-js@4 + assert.deepEqual(from(new Set([1, 2, 3]).union([4, 5])), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).union([3, 4])), [1, 2, 3, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).union(createIterable([3, 4]))), [1, 2, 3, 4]); + + assert.throws(() => new Set([1, 2, 3]).union(), TypeError); + + assert.throws(() => union.call({}, [1, 2, 3]), TypeError); + assert.throws(() => union.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => union.call(null, [1, 2, 3]), TypeError); + + if (DESCRIPTORS) { + // Should get iterator record of a set-like object before cloning this + // https://bugs.webkit.org/show_bug.cgi?id=289430 + const baseSet = new Set(); + const setLike = { + size: 0, + has() { return true; }, + keys() { + return defineProperty({}, 'next', { get() { + baseSet.clear(); + baseSet.add(4); + return function () { + return { done: true }; + }; + } }); + }, + }; + assert.deepEqual(from(baseSet.union(setLike)), [4]); + } +}); diff --git a/tests/unit-global/es.string.anchor.js b/tests/unit-global/es.string.anchor.js new file mode 100644 index 000000000000..d2e412bb8acd --- /dev/null +++ b/tests/unit-global/es.string.anchor.js @@ -0,0 +1,16 @@ +QUnit.test('String#anchor', assert => { + const { anchor } = String.prototype; + assert.isFunction(anchor); + assert.arity(anchor, 1); + assert.name(anchor, 'anchor'); + assert.looksNative(anchor); + assert.nonEnumerable(String.prototype, 'anchor'); + assert.same('a'.anchor('b'), 'a', 'lower case'); + assert.same('a'.anchor('"'), 'a', 'escape quotes'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('anchor test'); + assert.throws(() => anchor.call(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => anchor.call('a', symbol), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-global/es.string.at-alternative.js b/tests/unit-global/es.string.at-alternative.js new file mode 100644 index 000000000000..b776df5c085a --- /dev/null +++ b/tests/unit-global/es.string.at-alternative.js @@ -0,0 +1,34 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#at', assert => { + const { at } = String.prototype; + assert.isFunction(at); + assert.arity(at, 1); + assert.name(at, 'at'); + assert.looksNative(at); + assert.nonEnumerable(String.prototype, 'at'); + assert.same('1', '123'.at(0)); + assert.same('2', '123'.at(1)); + assert.same('3', '123'.at(2)); + assert.same(undefined, '123'.at(3)); + assert.same('3', '123'.at(-1)); + assert.same('2', '123'.at(-2)); + assert.same('1', '123'.at(-3)); + assert.same(undefined, '123'.at(-4)); + assert.same('1', '123'.at(0.4)); + assert.same('1', '123'.at(0.5)); + assert.same('1', '123'.at(0.6)); + assert.same('1', '1'.at(NaN)); + assert.same('1', '1'.at()); + assert.same('1', '123'.at(-0)); + // TODO: disabled by default because of the conflict with old proposal + // assert.same('\uD842', '𠮷'.at()); + assert.same('1', at.call({ toString() { return '123'; } }, 0)); + + assert.throws(() => at.call(Symbol('at-alternative test'), 0), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => at.call(null, 0), TypeError); + assert.throws(() => at.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.string.big.js b/tests/unit-global/es.string.big.js new file mode 100644 index 000000000000..f2387c343b62 --- /dev/null +++ b/tests/unit-global/es.string.big.js @@ -0,0 +1,13 @@ +QUnit.test('String#big', assert => { + const { big } = String.prototype; + assert.isFunction(big); + assert.arity(big, 0); + assert.name(big, 'big'); + assert.looksNative(big); + assert.nonEnumerable(String.prototype, 'big'); + assert.same('a'.big(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => big.call(Symbol('big test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.blink.js b/tests/unit-global/es.string.blink.js new file mode 100644 index 000000000000..031c1585d377 --- /dev/null +++ b/tests/unit-global/es.string.blink.js @@ -0,0 +1,13 @@ +QUnit.test('String#blink', assert => { + const { blink } = String.prototype; + assert.isFunction(blink); + assert.arity(blink, 0); + assert.name(blink, 'blink'); + assert.looksNative(blink); + assert.nonEnumerable(String.prototype, 'blink'); + assert.same('a'.blink(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => blink.call(Symbol('blink test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.bold.js b/tests/unit-global/es.string.bold.js new file mode 100644 index 000000000000..65b917e8722a --- /dev/null +++ b/tests/unit-global/es.string.bold.js @@ -0,0 +1,13 @@ +QUnit.test('String#bold', assert => { + const { bold } = String.prototype; + assert.isFunction(bold); + assert.arity(bold, 0); + assert.name(bold, 'bold'); + assert.looksNative(bold); + assert.nonEnumerable(String.prototype, 'bold'); + assert.same('a'.bold(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => bold.call(Symbol('bold test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.code-point-at.js b/tests/unit-global/es.string.code-point-at.js new file mode 100644 index 000000000000..1eea3998c8f0 --- /dev/null +++ b/tests/unit-global/es.string.code-point-at.js @@ -0,0 +1,68 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#codePointAt', assert => { + const { codePointAt } = String.prototype; + assert.isFunction(codePointAt); + assert.arity(codePointAt, 1); + assert.name(codePointAt, 'codePointAt'); + assert.looksNative(codePointAt); + assert.nonEnumerable(String.prototype, 'codePointAt'); + assert.same('abc\uD834\uDF06def'.codePointAt(''), 0x61); + assert.same('abc\uD834\uDF06def'.codePointAt('_'), 0x61); + assert.same('abc\uD834\uDF06def'.codePointAt(), 0x61); + assert.same('abc\uD834\uDF06def'.codePointAt(-Infinity), undefined); + assert.same('abc\uD834\uDF06def'.codePointAt(-1), undefined); + assert.same('abc\uD834\uDF06def'.codePointAt(-0), 0x61); + assert.same('abc\uD834\uDF06def'.codePointAt(0), 0x61); + assert.same('abc\uD834\uDF06def'.codePointAt(3), 0x1D306); + assert.same('abc\uD834\uDF06def'.codePointAt(4), 0xDF06); + assert.same('abc\uD834\uDF06def'.codePointAt(5), 0x64); + assert.same('abc\uD834\uDF06def'.codePointAt(42), undefined); + assert.same('abc\uD834\uDF06def'.codePointAt(Infinity), undefined); + assert.same('abc\uD834\uDF06def'.codePointAt(Infinity), undefined); + assert.same('abc\uD834\uDF06def'.codePointAt(NaN), 0x61); + assert.same('abc\uD834\uDF06def'.codePointAt(false), 0x61); + assert.same('abc\uD834\uDF06def'.codePointAt(null), 0x61); + assert.same('abc\uD834\uDF06def'.codePointAt(undefined), 0x61); + assert.same('\uD834\uDF06def'.codePointAt(''), 0x1D306); + assert.same('\uD834\uDF06def'.codePointAt('1'), 0xDF06); + assert.same('\uD834\uDF06def'.codePointAt('_'), 0x1D306); + assert.same('\uD834\uDF06def'.codePointAt(), 0x1D306); + assert.same('\uD834\uDF06def'.codePointAt(-1), undefined); + assert.same('\uD834\uDF06def'.codePointAt(-0), 0x1D306); + assert.same('\uD834\uDF06def'.codePointAt(0), 0x1D306); + assert.same('\uD834\uDF06def'.codePointAt(1), 0xDF06); + assert.same('\uD834\uDF06def'.codePointAt(42), undefined); + assert.same('\uD834\uDF06def'.codePointAt(false), 0x1D306); + assert.same('\uD834\uDF06def'.codePointAt(null), 0x1D306); + assert.same('\uD834\uDF06def'.codePointAt(undefined), 0x1D306); + assert.same('\uD834abc'.codePointAt(''), 0xD834); + assert.same('\uD834abc'.codePointAt('_'), 0xD834); + assert.same('\uD834abc'.codePointAt(), 0xD834); + assert.same('\uD834abc'.codePointAt(-1), undefined); + assert.same('\uD834abc'.codePointAt(-0), 0xD834); + assert.same('\uD834abc'.codePointAt(0), 0xD834); + assert.same('\uD834abc'.codePointAt(false), 0xD834); + assert.same('\uD834abc'.codePointAt(NaN), 0xD834); + assert.same('\uD834abc'.codePointAt(null), 0xD834); + assert.same('\uD834abc'.codePointAt(undefined), 0xD834); + assert.same('\uDF06abc'.codePointAt(''), 0xDF06); + assert.same('\uDF06abc'.codePointAt('_'), 0xDF06); + assert.same('\uDF06abc'.codePointAt(), 0xDF06); + assert.same('\uDF06abc'.codePointAt(-1), undefined); + assert.same('\uDF06abc'.codePointAt(-0), 0xDF06); + assert.same('\uDF06abc'.codePointAt(0), 0xDF06); + assert.same('\uDF06abc'.codePointAt(false), 0xDF06); + assert.same('\uDF06abc'.codePointAt(NaN), 0xDF06); + assert.same('\uDF06abc'.codePointAt(null), 0xDF06); + assert.same('\uDF06abc'.codePointAt(undefined), 0xDF06); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => codePointAt.call(Symbol('codePointAt test'), 1), 'throws on symbol context'); + } + + if (STRICT) { + assert.throws(() => codePointAt.call(null, 0), TypeError); + assert.throws(() => codePointAt.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.string.ends-with.js b/tests/unit-global/es.string.ends-with.js new file mode 100644 index 000000000000..c200b02d9f8b --- /dev/null +++ b/tests/unit-global/es.string.ends-with.js @@ -0,0 +1,45 @@ +import { GLOBAL, STRICT } from '../helpers/constants.js'; + +const Symbol = GLOBAL.Symbol || {}; + +QUnit.test('String#endsWith', assert => { + const { endsWith } = String.prototype; + assert.isFunction(endsWith); + assert.arity(endsWith, 1); + assert.name(endsWith, 'endsWith'); + assert.looksNative(endsWith); + assert.nonEnumerable(String.prototype, 'endsWith'); + assert.true('undefined'.endsWith()); + assert.false('undefined'.endsWith(null)); + assert.true('abc'.endsWith('')); + assert.true('abc'.endsWith('c')); + assert.true('abc'.endsWith('bc')); + assert.false('abc'.endsWith('ab')); + assert.true('abc'.endsWith('', NaN)); + assert.false('abc'.endsWith('c', -1)); + assert.true('abc'.endsWith('a', 1)); + assert.true('abc'.endsWith('c', Infinity)); + assert.true('abc'.endsWith('a', true)); + assert.false('abc'.endsWith('c', 'x')); + assert.false('abc'.endsWith('a', 'x')); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('endsWith test'); + assert.throws(() => endsWith.call(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => endsWith.call('a', symbol), 'throws on symbol argument'); + } + + if (STRICT) { + assert.throws(() => endsWith.call(null, '.'), TypeError); + assert.throws(() => endsWith.call(undefined, '.'), TypeError); + } + + const regexp = /./; + assert.throws(() => '/./'.endsWith(regexp), TypeError); + regexp[Symbol.match] = false; + assert.notThrows(() => '/./'.endsWith(regexp)); + const object = {}; + assert.notThrows(() => '[object Object]'.endsWith(object)); + object[Symbol.match] = true; + assert.throws(() => '[object Object]'.endsWith(object), TypeError); +}); diff --git a/tests/unit-global/es.string.fixed.js b/tests/unit-global/es.string.fixed.js new file mode 100644 index 000000000000..84a807fbdad5 --- /dev/null +++ b/tests/unit-global/es.string.fixed.js @@ -0,0 +1,13 @@ +QUnit.test('String#fixed', assert => { + const { fixed } = String.prototype; + assert.isFunction(fixed); + assert.arity(fixed, 0); + assert.name(fixed, 'fixed'); + assert.looksNative(fixed); + assert.nonEnumerable(String.prototype, 'fixed'); + assert.same('a'.fixed(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => fixed.call(Symbol('fixed test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.fontcolor.js b/tests/unit-global/es.string.fontcolor.js new file mode 100644 index 000000000000..c09e564777c4 --- /dev/null +++ b/tests/unit-global/es.string.fontcolor.js @@ -0,0 +1,14 @@ +QUnit.test('String#fontcolor', assert => { + const { fontcolor } = String.prototype; + assert.isFunction(fontcolor); + assert.arity(fontcolor, 1); + assert.name(fontcolor, 'fontcolor'); + assert.looksNative(fontcolor); + assert.nonEnumerable(String.prototype, 'fontcolor'); + assert.same('a'.fontcolor('b'), 'a', 'lower case'); + assert.same('a'.fontcolor('"'), 'a', 'escape quotes'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => fontcolor.call(Symbol('fontcolor test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.fontsize.js b/tests/unit-global/es.string.fontsize.js new file mode 100644 index 000000000000..a5b539a7bf42 --- /dev/null +++ b/tests/unit-global/es.string.fontsize.js @@ -0,0 +1,16 @@ +QUnit.test('String#fontsize', assert => { + const { fontsize } = String.prototype; + assert.isFunction(fontsize); + assert.arity(fontsize, 1); + assert.name(fontsize, 'fontsize'); + assert.looksNative(fontsize); + assert.nonEnumerable(String.prototype, 'fontsize'); + assert.same('a'.fontsize('b'), 'a', 'lower case'); + assert.same('a'.fontsize('"'), 'a', 'escape quotes'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('fontsize test'); + assert.throws(() => fontsize.call(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => fontsize.call('a', symbol), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-global/es.string.from-code-point.js b/tests/unit-global/es.string.from-code-point.js new file mode 100644 index 000000000000..ccc8da14a072 --- /dev/null +++ b/tests/unit-global/es.string.from-code-point.js @@ -0,0 +1,49 @@ +/* eslint-disable prefer-spread -- required for testing */ +QUnit.test('String.fromCodePoint', assert => { + const { fromCodePoint } = String; + assert.isFunction(fromCodePoint); + assert.arity(fromCodePoint, 1); + assert.name(fromCodePoint, 'fromCodePoint'); + assert.looksNative(fromCodePoint); + assert.nonEnumerable(String, 'fromCodePoint'); + assert.same(fromCodePoint(''), '\0'); + assert.same(fromCodePoint(), ''); + assert.same(fromCodePoint(-0), '\0'); + assert.same(fromCodePoint(0), '\0'); + assert.same(fromCodePoint(0x1D306), '\uD834\uDF06'); + assert.same(fromCodePoint(0x1D306, 0x61, 0x1D307), '\uD834\uDF06a\uD834\uDF07'); + assert.same(fromCodePoint(0x61, 0x62, 0x1D307), 'ab\uD834\uDF07'); + assert.same(fromCodePoint(false), '\0'); + assert.same(fromCodePoint(null), '\0'); + assert.throws(() => fromCodePoint('_'), RangeError); + assert.throws(() => fromCodePoint('+Infinity'), RangeError); + assert.throws(() => fromCodePoint('-Infinity'), RangeError); + assert.throws(() => fromCodePoint(-1), RangeError); + assert.throws(() => fromCodePoint(0x10FFFF + 1), RangeError); + assert.throws(() => fromCodePoint(3.14), RangeError); + assert.throws(() => fromCodePoint(3e-2), RangeError); + assert.throws(() => fromCodePoint(-Infinity), RangeError); + assert.throws(() => fromCodePoint(Infinity), RangeError); + assert.throws(() => fromCodePoint(NaN), RangeError); + assert.throws(() => fromCodePoint(undefined), RangeError); + assert.throws(() => fromCodePoint({}), RangeError); + assert.throws(() => fromCodePoint(/./), RangeError); + let number = 0x60; + assert.same(fromCodePoint({ + valueOf() { + return ++number; + }, + }), 'a'); + assert.same(number, 0x61); + // one code unit per symbol + let counter = 2 ** 15 * 3 / 2; + let result = []; + while (--counter >= 0) result.push(0); + // should not throw + fromCodePoint.apply(null, result); + counter = 2 ** 15 * 3 / 2; + result = []; + while (--counter >= 0) result.push(0xFFFF + 1); + // should not throw + fromCodePoint.apply(null, result); +}); diff --git a/tests/unit-global/es.string.includes.js b/tests/unit-global/es.string.includes.js new file mode 100644 index 000000000000..6e06788b5d31 --- /dev/null +++ b/tests/unit-global/es.string.includes.js @@ -0,0 +1,36 @@ +import { GLOBAL, STRICT } from '../helpers/constants.js'; + +const Symbol = GLOBAL.Symbol || {}; + +QUnit.test('String#includes', assert => { + const { includes } = String.prototype; + assert.isFunction(includes); + assert.arity(includes, 1); + assert.name(includes, 'includes'); + assert.looksNative(includes); + assert.nonEnumerable(String.prototype, 'includes'); + assert.false('abc'.includes()); + assert.true('aundefinedb'.includes()); + assert.true('abcd'.includes('b', 1)); + assert.false('abcd'.includes('b', 2)); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('includes test'); + assert.throws(() => includes.call(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => includes.call('a', symbol), 'throws on symbol argument'); + } + + if (STRICT) { + assert.throws(() => includes.call(null, '.'), TypeError); + assert.throws(() => includes.call(undefined, '.'), TypeError); + } + + const regexp = /./; + assert.throws(() => '/./'.includes(regexp), TypeError); + regexp[Symbol.match] = false; + assert.notThrows(() => '/./'.includes(regexp)); + const object = {}; + assert.notThrows(() => '[object Object]'.includes(object)); + object[Symbol.match] = true; + assert.throws(() => '[object Object]'.includes(object), TypeError); +}); diff --git a/tests/unit-global/es.string.is-well-formed.js b/tests/unit-global/es.string.is-well-formed.js new file mode 100644 index 000000000000..c8f63ff28950 --- /dev/null +++ b/tests/unit-global/es.string.is-well-formed.js @@ -0,0 +1,44 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#isWellFormed', assert => { + const { isWellFormed } = String.prototype; + assert.isFunction(isWellFormed); + assert.arity(isWellFormed, 0); + assert.name(isWellFormed, 'isWellFormed'); + assert.looksNative(isWellFormed); + assert.nonEnumerable(String.prototype, 'isWellFormed'); + + assert.true(isWellFormed.call('a'), 'a'); + assert.true(isWellFormed.call('abc'), 'abc'); + assert.true(isWellFormed.call('💩'), '💩'); + assert.true(isWellFormed.call('💩b'), '💩b'); + assert.true(isWellFormed.call('a💩'), '💩'); + assert.true(isWellFormed.call('a💩b'), 'a💩b'); + assert.true(isWellFormed.call('💩a💩'), '💩a💩'); + assert.true(!isWellFormed.call('\uD83D'), '\uD83D'); + assert.true(!isWellFormed.call('\uDCA9'), '\uDCA9'); + assert.true(!isWellFormed.call('\uDCA9\uD83D'), '\uDCA9\uD83D'); + assert.true(!isWellFormed.call('a\uD83D'), 'a\uD83D'); + assert.true(!isWellFormed.call('\uDCA9a'), '\uDCA9a'); + assert.true(!isWellFormed.call('a\uD83Da'), 'a\uD83Da'); + assert.true(!isWellFormed.call('a\uDCA9a'), 'a\uDCA9a'); + + assert.true(isWellFormed.call({ + toString() { + return 'abc'; + }, + }), 'conversion #1'); + + assert.true(!isWellFormed.call({ + toString() { + return '\uD83D'; + }, + }), 'conversion #2'); + + if (STRICT) { + assert.throws(() => isWellFormed.call(null), TypeError, 'coercible #1'); + assert.throws(() => isWellFormed.call(undefined), TypeError, 'coercible #2'); + } + + assert.throws(() => isWellFormed.call(Symbol('isWellFormed test')), 'throws on symbol context'); +}); diff --git a/tests/unit-global/es.string.italics.js b/tests/unit-global/es.string.italics.js new file mode 100644 index 000000000000..67b97629f7e3 --- /dev/null +++ b/tests/unit-global/es.string.italics.js @@ -0,0 +1,13 @@ +QUnit.test('String#italics', assert => { + const { italics } = String.prototype; + assert.isFunction(italics); + assert.arity(italics, 0); + assert.name(italics, 'italics'); + assert.looksNative(italics); + assert.nonEnumerable(String.prototype, 'italics'); + assert.same('a'.italics(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => italics.call(Symbol('italics test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.iterator.js b/tests/unit-global/es.string.iterator.js new file mode 100644 index 000000000000..3cc14e38d401 --- /dev/null +++ b/tests/unit-global/es.string.iterator.js @@ -0,0 +1,49 @@ +import { GLOBAL } from '../helpers/constants.js'; + +const Symbol = GLOBAL.Symbol || {}; + +QUnit.test('String#@@iterator', assert => { + assert.isIterable(String.prototype); + let iterator = 'qwe'[Symbol.iterator](); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'String Iterator'); + assert.same(String(iterator), '[object String Iterator]'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + assert.same(Array.from('𠮷𠮷𠮷').length, 3); + iterator = '𠮷𠮷𠮷'[Symbol.iterator](); + assert.deepEqual(iterator.next(), { + value: '𠮷', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: '𠮷', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: '𠮷', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + // early FF case with native method, but polyfilled `Symbol` + // assert.throws(() => ''[Symbol.iterator].call(Symbol()), 'throws on symbol context'); +}); diff --git a/tests/unit-global/es.string.link.js b/tests/unit-global/es.string.link.js new file mode 100644 index 000000000000..2b3bea265572 --- /dev/null +++ b/tests/unit-global/es.string.link.js @@ -0,0 +1,16 @@ +QUnit.test('String#link', assert => { + const { link } = String.prototype; + assert.isFunction(link); + assert.arity(link, 1); + assert.name(link, 'link'); + assert.looksNative(link); + assert.nonEnumerable(String.prototype, 'link'); + assert.same('a'.link('b'), 'a', 'lower case'); + assert.same('a'.link('"'), 'a', 'escape quotes'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('link test'); + assert.throws(() => link.call(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => link.call('a', symbol), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-global/es.string.match-all.js b/tests/unit-global/es.string.match-all.js new file mode 100644 index 000000000000..1a06c99481f9 --- /dev/null +++ b/tests/unit-global/es.string.match-all.js @@ -0,0 +1,140 @@ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +QUnit.test('String#matchAll', assert => { + const { matchAll } = String.prototype; + const { assign } = Object; + assert.isFunction(matchAll); + assert.arity(matchAll, 1); + assert.name(matchAll, 'matchAll'); + assert.looksNative(matchAll); + assert.nonEnumerable(String.prototype, 'matchAll'); + let data = ['aabc', { toString() { return 'aabc'; } }]; + for (const target of data) { + const iterator = matchAll.call(target, /[ac]/g); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: assign(['a'], { + input: 'aabc', + index: 0, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['a'], { + input: 'aabc', + index: 1, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['c'], { + input: 'aabc', + index: 3, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + } + let iterator = '1111a2b3cccc'.matchAll(/(\d)(\D)/g); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'RegExp String Iterator'); + assert.same(String(iterator), '[object RegExp String Iterator]'); + assert.deepEqual(iterator.next(), { + value: assign(['1a', '1', 'a'], { + input: '1111a2b3cccc', + index: 3, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['2b', '2', 'b'], { + input: '1111a2b3cccc', + index: 5, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['3c', '3', 'c'], { + input: '1111a2b3cccc', + index: 7, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + // eslint-disable-next-line regexp/no-missing-g-flag -- required for testing + assert.throws(() => '1111a2b3cccc'.matchAll(/(\d)(\D)/), TypeError); + iterator = '1111a2b3cccc'.matchAll('(\\d)(\\D)'); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: assign(['1a', '1', 'a'], { + input: '1111a2b3cccc', + index: 3, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['2b', '2', 'b'], { + input: '1111a2b3cccc', + index: 5, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['3c', '3', 'c'], { + input: '1111a2b3cccc', + index: 7, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + /* IE8- issue + iterator = 'abc'.matchAll(/\B/g); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: assign([''], { + input: 'abc', + index: 1, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign([''], { + input: 'abc', + index: 2, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + */ + data = [null, undefined, NaN, 42, {}, []]; + for (const target of data) { + assert.notThrows(() => ''.matchAll(target), `Not throws on ${ target } as the first argument`); + } + + if (DESCRIPTORS && typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('matchAll test'); + assert.throws(() => matchAll.call(symbol, /./), 'throws on symbol context'); + assert.throws(() => matchAll.call('a', symbol), 'throws on symbol argument'); + } + + if (STRICT) { + assert.throws(() => matchAll.call(null, /./g), TypeError, 'Throws on null as `this`'); + assert.throws(() => matchAll.call(undefined, /./g), TypeError, 'Throws on undefined as `this`'); + } +}); diff --git a/tests/unit-global/es.string.match.js b/tests/unit-global/es.string.match.js new file mode 100644 index 000000000000..722a78e3b284 --- /dev/null +++ b/tests/unit-global/es.string.match.js @@ -0,0 +1,238 @@ +// TODO: fix escaping in regexps +/* eslint-disable prefer-regex-literals, regexp/prefer-regexp-exec -- required for testing */ +import { GLOBAL, NATIVE, STRICT } from '../helpers/constants.js'; +import { patchRegExp$exec } from '../helpers/helpers.js'; + +const Symbol = GLOBAL.Symbol || {}; + +const run = assert => { + assert.isFunction(''.match); + assert.arity(''.match, 1); + assert.name(''.match, 'match'); + assert.looksNative(''.match); + assert.nonEnumerable(String.prototype, 'match'); + let instance = Object(true); + instance.match = String.prototype.match; + assert.same(instance.match(true)[0], 'true', 'S15.5.4.10_A1_T1'); + instance = Object(false); + instance.match = String.prototype.match; + assert.same(instance.match(false)[0], 'false', 'S15.5.4.10_A1_T2'); + let matched = ''.match(); + let expected = RegExp().exec(''); + assert.same(matched.length, expected.length, 'S15.5.4.10_A1_T4 #1'); + assert.same(matched.index, expected.index, 'S15.5.4.10_A1_T4 #2'); + assert.same(matched.input, expected.input, 'S15.5.4.10_A1_T4 #3'); + assert.same('gnulluna'.match(null)[0], 'null', 'S15.5.4.10_A1_T5'); + matched = Object('undefined').match(undefined); + expected = RegExp(undefined).exec('undefined'); + assert.same(matched.length, expected.length, 'S15.5.4.10_A1_T6 #1'); + assert.same(matched.index, expected.index, 'S15.5.4.10_A1_T6 #2'); + assert.same(matched.input, expected.input, 'S15.5.4.10_A1_T6 #3'); + let object = { toString() { /* empty */ } }; + matched = String(object).match(undefined); + expected = RegExp(undefined).exec('undefined'); + assert.same(matched.length, expected.length, 'S15.5.4.10_A1_T8 #1'); + assert.same(matched.index, expected.index, 'S15.5.4.10_A1_T8 #2'); + assert.same(matched.input, expected.input, 'S15.5.4.10_A1_T8 #3'); + object = { toString() { return '\u0041B'; } }; + let string = 'ABB\u0041BABAB'; + assert.same(string.match(object)[0], 'AB', 'S15.5.4.10_A1_T10'); + object = { toString() { throw new Error('intostr'); } }; + try { + string.match(object); + assert.avoid('S15.5.4.10_A1_T11 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'intostr', `S15.5.4.10_A1_T11 #1.1: Exception === "intostr". Actual: ${ error }`); + } + object = { + toString() { + return {}; + }, + valueOf() { + throw new Error('intostr'); + }, + }; + try { + string.match(object); + assert.avoid('S15.5.4.10_A1_T12 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'intostr', `S15.5.4.10_A1_T12 #1.1: Exception === "intostr". Actual: ${ error }`); + } + object = { + toString() { + return {}; + }, + valueOf() { + return 1; + }, + }; + assert.same('ABB\u0041B\u0031ABAB\u0031BBAA'.match(object)[0], '1', 'S15.5.4.10_A1_T13 #1'); + assert.same('ABB\u0041B\u0031ABAB\u0031BBAA'.match(object).length, 1, 'S15.5.4.10_A1_T13 #2'); + let regexp = RegExp('77'); + assert.same('ABB\u0041BABAB\u0037\u0037BBAA'.match(regexp)[0], '77', 'S15.5.4.10_A1_T14'); + string = '1234567890'; + assert.same(string.match(3)[0], '3', 'S15.5.4.10_A2_T1 #1'); + assert.same(string.match(3).length, 1, 'S15.5.4.10_A2_T1 #2'); + assert.same(string.match(3).index, 2, 'S15.5.4.10_A2_T1 #3'); + assert.same(string.match(3).input, string, 'S15.5.4.10_A2_T1 #4'); + let matches = ['34', '34', '34']; + string = '343443444'; + assert.same(string.match(/34/g).length, 3, 'S15.5.4.10_A2_T2 #1'); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(string.match(/34/g)[i], matches[i], 'S15.5.4.10_A2_T2 #2'); + } + matches = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']; + string = '123456abcde7890'; + assert.same(string.match(/\d/g).length, 10, 'S15.5.4.10_A2_T3 #1'); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(string.match(/\d/g)[i], matches[i], 'S15.5.4.10_A2_T3 #2'); + } + matches = ['12', '34', '56', '78', '90']; + assert.same(string.match(/\d{2}/g).length, 5, 'S15.5.4.10_A2_T4 #1'); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(string.match(/\d{2}/g)[i], matches[i], 'S15.5.4.10_A2_T4 #2'); + } + matches = ['ab', 'cd']; + assert.same(string.match(/\D{2}/g).length, 2, 'S15.5.4.10_A2_T5 #1'); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(string.match(/\D{2}/g)[i], matches[i], 'S15.5.4.10_A2_T5 #2'); + } + string = 'Boston, Mass. 02134'; + assert.same(string.match(/(\d{5})([ -]?\d{4})?$/)[0], '02134', 'S15.5.4.10_A2_T6 #1'); + assert.same(string.match(/(\d{5})([ -]?\d{4})?$/)[1], '02134', 'S15.5.4.10_A2_T6 #2'); + if (NATIVE) assert.same(string.match(/(\d{5})([ -]?\d{4})?$/)[2], undefined, 'S15.5.4.10_A2_T6 #3'); + assert.same(string.match(/(\d{5})([ -]?\d{4})?$/).length, 3, 'S15.5.4.10_A2_T6 #4'); + assert.same(string.match(/(\d{5})([ -]?\d{4})?$/).index, 14, 'S15.5.4.10_A2_T6 #5'); + assert.same(string.match(/(\d{5})([ -]?\d{4})?$/).input, string, 'S15.5.4.10_A2_T6 #6'); + assert.same(string.match(/(\d{5})([ -]?\d{4})?$/g).length, 1, 'S15.5.4.10_A2_T7 #1'); + assert.same(string.match(/(\d{5})([ -]?\d{4})?$/g)[0], '02134', 'S15.5.4.10_A2_T7 #2'); + /* IE8- buggy here (empty string instead of `undefined`), but we don't polyfill base `.match` logic + matches = ['02134', '02134', undefined]; + string = 'Boston, MA 02134'; + regexp = /([\d]{5})([-\ ]?[\d]{4})?$/; + regexp.lastIndex = 0; + assert.same(string.match(regexp).length, 3, 'S15.5.4.10_A2_T8 #1'); + assert.same(string.match(regexp).index, string.lastIndexOf('0'), 'S15.5.4.10_A2_T8 #2'); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(string.match(regexp)[i], matches[i], 'S15.5.4.10_A2_T8 #3'); + } + string = 'Boston, MA 02134'; + matches = ['02134', '02134', undefined]; + regexp = /([\d]{5})([-\ ]?[\d]{4})?$/; + regexp.lastIndex = string.length; + assert.same(string.match(regexp).length, 3, 'S15.5.4.10_A2_T9 #1'); + assert.same(string.match(regexp).index, string.lastIndexOf('0'), 'S15.5.4.10_A2_T9 #2'); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(string.match(regexp)[i], matches[i], 'S15.5.4.10_A2_T9 #3'); + } + string = 'Boston, MA 02134'; + matches = ['02134', '02134', undefined]; + regexp = /([\d]{5})([-\ ]?[\d]{4})?$/; + regexp.lastIndex = string.lastIndexOf('0'); + assert.same(string.match(regexp).length, 3, 'S15.5.4.10_A2_T10 #1'); + assert.same(string.match(regexp).index, string.lastIndexOf('0'), 'S15.5.4.10_A2_T10 #2'); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(string.match(regexp)[i], matches[i], 'S15.5.4.10_A2_T10 #3'); + } + string = 'Boston, MA 02134'; + matches = ['02134', '02134', undefined]; + regexp = /([\d]{5})([-\ ]?[\d]{4})?$/; + regexp.lastIndex = string.lastIndexOf('0') + 1; + assert.same(string.match(regexp).length, 3, 'S15.5.4.10_A2_T11 #1'); + assert.same(string.match(regexp).index, string.lastIndexOf('0'), 'S15.5.4.10_A2_T11 #2'); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(string.match(regexp)[i], matches[i], 'S15.5.4.10_A2_T11 #3'); + } + */ + string = 'Boston, MA 02134'; + regexp = /(\d{5})([ -]?\d{4})?$/g; + assert.same(string.match(regexp).length, 1, 'S15.5.4.10_A2_T12 #1'); + assert.same(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T12 #2'); + regexp.lastIndex = 0; + assert.same(string.match(regexp).length, 1, 'S15.5.4.10_A2_T13 #1'); + assert.same(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T13 #2'); + regexp.lastIndex = string.length; + assert.same(string.match(regexp).length, 1, 'S15.5.4.10_A2_T14 #1'); + assert.same(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T14 #2'); + regexp.lastIndex = string.lastIndexOf('0'); + assert.same(string.match(regexp).length, 1, 'S15.5.4.10_A2_T15 #1'); + assert.same(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T15 #2'); + regexp.lastIndex = string.lastIndexOf('0') + 1; + assert.same(string.match(regexp).length, 1, 'S15.5.4.10_A2_T16 #1'); + assert.same(string.match(regexp)[0], '02134', 'S15.5.4.10_A2_T16 #2'); + regexp = /0./; + const number = 10203040506070809000; + assert.same(''.match.call(number, regexp)[0], '02', 'S15.5.4.10_A2_T17 #1'); + assert.same(''.match.call(number, regexp).length, 1, 'S15.5.4.10_A2_T17 #2'); + assert.same(''.match.call(number, regexp).index, 1, 'S15.5.4.10_A2_T17 #3'); + assert.same(''.match.call(number, regexp).input, String(number), 'S15.5.4.10_A2_T17 #4'); + regexp.lastIndex = 0; + assert.same(''.match.call(number, regexp)[0], '02', 'S15.5.4.10_A2_T18 #1'); + assert.same(''.match.call(number, regexp).length, 1, 'S15.5.4.10_A2_T18 #2'); + assert.same(''.match.call(number, regexp).index, 1, 'S15.5.4.10_A2_T18 #3'); + assert.same(''.match.call(number, regexp).input, String(number), 'S15.5.4.10_A2_T18 #4'); + + assert.throws(() => ''.match.call(Symbol('match test'), /./), 'throws on symbol context'); +}; + +QUnit.test('String#match regression', run); + +QUnit.test('RegExp#@@match appearance', assert => { + const match = /./[Symbol.match]; + assert.isFunction(match); + // assert.name(match, '[Symbol.match]'); + assert.arity(match, 1); + assert.looksNative(match); + assert.nonEnumerable(RegExp.prototype, Symbol.match); +}); + +QUnit.test('RegExp#@@match basic behavior', assert => { + const string = '123456abcde7890'; + const matches = ['12', '34', '56', '78', '90']; + assert.same(/\d{2}/g[Symbol.match](string).length, 5); + for (let i = 0, { length } = matches; i < length; ++i) { + assert.same(/\d{2}/g[Symbol.match](string)[i], matches[i]); + } +}); + +QUnit.test('String#match delegates to @@match', assert => { + const string = STRICT ? 'string' : Object('string'); + const number = STRICT ? 42 : Object(42); + const object = {}; + object[Symbol.match] = function (it) { + return { value: it }; + }; + assert.same(string.match(object).value, string); + assert.same(''.match.call(number, object).value, number); + const regexp = /./; + regexp[Symbol.match] = function (it) { + return { value: it }; + }; + assert.same(string.match(regexp).value, string); + assert.same(''.match.call(number, regexp).value, number); +}); + +QUnit.test('RegExp#@@match delegates to exec', assert => { + const exec = function (...args) { + execCalled = true; + return /./.exec.apply(this, args); + }; + + let execCalled = false; + let re = /[ac]/; + re.exec = exec; + assert.deepEqual(re[Symbol.match]('abc'), ['a']); + assert.true(execCalled); + + re = /a/; + // Not a function, should be ignored + re.exec = 3; + assert.deepEqual(re[Symbol.match]('abc'), ['a']); + + re = /a/; + // Does not return an object, should throw + re.exec = () => 3; + assert.throws(() => re[Symbol.match]('abc')); +}); + +QUnit.test('RegExp#@@match implementation', patchRegExp$exec(run)); diff --git a/tests/unit-global/es.string.pad-end.js b/tests/unit-global/es.string.pad-end.js new file mode 100644 index 000000000000..6651e511aa58 --- /dev/null +++ b/tests/unit-global/es.string.pad-end.js @@ -0,0 +1,26 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#padEnd', assert => { + const { padEnd } = String.prototype; + assert.isFunction(padEnd); + assert.arity(padEnd, 1); + assert.name(padEnd, 'padEnd'); + assert.looksNative(padEnd); + assert.nonEnumerable(String.prototype, 'padEnd'); + assert.same('abc'.padEnd(5), 'abc '); + assert.same('abc'.padEnd(4, 'de'), 'abcd'); + assert.same('abc'.padEnd(), 'abc'); + assert.same('abc'.padEnd(5, '_'), 'abc__'); + assert.same(''.padEnd(0), ''); + assert.same('foo'.padEnd(1), 'foo'); + assert.same('foo'.padEnd(5, ''), 'foo'); + + const symbol = Symbol('padEnd test'); + assert.throws(() => padEnd.call(symbol, 10, 'a'), 'throws on symbol context'); + assert.throws(() => padEnd.call('a', 10, symbol), 'throws on symbol argument'); + + if (STRICT) { + assert.throws(() => padEnd.call(null, 0), TypeError); + assert.throws(() => padEnd.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.string.pad-start.js b/tests/unit-global/es.string.pad-start.js new file mode 100644 index 000000000000..37b4a4172165 --- /dev/null +++ b/tests/unit-global/es.string.pad-start.js @@ -0,0 +1,26 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#padStart', assert => { + const { padStart } = String.prototype; + assert.isFunction(padStart); + assert.arity(padStart, 1); + assert.name(padStart, 'padStart'); + assert.looksNative(padStart); + assert.nonEnumerable(String.prototype, 'padStart'); + assert.same('abc'.padStart(5), ' abc'); + assert.same('abc'.padStart(4, 'de'), 'dabc'); + assert.same('abc'.padStart(), 'abc'); + assert.same('abc'.padStart(5, '_'), '__abc'); + assert.same(''.padStart(0), ''); + assert.same('foo'.padStart(1), 'foo'); + assert.same('foo'.padStart(5, ''), 'foo'); + + const symbol = Symbol('padStart test'); + assert.throws(() => padStart.call(symbol, 10, 'a'), 'throws on symbol context'); + assert.throws(() => padStart.call('a', 10, symbol), 'throws on symbol argument'); + + if (STRICT) { + assert.throws(() => padStart.call(null, 0), TypeError); + assert.throws(() => padStart.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.string.raw.js b/tests/unit-global/es.string.raw.js new file mode 100644 index 000000000000..a521b2297f98 --- /dev/null +++ b/tests/unit-global/es.string.raw.js @@ -0,0 +1,21 @@ +QUnit.test('String.raw', assert => { + const { raw } = String; + assert.isFunction(raw); + assert.arity(raw, 1); + assert.name(raw, 'raw'); + assert.looksNative(raw); + assert.nonEnumerable(String, 'raw'); + assert.same(raw({ raw: ['Hi\\n', '!'] }, 'Bob'), 'Hi\\nBob!', 'raw is array'); + assert.same(raw({ raw: 'test' }, 0, 1, 2), 't0e1s2t', 'raw is string'); + assert.same(raw({ raw: 'test' }, 0), 't0est', 'lacks substituting'); + assert.same(raw({ raw: [] }), '', 'empty template'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('raw test'); + assert.throws(() => raw({ raw: [symbol] }, 0), TypeError, 'throws on symbol #1'); + assert.throws(() => raw({ raw: 'test' }, symbol), TypeError, 'throws on symbol #2'); + } + + assert.throws(() => raw({}), TypeError); + assert.throws(() => raw({ raw: null }), TypeError); +}); diff --git a/tests/unit-global/es.string.repeat.js b/tests/unit-global/es.string.repeat.js new file mode 100644 index 000000000000..9786ecde0146 --- /dev/null +++ b/tests/unit-global/es.string.repeat.js @@ -0,0 +1,23 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#repeat', assert => { + const { repeat } = String.prototype; + assert.isFunction(repeat); + assert.arity(repeat, 1); + assert.name(repeat, 'repeat'); + assert.looksNative(repeat); + assert.nonEnumerable(String.prototype, 'repeat'); + assert.same('qwe'.repeat(3), 'qweqweqwe'); + assert.same('qwe'.repeat(2.5), 'qweqwe'); + assert.throws(() => 'qwe'.repeat(-1), RangeError); + assert.throws(() => 'qwe'.repeat(Infinity), RangeError); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => repeat.call(Symbol('repeat test')), 'throws on symbol context'); + } + + if (STRICT) { + assert.throws(() => repeat.call(null, 1), TypeError); + assert.throws(() => repeat.call(undefined, 1), TypeError); + } +}); diff --git a/tests/unit-global/es.string.replace-all.js b/tests/unit-global/es.string.replace-all.js new file mode 100644 index 000000000000..80ac5f6fb418 --- /dev/null +++ b/tests/unit-global/es.string.replace-all.js @@ -0,0 +1,52 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#replaceAll', assert => { + const { replaceAll } = String.prototype; + assert.isFunction(replaceAll); + assert.arity(replaceAll, 2); + assert.name(replaceAll, 'replaceAll'); + assert.looksNative(replaceAll); + assert.nonEnumerable(String.prototype, 'replaceAll'); + assert.same('q=query+string+parameters'.replaceAll('+', ' '), 'q=query string parameters'); + assert.same('foo'.replaceAll('o', {}), 'f[object Object][object Object]'); + assert.same('[object Object]x[object Object]'.replaceAll({}, 'y'), 'yxy'); + assert.same(replaceAll.call({}, 'bject', 'lolo'), '[ololo Ololo]'); + assert.same('aba'.replaceAll('b', (search, i, string) => { + assert.same(search, 'b', '`search` is `b`'); + assert.same(i, 1, '`i` is 1'); + assert.same(string, 'aba', '`string` is `aba`'); + return 'c'; + }), 'aca'); + const searcher = { + [Symbol.replace](O, replaceValue) { + assert.same(this, searcher, '`this` is `searcher`'); + assert.same(String(O), 'aba', '`O` is `aba`'); + assert.same(String(replaceValue), 'c', '`replaceValue` is `c`'); + return 'foo'; + }, + }; + assert.same('aba'.replaceAll(searcher, 'c'), 'foo'); + assert.same('aba'.replaceAll('b'), 'aundefineda'); + assert.same('xxx'.replaceAll('', '_'), '_x_x_x_'); + assert.same('121314'.replaceAll('1', '$$'), '$2$3$4', '$$'); + assert.same('121314'.replaceAll('1', '$&'), '121314', '$&'); + assert.same('121314'.replaceAll('1', '$`'), '212312134', '$`'); + assert.same('121314'.replaceAll('1', "$'"), '213142314344', "$'"); + + const symbol = Symbol('replaceAll test'); + assert.throws(() => replaceAll.call(symbol, 'a', 'b'), 'throws on symbol context'); + assert.throws(() => replaceAll.call('a', symbol, 'b'), 'throws on symbol argument 1'); + assert.throws(() => replaceAll.call('a', 'b', symbol), 'throws on symbol argument 2'); + + if (STRICT) { + assert.throws(() => replaceAll.call(null, 'a', 'b'), TypeError); + assert.throws(() => replaceAll.call(undefined, 'a', 'b'), TypeError); + } + + // eslint-disable-next-line regexp/no-missing-g-flag -- required for testing + assert.throws(() => 'b.b.b.b.b'.replaceAll(/\./, 'a'), TypeError); + // eslint-disable-next-line unicorn/prefer-string-replace-all -- required for testing + assert.same('b.b.b.b.b'.replaceAll(/\./g, 'a'), 'babababab'); + const object = {}; + assert.same('[object Object]'.replaceAll(object, 'a'), 'a'); +}); diff --git a/tests/unit-global/es.string.replace.js b/tests/unit-global/es.string.replace.js new file mode 100644 index 000000000000..7a52a0aecc2d --- /dev/null +++ b/tests/unit-global/es.string.replace.js @@ -0,0 +1,230 @@ +/* eslint-disable prefer-regex-literals, regexp/no-unused-capturing-group, sonarjs/slow-regex, unicorn/prefer-string-replace-all -- required for testing */ +import { GLOBAL, NATIVE, STRICT } from '../helpers/constants.js'; +import { patchRegExp$exec } from '../helpers/helpers.js'; + +const Symbol = GLOBAL.Symbol || {}; + +const run = assert => { + assert.isFunction(''.replace); + assert.arity(''.replace, 2); + assert.name(''.replace, 'replace'); + assert.looksNative(''.replace); + assert.nonEnumerable(String.prototype, 'replace'); + let instance = Object(true); + instance.replace = String.prototype.replace; + assert.same(instance.replace(true, 1), '1', 'S15.5.4.11_A1_T1'); + instance = Object(false); + instance.replace = String.prototype.replace; + assert.same(instance.replace(false, undefined), 'undefined', 'S15.5.4.11_A1_T2'); + assert.same('gnulluna'.replace(null, (a1, a2) => `${ a2 }`), 'g1una', 'S15.5.4.11_A1_T4'); + assert.same('gnulluna'.replace(null, () => { /* empty */ }), 'gundefineduna', 'S15.5.4.11_A1_T5'); + assert.same(Object('undefined').replace(undefined, (a1, a2) => a2 + 42), '42', 'S15.5.4.11_A1_T6'); + assert.same('undefined'.replace('e', undefined), 'undundefinedfined', 'S15.5.4.11_A1_T7'); + assert.same(String({ + toString() { /* empty */ }, + }).replace(/e/g, undefined), 'undundefinedfinundefinedd', 'S15.5.4.11_A1_T8'); + assert.same(new String({ + valueOf() { /* empty */ }, + toString: undefined, + }).replace(function () { /* empty */ }(), (a1, a2, a3) => a1 + a2 + a3), 'undefined0undefined', 'S15.5.4.11_A1_T9'); + assert.same('ABB\u0041BABAB'.replace({ + toString() { + return '\u0041B'; + }, + }, () => { /* empty */ }), 'undefinedBABABAB', 'S15.5.4.11_A1_T10'); + if (NATIVE) { + try { + 'ABB\u0041BABAB'.replace({ + toString() { + throw new Error('insearchValue'); + }, + }, { + toString() { + throw new Error('inreplaceValue'); + }, + }); + assert.avoid('S15.5.4.11_A1_T11 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'insearchValue', 'S15.5.4.11_A1_T11 #2'); + } + try { + Object('ABB\u0041BABAB').replace({ + toString() { + return {}; + }, + valueOf() { + throw new Error('insearchValue'); + }, + }, { + toString() { + throw new Error('inreplaceValue'); + }, + }); + assert.avoid('S15.5.4.11_A1_T12 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'insearchValue', 'S15.5.4.11_A1_T12 #2'); + } + } + try { + 'ABB\u0041BABAB\u0031BBAA'.replace({ + toString() { + return {}; + }, + valueOf() { + throw new Error('insearchValue'); + }, + }, { + toString() { + return 1; + }, + }); + assert.avoid('S15.5.4.11_A1_T13 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'insearchValue', 'S15.5.4.11_A1_T13 #2'); + } + assert.same('ABB\u0041BABAB\u0037\u0037BBAA'.replace(new RegExp('77'), 1), 'ABBABABAB\u0031BBAA', 'S15.5.4.11_A1_T14'); + instance = Object(1100.00777001); + instance.replace = String.prototype.replace; + try { + instance.replace({ + toString() { + return /77/; + }, + }, 1); + assert.avoid('S15.5.4.11_A1_T15 #1 lead to throwing exception'); + } catch (error) { + assert.true(error instanceof TypeError, 'S15.5.4.11_A1_T15 #2'); + } + instance = Object(1100.00777001); + instance.replace = String.prototype.replace; + try { + instance.replace(/77/, { + toString() { + return (a1, a2) => `${ a2 }z`; + }, + }); + assert.avoid('S15.5.4.11_A1_T16 #1 lead to throwing exception'); + } catch (error) { + assert.true(error instanceof TypeError, 'S15.5.4.11_A1_T16 #2'); + } + assert.same('asdf'.replace(RegExp('', 'g'), '1'), '1a1s1d1f1', 'S15.5.4.11_A1_T17'); + assert.same('She sells seashells by the seashore.'.replace(/sh/g, 'sch'), 'She sells seaschells by the seaschore.', 'S15.5.4.11_A2_T1'); + assert.same('She sells seashells by the seashore.'.replace(/sh/g, '$$sch'), 'She sells sea$schells by the sea$schore.', 'S15.5.4.11_A2_T2'); + assert.same('She sells seashells by the seashore.'.replace(/sh/g, '$&sch'), 'She sells seashschells by the seashschore.', 'S15.5.4.11_A2_T3'); + assert.same('She sells seashells by the seashore.'.replace(/sh/g, '$`sch'), 'She sells seaShe sells seaschells by the seaShe sells seashells by the seaschore.', 'S15.5.4.11_A2_T4'); + assert.same('She sells seashells by the seashore.'.replace(/sh/g, "$'sch"), 'She sells seaells by the seashore.schells by the seaore.schore.', 'S15.5.4.11_A2_T5'); + assert.same('She sells seashells by the seashore.'.replace(/sh/, 'sch'), 'She sells seaschells by the seashore.', 'S15.5.4.11_A2_T6'); + assert.same('She sells seashells by the seashore.'.replace(/sh/, '$$sch'), 'She sells sea$schells by the seashore.', 'S15.5.4.11_A2_T7'); + assert.same('She sells seashells by the seashore.'.replace(/sh/, '$&sch'), 'She sells seashschells by the seashore.', 'S15.5.4.11_A2_T8'); + assert.same('She sells seashells by the seashore.'.replace(/sh/, '$`sch'), 'She sells seaShe sells seaschells by the seashore.', 'S15.5.4.11_A2_T9'); + assert.same('She sells seashells by the seashore.'.replace(/sh/, "$'sch"), 'She sells seaells by the seashore.schells by the seashore.', 'S15.5.4.11_A2_T10'); + assert.same('uid=31'.replace(/(uid=)(\d+)/, '$1115'), 'uid=115', 'S15.5.4.11_A3_T1'); + assert.same('uid=31'.replace(/(uid=)(\d+)/, '$11A15'), 'uid=1A15', 'S15.5.4.11_A3_T3'); + assert.same('abc12 def34'.replace(/([a-z]+)(\d+)/, (a, b, c) => c + b), '12abc def34', 'S15.5.4.11_A4_T1'); + // eslint-disable-next-line regexp/optimal-quantifier-concatenation -- required for testing + assert.same('aaaaaaaaaa,aaaaaaaaaaaaaaa'.replace(/^(a+)\1*,\1+$/, '$1'), 'aaaaa', 'S15.5.4.11_A5_T1'); + + // https://github.com/zloirock/core-js/issues/471 + // eslint-disable-next-line regexp/no-useless-dollar-replacements, regexp/strict -- required for testing + assert.same('{price} Retail'.replace(/{price}/g, '$25.00'), '$25.00 Retail'); + // eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing + assert.same('a'.replace(/(.)/, '$0'), '$0'); + + assert.throws(() => ''.replace.call(Symbol('replace test'), /./, ''), 'throws on symbol context'); +}; + +QUnit.test('String#replace regression', run); + +QUnit.test('RegExp#@@replace appearance', assert => { + const replace = /./[Symbol.replace]; + assert.isFunction(replace); + // assert.name(replace, '[Symbol.replace]'); + assert.arity(replace, 2); + assert.looksNative(replace); + assert.nonEnumerable(RegExp.prototype, Symbol.replace); +}); + +QUnit.test('RegExp#@@replace basic behavior', assert => { + assert.same(/([a-z]+)(\d+)/[Symbol.replace]('abc12 def34', (a, b, c) => c + b), '12abc def34'); +}); + +QUnit.test('String.replace delegates to @@replace', assert => { + const string = STRICT ? 'string' : Object('string'); + const number = STRICT ? 42 : Object(42); + const object = {}; + object[Symbol.replace] = function (a, b) { + return { a, b }; + }; + assert.same(string.replace(object, 42).a, string); + assert.same(string.replace(object, 42).b, 42); + assert.same(''.replace.call(number, object, 42).a, number); + assert.same(''.replace.call(number, object, 42).b, 42); + const regexp = /./; + regexp[Symbol.replace] = function (a, b) { + return { a, b }; + }; + assert.same(string.replace(regexp, 42).a, string); + assert.same(string.replace(regexp, 42).b, 42); + assert.same(''.replace.call(number, regexp, 42).a, number); + assert.same(''.replace.call(number, regexp, 42).b, 42); +}); + +QUnit.test('RegExp#@@replace delegates to exec', assert => { + const exec = function (...args) { + execCalled = true; + return /./.exec.apply(this, args); + }; + + let execCalled = false; + let re = /[ac]/; + re.exec = exec; + assert.deepEqual(re[Symbol.replace]('abc', 'f'), 'fbc'); + assert.true(execCalled); + assert.same(re.lastIndex, 0); + + execCalled = false; + re = /[ac]/g; + re.exec = exec; + assert.deepEqual(re[Symbol.replace]('abc', 'f'), 'fbf'); + assert.true(execCalled); + assert.same(re.lastIndex, 0); + + re = /a/; + // Not a function, should be ignored + re.exec = 3; + assert.deepEqual(re[Symbol.replace]('abc', 'f'), 'fbc'); + + re = /a/; + // Does not return an object, should throw + re.exec = () => 3; + assert.throws(() => re[Symbol.replace]('abc', 'f')); +}); + +QUnit.test('RegExp#@@replace correctly handles substitutions', assert => { + const re = /./; + re.exec = function () { + const result = ['23', '7']; + result.groups = { '!!!': '7' }; + result.index = 1; + return result; + }; + // eslint-disable-next-line regexp/no-useless-dollar-replacements -- false positive + assert.same('1234'.replace(re, '$1'), '174'); + // eslint-disable-next-line regexp/no-useless-dollar-replacements -- required for testing + assert.same('1234'.replace(re, '$'), '174'); + assert.same('1234'.replace(re, '$`'), '114'); + assert.same('1234'.replace(re, "$'"), '144'); + assert.same('1234'.replace(re, '$$'), '1$4'); + assert.same('1234'.replace(re, '$&'), '1234'); + // eslint-disable-next-line regexp/prefer-escape-replacement-dollar-char -- required for testing + assert.same('1234'.replace(re, '$x'), '1$x4'); + + let args; + assert.same('1234'.replace(re, (...$args) => { + args = $args; + return 'x'; + }), '1x4'); + assert.deepEqual(args, ['23', '7', 1, '1234', { '!!!': '7' }]); +}); + +QUnit.test('RegExp#@@replace implementation', patchRegExp$exec(run)); diff --git a/tests/unit-global/es.string.search.js b/tests/unit-global/es.string.search.js new file mode 100644 index 000000000000..353133c51246 --- /dev/null +++ b/tests/unit-global/es.string.search.js @@ -0,0 +1,135 @@ +/* eslint-disable prefer-regex-literals -- required for testing */ +import { GLOBAL, STRICT } from '../helpers/constants.js'; +import { patchRegExp$exec } from '../helpers/helpers.js'; + +const Symbol = GLOBAL.Symbol || {}; + +const run = assert => { + assert.isFunction(''.search); + assert.arity(''.search, 1); + assert.name(''.search, 'search'); + assert.looksNative(''.search); + assert.nonEnumerable(String.prototype, 'search'); + let instance = Object(true); + instance.search = String.prototype.search; + assert.same(instance.search(true), 0, 'S15.5.4.12_A1_T1'); + instance = Object(false); + instance.search = String.prototype.search; + assert.same(instance.search(false), 0, 'S15.5.4.12_A1_T2'); + assert.same(''.search(), 0, 'S15.5.4.12_A1_T4 #1'); + assert.same('--undefined--'.search(), 0, 'S15.5.4.12_A1_T4 #2'); + assert.same('gnulluna'.search(null), 1, 'S15.5.4.12_A1_T5'); + assert.same(Object('undefined').search(undefined), 0, 'S15.5.4.12_A1_T6'); + assert.same('undefined'.search(undefined), 0, 'S15.5.4.12_A1_T7'); + assert.same(String({ + toString() { /* empty */ }, + }).search(undefined), 0, 'S15.5.4.12_A1_T8'); + assert.same('ssABB\u0041BABAB'.search({ + toString() { + return '\u0041B'; + }, + }), 2, 'S15.5.4.12_A1_T10'); + try { + 'ABB\u0041BABAB'.search({ + toString() { + throw new Error('intostr'); + }, + }); + assert.avoid('S15.5.4.12_A1_T11 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'intostr', 'S15.5.4.12_A1_T11 #2'); + } + try { + Object('ABB\u0041BABAB').search({ + toString() { + return {}; + }, + valueOf() { + throw new Error('intostr'); + }, + }); + assert.avoid('S15.5.4.12_A1_T12 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'intostr', 'S15.5.4.12_A1_T12 #2'); + } + assert.same('ABB\u0041B\u0031ABAB\u0031BBAA'.search({ + toString() { + return {}; + }, + valueOf() { + return 1; + }, + }), 5, 'S15.5.4.12_A1_T13'); + assert.same('ABB\u0041BABAB\u0037\u0037BBAA'.search(RegExp('77')), 9, 'S15.5.4.12_A1_T14'); + assert.same(Object('test string').search('string'), 5, 'S15.5.4.12_A2_T1'); + assert.same(Object('test string').search('String'), -1, 'S15.5.4.12_A2_T2'); + assert.same(Object('test string').search(/string/i), 5, 'S15.5.4.12_A2_T3'); + assert.same(Object('test string').search(/Four/), -1, 'S15.5.4.12_A2_T4'); + assert.same(Object('one two three four five').search(/four/), 14, 'S15.5.4.12_A2_T5'); + assert.same(Object('test string').search('nonexistent'), -1, 'S15.5.4.12_A2_T6'); + assert.same(Object('test string probe').search('string pro'), 5, 'S15.5.4.12_A2_T7'); + let string = Object('power of the power of the power of the power of the power of the power of the great sword'); + assert.same(string.search(/the/), string.search(/the/g), 'S15.5.4.12_A3_T1'); + string = Object('power \u006F\u0066 the power of the power \u006F\u0066 the power of the power \u006F\u0066 the power of the great sword'); + assert.same(string.search(/of/), string.search(/of/g), 'S15.5.4.12_A3_T2'); + + assert.throws(() => ''.search.call(Symbol('search test'), /./), 'throws on symbol context'); +}; + +QUnit.test('String#search regression', run); + +QUnit.test('RegExp#@@search appearance', assert => { + const search = /./[Symbol.search]; + assert.isFunction(search); + // assert.name(search, '[Symbol.search]'); + assert.arity(search, 1); + assert.looksNative(search); + assert.nonEnumerable(RegExp.prototype, Symbol.search); +}); + +QUnit.test('RegExp#@@search basic behavior', assert => { + assert.same(/four/[Symbol.search]('one two three four five'), 14); + assert.same(/Four/[Symbol.search]('one two three four five'), -1); +}); + +QUnit.test('String#search delegates to @@search', assert => { + const string = STRICT ? 'string' : Object('string'); + const number = STRICT ? 42 : Object(42); + const object = {}; + object[Symbol.search] = function (it) { + return { value: it }; + }; + assert.same(string.search(object).value, string); + assert.same(''.search.call(number, object).value, number); + const regexp = /./; + regexp[Symbol.search] = function (it) { + return { value: it }; + }; + assert.same(string.search(regexp).value, string); + assert.same(''.search.call(number, regexp).value, number); +}); + +QUnit.test('RegExp#@@search delegates to exec', assert => { + let execCalled = false; + let re = /b/; + re.lastIndex = 7; + re.exec = function (...args) { + execCalled = true; + return /./.exec.apply(this, args); + }; + assert.deepEqual(re[Symbol.search]('abc'), 1); + assert.true(execCalled); + assert.same(re.lastIndex, 7); + + re = /b/; + // Not a function, should be ignored + re.exec = 3; + assert.deepEqual(re[Symbol.search]('abc'), 1); + + re = /b/; + // Does not return an object, should throw + re.exec = () => 3; + assert.throws(() => re[Symbol.search]('abc')); +}); + +QUnit.test('RegExp#@@search implementation', patchRegExp$exec(run)); diff --git a/tests/unit-global/es.string.small.js b/tests/unit-global/es.string.small.js new file mode 100644 index 000000000000..d7fd26735a5f --- /dev/null +++ b/tests/unit-global/es.string.small.js @@ -0,0 +1,13 @@ +QUnit.test('String#small', assert => { + const { small } = String.prototype; + assert.isFunction(small); + assert.arity(small, 0); + assert.name(small, 'small'); + assert.looksNative(small); + assert.nonEnumerable(String.prototype, 'small'); + assert.same('a'.small(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => small.call(Symbol('small test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.split.js b/tests/unit-global/es.string.split.js new file mode 100644 index 000000000000..2c25727daf3d --- /dev/null +++ b/tests/unit-global/es.string.split.js @@ -0,0 +1,783 @@ +/* eslint-disable prefer-regex-literals -- required for testing */ +/* eslint-disable regexp/no-empty-group, regexp/no-empty-capturing-group -- required for testing */ +/* eslint-disable regexp/optimal-lookaround-quantifier, regexp/no-lazy-ends -- required for testing */ +import { GLOBAL, NATIVE, STRICT } from '../helpers/constants.js'; +import { patchRegExp$exec } from '../helpers/helpers.js'; + +const Symbol = GLOBAL.Symbol || {}; + +const run = assert => { + assert.isFunction(''.split); + assert.arity(''.split, 2); + assert.name(''.split, 'split'); + assert.looksNative(''.split); + assert.nonEnumerable(String.prototype, 'split'); + assert.arrayEqual('ab'.split(), ['ab'], 'If "separator" is undefined must return Array with one String - "this" string'); + assert.arrayEqual('ab'.split(undefined), ['ab'], 'If "separator" is undefined must return Array with one String - "this" string'); + assert.arrayEqual('ab'.split(undefined, 0), [], 'If "separator" is undefined and "limit" set to 0 must return Array[]'); + assert.arrayEqual(''.split(), [''], "''.split() results in ['']"); + assert.arrayEqual(''.split(/./), [''], "''.split(/./) results in ['']"); + assert.arrayEqual(''.split(/.?/), [], "''.split(/.?/) results in []"); + assert.arrayEqual(''.split(/.??/), [], "''.split(/.??/) results in []"); + assert.arrayEqual('ab'.split(/a*/), ['', 'b'], "'ab'.split(/a*/) results in ['', 'b']"); + assert.arrayEqual('ab'.split(/a*?/), ['a', 'b'], "'ab'.split(/a*?/) results in ['a', 'b']"); + // eslint-disable-next-line regexp/no-useless-non-capturing-group -- required for testing + assert.arrayEqual('ab'.split(/(?:ab)/), ['', ''], "'ab'.split(/(?:ab)/) results in ['', '']"); + assert.arrayEqual('ab'.split(/(?:ab)*/), ['', ''], "'ab'.split(/(?:ab)*/) results in ['', '']"); + assert.arrayEqual('ab'.split(/(?:ab)*?/), ['a', 'b'], "'ab'.split(/(?:ab)*?/) results in ['a', 'b']"); + assert.arrayEqual('test'.split(''), ['t', 'e', 's', 't'], "'test'.split('') results in ['t', 'e', 's', 't']"); + assert.arrayEqual('test'.split(), ['test'], "'test'.split() results in ['test']"); + assert.arrayEqual('111'.split(1), ['', '', '', ''], "'111'.split(1) results in ['', '', '', '']"); + assert.arrayEqual('test'.split(/(?:)/, 2), ['t', 'e'], "'test'.split(/(?:)/, 2) results in ['t', 'e']"); + assert.arrayEqual('test'.split(/(?:)/, -1), ['t', 'e', 's', 't'], "'test'.split(/(?:)/, -1) results in ['t', 'e', 's', 't']"); + assert.arrayEqual('test'.split(/(?:)/, undefined), ['t', 'e', 's', 't'], "'test'.split(/(?:)/, undefined) results in ['t', 'e', 's', 't']"); + assert.arrayEqual('test'.split(/(?:)/, null), [], "'test'.split(/(?:)/, null) results in []"); + assert.arrayEqual('test'.split(/(?:)/, NaN), [], "'test'.split(/(?:)/, NaN) results in []"); + assert.arrayEqual('test'.split(/(?:)/, true), ['t'], "'test'.split(/(?:)/, true) results in ['t']"); + assert.arrayEqual('test'.split(/(?:)/, '2'), ['t', 'e'], "'test'.split(/(?:)/, '2') results in ['t', 'e']"); + assert.arrayEqual('test'.split(/(?:)/, 'two'), [], "'test'.split(/(?:)/, 'two') results in []"); + assert.arrayEqual('a'.split(/-/), ['a'], "'a'.split(/-/) results in ['a']"); + assert.arrayEqual('a'.split(/-?/), ['a'], "'a'.split(/-?/) results in ['a']"); + assert.arrayEqual('a'.split(/-??/), ['a'], "'a'.split(/-??/) results in ['a']"); + assert.arrayEqual('a'.split(/a/), ['', ''], "'a'.split(/a/) results in ['', '']"); + assert.arrayEqual('a'.split(/a?/), ['', ''], "'a'.split(/a?/) results in ['', '']"); + assert.arrayEqual('a'.split(/a??/), ['a'], "'a'.split(/a??/) results in ['a']"); + assert.arrayEqual('ab'.split(/-/), ['ab'], "'ab'.split(/-/) results in ['ab']"); + assert.arrayEqual('ab'.split(/-?/), ['a', 'b'], "'ab'.split(/-?/) results in ['a', 'b']"); + assert.arrayEqual('ab'.split(/-??/), ['a', 'b'], "'ab'.split(/-??/) results in ['a', 'b']"); + assert.arrayEqual('a-b'.split(/-/), ['a', 'b'], "'a-b'.split(/-/) results in ['a', 'b']"); + assert.arrayEqual('a-b'.split(/-?/), ['a', 'b'], "'a-b'.split(/-?/) results in ['a', 'b']"); + assert.arrayEqual('a-b'.split(/-??/), ['a', '-', 'b'], "'a-b'.split(/-??/) results in ['a', '-', 'b']"); + assert.arrayEqual('a--b'.split(/-/), ['a', '', 'b'], "'a--b'.split(/-/) results in ['a', '', 'b']"); + assert.arrayEqual('a--b'.split(/-?/), ['a', '', 'b'], "'a--b'.split(/-?/) results in ['a', '', 'b']"); + assert.arrayEqual('a--b'.split(/-??/), ['a', '-', '-', 'b'], "'a--b'.split(/-??/) results in ['a', '-', '-', 'b']"); + assert.arrayEqual(''.split(/()()/), [], "''.split(/()()/) results in []"); + assert.arrayEqual('.'.split(/()()/), ['.'], "'.'.split(/()()/) results in ['.']"); + assert.arrayEqual('.'.split(/(.?)(.?)/), ['', '.', '', ''], "'.'.split(/(.?)(.?)/) results in ['', '.', '', '']"); + assert.arrayEqual('.'.split(/(.??)(.??)/), ['.'], "'.'.split(/(.??)(.??)/) results in ['.']"); + // eslint-disable-next-line regexp/optimal-quantifier-concatenation -- ignore + assert.arrayEqual('.'.split(/(.)?(.)?/), ['', '.', undefined, ''], "'.'.split(/(.)?(.)?/) results in ['', '.', undefined, '']"); + assert.arrayEqual('Aboldandcoded'.split(/<(\/)?([^<>]+)>/), ['A', undefined, 'B', 'bold', '/', 'B', 'and', undefined, 'CODE', 'coded', '/', 'CODE', ''], "'Aboldandcoded'.split(/<(\\/)?([^<>]+)>/) results in ['A', undefined, 'B', 'bold', '/', 'B', 'and', undefined, 'CODE', 'coded', '/', 'CODE', '']"); + assert.arrayEqual('tesst'.split(/(s)*/), ['t', undefined, 'e', 's', 't'], "'tesst'.split(/(s)*/) results in ['t', undefined, 'e', 's', 't']"); + assert.arrayEqual('tesst'.split(/(s)*?/), ['t', undefined, 'e', undefined, 's', undefined, 's', undefined, 't'], "'tesst'.split(/(s)*?/) results in ['t', undefined, 'e', undefined, 's', undefined, 's', undefined, 't']"); + assert.arrayEqual('tesst'.split(/(s*)/), ['t', '', 'e', 'ss', 't'], "'tesst'.split(/(s*)/) results in ['t', '', 'e', 'ss', 't']"); + assert.arrayEqual('tesst'.split(/(s*?)/), ['t', '', 'e', '', 's', '', 's', '', 't'], "'tesst'.split(/(s*?)/) results in ['t', '', 'e', '', 's', '', 's', '', 't']"); + assert.arrayEqual('tesst'.split(/s*/), ['t', 'e', 't'], "'tesst'.split(/(?:s)*/) results in ['t', 'e', 't']"); + assert.arrayEqual('tesst'.split(/(?=s+)/), ['te', 's', 'st'], "'tesst'.split(/(?=s+)/) results in ['te', 's', 'st']"); + assert.arrayEqual('test'.split('t'), ['', 'es', ''], "'test'.split('t') results in ['', 'es', '']"); + assert.arrayEqual('test'.split('es'), ['t', 't'], "'test'.split('es') results in ['t', 't']"); + assert.arrayEqual('test'.split(/t/), ['', 'es', ''], "'test'.split(/t/) results in ['', 'es', '']"); + assert.arrayEqual('test'.split(/es/), ['t', 't'], "'test'.split(/es/) results in ['t', 't']"); + assert.arrayEqual('test'.split(/(t)/), ['', 't', 'es', 't', ''], "'test'.split(/(t)/) results in ['', 't', 'es', 't', '']"); + assert.arrayEqual('test'.split(/(es)/), ['t', 'es', 't'], "'test'.split(/(es)/) results in ['t', 'es', 't']"); + assert.arrayEqual('test'.split(/(t)(e)(s)(t)/), ['', 't', 'e', 's', 't', ''], "'test'.split(/(t)(e)(s)(t)/) results in ['', 't', 'e', 's', 't', '']"); + assert.arrayEqual('.'.split(/(((.((.??)))))/), ['', '.', '.', '.', '', '', ''], "'.'.split(/(((.((.??)))))/) results in ['', '.', '.', '.', '', '', '']"); + assert.arrayEqual('.'.split(/(((((.??)))))/), ['.'], "'.'.split(/(((((.??)))))/) results in ['.']"); + assert.arrayEqual('a b c d'.split(/ /, -(2 ** 32) + 1), ['a'], "'a b c d'.split(/ /, -(2 ** 32) + 1) results in ['a']"); + assert.arrayEqual('a b c d'.split(/ /, 2 ** 32 + 1), ['a'], "'a b c d'.split(/ /, 2 ** 32 + 1) results in ['a']"); + assert.arrayEqual('a b c d'.split(/ /, Infinity), [], "'a b c d'.split(/ /, Infinity) results in []"); + let instance = Object(true); + instance.split = String.prototype.split; + let split = instance.split(true, false); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T1 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T1 #2'); + assert.same(split.length, 0, 'S15.5.4.14_A1_T1 #3'); + instance = Object(false); + instance.split = String.prototype.split; + split = instance.split(false, 0, null); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T2 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T2 #2'); + assert.same(split.length, 0, 'S15.5.4.14_A1_T2 #3'); + split = ''.split(); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T4 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T4 #2'); + assert.same(split.length, 1, 'S15.5.4.14_A1_T4 #3'); + assert.same(split[0], '', 'S15.5.4.14_A1_T4 #4'); + split = 'gnulluna'.split(null); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T5 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T5 #2'); + assert.same(split.length, 2, 'S15.5.4.14_A1_T5 #3'); + assert.same(split[0], 'g', 'S15.5.4.14_A1_T5 #4'); + assert.same(split[1], 'una', 'S15.5.4.14_A1_T5 #5'); + if (NATIVE) { + split = Object('1undefined').split(undefined); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T6 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T6 #2'); + assert.same(split.length, 1, 'S15.5.4.14_A1_T6 #3'); + assert.same(split[0], '1undefined', 'S15.5.4.14_A1_T6 #4'); + split = 'undefinedd'.split(undefined); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T7 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T7 #2'); + assert.same(split.length, 1, 'S15.5.4.14_A1_T7 #3'); + assert.same(split[0], 'undefinedd', 'S15.5.4.14_A1_T7 #4'); + split = String({ + toString() { /* empty */ }, + }).split(undefined); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T8 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T8 #2'); + assert.same(split.length, 1, 'S15.5.4.14_A1_T8 #3'); + assert.same(split[0], 'undefined', 'S15.5.4.14_A1_T8 #4'); + } + split = new String({ + valueOf() { /* empty */ }, + toString: undefined, + }).split(() => { /* empty */ }); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T9 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T9 #2'); + assert.same(split.length, 1, 'S15.5.4.14_A1_T9 #3'); + assert.same(split[0], 'undefined', 'S15.5.4.14_A1_T9 #4'); + split = 'ABB\u0041BABAB'.split({ + toString() { + return '\u0042B'; + }, + }, { + valueOf() { + return true; + }, + }); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T10 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T10 #2'); + assert.same(split.length, 1, 'S15.5.4.14_A1_T10 #3'); + assert.same(split[0], 'A', 'S15.5.4.14_A1_T10 #4'); + try { + 'ABB\u0041BABAB'.split({ + toString() { + return '\u0041B'; + }, + }, { + valueOf() { + throw new Error('intointeger'); + }, + }); + assert.avoid('S15.5.4.14_A1_T11 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'intointeger', 'S15.5.4.14_A1_T11 #2'); + } + if (NATIVE) { + try { + new String('ABB\u0041BABAB').split({ + toString() { + return '\u0041B'; + }, + }, { + valueOf() { + return {}; + }, + toString() { + throw new Error('intointeger'); + }, + }); + assert.avoid('S15.5.4.14_A1_T12 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'intointeger', 'S15.5.4.14_A1_T12 #2'); + } + } + split = 'ABB\u0041BABAB\u0042cc^^\u0042Bvv%%B\u0042xxx'.split({ + toString() { + return '\u0042\u0042'; + }, + }, { + valueOf() { + return {}; + }, + toString() { + return '2'; + }, + }); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T13 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T13 #2'); + assert.same(split.length, 2, 'S15.5.4.14_A1_T13 #3'); + assert.same(split[0], 'A', 'S15.5.4.14_A1_T13 #4'); + assert.same(split[1], 'ABABA', 'S15.5.4.14_A1_T13 #5'); + if (NATIVE) { + try { + instance = Object(10001.10001); + instance.split = String.prototype.split; + instance.split({ + toString() { + throw new Error('intostr'); + }, + }, { + valueOf() { + throw new Error('intoint'); + }, + }); + assert.avoid('S15.5.4.14_A1_T14 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'intoint', 'S15.5.4.14_A1_T14 #2'); + } + try { + class F { + constructor(value) { + this.value = value; + } + valueOf() { + return `${ this.value }`; + } + toString() { + return new Number(); + } + } + F.prototype.split = String.prototype.split; + new F().split({ + toString() { + return {}; + }, + valueOf() { + throw new Error('intostr'); + }, + }, { + valueOf() { + throw new Error('intoint'); + }, + }); + assert.avoid('S15.5.4.14_A1_T15 #1 lead to throwing exception'); + } catch (error) { + assert.same(error.message, 'intoint', 'S15.5.4.14_A1_T15 #2'); + } + } + try { + String.prototype.split.call(6776767677.006771, { + toString() { + return /77/g; + }, + }); + assert.avoid('S15.5.4.14_A1_T16 #1 lead to throwing exception'); + } catch (error) { + assert.true(error instanceof TypeError, 'S15.5.4.14_A1_T16 #2'); + } + split = String.prototype.split.call(6776767677.006771, /77/g); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T17 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T17 #2'); + assert.same(split.length, 4, 'S15.5.4.14_A1_T17 #3'); + assert.same(split[0], '6', 'S15.5.4.14_A1_T17 #4'); + assert.same(split[1], '67676', 'S15.5.4.14_A1_T17 #5'); + assert.same(split[2], '.006', 'S15.5.4.14_A1_T17 #6'); + assert.same(split[3], '1', 'S15.5.4.14_A1_T17 #7'); + split = String.prototype.split.call(6776767677.006771, /00/, 1); + assert.same(typeof split, 'object', 'S15.5.4.14_A1_T18 #1'); + assert.same(split.constructor, Array, 'S15.5.4.14_A1_T18 #2'); + assert.same(split.length, 1, 'S15.5.4.14_A1_T18 #3'); + assert.same(split[0], '6776767677.', 'S15.5.4.14_A1_T18 #4'); + split = Object('one,two,three,four,five').split(','); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T1 #1'); + assert.same(split.length, 5, 'S15.5.4.14_A2_T1 #2'); + assert.same(split[0], 'one', 'S15.5.4.14_A2_T1 #3'); + assert.same(split[1], 'two', 'S15.5.4.14_A2_T1 #4'); + assert.same(split[2], 'three', 'S15.5.4.14_A2_T1 #5'); + assert.same(split[3], 'four', 'S15.5.4.14_A2_T1 #6'); + assert.same(split[4], 'five', 'S15.5.4.14_A2_T1 #7'); + split = Object('one two three four five').split(' '); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T2 #1'); + assert.same(split.length, 5, 'S15.5.4.14_A2_T2 #2'); + assert.same(split[0], 'one', 'S15.5.4.14_A2_T2 #3'); + assert.same(split[1], 'two', 'S15.5.4.14_A2_T2 #4'); + assert.same(split[2], 'three', 'S15.5.4.14_A2_T2 #5'); + assert.same(split[3], 'four', 'S15.5.4.14_A2_T2 #6'); + assert.same(split[4], 'five', 'S15.5.4.14_A2_T2 #7'); + split = Object('one two three four five').split(RegExp(' '), 2); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T3 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A2_T3 #2'); + assert.same(split[0], 'one', 'S15.5.4.14_A2_T3 #3'); + assert.same(split[1], 'two', 'S15.5.4.14_A2_T3 #4'); + split = Object('one two three').split(''); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T4 #1'); + assert.same(split.length, 'one two three'.length, 'S15.5.4.14_A2_T4 #2'); + assert.same(split[0], 'o', 'S15.5.4.14_A2_T4 #3'); + assert.same(split[1], 'n', 'S15.5.4.14_A2_T4 #4'); + assert.same(split[11], 'e', 'S15.5.4.14_A2_T4 #5'); + assert.same(split[12], 'e', 'S15.5.4.14_A2_T4 #6'); + split = Object('one-1,two-2,four-4').split(/,/); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T5 #1'); + assert.same(split.length, 3, 'S15.5.4.14_A2_T5 #2'); + assert.same(split[0], 'one-1', 'S15.5.4.14_A2_T5 #3'); + assert.same(split[1], 'two-2', 'S15.5.4.14_A2_T5 #4'); + assert.same(split[2], 'four-4', 'S15.5.4.14_A2_T5 #5'); + let string = Object('one-1 two-2 three-3'); + split = string.split(''); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T6 #1'); + assert.same(split.length, string.length, 'S15.5.4.14_A2_T6 #2'); + for (let i = 0, { length } = split; i < length; ++i) { + assert.same(split[i], string.charAt(i), `S15.5.4.14_A2_T6 #${ i + 3 }`); + } + if (NATIVE) { + string = 'thisundefinedisundefinedaundefinedstringundefinedobject'; + split = string.split(undefined); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T7 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T7 #2'); + assert.same(split[0], string, 'S15.5.4.14_A2_T7 #3'); + } + string = 'thisnullisnullanullstringnullobject'; + let expected = ['this', 'is', 'a', 'string', 'object']; + split = string.split(null); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T8 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T8 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T8 #${ i + 3 }`); + } + string = 'thistrueistrueatruestringtrueobject'; + expected = ['this', 'is', 'a', 'string', 'object']; + split = string.split(true); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T9 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T9 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T9 #${ i + 3 }`); + } + string = 'this123is123a123string123object'; + expected = ['this', 'is', 'a', 'string', 'object']; + split = string.split(123); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T10 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T10 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T10 #${ i + 3 }`); + } + split = Object('one-1,two-2,four-4').split(':'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T11 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T11 #2'); + assert.same(split[0], 'one-1,two-2,four-4', 'S15.5.4.14_A2_T11 #3'); + split = Object('one-1 two-2 four-4').split('r-42'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T12 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T12 #2'); + assert.same(split[0], 'one-1 two-2 four-4', 'S15.5.4.14_A2_T12 #3'); + split = Object('one-1 two-2 four-4').split('-4'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T13 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A2_T13 #2'); + assert.same(split[0], 'one-1 two-2 four', 'S15.5.4.14_A2_T13 #3'); + assert.same(split[1], '', 'S15.5.4.14_A2_T13 #4'); + split = Object('one-1 two-2 four-4').split('on'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T14 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A2_T14 #2'); + assert.same(split[0], '', 'S15.5.4.14_A2_T14 #3'); + assert.same(split[1], 'e-1 two-2 four-4', 'S15.5.4.14_A2_T14 #4'); + split = new String().split(''); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T15 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A2_T15 #2'); + assert.same(split[0], undefined, 'S15.5.4.14_A2_T15 #3'); + split = new String().split(' '); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T16 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T16 #2'); + assert.same(split[0], '', 'S15.5.4.14_A2_T16 #3'); + split = Object(' ').split(''); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T18 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T18 #2'); + assert.same(split[0], ' ', 'S15.5.4.14_A2_T18 #3'); + split = Object(' ').split(' '); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T19 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A2_T19 #2'); + assert.same(split[0], '', 'S15.5.4.14_A2_T19 #3'); + assert.same(split[1], '', 'S15.5.4.14_A2_T19 #4'); + split = ''.split('x'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T19 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T19 #2'); + assert.same(split[0], '', 'S15.5.4.14_A2_T19 #3'); + string = Object('one-1 two-2 three-3'); + split = string.split(new RegExp()); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T20 #1'); + assert.same(split.length, string.length, 'S15.5.4.14_A2_T20 #2'); + for (let i = 0, { length } = split; i < length; ++i) { + assert.same(split[i], string.charAt(i), `S15.5.4.14_A2_T20 #${ i + 3 }`); + } + split = Object('hello').split('ll'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T21 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A2_T21 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A2_T21 #3'); + assert.same(split[1], 'o', 'S15.5.4.14_A2_T21 #4'); + split = Object('hello').split('l'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T22 #1'); + assert.same(split.length, 3, 'S15.5.4.14_A2_T22 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A2_T22 #3'); + assert.same(split[1], '', 'S15.5.4.14_A2_T22 #4'); + assert.same(split[2], 'o', 'S15.5.4.14_A2_T22 #5'); + split = Object('hello').split('x'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T23 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T23 #2'); + assert.same(split[0], 'hello', 'S15.5.4.14_A2_T23 #3'); + split = Object('hello').split('h'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T24 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A2_T24 #2'); + assert.same(split[0], '', 'S15.5.4.14_A2_T24 #3'); + assert.same(split[1], 'ello', 'S15.5.4.14_A2_T24 #4'); + split = Object('hello').split('o'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T25 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A2_T25 #2'); + assert.same(split[0], 'hell', 'S15.5.4.14_A2_T25 #3'); + assert.same(split[1], '', 'S15.5.4.14_A2_T25 #4'); + split = Object('hello').split('hello'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T26 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A2_T26 #2'); + assert.same(split[0], '', 'S15.5.4.14_A2_T26 #3'); + assert.same(split[1], '', 'S15.5.4.14_A2_T26 #4'); + split = Object('hello').split(undefined); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T27 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T27 #2'); + assert.same(split[0], 'hello', 'S15.5.4.14_A2_T27 #3'); + split = Object('hello').split('hellothere'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T28 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T28 #2'); + assert.same(split[0], 'hello', 'S15.5.4.14_A2_T28 #3'); + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1); + expected = ['', '00', '', '', '', '22', '33', '44', '60']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T29 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T29 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T29 #${ i + 3 }`); + } + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, 1); + expected = ['']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T30 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T30 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T30 #${ i + 3 }`); + } + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, 2); + expected = ['', '00']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T31 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T31 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T31 #${ i + 3 }`); + } + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, 0); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T32 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A2_T32 #2'); + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, 100); + expected = ['', '00', '', '', '', '22', '33', '44', '60']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T33 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T33 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T33 #${ i + 3 }`); + } + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, undefined); + expected = ['', '00', '', '', '', '22', '33', '44', '60']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T34 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T34 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T34 #${ i + 3 }`); + } + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, 2 ** 32 - 1); + expected = ['', '00', '', '', '', '22', '33', '44', '60']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T35 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T35 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T35 #${ i + 3 }`); + } + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, 'boo'); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T36 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A2_T36 #2'); + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, -(2 ** 32) + 1); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T37 #1'); + assert.arrayEqual(split, [''], 'S15.5.4.14_A2_T37 #2'); + instance = Object(100111122133144160); + instance.split = String.prototype.split; + split = instance.split(1, NaN); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T38 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A2_T38 #2'); + split = Object('hello').split('l', 0); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T39 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A2_T39 #2'); + split = Object('hello').split('l', 1); + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T40 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A2_T40 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A2_T40 #3'); + split = Object('hello').split('l', 2); + expected = ['he', '']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T41 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T41 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T41 #${ i + 3 }`); + } + split = Object('hello').split('l', 3); + expected = ['he', '', 'o']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T42 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T42 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T42 #${ i + 3 }`); + } + split = Object('hello').split('l', 4); + expected = ['he', '', 'o']; + assert.same(split.constructor, Array, 'S15.5.4.14_A2_T43 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A2_T43 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A2_T43 #${ i + 3 }`); + } + split = Object('one,two,three,four,five').split(); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T1 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T1 #2'); + assert.same(split[0], 'one,two,three,four,five', 'S15.5.4.14_A3_T1 #3'); + split = String.prototype.split.call({}); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T2 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T2 #2'); + assert.same(split[0], '[object Object]', 'S15.5.4.14_A3_T2 #3'); + split = String.prototype.split.call({ + toString() { + return 'function(){}'; + }, + }); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T3 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T3 #2'); + assert.same(split[0], 'function(){}', 'S15.5.4.14_A3_T3 #3'); + split = String.prototype.split.call(Object(NaN)); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T4 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T4 #2'); + assert.same(split[0], 'NaN', 'S15.5.4.14_A3_T4 #3'); + split = String.prototype.split.call(Object(-1234567890)); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T5 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T5 #2'); + assert.same(split[0], '-1234567890', 'S15.5.4.14_A3_T5 #3'); + instance = Object(-1e21); + split = String.prototype.split.call(instance); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T6 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T6 #2'); + assert.same(split[0], instance.toString(), 'S15.5.4.14_A3_T6 #3'); + split = String.prototype.split.call(Math); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T7 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T7 #2'); + assert.same(split[0], '[object Math]', 'S15.5.4.14_A3_T7 #3'); + split = String.prototype.split.call([1, 2, 3, 4, 5]); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T8 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T8 #2'); + assert.same(split[0], '1,2,3,4,5', 'S15.5.4.14_A3_T8 #3'); + split = String.prototype.split.call(Object(false)); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T9 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T9 #2'); + assert.same(split[0], 'false', 'S15.5.4.14_A3_T9 #3'); + split = String.prototype.split.call(new String()); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T10 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T10 #2'); + assert.same(split[0], '', 'S15.5.4.14_A3_T10 #3'); + split = String.prototype.split.call(Object(' ')); + assert.same(split.constructor, Array, 'S15.5.4.14_A3_T11 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A3_T11 #2'); + assert.same(split[0], ' ', 'S15.5.4.14_A3_T11 #3'); + if (NATIVE) { + split = Object('hello').split(/l/); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T1 #1'); + assert.same(split.length, 3, 'S15.5.4.14_A4_T1 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A4_T1 #3'); + assert.same(split[1], '', 'S15.5.4.14_A4_T1 #4'); + assert.same(split[2], 'o', 'S15.5.4.14_A4_T1 #5'); + } + split = Object('hello').split(/l/, 0); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T2 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A4_T2 #2'); + split = Object('hello').split(/l/, 1); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T3 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A4_T3 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A4_T3 #3'); + if (NATIVE) { + split = Object('hello').split(/l/, 2); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T4 #1'); + assert.same(split.length, 2, 'S15.5.4.14_A4_T4 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A4_T4 #3'); + assert.same(split[1], '', 'S15.5.4.14_A4_T4 #4'); + split = Object('hello').split(/l/, 3); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T5 #1'); + assert.same(split.length, 3, 'S15.5.4.14_A4_T5 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A4_T5 #3'); + assert.same(split[1], '', 'S15.5.4.14_A4_T5 #4'); + assert.same(split[2], 'o', 'S15.5.4.14_A4_T5 #5'); + split = Object('hello').split(/l/, 4); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T6 #1'); + assert.same(split.length, 3, 'S15.5.4.14_A4_T6 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A4_T6 #3'); + assert.same(split[1], '', 'S15.5.4.14_A4_T6 #4'); + assert.same(split[2], 'o', 'S15.5.4.14_A4_T6 #5'); + split = Object('hello').split(/l/, undefined); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T7 #1'); + assert.same(split.length, 3, 'S15.5.4.14_A4_T7 #2'); + assert.same(split[0], 'he', 'S15.5.4.14_A4_T7 #3'); + assert.same(split[1], '', 'S15.5.4.14_A4_T7 #4'); + assert.same(split[2], 'o', 'S15.5.4.14_A4_T7 #5'); + } + split = Object('hello').split(/l/, 'hi'); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T8 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A4_T8 #2'); + split = Object('hello').split(new RegExp()); + expected = ['h', 'e', 'l', 'l', 'o']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T10 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T10 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T10 #${ i + 3 }`); + } + split = Object('hello').split(new RegExp(), 0); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T11 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A4_T11 #2'); + split = Object('hello').split(new RegExp(), 1); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T12 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A4_T12 #2'); + assert.same(split[0], 'h', 'S15.5.4.14_A4_T12 #3'); + split = Object('hello').split(new RegExp(), 2); + expected = ['h', 'e']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T13 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T13 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T13 #${ i + 3 }`); + } + split = Object('hello').split(new RegExp(), 3); + expected = ['h', 'e', 'l']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T14 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T14 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T14 #${ i + 3 }`); + } + split = Object('hello').split(new RegExp(), 4); + expected = ['h', 'e', 'l', 'l']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T15 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T15 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T15 #${ i + 3 }`); + } + split = Object('hello').split(new RegExp(), undefined); + expected = ['h', 'e', 'l', 'l', 'o']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T16 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T16 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T16 #${ i + 3 }`); + } + split = Object('hello').split(new RegExp(), 'hi'); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T18 #1'); + assert.same(split.length, 0, 'S15.5.4.14_A4_T18 #2'); + split = Object('a b c de f').split(/\s/); + expected = ['a', 'b', 'c', 'de', 'f']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T19 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T19 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T19 #${ i + 3 }`); + } + split = Object('a b c de f').split(/\s/, 3); + expected = ['a', 'b', 'c']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T20 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T20 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T20 #${ i + 3 }`); + } + split = Object('a b c de f').split(/X/); + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T21 #1'); + assert.same(split.length, 1, 'S15.5.4.14_A4_T21 #2'); + assert.same(split[0], 'a b c de f', 'S15.5.4.14_A4_T21 #3'); + split = Object('dfe23iu 34 =+65--').split(/\d+/); + expected = ['dfe', 'iu ', ' =+', '--']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T22 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T22 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T22 #${ i + 3 }`); + } + if (NATIVE) { + split = Object('abc').split(/[a-z]/); + expected = ['', '', '', '']; + assert.same(split.constructor, Array, 'S15.5.4.14_A4_T24 #1'); + assert.same(split.length, expected.length, 'S15.5.4.14_A4_T24 #2'); + for (let i = 0, { length } = expected; i < length; ++i) { + assert.same(expected[i], split[i], `S15.5.4.14_A4_T24 #${ i + 3 }`); + } + } + + assert.throws(() => ''.split.call(Symbol('aplit test'), /./), 'throws on symbol context'); +}; + +QUnit.test('String#split regression', run); + +QUnit.test('RegExp#@@split appearance', assert => { + const split = /./[Symbol.split]; + assert.isFunction(split); + // assert.name(split, '[Symbol.split]'); + assert.arity(split, 2); + assert.looksNative(split); + assert.nonEnumerable(RegExp.prototype, Symbol.split); +}); + +QUnit.test('RegExp#@@split basic behavior', assert => { + assert.same(/\s/[Symbol.split]('a b c de f').length, 5); + assert.same(/\s/[Symbol.split]('a b c de f', undefined).length, 5); + assert.same(/\s/[Symbol.split]('a b c de f', 1).length, 1); + assert.same(/\s/[Symbol.split]('a b c de f', 10).length, 5); +}); + +QUnit.test('String#split delegates to @@split', assert => { + const string = STRICT ? 'string' : Object('string'); + const number = STRICT ? 42 : Object(42); + const object = {}; + object[Symbol.split] = function (a, b) { + return { a, b }; + }; + assert.same(string.split(object, 42).a, string); + assert.same(string.split(object, 42).b, 42); + assert.same(''.split.call(number, object, 42).a, number); + assert.same(''.split.call(number, object, 42).b, 42); + const regexp = /./; + regexp[Symbol.split] = function (a, b) { + return { a, b }; + }; + assert.same(string.split(regexp, 42).a, string); + assert.same(string.split(regexp, 42).b, 42); + assert.same(''.split.call(number, regexp, 42).a, number); + assert.same(''.split.call(number, regexp, 42).b, 42); +}); + +QUnit.test('RegExp#@@split delegates to exec', assert => { + let execCalled = false; + let speciesCalled = false; + let execSpeciesCalled = false; + const re = /[24]/; + re.exec = function (...args) { + execCalled = true; + return /./.exec.apply(this, args); + }; + re.constructor = { + // eslint-disable-next-line object-shorthand -- constructor + [Symbol.species]: function (source, flags) { + const re2 = new RegExp(source, flags); + speciesCalled = true; + re2.exec = function (...args) { + execSpeciesCalled = true; + return /./.exec.apply(this, args); + }; + return re2; + }, + }; + assert.deepEqual(re[Symbol.split]('123451234'), ['1', '3', '51', '3', '']); + assert.false(execCalled); + assert.true(speciesCalled); + assert.true(execSpeciesCalled); + + re.constructor = { + // eslint-disable-next-line object-shorthand -- constructor + [Symbol.species]: function (source, flags) { + const re2 = new RegExp(source, flags); + // Not a function, should be ignored + re2.exec = 3; + return re2; + }, + }; + assert.deepEqual(re[Symbol.split]('123451234'), ['1', '3', '51', '3', '']); + + re.constructor = { + // eslint-disable-next-line object-shorthand -- constructor + [Symbol.species]: function (source, flags) { + const re2 = new RegExp(source, flags); + // Does not return an object, should throw + re2.exec = () => 3; + return re2; + }, + }; + assert.throws(() => re[Symbol.split]('123451234')); +}); + +QUnit.test('RegExp#@@split implementation', patchRegExp$exec(run)); diff --git a/tests/unit-global/es.string.starts-with.js b/tests/unit-global/es.string.starts-with.js new file mode 100644 index 000000000000..8f892c67b2ea --- /dev/null +++ b/tests/unit-global/es.string.starts-with.js @@ -0,0 +1,44 @@ +import { GLOBAL, STRICT } from '../helpers/constants.js'; + +const Symbol = GLOBAL.Symbol || {}; + +QUnit.test('String#startsWith', assert => { + const { startsWith } = String.prototype; + assert.isFunction(startsWith); + assert.arity(startsWith, 1); + assert.name(startsWith, 'startsWith'); + assert.looksNative(startsWith); + assert.nonEnumerable(String.prototype, 'startsWith'); + assert.true('undefined'.startsWith()); + assert.false('undefined'.startsWith(null)); + assert.true('abc'.startsWith('')); + assert.true('abc'.startsWith('a')); + assert.true('abc'.startsWith('ab')); + assert.false('abc'.startsWith('bc')); + assert.true('abc'.startsWith('', NaN)); + assert.true('abc'.startsWith('a', -1)); + assert.false('abc'.startsWith('a', 1)); + assert.false('abc'.startsWith('a', Infinity)); + assert.true('abc'.startsWith('b', true)); + assert.true('abc'.startsWith('a', 'x')); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('startsWith test'); + assert.throws(() => startsWith.call(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => startsWith.call('a', symbol), 'throws on symbol argument'); + } + + if (STRICT) { + assert.throws(() => startsWith.call(null, '.'), TypeError); + assert.throws(() => startsWith.call(undefined, '.'), TypeError); + } + + const regexp = /./; + assert.throws(() => '/./'.startsWith(regexp), TypeError); + regexp[Symbol.match] = false; + assert.notThrows(() => '/./'.startsWith(regexp)); + const object = {}; + assert.notThrows(() => '[object Object]'.startsWith(object)); + object[Symbol.match] = true; + assert.throws(() => '[object Object]'.startsWith(object), TypeError); +}); diff --git a/tests/unit-global/es.string.strike.js b/tests/unit-global/es.string.strike.js new file mode 100644 index 000000000000..b4b39441787a --- /dev/null +++ b/tests/unit-global/es.string.strike.js @@ -0,0 +1,13 @@ +QUnit.test('String#strike', assert => { + const { strike } = String.prototype; + assert.isFunction(strike); + assert.arity(strike, 0); + assert.name(strike, 'strike'); + assert.looksNative(strike); + assert.nonEnumerable(String.prototype, 'strike'); + assert.same('a'.strike(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => strike.call(Symbol('strike test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.sub.js b/tests/unit-global/es.string.sub.js new file mode 100644 index 000000000000..8bc2e3de1c0d --- /dev/null +++ b/tests/unit-global/es.string.sub.js @@ -0,0 +1,13 @@ +QUnit.test('String#sub', assert => { + const { sub } = String.prototype; + assert.isFunction(sub); + assert.arity(sub, 0); + assert.name(sub, 'sub'); + assert.looksNative(sub); + assert.nonEnumerable(String.prototype, 'sub'); + assert.same('a'.sub(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => sub.call(Symbol('sub test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.substr.js b/tests/unit-global/es.string.substr.js new file mode 100644 index 000000000000..2478f7301323 --- /dev/null +++ b/tests/unit-global/es.string.substr.js @@ -0,0 +1,23 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#substr', assert => { + const { substr } = String.prototype; + assert.isFunction(substr); + assert.arity(substr, 2); + assert.name(substr, 'substr'); + assert.looksNative(substr); + assert.nonEnumerable(String.prototype, 'substr'); + + assert.same('12345'.substr(1, 3), '234'); + + assert.same('ab'.substr(-1), 'b'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => substr.call(Symbol('substr test'), 1, 3), 'throws on symbol context'); + } + + if (STRICT) { + assert.throws(() => substr.call(null, 1, 3), TypeError, 'Throws on null as `this`'); + assert.throws(() => substr.call(undefined, 1, 3), TypeError, 'Throws on undefined as `this`'); + } +}); diff --git a/tests/unit-global/es.string.sup.js b/tests/unit-global/es.string.sup.js new file mode 100644 index 000000000000..36465bac7162 --- /dev/null +++ b/tests/unit-global/es.string.sup.js @@ -0,0 +1,13 @@ +QUnit.test('String#sup', assert => { + const { sup } = String.prototype; + assert.isFunction(sup); + assert.arity(sup, 0); + assert.name(sup, 'sup'); + assert.looksNative(sup); + assert.nonEnumerable(String.prototype, 'sup'); + assert.same('a'.sup(), 'a', 'lower case'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => sup.call(Symbol('sup test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-global/es.string.to-well-formed.js b/tests/unit-global/es.string.to-well-formed.js new file mode 100644 index 000000000000..25e7e0077ffa --- /dev/null +++ b/tests/unit-global/es.string.to-well-formed.js @@ -0,0 +1,40 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#toWellFormed', assert => { + const { toWellFormed } = String.prototype; + assert.isFunction(toWellFormed); + assert.arity(toWellFormed, 0); + assert.name(toWellFormed, 'toWellFormed'); + assert.looksNative(toWellFormed); + assert.nonEnumerable(String.prototype, 'toWellFormed'); + + assert.same(toWellFormed.call('a'), 'a', 'a'); + assert.same(toWellFormed.call('abc'), 'abc', 'abc'); + assert.same(toWellFormed.call('💩'), '💩', '💩'); + assert.same(toWellFormed.call('💩b'), '💩b', '💩b'); + assert.same(toWellFormed.call('a💩'), 'a💩', '💩'); + assert.same(toWellFormed.call('a💩b'), 'a💩b', 'a💩b'); + assert.same(toWellFormed.call('💩a💩'), '💩a💩'); + assert.same(toWellFormed.call('\uD83D'), '\uFFFD', '\uD83D'); + assert.same(toWellFormed.call('\uDCA9'), '\uFFFD', '\uDCA9'); + assert.same(toWellFormed.call('\uDCA9\uD83D'), '\uFFFD\uFFFD', '\uDCA9\uD83D'); + assert.same(toWellFormed.call('a\uD83D'), 'a\uFFFD', 'a\uFFFD'); + assert.same(toWellFormed.call('\uDCA9a'), '\uFFFDa', '\uDCA9a'); + assert.same(toWellFormed.call('a\uD83Da'), 'a\uFFFDa', 'a\uD83Da'); + assert.same(toWellFormed.call('a\uDCA9a'), 'a\uFFFDa', 'a\uDCA9a'); + + assert.same(toWellFormed.call({ + toString() { + return 'abc'; + }, + }), 'abc', 'conversion #1'); + + assert.same(toWellFormed.call(1), '1', 'conversion #2'); + + if (STRICT) { + assert.throws(() => toWellFormed.call(null), TypeError, 'coercible #1'); + assert.throws(() => toWellFormed.call(undefined), TypeError, 'coercible #2'); + } + + assert.throws(() => toWellFormed.call(Symbol('toWellFormed test')), 'throws on symbol context'); +}); diff --git a/tests/unit-global/es.string.trim-end.js b/tests/unit-global/es.string.trim-end.js new file mode 100644 index 000000000000..a84d0326c8c3 --- /dev/null +++ b/tests/unit-global/es.string.trim-end.js @@ -0,0 +1,21 @@ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +QUnit.test('String#trimEnd', assert => { + const { trimEnd, trimRight } = String.prototype; + assert.isFunction(trimEnd); + assert.arity(trimEnd, 0); + assert.name(trimEnd, 'trimEnd'); + assert.looksNative(trimEnd); + assert.nonEnumerable(String.prototype, 'trimEnd'); + assert.same(trimEnd, trimRight, 'same #trimRight'); + assert.same(' \n q w e \n '.trimEnd(), ' \n q w e', 'removes whitespaces at right side of string'); + assert.same(WHITESPACES.trimEnd(), '', 'removes all whitespaces'); + assert.same('\u200B\u0085'.trimEnd(), '\u200B\u0085', "shouldn't remove this symbols"); + + assert.throws(() => trimEnd.call(Symbol('trimEnd test')), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => trimEnd.call(null, 0), TypeError); + assert.throws(() => trimEnd.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.string.trim-left.js b/tests/unit-global/es.string.trim-left.js new file mode 100644 index 000000000000..1eea62b1b456 --- /dev/null +++ b/tests/unit-global/es.string.trim-left.js @@ -0,0 +1,21 @@ +/* eslint-disable unicorn/prefer-string-trim-start-end -- required for testing */ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +QUnit.test('String#trimLeft', assert => { + const { trimLeft } = String.prototype; + assert.isFunction(trimLeft); + assert.arity(trimLeft, 0); + assert.name(trimLeft, 'trimStart'); + assert.looksNative(trimLeft); + assert.nonEnumerable(String.prototype, 'trimLeft'); + assert.same(' \n q w e \n '.trimLeft(), 'q w e \n ', 'removes whitespaces at left side of string'); + assert.same(WHITESPACES.trimLeft(), '', 'removes all whitespaces'); + assert.same('\u200B\u0085'.trimLeft(), '\u200B\u0085', "shouldn't remove this symbols"); + + assert.throws(() => trimLeft.call(Symbol('trimLeft test')), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => trimLeft.call(null, 0), TypeError); + assert.throws(() => trimLeft.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.string.trim-right.js b/tests/unit-global/es.string.trim-right.js new file mode 100644 index 000000000000..a0502460c4d3 --- /dev/null +++ b/tests/unit-global/es.string.trim-right.js @@ -0,0 +1,21 @@ +/* eslint-disable unicorn/prefer-string-trim-start-end -- required for testing */ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +QUnit.test('String#trimRight', assert => { + const { trimRight } = String.prototype; + assert.isFunction(trimRight); + assert.arity(trimRight, 0); + assert.name(trimRight, 'trimEnd'); + assert.looksNative(trimRight); + assert.nonEnumerable(String.prototype, 'trimRight'); + assert.same(' \n q w e \n '.trimRight(), ' \n q w e', 'removes whitespaces at right side of string'); + assert.same(WHITESPACES.trimRight(), '', 'removes all whitespaces'); + assert.same('\u200B\u0085'.trimRight(), '\u200B\u0085', "shouldn't remove this symbols"); + + assert.throws(() => trimRight.call(Symbol('trimRight test')), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => trimRight.call(null, 0), TypeError); + assert.throws(() => trimRight.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.string.trim-start.js b/tests/unit-global/es.string.trim-start.js new file mode 100644 index 000000000000..ea6504ad7a4a --- /dev/null +++ b/tests/unit-global/es.string.trim-start.js @@ -0,0 +1,21 @@ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +QUnit.test('String#trimStart', assert => { + const { trimStart, trimLeft } = String.prototype; + assert.isFunction(trimStart); + assert.arity(trimStart, 0); + assert.name(trimStart, 'trimStart'); + assert.looksNative(trimStart); + assert.nonEnumerable(String.prototype, 'trimStart'); + assert.same(trimStart, trimLeft, 'same #trimLeft'); + assert.same(' \n q w e \n '.trimStart(), 'q w e \n ', 'removes whitespaces at left side of string'); + assert.same(WHITESPACES.trimStart(), '', 'removes all whitespaces'); + assert.same('\u200B\u0085'.trimStart(), '\u200B\u0085', "shouldn't remove this symbols"); + + assert.throws(() => trimStart.call(Symbol('trimStart test')), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => trimStart.call(null, 0), TypeError); + assert.throws(() => trimStart.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.string.trim.js b/tests/unit-global/es.string.trim.js new file mode 100644 index 000000000000..6d029b80b282 --- /dev/null +++ b/tests/unit-global/es.string.trim.js @@ -0,0 +1,22 @@ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +QUnit.test('String#trim', assert => { + const { trim } = String.prototype; + assert.isFunction(''.trim); + assert.arity(trim, 0); + assert.name(trim, 'trim'); + assert.looksNative(trim); + assert.nonEnumerable(String.prototype, 'trim'); + assert.same(' \n q w e \n '.trim(), 'q w e', 'removes whitespaces at left & right side of string'); + assert.same(WHITESPACES.trim(), '', 'removes all whitespaces'); + assert.same('\u200B\u0085'.trim(), '\u200B\u0085', "shouldn't remove this symbols"); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => trim.call(Symbol('trim test')), 'throws on symbol context'); + } + + if (STRICT) { + assert.throws(() => trim.call(null, 0), TypeError); + assert.throws(() => trim.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/es.suppressed-error.constructor.js b/tests/unit-global/es.suppressed-error.constructor.js new file mode 100644 index 000000000000..6ea66f67c056 --- /dev/null +++ b/tests/unit-global/es.suppressed-error.constructor.js @@ -0,0 +1,50 @@ +/* eslint-disable unicorn/throw-new-error -- testing */ +QUnit.test('SuppressedError', assert => { + assert.isFunction(SuppressedError); + assert.arity(SuppressedError, 3); + assert.name(SuppressedError, 'SuppressedError'); + assert.looksNative(SuppressedError); + assert.true(new SuppressedError() instanceof SuppressedError); + assert.true(new SuppressedError() instanceof Error); + assert.true(SuppressedError() instanceof SuppressedError); + assert.true(SuppressedError() instanceof Error); + + assert.same(SuppressedError().error, undefined); + assert.same(SuppressedError().suppressed, undefined); + assert.same(SuppressedError().message, ''); + assert.same(SuppressedError().cause, undefined); + assert.false('cause' in SuppressedError()); + assert.same(SuppressedError().name, 'SuppressedError'); + + assert.same(new SuppressedError().error, undefined); + assert.same(new SuppressedError().suppressed, undefined); + assert.same(new SuppressedError().message, ''); + assert.same(new SuppressedError().cause, undefined); + assert.false('cause' in new SuppressedError()); + assert.same(new SuppressedError().name, 'SuppressedError'); + + const error1 = SuppressedError(1, 2, 3, { cause: 4 }); + + assert.same(error1.error, 1); + assert.same(error1.suppressed, 2); + assert.same(error1.message, '3'); + assert.same(error1.cause, undefined); + assert.false('cause' in error1); + assert.same(error1.name, 'SuppressedError'); + + const error2 = new SuppressedError(1, 2, 3, { cause: 4 }); + + assert.same(error2.error, 1); + assert.same(error2.suppressed, 2); + assert.same(error2.message, '3'); + assert.same(error2.cause, undefined); + assert.false('cause' in error2); + assert.same(error2.name, 'SuppressedError'); + + assert.throws(() => SuppressedError(1, 2, Symbol('SuppressedError constructor test')), 'throws on symbol as a message'); + assert.same(({}).toString.call(SuppressedError()), '[object Error]', 'Object#toString'); + + assert.same(SuppressedError.prototype.constructor, SuppressedError, 'prototype constructor'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.false(SuppressedError.prototype.hasOwnProperty('cause'), 'prototype has not cause'); +}); diff --git a/tests/unit-global/es.symbol.async-dispose.js b/tests/unit-global/es.symbol.async-dispose.js new file mode 100644 index 000000000000..1111f1d2d931 --- /dev/null +++ b/tests/unit-global/es.symbol.async-dispose.js @@ -0,0 +1,14 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.asyncDispose', assert => { + assert.true('asyncDispose' in Symbol, 'Symbol.asyncDispose available'); + assert.true(Object(Symbol.asyncDispose) instanceof Symbol, 'Symbol.asyncDispose is symbol'); + // Node 20.4.0 add `Symbol.asyncDispose`, but with incorrect descriptor + // https://github.com/nodejs/node/issues/48699 + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'asyncDispose'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/es.symbol.async-iterator.js b/tests/unit-global/es.symbol.async-iterator.js new file mode 100644 index 000000000000..341c0907ddd3 --- /dev/null +++ b/tests/unit-global/es.symbol.async-iterator.js @@ -0,0 +1,13 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.asyncIterator', assert => { + assert.true('asyncIterator' in Symbol, 'Symbol.asyncIterator available'); + assert.nonEnumerable(Symbol, 'asyncIterator'); + assert.true(Object(Symbol.asyncIterator) instanceof Symbol, 'Symbol.asyncIterator is symbol'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'asyncIterator'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/es.symbol.constructor.js b/tests/unit-global/es.symbol.constructor.js new file mode 100644 index 000000000000..864be5b0ea5d --- /dev/null +++ b/tests/unit-global/es.symbol.constructor.js @@ -0,0 +1,246 @@ +import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants.js'; + +const { + defineProperty, + defineProperties, + getOwnPropertyDescriptor, + getOwnPropertyNames, + getOwnPropertySymbols, + keys, + create, +} = Object; +const { ownKeys } = GLOBAL.Reflect || {}; + +QUnit.test('Symbol', assert => { + assert.isFunction(Symbol); + if (NATIVE) assert.same(Symbol.length, 0, 'arity is 0'); + assert.name(Symbol, 'Symbol'); + assert.looksNative(Symbol); + const symbol1 = Symbol('symbol'); + const symbol2 = Symbol('symbol'); + assert.notSame(symbol1, symbol2, 'Symbol("symbol") !== Symbol("symbol")'); + const object = {}; + object[symbol1] = 42; + assert.same(object[symbol1], 42, 'Symbol() work as key'); + assert.notSame(object[symbol2], 42, 'Various symbols from one description are various keys'); + // assert.throws(() => Symbol(Symbol('foo')), 'throws on symbol argument'); + if (DESCRIPTORS) { + let count = 0; + // eslint-disable-next-line no-unused-vars -- required for testing + for (const key in object) count++; + assert.same(count, 0, 'object[Symbol()] is not enumerable'); + } +}); + +QUnit.test('Symbol as global key', assert => { + const TEXT = 'test global symbol key'; + const symbol = Symbol(TEXT); + GLOBAL[symbol] = TEXT; + assert.same(GLOBAL[symbol], TEXT, TEXT); +}); + +QUnit.test('Well-known Symbols', assert => { + const wks = [ + 'hasInstance', + 'isConcatSpreadable', + 'iterator', + 'match', + 'matchAll', + 'replace', + 'search', + 'species', + 'split', + 'toPrimitive', + 'toStringTag', + 'unscopables', + ]; + for (const name of wks) { + assert.true(name in Symbol, `Symbol.${ name } available`); + assert.true(Object(Symbol[name]) instanceof Symbol, `Symbol.${ name } is symbol`); + if (DESCRIPTORS) { + const descriptor = getOwnPropertyDescriptor(Symbol, name); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } + } +}); + +QUnit.test('Symbol#@@toPrimitive', assert => { + const symbol = Symbol('Symbol#@@toPrimitive test'); + assert.isFunction(Symbol.prototype[Symbol.toPrimitive]); + assert.same(symbol, symbol[Symbol.toPrimitive](), 'works'); +}); + +QUnit.test('Symbol#@@toStringTag', assert => { + assert.same(Symbol.prototype[Symbol.toStringTag], 'Symbol', 'Symbol::@@toStringTag is `Symbol`'); +}); + +if (DESCRIPTORS) { + QUnit.test('Symbols & descriptors', assert => { + const d = Symbol('d'); + const e = Symbol('e'); + const f = Symbol('f'); + const i = Symbol('i'); + const j = Symbol('j'); + const prototype = { g: 'g' }; + prototype[i] = 'i'; + defineProperty(prototype, 'h', { + value: 'h', + }); + defineProperty(prototype, 'j', { + value: 'j', + }); + const object = create(prototype); + object.a = 'a'; + object[d] = 'd'; + defineProperty(object, 'b', { + value: 'b', + }); + defineProperty(object, 'c', { + value: 'c', + enumerable: true, + }); + defineProperty(object, e, { + configurable: true, + writable: true, + value: 'e', + }); + const descriptor = { + value: 'f', + enumerable: true, + }; + defineProperty(object, f, descriptor); + assert.true(descriptor.enumerable, 'defineProperty not changes descriptor object'); + assert.deepEqual(getOwnPropertyDescriptor(object, 'a'), { + configurable: true, + writable: true, + enumerable: true, + value: 'a', + }, 'getOwnPropertyDescriptor a'); + assert.deepEqual(getOwnPropertyDescriptor(object, 'b'), { + configurable: false, + writable: false, + enumerable: false, + value: 'b', + }, 'getOwnPropertyDescriptor b'); + assert.deepEqual(getOwnPropertyDescriptor(object, 'c'), { + configurable: false, + writable: false, + enumerable: true, + value: 'c', + }, 'getOwnPropertyDescriptor c'); + assert.deepEqual(getOwnPropertyDescriptor(object, d), { + configurable: true, + writable: true, + enumerable: true, + value: 'd', + }, 'getOwnPropertyDescriptor d'); + assert.deepEqual(getOwnPropertyDescriptor(object, e), { + configurable: true, + writable: true, + enumerable: false, + value: 'e', + }, 'getOwnPropertyDescriptor e'); + assert.deepEqual(getOwnPropertyDescriptor(object, f), { + configurable: false, + writable: false, + enumerable: true, + value: 'f', + }, 'getOwnPropertyDescriptor f'); + assert.same(getOwnPropertyDescriptor(object, 'g'), undefined, 'getOwnPropertyDescriptor g'); + assert.same(getOwnPropertyDescriptor(object, 'h'), undefined, 'getOwnPropertyDescriptor h'); + assert.same(getOwnPropertyDescriptor(object, i), undefined, 'getOwnPropertyDescriptor i'); + assert.same(getOwnPropertyDescriptor(object, j), undefined, 'getOwnPropertyDescriptor j'); + assert.same(getOwnPropertyDescriptor(object, 'k'), undefined, 'getOwnPropertyDescriptor k'); + assert.false(getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable, 'getOwnPropertyDescriptor on Object.prototype'); + assert.same(getOwnPropertyDescriptor(Object.prototype, d), undefined, 'getOwnPropertyDescriptor on Object.prototype missed symbol'); + assert.same(keys(object).length, 2, 'Object.keys'); + assert.same(getOwnPropertyNames(object).length, 3, 'Object.getOwnPropertyNames'); + assert.same(getOwnPropertySymbols(object).length, 3, 'Object.getOwnPropertySymbols'); + assert.same(ownKeys(object).length, 6, 'Reflect.ownKeys'); + delete object[e]; + object[e] = 'e'; + assert.deepEqual(getOwnPropertyDescriptor(object, e), { + configurable: true, + writable: true, + enumerable: true, + value: 'e', + }, 'redefined non-enum key'); + }); + + QUnit.test('Symbols & Object.defineProperties', assert => { + const c = Symbol('c'); + const d = Symbol('d'); + const descriptors = { + a: { + value: 'a', + }, + }; + descriptors[c] = { + value: 'c', + }; + defineProperty(descriptors, 'b', { + value: { + value: 'b', + }, + }); + defineProperty(descriptors, d, { + value: { + value: 'd', + }, + }); + const object = defineProperties({}, descriptors); + assert.same(object.a, 'a', 'a'); + assert.same(object.b, undefined, 'b'); + assert.same(object[c], 'c', 'c'); + assert.same(object[d], undefined, 'd'); + }); + + QUnit.test('Symbols & Object.create', assert => { + const c = Symbol('c'); + const d = Symbol('d'); + const descriptors = { + a: { + value: 'a', + }, + }; + descriptors[c] = { + value: 'c', + }; + defineProperty(descriptors, 'b', { + value: { + value: 'b', + }, + }); + defineProperty(descriptors, d, { + value: { + value: 'd', + }, + }); + const object = create(null, descriptors); + assert.same(object.a, 'a', 'a'); + assert.same(object.b, undefined, 'b'); + assert.same(object[c], 'c', 'c'); + assert.same(object[d], undefined, 'd'); + }); + + const constructors = ['Map', 'Set', 'Promise']; + for (const name of constructors) { + QUnit.test(`${ name }@@species`, assert => { + assert.same(GLOBAL[name][Symbol.species], GLOBAL[name], `${ name }@@species === ${ name }`); + const Subclass = create(GLOBAL[name]); + assert.same(Subclass[Symbol.species], Subclass, `${ name } subclass`); + }); + } + + QUnit.test('Array@@species', assert => { + assert.same(Array[Symbol.species], Array, 'Array@@species === Array'); + const Subclass = create(Array); + assert.same(Subclass[Symbol.species], Subclass, 'Array subclass'); + }); + + QUnit.test('Symbol.sham flag', assert => { + assert.same(Symbol.sham, typeof Symbol('Symbol.sham flag test') == 'symbol' ? undefined : true); + }); +} diff --git a/tests/tests/es.symbol.description.js b/tests/unit-global/es.symbol.description.js similarity index 79% rename from tests/tests/es.symbol.description.js rename to tests/unit-global/es.symbol.description.js index b65fd78b6755..7a42c31fbaa6 100644 --- a/tests/tests/es.symbol.description.js +++ b/tests/unit-global/es.symbol.description.js @@ -1,4 +1,5 @@ -import { DESCRIPTORS } from '../helpers/constants'; +/* eslint-disable symbol-description -- required for testing */ +import { DESCRIPTORS } from '../helpers/constants.js'; QUnit.test('Symbol#description', assert => { assert.same(Symbol('foo').description, 'foo'); @@ -11,10 +12,10 @@ QUnit.test('Symbol#description', assert => { assert.same(Object(Symbol('foo')).description, 'foo'); assert.same(Object(Symbol()).description, undefined); if (DESCRIPTORS) { - assert.ok(!Object.prototype.hasOwnProperty.call(Symbol('foo'), 'description')); + assert.false(Object.hasOwn(Symbol('foo'), 'description')); const descriptor = Object.getOwnPropertyDescriptor(Symbol.prototype, 'description'); - assert.same(descriptor.enumerable, false); - assert.same(descriptor.configurable, true); + assert.false(descriptor.enumerable); + assert.true(descriptor.configurable); assert.same(typeof descriptor.get, 'function'); } if (typeof Symbol() == 'symbol') { diff --git a/tests/unit-global/es.symbol.dispose.js b/tests/unit-global/es.symbol.dispose.js new file mode 100644 index 000000000000..910fcb2cb1e5 --- /dev/null +++ b/tests/unit-global/es.symbol.dispose.js @@ -0,0 +1,14 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.dispose', assert => { + assert.true('dispose' in Symbol, 'Symbol.dispose available'); + assert.true(Object(Symbol.dispose) instanceof Symbol, 'Symbol.dispose is symbol'); + // Node 20.4.0 add `Symbol.dispose`, but with incorrect descriptor + // https://github.com/nodejs/node/issues/48699 + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'dispose'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/es.symbol.for.js b/tests/unit-global/es.symbol.for.js new file mode 100644 index 000000000000..953f37c57e95 --- /dev/null +++ b/tests/unit-global/es.symbol.for.js @@ -0,0 +1,13 @@ +import { NATIVE } from '../helpers/constants.js'; + +QUnit.test('Symbol.for', assert => { + assert.isFunction(Symbol.for, 'Symbol.for is function'); + assert.nonEnumerable(Symbol, 'for'); + assert.arity(Symbol.for, 1, 'Symbol.for arity is 1'); + if (NATIVE) assert.name(Symbol.for, 'for', 'Symbol.for.name is "for"'); + assert.looksNative(Symbol.for, 'Symbol.for looks like native'); + const symbol = Symbol.for('foo'); + assert.same(Symbol.for('foo'), symbol, 'registry'); + assert.true(Object(symbol) instanceof Symbol, 'returns symbol'); + assert.throws(() => Symbol.for(Symbol('foo')), 'throws on symbol argument'); +}); diff --git a/tests/unit-global/es.symbol.key-for.js b/tests/unit-global/es.symbol.key-for.js new file mode 100644 index 000000000000..d5a3b415f83e --- /dev/null +++ b/tests/unit-global/es.symbol.key-for.js @@ -0,0 +1,10 @@ +QUnit.test('Symbol.keyFor', assert => { + assert.isFunction(Symbol.keyFor, 'Symbol.keyFor is function'); + assert.nonEnumerable(Symbol, 'keyFor'); + assert.arity(Symbol.keyFor, 1, 'Symbol.keyFor arity is 1'); + assert.name(Symbol.keyFor, 'keyFor', 'Symbol.keyFor.name is "keyFor"'); + assert.looksNative(Symbol.keyFor, 'Symbol.keyFor looks like native'); + assert.same(Symbol.keyFor(Symbol.for('foo')), 'foo'); + assert.same(Symbol.keyFor(Symbol('foo')), undefined); + assert.throws(() => Symbol.keyFor('foo'), 'throws on non-symbol'); +}); diff --git a/tests/unit-global/es.typed-array.at.js b/tests/unit-global/es.typed-array.at.js new file mode 100644 index 000000000000..9e674fbe9278 --- /dev/null +++ b/tests/unit-global/es.typed-array.at.js @@ -0,0 +1,29 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.indexOf', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { at } = TypedArray.prototype; + assert.isFunction(at, `${ name }::at is function`); + assert.arity(at, 1, `${ name }::at arity is 1`); + assert.name(at, 'at', `${ name }::at name is 'at'`); + assert.looksNative(at, `${ name }::at looks native`); + assert.same(1, new TypedArray([1, 2, 3]).at(0)); + assert.same(2, new TypedArray([1, 2, 3]).at(1)); + assert.same(3, new TypedArray([1, 2, 3]).at(2)); + assert.same(undefined, new TypedArray([1, 2, 3]).at(3)); + assert.same(3, new TypedArray([1, 2, 3]).at(-1)); + assert.same(2, new TypedArray([1, 2, 3]).at(-2)); + assert.same(1, new TypedArray([1, 2, 3]).at(-3)); + assert.same(undefined, new TypedArray([1, 2, 3]).at(-4)); + assert.same(1, new TypedArray([1, 2, 3]).at(0.4)); + assert.same(1, new TypedArray([1, 2, 3]).at(0.5)); + assert.same(1, new TypedArray([1, 2, 3]).at(0.6)); + assert.same(1, new TypedArray([1]).at(NaN)); + assert.same(1, new TypedArray([1]).at()); + assert.same(1, new TypedArray([1, 2, 3]).at(-0)); + assert.throws(() => at.call({ 0: 1, length: 1 }, 0), TypeError); + assert.throws(() => at.call(null, 0), TypeError); + assert.throws(() => at.call(undefined, 0), TypeError); + } +}); diff --git a/tests/tests/es.typed-array.constructors.js b/tests/unit-global/es.typed-array.constructors.js similarity index 89% rename from tests/tests/es.typed-array.constructors.js rename to tests/unit-global/es.typed-array.constructors.js index 5f61aa5ff4ed..eff383da8c17 100644 --- a/tests/tests/es.typed-array.constructors.js +++ b/tests/unit-global/es.typed-array.constructors.js @@ -1,14 +1,10 @@ -import { DESCRIPTORS, GLOBAL, NATIVE, TYPED_ARRAYS } from '../helpers/constants'; -import { createIterable } from '../helpers/helpers'; +import { DESCRIPTORS, NATIVE, TYPED_ARRAYS } from '../helpers/constants.js'; +import { createIterable } from '../helpers/helpers.js'; -const Symbol = GLOBAL.Symbol || {}; const { keys, getOwnPropertyDescriptor, getPrototypeOf, defineProperty, assign } = Object; if (DESCRIPTORS) { - for (const name in TYPED_ARRAYS) { - const bytes = TYPED_ARRAYS[name]; - const TypedArray = GLOBAL[name]; - + for (const { name, TypedArray, bytes } of TYPED_ARRAYS) { QUnit.test(`${ name } constructor`, assert => { assert.isFunction(TypedArray); assert.arity(TypedArray, 3); @@ -109,6 +105,20 @@ if (DESCRIPTORS) { assert.arrayEqual(array, [1, 2, 3, 4], 'correct values, passed iterable'); return true; }, 'passed iterable'); + assert.notThrows(() => { + array = new TypedArray([{ valueOf() { return 2; } }]); + assert.same(array.byteOffset, 0, '#byteOffset, passed array with object convertible to primitive'); + assert.same(array.byteLength, bytes, '#byteLength, passed array with object convertible to primitive'); + assert.arrayEqual(array, [2], 'correct values, passed array with object convertible to primitive'); + return true; + }, 'passed array with object convertible to primitive'); + assert.notThrows(() => { + array = new TypedArray(createIterable([{ valueOf() { return 2; } }])); + assert.same(array.byteOffset, 0, '#byteOffset, passed iterable with object convertible to primitive'); + assert.same(array.byteLength, bytes, '#byteLength, passed iterable with object convertible to primitive'); + assert.arrayEqual(array, [2], 'correct values, passed iterable with object convertible to primitive'); + return true; + }, 'passed iterable with object convertible to primitive'); array = new TypedArray(new TypedArray([1, 2, 3, 4])); assert.same(array.byteOffset, 0, '#byteOffset, passed typed array'); assert.same(array.byteLength, 4 * bytes, '#byteLength, passed typed array'); @@ -163,6 +173,7 @@ if (DESCRIPTORS) { assert.throws(() => new TypedArray(new ArrayBuffer(8), 16), 'If newByteLength < 0, throw a RangeError exception'); assert.throws(() => new TypedArray(new ArrayBuffer(24), 8, 24), 'If offset+newByteLength > bufferByteLength, throw a RangeError exception'); } + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing assert.throws(() => TypedArray(1), TypeError, 'throws without `new`'); assert.same(TypedArray[Symbol.species], TypedArray, '@@species'); }); @@ -245,8 +256,8 @@ if (DESCRIPTORS) { }); QUnit.test(`${ name }.sham`, assert => { - if (TypedArray.sham) assert.ok(true, `${ name }.sham flag exists`); - else assert.ok(true, `${ name }.sham flag missed`); + if (TypedArray.sham) assert.required(`${ name }.sham flag exists`); + else assert.required(`${ name }.sham flag missed`); }); } } diff --git a/tests/tests/es.typed-array.copy-within.js b/tests/unit-global/es.typed-array.copy-within.js similarity index 89% rename from tests/tests/es.typed-array.copy-within.js rename to tests/unit-global/es.typed-array.copy-within.js index 0c62d8d4da31..b9aed39137f9 100644 --- a/tests/tests/es.typed-array.copy-within.js +++ b/tests/unit-global/es.typed-array.copy-within.js @@ -1,16 +1,15 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.copyWithin', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { copyWithin } = TypedArray.prototype; assert.isFunction(copyWithin, `${ name }::copyWithin is function`); assert.arity(copyWithin, 2, `${ name }::copyWithin arity is 2`); assert.name(copyWithin, 'copyWithin', `${ name }::copyWithin name is 'copyWithin'`); assert.looksNative(copyWithin, `${ name }::copyWithin looks native`); const array = new TypedArray(5); - assert.strictEqual(array.copyWithin(0), array, 'return this'); + assert.same(array.copyWithin(0), array, 'return this'); assert.arrayEqual(new TypedArray([1, 2, 3, 4, 5]).copyWithin(0, 3), [4, 5, 3, 4, 5]); assert.arrayEqual(new TypedArray([1, 2, 3, 4, 5]).copyWithin(1, 3), [1, 4, 5, 4, 5]); assert.arrayEqual(new TypedArray([1, 2, 3, 4, 5]).copyWithin(1, 2), [1, 3, 4, 5, 5]); diff --git a/tests/unit-global/es.typed-array.every.js b/tests/unit-global/es.typed-array.every.js new file mode 100644 index 000000000000..0dfd361ae675 --- /dev/null +++ b/tests/unit-global/es.typed-array.every.js @@ -0,0 +1,38 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.every', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { every } = TypedArray.prototype; + assert.isFunction(every, `${ name }::every is function`); + assert.arity(every, 1, `${ name }::every arity is 1`); + assert.name(every, 'every', `${ name }::every name is 'every'`); + assert.looksNative(every, `${ name }::every looks native`); + const array = new TypedArray([1]); + const context = {}; + array.every(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true(new TypedArray([1, 2, 3]).every(it => typeof it == 'number')); + assert.true(new TypedArray([1, 2, 3]).every(it => it < 4)); + assert.false(new TypedArray([1, 2, 3]).every(it => it < 3)); + assert.false(new TypedArray([1, 2, 3]).every(it => typeof it == 'string')); + assert.true(new TypedArray([1, 2, 3]).every(function () { + return +this === 1; + }, 1)); + let values = ''; + let keys = ''; + new TypedArray([1, 2, 3]).every((value, key) => { + values += value; + keys += key; + return true; + }); + assert.same(values, '123'); + assert.same(keys, '012'); + assert.throws(() => every.call([0], () => { /* empty */ }), "isn't generic"); + } +}); diff --git a/tests/unit-global/es.typed-array.fill.js b/tests/unit-global/es.typed-array.fill.js new file mode 100644 index 000000000000..e3202eb12957 --- /dev/null +++ b/tests/unit-global/es.typed-array.fill.js @@ -0,0 +1,26 @@ +import { createConversionChecker } from '../helpers/helpers.js'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.fill', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { fill } = TypedArray.prototype; + assert.isFunction(fill, `${ name }::fill is function`); + assert.arity(fill, 1, `${ name }::fill arity is 1`); + assert.name(fill, 'fill', `${ name }::fill name is 'fill'`); + assert.looksNative(fill, `${ name }::fill looks native`); + const array = new TypedArray(5); + assert.same(array.fill(5), array, 'return this'); + assert.arrayEqual(new TypedArray(5).fill(5), [5, 5, 5, 5, 5], 'basic'); + assert.arrayEqual(new TypedArray(5).fill(5, 1), [0, 5, 5, 5, 5], 'start index'); + assert.arrayEqual(new TypedArray(5).fill(5, 1, 4), [0, 5, 5, 5, 0], 'end index'); + assert.arrayEqual(new TypedArray(5).fill(5, 6, 1), [0, 0, 0, 0, 0], 'start > end'); + assert.arrayEqual(new TypedArray(5).fill(5, -3, 4), [0, 0, 5, 5, 0], 'negative start index'); + assert.throws(() => fill.call([0], 1), "isn't generic"); + + const checker = createConversionChecker(10); + assert.same(new TypedArray(5).fill(checker)[2], 10); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); + } +}); diff --git a/tests/tests/es.typed-array.filter.js b/tests/unit-global/es.typed-array.filter.js similarity index 86% rename from tests/tests/es.typed-array.filter.js rename to tests/unit-global/es.typed-array.filter.js index b66821c609cc..623ca6c4f25b 100644 --- a/tests/tests/es.typed-array.filter.js +++ b/tests/unit-global/es.typed-array.filter.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.filter', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { filter } = TypedArray.prototype; assert.isFunction(filter, `${ name }::filter is function`); assert.arity(filter, 1, `${ name }::filter arity is 1`); @@ -19,7 +18,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.filter', assert => { assert.same(this, context, 'correct callback context'); }, context); const instance = new TypedArray([1, 2, 3, 4, 5, 6, 7, 8, 9]).filter(it => it % 2); - assert.ok(instance instanceof TypedArray, 'correct instance'); + assert.true(instance instanceof TypedArray, 'correct instance'); assert.arrayEqual(instance, [1, 3, 5, 7, 9], 'works'); let values = ''; let keys = ''; diff --git a/tests/tests/es.typed-array.find-index.js b/tests/unit-global/es.typed-array.find-index.js similarity index 88% rename from tests/tests/es.typed-array.find-index.js rename to tests/unit-global/es.typed-array.find-index.js index 316c6951803f..0893b25b7101 100644 --- a/tests/tests/es.typed-array.find-index.js +++ b/tests/unit-global/es.typed-array.find-index.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.findIndex', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { findIndex } = TypedArray.prototype; assert.isFunction(findIndex, `${ name }::findIndex is function`); assert.arity(findIndex, 1, `${ name }::findIndex arity is 1`); @@ -19,6 +18,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.findIndex', assert => { assert.same(this, context, 'correct callback context'); }, context); assert.same(new TypedArray([1, 2, 3]).findIndex(it => !(it % 2)), 1); + // eslint-disable-next-line unicorn/prefer-array-index-of -- ignore assert.same(new TypedArray([1, 2, 3]).findIndex(it => it === 4), -1); let values = ''; let keys = ''; diff --git a/tests/unit-global/es.typed-array.find-last-index.js b/tests/unit-global/es.typed-array.find-last-index.js new file mode 100644 index 000000000000..020b9e0e0ca3 --- /dev/null +++ b/tests/unit-global/es.typed-array.find-last-index.js @@ -0,0 +1,32 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.findLastIndex', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { findLastIndex } = TypedArray.prototype; + assert.isFunction(findLastIndex, `${ name }::findLastIndex is function`); + assert.arity(findLastIndex, 1, `${ name }::findLastIndex arity is 1`); + assert.name(findLastIndex, 'findLastIndex', `${ name }::findLastIndex name is 'findLastIndex'`); + assert.looksNative(findLastIndex, `${ name }::findLastIndex looks native`); + const array = new TypedArray([1]); + const context = {}; + array.findLastIndex(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same(new TypedArray([1, 2, 3, 2, 1]).findLastIndex(it => !(it % 2)), 3); + assert.same(new TypedArray([1, 2, 3, 2, 1]).findLastIndex(it => it > 3), -1); + let values = ''; + let keys = ''; + new TypedArray([1, 2, 3]).findLastIndex((value, key) => { + values += value; + keys += key; + }); + assert.same(values, '321'); + assert.same(keys, '210'); + assert.throws(() => findLastIndex.call([0], () => { /* empty */ }), "isn't generic"); + } +}); diff --git a/tests/unit-global/es.typed-array.find-last.js b/tests/unit-global/es.typed-array.find-last.js new file mode 100644 index 000000000000..504bbe31f5ff --- /dev/null +++ b/tests/unit-global/es.typed-array.find-last.js @@ -0,0 +1,32 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.findLast', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { findLast } = TypedArray.prototype; + assert.isFunction(findLast, `${ name }::findLast is function`); + assert.arity(findLast, 1, `${ name }::findLast arity is 1`); + assert.name(findLast, 'findLast', `${ name }::findLast name is 'findLast'`); + assert.looksNative(findLast, `${ name }::findLast looks native`); + const array = new TypedArray([1]); + const context = {}; + array.findLast(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same(new TypedArray([1, 2, 3, 4, 5]).findLast(it => !(it % 2)), 4); + assert.same(new TypedArray([1, 2, 3, 4, 5]).findLast(it => it === 6), undefined); + let values = ''; + let keys = ''; + new TypedArray([1, 2, 3]).findLast((value, key) => { + values += value; + keys += key; + }); + assert.same(values, '321'); + assert.same(keys, '210'); + assert.throws(() => findLast.call([0], () => { /* empty */ }), "isn't generic"); + } +}); diff --git a/tests/tests/es.typed-array.find.js b/tests/unit-global/es.typed-array.find.js similarity index 90% rename from tests/tests/es.typed-array.find.js rename to tests/unit-global/es.typed-array.find.js index 8845c9b7bf3d..74cb7978bc01 100644 --- a/tests/tests/es.typed-array.find.js +++ b/tests/unit-global/es.typed-array.find.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.find', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { find } = TypedArray.prototype; assert.isFunction(find, `${ name }::find is function`); assert.arity(find, 1, `${ name }::find arity is 1`); diff --git a/tests/tests/es.typed-array.for-each.js b/tests/unit-global/es.typed-array.for-each.js similarity index 90% rename from tests/tests/es.typed-array.for-each.js rename to tests/unit-global/es.typed-array.for-each.js index 8b1937c120c5..0552fa666399 100644 --- a/tests/tests/es.typed-array.for-each.js +++ b/tests/unit-global/es.typed-array.for-each.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.forEach', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { forEach } = TypedArray.prototype; assert.isFunction(forEach, `${ name }::forEach is function`); assert.arity(forEach, 1, `${ name }::forEach arity is 1`); diff --git a/tests/unit-global/es.typed-array.from.js b/tests/unit-global/es.typed-array.from.js new file mode 100644 index 000000000000..46f3ae8985aa --- /dev/null +++ b/tests/unit-global/es.typed-array.from.js @@ -0,0 +1,47 @@ +import { DESCRIPTORS, NATIVE, TYPED_ARRAYS_WITH_BIG_INT } from '../helpers/constants.js'; +import { createIterable } from '../helpers/helpers.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArray%.from', assert => { + // we can't implement %TypedArray% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray, $ } of TYPED_ARRAYS_WITH_BIG_INT) { + assert.isFunction(TypedArray.from, `${ name }.from is function`); + assert.arity(TypedArray.from, 1, `${ name }.from arity is 1`); + assert.name(TypedArray.from, 'from', `${ name }.from name is 'from'`); + assert.looksNative(TypedArray.from, `${ name }.from looks native`); + let instance = TypedArray.from([$(1), $(2), $(3)]); + assert.true(instance instanceof TypedArray, 'correct instance with array'); + assert.deepEqual(instance, new TypedArray([$(1), $(2), $(3)]), 'correct elements with array'); + instance = TypedArray.from({ + 0: $(1), + 1: $(2), + 2: $(3), + length: 3, + }); + assert.true(instance instanceof TypedArray, 'correct instance with array-like'); + assert.deepEqual(instance, new TypedArray([$(1), $(2), $(3)]), 'correct elements with array-like'); + instance = TypedArray.from(createIterable([$(1), $(2), $(3)])); + assert.true(instance instanceof TypedArray, 'correct instance with iterable'); + assert.deepEqual(instance, new TypedArray([$(1), $(2), $(3)]), 'correct elements with iterable'); + assert.deepEqual(TypedArray.from([1, 2, 3], it => String(it ** 2)), new TypedArray([$(1), $(4), $(9)]), 'accept callback'); + assert.deepEqual(TypedArray.from([{ valueOf() { return $(2); } }]), new TypedArray([$(2)]), 'passed array with object convertible to primitive'); + assert.deepEqual(TypedArray.from(createIterable([{ valueOf() { return $(2); } }])), new TypedArray([$(2)]), 'passed iterable with object convertible to primitive'); + const context = {}; + TypedArray.from([$(1)], function (value, key) { + assert.same(arguments.length, 2, 'correct number of callback arguments'); + assert.same(value, $(1), 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(this, context, 'correct callback context'); + return $(1); + }, context); + assert.throws(() => TypedArray.from.call(undefined, []), "isn't generic #1"); + if (NATIVE) { + assert.throws(() => TypedArray.from.call(Array, []), "isn't generic #2"); + assert.notThrows(() => TypedArray.from({ + 0: $(1), + length: -1, + }, () => { + throw new Error(); + }), 'uses ToLength'); + } + } +}); diff --git a/tests/unit-global/es.typed-array.includes.js b/tests/unit-global/es.typed-array.includes.js new file mode 100644 index 000000000000..df3d07edd6d4 --- /dev/null +++ b/tests/unit-global/es.typed-array.includes.js @@ -0,0 +1,18 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.includes', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { includes } = TypedArray.prototype; + assert.isFunction(includes, `${ name }::includes is function`); + assert.arity(includes, 1, `${ name }::includes arity is 1`); + assert.name(includes, 'includes', `${ name }::includes name is 'includes'`); + assert.looksNative(includes, `${ name }::includes looks native`); + assert.true(new TypedArray([1, 1, 1]).includes(1)); + assert.false(new TypedArray([1, 2, 3]).includes(1, 1)); + assert.true(new TypedArray([1, 2, 3]).includes(2, 1)); + assert.false(new TypedArray([1, 2, 3]).includes(2, -1)); + assert.true(new TypedArray([1, 2, 3]).includes(2, -2)); + assert.throws(() => includes.call([1], 1), "isn't generic"); + } +}); diff --git a/tests/tests/es.typed-array.index-of.js b/tests/unit-global/es.typed-array.index-of.js similarity index 85% rename from tests/tests/es.typed-array.index-of.js rename to tests/unit-global/es.typed-array.index-of.js index 8c185e6da2f5..c590433f9e40 100644 --- a/tests/tests/es.typed-array.index-of.js +++ b/tests/unit-global/es.typed-array.index-of.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.indexOf', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { indexOf } = TypedArray.prototype; assert.isFunction(indexOf, `${ name }::indexOf is function`); assert.arity(indexOf, 1, `${ name }::indexOf arity is 1`); diff --git a/tests/tests/es.typed-array.iterator.js b/tests/unit-global/es.typed-array.iterator.js similarity index 85% rename from tests/tests/es.typed-array.iterator.js rename to tests/unit-global/es.typed-array.iterator.js index 445a961f94f0..78a14854be51 100644 --- a/tests/tests/es.typed-array.iterator.js +++ b/tests/unit-global/es.typed-array.iterator.js @@ -1,11 +1,10 @@ -import { DESCRIPTORS, GLOBAL, NATIVE, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, GLOBAL, NATIVE, TYPED_ARRAYS } from '../helpers/constants.js'; const Symbol = GLOBAL.Symbol || {}; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.keys', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { keys } = TypedArray.prototype; assert.isFunction(keys, `${ name }::keys is function`); assert.arity(keys, 0, `${ name }::keys arity is 0`); @@ -14,7 +13,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.keys', assert => { const iterator = new TypedArray([1, 2, 3]).keys(); assert.isIterator(iterator); assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); assert.deepEqual(iterator.next(), { value: 0, done: false, @@ -37,8 +36,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.keys', assert => { if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.values', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { values } = TypedArray.prototype; assert.isFunction(values, `${ name }::values is function`); assert.arity(values, 0, `${ name }::values arity is 0`); @@ -47,7 +45,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.values', assert => { const iterator = new TypedArray([1, 2, 3]).values(); assert.isIterator(iterator); assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); assert.deepEqual(iterator.next(), { value: 1, done: false, @@ -70,8 +68,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.values', assert => { if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.entries', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { entries } = TypedArray.prototype; assert.isFunction(entries, `${ name }::entries is function`); assert.arity(entries, 0, `${ name }::entries arity is 0`); @@ -80,7 +77,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.entries', assert => { const iterator = new TypedArray([1, 2, 3]).entries(); assert.isIterator(iterator); assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); assert.deepEqual(iterator.next(), { value: [0, 1], done: false, @@ -103,17 +100,16 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.entries', assert => { if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.@@iterator', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; - assert.isIterable(TypedArray.prototype, `${ name } is itrable`); + for (const { name, TypedArray } of TYPED_ARRAYS) { + assert.isIterable(TypedArray.prototype, `${ name } is iterable`); assert.arity(TypedArray.prototype[Symbol.iterator], 0, `${ name }::@@iterator arity is 0`); assert.name(TypedArray.prototype[Symbol.iterator], 'values', `${ name }::@@iterator name is 'values'`); assert.looksNative(TypedArray.prototype[Symbol.iterator], `${ name }::@@iterator looks native`); - assert.strictEqual(TypedArray.prototype[Symbol.iterator], TypedArray.prototype.values); + assert.same(TypedArray.prototype[Symbol.iterator], TypedArray.prototype.values); const iterator = new TypedArray([1, 2, 3])[Symbol.iterator](); assert.isIterator(iterator); assert.isIterable(iterator); - assert.strictEqual(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); assert.deepEqual(iterator.next(), { value: 1, done: false, diff --git a/tests/tests/es.typed-array.join.js b/tests/unit-global/es.typed-array.join.js similarity index 77% rename from tests/tests/es.typed-array.join.js rename to tests/unit-global/es.typed-array.join.js index eabb8b72ad1a..6a7ed10f6371 100644 --- a/tests/tests/es.typed-array.join.js +++ b/tests/unit-global/es.typed-array.join.js @@ -1,9 +1,9 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +/* eslint-disable unicorn/require-array-join-separator -- required for testing */ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.join', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { join } = TypedArray.prototype; assert.isFunction(join, `${ name }::join is function`); assert.arity(join, 1, `${ name }::join arity is 1`); diff --git a/tests/tests/es.typed-array.last-index-of.js b/tests/unit-global/es.typed-array.last-index-of.js similarity index 86% rename from tests/tests/es.typed-array.last-index-of.js rename to tests/unit-global/es.typed-array.last-index-of.js index c7cfed28dacf..1d71265ab8e7 100644 --- a/tests/tests/es.typed-array.last-index-of.js +++ b/tests/unit-global/es.typed-array.last-index-of.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.lastIndexOf', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { lastIndexOf } = TypedArray.prototype; assert.isFunction(lastIndexOf, `${ name }::lastIndexOf is function`); assert.arity(lastIndexOf, 1, `${ name }::lastIndexOf arity is 1`); diff --git a/tests/tests/es.typed-array.map.js b/tests/unit-global/es.typed-array.map.js similarity index 86% rename from tests/tests/es.typed-array.map.js rename to tests/unit-global/es.typed-array.map.js index 4a81b4dbd1d3..20a692a49c71 100644 --- a/tests/tests/es.typed-array.map.js +++ b/tests/unit-global/es.typed-array.map.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.map', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { map } = TypedArray.prototype; assert.isFunction(map, `${ name }::map is function`); assert.arity(map, 1, `${ name }::map arity is 1`); @@ -19,7 +18,7 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.map', assert => { assert.same(this, context, 'correct callback context'); }, context); const instance = new TypedArray([1, 2, 3, 4, 5]).map(it => it * 2); - assert.ok(instance instanceof TypedArray, 'correct instance'); + assert.true(instance instanceof TypedArray, 'correct instance'); assert.arrayEqual(instance, [2, 4, 6, 8, 10], 'works'); let values = ''; let keys = ''; diff --git a/tests/unit-global/es.typed-array.of.js b/tests/unit-global/es.typed-array.of.js new file mode 100644 index 000000000000..a81a0d367db2 --- /dev/null +++ b/tests/unit-global/es.typed-array.of.js @@ -0,0 +1,22 @@ +import { DESCRIPTORS, NATIVE, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArray%.of', assert => { + // we can't implement %TypedArray% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + assert.isFunction(TypedArray.of, `${ name }.of is function`); + assert.arity(TypedArray.of, 0, `${ name }.of arity is 0`); + assert.name(TypedArray.of, 'of', `${ name }.of name is 'of'`); + assert.looksNative(TypedArray.of, `${ name }.of looks native`); + let instance = TypedArray.of(); + assert.true(instance instanceof TypedArray, 'correct instance with 0 arguments'); + assert.arrayEqual(instance, [], 'correct elements with 0 arguments'); + instance = TypedArray.of(1); + assert.true(instance instanceof TypedArray, 'correct instance with 1 argument'); + assert.arrayEqual(instance, [1], 'correct elements with 1 argument'); + instance = TypedArray.of(1, 2, 3); + assert.true(instance instanceof TypedArray, 'correct instance with several arguments'); + assert.arrayEqual(instance, [1, 2, 3], 'correct elements with several arguments'); + assert.throws(() => TypedArray.of.call(undefined, 1), "isn't generic #1"); + if (NATIVE) assert.throws(() => TypedArray.of.call(Array, 1), "isn't generic #2"); + } +}); diff --git a/tests/tests/es.typed-array.reduce-right.js b/tests/unit-global/es.typed-array.reduce-right.js similarity index 92% rename from tests/tests/es.typed-array.reduce-right.js rename to tests/unit-global/es.typed-array.reduce-right.js index ce5b4dcfc549..858e83af0e0f 100644 --- a/tests/tests/es.typed-array.reduce-right.js +++ b/tests/unit-global/es.typed-array.reduce-right.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.reduceRight', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { reduceRight } = TypedArray.prototype; assert.isFunction(reduceRight, `${ name }::reduceRight is function`); assert.arity(reduceRight, 1, `${ name }::reduceRight arity is 1`); diff --git a/tests/tests/es.typed-array.reduce.js b/tests/unit-global/es.typed-array.reduce.js similarity index 92% rename from tests/tests/es.typed-array.reduce.js rename to tests/unit-global/es.typed-array.reduce.js index ac701e6976d7..a7c4477801ed 100644 --- a/tests/tests/es.typed-array.reduce.js +++ b/tests/unit-global/es.typed-array.reduce.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.reduce', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { reduce } = TypedArray.prototype; assert.isFunction(reduce, `${ name }::reduce is function`); assert.arity(reduce, 1, `${ name }::reduce arity is 1`); diff --git a/tests/tests/es.typed-array.reverse.js b/tests/unit-global/es.typed-array.reverse.js similarity index 85% rename from tests/tests/es.typed-array.reverse.js rename to tests/unit-global/es.typed-array.reverse.js index 6d647bf8395a..908919379bf4 100644 --- a/tests/tests/es.typed-array.reverse.js +++ b/tests/unit-global/es.typed-array.reverse.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.reverse', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { reverse } = TypedArray.prototype; assert.isFunction(reverse, `${ name }::reverse is function`); assert.arity(reverse, 0, `${ name }::reverse arity is 0`); diff --git a/tests/unit-global/es.typed-array.set.js b/tests/unit-global/es.typed-array.set.js new file mode 100644 index 000000000000..d8d1a182b032 --- /dev/null +++ b/tests/unit-global/es.typed-array.set.js @@ -0,0 +1,33 @@ +import { DESCRIPTORS, NATIVE, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.set', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { set } = TypedArray.prototype; + assert.isFunction(set, `${ name }::set is function`); + if (NATIVE) assert.arity(set, 1, `${ name }::set arity is 1`); + assert.name(set, 'set', `${ name }::set name is 'set'`); + assert.looksNative(set, `${ name }::set looks native`); + assert.same(new TypedArray(1).set([1]), undefined, 'void'); + const array1 = new TypedArray([1, 2, 3, 4, 5]); + const array2 = new TypedArray(5); + array2.set(array1); + assert.arrayEqual(array2, [1, 2, 3, 4, 5]); + assert.throws(() => array2.set(array1, 1)); + assert.throws(() => array2.set(array1, -1)); + array2.set(new TypedArray([99, 98]), 2); + assert.arrayEqual(array2, [1, 2, 99, 98, 5]); + array2.set(new TypedArray([99, 98, 97]), 2); + assert.arrayEqual(array2, [1, 2, 99, 98, 97]); + assert.throws(() => array2.set(new TypedArray([99, 98, 97, 96]), 2)); + assert.throws(() => array2.set([101, 102, 103, 104], 4)); + const array3 = new TypedArray(2); + assert.notThrows(() => array3.set({ length: 2, 0: 1, 1: 2 }), 'set array-like #1'); + assert.arrayEqual(array3, [1, 2], 'set array-like #2'); + assert.notThrows(() => array3.set('34'), 'set string #1'); + assert.arrayEqual(array3, [3, 4], 'set string #2'); + assert.notThrows(() => array3.set(1), 'set number #1'); + assert.arrayEqual(array3, [3, 4], 'set number #2'); + assert.throws(() => set.call([1, 2, 3], [1]), "isn't generic"); + } +}); diff --git a/tests/unit-global/es.typed-array.slice.js b/tests/unit-global/es.typed-array.slice.js new file mode 100644 index 000000000000..178694973dc5 --- /dev/null +++ b/tests/unit-global/es.typed-array.slice.js @@ -0,0 +1,23 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.slice', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { slice } = TypedArray.prototype; + assert.isFunction(slice, `${ name }::slice is function`); + assert.arity(slice, 2, `${ name }::slice arity is 0`); + assert.name(slice, 'slice', `${ name }::slice name is 'slice'`); + assert.looksNative(slice, `${ name }::slice looks native`); + const array = new TypedArray([1, 2, 3, 4, 5]); + assert.notSame(array.slice(), array, 'returns new array'); + assert.true(array.slice() instanceof TypedArray, 'correct instance'); + assert.notSame(array.slice().buffer, array.buffer, 'with new buffer'); + assert.arrayEqual(array.slice(), array); + assert.arrayEqual(array.slice(1, 3), [2, 3]); + assert.arrayEqual(array.slice(1, undefined), [2, 3, 4, 5]); + assert.arrayEqual(array.slice(1, -1), [2, 3, 4]); + assert.arrayEqual(array.slice(-2, -1), [4]); + assert.arrayEqual(array.slice(-2, -3), []); + assert.throws(() => slice.call([1, 2], 1), "isn't generic"); + } +}); diff --git a/tests/unit-global/es.typed-array.some.js b/tests/unit-global/es.typed-array.some.js new file mode 100644 index 000000000000..803e3a5e71aa --- /dev/null +++ b/tests/unit-global/es.typed-array.some.js @@ -0,0 +1,37 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.some', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { some } = TypedArray.prototype; + assert.isFunction(some, `${ name }::some is function`); + assert.arity(some, 1, `${ name }::some arity is 1`); + assert.name(some, 'some', `${ name }::some name is 'some'`); + assert.looksNative(some, `${ name }::some looks native`); + const array = new TypedArray([1]); + const context = {}; + array.some(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true(new TypedArray([1, 2, 3]).some(it => typeof it == 'number')); + assert.true(new TypedArray([1, 2, 3]).some(it => it < 3)); + assert.false(new TypedArray([1, 2, 3]).some(it => it < 0)); + assert.false(new TypedArray([1, 2, 3]).some(it => typeof it == 'string')); + assert.true(new TypedArray([1, 2, 3]).some(function () { + return +this === 1; + }, 1)); + let values = ''; + let keys = ''; + new TypedArray([1, 2, 3]).some((value, key) => { + values += value; + keys += key; + }); + assert.same(values, '123'); + assert.same(keys, '012'); + assert.throws(() => some.call([0], () => { /* empty */ }), "isn't generic"); + } +}); diff --git a/tests/unit-global/es.typed-array.sort.js b/tests/unit-global/es.typed-array.sort.js new file mode 100644 index 000000000000..69034c454fd0 --- /dev/null +++ b/tests/unit-global/es.typed-array.sort.js @@ -0,0 +1,68 @@ +import { DESCRIPTORS, STRICT, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.sort', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { sort } = TypedArray.prototype; + assert.isFunction(sort, `${ name }::sort is function`); + assert.arity(sort, 1, `${ name }::sort arity is 1`); + assert.name(sort, 'sort', `${ name }::sort name is 'sort'`); + assert.looksNative(sort, `${ name }::sort looks native`); + + if (name.indexOf('Float') === 0) { + assert.deepEqual(new TypedArray([1, -1, 3, NaN, 2, 0, 11, -0]).sort(), new TypedArray([-1, -0, 0, 1, 2, 3, 11, NaN]), '#1'); + assert.true(1 / new TypedArray([0, -0]).sort()[0] < 0, '-0'); + assert.deepEqual(new TypedArray([NaN, 1, NaN]).sort(), new TypedArray([1, NaN, NaN]), 'NaN'); + } + + if (name.indexOf('8') === -1) { + const expected = Array(516); + let array = new TypedArray(516); + let index, mod, j, k, postfix; + + for (index = 0; index < 516; index++) { + mod = index % 4; + array[index] = 515 - index; + expected[index] = index - 2 * mod + 3; + } + + array.sort((a, b) => (a / 4 | 0) - (b / 4 | 0)); + + assert.same(String(array), String(expected), 'stable #1'); + + let result = ''; + array = new TypedArray(520); + index = 0; + + for (j = 0; j < 10; j++) { + switch (j) { + case 1: case 4: case 5: case 7: postfix = 3; break; + case 3: case 6: postfix = 4; break; + default: postfix = 2; + } + + for (k = 0; k < 52; k++) { + array[index] = 10 * index++ + postfix; + } + } + + array.sort((a, b) => b % 10 - a % 10); + + for (index = 0; index < array.length; index++) { + j = String((array[index] / 520) | 0); + if (result.charAt(result.length - 1) !== j) result += j; + } + + assert.same(result, '3614570289', 'stable #2'); + } + + assert.throws(() => sort.call([0], () => { /* empty */ }), "isn't generic"); + assert.notThrows(() => new TypedArray([1, 2, 3]).sort(undefined).length === 3, 'works with undefined'); + assert.throws(() => new TypedArray([1, 2, 3]).sort(null), 'throws on null'); + assert.throws(() => new TypedArray([1, 2, 3]).sort({}), 'throws on {}'); + if (STRICT) { + assert.throws(() => sort.call(null), TypeError, 'ToObject(this)'); + assert.throws(() => sort.call(undefined), TypeError, 'ToObject(this)'); + } + } +}); diff --git a/tests/tests/es.typed-array.subarray.js b/tests/unit-global/es.typed-array.subarray.js similarity index 82% rename from tests/tests/es.typed-array.subarray.js rename to tests/unit-global/es.typed-array.subarray.js index e2549dbb6180..e4943516b3e1 100644 --- a/tests/tests/es.typed-array.subarray.js +++ b/tests/unit-global/es.typed-array.subarray.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, NATIVE, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, NATIVE, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.subarray', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { subarray } = TypedArray.prototype; assert.isFunction(subarray, `${ name }::subarray is function`); if (NATIVE) assert.arity(subarray, 2, `${ name }::subarray arity is 2`); @@ -11,8 +10,8 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.subarray', assert => { assert.looksNative(subarray, `${ name }::subarray looks native`); const array1 = new TypedArray([1, 2, 3, 4, 5]); const array2 = array1.subarray(3); - assert.ok(array1 !== array2, 'creates new array'); - assert.ok(array2 instanceof TypedArray, `instance ${ name }`); + assert.notSame(array1, array2, 'creates new array'); + assert.true(array2 instanceof TypedArray, `instance ${ name }`); assert.same(array1.buffer, array2.buffer, 'with the same buffer'); assert.arrayEqual(array2, [4, 5]); assert.arrayEqual(array1.subarray(1, 3), [2, 3]); diff --git a/tests/tests/es.typed-array.to-locale-string.js b/tests/unit-global/es.typed-array.to-locale-string.js similarity index 83% rename from tests/tests/es.typed-array.to-locale-string.js rename to tests/unit-global/es.typed-array.to-locale-string.js index 1060082933f1..381627f7c273 100644 --- a/tests/tests/es.typed-array.to-locale-string.js +++ b/tests/unit-global/es.typed-array.to-locale-string.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.toLocaleString', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { toLocaleString } = TypedArray.prototype; assert.isFunction(toLocaleString, `${ name }::toLocaleString is function`); assert.arity(toLocaleString, 0, `${ name }::toLocaleString arity is 0`); diff --git a/tests/unit-global/es.typed-array.to-reversed.js b/tests/unit-global/es.typed-array.to-reversed.js new file mode 100644 index 000000000000..d0935ff2a85a --- /dev/null +++ b/tests/unit-global/es.typed-array.to-reversed.js @@ -0,0 +1,22 @@ +import { DESCRIPTORS, TYPED_ARRAYS_WITH_BIG_INT } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.toReversed', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray, $ } of TYPED_ARRAYS_WITH_BIG_INT) { + const { toReversed } = TypedArray.prototype; + + assert.isFunction(toReversed, `${ name }::toReversed is function`); + assert.arity(toReversed, 0, `${ name }::toReversed arity is 0`); + assert.name(toReversed, 'toReversed', `${ name }::toReversed name is 'toReversed'`); + assert.looksNative(toReversed, `${ name }::toReversed looks native`); + + const array = new TypedArray([$(1), $(2)]); + assert.notSame(array.toReversed(), array, 'immutable'); + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4)]).toReversed(), new TypedArray([$(4), $(3), $(2), $(1)]), 'works #1'); + assert.deepEqual(new TypedArray([$(1), $(2), $(3)]).toReversed(), new TypedArray([$(3), $(2), $(1)]), 'works #2'); + + assert.throws(() => toReversed.call(null), TypeError, "isn't generic #1"); + assert.throws(() => toReversed.call(undefined), TypeError, "isn't generic #2"); + assert.throws(() => toReversed.call([$(1), $(2)]), TypeError, "isn't generic #3"); + } +}); diff --git a/tests/unit-global/es.typed-array.to-sorted.js b/tests/unit-global/es.typed-array.to-sorted.js new file mode 100644 index 000000000000..933f79a1d6f7 --- /dev/null +++ b/tests/unit-global/es.typed-array.to-sorted.js @@ -0,0 +1,71 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.toSorted', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { toSorted } = TypedArray.prototype; + + assert.isFunction(toSorted, `${ name }::toSorted is function`); + assert.arity(toSorted, 1, `${ name }::toSorted arity is 1`); + assert.name(toSorted, 'toSorted', `${ name }::toSorted name is 'toSorted'`); + assert.looksNative(toSorted, `${ name }::toSorted looks native`); + + let array = new TypedArray([1]); + assert.notSame(array.toSorted(), array, 'immutable'); + + if (name.indexOf('Float') === 0) { + assert.deepEqual(new TypedArray([1, -1, 3, NaN, 2, 0, 11, -0]).toSorted(), new TypedArray([-1, -0, 0, 1, 2, 3, 11, NaN]), '#1'); + assert.true(1 / new TypedArray([0, -0]).toSorted()[0] < 0, '-0'); + assert.deepEqual(new TypedArray([NaN, 1, NaN]).toSorted(), new TypedArray([1, NaN, NaN]), 'NaN'); + } + + if (name.indexOf('8') === -1) { + const expected = Array(516); + array = new TypedArray(516); + let index, mod, j, k, postfix; + + for (index = 0; index < 516; index++) { + mod = index % 4; + array[index] = 515 - index; + expected[index] = index - 2 * mod + 3; + } + + array = array.toSorted((a, b) => (a / 4 | 0) - (b / 4 | 0)); + + assert.arrayEqual(array, expected, 'stable #1'); + + let result = ''; + array = new TypedArray(520); + index = 0; + + for (j = 0; j < 10; j++) { + switch (j) { + case 1: case 4: case 5: case 7: postfix = 3; break; + case 3: case 6: postfix = 4; break; + default: postfix = 2; + } + + for (k = 0; k < 52; k++) { + array[index] = 10 * index++ + postfix; + } + } + + array = array.toSorted((a, b) => b % 10 - a % 10); + + for (index = 0; index < array.length; index++) { + j = String((array[index] / 520) | 0); + if (result.charAt(result.length - 1) !== j) result += j; + } + + assert.same(result, '3614570289', 'stable #2'); + } + + assert.notThrows(() => new TypedArray([1, 2, 3]).toSorted(undefined).length === 3, 'works with undefined'); + assert.throws(() => new TypedArray([1, 2, 3]).toSorted(null), 'throws on null'); + assert.throws(() => new TypedArray([1, 2, 3]).toSorted({}), 'throws on {}'); + + assert.throws(() => toSorted.call(null), TypeError, "isn't generic #1"); + assert.throws(() => toSorted.call(undefined), TypeError, "isn't generic #2"); + assert.throws(() => toSorted.call([1, 2]), TypeError, "isn't generic #3"); + } +}); diff --git a/tests/tests/es.typed-array.to-string.js b/tests/unit-global/es.typed-array.to-string.js similarity index 81% rename from tests/tests/es.typed-array.to-string.js rename to tests/unit-global/es.typed-array.to-string.js index 12e3807f0ad4..c820bf8942b9 100644 --- a/tests/tests/es.typed-array.to-string.js +++ b/tests/unit-global/es.typed-array.to-string.js @@ -1,9 +1,8 @@ -import { DESCRIPTORS, GLOBAL, TYPED_ARRAYS } from '../helpers/constants'; +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.toString', assert => { // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor - for (const name in TYPED_ARRAYS) { - const TypedArray = GLOBAL[name]; + for (const { name, TypedArray } of TYPED_ARRAYS) { const { toString } = TypedArray.prototype; assert.isFunction(toString, `${ name }::toString is function`); assert.arity(toString, 0, `${ name }::toString arity is 0`); diff --git a/tests/unit-global/es.typed-array.with.js b/tests/unit-global/es.typed-array.with.js new file mode 100644 index 000000000000..6eb67bedd206 --- /dev/null +++ b/tests/unit-global/es.typed-array.with.js @@ -0,0 +1,46 @@ +import { createConversionChecker } from '../helpers/helpers.js'; +import { DESCRIPTORS, TYPED_ARRAYS_WITH_BIG_INT } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.with', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray, $ } of TYPED_ARRAYS_WITH_BIG_INT) { + const { with: withAt } = TypedArray.prototype; + + assert.isFunction(withAt, `${ name }::with is function`); + assert.arity(withAt, 2, `${ name }::with arity is 0`); + // assert.name(withAt, 'with', `${ name }::with name is 'with'`); + assert.looksNative(withAt, `${ name }::with looks native`); + + const array = new TypedArray([$(1), $(2), $(3), $(4), $(5)]); + assert.notSame(array.with(2, $(1)), array, 'immutable'); + + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4), $(5)]).with(2, $(6)), new TypedArray([$(1), $(2), $(6), $(4), $(5)])); + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4), $(5)]).with(-2, $(6)), new TypedArray([$(1), $(2), $(3), $(6), $(5)])); + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4), $(5)]).with('1', $(6)), new TypedArray([$(1), $(6), $(3), $(4), $(5)])); + + assert.throws(() => new TypedArray([$(1), $(2), $(3), $(4), $(5)]).with(5, $(6)), RangeError); + assert.throws(() => new TypedArray([$(1), $(2), $(3), $(4), $(5)]).with(-6, $(6)), RangeError); + + assert.throws(() => withAt.call(null, 1, $(2)), TypeError, "isn't generic #1"); + assert.throws(() => withAt.call(undefined, 1, $(2)), TypeError, "isn't generic #2"); + assert.throws(() => withAt.call([1, 2], 1, $(3)), TypeError, "isn't generic #3"); + + const checker = createConversionChecker($(10)); + assert.same(new TypedArray(5).with(2, checker)[2], $(10)); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); + + assert.true(!!function () { + try { + new TypedArray(1).with(2, { valueOf() { throw 8; } }); + } catch (error) { + // some early implementations, like WebKit, does not follow the final semantic + // https://github.com/tc39/proposal-change-array-by-copy/pull/86 + return error === 8; + } + }(), 'proper order of operations'); + + // WebKit doesn't handle this correctly. It should truncate a negative fractional index to zero, but instead throws an error + assert.same(new TypedArray(1).with(-0.5, $(1))[0], $(1)); + } +}); diff --git a/tests/tests/es.typed.conversions.float32.js b/tests/unit-global/es.typed.conversions.float32.js similarity index 81% rename from tests/tests/es.typed.conversions.float32.js rename to tests/unit-global/es.typed.conversions.float32.js index 98e51d880a05..393cf8e40403 100644 --- a/tests/tests/es.typed.conversions.float32.js +++ b/tests/unit-global/es.typed.conversions.float32.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, LITTLE_ENDIAN } from '../helpers/constants'; +import { DESCRIPTORS, LITTLE_ENDIAN, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Float32 conversions', assert => { const float32array = new Float32Array(1); @@ -27,6 +27,7 @@ if (DESCRIPTORS) QUnit.test('Float32 conversions', assert => { [-128, -128, [0, 0, 0, 195]], [255, 255, [0, 0, 127, 67]], [-255, -255, [0, 0, 127, 195]], + // eslint-disable-next-line no-loss-of-precision -- false positive [255.1, 255.10000610351562, [154, 25, 127, 67]], [255.9, 255.89999389648438, [102, 230, 127, 67]], [256, 256, [0, 0, 128, 67]], @@ -48,18 +49,18 @@ if (DESCRIPTORS) QUnit.test('Float32 conversions', assert => { [4294967295, 4294967296, [0, 0, 128, 79]], [4294967296, 4294967296, [0, 0, 128, 79]], [4294967297, 4294967296, [0, 0, 128, 79]], - [9007199254740991, 9007199254740992, [0, 0, 0, 90]], - [-9007199254740991, -9007199254740992, [0, 0, 0, 218]], - [9007199254740992, 9007199254740992, [0, 0, 0, 90]], - [-9007199254740992, -9007199254740992, [0, 0, 0, 218]], - [9007199254740994, 9007199254740992, [0, 0, 0, 90]], - [-9007199254740994, -9007199254740992, [0, 0, 0, 218]], + [MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1, [0, 0, 0, 90]], + [MIN_SAFE_INTEGER, MIN_SAFE_INTEGER - 1, [0, 0, 0, 218]], + [MAX_SAFE_INTEGER + 1, MAX_SAFE_INTEGER + 1, [0, 0, 0, 90]], + [MIN_SAFE_INTEGER - 1, MIN_SAFE_INTEGER - 1, [0, 0, 0, 218]], + [MAX_SAFE_INTEGER + 3, MAX_SAFE_INTEGER + 1, [0, 0, 0, 90]], + [MIN_SAFE_INTEGER - 3, MIN_SAFE_INTEGER - 1, [0, 0, 0, 218]], [Infinity, Infinity, [0, 0, 128, 127]], [-Infinity, -Infinity, [0, 0, 128, 255]], - [1.7976931348623157e+308, Infinity, [0, 0, 128, 127]], - [-1.7976931348623157e+308, -Infinity, [0, 0, 128, 255]], - [5e-324, 0, [0, 0, 0, 0]], - [-5e-324, -0, [0, 0, 0, 128]], + [Number.MAX_VALUE, Infinity, [0, 0, 128, 127]], + [-Number.MAX_VALUE, -Infinity, [0, 0, 128, 255]], + [Number.MIN_VALUE, 0, [0, 0, 0, 0]], + [-Number.MIN_VALUE, -0, [0, 0, 0, 128]], ]; for (const [value, conversion, little] of data) { const big = little.slice().reverse(); diff --git a/tests/tests/es.typed.conversions.float64.js b/tests/unit-global/es.typed.conversions.float64.js similarity index 81% rename from tests/tests/es.typed.conversions.float64.js rename to tests/unit-global/es.typed.conversions.float64.js index 08ecb55b9871..f9ef0ff4fd28 100644 --- a/tests/tests/es.typed.conversions.float64.js +++ b/tests/unit-global/es.typed.conversions.float64.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, LITTLE_ENDIAN } from '../helpers/constants'; +import { DESCRIPTORS, LITTLE_ENDIAN, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Float64 conversions', assert => { const float64array = new Float64Array(1); @@ -48,20 +48,18 @@ if (DESCRIPTORS) QUnit.test('Float64 conversions', assert => { [4294967295, 4294967295, [0, 0, 224, 255, 255, 255, 239, 65]], [4294967296, 4294967296, [0, 0, 0, 0, 0, 0, 240, 65]], [4294967297, 4294967297, [0, 0, 16, 0, 0, 0, 240, 65]], - [9007199254740991, 9007199254740991, [255, 255, 255, 255, 255, 255, 63, 67]], - [-9007199254740991, -9007199254740991, [255, 255, 255, 255, 255, 255, 63, 195]], - [9007199254740992, 9007199254740992, [0, 0, 0, 0, 0, 0, 64, 67]], - [-9007199254740992, -9007199254740992, [0, 0, 0, 0, 0, 0, 64, 195]], - [9007199254740994, 9007199254740994, [1, 0, 0, 0, 0, 0, 64, 67]], - [-9007199254740994, -9007199254740994, [1, 0, 0, 0, 0, 0, 64, 195]], + [MAX_SAFE_INTEGER, MAX_SAFE_INTEGER, [255, 255, 255, 255, 255, 255, 63, 67]], + [MIN_SAFE_INTEGER, MIN_SAFE_INTEGER, [255, 255, 255, 255, 255, 255, 63, 195]], + [MAX_SAFE_INTEGER + 1, MAX_SAFE_INTEGER + 1, [0, 0, 0, 0, 0, 0, 64, 67]], + [MIN_SAFE_INTEGER - 1, MIN_SAFE_INTEGER - 1, [0, 0, 0, 0, 0, 0, 64, 195]], + [MAX_SAFE_INTEGER + 3, MAX_SAFE_INTEGER + 3, [1, 0, 0, 0, 0, 0, 64, 67]], + [MIN_SAFE_INTEGER - 3, MIN_SAFE_INTEGER - 3, [1, 0, 0, 0, 0, 0, 64, 195]], [Infinity, Infinity, [0, 0, 0, 0, 0, 0, 240, 127]], [-Infinity, -Infinity, [0, 0, 0, 0, 0, 0, 240, 255]], - [-1.7976931348623157e+308, -1.7976931348623157e+308, - [255, 255, 255, 255, 255, 255, 239, 255]], - [1.7976931348623157e+308, 1.7976931348623157e+308, - [255, 255, 255, 255, 255, 255, 239, 127]], - [5e-324, 5e-324, [1, 0, 0, 0, 0, 0, 0, 0]], - [-5e-324, -5e-324, [1, 0, 0, 0, 0, 0, 0, 128]], + [-Number.MAX_VALUE, -Number.MAX_VALUE, [255, 255, 255, 255, 255, 255, 239, 255]], + [Number.MAX_VALUE, Number.MAX_VALUE, [255, 255, 255, 255, 255, 255, 239, 127]], + [Number.MIN_VALUE, Number.MIN_VALUE, [1, 0, 0, 0, 0, 0, 0, 0]], + [-Number.MIN_VALUE, -Number.MIN_VALUE, [1, 0, 0, 0, 0, 0, 0, 128]], ]; for (const [value, conversion, little] of data) { const big = little.slice().reverse(); diff --git a/tests/tests/es.typed.conversions.int16.js b/tests/unit-global/es.typed.conversions.int16.js similarity index 83% rename from tests/tests/es.typed.conversions.int16.js rename to tests/unit-global/es.typed.conversions.int16.js index 3989585e7e8c..21809785ba43 100644 --- a/tests/tests/es.typed.conversions.int16.js +++ b/tests/unit-global/es.typed.conversions.int16.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, GLOBAL, LITTLE_ENDIAN, NATIVE } from '../helpers/constants'; +import { DESCRIPTORS, GLOBAL, LITTLE_ENDIAN, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, NATIVE } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Int16 conversions', assert => { const int16array = new Int16Array(1); @@ -12,7 +12,7 @@ if (DESCRIPTORS) QUnit.test('Int16 conversions', assert => { return it === 0 && 1 / it === -Infinity ? '-0' : it; } - let data = [ + const data = [ [0, 0, [0, 0]], [-0, 0, [0, 0]], [1, 1, [1, 0]], @@ -44,28 +44,28 @@ if (DESCRIPTORS) QUnit.test('Int16 conversions', assert => { [2147483648, 0, [0, 0]], [-2147483648, 0, [0, 0]], [4294967296, 0, [0, 0]], - [9007199254740992, 0, [0, 0]], - [-9007199254740992, 0, [0, 0]], + [MAX_SAFE_INTEGER + 1, 0, [0, 0]], + [MIN_SAFE_INTEGER - 1, 0, [0, 0]], [Infinity, 0, [0, 0]], [-Infinity, 0, [0, 0]], - [-1.7976931348623157e+308, 0, [0, 0]], - [1.7976931348623157e+308, 0, [0, 0]], - [5e-324, 0, [0, 0]], - [-5e-324, 0, [0, 0]], + [-Number.MAX_VALUE, 0, [0, 0]], + [Number.MAX_VALUE, 0, [0, 0]], + [Number.MIN_VALUE, 0, [0, 0]], + [-Number.MIN_VALUE, 0, [0, 0]], [NaN, 0, [0, 0]], ]; // Android 4.3- bug if (NATIVE || !/Android [2-4]/.test(GLOBAL.navigator && navigator.userAgent)) { - data = data.concat([ + data.push( [2147483649, 1, [1, 0]], [-2147483649, -1, [255, 255]], [4294967295, -1, [255, 255]], [4294967297, 1, [1, 0]], - [9007199254740991, -1, [255, 255]], - [-9007199254740991, 1, [1, 0]], - [9007199254740994, 2, [2, 0]], - [-9007199254740994, -2, [254, 255]], - ]); + [MAX_SAFE_INTEGER, -1, [255, 255]], + [MIN_SAFE_INTEGER, 1, [1, 0]], + [MAX_SAFE_INTEGER + 3, 2, [2, 0]], + [MIN_SAFE_INTEGER - 3, -2, [254, 255]], + ); } for (const [value, conversion, little] of data) { const big = little.slice().reverse(); diff --git a/tests/tests/es.typed.conversions.int32.js b/tests/unit-global/es.typed.conversions.int32.js similarity index 84% rename from tests/tests/es.typed.conversions.int32.js rename to tests/unit-global/es.typed.conversions.int32.js index 585afb0c2e01..e91f45b039c7 100644 --- a/tests/tests/es.typed.conversions.int32.js +++ b/tests/unit-global/es.typed.conversions.int32.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, LITTLE_ENDIAN } from '../helpers/constants'; +import { DESCRIPTORS, LITTLE_ENDIAN, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Int32 conversions', assert => { const int32array = new Int32Array(1); @@ -48,18 +48,18 @@ if (DESCRIPTORS) QUnit.test('Int32 conversions', assert => { [4294967295, -1, [255, 255, 255, 255]], [4294967296, 0, [0, 0, 0, 0]], [4294967297, 1, [1, 0, 0, 0]], - [9007199254740991, -1, [255, 255, 255, 255]], - [-9007199254740991, 1, [1, 0, 0, 0]], - [9007199254740992, 0, [0, 0, 0, 0]], - [-9007199254740992, 0, [0, 0, 0, 0]], - [9007199254740994, 2, [2, 0, 0, 0]], - [-9007199254740994, -2, [254, 255, 255, 255]], + [MAX_SAFE_INTEGER, -1, [255, 255, 255, 255]], + [MIN_SAFE_INTEGER, 1, [1, 0, 0, 0]], + [MAX_SAFE_INTEGER + 1, 0, [0, 0, 0, 0]], + [MIN_SAFE_INTEGER - 1, 0, [0, 0, 0, 0]], + [MAX_SAFE_INTEGER + 3, 2, [2, 0, 0, 0]], + [MIN_SAFE_INTEGER - 3, -2, [254, 255, 255, 255]], [Infinity, 0, [0, 0, 0, 0]], [-Infinity, 0, [0, 0, 0, 0]], - [-1.7976931348623157e+308, 0, [0, 0, 0, 0]], - [1.7976931348623157e+308, 0, [0, 0, 0, 0]], - [5e-324, 0, [0, 0, 0, 0]], - [-5e-324, 0, [0, 0, 0, 0]], + [-Number.MAX_VALUE, 0, [0, 0, 0, 0]], + [Number.MAX_VALUE, 0, [0, 0, 0, 0]], + [Number.MIN_VALUE, 0, [0, 0, 0, 0]], + [-Number.MIN_VALUE, 0, [0, 0, 0, 0]], [NaN, 0, [0, 0, 0, 0]], ]; for (const [value, conversion, little] of data) { diff --git a/tests/tests/es.typed.conversions.int8.js b/tests/unit-global/es.typed.conversions.int8.js similarity index 79% rename from tests/tests/es.typed.conversions.int8.js rename to tests/unit-global/es.typed.conversions.int8.js index b68084547c6e..8ad1bba83b5f 100644 --- a/tests/tests/es.typed.conversions.int8.js +++ b/tests/unit-global/es.typed.conversions.int8.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, GLOBAL, LITTLE_ENDIAN, NATIVE } from '../helpers/constants'; +import { DESCRIPTORS, GLOBAL, LITTLE_ENDIAN, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, NATIVE } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Int8 conversions', assert => { const int8array = new Int8Array(1); @@ -12,7 +12,7 @@ if (DESCRIPTORS) QUnit.test('Int8 conversions', assert => { return it === 0 && 1 / it === -Infinity ? '-0' : it; } - let data = [ + const data = [ [0, 0, [0]], [-0, 0, [0]], [1, 1, [1]], @@ -44,28 +44,28 @@ if (DESCRIPTORS) QUnit.test('Int8 conversions', assert => { [2147483648, 0, [0]], [-2147483648, 0, [0]], [4294967296, 0, [0]], - [9007199254740992, 0, [0]], - [-9007199254740992, 0, [0]], + [MAX_SAFE_INTEGER + 1, 0, [0]], + [MIN_SAFE_INTEGER - 1, 0, [0]], [Infinity, 0, [0]], [-Infinity, 0, [0]], - [-1.7976931348623157e+308, 0, [0]], - [1.7976931348623157e+308, 0, [0]], - [5e-324, 0, [0]], - [-5e-324, 0, [0]], + [-Number.MAX_VALUE, 0, [0]], + [Number.MAX_VALUE, 0, [0]], + [Number.MIN_VALUE, 0, [0]], + [-Number.MIN_VALUE, 0, [0]], [NaN, 0, [0]], ]; // Android 4.3- bug if (NATIVE || !/Android [2-4]/.test(GLOBAL.navigator && navigator.userAgent)) { - data = data.concat([ + data.push( [2147483649, 1, [1]], [-2147483649, -1, [255]], [4294967295, -1, [255]], [4294967297, 1, [1]], - [9007199254740991, -1, [255]], - [-9007199254740991, 1, [1]], - [9007199254740994, 2, [2]], - [-9007199254740994, -2, [254]], - ]); + [MAX_SAFE_INTEGER, -1, [255]], + [MIN_SAFE_INTEGER, 1, [1]], + [MAX_SAFE_INTEGER + 3, 2, [2]], + [MIN_SAFE_INTEGER - 3, -2, [254]], + ); } for (const [value, conversion, little] of data) { const big = little.slice().reverse(); diff --git a/tests/tests/es.typed.conversions.uint16.js b/tests/unit-global/es.typed.conversions.uint16.js similarity index 83% rename from tests/tests/es.typed.conversions.uint16.js rename to tests/unit-global/es.typed.conversions.uint16.js index 9cb0c4415aec..5de2cd0a85ae 100644 --- a/tests/tests/es.typed.conversions.uint16.js +++ b/tests/unit-global/es.typed.conversions.uint16.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, GLOBAL, LITTLE_ENDIAN, NATIVE } from '../helpers/constants'; +import { DESCRIPTORS, GLOBAL, LITTLE_ENDIAN, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, NATIVE } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Uint16 conversions', assert => { const uint16array = new Uint16Array(1); @@ -12,7 +12,7 @@ if (DESCRIPTORS) QUnit.test('Uint16 conversions', assert => { return it === 0 && 1 / it === -Infinity ? '-0' : it; } - let data = [ + const data = [ [0, 0, [0, 0]], [-0, 0, [0, 0]], [1, 1, [1, 0]], @@ -44,28 +44,28 @@ if (DESCRIPTORS) QUnit.test('Uint16 conversions', assert => { [2147483648, 0, [0, 0]], [-2147483648, 0, [0, 0]], [4294967296, 0, [0, 0]], - [9007199254740992, 0, [0, 0]], - [-9007199254740992, 0, [0, 0]], + [MAX_SAFE_INTEGER + 1, 0, [0, 0]], + [MIN_SAFE_INTEGER - 1, 0, [0, 0]], [Infinity, 0, [0, 0]], [-Infinity, 0, [0, 0]], - [-1.7976931348623157e+308, 0, [0, 0]], - [1.7976931348623157e+308, 0, [0, 0]], - [5e-324, 0, [0, 0]], - [-5e-324, 0, [0, 0]], + [-Number.MAX_VALUE, 0, [0, 0]], + [Number.MAX_VALUE, 0, [0, 0]], + [Number.MIN_VALUE, 0, [0, 0]], + [-Number.MIN_VALUE, 0, [0, 0]], [NaN, 0, [0, 0]], ]; // Android 4.3- bug if (NATIVE || !/Android [2-4]/.test(GLOBAL.navigator && navigator.userAgent)) { - data = data.concat([ + data.push( [2147483649, 1, [1, 0]], [-2147483649, 65535, [255, 255]], [4294967295, 65535, [255, 255]], [4294967297, 1, [1, 0]], - [9007199254740991, 65535, [255, 255]], - [-9007199254740991, 1, [1, 0]], - [9007199254740994, 2, [2, 0]], - [-9007199254740994, 65534, [254, 255]], - ]); + [MAX_SAFE_INTEGER, 65535, [255, 255]], + [MIN_SAFE_INTEGER, 1, [1, 0]], + [MAX_SAFE_INTEGER + 3, 2, [2, 0]], + [MIN_SAFE_INTEGER - 3, 65534, [254, 255]], + ); } for (const [value, conversion, little] of data) { const big = little.slice().reverse(); diff --git a/tests/tests/es.typed.conversions.uint32.js b/tests/unit-global/es.typed.conversions.uint32.js similarity index 84% rename from tests/tests/es.typed.conversions.uint32.js rename to tests/unit-global/es.typed.conversions.uint32.js index c511d72219f0..994be27dc290 100644 --- a/tests/tests/es.typed.conversions.uint32.js +++ b/tests/unit-global/es.typed.conversions.uint32.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, LITTLE_ENDIAN } from '../helpers/constants'; +import { DESCRIPTORS, LITTLE_ENDIAN, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Uint32 conversions', assert => { const uint32array = new Uint32Array(1); @@ -48,17 +48,17 @@ if (DESCRIPTORS) QUnit.test('Uint32 conversions', assert => { [4294967295, 4294967295, [255, 255, 255, 255]], [4294967296, 0, [0, 0, 0, 0]], [4294967297, 1, [1, 0, 0, 0]], - [9007199254740991, 4294967295, [255, 255, 255, 255]], - [-9007199254740991, 1, [1, 0, 0, 0]], - [9007199254740992, 0, [0, 0, 0, 0]], - [-9007199254740992, 0, [0, 0, 0, 0]], - [9007199254740994, 2, [2, 0, 0, 0]], - [-9007199254740994, 4294967294, [254, 255, 255, 255]], + [MAX_SAFE_INTEGER, 4294967295, [255, 255, 255, 255]], + [MIN_SAFE_INTEGER, 1, [1, 0, 0, 0]], + [MAX_SAFE_INTEGER + 1, 0, [0, 0, 0, 0]], + [MIN_SAFE_INTEGER - 1, 0, [0, 0, 0, 0]], + [MAX_SAFE_INTEGER + 3, 2, [2, 0, 0, 0]], + [MIN_SAFE_INTEGER - 3, 4294967294, [254, 255, 255, 255]], [Infinity, 0, [0, 0, 0, 0]], [-Infinity, 0, [0, 0, 0, 0]], - [-1.7976931348623157e+308, 0, [0, 0, 0, 0]], - [1.7976931348623157e+308, 0, [0, 0, 0, 0]], - [5e-324, 0, [0, 0, 0, 0]], - [-5e-324, 0, [0, 0, 0, 0]], + [-Number.MAX_VALUE, 0, [0, 0, 0, 0]], + [Number.MAX_VALUE, 0, [0, 0, 0, 0]], + [Number.MIN_VALUE, 0, [0, 0, 0, 0]], + [-Number.MIN_VALUE, 0, [0, 0, 0, 0]], [NaN, 0, [0, 0, 0, 0]], ]; for (const [value, conversion, little] of data) { diff --git a/tests/tests/es.typed.conversions.uint8-clamped.js b/tests/unit-global/es.typed.conversions.uint8-clamped.js similarity index 77% rename from tests/tests/es.typed.conversions.uint8-clamped.js rename to tests/unit-global/es.typed.conversions.uint8-clamped.js index c41ef15a8723..ec265644a332 100644 --- a/tests/tests/es.typed.conversions.uint8-clamped.js +++ b/tests/unit-global/es.typed.conversions.uint8-clamped.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS } from '../helpers/constants'; +import { DESCRIPTORS, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Uint8Clamped conversions', assert => { const uint8clamped = new Uint8ClampedArray(1); @@ -44,18 +44,18 @@ if (DESCRIPTORS) QUnit.test('Uint8Clamped conversions', assert => { [4294967295, 255, [255]], [4294967296, 255, [255]], [4294967297, 255, [255]], - [9007199254740991, 255, [255]], - [-9007199254740991, 0, [0]], - [9007199254740992, 255, [255]], - [-9007199254740992, 0, [0]], - [9007199254740994, 255, [255]], - [-9007199254740994, 0, [0]], + [MAX_SAFE_INTEGER, 255, [255]], + [MIN_SAFE_INTEGER, 0, [0]], + [MAX_SAFE_INTEGER + 1, 255, [255]], + [MIN_SAFE_INTEGER - 1, 0, [0]], + [MAX_SAFE_INTEGER + 3, 255, [255]], + [MIN_SAFE_INTEGER - 3, 0, [0]], [Infinity, 255, [255]], [-Infinity, 0, [0]], - [-1.7976931348623157e+308, 0, [0]], - [1.7976931348623157e+308, 255, [255]], - [5e-324, 0, [0]], - [-5e-324, 0, [0]], + [-Number.MAX_VALUE, 0, [0]], + [Number.MAX_VALUE, 255, [255]], + [Number.MIN_VALUE, 0, [0]], + [-Number.MIN_VALUE, 0, [0]], [NaN, 0, [0]], ]; for (const [value, conversion, little] of data) { diff --git a/tests/tests/es.typed.conversions.uint8.js b/tests/unit-global/es.typed.conversions.uint8.js similarity index 79% rename from tests/tests/es.typed.conversions.uint8.js rename to tests/unit-global/es.typed.conversions.uint8.js index c4e5e7204442..eb6a548be106 100644 --- a/tests/tests/es.typed.conversions.uint8.js +++ b/tests/unit-global/es.typed.conversions.uint8.js @@ -1,4 +1,4 @@ -import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants'; +import { DESCRIPTORS, GLOBAL, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, NATIVE } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Uint8 conversions', assert => { const uint8array = new Uint8Array(1); @@ -11,7 +11,7 @@ if (DESCRIPTORS) QUnit.test('Uint8 conversions', assert => { return it === 0 && 1 / it === -Infinity ? '-0' : it; } - let data = [ + const data = [ [0, 0, [0]], [-0, 0, [0]], [1, 1, [1]], @@ -43,27 +43,27 @@ if (DESCRIPTORS) QUnit.test('Uint8 conversions', assert => { [2147483648, 0, [0]], [-2147483648, 0, [0]], [4294967296, 0, [0]], - [9007199254740992, 0, [0]], - [-9007199254740992, 0, [0]], + [MAX_SAFE_INTEGER + 1, 0, [0]], + [MIN_SAFE_INTEGER - 1, 0, [0]], [Infinity, 0, [0]], [-Infinity, 0, [0]], - [-1.7976931348623157e+308, 0, [0]], - [1.7976931348623157e+308, 0, [0]], - [5e-324, 0, [0]], - [-5e-324, 0, [0]], + [-Number.MAX_VALUE, 0, [0]], + [Number.MAX_VALUE, 0, [0]], + [Number.MIN_VALUE, 0, [0]], + [-Number.MIN_VALUE, 0, [0]], [NaN, 0, [0]], ]; // Android 4.3- bug if (NATIVE || !/Android [2-4]/.test(GLOBAL.navigator && navigator.userAgent)) { - data = data.concat([ + data.push( [2147483649, 1, [1]], [-2147483649, 255, [255]], [4294967295, 255, [255]], [4294967297, 1, [1]], - [9007199254740991, 255, [255]], - [-9007199254740991, 1, [1]], - [9007199254740994, 2, [2]], - [-9007199254740994, 254, [254]], - ]); + [MAX_SAFE_INTEGER, 255, [255]], + [MIN_SAFE_INTEGER, 1, [1]], + [MAX_SAFE_INTEGER + 3, 2, [2]], + [MIN_SAFE_INTEGER - 3, 254, [254]], + ); } for (const [value, conversion, little] of data) { uint8array[0] = value; diff --git a/tests/unit-global/es.uint8-array.from-base64.js b/tests/unit-global/es.uint8-array.from-base64.js new file mode 100644 index 000000000000..1d03588caaa8 --- /dev/null +++ b/tests/unit-global/es.uint8-array.from-base64.js @@ -0,0 +1,155 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('Uint8Array.fromBase64', assert => { + const { fromBase64 } = Uint8Array; + assert.isFunction(fromBase64); + assert.arity(fromBase64, 1); + assert.name(fromBase64, 'fromBase64'); + assert.looksNative(fromBase64); + + const array = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); + + assert.true(fromBase64('SGVsbG8gV29ybGQ=') instanceof Uint8Array, 'returns Uint8Array instance #1'); + assert.true(fromBase64.call(Int16Array, 'SGVsbG8gV29ybGQ=') instanceof Uint8Array, 'returns Uint8Array instance #2'); + + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ='), array, 'proper result'); + + assert.deepEqual(fromBase64('12/3'), new Uint8Array([215, 111, 247]), 'encoding #1'); + assert.throws(() => fromBase64('12_3'), SyntaxError, 'encoding #2'); + assert.deepEqual(fromBase64('12+3'), new Uint8Array([215, 111, 183]), 'encoding #3'); + assert.throws(() => fromBase64('12-3'), SyntaxError, 'encoding #4'); + assert.deepEqual(fromBase64('12/3', { alphabet: 'base64' }), new Uint8Array([215, 111, 247]), 'encoding #5'); + assert.throws(() => fromBase64('12_3', { alphabet: 'base64' }), SyntaxError, 'encoding #6'); + assert.deepEqual(fromBase64('12+3', { alphabet: 'base64' }), new Uint8Array([215, 111, 183]), 'encoding #7'); + assert.throws(() => fromBase64('12-3', { alphabet: 'base64' }), SyntaxError, 'encoding #8'); + assert.deepEqual(fromBase64('12_3', { alphabet: 'base64url' }), new Uint8Array([215, 111, 247]), 'encoding #9'); + assert.throws(() => fromBase64('12/3', { alphabet: 'base64url' }), SyntaxError, 'encoding #10'); + assert.deepEqual(fromBase64('12-3', { alphabet: 'base64url' }), new Uint8Array([215, 111, 183]), 'encoding #11'); + assert.throws(() => fromBase64('12+3', { alphabet: 'base64url' }), SyntaxError, 'encoding #12'); + + assert.throws(() => fromBase64(null), TypeError, "isn't generic #1"); + assert.throws(() => fromBase64(undefined), TypeError, "isn't generic #2"); + assert.throws(() => fromBase64(1234), TypeError, "isn't generic #3"); + assert.throws(() => fromBase64(Object('SGVsbG8gV29ybGQ=')), TypeError, "isn't generic #4"); + assert.throws(() => fromBase64('SGVsbG8gV29ybG%='), SyntaxError, 'throws on invalid #1'); + assert.throws(() => fromBase64('SGVsbG8gV29ybGQ1='), SyntaxError, 'throws on invalid #2'); + assert.throws(() => fromBase64('SGVsbG8gV29ybGQ1=', null), TypeError, 'incorrect options argument #1'); + assert.throws(() => fromBase64('SGVsbG8gV29ybGQ1=', 1), TypeError, 'incorrect options argument #2'); + assert.throws(() => fromBase64('SGVsbG8gV29ybGQ1=', { alphabet: 'base32' }), TypeError, 'incorrect encoding'); + assert.throws(() => fromBase64('SGVsbG8gV29ybGQ1=', { lastChunkHandling: 'fff' }), TypeError, 'incorrect lastChunkHandling'); + + assert.deepEqual(fromBase64('BBB'), new Uint8Array([4, 16]), 'ending #1'); + assert.deepEqual(fromBase64('BBB', { lastChunkHandling: 'loose' }), new Uint8Array([4, 16]), 'ending #2'); + assert.deepEqual(fromBase64('BBB', { lastChunkHandling: 'stop-before-partial' }), new Uint8Array([]), 'ending #3'); + assert.throws(() => fromBase64('BBB', { lastChunkHandling: 'strict' }), SyntaxError, 'ending #4'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ'), array, 'ending #5'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ', { lastChunkHandling: 'loose' }), array, 'ending #6'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ', { lastChunkHandling: 'stop-before-partial' }), array.slice(0, -2), 'ending #7'); + assert.throws(() => fromBase64('SGVsbG8gV29ybGQ', { lastChunkHandling: 'strict' }), SyntaxError, 'ending #8'); + + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ= '), array, 'spaces #1'); + assert.deepEqual(fromBase64('SGVsbG8gV2 9ybGQ='), array, 'spaces #2'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ=\n'), array, 'spaces #3'); + assert.deepEqual(fromBase64('SGVsbG8gV2\n9ybGQ='), array, 'spaces #4'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ= ', { lastChunkHandling: 'loose' }), array, 'spaces #5'); + assert.deepEqual(fromBase64('SGVsbG8gV2 9ybGQ=', { lastChunkHandling: 'loose' }), array, 'spaces #6'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ=\n', { lastChunkHandling: 'loose' }), array, 'spaces #7'); + assert.deepEqual(fromBase64('SGVsbG8gV2\n9ybGQ=', { lastChunkHandling: 'loose' }), array, 'spaces #8'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ= ', { lastChunkHandling: 'stop-before-partial' }), array, 'spaces #9'); + assert.deepEqual(fromBase64('SGVsbG8gV2 9ybGQ=', { lastChunkHandling: 'stop-before-partial' }), array, 'spaces #10'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ=\n', { lastChunkHandling: 'stop-before-partial' }), array, 'spaces #11'); + assert.deepEqual(fromBase64('SGVsbG8gV2\n9ybGQ=', { lastChunkHandling: 'stop-before-partial' }), array, 'spaces #12'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ= ', { lastChunkHandling: 'strict' }), array, 'spaces #13'); + assert.deepEqual(fromBase64('SGVsbG8gV2 9ybGQ=', { lastChunkHandling: 'strict' }), array, 'spaces #14'); + assert.deepEqual(fromBase64('SGVsbG8gV29ybGQ=\n', { lastChunkHandling: 'strict' }), array, 'spaces #15'); + assert.deepEqual(fromBase64('SGVsbG8gV2\n9ybGQ=', { lastChunkHandling: 'strict' }), array, 'spaces #16'); + + // Test262 + // Copyright 2024 Kevin Gibbons. All rights reserved. + // This code is governed by the BSD license found in the https://github.com/tc39/test262/blob/main/LICENSE file. + assert.arrayEqual(Uint8Array.fromBase64('x+/y'), [199, 239, 242]); + assert.arrayEqual(Uint8Array.fromBase64('x+/y', { alphabet: 'base64' }), [199, 239, 242]); + assert.throws(() => Uint8Array.fromBase64('x+/y', { alphabet: 'base64url' }), SyntaxError); + assert.arrayEqual(Uint8Array.fromBase64('x-_y', { alphabet: 'base64url' }), [199, 239, 242]); + assert.throws(() => Uint8Array.fromBase64('x-_y'), SyntaxError); + assert.throws(() => Uint8Array.fromBase64('x-_y', { alphabet: 'base64' }), SyntaxError); + + [ + 'Zm.9v', + 'Zm9v^', + 'Zg==&', + 'Z−==', // U+2212 'Minus Sign' + 'Z+==', // U+FF0B 'Fullwidth Plus Sign' + 'Zg\u00A0==', // nbsp + 'Zg\u2009==', // thin space + 'Zg\u2028==', // line separator + ].forEach(value => assert.throws(() => Uint8Array.fromBase64(value), SyntaxError)); + + // padding + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZg=='), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZg==', { lastChunkHandling: 'strict' }), [101, 120, 97, 102]); + + // no padding + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZg'), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]); + assert.throws(() => Uint8Array.fromBase64('ZXhhZg', { lastChunkHandling: 'strict' }), SyntaxError); + + // non-zero padding bits + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZh=='), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97, 102]); + assert.throws(() => Uint8Array.fromBase64('ZXhhZh==', { lastChunkHandling: 'strict' }), SyntaxError); + + // non-zero padding bits, no padding + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZh'), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'loose' }), [101, 120, 97, 102]); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]); + assert.throws(() => Uint8Array.fromBase64('ZXhhZh', { lastChunkHandling: 'strict' }), SyntaxError); + + // partial padding + assert.throws(() => Uint8Array.fromBase64('ZXhhZg='), SyntaxError); + assert.throws(() => Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'loose' }), SyntaxError); + assert.arrayEqual(Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'stop-before-partial' }), [101, 120, 97]); + assert.throws(() => Uint8Array.fromBase64('ZXhhZg=', { lastChunkHandling: 'strict' }), SyntaxError); + + // excess padding + assert.throws(() => Uint8Array.fromBase64('ZXhhZg==='), SyntaxError); + assert.throws(() => Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'loose' }), SyntaxError); + assert.throws(() => Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'stop-before-partial' }), SyntaxError); + assert.throws(() => Uint8Array.fromBase64('ZXhhZg===', { lastChunkHandling: 'strict' }), SyntaxError); + + // standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 + [ + ['', []], + ['Zg==', [102]], + ['Zm8=', [102, 111]], + ['Zm9v', [102, 111, 111]], + ['Zm9vYg==', [102, 111, 111, 98]], + ['Zm9vYmE=', [102, 111, 111, 98, 97]], + ['Zm9vYmFy', [102, 111, 111, 98, 97, 114]], + ].forEach(([string, bytes]) => { + const result = Uint8Array.fromBase64(string); + assert.same(Object.getPrototypeOf(result), Uint8Array.prototype, `decoding ${ string }`); + assert.same(result.length, bytes.length, `decoding ${ string }`); + assert.same(result.buffer.byteLength, bytes.length, `decoding ${ string }`); + assert.arrayEqual(result, bytes, `decoding ${ string }`); + }); + + [ + ['Z g==', 'space'], + ['Z\tg==', 'tab'], + ['Z\u000Ag==', 'LF'], + ['Z\u000Cg==', 'FF'], + ['Z\u000Dg==', 'CR'], + ].forEach(([string, name]) => { + const arr = Uint8Array.fromBase64(string); + assert.same(arr.length, 1); + assert.same(arr.buffer.byteLength, 1); + assert.arrayEqual(arr, [102], `ascii whitespace: ${ name }`); + }); + + assert.throws(() => Uint8Array.fromBase64('a'), SyntaxError, 'throws error on incorrect length of base64 string'); +}); diff --git a/tests/unit-global/es.uint8-array.from-hex.js b/tests/unit-global/es.uint8-array.from-hex.js new file mode 100644 index 000000000000..609d264141e4 --- /dev/null +++ b/tests/unit-global/es.uint8-array.from-hex.js @@ -0,0 +1,59 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('Uint8Array.fromHex', assert => { + const { fromHex } = Uint8Array; + assert.isFunction(fromHex); + assert.arity(fromHex, 1); + assert.name(fromHex, 'fromHex'); + assert.looksNative(fromHex); + + assert.true(fromHex('48656c6c6f20576f726c64') instanceof Uint8Array, 'returns Uint8Array instance #1'); + assert.true(fromHex.call(Int16Array, '48656c6c6f20576f726c64') instanceof Uint8Array, 'returns Uint8Array instance #2'); + + assert.deepEqual(fromHex('48656c6c6f20576f726c64'), new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]), 'proper result'); + + assert.throws(() => fromHex(null), TypeError, "isn't generic #1"); + assert.throws(() => fromHex(undefined), TypeError, "isn't generic #2"); + assert.throws(() => fromHex(1234), TypeError, "isn't generic #3"); + assert.throws(() => fromHex(Object('48656c6c6f20576f726c64')), TypeError, "isn't generic #4"); + assert.throws(() => fromHex('4865gc6c6f20576f726c64'), SyntaxError, 'throws on invalid #1'); + assert.throws(() => fromHex('48656c6c6f20576f726c641'), SyntaxError, 'throws on invalid #2'); + assert.throws(() => fromHex('48656c6c6f20576f726c64 '), SyntaxError, 'throws on invalid #3'); + assert.throws(() => fromHex('48656c6c6f20576f726c64\n'), SyntaxError, 'throws on invalid #4'); + + // Test262 + // Copyright 2024 Kevin Gibbons. All rights reserved. + // This code is governed by the BSD license found in the https://github.com/tc39/test262/blob/main/LICENSE file. + [ + 'a.a', + 'aa^', + 'a a', + 'a\ta', + 'a\u000Aa', + 'a\u000Ca', + 'a\u000Da', + 'a\u00A0a', // nbsp + 'a\u2009a', // thin space + 'a\u2028a', // line separator + ].forEach(value => assert.throws(() => Uint8Array.fromHex(value), SyntaxError)); + + assert.throws(() => Uint8Array.fromHex('a'), SyntaxError); + + [ + ['', []], + ['66', [102]], + ['666f', [102, 111]], + ['666F', [102, 111]], + ['666f6f', [102, 111, 111]], + ['666F6f', [102, 111, 111]], + ['666f6f62', [102, 111, 111, 98]], + ['666f6f6261', [102, 111, 111, 98, 97]], + ['666f6f626172', [102, 111, 111, 98, 97, 114]], + ].forEach(([string, bytes]) => { + const arr = Uint8Array.fromHex(string); + assert.same(Object.getPrototypeOf(arr), Uint8Array.prototype, `decoding ${ string }`); + assert.same(arr.length, bytes.length, `decoding ${ string }`); + assert.same(arr.buffer.byteLength, bytes.length, `decoding ${ string }`); + assert.arrayEqual(arr, bytes, `decoding ${ string }`); + }); +}); diff --git a/tests/unit-global/es.uint8-array.set-from-base64.js b/tests/unit-global/es.uint8-array.set-from-base64.js new file mode 100644 index 000000000000..e00c03bcdc7f --- /dev/null +++ b/tests/unit-global/es.uint8-array.set-from-base64.js @@ -0,0 +1,292 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('Uint8Array.prototype.setFromBase64', assert => { + const { setFromBase64 } = Uint8Array.prototype; + assert.isFunction(setFromBase64); + assert.arity(setFromBase64, 1); + assert.name(setFromBase64, 'setFromBase64'); + assert.looksNative(setFromBase64); + + const template = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0, 0, 0, 0, 0]); + + const array1 = new Uint8Array(16); + const result1 = array1.setFromBase64('SGVsbG8gV29ybGQ='); + + assert.deepEqual(array1, template, 'proper result array #1'); + assert.deepEqual(result1, { read: 16, written: 11 }, 'proper result #1'); + + assert.throws(() => setFromBase64.call(Array(16), 'SGVsbG8gV29ybGQ='), TypeError, "isn't generic, this #1"); + assert.throws(() => setFromBase64.call(new Int8Array(16), 'SGVsbG8gV29ybGQ='), TypeError, "isn't generic, this #2"); + assert.throws(() => new Uint8Array(16).setFromBase64(null), TypeError, "isn't generic, arg #1"); + assert.throws(() => new Uint8Array(16).setFromBase64(undefined), TypeError, "isn't generic, arg #2"); + assert.throws(() => new Uint8Array(16).setFromBase64(1234), TypeError, "isn't generic, arg #3"); + assert.throws(() => new Uint8Array(16).setFromBase64(Object('SGVsbG8gV29ybGQ=')), TypeError, "isn't generic, arg #4"); + assert.throws(() => new Uint8Array(16).setFromBase64('^'), SyntaxError, 'throws on invalid #1'); + assert.throws(() => new Uint8Array(16).setFromBase64('SGVsbG8gV29ybGQ=', null), TypeError, 'incorrect options argument #1'); + assert.throws(() => new Uint8Array(16).setFromBase64('SGVsbG8gV29ybGQ=', 1), TypeError, 'incorrect options argument #2'); + assert.throws(() => new Uint8Array(16).setFromBase64('SGVsbG8gV29ybGQ=', { alphabet: 'base32' }), TypeError, 'incorrect encoding'); + assert.throws(() => new Uint8Array(16).setFromBase64('SGVsbG8gV29ybGQ=', { lastChunkHandling: 'fff' }), TypeError, 'incorrect lastChunkHandling'); + + if (ArrayBuffer.prototype.transfer) { + const array = new Uint8Array(16); + array.buffer.transfer(); + + assert.throws(() => array.setFromHex('SGVsbG8gV29ybGQ='), TypeError, 'detached'); + } + + // Test262 + // Copyright 2024 Kevin Gibbons. All rights reserved. + // This code is governed by the BSD license found in the https://github.com/tc39/test262/blob/main/LICENSE file. + let target = new Uint8Array([255, 255, 255, 255]); + let result = target.setFromBase64('x+/y'); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [199, 239, 242, 255]); + + target = new Uint8Array([255, 255, 255, 255]); + result = target.setFromBase64('x+/y', { alphabet: 'base64' }); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [199, 239, 242, 255]); + + assert.throws(() => new Uint8Array([255, 255, 255, 255]).setFromBase64('x+/y', { alphabet: 'base64url' }), SyntaxError); + + target = new Uint8Array([255, 255, 255, 255]); + result = target.setFromBase64('x-_y', { alphabet: 'base64url' }); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [199, 239, 242, 255]); + + assert.throws(() => new Uint8Array([255, 255, 255, 255]).setFromBase64('x-_y'), SyntaxError); + assert.throws(() => new Uint8Array([255, 255, 255, 255]).setFromBase64('x-_y', { alphabet: 'base64' }), SyntaxError); + + [ + 'Zm.9v', + 'Zm9v^', + 'Zg==&', + 'Z−==', // U+2212 'Minus Sign' + 'Z+==', // U+FF0B 'Fullwidth Plus Sign' + 'Zg\u00A0==', // nbsp + 'Zg\u2009==', // thin space + 'Zg\u2028==', // line separator + ].forEach(value => assert.throws(() => new Uint8Array([255, 255, 255, 255, 255]).setFromBase64(value), SyntaxError)); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZg=='); + assert.same(result.read, 8); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'loose' }); + assert.same(result.read, 8); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'stop-before-partial' }); + assert.same(result.read, 8); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZg==', { lastChunkHandling: 'strict' }); + assert.same(result.read, 8); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + // no padding + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZg'); + assert.same(result.read, 6); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZg', { lastChunkHandling: 'loose' }); + assert.same(result.read, 6); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZg', { lastChunkHandling: 'stop-before-partial' }); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [101, 120, 97, 255, 255, 255]); + + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZg', { lastChunkHandling: 'strict' }), SyntaxError); + + // non-zero padding bits + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZh=='); + assert.same(result.read, 8); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZh==', { lastChunkHandling: 'loose' }); + assert.same(result.read, 8); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZh==', { lastChunkHandling: 'stop-before-partial' }); + assert.same(result.read, 8); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZh==', { lastChunkHandling: 'strict' }), SyntaxError); + + // non-zero padding bits, no padding + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZh'); + assert.same(result.read, 6); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZh', { lastChunkHandling: 'loose' }); + assert.same(result.read, 6); + assert.same(result.written, 4); + assert.arrayEqual(target, [101, 120, 97, 102, 255, 255]); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZh', { lastChunkHandling: 'stop-before-partial' }); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [101, 120, 97, 255, 255, 255]); + + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZh', { lastChunkHandling: 'strict' }), SyntaxError); + + // partial padding + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZg='), SyntaxError); + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZg=', { lastChunkHandling: 'loose' }), SyntaxError); + + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('ZXhhZg=', { lastChunkHandling: 'stop-before-partial' }); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [101, 120, 97, 255, 255, 255]); + + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZg=', { lastChunkHandling: 'strict' }), SyntaxError); + + // excess padding + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZg==='), SyntaxError); + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZg===', { lastChunkHandling: 'loose' }), SyntaxError); + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZg===', { lastChunkHandling: 'stop-before-partial' }), SyntaxError); + assert.throws(() => new Uint8Array([255, 255, 255, 255, 255, 255]).setFromBase64('ZXhhZg===', { lastChunkHandling: 'strict' }), SyntaxError); + + // standard test vectors from https://datatracker.ietf.org/doc/html/rfc4648#section-10 + [ + ['', []], + ['Zg==', [102]], + ['Zm8=', [102, 111]], + ['Zm9v', [102, 111, 111]], + ['Zm9vYg==', [102, 111, 111, 98]], + ['Zm9vYmE=', [102, 111, 111, 98, 97]], + ['Zm9vYmFy', [102, 111, 111, 98, 97, 114]], + ].forEach(([string, bytes]) => { + const allFF = [255, 255, 255, 255, 255, 255, 255, 255]; + target = new Uint8Array(allFF); + result = target.setFromBase64(string); + assert.same(result.read, string.length); + assert.same(result.written, bytes.length); + + const expected = bytes.concat(allFF.slice(bytes.length)); + assert.arrayEqual(target, expected, `decoding ${ string }`); + }); + + const base = new Uint8Array([255, 255, 255, 255, 255, 255, 255]); + const subarray = base.subarray(2, 5); + + result = subarray.setFromBase64('Zm9vYmFy'); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(subarray, [102, 111, 111]); + assert.arrayEqual(base, [255, 255, 102, 111, 111, 255, 255]); + + // buffer too small + target = new Uint8Array([255, 255, 255, 255, 255]); + result = target.setFromBase64('Zm9vYmFy'); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [102, 111, 111, 255, 255]); + + // buffer too small, padded + target = new Uint8Array([255, 255, 255, 255]); + result = target.setFromBase64('Zm9vYmE='); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [102, 111, 111, 255]); + + // buffer exact + target = new Uint8Array([255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('Zm9vYmFy'); + assert.same(result.read, 8); + assert.same(result.written, 6); + assert.arrayEqual(target, [102, 111, 111, 98, 97, 114]); + + // buffer exact, padded + target = new Uint8Array([255, 255, 255, 255, 255]); + result = target.setFromBase64('Zm9vYmE='); + assert.same(result.read, 8); + assert.same(result.written, 5); + assert.arrayEqual(target, [102, 111, 111, 98, 97]); + + // buffer exact, not padded + target = new Uint8Array([255, 255, 255, 255, 255]); + result = target.setFromBase64('Zm9vYmE'); + assert.same(result.read, 7); + assert.same(result.written, 5); + assert.arrayEqual(target, [102, 111, 111, 98, 97]); + + // buffer exact, padded, stop-before-partial + target = new Uint8Array([255, 255, 255, 255, 255]); + result = target.setFromBase64('Zm9vYmE=', { lastChunkHandling: 'stop-before-partial' }); + assert.same(result.read, 8); + assert.same(result.written, 5); + assert.arrayEqual(target, [102, 111, 111, 98, 97]); + + // buffer exact, not padded, stop-before-partial + target = new Uint8Array([255, 255, 255, 255, 255]); + result = target.setFromBase64('Zm9vYmE', { lastChunkHandling: 'stop-before-partial' }); + assert.same(result.read, 4); + assert.same(result.written, 3); + assert.arrayEqual(target, [102, 111, 111, 255, 255]); + + // buffer too large + target = new Uint8Array([255, 255, 255, 255, 255, 255, 255]); + result = target.setFromBase64('Zm9vYmFy'); + assert.same(result.read, 8); + assert.same(result.written, 6); + assert.arrayEqual(target, [102, 111, 111, 98, 97, 114, 255]); + + [ + ['Z g==', 'space'], + ['Z\tg==', 'tab'], + ['Z\u000Ag==', 'LF'], + ['Z\u000Cg==', 'FF'], + ['Z\u000Dg==', 'CR'], + ].forEach(([string, name]) => { + target = new Uint8Array([255, 255, 255]); + result = target.setFromBase64(string); + assert.same(result.read, 5); + assert.same(result.written, 1); + assert.arrayEqual(target, [102, 255, 255], `ascii whitespace: ${ name }`); + }); + + target = new Uint8Array([255, 255, 255, 255, 255]); + assert.throws(() => target.setFromBase64('MjYyZm.9v'), SyntaxError, 'illegal character in second chunk'); + assert.arrayEqual(target, [50, 54, 50, 255, 255], 'decoding from MjYyZm.9v should only write the valid chunks'); + + target = new Uint8Array([255, 255, 255, 255, 255]); + assert.throws(() => target.setFromBase64('MjYyZg', { lastChunkHandling: 'strict' }), SyntaxError, 'padding omitted with lastChunkHandling: strict'); + assert.arrayEqual(target, [50, 54, 50, 255, 255], 'decoding from MjYyZg should only write the valid chunks'); + + target = new Uint8Array([255, 255, 255, 255, 255]); + assert.throws(() => target.setFromBase64('MjYyZg==='), SyntaxError, 'extra characters after padding'); + assert.arrayEqual(target, [50, 54, 50, 255, 255], 'decoding from MjYyZg=== should not write the last chunk because it has extra padding'); + + target = new Uint8Array([255, 255, 255, 255, 255]); + assert.throws(() => target.setFromBase64('a'), SyntaxError, 'throws error on incorrect length of base64 string'); +}); diff --git a/tests/unit-global/es.uint8-array.set-from-hex.js b/tests/unit-global/es.uint8-array.set-from-hex.js new file mode 100644 index 000000000000..0cdc33816f0f --- /dev/null +++ b/tests/unit-global/es.uint8-array.set-from-hex.js @@ -0,0 +1,129 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('Uint8Array.prototype.setFromHex', assert => { + const { setFromHex } = Uint8Array.prototype; + assert.isFunction(setFromHex); + assert.arity(setFromHex, 1); + assert.name(setFromHex, 'setFromHex'); + assert.looksNative(setFromHex); + + const array1 = new Uint8Array(11); + const result1 = array1.setFromHex('48656c6c6f20576f726c64'); + + assert.deepEqual(array1, new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]), 'array #1'); + assert.deepEqual(result1, { read: 22, written: 11 }, 'result #1'); + + const array2 = new Uint8Array(10); + const result2 = array2.setFromHex('48656c6c6f20576f726c64'); + + assert.deepEqual(array2, new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108]), 'array #2'); + assert.deepEqual(result2, { read: 20, written: 10 }, 'result #2'); + + const array3 = new Uint8Array(12); + const result3 = array3.setFromHex('48656c6c6f20576f726c64'); + + assert.deepEqual(array3, new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 0]), 'array #3'); + assert.deepEqual(result3, { read: 22, written: 11 }, 'result #3'); + + const array4 = new Uint8Array(11); + + assert.throws(() => array4.setFromHex('4865gc6c6f20576f726c64'), SyntaxError, 'throws on invalid #1'); + assert.deepEqual(array4, new Uint8Array([72, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 'array #4'); + + if (ArrayBuffer.prototype.transfer) { + const array5 = new Uint8Array(11); + array5.buffer.transfer(); + + assert.throws(() => array5.setFromHex('48656c6c6f20576f726c64'), TypeError, 'detached'); + } + + assert.throws(() => setFromHex.call(Array(11), '48656c6c6f20576f726c64'), TypeError, "isn't generic, this #1"); + assert.throws(() => setFromHex.call(new Int8Array(11), '48656c6c6f20576f726c64'), TypeError, "isn't generic, this #2"); + assert.throws(() => new Uint8Array(11).setFromHex(null), TypeError, "isn't generic, arg #1"); + assert.throws(() => new Uint8Array(11).setFromHex(undefined), TypeError, "isn't generic, arg #2"); + assert.throws(() => new Uint8Array(11).setFromHex(1234), TypeError, "isn't generic, arg #3"); + assert.throws(() => new Uint8Array(11).setFromHex(Object('48656c6c6f20576f726c64')), TypeError, "isn't generic, arg #4"); + assert.throws(() => new Uint8Array(11).setFromHex('48656c6c6f20576f726c641'), SyntaxError, 'throws on invalid #2'); + assert.throws(() => new Uint8Array(11).setFromHex('48656c6c6f20576f726c64 '), SyntaxError, 'throws on invalid #3'); + assert.throws(() => new Uint8Array(11).setFromHex('48656c6c6f20576f726c64\n'), SyntaxError, 'throws on invalid #4'); + + // Test262 + // Copyright 2024 Kevin Gibbons. All rights reserved. + // This code is governed by the BSD license found in the https://github.com/tc39/test262/blob/main/LICENSE file. + [ + 'a.a', + 'aa^', + 'a a', + 'a\ta', + 'a\u000Aa', + 'a\u000Ca', + 'a\u000Da', + 'a\u00A0a', // nbsp + 'a\u2009a', // thin space + 'a\u2028a', // line separator + ].forEach(value => assert.throws(() => new Uint8Array([255, 255, 255, 255, 255]).setFromHex(value), SyntaxError)); + + [ + ['', []], + ['66', [102]], + ['666f', [102, 111]], + ['666F', [102, 111]], + ['666f6f', [102, 111, 111]], + ['666F6f', [102, 111, 111]], + ['666f6f62', [102, 111, 111, 98]], + ['666f6f6261', [102, 111, 111, 98, 97]], + ['666f6f626172', [102, 111, 111, 98, 97, 114]], + ].forEach(([string, bytes]) => { + const allFF = [255, 255, 255, 255, 255, 255, 255, 255]; + const target = new Uint8Array(allFF); + const result = target.setFromHex(string); + assert.same(result.read, string.length); + assert.same(result.written, bytes.length); + + const expected = bytes.concat(allFF.slice(bytes.length)); + assert.arrayEqual(target, expected, `decoding ${ string }`); + }); + + const base = new Uint8Array([255, 255, 255, 255, 255, 255, 255]); + const subarray = base.subarray(2, 5); + + let result = subarray.setFromHex('aabbcc'); + assert.same(result.read, 6); + assert.same(result.written, 3); + assert.arrayEqual(subarray, [170, 187, 204]); + assert.arrayEqual(base, [255, 255, 170, 187, 204, 255, 255]); + + // buffer too small + let target = new Uint8Array([255, 255]); + result = target.setFromHex('aabbcc'); + assert.same(result.read, 4); + assert.same(result.written, 2); + assert.arrayEqual(target, [170, 187]); + + // buffer exact + target = new Uint8Array([255, 255, 255]); + result = target.setFromHex('aabbcc'); + assert.same(result.read, 6); + assert.same(result.written, 3); + assert.arrayEqual(target, [170, 187, 204]); + + // buffer too large + target = new Uint8Array([255, 255, 255, 255]); + result = target.setFromHex('aabbcc'); + assert.same(result.read, 6); + assert.same(result.written, 3); + assert.arrayEqual(target, [170, 187, 204, 255]); + + [ + 'aaa ', + 'aaag', + ].forEach(value => { + target = new Uint8Array([255, 255, 255, 255, 255]); + assert.throws(() => target.setFromHex(value), SyntaxError); + assert.arrayEqual(target, [170, 255, 255, 255, 255], `decoding from ${ value }`); + }); + + target = new Uint8Array([255, 255, 255, 255, 255]); + assert.throws(() => target.setFromHex('aaa'), SyntaxError); + assert.arrayEqual(target, [255, 255, 255, 255, 255], 'when length is odd no data is written'); +}); diff --git a/tests/unit-global/es.uint8-array.to-base64.js b/tests/unit-global/es.uint8-array.to-base64.js new file mode 100644 index 000000000000..0658274fe4f6 --- /dev/null +++ b/tests/unit-global/es.uint8-array.to-base64.js @@ -0,0 +1,65 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('Uint8Array.prototype.toBase64', assert => { + const { toBase64 } = Uint8Array.prototype; + assert.isFunction(toBase64); + assert.arity(toBase64, 0); + assert.name(toBase64, 'toBase64'); + assert.looksNative(toBase64); + + const array = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); + + assert.same(array.toBase64(), 'SGVsbG8gV29ybGQ=', 'proper result'); + assert.same(array.toBase64({ alphabet: 'base64' }), 'SGVsbG8gV29ybGQ=', 'proper result, base64'); + assert.same(array.toBase64({ alphabet: 'base64url' }), 'SGVsbG8gV29ybGQ=', 'proper result, base64url'); + assert.same(array.toBase64({ omitPadding: true }), 'SGVsbG8gV29ybGQ', 'proper result'); + assert.same(array.toBase64({ omitPadding: false }), 'SGVsbG8gV29ybGQ=', 'proper result'); + + assert.throws(() => array.toBase64(null), TypeError, 'incorrect options argument #1'); + assert.throws(() => array.toBase64(1), TypeError, 'incorrect options argument #2'); + + assert.throws(() => array.toBase64({ alphabet: 'base32' }), TypeError, 'incorrect encoding'); + + assert.same(new Uint8Array([215, 111, 247]).toBase64(), '12/3', 'encoding #1'); + assert.same(new Uint8Array([215, 111, 247]).toBase64({ alphabet: 'base64' }), '12/3', 'encoding #2'); + assert.same(new Uint8Array([215, 111, 247]).toBase64({ alphabet: 'base64url' }), '12_3', 'encoding #3'); + assert.same(new Uint8Array([215, 111, 183]).toBase64(), '12+3', 'encoding #4'); + assert.same(new Uint8Array([215, 111, 183]).toBase64({ alphabet: 'base64' }), '12+3', 'encoding #5'); + assert.same(new Uint8Array([215, 111, 183]).toBase64({ alphabet: 'base64url' }), '12-3', 'encoding #6'); + + if (ArrayBuffer.prototype.transfer) { + const array2 = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); + array2.buffer.transfer(); + + assert.throws(() => array2.toBase64(), TypeError, 'detached'); + } + + assert.throws(() => toBase64.call(null), TypeError, "isn't generic #1"); + assert.throws(() => toBase64.call(undefined), TypeError, "isn't generic #2"); + assert.throws(() => toBase64.call(new Int16Array([1])), TypeError, "isn't generic #3"); + assert.throws(() => toBase64.call([1]), TypeError, "isn't generic #4"); + + // Test262 + // Copyright 2024 Kevin Gibbons. All rights reserved. + // This code is governed by the BSD license found in the https://github.com/tc39/test262/blob/main/LICENSE file. + assert.same(new Uint8Array([199, 239, 242]).toBase64(), 'x+/y'); + assert.same(new Uint8Array([199, 239, 242]).toBase64({ alphabet: 'base64' }), 'x+/y'); + assert.same(new Uint8Array([199, 239, 242]).toBase64({ alphabet: 'base64url' }), 'x-_y'); + assert.throws(() => new Uint8Array([199, 239, 242]).toBase64({ alphabet: 'other' }), TypeError); + + // works with default alphabet + assert.same(new Uint8Array([199, 239]).toBase64(), 'x+8='); + assert.same(new Uint8Array([199, 239]).toBase64({ omitPadding: false }), 'x+8='); + assert.same(new Uint8Array([199, 239]).toBase64({ omitPadding: true }), 'x+8'); + assert.same(new Uint8Array([255]).toBase64({ omitPadding: true }), '/w'); + + // works with base64url alphabet + assert.same(new Uint8Array([199, 239]).toBase64({ alphabet: 'base64url' }), 'x-8='); + assert.same(new Uint8Array([199, 239]).toBase64({ alphabet: 'base64url', omitPadding: false }), 'x-8='); + assert.same(new Uint8Array([199, 239]).toBase64({ alphabet: 'base64url', omitPadding: true }), 'x-8'); + assert.same(new Uint8Array([255]).toBase64({ alphabet: 'base64url', omitPadding: true }), '_w'); + + // performs ToBoolean on the argument + assert.same(new Uint8Array([255]).toBase64({ omitPadding: 0 }), '/w=='); + assert.same(new Uint8Array([255]).toBase64({ omitPadding: 1 }), '/w'); +}); diff --git a/tests/unit-global/es.uint8-array.to-hex.js b/tests/unit-global/es.uint8-array.to-hex.js new file mode 100644 index 000000000000..0385c0a1f15d --- /dev/null +++ b/tests/unit-global/es.uint8-array.to-hex.js @@ -0,0 +1,35 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('Uint8Array.prototype.toHex', assert => { + const { toHex } = Uint8Array.prototype; + assert.isFunction(toHex); + assert.arity(toHex, 0); + assert.name(toHex, 'toHex'); + assert.looksNative(toHex); + + assert.same(new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]).toHex(), '48656c6c6f20576f726c64', 'proper result #1'); + assert.same(new Uint8Array([255, 255, 255, 255, 255, 255, 255, 255]).toHex(), 'ffffffffffffffff', 'proper result #2'); + + if (ArrayBuffer.prototype.transfer) { + const array = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); + array.buffer.transfer(); + + assert.throws(() => array.toHex(), TypeError, 'detached'); + } + + assert.throws(() => toHex.call(null), TypeError, "isn't generic #1"); + assert.throws(() => toHex.call(undefined), TypeError, "isn't generic #2"); + assert.throws(() => toHex.call(new Int16Array([1])), TypeError, "isn't generic #3"); + assert.throws(() => toHex.call([1]), TypeError, "isn't generic #4"); + + // Test262 + // Copyright 2024 Kevin Gibbons. All rights reserved. + // This code is governed by the BSD license found in the https://github.com/tc39/test262/blob/main/LICENSE file. + assert.same(new Uint8Array([]).toHex(), ''); + assert.same(new Uint8Array([102]).toHex(), '66'); + assert.same(new Uint8Array([102, 111]).toHex(), '666f'); + assert.same(new Uint8Array([102, 111, 111]).toHex(), '666f6f'); + assert.same(new Uint8Array([102, 111, 111, 98]).toHex(), '666f6f62'); + assert.same(new Uint8Array([102, 111, 111, 98, 97]).toHex(), '666f6f6261'); + assert.same(new Uint8Array([102, 111, 111, 98, 97, 114]).toHex(), '666f6f626172'); +}); diff --git a/tests/unit-global/es.unescape.js b/tests/unit-global/es.unescape.js new file mode 100644 index 000000000000..81db1e709173 --- /dev/null +++ b/tests/unit-global/es.unescape.js @@ -0,0 +1,14 @@ +QUnit.test('unescape', assert => { + assert.isFunction(unescape); + assert.name(unescape, 'unescape'); + assert.arity(unescape, 1); + assert.looksNative(unescape); + assert.same(unescape('%21q2%u0444'), '!q2ф'); + assert.same(unescape('%u044q2%21'), '%u044q2!'); + assert.same(unescape(null), 'null'); + assert.same(unescape(undefined), 'undefined'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => unescape(Symbol('unescape test')), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-global/es.weak-map.js b/tests/unit-global/es.weak-map.js new file mode 100644 index 000000000000..58c7aec921dc --- /dev/null +++ b/tests/unit-global/es.weak-map.js @@ -0,0 +1,176 @@ +import { DESCRIPTORS, FREEZING, GLOBAL, NATIVE } from '../helpers/constants.js'; +import { createIterable, nativeSubclass } from '../helpers/helpers.js'; + +const Symbol = GLOBAL.Symbol || {}; +const { freeze, isFrozen, keys, getOwnPropertyNames, getOwnPropertySymbols } = Object; +const { ownKeys } = GLOBAL.Reflect || {}; + +QUnit.test('WeakMap', assert => { + assert.isFunction(WeakMap); + assert.name(WeakMap, 'WeakMap'); + assert.arity(WeakMap, 0); + assert.looksNative(WeakMap); + assert.true('delete' in WeakMap.prototype, 'delete in WeakMap.prototype'); + assert.true('get' in WeakMap.prototype, 'get in WeakMap.prototype'); + assert.true('has' in WeakMap.prototype, 'has in WeakMap.prototype'); + assert.true('set' in WeakMap.prototype, 'set in WeakMap.prototype'); + assert.true(new WeakMap() instanceof WeakMap, 'new WeakMap instanceof WeakMap'); + let object = {}; + assert.same(new WeakMap(createIterable([[object, 42]])).get(object), 42, 'Init from iterable'); + let weakmap = new WeakMap(); + const frozen = freeze({}); + weakmap.set(frozen, 42); + assert.same(weakmap.get(frozen), 42, 'Support frozen objects'); + weakmap = new WeakMap(); + weakmap.set(frozen, 42); + assert.true(weakmap.has(frozen), 'works with frozen objects, #1'); + assert.same(weakmap.get(frozen), 42, 'works with frozen objects, #2'); + weakmap.delete(frozen); + assert.false(weakmap.has(frozen), 'works with frozen objects, #3'); + assert.same(weakmap.get(frozen), undefined, 'works with frozen objects, #4'); + let done = false; + try { + new WeakMap(createIterable([null, 1, 2], { + return() { + return done = true; + }, + })); + } catch { /* empty */ } + assert.true(done, '.return #throw'); + assert.false(('clear' in WeakMap.prototype), 'should not contains `.clear` method'); + const array = []; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + new WeakMap(array); + assert.true(done); + object = {}; + new WeakMap().set(object, 1); + if (DESCRIPTORS) { + const results = []; + for (const key in object) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(object), []); + } + assert.arrayEqual(getOwnPropertyNames(object), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); + if (ownKeys) assert.arrayEqual(ownKeys(object), []); + if (nativeSubclass) { + const Subclass = nativeSubclass(WeakMap); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof WeakMap, 'correct subclassing with native classes #2'); + object = {}; + assert.same(new Subclass().set(object, 2).get(object), 2, 'correct subclassing with native classes #3'); + } + + const buffer = new ArrayBuffer(8); + const map = new WeakMap([[buffer, 8]]); + assert.true(map.has(buffer), 'works with ArrayBuffer keys'); +}); + +QUnit.test('WeakMap#delete', assert => { + assert.isFunction(WeakMap.prototype.delete); + if (NATIVE) assert.name(WeakMap.prototype.delete, 'delete'); + if (NATIVE) assert.arity(WeakMap.prototype.delete, 1); + assert.looksNative(WeakMap.prototype.delete); + assert.nonEnumerable(WeakMap.prototype, 'delete'); + const a = {}; + const b = {}; + const weakmap = new WeakMap(); + weakmap.set(a, 42); + weakmap.set(b, 21); + assert.true(weakmap.has(a), 'WeakMap has values before .delete() #1'); + assert.true(weakmap.has(b), 'WeakMap has values before .delete() #2'); + weakmap.delete(a); + assert.false(weakmap.has(a), 'WeakMap has not value after .delete() #1'); + assert.true(weakmap.has(b), 'WeakMap has not value after .delete() #2'); + assert.notThrows(() => !weakmap.delete(1), 'return false on primitive'); + const object = {}; + weakmap.set(object, 42); + freeze(object); + assert.true(weakmap.has(object), 'works with frozen objects #1'); + weakmap.delete(object); + assert.false(weakmap.has(object), 'works with frozen objects #2'); +}); + +QUnit.test('WeakMap#get', assert => { + assert.isFunction(WeakMap.prototype.get); + assert.name(WeakMap.prototype.get, 'get'); + if (NATIVE) assert.arity(WeakMap.prototype.get, 1); + assert.looksNative(WeakMap.prototype.get); + assert.nonEnumerable(WeakMap.prototype, 'get'); + const weakmap = new WeakMap(); + assert.same(weakmap.get({}), undefined, 'WeakMap .get() before .set() return undefined'); + let object = {}; + weakmap.set(object, 42); + assert.same(weakmap.get(object), 42, 'WeakMap .get() return value'); + weakmap.delete(object); + assert.same(weakmap.get(object), undefined, 'WeakMap .get() after .delete() return undefined'); + assert.notThrows(() => weakmap.get(1) === undefined, 'return undefined on primitive'); + object = {}; + weakmap.set(object, 42); + freeze(object); + assert.same(weakmap.get(object), 42, 'works with frozen objects #1'); + weakmap.delete(object); + assert.same(weakmap.get(object), undefined, 'works with frozen objects #2'); +}); + +QUnit.test('WeakMap#has', assert => { + assert.isFunction(WeakMap.prototype.has); + assert.name(WeakMap.prototype.has, 'has'); + if (NATIVE) assert.arity(WeakMap.prototype.has, 1); + assert.looksNative(WeakMap.prototype.has); + assert.nonEnumerable(WeakMap.prototype, 'has'); + const weakmap = new WeakMap(); + assert.false(weakmap.has({}), 'WeakMap .has() before .set() return false'); + let object = {}; + weakmap.set(object, 42); + assert.true(weakmap.has(object), 'WeakMap .has() return true'); + weakmap.delete(object); + assert.false(weakmap.has(object), 'WeakMap .has() after .delete() return false'); + assert.notThrows(() => !weakmap.has(1), 'return false on primitive'); + object = {}; + weakmap.set(object, 42); + freeze(object); + assert.true(weakmap.has(object), 'works with frozen objects #1'); + weakmap.delete(object); + assert.false(weakmap.has(object), 'works with frozen objects #2'); +}); + +QUnit.test('WeakMap#set', assert => { + assert.isFunction(WeakMap.prototype.set); + assert.name(WeakMap.prototype.set, 'set'); + assert.arity(WeakMap.prototype.set, 2); + assert.looksNative(WeakMap.prototype.set); + assert.nonEnumerable(WeakMap.prototype, 'set'); + const weakmap = new WeakMap(); + const object = {}; + weakmap.set(object, 33); + assert.same(weakmap.get(object), 33, 'works with object as keys'); + assert.same(weakmap.set({}, 42), weakmap, 'chaining'); + assert.throws(() => new WeakMap().set(42, 42), 'throws with primitive keys'); + const object1 = freeze({}); + const object2 = {}; + weakmap.set(object1, 42); + weakmap.set(object2, 42); + freeze(object); + assert.same(weakmap.get(object1), 42, 'works with frozen objects #1'); + assert.same(weakmap.get(object2), 42, 'works with frozen objects #2'); + weakmap.delete(object1); + weakmap.delete(object2); + assert.same(weakmap.get(object1), undefined, 'works with frozen objects #3'); + assert.same(weakmap.get(object2), undefined, 'works with frozen objects #4'); + const array = freeze([]); + weakmap.set(array, 42); + assert.same(weakmap.get(array), 42, 'works with frozen arrays #1'); + if (FREEZING) assert.true(isFrozen(array), 'works with frozen arrays #2'); +}); + +QUnit.test('WeakMap#@@toStringTag', assert => { + assert.same(WeakMap.prototype[Symbol.toStringTag], 'WeakMap', 'WeakMap::@@toStringTag is `WeakMap`'); + assert.same(String(new WeakMap()), '[object WeakMap]', 'correct stringification'); +}); diff --git a/tests/unit-global/es.weak-set.js b/tests/unit-global/es.weak-set.js new file mode 100644 index 000000000000..4312240f04a1 --- /dev/null +++ b/tests/unit-global/es.weak-set.js @@ -0,0 +1,115 @@ +import { DESCRIPTORS, GLOBAL, NATIVE } from '../helpers/constants.js'; +import { createIterable, nativeSubclass } from '../helpers/helpers.js'; + +const Symbol = GLOBAL.Symbol || {}; +const { freeze, keys, getOwnPropertyNames, getOwnPropertySymbols } = Object; +const { ownKeys } = GLOBAL.Reflect || {}; + +QUnit.test('WeakSet', assert => { + assert.isFunction(WeakSet); + assert.name(WeakSet, 'WeakSet'); + assert.arity(WeakSet, 0); + assert.looksNative(WeakSet); + assert.true('add' in WeakSet.prototype, 'add in WeakSet.prototype'); + assert.true('delete' in WeakSet.prototype, 'delete in WeakSet.prototype'); + assert.true('has' in WeakSet.prototype, 'has in WeakSet.prototype'); + assert.true(new WeakSet() instanceof WeakSet, 'new WeakSet instanceof WeakSet'); + let object = {}; + assert.true(new WeakSet(createIterable([object])).has(object), 'Init from iterable'); + const weakset = new WeakSet(); + const frozen = freeze({}); + weakset.add(frozen); + assert.true(weakset.has(frozen), 'works with frozen objects, #1'); + weakset.delete(frozen); + assert.false(weakset.has(frozen), 'works with frozen objects, #2'); + let done = false; + try { + new WeakSet(createIterable([null, 1, 2], { + return() { + return done = true; + }, + })); + } catch { /* empty */ } + assert.true(done, '.return #throw'); + assert.false(('clear' in WeakSet.prototype), 'should not contains `.clear` method'); + const array = []; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return [][Symbol.iterator].call(this); + }; + new WeakSet(array); + assert.true(done); + object = {}; + new WeakSet().add(object); + if (DESCRIPTORS) { + const results = []; + for (const key in object) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(object), []); + } + assert.arrayEqual(getOwnPropertyNames(object), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); + if (ownKeys) assert.arrayEqual(ownKeys(object), []); + if (nativeSubclass) { + const Subclass = nativeSubclass(WeakSet); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof WeakSet, 'correct subclassing with native classes #2'); + object = {}; + assert.true(new Subclass().add(object).has(object), 'correct subclassing with native classes #3'); + } + + const buffer = new ArrayBuffer(8); + const set = new WeakSet([buffer]); + assert.true(set.has(buffer), 'works with ArrayBuffer keys'); +}); + +QUnit.test('WeakSet#add', assert => { + assert.isFunction(WeakSet.prototype.add); + assert.name(WeakSet.prototype.add, 'add'); + assert.arity(WeakSet.prototype.add, 1); + assert.looksNative(WeakSet.prototype.add); + assert.nonEnumerable(WeakSet.prototype, 'add'); + const weakset = new WeakSet(); + assert.same(weakset.add({}), weakset, 'chaining'); + assert.throws(() => new WeakSet().add(42), 'throws with primitive keys'); +}); + +QUnit.test('WeakSet#delete', assert => { + assert.isFunction(WeakSet.prototype.delete); + if (NATIVE) assert.arity(WeakSet.prototype.delete, 1); + assert.looksNative(WeakSet.prototype.delete); + assert.nonEnumerable(WeakSet.prototype, 'delete'); + const a = {}; + const b = {}; + const weakset = new WeakSet().add(a).add(b); + assert.true(weakset.has(a), 'WeakSet has values before .delete() #1'); + assert.true(weakset.has(b), 'WeakSet has values before .delete() #2'); + weakset.delete(a); + assert.false(weakset.has(a), 'WeakSet has not value after .delete() #1'); + assert.true(weakset.has(b), 'WeakSet has not value after .delete() #2'); + assert.notThrows(() => !weakset.delete(1), 'return false on primitive'); +}); + +QUnit.test('WeakSet#has', assert => { + assert.isFunction(WeakSet.prototype.has); + assert.name(WeakSet.prototype.has, 'has'); + assert.arity(WeakSet.prototype.has, 1); + assert.looksNative(WeakSet.prototype.has); + assert.nonEnumerable(WeakSet.prototype, 'has'); + const weakset = new WeakSet(); + assert.false(weakset.has({}), 'WeakSet has`nt value'); + const object = {}; + weakset.add(object); + assert.true(weakset.has(object), 'WeakSet has value after .add()'); + weakset.delete(object); + assert.false(weakset.has(object), 'WeakSet has not value after .delete()'); + assert.notThrows(() => !weakset.has(1), 'return false on primitive'); +}); + +QUnit.test('WeakSet::@@toStringTag', assert => { + assert.same(WeakSet.prototype[Symbol.toStringTag], 'WeakSet', 'WeakSet::@@toStringTag is `WeakSet`'); + assert.same(String(new WeakSet()), '[object WeakSet]', 'correct stringification'); +}); diff --git a/tests/unit-global/esnext.array.filter-out.js b/tests/unit-global/esnext.array.filter-out.js new file mode 100644 index 000000000000..2eb185f78044 --- /dev/null +++ b/tests/unit-global/esnext.array.filter-out.js @@ -0,0 +1,37 @@ +// TODO: Remove from `core-js@4` +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#filterOut', assert => { + const { filterOut } = Array.prototype; + assert.isFunction(filterOut); + assert.arity(filterOut, 1); + assert.name(filterOut, 'filterOut'); + assert.looksNative(filterOut); + assert.nonEnumerable(Array.prototype, 'filterOut'); + let array = [1]; + const context = {}; + array.filterOut(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.deepEqual([1, 2, 3, 4, 5], [1, 2, 3, 'q', {}, 4, true, 5].filterOut(it => typeof it != 'number')); + if (STRICT) { + assert.throws(() => filterOut.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => filterOut.call(undefined, () => { /* empty */ }), TypeError); + } + assert.notThrows(() => filterOut.call({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }), 'uses ToLength'); + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(array.filterOut(Boolean).foo, 1, '@@species'); +}); diff --git a/tests/unit-global/esnext.array.filter-reject.js b/tests/unit-global/esnext.array.filter-reject.js new file mode 100644 index 000000000000..99b2483296a8 --- /dev/null +++ b/tests/unit-global/esnext.array.filter-reject.js @@ -0,0 +1,36 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#filterReject', assert => { + const { filterReject } = Array.prototype; + assert.isFunction(filterReject); + assert.arity(filterReject, 1); + assert.name(filterReject, 'filterReject'); + assert.looksNative(filterReject); + assert.nonEnumerable(Array.prototype, 'filterReject'); + let array = [1]; + const context = {}; + array.filterReject(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.deepEqual([1, 2, 3, 4, 5], [1, 2, 3, 'q', {}, 4, true, 5].filterReject(it => typeof it != 'number')); + if (STRICT) { + assert.throws(() => filterReject.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => filterReject.call(undefined, () => { /* empty */ }), TypeError); + } + assert.notThrows(() => filterReject.call({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }), 'uses ToLength'); + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(array.filterReject(Boolean).foo, 1, '@@species'); +}); diff --git a/tests/unit-global/esnext.array.group-by-to-map.js b/tests/unit-global/esnext.array.group-by-to-map.js new file mode 100644 index 000000000000..10489b8e9a99 --- /dev/null +++ b/tests/unit-global/esnext.array.group-by-to-map.js @@ -0,0 +1,38 @@ +import { STRICT } from '../helpers/constants.js'; + +const { from } = Array; + +QUnit.test('Array#groupByToMap', assert => { + const { groupByToMap } = Array.prototype; + assert.isFunction(groupByToMap); + assert.arity(groupByToMap, 1); + assert.looksNative(groupByToMap); + assert.nonEnumerable(Array.prototype, 'groupByToMap'); + let array = [1]; + const context = {}; + array.groupByToMap(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true([].groupByToMap(it => it) instanceof Map, 'returns Map'); + assert.deepEqual(from([1, 2, 3].groupByToMap(it => it % 2)), [[1, [1, 3]], [0, [2]]], '#1'); + assert.deepEqual( + from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].groupByToMap(it => `i${ it % 5 }`)), + [['i1', [1, 6, 11]], ['i2', [2, 7, 12]], ['i3', [3, 8]], ['i4', [4, 9]], ['i0', [5, 10]]], + '#2', + ); + assert.deepEqual(from(Array(3).groupByToMap(it => it)), [[undefined, [undefined, undefined, undefined]]], '#3'); + if (STRICT) { + assert.throws(() => groupByToMap.call(null, () => { /* empty */ }), TypeError, 'null this -> TypeError'); + assert.throws(() => groupByToMap.call(undefined, () => { /* empty */ }), TypeError, 'undefined this -> TypeError'); + } + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(array.groupByToMap(Boolean).get(true).foo, undefined, 'no @@species'); +}); diff --git a/tests/unit-global/esnext.array.group-by.js b/tests/unit-global/esnext.array.group-by.js new file mode 100644 index 000000000000..e6ff0c60f081 --- /dev/null +++ b/tests/unit-global/esnext.array.group-by.js @@ -0,0 +1,39 @@ +import { STRICT } from '../helpers/constants.js'; + +const { getPrototypeOf } = Object; + +QUnit.test('Array#groupBy', assert => { + const { groupBy } = Array.prototype; + assert.isFunction(groupBy); + assert.arity(groupBy, 1); + assert.name(groupBy, 'groupBy'); + assert.looksNative(groupBy); + assert.nonEnumerable(Array.prototype, 'groupBy'); + let array = [1]; + const context = {}; + array.groupBy(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same(getPrototypeOf([].groupBy(it => it)), null, 'null proto'); + assert.deepEqual([1, 2, 3].groupBy(it => it % 2), { 1: [1, 3], 0: [2] }, '#1'); + assert.deepEqual( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].groupBy(it => `i${ it % 5 }`), + { i1: [1, 6, 11], i2: [2, 7, 12], i3: [3, 8], i4: [4, 9], i0: [5, 10] }, + '#2', + ); + assert.deepEqual(Array(3).groupBy(it => it), { undefined: [undefined, undefined, undefined] }, '#3'); + if (STRICT) { + assert.throws(() => groupBy.call(null, () => { /* empty */ }), TypeError, 'null this -> TypeError'); + assert.throws(() => groupBy.call(undefined, () => { /* empty */ }), TypeError, 'undefined this -> TypeError'); + } + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(array.groupBy(Boolean).true.foo, undefined, 'no @@species'); +}); diff --git a/tests/unit-global/esnext.array.group-to-map.js b/tests/unit-global/esnext.array.group-to-map.js new file mode 100644 index 000000000000..09784a52ace9 --- /dev/null +++ b/tests/unit-global/esnext.array.group-to-map.js @@ -0,0 +1,39 @@ +import { STRICT } from '../helpers/constants.js'; + +const { from } = Array; + +QUnit.test('Array#groupToMap', assert => { + const { groupToMap } = Array.prototype; + assert.isFunction(groupToMap); + assert.arity(groupToMap, 1); + assert.name(groupToMap, 'groupToMap'); + assert.looksNative(groupToMap); + assert.nonEnumerable(Array.prototype, 'groupToMap'); + let array = [1]; + const context = {}; + array.groupToMap(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true([].groupToMap(it => it) instanceof Map, 'returns Map'); + assert.deepEqual(from([1, 2, 3].groupToMap(it => it % 2)), [[1, [1, 3]], [0, [2]]], '#1'); + assert.deepEqual( + from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].groupToMap(it => `i${ it % 5 }`)), + [['i1', [1, 6, 11]], ['i2', [2, 7, 12]], ['i3', [3, 8]], ['i4', [4, 9]], ['i0', [5, 10]]], + '#2', + ); + assert.deepEqual(from(Array(3).groupToMap(it => it)), [[undefined, [undefined, undefined, undefined]]], '#3'); + if (STRICT) { + assert.throws(() => groupToMap.call(null, () => { /* empty */ }), TypeError, 'null this -> TypeError'); + assert.throws(() => groupToMap.call(undefined, () => { /* empty */ }), TypeError, 'undefined this -> TypeError'); + } + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(array.groupToMap(Boolean).get(true).foo, undefined, 'no @@species'); +}); diff --git a/tests/unit-global/esnext.array.group.js b/tests/unit-global/esnext.array.group.js new file mode 100644 index 000000000000..b0eb27b740fb --- /dev/null +++ b/tests/unit-global/esnext.array.group.js @@ -0,0 +1,39 @@ +import { STRICT } from '../helpers/constants.js'; + +const { getPrototypeOf } = Object; + +QUnit.test('Array#group', assert => { + const { group } = Array.prototype; + assert.isFunction(group); + assert.arity(group, 1); + assert.name(group, 'group'); + assert.looksNative(group); + assert.nonEnumerable(Array.prototype, 'group'); + let array = [1]; + const context = {}; + array.group(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same(getPrototypeOf([].group(it => it)), null, 'null proto'); + assert.deepEqual([1, 2, 3].group(it => it % 2), { 1: [1, 3], 0: [2] }, '#1'); + assert.deepEqual( + [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].group(it => `i${ it % 5 }`), + { i1: [1, 6, 11], i2: [2, 7, 12], i3: [3, 8], i4: [4, 9], i0: [5, 10] }, + '#2', + ); + assert.deepEqual(Array(3).group(it => it), { undefined: [undefined, undefined, undefined] }, '#3'); + if (STRICT) { + assert.throws(() => group.call(null, () => { /* empty */ }), TypeError, 'null this -> TypeError'); + assert.throws(() => group.call(undefined, () => { /* empty */ }), TypeError, 'undefined this -> TypeError'); + } + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(array.group(Boolean).true.foo, undefined, 'no @@species'); +}); diff --git a/tests/unit-global/esnext.array.is-template-object.js b/tests/unit-global/esnext.array.is-template-object.js new file mode 100644 index 000000000000..d820310b32e5 --- /dev/null +++ b/tests/unit-global/esnext.array.is-template-object.js @@ -0,0 +1,29 @@ +QUnit.test('Array.isTemplateObject', assert => { + const { isTemplateObject } = Array; + const { freeze } = Object; + + assert.isFunction(isTemplateObject); + assert.arity(isTemplateObject, 1); + assert.name(isTemplateObject, 'isTemplateObject'); + assert.looksNative(isTemplateObject); + assert.nonEnumerable(Array, 'isTemplateObject'); + + assert.false(isTemplateObject(undefined)); + assert.false(isTemplateObject(null)); + assert.false(isTemplateObject({})); + assert.false(isTemplateObject(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }())); + assert.false(isTemplateObject([])); + assert.false(isTemplateObject(freeze([]))); + + const template = (() => { + try { + // eslint-disable-next-line no-template-curly-in-string -- safe + return Function('return (it => it)`qwe${ 123 }asd`')(); + } catch { /* empty */ } + })(); + + if (template) assert.true(isTemplateObject(template)); +}); diff --git a/tests/unit-global/esnext.array.last-index.js b/tests/unit-global/esnext.array.last-index.js new file mode 100644 index 000000000000..43840876fc6d --- /dev/null +++ b/tests/unit-global/esnext.array.last-index.js @@ -0,0 +1,10 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('Array#lastIndex', assert => { + const descriptor = Object.getOwnPropertyDescriptor(Array.prototype, 'lastIndex'); + assert.isFunction(descriptor.get); + assert.false(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same([1, 2, 3].lastIndex, 2); + assert.same([].lastIndex, 0); +}); diff --git a/tests/tests/esnext.array.last-item.js b/tests/unit-global/esnext.array.last-item.js similarity index 75% rename from tests/tests/esnext.array.last-item.js rename to tests/unit-global/esnext.array.last-item.js index 8997b29224a0..d6a8a64ba776 100644 --- a/tests/tests/esnext.array.last-item.js +++ b/tests/unit-global/esnext.array.last-item.js @@ -1,11 +1,11 @@ -import { DESCRIPTORS } from '../helpers/constants'; +import { DESCRIPTORS } from '../helpers/constants.js'; if (DESCRIPTORS) QUnit.test('Array#lastItem', assert => { const descriptor = Object.getOwnPropertyDescriptor(Array.prototype, 'lastItem'); assert.isFunction(descriptor.get); assert.isFunction(descriptor.set); - assert.same(descriptor.enumerable, false); - assert.same(descriptor.configurable, true); + assert.false(descriptor.enumerable); + assert.true(descriptor.configurable); assert.same([1, 2, 3].lastItem, 3); assert.same([].lastItem, undefined); let array = [1, 2, 3]; diff --git a/tests/unit-global/esnext.array.unique-by.js b/tests/unit-global/esnext.array.unique-by.js new file mode 100644 index 000000000000..1cedb5867d6b --- /dev/null +++ b/tests/unit-global/esnext.array.unique-by.js @@ -0,0 +1,55 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Array#uniqueBy', assert => { + const { uniqueBy } = Array.prototype; + assert.isFunction(uniqueBy); + assert.arity(uniqueBy, 1); + assert.name(uniqueBy, 'uniqueBy'); + assert.looksNative(uniqueBy); + assert.nonEnumerable(Array.prototype, 'uniqueBy'); + + let array = [1, 2, 3, 2, 1]; + assert.notSame(array.uniqueBy(), array); + assert.deepEqual(array.uniqueBy(), [1, 2, 3]); + + array = [ + { + id: 1, + uid: 10000, + }, + { + id: 2, + uid: 10000, + }, + { + id: 3, + uid: 10001, + }, + ]; + + assert.deepEqual(array.uniqueBy(it => it.uid), [ + { + id: 1, + uid: 10000, + }, + { + id: 3, + uid: 10001, + }, + ]); + + assert.deepEqual(array.uniqueBy(({ id, uid }) => `${ id }-${ uid }`), array); + + assert.deepEqual([1, undefined, 2, undefined, null, 1].uniqueBy(), [1, undefined, 2, null]); + + assert.deepEqual([0, -0].uniqueBy(), [0]); + assert.deepEqual([NaN, NaN].uniqueBy(), [NaN]); + + assert.deepEqual(uniqueBy.call({ length: 1, 0: 1 }), [1]); + + if (STRICT) { + assert.throws(() => uniqueBy.call(null), TypeError); + assert.throws(() => uniqueBy.call(undefined), TypeError); + } + assert.true('uniqueBy' in Array.prototype[Symbol.unscopables], 'In Array#@@unscopables'); +}); diff --git a/tests/unit-global/esnext.async-iterator.as-indexed-pairs.js b/tests/unit-global/esnext.async-iterator.as-indexed-pairs.js new file mode 100644 index 000000000000..d29221471e15 --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.as-indexed-pairs.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('AsyncIterator#asIndexedPairs', assert => { + const { asIndexedPairs } = AsyncIterator.prototype; + + assert.isFunction(asIndexedPairs); + assert.arity(asIndexedPairs, 0); + // assert.name(asIndexedPairs, 'asIndexedPairs'); + assert.looksNative(asIndexedPairs); + assert.nonEnumerable(AsyncIterator.prototype, 'asIndexedPairs'); + + if (STRICT) { + assert.throws(() => asIndexedPairs.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => asIndexedPairs.call(null, () => { /* empty */ }), TypeError); + } + + return asIndexedPairs.call(createIterator(['a', 'b', 'c'])).toArray().then(it => { + assert.same(it.toString(), '0,a,1,b,2,c', 'basic functionality'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.constructor.js b/tests/unit-global/esnext.async-iterator.constructor.js new file mode 100644 index 000000000000..0dec94087e30 --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.constructor.js @@ -0,0 +1,43 @@ +import { nativeSubclass } from '../helpers/helpers.js'; + +const { getPrototypeOf } = Object; + +QUnit.test('AsyncIterator', assert => { + assert.isFunction(AsyncIterator); + assert.arity(AsyncIterator, 0); + assert.name(AsyncIterator, 'AsyncIterator'); + assert.looksNative(AsyncIterator); + + const asyncGenerator = (() => { + try { + return Function('return async function*(){}()')(); + } catch { /* empty */ } + })(); + + if (asyncGenerator && globalThis.USE_FUNCTION_CONSTRUCTOR) { + const proto = getPrototypeOf(getPrototypeOf(getPrototypeOf(asyncGenerator))); + if (proto !== Object.prototype && proto !== null) { + assert.true(asyncGenerator instanceof AsyncIterator, 'AsyncGenerator'); + } + } + + assert.true(AsyncIterator.from([1, 2, 3]) instanceof AsyncIterator, 'Async From Proxy'); + assert.true(AsyncIterator.from([1, 2, 3]).drop(1) instanceof AsyncIterator, 'Async Drop Proxy'); + + if (nativeSubclass) { + const Sub = nativeSubclass(AsyncIterator); + assert.true(new Sub() instanceof AsyncIterator, 'abstract constructor'); + } + + assert.throws(() => new AsyncIterator(), 'direct constructor throws'); + assert.throws(() => AsyncIterator(), 'throws w/o `new`'); +}); + +QUnit.test('AsyncIterator#constructor', assert => { + assert.same(AsyncIterator.prototype.constructor, AsyncIterator, 'AsyncIterator#constructor is AsyncIterator'); +}); + +QUnit.test('AsyncIterator#@@toStringTag', assert => { + assert.same(AsyncIterator.prototype[Symbol.toStringTag], 'AsyncIterator', 'AsyncIterator::@@toStringTag is `AsyncIterator`'); + assert.same(String(AsyncIterator.from([1, 2, 3])), '[object AsyncIterator]', 'correct stringification'); +}); diff --git a/tests/unit-global/esnext.async-iterator.drop.js b/tests/unit-global/esnext.async-iterator.drop.js new file mode 100644 index 000000000000..36bb4983ce50 --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.drop.js @@ -0,0 +1,33 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('AsyncIterator#drop', assert => { + const { drop } = AsyncIterator.prototype; + + assert.isFunction(drop); + assert.arity(drop, 1); + assert.name(drop, 'drop'); + assert.looksNative(drop); + assert.nonEnumerable(AsyncIterator.prototype, 'drop'); + + if (STRICT) { + assert.throws(() => drop.call(undefined, 1), TypeError); + assert.throws(() => drop.call(null, 1), TypeError); + } + + assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => drop.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); + + return drop.call(createIterator([1, 2, 3]), 1).toArray().then(it => { + assert.arrayEqual(it, [2, 3], 'basic functionality'); + return drop.call(createIterator([1, 2, 3]), 1.5).toArray(); + }).then(it => { + assert.arrayEqual(it, [2, 3], 'float'); + return drop.call(createIterator([1, 2, 3]), 4).toArray(); + }).then(it => { + assert.arrayEqual(it, [], 'big'); + return drop.call(createIterator([1, 2, 3]), 0).toArray(); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'zero'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.every.js b/tests/unit-global/esnext.async-iterator.every.js new file mode 100644 index 000000000000..1055ff44a90f --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.every.js @@ -0,0 +1,40 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('AsyncIterator#every', assert => { + const { every } = AsyncIterator.prototype; + + assert.isFunction(every); + assert.arity(every, 1); + assert.name(every, 'every'); + assert.looksNative(every); + assert.nonEnumerable(AsyncIterator.prototype, 'every'); + + if (STRICT) { + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => every.call(createIterator([1]), undefined), TypeError); + assert.throws(() => every.call(createIterator([1]), null), TypeError); + assert.throws(() => every.call(createIterator([1]), {}), TypeError); + + return every.call(createIterator([1, 2, 3]), it => typeof it == 'number').then(result => { + assert.true(result, 'basic functionality, +'); + return every.call(createIterator([1, 2, 3]), it => it === 2); + }).then(result => { + assert.false(result, 'basic functionality, -'); + return every.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + }).then(() => { + return every.call(createIterator([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.filter.js b/tests/unit-global/esnext.async-iterator.filter.js new file mode 100644 index 000000000000..29adf808c1af --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.filter.js @@ -0,0 +1,37 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('AsyncIterator#filter', assert => { + const { filter } = AsyncIterator.prototype; + + assert.isFunction(filter); + assert.arity(filter, 1); + assert.name(filter, 'filter'); + assert.looksNative(filter); + assert.nonEnumerable(AsyncIterator.prototype, 'filter'); + + if (STRICT) { + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => filter.call(createIterator([1]), undefined), TypeError); + assert.throws(() => filter.call(createIterator([1]), null), TypeError); + assert.throws(() => filter.call(createIterator([1]), {}), TypeError); + + return filter.call(createIterator([1, 2, 3]), it => it % 2).toArray().then(it => { + assert.arrayEqual(it, [1, 3], 'basic functionality'); + return filter.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }).toArray(); + }).then(() => { + return filter.call(createIterator([1]), () => { throw 42; }).toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.find.js b/tests/unit-global/esnext.async-iterator.find.js new file mode 100644 index 000000000000..ef6dfcc17839 --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.find.js @@ -0,0 +1,40 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('AsyncIterator#find', assert => { + const { find } = AsyncIterator.prototype; + + assert.isFunction(find); + assert.arity(find, 1); + assert.name(find, 'find'); + assert.looksNative(find); + assert.nonEnumerable(AsyncIterator.prototype, 'find'); + + if (STRICT) { + assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => find.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => find.call(createIterator([1]), undefined), TypeError); + assert.throws(() => find.call(createIterator([1]), null), TypeError); + assert.throws(() => find.call(createIterator([1]), {}), TypeError); + + return find.call(createIterator([2, 3, 4]), it => it % 2).then(result => { + assert.same(result, 3, 'basic functionality, +'); + return find.call(createIterator([1, 2, 3]), it => it === 4); + }).then(result => { + assert.same(result, undefined, 'basic functionality, -'); + return find.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + }).then(() => { + return find.call(createIterator([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.flat-map.js b/tests/unit-global/esnext.async-iterator.flat-map.js new file mode 100644 index 000000000000..de5c450a3c6f --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.flat-map.js @@ -0,0 +1,38 @@ +import { createIterator, createIterable } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('AsyncIterator#flatMap', assert => { + const { flatMap } = AsyncIterator.prototype; + + assert.isFunction(flatMap); + assert.arity(flatMap, 1); + assert.name(flatMap, 'flatMap'); + assert.looksNative(flatMap); + assert.nonEnumerable(AsyncIterator.prototype, 'flatMap'); + + if (STRICT) { + assert.throws(() => flatMap.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => flatMap.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => flatMap.call(createIterator([1]), undefined), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), null), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), {}), TypeError); + + return flatMap.call(createIterator([1, [], 2, createIterable([3, 4]), [5, 6]]), it => typeof it == 'number' ? [-it] : it).toArray().then(it => { + assert.arrayEqual(it, [-1, -2, 3, 4, 5, 6], 'basic functionality'); + return flatMap.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + return [arg]; + }).toArray(); + }).then(() => { + return flatMap.call(createIterator([1]), () => { throw 42; }).toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.for-each.js b/tests/unit-global/esnext.async-iterator.for-each.js new file mode 100644 index 000000000000..28ed0c74a9e9 --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.for-each.js @@ -0,0 +1,39 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('AsyncIterator#forEach', assert => { + const { forEach } = AsyncIterator.prototype; + + assert.isFunction(forEach); + assert.arity(forEach, 1); + assert.name(forEach, 'forEach'); + assert.looksNative(forEach); + assert.nonEnumerable(AsyncIterator.prototype, 'forEach'); + + if (STRICT) { + assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => forEach.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => forEach.call(createIterator([1]), undefined), TypeError); + assert.throws(() => forEach.call(createIterator([1]), null), TypeError); + assert.throws(() => forEach.call(createIterator([1]), {}), TypeError); + + const array = []; + + return forEach.call(createIterator([1, 2, 3]), it => array.push(it)).then(() => { + assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); + return forEach.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + }).then(() => { + return forEach.call(createIterator([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.from.js b/tests/unit-global/esnext.async-iterator.from.js new file mode 100644 index 000000000000..c668b1e53646 --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.from.js @@ -0,0 +1,49 @@ +import ITERATOR from 'core-js-pure/es/symbol/iterator'; + +const { assign, create } = Object; + +QUnit.test('AsyncIterator.from', assert => { + const { from } = AsyncIterator; + + assert.isFunction(from); + assert.arity(from, 1); + assert.name(from, 'from'); + assert.looksNative(from); + assert.nonEnumerable(AsyncIterator, 'from'); + + assert.true(AsyncIterator.from([].values()) instanceof AsyncIterator, 'proxy, iterator'); + + assert.true(AsyncIterator.from([]) instanceof AsyncIterator, 'proxy, iterable'); + + const asyncIterator = assign(create(AsyncIterator.prototype), { + next: () => { /* empty */ }, + }); + + assert.same(AsyncIterator.from(asyncIterator), asyncIterator, 'does not wrap AsyncIterator instances'); + + assert.throws(() => from(undefined), TypeError); + assert.throws(() => from(null), TypeError); + + const closableIterator = { + closed: false, + [ITERATOR]() { return this; }, + next() { + return { value: Promise.reject(42), done: false }; + }, + return() { + this.closed = true; + return { value: undefined, done: true }; + }, + }; + + return AsyncIterator.from([1, Promise.resolve(2), 3]).toArray().then(result => { + assert.arrayEqual(result, [1, 2, 3], 'unwrap promises'); + }).then(() => { + return from(Iterator.from(closableIterator)).toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + assert.true(closableIterator.closed, 'doesn\'t close sync iterator on promise rejection'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.indexed.js b/tests/unit-global/esnext.async-iterator.indexed.js new file mode 100644 index 000000000000..2a71138fecbe --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.indexed.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('AsyncIterator#indexed', assert => { + const { indexed } = AsyncIterator.prototype; + + assert.isFunction(indexed); + assert.arity(indexed, 0); + assert.name(indexed, 'indexed'); + assert.looksNative(indexed); + assert.nonEnumerable(AsyncIterator.prototype, 'indexed'); + + if (STRICT) { + assert.throws(() => indexed.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => indexed.call(null, () => { /* empty */ }), TypeError); + } + + return indexed.call(createIterator(['a', 'b', 'c'])).toArray().then(it => { + assert.same(it.toString(), '0,a,1,b,2,c', 'basic functionality'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.map.js b/tests/unit-global/esnext.async-iterator.map.js new file mode 100644 index 000000000000..1e6c39d63a7c --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.map.js @@ -0,0 +1,37 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('AsyncIterator#map', assert => { + const { map } = AsyncIterator.prototype; + + assert.isFunction(map); + assert.arity(map, 1); + assert.name(map, 'map'); + assert.looksNative(map); + assert.nonEnumerable(AsyncIterator.prototype, 'map'); + + if (STRICT) { + assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => map.call(createIterator([1]), undefined), TypeError); + assert.throws(() => map.call(createIterator([1]), null), TypeError); + assert.throws(() => map.call(createIterator([1]), {}), TypeError); + + return map.call(createIterator([1, 2, 3]), it => it ** 2).toArray().then(it => { + assert.arrayEqual(it, [1, 4, 9], 'basic functionality'); + return map.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }).toArray(); + }).then(() => { + return map.call(createIterator([1]), () => { throw 42; }).toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.reduce.js b/tests/unit-global/esnext.async-iterator.reduce.js new file mode 100644 index 000000000000..1a2c2cef792f --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.reduce.js @@ -0,0 +1,44 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('AsyncIterator#reduce', assert => { + const { reduce } = AsyncIterator.prototype; + + assert.isFunction(reduce); + assert.arity(reduce, 1); + assert.name(reduce, 'reduce'); + assert.looksNative(reduce); + assert.nonEnumerable(AsyncIterator.prototype, 'reduce'); + + if (STRICT) { + assert.throws(() => reduce.call(undefined, () => { /* empty */ }, 1), TypeError); + assert.throws(() => reduce.call(null, () => { /* empty */ }, 1), TypeError); + } + + assert.throws(() => reduce.call(createIterator([1]), undefined, 1), TypeError); + assert.throws(() => reduce.call(createIterator([1]), null, 1), TypeError); + assert.throws(() => reduce.call(createIterator([1]), {}, 1), TypeError); + + return reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1).then(it => { + assert.same(it, 7, 'basic functionality, initial'); + return reduce.call(createIterator([2]), function (a, b, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 3, 'arguments length'); + assert.same(a, 1, 'argument 1'); + assert.same(b, 2, 'argument 2'); + assert.same(counter, 0, 'counter'); + }, 1); + }).then(() => { + return reduce.call(createIterator([1, 2, 3]), (a, b) => a + b); + }).then(it => { + assert.same(it, 6, 'basic functionality, no initial'); + return reduce.call(createIterator([]), (a, b) => a + b); + }).catch(() => { + assert.required('reduce an empty iterable with no initial'); + return reduce.call(createIterator([1]), () => { throw 42; }, 1); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.some.js b/tests/unit-global/esnext.async-iterator.some.js new file mode 100644 index 000000000000..0da8663b235d --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.some.js @@ -0,0 +1,40 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +QUnit.test('AsyncIterator#some', assert => { + const { some } = AsyncIterator.prototype; + + assert.isFunction(some); + assert.arity(some, 1); + assert.name(some, 'some'); + assert.looksNative(some); + assert.nonEnumerable(AsyncIterator.prototype, 'some'); + + if (STRICT) { + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => some.call(createIterator([1]), undefined), TypeError); + assert.throws(() => some.call(createIterator([1]), null), TypeError); + assert.throws(() => some.call(createIterator([1]), {}), TypeError); + + return some.call(createIterator([1, 2, 3]), it => it === 2).then(result => { + assert.true(result, 'basic functionality, +'); + return some.call(createIterator([1, 2, 3]), it => it === 4); + }).then(result => { + assert.false(result, 'basic functionality, -'); + return some.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + }).then(() => { + return some.call(createIterator([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.take.js b/tests/unit-global/esnext.async-iterator.take.js new file mode 100644 index 000000000000..51cd24b52bf9 --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.take.js @@ -0,0 +1,33 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('AsyncIterator#take', assert => { + const { take } = AsyncIterator.prototype; + + assert.isFunction(take); + assert.arity(take, 1); + assert.name(take, 'take'); + assert.looksNative(take); + assert.nonEnumerable(AsyncIterator.prototype, 'take'); + + if (STRICT) { + assert.throws(() => take.call(undefined, 1), TypeError); + assert.throws(() => take.call(null, 1), TypeError); + } + + assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => take.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); + + return take.call(createIterator([1, 2, 3]), 2).toArray().then(it => { + assert.arrayEqual(it, [1, 2], 'basic functionality'); + return take.call(createIterator([1, 2, 3]), 1.5).toArray(); + }).then(it => { + assert.arrayEqual(it, [1], 'float'); + return take.call(createIterator([1, 2, 3]), 4).toArray(); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'big'); + return take.call(createIterator([1, 2, 3]), 0).toArray(); + }).then(it => { + assert.arrayEqual(it, [], 'zero'); + }); +}); diff --git a/tests/unit-global/esnext.async-iterator.to-array.js b/tests/unit-global/esnext.async-iterator.to-array.js new file mode 100644 index 000000000000..ba6ef4dbcb40 --- /dev/null +++ b/tests/unit-global/esnext.async-iterator.to-array.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('AsyncIterator#toArray', assert => { + const { toArray } = AsyncIterator.prototype; + + assert.isFunction(toArray); + assert.arity(toArray, 0); + assert.name(toArray, 'toArray'); + assert.looksNative(toArray); + assert.nonEnumerable(AsyncIterator.prototype, 'toArray'); + + if (STRICT) { + assert.throws(() => toArray.call(undefined), TypeError); + assert.throws(() => toArray.call(null), TypeError); + } + + return toArray.call(createIterator([1, 2, 3])).then(it => { + assert.arrayEqual(it, [1, 2, 3]); + }); +}); diff --git a/tests/unit-global/esnext.bigint.range.js b/tests/unit-global/esnext.bigint.range.js new file mode 100644 index 000000000000..feabd5dfa5e5 --- /dev/null +++ b/tests/unit-global/esnext.bigint.range.js @@ -0,0 +1,61 @@ +/* eslint-disable es/no-bigint -- safe */ +if (typeof BigInt == 'function') QUnit.test('BigInt.range', assert => { + const { range } = BigInt; + const { from } = Array; + assert.isFunction(range); + assert.name(range, 'range'); + assert.arity(range, 3); + assert.looksNative(range); + assert.nonEnumerable(BigInt, 'range'); + + let iterator = range(BigInt(1), BigInt(2)); + + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: BigInt(1), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.deepEqual(from(range(BigInt(-1), BigInt(5))), [BigInt(-1), BigInt(0), BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + assert.deepEqual(from(range(BigInt(-5), BigInt(1))), [BigInt(-5), BigInt(-4), BigInt(-3), BigInt(-2), BigInt(-1), BigInt(0)]); + assert.deepEqual( + from(range(BigInt('9007199254740991'), BigInt('9007199254740992'), { inclusive: true })), + [BigInt('9007199254740991'), BigInt('9007199254740992')], + ); + assert.deepEqual(from(range(BigInt(0), BigInt(0))), []); + assert.deepEqual(from(range(BigInt(0), BigInt(-5), BigInt(1))), []); + + iterator = range(BigInt(1), BigInt(3)); + assert.deepEqual(iterator.start, BigInt(1)); + assert.deepEqual(iterator.end, BigInt(3)); + assert.deepEqual(iterator.step, BigInt(1)); + assert.false(iterator.inclusive); + + iterator = range(BigInt(-1), BigInt(-3), { inclusive: true }); + assert.deepEqual(iterator.start, BigInt(-1)); + assert.deepEqual(iterator.end, BigInt(-3)); + assert.same(iterator.step, BigInt(-1)); + assert.true(iterator.inclusive); + + iterator = range(BigInt(-1), BigInt(-3), { step: BigInt(4), inclusive() { /* empty */ } }); + assert.same(iterator.start, BigInt(-1)); + assert.same(iterator.end, BigInt(-3)); + assert.same(iterator.step, BigInt(4)); + assert.true(iterator.inclusive); + + iterator = range(BigInt(0), BigInt(5)); + assert.throws(() => Object.getOwnPropertyDescriptor(iterator, 'start').get.call({}), TypeError); + + assert.throws(() => range(Infinity, BigInt(10), BigInt(0)), TypeError); + assert.throws(() => range(-Infinity, BigInt(10), BigInt(0)), TypeError); + assert.throws(() => range(BigInt(0), BigInt(10), Infinity), TypeError); + assert.throws(() => range(BigInt(0), BigInt(10), { step: Infinity }), TypeError); + + assert.throws(() => range({}, BigInt(1)), TypeError); + assert.throws(() => range(BigInt(1), {}), TypeError); +}); diff --git a/tests/unit-global/esnext.composite-key.js b/tests/unit-global/esnext.composite-key.js new file mode 100644 index 000000000000..b6eb154ca3a2 --- /dev/null +++ b/tests/unit-global/esnext.composite-key.js @@ -0,0 +1,46 @@ + +import { FREEZING } from '../helpers/constants.js'; + +const { getPrototypeOf, isFrozen } = Object; + +QUnit.test('compositeKey', assert => { + assert.isFunction(compositeKey); + assert.name(compositeKey, 'compositeKey'); + assert.looksNative(compositeKey); + + const key = compositeKey({}); + assert.same(typeof key, 'object'); + assert.same({}.toString.call(key), '[object Object]'); + assert.same(getPrototypeOf(key), null); + if (FREEZING) assert.true(isFrozen(key)); + + const a = ['a']; + const b = ['b']; + const c = ['c']; + + assert.same(compositeKey(a), compositeKey(a)); + assert.notSame(compositeKey(a), compositeKey(['a'])); + assert.notSame(compositeKey(a), compositeKey(a, 1)); + assert.notSame(compositeKey(a), compositeKey(a, b)); + assert.same(compositeKey(a, 1), compositeKey(a, 1)); + assert.same(compositeKey(a, b), compositeKey(a, b)); + assert.notSame(compositeKey(a, b), compositeKey(b, a)); + assert.same(compositeKey(a, b, c), compositeKey(a, b, c)); + assert.notSame(compositeKey(a, b, c), compositeKey(c, b, a)); + assert.notSame(compositeKey(a, b, c), compositeKey(a, c, b)); + assert.notSame(compositeKey(a, b, c, 1), compositeKey(a, b, c)); + assert.same(compositeKey(a, b, c, 1), compositeKey(a, b, c, 1)); + assert.same(compositeKey(1, a), compositeKey(1, a)); + assert.notSame(compositeKey(1, a), compositeKey(a, 1)); + assert.same(compositeKey(1, a, 2, b), compositeKey(1, a, 2, b)); + assert.notSame(compositeKey(1, a, 2, b), compositeKey(1, a, b, 2)); + assert.same(compositeKey(1, 2, a, b), compositeKey(1, 2, a, b)); + assert.notSame(compositeKey(1, 2, a, b), compositeKey(1, a, b, 2)); + assert.same(compositeKey(a, a), compositeKey(a, a)); + assert.notSame(compositeKey(a, a), compositeKey(a, ['a'])); + assert.notSame(compositeKey(a, a), compositeKey(a, b)); + + assert.throws(() => compositeKey(), TypeError); + assert.throws(() => compositeKey(1, 2), TypeError); + assert.throws(() => compositeKey('foo', null, true), TypeError); +}); diff --git a/tests/unit-global/esnext.composite-symbol.js b/tests/unit-global/esnext.composite-symbol.js new file mode 100644 index 000000000000..987e26033c8f --- /dev/null +++ b/tests/unit-global/esnext.composite-symbol.js @@ -0,0 +1,39 @@ + +QUnit.test('compositeSymbol', assert => { + assert.isFunction(compositeSymbol); + assert.name(compositeSymbol, 'compositeSymbol'); + assert.looksNative(compositeSymbol); + + assert.true(Object(compositeSymbol({})) instanceof Symbol); + + const a = ['a']; + const b = ['b']; + const c = ['c']; + + assert.same(compositeSymbol(a), compositeSymbol(a)); + assert.notSame(compositeSymbol(a), compositeSymbol(['a'])); + assert.notSame(compositeSymbol(a), compositeSymbol(a, 1)); + assert.notSame(compositeSymbol(a), compositeSymbol(a, b)); + assert.same(compositeSymbol(a, 1), compositeSymbol(a, 1)); + assert.same(compositeSymbol(a, b), compositeSymbol(a, b)); + assert.notSame(compositeSymbol(a, b), compositeSymbol(b, a)); + assert.same(compositeSymbol(a, b, c), compositeSymbol(a, b, c)); + assert.notSame(compositeSymbol(a, b, c), compositeSymbol(c, b, a)); + assert.notSame(compositeSymbol(a, b, c), compositeSymbol(a, c, b)); + assert.notSame(compositeSymbol(a, b, c, 1), compositeSymbol(a, b, c)); + assert.same(compositeSymbol(a, b, c, 1), compositeSymbol(a, b, c, 1)); + assert.same(compositeSymbol(1, a), compositeSymbol(1, a)); + assert.notSame(compositeSymbol(1, a), compositeSymbol(a, 1)); + assert.same(compositeSymbol(1, a, 2, b), compositeSymbol(1, a, 2, b)); + assert.notSame(compositeSymbol(1, a, 2, b), compositeSymbol(1, a, b, 2)); + assert.same(compositeSymbol(1, 2, a, b), compositeSymbol(1, 2, a, b)); + assert.notSame(compositeSymbol(1, 2, a, b), compositeSymbol(1, a, b, 2)); + assert.same(compositeSymbol(a, a), compositeSymbol(a, a)); + assert.notSame(compositeSymbol(a, a), compositeSymbol(a, ['a'])); + assert.notSame(compositeSymbol(a, a), compositeSymbol(a, b)); + assert.same(compositeSymbol(), compositeSymbol()); + assert.same(compositeSymbol(1, 2), compositeSymbol(1, 2)); + assert.notSame(compositeSymbol(1, 2), compositeSymbol(2, 1)); + assert.same(compositeSymbol('foo', null, true), compositeSymbol('foo', null, true)); + assert.same(compositeSymbol('string'), Symbol.for('string')); +}); diff --git a/tests/unit-global/esnext.data-view.set-uint8-clamped.js b/tests/unit-global/esnext.data-view.set-uint8-clamped.js new file mode 100644 index 000000000000..d820b9f67df4 --- /dev/null +++ b/tests/unit-global/esnext.data-view.set-uint8-clamped.js @@ -0,0 +1,81 @@ +import { DESCRIPTORS, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../helpers/constants.js'; + +QUnit.test('DataView.prototype.{ getUint8Clamped, setUint8Clamped }', assert => { + const { getUint8Clamped, setUint8Clamped } = DataView.prototype; + + assert.isFunction(getUint8Clamped); + assert.arity(getUint8Clamped, 1); + assert.name(getUint8Clamped, 'getUint8Clamped'); + + assert.isFunction(setUint8Clamped); + assert.arity(setUint8Clamped, 2); + assert.name(setUint8Clamped, 'setUint8Clamped'); + + assert.same(new DataView(new ArrayBuffer(8)).setUint8Clamped(0, 0), undefined, 'void'); + + function toString(it) { + return it === 0 && 1 / it === -Infinity ? '-0' : it; + } + + const data = [ + [0, 0, [0]], + [-0, 0, [0]], + [1, 1, [1]], + [-1, 0, [0]], + [1.1, 1, [1]], + [-1.1, 0, [0]], + [1.9, 2, [2]], + [-1.9, 0, [0]], + [127, 127, [127]], + [-127, 0, [0]], + [128, 128, [128]], + [-128, 0, [0]], + [255, 255, [255]], + [-255, 0, [0]], + [255.1, 255, [255]], + [255.9, 255, [255]], + [256, 255, [255]], + [32767, 255, [255]], + [-32767, 0, [0]], + [32768, 255, [255]], + [-32768, 0, [0]], + [65535, 255, [255]], + [65536, 255, [255]], + [65537, 255, [255]], + [65536.54321, 255, [255]], + [-65536.54321, 0, [0]], + [2147483647, 255, [255]], + [-2147483647, 0, [0]], + [2147483648, 255, [255]], + [-2147483648, 0, [0]], + [2147483649, 255, [255]], + [-2147483649, 0, [0]], + [4294967295, 255, [255]], + [4294967296, 255, [255]], + [4294967297, 255, [255]], + [MAX_SAFE_INTEGER, 255, [255]], + [MIN_SAFE_INTEGER, 0, [0]], + [MAX_SAFE_INTEGER + 1, 255, [255]], + [MIN_SAFE_INTEGER - 1, 0, [0]], + [MAX_SAFE_INTEGER + 3, 255, [255]], + [MIN_SAFE_INTEGER - 3, 0, [0]], + [Infinity, 255, [255]], + [-Infinity, 0, [0]], + [-Number.MAX_VALUE, 0, [0]], + [Number.MAX_VALUE, 255, [255]], + [Number.MIN_VALUE, 0, [0]], + [-Number.MIN_VALUE, 0, [0]], + [NaN, 0, [0]], + ]; + + const buffer = new ArrayBuffer(1); + const view = new DataView(buffer); + const array = DESCRIPTORS ? new Uint8Array(buffer) : null; + + for (const [value, conversion, little] of data) { + view.setUint8Clamped(0, value); + assert.same(view.getUint8Clamped(0), conversion, `DataView.prototype.setUint8Clamped + DataView.prototype.getUint8Clamped, ${ toString(value) } -> ${ toString(conversion) }`); + assert.same(view.getUint8(0), conversion, `DataView.prototype.setUint8Clamped + DataView.prototype.getUint8, ${ toString(value) } -> ${ toString(conversion) }`); + if (DESCRIPTORS) assert.arrayEqual(array, little, `DataView.prototype.setUint8Clamped + Uint8Array ${ toString(value) } -> [${ little }]`); + } +}); diff --git a/tests/unit-global/esnext.function.demethodize.js b/tests/unit-global/esnext.function.demethodize.js new file mode 100644 index 000000000000..848ef294f1ad --- /dev/null +++ b/tests/unit-global/esnext.function.demethodize.js @@ -0,0 +1,10 @@ +QUnit.test('Function#demethodize', assert => { + const { demethodize } = Function.prototype; + assert.isFunction(demethodize); + assert.arity(demethodize, 0); + assert.name(demethodize, 'demethodize'); + assert.looksNative(demethodize); + assert.nonEnumerable(Function.prototype, 'demethodize'); + assert.same(function () { return 42; }.demethodize()(), 42); + assert.deepEqual(Array.prototype.slice.demethodize()([1, 2, 3], 1), [2, 3]); +}); diff --git a/tests/unit-global/esnext.function.is-callable.js b/tests/unit-global/esnext.function.is-callable.js new file mode 100644 index 000000000000..b29f194c9815 --- /dev/null +++ b/tests/unit-global/esnext.function.is-callable.js @@ -0,0 +1,40 @@ +import { fromSource } from '../helpers/helpers.js'; + +QUnit.test('Function.isCallable', assert => { + const { isCallable } = Function; + assert.isFunction(isCallable); + assert.arity(isCallable, 1); + assert.name(isCallable, 'isCallable'); + assert.looksNative(isCallable); + assert.nonEnumerable(Function, 'isCallable'); + assert.false(isCallable({}), 'object'); + assert.false(isCallable(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }()), 'arguments'); + assert.false(isCallable([]), 'array'); + assert.false(isCallable(/./), 'regex'); + assert.false(isCallable(1), 'number'); + assert.false(isCallable(true), 'boolean'); + assert.false(isCallable('1'), 'string'); + assert.false(isCallable(null), 'null'); + assert.false(isCallable(), 'undefined'); + assert.true(isCallable(Function.call), 'native function'); + // eslint-disable-next-line prefer-arrow-callback -- required + assert.true(isCallable(function () { /* empty */ }), 'function'); + + const arrow = fromSource('it => it'); + if (arrow) assert.true(isCallable(arrow), 'arrow'); + const klass = fromSource('class {}'); + // Safari 9 and Edge 13- bugs + if (klass && !/constructor|function/.test(klass)) assert.false(isCallable(klass), 'class'); + const gen = fromSource('function * () {}'); + if (gen) assert.true(isCallable(gen), 'gen'); + const asyncFunc = fromSource('async function () {}'); + if (asyncFunc) assert.true(isCallable(asyncFunc), 'asyncFunc'); + const asyncGen = fromSource('async * function () {}'); + if (asyncGen) assert.true(isCallable(asyncGen), 'asyncGen'); + const method = fromSource('({f(){}}).f'); + // Safari 9 bug + if (method && !/function/.test(method)) assert.true(isCallable(method), 'method'); +}); diff --git a/tests/unit-global/esnext.function.is-constructor.js b/tests/unit-global/esnext.function.is-constructor.js new file mode 100644 index 000000000000..e07c1ab765aa --- /dev/null +++ b/tests/unit-global/esnext.function.is-constructor.js @@ -0,0 +1,45 @@ +import { fromSource } from '../helpers/helpers.js'; + +QUnit.test('Function.isConstructor', assert => { + const { isConstructor } = Function; + assert.isFunction(isConstructor); + assert.arity(isConstructor, 1); + assert.name(isConstructor, 'isConstructor'); + assert.looksNative(isConstructor); + assert.nonEnumerable(Function, 'isConstructor'); + assert.false(isConstructor({}), 'object'); + assert.false(isConstructor(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }()), 'arguments'); + assert.false(isConstructor([]), 'array'); + assert.false(isConstructor(/./), 'regex'); + assert.false(isConstructor(1), 'number'); + assert.false(isConstructor(true), 'boolean'); + assert.false(isConstructor('1'), 'string'); + assert.false(isConstructor(null), 'null'); + assert.false(isConstructor(), 'undefined'); + // assert.false(isConstructor(Function.call), 'native function'); // fails in some old engines + // eslint-disable-next-line prefer-arrow-callback -- required + assert.true(isConstructor(function () { /* empty */ }), 'function'); + + const arrow = fromSource('it => it'); + if (arrow) assert.false(isConstructor(arrow), 'arrow'); + const klass = fromSource('class {}'); + // Safari 9 and Edge 13- bugs + if (klass && !/constructor|function/.test(klass)) assert.true(isConstructor(klass), 'class'); + const Gen = fromSource('function * () {}'); + // V8 ~ Chrome 49- bug + if (Gen) try { + new Gen(); + } catch { + assert.false(isConstructor(Gen), 'gen'); + } + const asyncFunc = fromSource('async function () {}'); + if (asyncFunc) assert.false(isConstructor(asyncFunc), 'asyncFunc'); + const asyncGen = fromSource('async * function () {}'); + if (asyncGen) assert.false(isConstructor(asyncGen), 'asyncGen'); + const method = fromSource('({f(){}}).f'); + // Safari 9 bug + if (method && !/function/.test(method)) assert.false(isConstructor(method), 'method'); +}); diff --git a/tests/unit-global/esnext.function.metadata.js b/tests/unit-global/esnext.function.metadata.js new file mode 100644 index 000000000000..6b35e2e1185e --- /dev/null +++ b/tests/unit-global/esnext.function.metadata.js @@ -0,0 +1,4 @@ +QUnit.test('Function#@@metadata', assert => { + assert.true(Symbol.metadata in Function.prototype); + assert.same(Function.prototype[Symbol.metadata], null, 'is null'); +}); diff --git a/tests/unit-global/esnext.function.un-this.js b/tests/unit-global/esnext.function.un-this.js new file mode 100644 index 000000000000..8c6aafc92710 --- /dev/null +++ b/tests/unit-global/esnext.function.un-this.js @@ -0,0 +1,10 @@ +QUnit.test('Function#unThis', assert => { + const { unThis } = Function.prototype; + assert.isFunction(unThis); + assert.arity(unThis, 0); + // assert.name(unThis, 'unThis'); + assert.looksNative(unThis); + assert.nonEnumerable(Function.prototype, 'unThis'); + assert.same(function () { return 42; }.unThis()(), 42); + assert.deepEqual(Array.prototype.slice.unThis()([1, 2, 3], 1), [2, 3]); +}); diff --git a/tests/unit-global/esnext.iterator.as-indexed-pairs.js b/tests/unit-global/esnext.iterator.as-indexed-pairs.js new file mode 100644 index 000000000000..7bf4dcdc7864 --- /dev/null +++ b/tests/unit-global/esnext.iterator.as-indexed-pairs.js @@ -0,0 +1,22 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('Iterator#asIndexedPairs', assert => { + const { asIndexedPairs } = Iterator.prototype; + + assert.isFunction(asIndexedPairs); + assert.arity(asIndexedPairs, 0); + // assert.name(asIndexedPairs, 'asIndexedPairs'); + assert.looksNative(asIndexedPairs); + assert.nonEnumerable(Iterator.prototype, 'asIndexedPairs'); + + assert.arrayEqual(asIndexedPairs.call(createIterator(['a', 'b', 'c'])).toArray().toString(), '0,a,1,b,2,c', 'basic functionality'); + + if (STRICT) { + assert.throws(() => asIndexedPairs.call(undefined), TypeError); + assert.throws(() => asIndexedPairs.call(null), TypeError); + } + + assert.throws(() => asIndexedPairs.call({}).next(), TypeError); + assert.throws(() => asIndexedPairs.call([]).next(), TypeError); +}); diff --git a/tests/unit-global/esnext.iterator.chunks.js b/tests/unit-global/esnext.iterator.chunks.js new file mode 100644 index 000000000000..f2ffae6de392 --- /dev/null +++ b/tests/unit-global/esnext.iterator.chunks.js @@ -0,0 +1,47 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +const { from } = Array; + +QUnit.test('Iterator#chunks', assert => { + const { chunks } = Iterator.prototype; + + assert.isFunction(chunks); + assert.arity(chunks, 1); + assert.name(chunks, 'chunks'); + assert.looksNative(chunks); + assert.nonEnumerable(Iterator.prototype, 'chunks'); + + assert.arrayEqual(from(chunks.call(createIterator([1, 2, 3]), 2)), [[1, 2], [3]], 'basic functionality'); + assert.arrayEqual(from(chunks.call(createIterator([1, 2, 3, 4]), 2)), [[1, 2], [3, 4]], 'basic functionality'); + assert.arrayEqual(from(chunks.call(createIterator([]), 2)), [], 'basic functionality on empty iterable'); + + const it = createIterator([1, 2, 3]); + const result = chunks.call(it, 3); + assert.isIterable(result, 'returns iterable'); + assert.isIterator(result, 'returns iterator'); + assert.true(result instanceof Iterator, 'returns iterator'); + assert.deepEqual(result.next(), { done: false, value: [1, 2, 3] }, '.next with active inner iterator result'); + assert.deepEqual(result.return(), { done: true, value: undefined }, '.return with active inner iterator result'); + assert.deepEqual(result.next(), { done: true, value: undefined }, '.return with active inner iterator result on closed iterator'); + + if (STRICT) { + assert.throws(() => chunks.call('', 1), TypeError, 'iterable non-object this'); + assert.throws(() => chunks.call(undefined, 1), TypeError, 'non-iterable-object this #1'); + assert.throws(() => chunks.call(null, 1), TypeError, 'non-iterable-object this #2'); + assert.throws(() => chunks.call(5, 1), TypeError, 'non-iterable-object this #3'); + } + + assert.throws(() => chunks.call(it), RangeError, 'throws on empty argument'); + assert.throws(() => chunks.call(it, -1), RangeError, 'throws on negative argument'); + + const observableReturn = { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }; + const itObservable = createIterator([1, 2, 3], observableReturn); + assert.throws(() => chunks.call(itObservable, 0x100000000), RangeError, 'throws on argument more then 2^32 - 1'); + assert.true(itObservable.called, 'iterator closed on argument validation error'); +}); diff --git a/tests/unit-global/esnext.iterator.indexed.js b/tests/unit-global/esnext.iterator.indexed.js new file mode 100644 index 000000000000..3c1dd51da544 --- /dev/null +++ b/tests/unit-global/esnext.iterator.indexed.js @@ -0,0 +1,22 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('Iterator#indexed', assert => { + const { indexed } = Iterator.prototype; + + assert.isFunction(indexed); + assert.arity(indexed, 0); + assert.name(indexed, 'indexed'); + assert.looksNative(indexed); + assert.nonEnumerable(Iterator.prototype, 'indexed'); + + assert.arrayEqual(indexed.call(createIterator(['a', 'b', 'c'])).toArray().toString(), '0,a,1,b,2,c', 'basic functionality'); + + if (STRICT) { + assert.throws(() => indexed.call(undefined), TypeError); + assert.throws(() => indexed.call(null), TypeError); + } + + assert.throws(() => indexed.call({}).next(), TypeError); + assert.throws(() => indexed.call([]).next(), TypeError); +}); diff --git a/tests/unit-global/esnext.iterator.range.js b/tests/unit-global/esnext.iterator.range.js new file mode 100644 index 000000000000..40942ada26b1 --- /dev/null +++ b/tests/unit-global/esnext.iterator.range.js @@ -0,0 +1,127 @@ +import { MAX_SAFE_INTEGER } from '../helpers/constants.js'; +/* eslint-disable es/no-bigint -- safe */ +QUnit.test('Iterator.range', assert => { + const { range } = Iterator; + const { from } = Array; + assert.isFunction(range); + assert.name(range, 'range'); + assert.arity(range, 3); + assert.looksNative(range); + assert.nonEnumerable(Iterator, 'range'); + + let iterator = range(1, 2); + + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: 1, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.deepEqual(from(range(-1, 5)), [-1, 0, 1, 2, 3, 4]); + assert.deepEqual(from(range(-5, 1)), [-5, -4, -3, -2, -1, 0]); + assert.deepEqual( + from(range(0, 1, 0.1)), + [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9], + ); + assert.deepEqual( + from(range(MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1, { inclusive: true })), + [MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1], + ); + assert.deepEqual(from(range(0, 0)), []); + assert.deepEqual(from(range(0, -5, 1)), []); + + assert.deepEqual(from(range(NaN, 0)), []); + assert.deepEqual(from(range(0, NaN)), []); + assert.deepEqual(from(range(NaN, NaN)), []); + assert.deepEqual(from(range(0, 0, { step: NaN })), []); + assert.deepEqual(from(range(0, 5, NaN)), []); + + iterator = range(1, 3); + assert.deepEqual(iterator.start, 1); + assert.deepEqual(iterator.end, 3); + assert.deepEqual(iterator.step, 1); + assert.false(iterator.inclusive); + + iterator = range(-1, -3, { inclusive: true }); + assert.deepEqual(iterator.start, -1); + assert.deepEqual(iterator.end, -3); + assert.same(iterator.step, -1); + assert.true(iterator.inclusive); + + iterator = range(-1, -3, { step: 4, inclusive() { /* empty */ } }); + assert.same(iterator.start, -1); + assert.same(iterator.end, -3); + assert.same(iterator.step, 4); + assert.true(iterator.inclusive); + + iterator = range(0, 5); + assert.throws(() => Object.getOwnPropertyDescriptor(iterator, 'start').get.call({}), TypeError); + + assert.throws(() => range(Infinity, 10, 0), RangeError); + assert.throws(() => range(-Infinity, 10, 0), RangeError); + assert.throws(() => range(0, 10, Infinity), RangeError); + assert.throws(() => range(0, 10, { step: Infinity }), RangeError); + + assert.throws(() => range({}, 1), TypeError); + assert.throws(() => range(1, {}), TypeError); + assert.throws(() => range('1', 2), TypeError); + assert.throws(() => range({ valueOf() { return 1; } }, 2), TypeError); + + if (typeof BigInt == 'function') { + iterator = range(BigInt(1), BigInt(2)); + + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: BigInt(1), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.deepEqual(from(range(BigInt(-1), BigInt(5))), [BigInt(-1), BigInt(0), BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + assert.deepEqual(from(range(BigInt(-5), BigInt(1))), [BigInt(-5), BigInt(-4), BigInt(-3), BigInt(-2), BigInt(-1), BigInt(0)]); + assert.deepEqual( + from(range(BigInt('9007199254740991'), BigInt('9007199254740992'), { inclusive: true })), + [BigInt('9007199254740991'), BigInt('9007199254740992')], + ); + assert.deepEqual(from(range(BigInt(0), BigInt(0))), []); + assert.deepEqual(from(range(BigInt(0), BigInt(-5), BigInt(1))), []); + + iterator = range(BigInt(1), BigInt(3)); + assert.deepEqual(iterator.start, BigInt(1)); + assert.deepEqual(iterator.end, BigInt(3)); + assert.deepEqual(iterator.step, BigInt(1)); + assert.false(iterator.inclusive); + + iterator = range(BigInt(-1), BigInt(-3), { inclusive: true }); + assert.deepEqual(iterator.start, BigInt(-1)); + assert.deepEqual(iterator.end, BigInt(-3)); + assert.same(iterator.step, BigInt(-1)); + assert.true(iterator.inclusive); + + iterator = range(BigInt(-1), BigInt(-3), { step: BigInt(4), inclusive() { /* empty */ } }); + assert.same(iterator.start, BigInt(-1)); + assert.same(iterator.end, BigInt(-3)); + assert.same(iterator.step, BigInt(4)); + assert.true(iterator.inclusive); + + iterator = range(BigInt(0), BigInt(5)); + assert.throws(() => Object.getOwnPropertyDescriptor(iterator, 'start').get.call({}), TypeError); + + assert.throws(() => range(Infinity, BigInt(10), BigInt(0)), TypeError); + assert.throws(() => range(-Infinity, BigInt(10), BigInt(0)), TypeError); + assert.throws(() => range(BigInt(0), BigInt(10), Infinity), TypeError); + assert.throws(() => range(BigInt(0), BigInt(10), { step: Infinity }), TypeError); + + assert.throws(() => range({}, BigInt(1)), TypeError); + assert.throws(() => range(BigInt(1), {}), TypeError); + } +}); diff --git a/tests/unit-global/esnext.iterator.sliding.js b/tests/unit-global/esnext.iterator.sliding.js new file mode 100644 index 000000000000..e74ffc0c2afa --- /dev/null +++ b/tests/unit-global/esnext.iterator.sliding.js @@ -0,0 +1,48 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +const { from } = Array; + +QUnit.test('Iterator#sliding', assert => { + const { sliding } = Iterator.prototype; + + assert.isFunction(sliding); + assert.arity(sliding, 1); + assert.name(sliding, 'sliding'); + assert.looksNative(sliding); + assert.nonEnumerable(Iterator.prototype, 'sliding'); + + assert.arrayEqual(from(sliding.call(createIterator([1, 2, 3]), 2)), [[1, 2], [2, 3]], 'basic functionality #1'); + assert.arrayEqual(from(sliding.call(createIterator([1, 2, 3, 4]), 2)), [[1, 2], [2, 3], [3, 4]], 'basic functionality #2'); + assert.arrayEqual(from(sliding.call(createIterator([1, 2]), 3)), [[1, 2]], 'basic functionality #3'); + assert.arrayEqual(from(sliding.call(createIterator([]), 2)), [], 'basic functionality on empty iterable'); + + const it = createIterator([1, 2, 3]); + const result = sliding.call(it, 3); + assert.isIterable(result, 'returns iterable'); + assert.isIterator(result, 'returns iterator'); + assert.true(result instanceof Iterator, 'returns iterator'); + assert.deepEqual(result.next(), { done: false, value: [1, 2, 3] }, '.next with active inner iterator result'); + assert.deepEqual(result.return(), { done: true, value: undefined }, '.return with active inner iterator result'); + assert.deepEqual(result.next(), { done: true, value: undefined }, '.return with active inner iterator result on closed iterator'); + + if (STRICT) { + assert.throws(() => sliding.call('', 1), TypeError, 'iterable non-object this'); + assert.throws(() => sliding.call(undefined, 1), TypeError, 'non-iterable-object this #1'); + assert.throws(() => sliding.call(null, 1), TypeError, 'non-iterable-object this #2'); + assert.throws(() => sliding.call(5, 1), TypeError, 'non-iterable-object this #3'); + } + + assert.throws(() => sliding.call(it), RangeError, 'throws on empty argument'); + assert.throws(() => sliding.call(it, -1), RangeError, 'throws on negative argument'); + + const observableReturn = { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }; + const itObservable = createIterator([1, 2, 3], observableReturn); + assert.throws(() => sliding.call(itObservable, 0x100000000), RangeError, 'throws on argument more then 2^32 - 1'); + assert.true(itObservable.called, 'iterator closed on argument validation error'); +}); diff --git a/tests/unit-global/esnext.iterator.to-async.js b/tests/unit-global/esnext.iterator.to-async.js new file mode 100644 index 000000000000..7ff7238fba0f --- /dev/null +++ b/tests/unit-global/esnext.iterator.to-async.js @@ -0,0 +1,43 @@ +import { STRICT } from '../helpers/constants.js'; +import ITERATOR from 'core-js-pure/es/symbol/iterator'; + +QUnit.test('Iterator#toAsync', assert => { + const { toAsync } = Iterator.prototype; + + assert.isFunction(toAsync); + assert.arity(toAsync, 0); + assert.name(toAsync, 'toAsync'); + assert.looksNative(toAsync); + assert.nonEnumerable(Iterator.prototype, 'toAsync'); + + if (STRICT) { + assert.throws(() => toAsync.call(undefined), TypeError); + assert.throws(() => toAsync.call(null), TypeError); + } + + const closableIterator = { + closed: false, + [ITERATOR]() { return this; }, + next() { + return { value: Promise.reject(42), done: false }; + }, + return() { + this.closed = true; + return { value: undefined, done: true }; + }, + }; + + return [1, 2, 3].values().toAsync().map(it => Promise.resolve(it)).toArray().then(it => { + assert.arrayEqual(it, [1, 2, 3]); + return new Set([1, 2, 3]).values().toAsync().map(el => Promise.resolve(el)).toArray(); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3]); + }).then(() => { + return Iterator.from(closableIterator).toAsync().toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + assert.true(closableIterator.closed, 'doesn\'t close sync iterator on promise rejection'); + }); +}); diff --git a/tests/unit-global/esnext.iterator.windows.js b/tests/unit-global/esnext.iterator.windows.js new file mode 100644 index 000000000000..4032a1ed47f5 --- /dev/null +++ b/tests/unit-global/esnext.iterator.windows.js @@ -0,0 +1,54 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +const { from } = Array; + +QUnit.test('Iterator#windows', assert => { + const { windows } = Iterator.prototype; + + assert.isFunction(windows); + assert.arity(windows, 1); + assert.name(windows, 'windows'); + assert.looksNative(windows); + assert.nonEnumerable(Iterator.prototype, 'windows'); + + assert.arrayEqual(from(windows.call(createIterator([1, 2, 3]), 2)), [[1, 2], [2, 3]], 'basic functionality #1'); + assert.arrayEqual(from(windows.call(createIterator([1, 2, 3, 4]), 2)), [[1, 2], [2, 3], [3, 4]], 'basic functionality #2'); + assert.arrayEqual(from(windows.call(createIterator([1, 2]), 3)), [], 'basic functionality #3'); + assert.arrayEqual(from(windows.call(createIterator([]), 2)), [], 'basic functionality on empty iterable'); + + assert.arrayEqual(from(windows.call(createIterator([1, 2]), 3, 'only-full')), [], 'undersized #1'); + assert.arrayEqual(from(windows.call(createIterator([1, 2]), 3, 'allow-partial')), [[1, 2]], 'undersized #2'); + + const it = createIterator([1, 2, 3]); + const result = windows.call(it, 3); + assert.isIterable(result, 'returns iterable'); + assert.isIterator(result, 'returns iterator'); + assert.true(result instanceof Iterator, 'returns iterator'); + assert.deepEqual(result.next(), { done: false, value: [1, 2, 3] }, '.next with active inner iterator result'); + assert.deepEqual(result.return(), { done: true, value: undefined }, '.return with active inner iterator result'); + assert.deepEqual(result.next(), { done: true, value: undefined }, '.return with active inner iterator result on closed iterator'); + + if (STRICT) { + assert.throws(() => windows.call('', 1), TypeError, 'iterable non-object this'); + assert.throws(() => windows.call(undefined, 1), TypeError, 'non-iterable-object this #1'); + assert.throws(() => windows.call(null, 1), TypeError, 'non-iterable-object this #2'); + assert.throws(() => windows.call(5, 1), TypeError, 'non-iterable-object this #3'); + } + + assert.throws(() => windows.call(it), RangeError, 'throws on empty argument'); + assert.throws(() => windows.call(it, -1), RangeError, 'throws on negative argument'); + + const observableReturn = { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }; + const itObservable = createIterator([1, 2, 3], observableReturn); + assert.throws(() => windows.call(itObservable, 0x100000000), RangeError, 'throws on argument more then 2^32 - 1'); + assert.true(itObservable.called, 'iterator closed on argument validation error'); + + assert.throws(() => windows.call(createIterator([1]), 2, null), TypeError, 'incorrect `undersized` argument #1'); + assert.throws(() => windows.call(createIterator([1]), 2, 'allowpartial'), TypeError, 'incorrect `undersized` argument #2'); +}); diff --git a/tests/unit-global/esnext.iterator.zip-keyed.js b/tests/unit-global/esnext.iterator.zip-keyed.js new file mode 100644 index 000000000000..9071515041de --- /dev/null +++ b/tests/unit-global/esnext.iterator.zip-keyed.js @@ -0,0 +1,100 @@ +import { createIterator } from '../helpers/helpers.js'; +import { DESCRIPTORS } from '../helpers/constants.js'; + +function nullProto(obj) { + return Object.assign(Object.create(null), obj); +} + +QUnit.test('Iterator.zipKeyed', assert => { + const { zipKeyed } = Iterator; + const { from } = Array; + const { defineProperty } = Object; + + assert.isFunction(zipKeyed); + assert.arity(zipKeyed, 1); + assert.name(zipKeyed, 'zipKeyed'); + assert.looksNative(zipKeyed); + assert.nonEnumerable(Iterator, 'zipKeyed'); + + let result = zipKeyed({ a: [0, 1, 2], b: [3, 4, 5], c: [7, 8, 9] }); + assert.deepEqual(from(result), [{ a: 0, b: 3, c: 7 }, { a: 1, b: 4, c: 8 }, { a: 2, b: 5, c: 9 }]); + result = zipKeyed({ a: [0, 1, 2], b: [3, 4, 5, 6], c: [7, 8, 9] }); + assert.deepEqual(from(result), [{ a: 0, b: 3, c: 7 }, { a: 1, b: 4, c: 8 }, { a: 2, b: 5, c: 9 }]); + result = zipKeyed({ a: [0, 1, 2], b: [3, 4, 5, 6], c: [7, 8, 9] }, { mode: 'longest', padding: { c: 10 } }); + assert.deepEqual(from(result), [{ a: 0, b: 3, c: 7 }, { a: 1, b: 4, c: 8 }, { a: 2, b: 5, c: 9 }, { a: undefined, b: 6, c: 10 }]); + result = zipKeyed({ a: [0, 1, 2], b: [3, 4, 5, 6], c: [7, 8, 9] }, { mode: 'strict' }); + assert.throws(() => from(result), TypeError); + + if (DESCRIPTORS) { + let obj = {}; + defineProperty(obj, 'a', { get: () => [0, 1, 2], enumerable: true }); + defineProperty(obj, 'b', { get: () => [3, 4, 5], enumerable: true }); + defineProperty(obj, 'c', { get: () => [7, 8, 9], enumerable: true }); + defineProperty(obj, Symbol('d'), { get: () => [10, 11, 12] }); + assert.deepEqual(from(zipKeyed(obj)), [{ a: 0, b: 3, c: 7 }, { a: 1, b: 4, c: 8 }, { a: 2, b: 5, c: 9 }]); + + const it = createIterator([1, 2], { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }); + obj = { a: it }; + defineProperty(obj, 'b', { get: () => { throw new Error(); }, enumerable: true }); + assert.throws(() => from(zipKeyed(obj)), Error); + assert.true(it.called, 'iterator return called'); + + const foo = Symbol('foo'); + const bar = Symbol('bar'); + const zipped = Iterator.zipKeyed({ [foo]: [1, 2, 3], [bar]: [4, 5, 6], baz: [7, 8, 9] }); + result = from(zipped); + assert.same(result[0][foo], 1); + assert.same(result[0][bar], 4); + assert.same(result[0].baz, 7); + + assert.same(result[1][foo], 2); + assert.same(result[1][bar], 5); + assert.same(result[1].baz, 8); + + assert.same(result[2][foo], 3); + assert.same(result[2][bar], 6); + assert.same(result[2].baz, 9); + } + + { + const $result = zipKeyed({ + a: [0, 1, 2], + b: [3, 4, 5, 6, 7], + c: [8, 9], + }, { + mode: 'longest', + }); + + assert.deepEqual(from($result), [ + nullProto({ a: 0, b: 3, c: 8 }), + nullProto({ a: 1, b: 4, c: 9 }), + nullProto({ a: 2, b: 5, c: undefined }), + nullProto({ a: undefined, b: 6, c: undefined }), + nullProto({ a: undefined, b: 7, c: undefined }), + ]); + } + + { + const $result = zipKeyed({ + a: [0, 1, 2], + b: [3, 4, 5, 6, 7], + c: [8, 9], + }, { + mode: 'longest', + padding: { a: 'A', b: 'B', c: 'C' }, + }); + + assert.deepEqual(from($result), [ + nullProto({ a: 0, b: 3, c: 8 }), + nullProto({ a: 1, b: 4, c: 9 }), + nullProto({ a: 2, b: 5, c: 'C' }), + nullProto({ a: 'A', b: 6, c: 'C' }), + nullProto({ a: 'A', b: 7, c: 'C' }), + ]); + } +}); diff --git a/tests/unit-global/esnext.iterator.zip.js b/tests/unit-global/esnext.iterator.zip.js new file mode 100644 index 000000000000..6c8b6c2703f6 --- /dev/null +++ b/tests/unit-global/esnext.iterator.zip.js @@ -0,0 +1,102 @@ +import { createIterator } from '../helpers/helpers.js'; + +QUnit.test('Iterator.zip', assert => { + const { zip } = Iterator; + const { from } = Array; + + assert.isFunction(zip); + assert.arity(zip, 1); + assert.name(zip, 'zip'); + assert.looksNative(zip); + assert.nonEnumerable(Iterator, 'zip'); + + let result = zip([[1, 2, 3], [4, 5, 6]]); + assert.deepEqual(from(result), [[1, 4], [2, 5], [3, 6]]); + result = zip([[1, 2, 3], [4, 5, 6, 7]]); + assert.deepEqual(from(result), [[1, 4], [2, 5], [3, 6]]); + result = zip([[1, 2, 3], [4, 5, 6, 7]], { mode: 'longest', padding: [9] }); + assert.deepEqual(from(result), [[1, 4], [2, 5], [3, 6], [9, 7]]); + result = zip([[1, 2, 3, 4], [5, 6, 7]], { mode: 'longest', padding: [1, 9] }); + assert.deepEqual(from(result), [[1, 5], [2, 6], [3, 7], [4, 9]]); + result = zip([[1, 2, 3], [4, 5, 6], [7, 8, 9]], { mode: 'strict' }); + assert.deepEqual(from(result), [[1, 4, 7], [2, 5, 8], [3, 6, 9]]); + result = zip([[1, 2, 3], [4, 5, 6, 7]], { mode: 'strict' }); + assert.throws(() => from(result), TypeError); + + const observableReturn = { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }; + + { + const it1 = createIterator([1, 2], observableReturn); + const it2 = createIterator([3, 4], observableReturn); + result = zip([it1, it2]); + assert.deepEqual(result.next().value, [1, 3]); + assert.deepEqual(result.return(), { done: true, value: undefined }); + assert.deepEqual(result.next(), { done: true, value: undefined }); + assert.true(it1.called, 'first iterator return called'); + assert.true(it2.called, 'second iterator return called'); + } + + { + const it = createIterator([1, 2, 3], observableReturn); + result = zip([it, [4, 5]], { mode: 'strict' }); + assert.throws(() => from(result), TypeError); + assert.true(it.called, 'iterator return called #1'); + } + + { + const it = createIterator([3, 4, 5], observableReturn); + result = zip([[1, 2], it], { mode: 'strict' }); + assert.throws(() => from(result), TypeError); + assert.true(it.called, 'iterator return called #2'); + } + + { + const it1 = createIterator([1, 2], { next() { throw new Error(); } }); + const it2 = createIterator([3, 4], observableReturn); + result = zip([it1, it2]); + assert.throws(() => from(result), Error); + assert.true(it2.called, 'iterator return called #4'); + } + + { + const $result = zip([ + [0, 1, 2], + [3, 4, 5, 6, 7], + [8, 9], + ], { + mode: 'longest', + }); + + assert.deepEqual(from($result), [ + [0, 3, 8], + [1, 4, 9], + [2, 5, undefined], + [undefined, 6, undefined], + [undefined, 7, undefined], + ]); + } + + { + const $result = zip([ + [0, 1, 2], + [3, 4, 5, 6, 7], + [8, 9], + ], { + mode: 'longest', + padding: ['A', 'B', 'C'], + }); + + assert.deepEqual(from($result), [ + [0, 3, 8], + [1, 4, 9], + [2, 5, 'C'], + ['A', 6, 'C'], + ['A', 7, 'C'], + ]); + } +}); diff --git a/tests/unit-global/esnext.map.delete-all.js b/tests/unit-global/esnext.map.delete-all.js new file mode 100644 index 000000000000..5796b7ac0c2a --- /dev/null +++ b/tests/unit-global/esnext.map.delete-all.js @@ -0,0 +1,31 @@ +QUnit.test('Map#deleteAll', assert => { + const { deleteAll } = Map.prototype; + const { from } = Array; + + assert.isFunction(deleteAll); + assert.arity(deleteAll, 0); + assert.name(deleteAll, 'deleteAll'); + assert.looksNative(deleteAll); + assert.nonEnumerable(Map.prototype, 'deleteAll'); + + let set = new Map([[1, 2], [2, 3], [3, 4]]); + assert.true(set.deleteAll(1, 2)); + assert.deepEqual(from(set), [[3, 4]]); + + set = new Map([[1, 2], [2, 3], [3, 4]]); + assert.false(set.deleteAll(3, 4)); + assert.deepEqual(from(set), [[1, 2], [2, 3]]); + + set = new Map([[1, 2], [2, 3], [3, 4]]); + assert.false(set.deleteAll(4, 5)); + assert.deepEqual(from(set), [[1, 2], [2, 3], [3, 4]]); + + set = new Map([[1, 2], [2, 3], [3, 4]]); + assert.true(set.deleteAll()); + assert.deepEqual(from(set), [[1, 2], [2, 3], [3, 4]]); + + assert.throws(() => deleteAll.call({ delete() { /* empty */ } }, 1, 2, 3)); + assert.throws(() => deleteAll.call({}, 1, 2, 3), TypeError); + assert.throws(() => deleteAll.call(undefined, 1, 2, 3), TypeError); + assert.throws(() => deleteAll.call(null, 1, 2, 3), TypeError); +}); diff --git a/tests/unit-global/esnext.map.emplace.js b/tests/unit-global/esnext.map.emplace.js new file mode 100644 index 000000000000..098039221cb9 --- /dev/null +++ b/tests/unit-global/esnext.map.emplace.js @@ -0,0 +1,50 @@ +QUnit.test('Map#emplace', assert => { + const { emplace } = Map.prototype; + assert.isFunction(emplace); + assert.arity(emplace, 2); + assert.name(emplace, 'emplace'); + assert.looksNative(emplace); + assert.nonEnumerable(Map.prototype, 'emplace'); + + const map = new Map([['a', 2]]); + let handler = { + update(value, key, that) { + assert.same(this, handler, 'correct handler in callback'); + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, 'a', 'correct key in callback'); + assert.same(that, map, 'correct map in callback'); + return value ** 2; + }, + insert() { + assert.avoid(); + }, + }; + assert.same(map.emplace('a', handler), 4, 'returns a correct value'); + handler = { + update() { + assert.avoid(); + }, + insert(key, that) { + assert.same(this, handler, 'correct handler in callback'); + assert.same(arguments.length, 2, 'correct number of callback arguments'); + assert.same(key, 'b', 'correct key in callback'); + assert.same(that, map, 'correct map in callback'); + return 3; + }, + }; + assert.same(map.emplace('b', handler), 3, 'returns a correct value'); + assert.same(map.size, 2, 'correct size'); + assert.same(map.get('a'), 4, 'correct result #1'); + assert.same(map.get('b'), 3, 'correct result #2'); + + assert.same(new Map([['a', 2]]).emplace('b', { insert: () => 3 }), 3); + assert.same(new Map([['a', 2]]).emplace('a', { update: value => value ** 2 }), 4); + + handler = { update() { /* empty */ }, insert() { /* empty */ } }; + assert.throws(() => new Map().emplace('a'), TypeError); + assert.throws(() => emplace.call({}, 'a', handler), TypeError); + assert.throws(() => emplace.call([], 'a', handler), TypeError); + assert.throws(() => emplace.call(undefined, 'a', handler), TypeError); + assert.throws(() => emplace.call(null, 'a', handler), TypeError); +}); diff --git a/tests/unit-global/esnext.map.every.js b/tests/unit-global/esnext.map.every.js new file mode 100644 index 000000000000..533d70cd69df --- /dev/null +++ b/tests/unit-global/esnext.map.every.js @@ -0,0 +1,36 @@ +QUnit.test('Map#every', assert => { + const { every } = Map.prototype; + assert.isFunction(every); + assert.arity(every, 1); + assert.name(every, 'every'); + assert.looksNative(every); + assert.nonEnumerable(Map.prototype, 'every'); + + let map = new Map([[9, 1]]); + const context = {}; + map.every(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 9, 'correct index in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + map = new Map([[0, 1], [1, 2], [2, 3]]); + assert.true(map.every(it => typeof it == 'number')); + assert.true(map.every(it => it < 4)); + assert.false(map.every(it => it < 3)); + assert.false(map.every(it => typeof it == 'string')); + assert.true(map.every(function () { + return +this === 1; + }, 1)); + let result = ''; + map.every((value, key) => result += key); + assert.same(result, '012'); + assert.true(map.every((value, key, that) => that === map)); + + assert.throws(() => every.call(new Set(), () => { /* empty */ }), TypeError); + assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => every.call([], () => { /* empty */ }), TypeError); + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.map.filter.js b/tests/unit-global/esnext.map.filter.js new file mode 100644 index 000000000000..f8ddaca861a7 --- /dev/null +++ b/tests/unit-global/esnext.map.filter.js @@ -0,0 +1,45 @@ +QUnit.test('Map#filter', assert => { + const { filter } = Map.prototype; + const { from } = Array; + + assert.isFunction(filter); + assert.arity(filter, 1); + assert.name(filter, 'filter'); + assert.looksNative(filter); + assert.nonEnumerable(Map.prototype, 'filter'); + + const map = new Map([[1, 2]]); + const context = {}; + map.filter(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Map().filter(it => it) instanceof Map); + + assert.deepEqual(from(new Map([ + ['a', 1], + [1, 2], + ['b', 3], + [2, 'q'], + ['c', {}], + [3, 4], + ['d', true], + [4, 5], + ]).filter(it => typeof it == 'number')), [ + ['a', 1], + [1, 2], + ['b', 3], + [3, 4], + [4, 5], + ]); + + assert.throws(() => filter.call(new Set(), () => { /* empty */ }), TypeError); + assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call([], () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/tests/esnext.map.find-key.js b/tests/unit-global/esnext.map.find-key.js similarity index 100% rename from tests/tests/esnext.map.find-key.js rename to tests/unit-global/esnext.map.find-key.js diff --git a/tests/tests/esnext.map.find.js b/tests/unit-global/esnext.map.find.js similarity index 100% rename from tests/tests/esnext.map.find.js rename to tests/unit-global/esnext.map.find.js diff --git a/tests/unit-global/esnext.map.from.js b/tests/unit-global/esnext.map.from.js new file mode 100644 index 000000000000..608b5a892f55 --- /dev/null +++ b/tests/unit-global/esnext.map.from.js @@ -0,0 +1,24 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Map.from', assert => { + const { from } = Map; + const toArray = Array.from; + assert.isFunction(from); + assert.arity(from, 1); + assert.name(from, 'from'); + assert.looksNative(from); + assert.nonEnumerable(Map, 'from'); + assert.true(from([]) instanceof Map); + assert.deepEqual(toArray(from([])), []); + assert.deepEqual(toArray(from([[1, 2]])), [[1, 2]]); + assert.deepEqual(toArray(from([[1, 2], [2, 3], [1, 4]])), [[1, 4], [2, 3]]); + assert.deepEqual(toArray(from(createIterable([[1, 2], [2, 3], [1, 4]]))), [[1, 4], [2, 3]]); + const pair = [1, 2]; + const context = {}; + from([pair], function (element, index) { + assert.same(element, pair); + assert.same(index, 0); + assert.same(this, context); + return element; + }, context); +}); diff --git a/tests/unit-global/esnext.map.get-or-insert-computed.js b/tests/unit-global/esnext.map.get-or-insert-computed.js new file mode 100644 index 000000000000..dc78d6a488b5 --- /dev/null +++ b/tests/unit-global/esnext.map.get-or-insert-computed.js @@ -0,0 +1,41 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Map#getOrInsertComputed', assert => { + const { getOrInsertComputed } = Map.prototype; + const { from } = Array; + assert.isFunction(getOrInsertComputed); + assert.arity(getOrInsertComputed, 2); + assert.name(getOrInsertComputed, 'getOrInsertComputed'); + assert.looksNative(getOrInsertComputed); + assert.nonEnumerable(Map.prototype, 'getOrInsertComputed'); + + let map = new Map([['a', 2]]); + assert.same(map.getOrInsertComputed('a', () => 3), 2, 'result#1'); + assert.deepEqual(from(map), [['a', 2]], 'map#1'); + map = new Map([['a', 2]]); + assert.same(map.getOrInsertComputed('b', () => 3), 3, 'result#2'); + assert.deepEqual(from(map), [['a', 2], ['b', 3]], 'map#2'); + + map = new Map([['a', 2]]); + map.getOrInsertComputed('a', () => assert.avoid()); + + map = new Map([['a', 2]]); + map.getOrInsertComputed('b', function (key) { + if (STRICT) assert.same(this, undefined, 'correct handler in callback'); + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(key, 'b', 'correct key in callback'); + }); + + map = new Map([['a', 2]]); + map.getOrInsertComputed(-0, key => assert.same(key, 0, 'CanonicalizeKeyedCollectionKey')); + + assert.throws(() => new Map().getOrInsertComputed('a', {}), TypeError, 'non-callable#1'); + assert.throws(() => new Map().getOrInsertComputed('a', 1), TypeError, 'non-callable#2'); + assert.throws(() => new Map().getOrInsertComputed('a', null), TypeError, 'non-callable#3'); + assert.throws(() => new Map().getOrInsertComputed('a', undefined), TypeError, 'non-callable#4'); + assert.throws(() => new Map().getOrInsertComputed('a'), TypeError, 'non-callable#5'); + assert.throws(() => getOrInsertComputed.call({}, 'a', () => 3), TypeError, 'non-generic#1'); + assert.throws(() => getOrInsertComputed.call([], 'a', () => 3), TypeError, 'non-generic#2'); + assert.throws(() => getOrInsertComputed.call(undefined, 'a', () => 3), TypeError, 'non-generic#3'); + assert.throws(() => getOrInsertComputed.call(null, 'a', () => 3), TypeError, 'non-generic#4'); +}); diff --git a/tests/unit-global/esnext.map.get-or-insert.js b/tests/unit-global/esnext.map.get-or-insert.js new file mode 100644 index 000000000000..7f7dd7cf030d --- /dev/null +++ b/tests/unit-global/esnext.map.get-or-insert.js @@ -0,0 +1,21 @@ +QUnit.test('Map#getOrInsert', assert => { + const { getOrInsert } = Map.prototype; + const { from } = Array; + assert.isFunction(getOrInsert); + assert.arity(getOrInsert, 2); + assert.name(getOrInsert, 'getOrInsert'); + assert.looksNative(getOrInsert); + assert.nonEnumerable(Map.prototype, 'getOrInsert'); + + let map = new Map([['a', 2]]); + assert.same(map.getOrInsert('a', 3), 2, 'result#1'); + assert.deepEqual(from(map), [['a', 2]], 'map#1'); + map = new Map([['a', 2]]); + assert.same(map.getOrInsert('b', 3), 3, 'result#2'); + assert.deepEqual(from(map), [['a', 2], ['b', 3]], 'map#2'); + + assert.throws(() => getOrInsert.call({}, 'a', 1), TypeError, 'non-generic#1'); + assert.throws(() => getOrInsert.call([], 'a', 1), TypeError, 'non-generic#2'); + assert.throws(() => getOrInsert.call(undefined, 'a', 1), TypeError, 'non-generic#3'); + assert.throws(() => getOrInsert.call(null, 'a', 1), TypeError, 'non-generic#4'); +}); diff --git a/tests/unit-global/esnext.map.includes.js b/tests/unit-global/esnext.map.includes.js new file mode 100644 index 000000000000..ff11cadab11d --- /dev/null +++ b/tests/unit-global/esnext.map.includes.js @@ -0,0 +1,25 @@ +QUnit.test('Map#includes', assert => { + const { includes } = Map.prototype; + assert.isFunction(includes); + assert.name(includes, 'includes'); + assert.arity(includes, 1); + assert.looksNative(includes); + assert.nonEnumerable(Map.prototype, 'includes'); + + const object = {}; + const map = new Map([[1, 1], [2, 2], [3, 3], [4, -0], [5, object], [6, NaN]]); + assert.true(map.includes(1)); + assert.true(map.includes(-0)); + assert.true(map.includes(0)); + assert.true(map.includes(object)); + assert.false(map.includes(4)); + assert.false(map.includes(-0.5)); + assert.false(map.includes({})); + assert.true(map.includes(NaN)); + + assert.throws(() => includes.call(new Set(), 1), TypeError); + assert.throws(() => includes.call({}, 1), TypeError); + assert.throws(() => includes.call([], 1), TypeError); + assert.throws(() => includes.call(undefined, 1), TypeError); + assert.throws(() => includes.call(null, 1), TypeError); +}); diff --git a/tests/unit-global/esnext.map.key-by.js b/tests/unit-global/esnext.map.key-by.js new file mode 100644 index 000000000000..48987656ff53 --- /dev/null +++ b/tests/unit-global/esnext.map.key-by.js @@ -0,0 +1,24 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Map.keyBy', assert => { + const { keyBy } = Map; + const toArray = Array.from; + + assert.isFunction(keyBy); + assert.arity(keyBy, 2); + assert.name(keyBy, 'keyBy'); + assert.looksNative(keyBy); + assert.nonEnumerable(Map, 'keyBy'); + + assert.true(Map.keyBy([], it => it) instanceof Map); + + assert.deepEqual(toArray(Map.keyBy([], it => it)), []); + assert.deepEqual(toArray(Map.keyBy([1, 2], it => it ** 2)), [[1, 1], [4, 2]]); + assert.deepEqual(toArray(Map.keyBy([1, 2, 1], it => it ** 2)), [[1, 1], [4, 2]]); + assert.deepEqual(toArray(Map.keyBy(createIterable([1, 2]), it => it ** 2)), [[1, 1], [4, 2]]); + + const element = {}; + Map.keyBy([element], it => assert.same(it, element)); + + // assert.throws(() => keyBy([1, 2], it => it)); +}); diff --git a/tests/tests/esnext.map.key-of.js b/tests/unit-global/esnext.map.key-of.js similarity index 100% rename from tests/tests/esnext.map.key-of.js rename to tests/unit-global/esnext.map.key-of.js diff --git a/tests/unit-global/esnext.map.map-keys.js b/tests/unit-global/esnext.map.map-keys.js new file mode 100644 index 000000000000..79421e3e25ee --- /dev/null +++ b/tests/unit-global/esnext.map.map-keys.js @@ -0,0 +1,48 @@ +QUnit.test('Map#mapKeys', assert => { + const { mapKeys } = Map.prototype; + const { from } = Array; + + assert.isFunction(mapKeys); + assert.arity(mapKeys, 1); + assert.name(mapKeys, 'mapKeys'); + assert.looksNative(mapKeys); + assert.nonEnumerable(Map.prototype, 'mapKeys'); + + const map = new Map([[1, 2]]); + const context = {}; + map.mapKeys(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Map().mapKeys(it => it) instanceof Map); + + assert.deepEqual(from(new Map([ + ['a', 1], + [1, 2], + ['b', 3], + [2, 'q'], + ['c', {}], + [3, 4], + ['d', true], + [4, 5], + ]).mapKeys((value, key) => `${ key }${ value }`)), [ + ['a1', 1], + ['12', 2], + ['b3', 3], + ['2q', 'q'], + ['c[object Object]', {}], + ['34', 4], + ['dtrue', true], + ['45', 5], + ]); + + assert.throws(() => mapKeys.call(new Set(), () => { /* empty */ }), TypeError); + assert.throws(() => mapKeys.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => mapKeys.call([], () => { /* empty */ }), TypeError); + assert.throws(() => mapKeys.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => mapKeys.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.map.map-values.js b/tests/unit-global/esnext.map.map-values.js new file mode 100644 index 000000000000..272893a6852a --- /dev/null +++ b/tests/unit-global/esnext.map.map-values.js @@ -0,0 +1,48 @@ +QUnit.test('Map#mapValues', assert => { + const { mapValues } = Map.prototype; + const { from } = Array; + + assert.isFunction(mapValues); + assert.arity(mapValues, 1); + assert.name(mapValues, 'mapValues'); + assert.looksNative(mapValues); + assert.nonEnumerable(Map.prototype, 'mapValues'); + + const map = new Map([[1, 2]]); + const context = {}; + map.mapValues(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Map().mapValues(it => it) instanceof Map); + + assert.deepEqual(from(new Map([ + ['a', 1], + [1, 2], + ['b', 3], + [2, 'q'], + ['c', {}], + [3, 4], + ['d', true], + [4, 5], + ]).mapValues((value, key) => `${ key }${ value }`)), [ + ['a', 'a1'], + [1, '12'], + ['b', 'b3'], + [2, '2q'], + ['c', 'c[object Object]'], + [3, '34'], + ['d', 'dtrue'], + [4, '45'], + ]); + + assert.throws(() => mapValues.call(new Set(), () => { /* empty */ }), TypeError); + assert.throws(() => mapValues.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => mapValues.call([], () => { /* empty */ }), TypeError); + assert.throws(() => mapValues.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => mapValues.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.map.merge.js b/tests/unit-global/esnext.map.merge.js new file mode 100644 index 000000000000..f42ce00c889d --- /dev/null +++ b/tests/unit-global/esnext.map.merge.js @@ -0,0 +1,25 @@ +QUnit.test('Map#merge', assert => { + const { merge } = Map.prototype; + const { from } = Array; + + assert.isFunction(merge); + assert.arity(merge, 1); + assert.name(merge, 'merge'); + assert.looksNative(merge); + assert.nonEnumerable(Map.prototype, 'merge'); + + const map = new Map([[1, 2]]); + const result = map.merge([[3, 4]]); + assert.same(result, map); + assert.true(result instanceof Map); + + assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[5, 6]])), [[1, 2], [3, 4], [5, 6]]); + assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[3, 5], [5, 6]])), [[1, 2], [3, 5], [5, 6]]); + assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([])), [[1, 2], [3, 4]]); + + assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[3, 5]], [[5, 6]])), [[1, 2], [3, 5], [5, 6]]); + + assert.throws(() => merge.call({}, [[1, 2]]), TypeError); + assert.throws(() => merge.call(undefined, [[1, 2]]), TypeError); + assert.throws(() => merge.call(null, [[1, 2]]), TypeError); +}); diff --git a/tests/unit-global/esnext.map.of.js b/tests/unit-global/esnext.map.of.js new file mode 100644 index 000000000000..a8e111e4af6f --- /dev/null +++ b/tests/unit-global/esnext.map.of.js @@ -0,0 +1,12 @@ +QUnit.test('Map.of', assert => { + const { of } = Map; + const toArray = Array.from; + assert.isFunction(of); + assert.arity(of, 0); + assert.name(of, 'of'); + assert.looksNative(of); + assert.nonEnumerable(Map, 'of'); + assert.true(of() instanceof Map); + assert.deepEqual(toArray(of([1, 2])), [[1, 2]]); + assert.deepEqual(toArray(of([1, 2], [2, 3], [1, 4])), [[1, 4], [2, 3]]); +}); diff --git a/tests/tests/esnext.map.reduce.js b/tests/unit-global/esnext.map.reduce.js similarity index 100% rename from tests/tests/esnext.map.reduce.js rename to tests/unit-global/esnext.map.reduce.js diff --git a/tests/unit-global/esnext.map.some.js b/tests/unit-global/esnext.map.some.js new file mode 100644 index 000000000000..cdff073fccf4 --- /dev/null +++ b/tests/unit-global/esnext.map.some.js @@ -0,0 +1,39 @@ +QUnit.test('Map#some', assert => { + const { some } = Map.prototype; + assert.isFunction(some); + assert.arity(some, 1); + assert.name(some, 'some'); + assert.looksNative(some); + assert.nonEnumerable(Map.prototype, 'some'); + + let map = new Map([[9, 1]]); + const context = {}; + map.some(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 9, 'correct index in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + map = new Map([[0, 1], [1, '2'], [2, 3]]); + assert.true(map.some(it => typeof it == 'number')); + assert.true(map.some(it => it < 3)); + assert.false(map.some(it => it < 0)); + assert.true(map.some(it => typeof it == 'string')); + assert.false(map.some(function () { + return +this !== 1; + }, 1)); + let result = ''; + map.some((value, key) => { + result += key; + return false; + }); + assert.same(result, '012'); + assert.true(map.some((value, key, that) => that === map)); + + assert.throws(() => some.call(new Set(), () => { /* empty */ }), TypeError); + assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => some.call([], () => { /* empty */ }), TypeError); + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.map.update-or-insert.js b/tests/unit-global/esnext.map.update-or-insert.js new file mode 100644 index 000000000000..bafd82367cdf --- /dev/null +++ b/tests/unit-global/esnext.map.update-or-insert.js @@ -0,0 +1,36 @@ +QUnit.test('Map#updateOrInsert', assert => { + const { updateOrInsert } = Map.prototype; + assert.isFunction(updateOrInsert); + assert.arity(updateOrInsert, 2); + assert.looksNative(updateOrInsert); + assert.nonEnumerable(Map.prototype, 'updateOrInsert'); + + const map = new Map([['a', 2]]); + assert.same(map.updateOrInsert('a', function (value) { + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + return value ** 2; + }, () => { + assert.avoid(); + return 3; + }), 4, 'returns a correct value'); + assert.same(map.updateOrInsert('b', value => { + assert.avoid(); + return value ** 2; + }, function () { + assert.same(arguments.length, 0, 'correct number of callback arguments'); + return 3; + }), 3, 'returns a correct value'); + assert.same(map.size, 2, 'correct size'); + assert.same(map.get('a'), 4, 'correct result #1'); + assert.same(map.get('b'), 3, 'correct result #2'); + + assert.same(new Map([['a', 2]]).updateOrInsert('b', null, () => 3), 3); + assert.same(new Map([['a', 2]]).updateOrInsert('a', value => value ** 2), 4); + + assert.throws(() => new Map().updateOrInsert('a'), TypeError); + assert.throws(() => updateOrInsert.call({}, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => updateOrInsert.call([], 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => updateOrInsert.call(undefined, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => updateOrInsert.call(null, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); +}); diff --git a/tests/tests/esnext.map.update.js b/tests/unit-global/esnext.map.update.js similarity index 100% rename from tests/tests/esnext.map.update.js rename to tests/unit-global/esnext.map.update.js diff --git a/tests/unit-global/esnext.map.upsert.js b/tests/unit-global/esnext.map.upsert.js new file mode 100644 index 000000000000..e699f18e130a --- /dev/null +++ b/tests/unit-global/esnext.map.upsert.js @@ -0,0 +1,36 @@ +QUnit.test('Map#upsert', assert => { + const { upsert } = Map.prototype; + assert.isFunction(upsert); + assert.arity(upsert, 2); + assert.looksNative(upsert); + assert.nonEnumerable(Map.prototype, 'upsert'); + + const map = new Map([['a', 2]]); + assert.same(map.upsert('a', function (value) { + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + return value ** 2; + }, () => { + assert.avoid(); + return 3; + }), 4, 'returns a correct value'); + assert.same(map.upsert('b', value => { + assert.avoid(); + return value ** 2; + }, function () { + assert.same(arguments.length, 0, 'correct number of callback arguments'); + return 3; + }), 3, 'returns a correct value'); + assert.same(map.size, 2, 'correct size'); + assert.same(map.get('a'), 4, 'correct result #1'); + assert.same(map.get('b'), 3, 'correct result #2'); + + assert.same(new Map([['a', 2]]).upsert('b', null, () => 3), 3); + assert.same(new Map([['a', 2]]).upsert('a', value => value ** 2), 4); + + assert.throws(() => new Map().upsert('a'), TypeError); + assert.throws(() => upsert.call({}, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call([], 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call(undefined, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call(null, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.math.clamp.js b/tests/unit-global/esnext.math.clamp.js new file mode 100644 index 000000000000..8df03237defe --- /dev/null +++ b/tests/unit-global/esnext.math.clamp.js @@ -0,0 +1,29 @@ +QUnit.test('Math.clamp', assert => { + const { clamp } = Math; + assert.isFunction(clamp); + assert.name(clamp, 'clamp'); + assert.arity(clamp, 3); + assert.looksNative(clamp); + assert.nonEnumerable(Math, 'clamp'); + + assert.same(clamp(2, 4, 6), 4); + assert.same(clamp(4, 2, 6), 4); + assert.same(clamp(6, 2, 4), 4); + + assert.same(clamp(-0, 0, 1), 0, 'If value is -0𝔽 and min is +0𝔽, return +0𝔽.'); + assert.same(clamp(0, -0, 1), 0, 'If value is +0𝔽 and min is -0𝔽, return +0𝔽.'); + assert.same(clamp(-0, -1, 0), -0, 'If value is -0𝔽 and max is +0𝔽, return -0𝔽.'); + assert.same(clamp(0, -1, -0), -0, 'If value is +0𝔽 and max is -0𝔽, return -0𝔽.'); + assert.same(clamp(0, -0, -0), -0, 'If min = max return min.'); + + assert.same(clamp(2, 0, -0), -0, 'min is +0𝔽 and max is -0𝔽'); + assert.same(clamp(2, 3, 1), 1, 'min > max'); + + assert.same(clamp(NaN, 3, 1), NaN, 'If value is NaN, return NaN.'); + assert.same(clamp(2, NaN, 1), NaN, 'If min is NaN, return NaN.'); + assert.same(clamp(2, 3, NaN), NaN, 'If max is NaN, return NaN.'); + + assert.throws(() => clamp({ valueOf: () => 2 }, 1, 3), TypeError, 'If value is not a Number, throw a TypeError exception'); + assert.throws(() => clamp(2, Object(1), 3), TypeError, 'If min is not a Number, throw a TypeError exception.'); + assert.throws(() => clamp(2, 1, Object(3)), TypeError, 'If max is not a Number, throw a TypeError exception.'); +}); diff --git a/tests/unit-global/esnext.math.deg-per-rad.js b/tests/unit-global/esnext.math.deg-per-rad.js new file mode 100644 index 000000000000..6962555459d6 --- /dev/null +++ b/tests/unit-global/esnext.math.deg-per-rad.js @@ -0,0 +1,8 @@ +QUnit.test('Math.DEG_PER_RAD', assert => { + const { DEG_PER_RAD, PI } = Math; + assert.true('DEG_PER_RAD' in Math, 'DEG_PER_RAD in Math'); + assert.nonEnumerable(Math, 'DEG_PER_RAD'); + assert.nonConfigurable(Number, 'DEG_PER_RAD'); + assert.nonWritable(Number, 'DEG_PER_RAD'); + assert.same(DEG_PER_RAD, PI / 180, 'Is Math.PI / 180'); +}); diff --git a/tests/unit-global/esnext.math.degrees.js b/tests/unit-global/esnext.math.degrees.js new file mode 100644 index 000000000000..b9d05e62459a --- /dev/null +++ b/tests/unit-global/esnext.math.degrees.js @@ -0,0 +1,19 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.degrees', assert => { + const { degrees, PI } = Math; + assert.isFunction(degrees); + assert.name(degrees, 'degrees'); + assert.arity(degrees, 1); + assert.looksNative(degrees); + assert.nonEnumerable(Math, 'degrees'); + assert.same(degrees(0), 0); + assert.same(degrees(PI / 2), 90); + assert.same(degrees(PI), 180); + assert.same(degrees(3 * PI / 2), 270); + + const checker = createConversionChecker(3 * PI / 2); + assert.same(degrees(checker), 270, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/esnext.math.fscale.js b/tests/unit-global/esnext.math.fscale.js new file mode 100644 index 000000000000..e9d0be5e8709 --- /dev/null +++ b/tests/unit-global/esnext.math.fscale.js @@ -0,0 +1,32 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.fscale', assert => { + const { fscale, fround, PI } = Math; + assert.isFunction(fscale); + assert.name(fscale, 'fscale'); + assert.arity(fscale, 5); + assert.looksNative(fscale); + assert.nonEnumerable(Math, 'fscale'); + assert.same(fscale(3, 1, 2, 1, 2), 3); + assert.same(fscale(0, 3, 5, 8, 10), 5); + assert.same(fscale(1, 1, 1, 1, 1), NaN); + assert.same(fscale(-1, -1, -1, -1, -1), NaN); + assert.same(fscale(3, 1, 2, 1, PI), fround((3 - 1) * (PI - 1) / (2 - 1) + 1)); + + const checker1 = createConversionChecker(3); + const checker2 = createConversionChecker(1); + const checker3 = createConversionChecker(2); + const checker4 = createConversionChecker(1); + const checker5 = createConversionChecker(2); + assert.same(fscale(checker1, checker2, checker3, checker4, checker5), 3, 'object wrapper'); + assert.same(checker1.$valueOf, 1, 'checker1 valueOf calls'); + assert.same(checker1.$toString, 0, 'checker1 toString calls'); + assert.same(checker2.$valueOf, 1, 'checker2 valueOf calls'); + assert.same(checker2.$toString, 0, 'checker2 toString calls'); + assert.same(checker3.$valueOf, 1, 'checker3 valueOf calls'); + assert.same(checker3.$toString, 0, 'checker3 toString calls'); + assert.same(checker4.$valueOf, 1, 'checker4 valueOf calls'); + assert.same(checker4.$toString, 0, 'checker4 toString calls'); + assert.same(checker5.$valueOf, 1, 'checker5 valueOf calls'); + assert.same(checker5.$toString, 0, 'checker5 toString calls'); +}); diff --git a/tests/tests/esnext.math.iaddh.js b/tests/unit-global/esnext.math.iaddh.js similarity index 100% rename from tests/tests/esnext.math.iaddh.js rename to tests/unit-global/esnext.math.iaddh.js diff --git a/tests/tests/esnext.math.imulh.js b/tests/unit-global/esnext.math.imulh.js similarity index 100% rename from tests/tests/esnext.math.imulh.js rename to tests/unit-global/esnext.math.imulh.js diff --git a/tests/tests/esnext.math.isubh.js b/tests/unit-global/esnext.math.isubh.js similarity index 100% rename from tests/tests/esnext.math.isubh.js rename to tests/unit-global/esnext.math.isubh.js diff --git a/tests/unit-global/esnext.math.rad-per-deg.js b/tests/unit-global/esnext.math.rad-per-deg.js new file mode 100644 index 000000000000..d7f82d7a25d4 --- /dev/null +++ b/tests/unit-global/esnext.math.rad-per-deg.js @@ -0,0 +1,8 @@ +QUnit.test('Math.RAD_PER_DEG', assert => { + const { RAD_PER_DEG, PI } = Math; + assert.true('RAD_PER_DEG' in Math, 'RAD_PER_DEG in Math'); + assert.nonEnumerable(Math, 'RAD_PER_DEG'); + assert.nonConfigurable(Number, 'RAD_PER_DEG'); + assert.nonWritable(Number, 'RAD_PER_DEG'); + assert.same(RAD_PER_DEG, 180 / PI, 'Is 180 / Math.PI'); +}); diff --git a/tests/unit-global/esnext.math.radians.js b/tests/unit-global/esnext.math.radians.js new file mode 100644 index 000000000000..20977d6e7d3b --- /dev/null +++ b/tests/unit-global/esnext.math.radians.js @@ -0,0 +1,19 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.radians', assert => { + const { radians, PI } = Math; + assert.isFunction(radians); + assert.name(radians, 'radians'); + assert.arity(radians, 1); + assert.looksNative(radians); + assert.nonEnumerable(Math, 'radians'); + assert.same(radians(0), 0); + assert.same(radians(90), PI / 2); + assert.same(radians(180), PI); + assert.same(radians(270), 3 * PI / 2); + + const checker = createConversionChecker(270); + assert.same(radians(checker), 3 * PI / 2, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-global/esnext.math.scale.js b/tests/unit-global/esnext.math.scale.js new file mode 100644 index 000000000000..fc0d26ede533 --- /dev/null +++ b/tests/unit-global/esnext.math.scale.js @@ -0,0 +1,31 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.scale', assert => { + const { scale } = Math; + assert.isFunction(scale); + assert.name(scale, 'scale'); + assert.arity(scale, 5); + assert.looksNative(scale); + assert.nonEnumerable(Math, 'scale'); + assert.same(scale(3, 1, 2, 1, 2), 3); + assert.same(scale(0, 3, 5, 8, 10), 5); + assert.same(scale(1, 1, 1, 1, 1), NaN); + assert.same(scale(-1, -1, -1, -1, -1), NaN); + + const checker1 = createConversionChecker(3); + const checker2 = createConversionChecker(1); + const checker3 = createConversionChecker(2); + const checker4 = createConversionChecker(1); + const checker5 = createConversionChecker(2); + assert.same(scale(checker1, checker2, checker3, checker4, checker5), 3, 'object wrapper'); + assert.same(checker1.$valueOf, 1, 'checker1 valueOf calls'); + assert.same(checker1.$toString, 0, 'checker1 toString calls'); + assert.same(checker2.$valueOf, 1, 'checker2 valueOf calls'); + assert.same(checker2.$toString, 0, 'checker2 toString calls'); + assert.same(checker3.$valueOf, 1, 'checker3 valueOf calls'); + assert.same(checker3.$toString, 0, 'checker3 toString calls'); + assert.same(checker4.$valueOf, 1, 'checker4 valueOf calls'); + assert.same(checker4.$toString, 0, 'checker4 toString calls'); + assert.same(checker5.$valueOf, 1, 'checker5 valueOf calls'); + assert.same(checker5.$toString, 0, 'checker5 toString calls'); +}); diff --git a/tests/tests/esnext.math.seeded-prng.js b/tests/unit-global/esnext.math.seeded-prng.js similarity index 100% rename from tests/tests/esnext.math.seeded-prng.js rename to tests/unit-global/esnext.math.seeded-prng.js diff --git a/tests/unit-global/esnext.math.signbit.js b/tests/unit-global/esnext.math.signbit.js new file mode 100644 index 000000000000..87363bf537ea --- /dev/null +++ b/tests/unit-global/esnext.math.signbit.js @@ -0,0 +1,25 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +QUnit.test('Math.signbit', assert => { + const { signbit } = Math; + assert.isFunction(signbit); + assert.name(signbit, 'signbit'); + assert.arity(signbit, 1); + assert.looksNative(signbit); + assert.nonEnumerable(Math, 'signbit'); + assert.false(signbit(NaN)); + assert.false(signbit()); + assert.true(signbit(-0)); + assert.false(signbit(0)); + assert.false(signbit(Infinity)); + assert.true(signbit(-Infinity)); + assert.false(signbit(13510798882111488)); + assert.true(signbit(-13510798882111488)); + assert.false(signbit(42.5)); + assert.true(signbit(-42.5)); + + const checker = createConversionChecker(-13510798882111488); + assert.true(signbit(checker), 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/tests/esnext.math.umulh.js b/tests/unit-global/esnext.math.umulh.js similarity index 100% rename from tests/tests/esnext.math.umulh.js rename to tests/unit-global/esnext.math.umulh.js diff --git a/tests/unit-global/esnext.number.clamp.js b/tests/unit-global/esnext.number.clamp.js new file mode 100644 index 000000000000..e525af6bc139 --- /dev/null +++ b/tests/unit-global/esnext.number.clamp.js @@ -0,0 +1,29 @@ +QUnit.test('Number#clamp', assert => { + const { clamp } = Number.prototype; + assert.isFunction(clamp); + assert.name(clamp, 'clamp'); + assert.arity(clamp, 2); + assert.looksNative(clamp); + assert.nonEnumerable(Number.prototype, 'clamp'); + + assert.same(clamp.call(2, 4, 6), 4); + assert.same(clamp.call(4, 2, 6), 4); + assert.same(clamp.call(6, 2, 4), 4); + + assert.same(clamp.call(-0, 0, 1), 0, 'If value is -0𝔽 and min is +0𝔽, return +0𝔽.'); + assert.same(clamp.call(0, -0, 1), 0, 'If value is +0𝔽 and min is -0𝔽, return +0𝔽.'); + assert.same(clamp.call(-0, -1, 0), -0, 'If value is -0𝔽 and max is +0𝔽, return -0𝔽.'); + assert.same(clamp.call(0, -1, -0), -0, 'If value is +0𝔽 and max is -0𝔽, return -0𝔽.'); + assert.same(clamp.call(0, -0, -0), -0, 'If min = max return min.'); + + assert.same(clamp.call(2, 0, -0), -0, 'min is +0𝔽 and max is -0𝔽'); + assert.same(clamp.call(2, 3, 1), 1, 'min > max'); + + assert.same(clamp.call(NaN, 3, 1), NaN, 'If value is NaN, return NaN.'); + assert.same(clamp.call(2, NaN, 1), NaN, 'If min is NaN, return NaN.'); + assert.same(clamp.call(2, 3, NaN), NaN, 'If max is NaN, return NaN.'); + + assert.throws(() => clamp.call({ valueOf: () => 2 }, 1, 3), TypeError, 'If value is not a Number, throw a TypeError exception'); + assert.throws(() => clamp.call(2, Object(1), 3), TypeError, 'If min is not a Number, throw a TypeError exception.'); + assert.throws(() => clamp.call(2, 1, Object(3)), TypeError, 'If max is not a Number, throw a TypeError exception.'); +}); diff --git a/tests/unit-global/esnext.number.from-string.js b/tests/unit-global/esnext.number.from-string.js new file mode 100644 index 000000000000..202948739d3b --- /dev/null +++ b/tests/unit-global/esnext.number.from-string.js @@ -0,0 +1,48 @@ +QUnit.test('Number.fromString', assert => { + const { fromString } = Number; + assert.isFunction(fromString); + assert.name(fromString, 'fromString'); + assert.arity(fromString, 2); + assert.looksNative(fromString); + assert.nonEnumerable(Number, 'fromString'); + assert.throws(() => fromString(undefined), TypeError, 'The first argument should be a string #1'); + assert.throws(() => fromString(Object('10')), TypeError, 'The first argument should be a string #1'); + assert.throws(() => fromString(''), SyntaxError, 'Empty string'); + assert.same(fromString('-10', 2), -2, 'Works with negative numbers'); + assert.throws(() => fromString('-'), SyntaxError, '-'); + assert.same(fromString('10'), 10, 'Default radix is 10 #1'); + assert.same(fromString('10', undefined), 10, 'Default radix is 10 #2'); + for (let radix = 2; radix <= 36; ++radix) { + assert.same(fromString('10', radix), radix, `Radix ${ radix }`); + } + assert.throws(() => fromString('10', -4294967294), RangeError, 'Radix uses ToInteger #1'); + + assert.same(fromString('10', 2.5), 2, 'Radix uses ToInteger #2'); + assert.same(fromString('42'), 42); + assert.same(fromString('42', 10), 42); + assert.same(fromString('3.14159', 10), 3.14159); + assert.same(fromString('-100.11', 2), -4.75); + assert.same(fromString('202.1', 3), 20.333333333333332); + + assert.same(fromString('0'), 0); + assert.same(fromString('0', 2), 0); + assert.same(fromString('-0'), -0); + assert.same(fromString('-0', 2), -0); + + assert.throws(() => fromString('0xc0ffee'), SyntaxError); + assert.throws(() => fromString('0o755'), SyntaxError); + assert.throws(() => fromString('0b00101010'), SyntaxError); + assert.throws(() => fromString('C0FFEE', 16), SyntaxError); + assert.same(fromString('c0ffee', 16), 12648430); + assert.same(fromString('755', 8), 493); + assert.throws(() => fromString(''), SyntaxError); + assert.throws(() => fromString(' '), SyntaxError); + assert.throws(() => fromString(' 1'), SyntaxError); + assert.throws(() => fromString(' \n '), SyntaxError); + assert.throws(() => fromString('x'), SyntaxError); + assert.throws(() => fromString('1234', 0), RangeError); + assert.throws(() => fromString('1234', 1), RangeError); + assert.throws(() => fromString('1234', 37), RangeError); + assert.throws(() => fromString('010'), SyntaxError); + assert.throws(() => fromString('1_000_000_000'), SyntaxError); +}); diff --git a/tests/unit-global/esnext.number.range.js b/tests/unit-global/esnext.number.range.js new file mode 100644 index 000000000000..0551e3fb1ea1 --- /dev/null +++ b/tests/unit-global/esnext.number.range.js @@ -0,0 +1,72 @@ +import { MAX_SAFE_INTEGER } from '../helpers/constants.js'; + +QUnit.test('Number.range', assert => { + const { range } = Number; + const { from } = Array; + assert.isFunction(range); + assert.name(range, 'range'); + assert.arity(range, 3); + assert.looksNative(range); + assert.nonEnumerable(Number, 'range'); + + let iterator = range(1, 2); + + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: 1, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.deepEqual(from(range(-1, 5)), [-1, 0, 1, 2, 3, 4]); + assert.deepEqual(from(range(-5, 1)), [-5, -4, -3, -2, -1, 0]); + assert.deepEqual( + from(range(0, 1, 0.1)), + [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9], + ); + assert.deepEqual( + from(range(MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1, { inclusive: true })), + [MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1], + ); + assert.deepEqual(from(range(0, 0)), []); + assert.deepEqual(from(range(0, -5, 1)), []); + + assert.deepEqual(from(range(NaN, 0)), []); + assert.deepEqual(from(range(0, NaN)), []); + assert.deepEqual(from(range(NaN, NaN)), []); + assert.deepEqual(from(range(0, 0, { step: NaN })), []); + assert.deepEqual(from(range(0, 5, NaN)), []); + + iterator = range(1, 3); + assert.deepEqual(iterator.start, 1); + assert.deepEqual(iterator.end, 3); + assert.deepEqual(iterator.step, 1); + assert.false(iterator.inclusive); + + iterator = range(-1, -3, { inclusive: true }); + assert.deepEqual(iterator.start, -1); + assert.deepEqual(iterator.end, -3); + assert.same(iterator.step, -1); + assert.true(iterator.inclusive); + + iterator = range(-1, -3, { step: 4, inclusive() { /* empty */ } }); + assert.same(iterator.start, -1); + assert.same(iterator.end, -3); + assert.same(iterator.step, 4); + assert.true(iterator.inclusive); + + iterator = range(0, 5); + assert.throws(() => Object.getOwnPropertyDescriptor(iterator, 'start').get.call({}), TypeError); + + assert.throws(() => range(Infinity, 10, 0), RangeError); + assert.throws(() => range(-Infinity, 10, 0), RangeError); + assert.throws(() => range(0, 10, Infinity), RangeError); + assert.throws(() => range(0, 10, { step: Infinity }), RangeError); + + assert.throws(() => range({}, 1), TypeError); + assert.throws(() => range(1, {}), TypeError); +}); diff --git a/tests/unit-global/esnext.object.iterate-entries.js b/tests/unit-global/esnext.object.iterate-entries.js new file mode 100644 index 000000000000..62709ddbd0ee --- /dev/null +++ b/tests/unit-global/esnext.object.iterate-entries.js @@ -0,0 +1,31 @@ +QUnit.test('Object.iterateEntries', assert => { + const { iterateEntries } = Object; + assert.isFunction(iterateEntries); + assert.name(iterateEntries, 'iterateEntries'); + assert.arity(iterateEntries, 1); + assert.looksNative(iterateEntries); + assert.nonEnumerable(Object, 'iterateEntries'); + + const object = { + q: 1, + w: 2, + e: 3, + }; + const iterator = iterateEntries(object); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Object Iterator'); + assert.deepEqual(iterator.next(), { + value: ['q', 1], + done: false, + }); + delete object.w; + assert.deepEqual(iterator.next(), { + value: ['e', 3], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-global/esnext.object.iterate-keys.js b/tests/unit-global/esnext.object.iterate-keys.js new file mode 100644 index 000000000000..9593bdba1400 --- /dev/null +++ b/tests/unit-global/esnext.object.iterate-keys.js @@ -0,0 +1,31 @@ +QUnit.test('Object.iterateKeys', assert => { + const { iterateKeys } = Object; + assert.isFunction(iterateKeys); + assert.name(iterateKeys, 'iterateKeys'); + assert.arity(iterateKeys, 1); + assert.looksNative(iterateKeys); + assert.nonEnumerable(Object, 'iterateKeys'); + + const object = { + q: 1, + w: 2, + e: 3, + }; + const iterator = iterateKeys(object); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Object Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + delete object.w; + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-global/esnext.object.iterate-values.js b/tests/unit-global/esnext.object.iterate-values.js new file mode 100644 index 000000000000..76518b259ce5 --- /dev/null +++ b/tests/unit-global/esnext.object.iterate-values.js @@ -0,0 +1,31 @@ +QUnit.test('Object.iterateValues', assert => { + const { iterateValues } = Object; + assert.isFunction(iterateValues); + assert.name(iterateValues, 'iterateValues'); + assert.arity(iterateValues, 1); + assert.looksNative(iterateValues); + assert.nonEnumerable(Object, 'iterateValues'); + + const object = { + q: 1, + w: 2, + e: 3, + }; + const iterator = iterateValues(object); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Object Iterator'); + assert.deepEqual(iterator.next(), { + value: 1, + done: false, + }); + delete object.w; + assert.deepEqual(iterator.next(), { + value: 3, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-global/esnext.observable.constructor.js b/tests/unit-global/esnext.observable.constructor.js new file mode 100644 index 000000000000..bc45ca189cf0 --- /dev/null +++ b/tests/unit-global/esnext.observable.constructor.js @@ -0,0 +1,47 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('Observable', assert => { + assert.isFunction(Observable); + assert.arity(Observable, 1); + assert.name(Observable, 'Observable'); + assert.looksNative(Observable); + assert.throws(() => Observable(() => { /* empty */ }), 'throws w/o `new`'); + const observable = new Observable(function (subscriptionObserver) { + assert.same(typeof subscriptionObserver, 'object', 'Subscription observer is object'); + assert.same(subscriptionObserver.constructor, Object); + const { next, error, complete } = subscriptionObserver; + assert.isFunction(next); + assert.isFunction(error); + assert.isFunction(complete); + assert.arity(next, 1); + assert.arity(error, 1); + assert.arity(complete, 0); + if (STRICT) { + assert.same(this, undefined, 'correct executor context'); + } + }); + observable.subscribe({}); + assert.true(observable instanceof Observable); +}); + +QUnit.test('Observable#subscribe', assert => { + assert.isFunction(Observable.prototype.subscribe); + assert.arity(Observable.prototype.subscribe, 1); + assert.name(Observable.prototype.subscribe, 'subscribe'); + assert.looksNative(Observable.prototype.subscribe); + const subscription = new Observable(() => { /* empty */ }).subscribe({}); + assert.same(typeof subscription, 'object', 'Subscription is object'); + assert.same(subscription.constructor, Object); + assert.isFunction(subscription.unsubscribe); + assert.arity(subscription.unsubscribe, 0); +}); + +QUnit.test('Observable#constructor', assert => { + assert.same(Observable.prototype.constructor, Observable); +}); + +QUnit.test('Observable#@@observable', assert => { + assert.isFunction(Observable.prototype[Symbol.observable]); + const observable = new Observable(() => { /* empty*/ }); + assert.same(observable[Symbol.observable](), observable); +}); diff --git a/tests/unit-global/esnext.observable.from.js b/tests/unit-global/esnext.observable.from.js new file mode 100644 index 000000000000..93f17b5be65e --- /dev/null +++ b/tests/unit-global/esnext.observable.from.js @@ -0,0 +1,6 @@ +QUnit.test('Observable.from', assert => { + assert.isFunction(Observable.from); + assert.arity(Observable.from, 1); + assert.name(Observable.from, 'from'); + assert.looksNative(Observable.from); +}); diff --git a/tests/unit-global/esnext.observable.of.js b/tests/unit-global/esnext.observable.of.js new file mode 100644 index 000000000000..4307aa9140aa --- /dev/null +++ b/tests/unit-global/esnext.observable.of.js @@ -0,0 +1,6 @@ +QUnit.test('Observable.of', assert => { + assert.isFunction(Observable.of); + assert.arity(Observable.of, 0); + assert.name(Observable.of, 'of'); + assert.looksNative(Observable.of); +}); diff --git a/tests/tests/esnext.reflect.define-metadata.js b/tests/unit-global/esnext.reflect.define-metadata.js similarity index 100% rename from tests/tests/esnext.reflect.define-metadata.js rename to tests/unit-global/esnext.reflect.define-metadata.js diff --git a/tests/unit-global/esnext.reflect.delete-metadata.js b/tests/unit-global/esnext.reflect.delete-metadata.js new file mode 100644 index 000000000000..a5136cc20611 --- /dev/null +++ b/tests/unit-global/esnext.reflect.delete-metadata.js @@ -0,0 +1,21 @@ +QUnit.test('Reflect.deleteMetadata', assert => { + const { defineMetadata, hasOwnMetadata, deleteMetadata } = Reflect; + const { create } = Object; + assert.isFunction(deleteMetadata); + assert.arity(deleteMetadata, 2); + assert.name(deleteMetadata, 'deleteMetadata'); + assert.looksNative(deleteMetadata); + assert.nonEnumerable(Reflect, 'deleteMetadata'); + assert.throws(() => deleteMetadata('key', undefined, undefined), TypeError); + assert.false(deleteMetadata('key', {}, undefined)); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.true(deleteMetadata('key', object, undefined)); + const prototype = {}; + defineMetadata('key', 'value', prototype, undefined); + assert.false(deleteMetadata('key', create(prototype), undefined)); + object = {}; + defineMetadata('key', 'value', object, undefined); + deleteMetadata('key', object, undefined); + assert.false(hasOwnMetadata('key', object, undefined)); +}); diff --git a/tests/unit-global/esnext.reflect.get-metadata-keys.js b/tests/unit-global/esnext.reflect.get-metadata-keys.js new file mode 100644 index 000000000000..7f26d01f3578 --- /dev/null +++ b/tests/unit-global/esnext.reflect.get-metadata-keys.js @@ -0,0 +1,52 @@ +QUnit.test('Reflect.getMetadataKeys', assert => { + const { defineMetadata, getMetadataKeys } = Reflect; + const { create } = Object; + assert.isFunction(getMetadataKeys); + assert.arity(getMetadataKeys, 1); + assert.name(getMetadataKeys, 'getMetadataKeys'); + assert.looksNative(getMetadataKeys); + assert.nonEnumerable(Reflect, 'getMetadataKeys'); + assert.throws(() => getMetadataKeys(undefined, undefined), TypeError); + assert.deepEqual(getMetadataKeys({}, undefined), []); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key']); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key']); + object = {}; + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1']); + object = {}; + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + defineMetadata('key0', 'value', object, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1']); + prototype = {}; + defineMetadata('key2', 'value', prototype, undefined); + object = create(prototype); + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1', 'key2']); + assert.deepEqual(getMetadataKeys({}, 'name'), []); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.deepEqual(getMetadataKeys(object, 'name'), ['key']); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.deepEqual(getMetadataKeys(object, 'name'), ['key']); + object = {}; + defineMetadata('key0', 'value', object, 'name'); + defineMetadata('key1', 'value', object, 'name'); + defineMetadata('key0', 'value', object, 'name'); + assert.deepEqual(getMetadataKeys(object, 'name'), ['key0', 'key1']); + prototype = {}; + defineMetadata('key2', 'value', prototype, 'name'); + object = create(prototype); + defineMetadata('key0', 'value', object, 'name'); + defineMetadata('key1', 'value', object, 'name'); + assert.deepEqual(getMetadataKeys(object, 'name'), ['key0', 'key1', 'key2']); +}); diff --git a/tests/tests/esnext.reflect.get-metadata.js b/tests/unit-global/esnext.reflect.get-metadata.js similarity index 100% rename from tests/tests/esnext.reflect.get-metadata.js rename to tests/unit-global/esnext.reflect.get-metadata.js diff --git a/tests/unit-global/esnext.reflect.get-own-metadata-keys.js b/tests/unit-global/esnext.reflect.get-own-metadata-keys.js new file mode 100644 index 000000000000..c0868c82752d --- /dev/null +++ b/tests/unit-global/esnext.reflect.get-own-metadata-keys.js @@ -0,0 +1,52 @@ +QUnit.test('Reflect.getOwnMetadataKeys', assert => { + const { defineMetadata, getOwnMetadataKeys } = Reflect; + const { create } = Object; + assert.isFunction(getOwnMetadataKeys); + assert.arity(getOwnMetadataKeys, 1); + assert.name(getOwnMetadataKeys, 'getOwnMetadataKeys'); + assert.looksNative(getOwnMetadataKeys); + assert.nonEnumerable(Reflect, 'getOwnMetadataKeys'); + assert.throws(() => getOwnMetadataKeys(undefined, undefined), TypeError); + assert.deepEqual(getOwnMetadataKeys({}, undefined), []); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key']); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), []); + object = {}; + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); + object = {}; + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + defineMetadata('key0', 'value', object, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); + prototype = {}; + defineMetadata('key2', 'value', prototype, undefined); + object = create(prototype); + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); + assert.deepEqual(getOwnMetadataKeys({}, 'name'), []); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key']); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.deepEqual(getOwnMetadataKeys(object, 'name'), []); + object = {}; + defineMetadata('key0', 'value', object, 'name'); + defineMetadata('key1', 'value', object, 'name'); + defineMetadata('key0', 'value', object, 'name'); + assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key0', 'key1']); + prototype = {}; + defineMetadata('key2', 'value', prototype, 'name'); + object = create(prototype); + defineMetadata('key0', 'value', object, 'name'); + defineMetadata('key1', 'value', object, 'name'); + assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key0', 'key1']); +}); diff --git a/tests/tests/esnext.reflect.get-own-matadata.js b/tests/unit-global/esnext.reflect.get-own-metadata.js similarity index 100% rename from tests/tests/esnext.reflect.get-own-matadata.js rename to tests/unit-global/esnext.reflect.get-own-metadata.js diff --git a/tests/unit-global/esnext.reflect.has-metadata.js b/tests/unit-global/esnext.reflect.has-metadata.js new file mode 100644 index 000000000000..5961daef234c --- /dev/null +++ b/tests/unit-global/esnext.reflect.has-metadata.js @@ -0,0 +1,26 @@ +QUnit.test('Reflect.hasMetadata', assert => { + const { defineMetadata, hasMetadata } = Reflect; + const { create } = Object; + assert.isFunction(hasMetadata); + assert.arity(hasMetadata, 2); + assert.name(hasMetadata, 'hasMetadata'); + assert.looksNative(hasMetadata); + assert.nonEnumerable(Reflect, 'hasMetadata'); + assert.throws(() => hasMetadata('key', undefined, undefined), TypeError); + assert.false(hasMetadata('key', {}, undefined)); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.true(hasMetadata('key', object, undefined)); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.true(hasMetadata('key', object, undefined)); + assert.false(hasMetadata('key', {}, 'name')); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.true(hasMetadata('key', object, 'name')); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.true(hasMetadata('key', object, 'name')); +}); diff --git a/tests/unit-global/esnext.reflect.has-own-metadata.js b/tests/unit-global/esnext.reflect.has-own-metadata.js new file mode 100644 index 000000000000..af5848ea8cf1 --- /dev/null +++ b/tests/unit-global/esnext.reflect.has-own-metadata.js @@ -0,0 +1,26 @@ +QUnit.test('Reflect.hasOwnMetadata', assert => { + const { defineMetadata, hasOwnMetadata } = Reflect; + const { create } = Object; + assert.isFunction(hasOwnMetadata); + assert.arity(hasOwnMetadata, 2); + assert.name(hasOwnMetadata, 'hasOwnMetadata'); + assert.looksNative(hasOwnMetadata); + assert.nonEnumerable(Reflect, 'hasOwnMetadata'); + assert.throws(() => hasOwnMetadata('key', undefined, undefined), TypeError); + assert.false(hasOwnMetadata('key', {}, undefined)); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.true(hasOwnMetadata('key', object, undefined)); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.false(hasOwnMetadata('key', object, undefined)); + assert.false(hasOwnMetadata('key', {}, 'name')); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.true(hasOwnMetadata('key', object, 'name')); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.false(hasOwnMetadata('key', object, 'name')); +}); diff --git a/tests/unit-global/esnext.reflect.metadata.js b/tests/unit-global/esnext.reflect.metadata.js new file mode 100644 index 000000000000..e10d5c7308c8 --- /dev/null +++ b/tests/unit-global/esnext.reflect.metadata.js @@ -0,0 +1,17 @@ +QUnit.test('Reflect.metadata', assert => { + const { metadata, hasOwnMetadata } = Reflect; + assert.isFunction(metadata); + assert.arity(metadata, 2); + assert.name(metadata, 'metadata'); + assert.looksNative(metadata); + assert.isFunction(metadata('key', 'value')); + assert.nonEnumerable(Reflect, 'metadata'); + const decorator = metadata('key', 'value'); + assert.throws(() => decorator(undefined, 'name'), TypeError); + let target = function () { /* empty */ }; + decorator(target); + assert.true(hasOwnMetadata('key', target, undefined)); + target = {}; + decorator(target, 'name'); + assert.true(hasOwnMetadata('key', target, 'name')); +}); diff --git a/tests/unit-global/esnext.set.add-all.js b/tests/unit-global/esnext.set.add-all.js new file mode 100644 index 000000000000..7f47b137eb17 --- /dev/null +++ b/tests/unit-global/esnext.set.add-all.js @@ -0,0 +1,22 @@ +QUnit.test('Set#addAll', assert => { + const { addAll } = Set.prototype; + const { from } = Array; + + assert.isFunction(addAll); + assert.arity(addAll, 0); + assert.name(addAll, 'addAll'); + assert.looksNative(addAll); + assert.nonEnumerable(Set.prototype, 'addAll'); + + const set = new Set([1]); + assert.same(set.addAll(2), set); + + assert.deepEqual(from(new Set([1, 2, 3]).addAll(4, 5)), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).addAll(3, 4)), [1, 2, 3, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).addAll()), [1, 2, 3]); + + assert.throws(() => addAll.call({ add() { /* empty */ } }, 1, 2, 3)); + assert.throws(() => addAll.call({}, 1, 2, 3), TypeError); + assert.throws(() => addAll.call(undefined, 1, 2, 3), TypeError); + assert.throws(() => addAll.call(null, 1, 2, 3), TypeError); +}); diff --git a/tests/unit-global/esnext.set.delete-all.js b/tests/unit-global/esnext.set.delete-all.js new file mode 100644 index 000000000000..954db92e9983 --- /dev/null +++ b/tests/unit-global/esnext.set.delete-all.js @@ -0,0 +1,31 @@ +QUnit.test('Set#deleteAll', assert => { + const { deleteAll } = Set.prototype; + const { from } = Array; + + assert.isFunction(deleteAll); + assert.arity(deleteAll, 0); + assert.name(deleteAll, 'deleteAll'); + assert.looksNative(deleteAll); + assert.nonEnumerable(Set.prototype, 'deleteAll'); + + let set = new Set([1, 2, 3]); + assert.true(set.deleteAll(1, 2)); + assert.deepEqual(from(set), [3]); + + set = new Set([1, 2, 3]); + assert.false(set.deleteAll(3, 4)); + assert.deepEqual(from(set), [1, 2]); + + set = new Set([1, 2, 3]); + assert.false(set.deleteAll(4, 5)); + assert.deepEqual(from(set), [1, 2, 3]); + + set = new Set([1, 2, 3]); + assert.true(set.deleteAll()); + assert.deepEqual(from(set), [1, 2, 3]); + + assert.throws(() => deleteAll.call({ delete() { /* empty */ } }, 1, 2, 3)); + assert.throws(() => deleteAll.call({}, 1, 2, 3), TypeError); + assert.throws(() => deleteAll.call(undefined, 1, 2, 3), TypeError); + assert.throws(() => deleteAll.call(null, 1, 2, 3), TypeError); +}); diff --git a/tests/unit-global/esnext.set.every.js b/tests/unit-global/esnext.set.every.js new file mode 100644 index 000000000000..af036adf498c --- /dev/null +++ b/tests/unit-global/esnext.set.every.js @@ -0,0 +1,30 @@ +QUnit.test('Set#every', assert => { + const { every } = Set.prototype; + + assert.isFunction(every); + assert.arity(every, 1); + assert.name(every, 'every'); + assert.looksNative(every); + assert.nonEnumerable(Set.prototype, 'every'); + + const set = new Set([1]); + const context = {}; + set.every(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, set, 'correct link to set in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Set([1, 2, 3]).every(it => typeof it == 'number')); + assert.false(new Set(['1', '2', '3']).some(it => typeof it == 'number')); + assert.false(new Set([1, '2', 3]).every(it => typeof it == 'number')); + assert.true(new Set().every(it => typeof it == 'number')); + + assert.throws(() => every.call(new Map(), () => { /* empty */ }), TypeError); + assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => every.call([], () => { /* empty */ }), TypeError); + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.set.filter.js b/tests/unit-global/esnext.set.filter.js new file mode 100644 index 000000000000..aea26a0cf61e --- /dev/null +++ b/tests/unit-global/esnext.set.filter.js @@ -0,0 +1,30 @@ +QUnit.test('Set#filter', assert => { + const { filter } = Set.prototype; + const { from } = Array; + + assert.isFunction(filter); + assert.arity(filter, 1); + assert.name(filter, 'filter'); + assert.looksNative(filter); + assert.nonEnumerable(Set.prototype, 'filter'); + + const set = new Set([1]); + const context = {}; + set.filter(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, set, 'correct link to set in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Set().filter(it => it) instanceof Set); + + assert.deepEqual(from(new Set([1, 2, 3, 'q', {}, 4, true, 5]).filter(it => typeof it == 'number')), [1, 2, 3, 4, 5]); + + assert.throws(() => filter.call(new Map(), () => { /* empty */ }), TypeError); + assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call([], () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/tests/esnext.set.find.js b/tests/unit-global/esnext.set.find.js similarity index 100% rename from tests/tests/esnext.set.find.js rename to tests/unit-global/esnext.set.find.js diff --git a/tests/unit-global/esnext.set.from.js b/tests/unit-global/esnext.set.from.js new file mode 100644 index 000000000000..7cdf60aeb71e --- /dev/null +++ b/tests/unit-global/esnext.set.from.js @@ -0,0 +1,23 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Set.from', assert => { + const { from } = Set; + const toArray = Array.from; + assert.isFunction(from); + assert.arity(from, 1); + assert.name(from, 'from'); + assert.looksNative(from); + assert.nonEnumerable(Set, 'from'); + assert.true(from([]) instanceof Set); + assert.deepEqual(toArray(from([])), []); + assert.deepEqual(toArray(from([1])), [1]); + assert.deepEqual(toArray(from([1, 2, 3, 2, 1])), [1, 2, 3]); + assert.deepEqual(toArray(from(createIterable([1, 2, 3, 2, 1]))), [1, 2, 3]); + const context = {}; + from([1], function (element, index) { + assert.same(element, 1); + assert.same(index, 0); + assert.same(this, context); + return element; + }, context); +}); diff --git a/tests/unit-global/esnext.set.join.js b/tests/unit-global/esnext.set.join.js new file mode 100644 index 000000000000..0152fbe52dfb --- /dev/null +++ b/tests/unit-global/esnext.set.join.js @@ -0,0 +1,20 @@ +/* eslint-disable unicorn/require-array-join-separator -- required for testing */ +QUnit.test('Set#join', assert => { + const { join } = Set.prototype; + + assert.isFunction(join); + assert.arity(join, 1); + assert.name(join, 'join'); + assert.looksNative(join); + assert.nonEnumerable(Set.prototype, 'join'); + + assert.same(new Set([1, 2, 3]).join(), '1,2,3'); + assert.same(new Set([1, 2, 3]).join(undefined), '1,2,3'); + assert.same(new Set([1, 2, 3]).join('|'), '1|2|3'); + + assert.throws(() => join.call(new Map()), TypeError); + assert.throws(() => join.call({}), TypeError); + assert.throws(() => join.call([]), TypeError); + assert.throws(() => join.call(undefined), TypeError); + assert.throws(() => join.call(null), TypeError); +}); diff --git a/tests/unit-global/esnext.set.map.js b/tests/unit-global/esnext.set.map.js new file mode 100644 index 000000000000..ef7b420eb0ed --- /dev/null +++ b/tests/unit-global/esnext.set.map.js @@ -0,0 +1,31 @@ +QUnit.test('Set#map', assert => { + const { map } = Set.prototype; + const { from } = Array; + + assert.isFunction(map); + assert.arity(map, 1); + assert.name(map, 'map'); + assert.looksNative(map); + assert.nonEnumerable(Set.prototype, 'map'); + + const set = new Set([1]); + const context = {}; + set.map(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, set, 'correct link to set in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Set().map(it => it) instanceof Set); + + assert.deepEqual(from(new Set([1, 2, 3]).map(it => it ** 2)), [1, 4, 9]); + assert.deepEqual(from(new Set([1, 2, 3]).map(it => it % 2)), [1, 0]); + + assert.throws(() => map.call(new Map(), () => { /* empty */ }), TypeError); + assert.throws(() => map.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => map.call([], () => { /* empty */ }), TypeError); + assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.set.of.js b/tests/unit-global/esnext.set.of.js new file mode 100644 index 000000000000..a3772de00ad9 --- /dev/null +++ b/tests/unit-global/esnext.set.of.js @@ -0,0 +1,12 @@ +QUnit.test('Set.of', assert => { + const { of } = Set; + const toArray = Array.from; + assert.isFunction(of); + assert.arity(of, 0); + assert.name(of, 'of'); + assert.looksNative(of); + assert.nonEnumerable(Set, 'of'); + assert.true(of() instanceof Set); + assert.deepEqual(toArray(of(1)), [1]); + assert.deepEqual(toArray(of(1, 2, 3, 2, 1)), [1, 2, 3]); +}); diff --git a/tests/tests/esnext.set.reduce.js b/tests/unit-global/esnext.set.reduce.js similarity index 100% rename from tests/tests/esnext.set.reduce.js rename to tests/unit-global/esnext.set.reduce.js diff --git a/tests/unit-global/esnext.set.some.js b/tests/unit-global/esnext.set.some.js new file mode 100644 index 000000000000..0ed625f1049e --- /dev/null +++ b/tests/unit-global/esnext.set.some.js @@ -0,0 +1,30 @@ +QUnit.test('Set#some', assert => { + const { some } = Set.prototype; + + assert.isFunction(some); + assert.arity(some, 1); + assert.name(some, 'some'); + assert.looksNative(some); + assert.nonEnumerable(Set.prototype, 'some'); + + const set = new Set([1]); + const context = {}; + set.some(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, set, 'correct link to set in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Set([1, 2, 3]).some(it => typeof it == 'number')); + assert.false(new Set(['1', '2', '3']).some(it => typeof it == 'number')); + assert.true(new Set([1, '2', 3]).some(it => typeof it == 'number')); + assert.false(new Set().some(it => typeof it == 'number')); + + assert.throws(() => some.call(new Map(), () => { /* empty */ }), TypeError); + assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => some.call([], () => { /* empty */ }), TypeError); + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.string.at.js b/tests/unit-global/esnext.string.at.js new file mode 100644 index 000000000000..fefa1a37dd42 --- /dev/null +++ b/tests/unit-global/esnext.string.at.js @@ -0,0 +1,97 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#at', assert => { + const { at } = String.prototype; + assert.isFunction(at); + assert.arity(at, 1); + assert.name(at, 'at'); + assert.looksNative(at); + assert.nonEnumerable(String.prototype, 'at'); + // String that starts with a BMP symbol + // assert.same('abc\uD834\uDF06def'.at(-Infinity), ''); + // assert.same('abc\uD834\uDF06def'.at(-1), ''); + assert.same('abc\uD834\uDF06def'.at(-0), 'a'); + assert.same('abc\uD834\uDF06def'.at(+0), 'a'); + assert.same('abc\uD834\uDF06def'.at(1), 'b'); + assert.same('abc\uD834\uDF06def'.at(3), '\uD834\uDF06'); + assert.same('abc\uD834\uDF06def'.at(4), '\uDF06'); + assert.same('abc\uD834\uDF06def'.at(5), 'd'); + // assert.same('abc\uD834\uDF06def'.at(42), ''); + // assert.same('abc\uD834\uDF06def'.at(Infinity), ''); + assert.same('abc\uD834\uDF06def'.at(null), 'a'); + assert.same('abc\uD834\uDF06def'.at(undefined), 'a'); + assert.same('abc\uD834\uDF06def'.at(), 'a'); + assert.same('abc\uD834\uDF06def'.at(false), 'a'); + assert.same('abc\uD834\uDF06def'.at(NaN), 'a'); + assert.same('abc\uD834\uDF06def'.at(''), 'a'); + assert.same('abc\uD834\uDF06def'.at('_'), 'a'); + assert.same('abc\uD834\uDF06def'.at('1'), 'b'); + assert.same('abc\uD834\uDF06def'.at([]), 'a'); + assert.same('abc\uD834\uDF06def'.at({}), 'a'); + assert.same('abc\uD834\uDF06def'.at(-0.9), 'a'); + assert.same('abc\uD834\uDF06def'.at(1.9), 'b'); + assert.same('abc\uD834\uDF06def'.at(7.9), 'f'); + // assert.same('abc\uD834\uDF06def'.at(2 ** 32), ''); + // String that starts with an astral symbol + // assert.same('\uD834\uDF06def'.at(-Infinity), ''); + // assert.same('\uD834\uDF06def'.at(-1), ''); + assert.same('\uD834\uDF06def'.at(-0), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at(0), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at(1), '\uDF06'); + assert.same('\uD834\uDF06def'.at(2), 'd'); + assert.same('\uD834\uDF06def'.at(3), 'e'); + assert.same('\uD834\uDF06def'.at(4), 'f'); + // assert.same('\uD834\uDF06def'.at(42), ''); + // assert.same('\uD834\uDF06def'.at(Infinity), ''); + assert.same('\uD834\uDF06def'.at(null), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at(undefined), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at(), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at(false), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at(NaN), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at(''), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at('_'), '\uD834\uDF06'); + assert.same('\uD834\uDF06def'.at('1'), '\uDF06'); + // Lone high surrogates + // assert.same('\uD834abc'.at(-Infinity), ''); + // assert.same('\uD834abc'.at(-1), ''); + assert.same('\uD834abc'.at(-0), '\uD834'); + assert.same('\uD834abc'.at(0), '\uD834'); + assert.same('\uD834abc'.at(1), 'a'); + // assert.same('\uD834abc'.at(42), ''); + // assert.same('\uD834abc'.at(Infinity), ''); + assert.same('\uD834abc'.at(null), '\uD834'); + assert.same('\uD834abc'.at(undefined), '\uD834'); + assert.same('\uD834abc'.at(), '\uD834'); + assert.same('\uD834abc'.at(false), '\uD834'); + assert.same('\uD834abc'.at(NaN), '\uD834'); + assert.same('\uD834abc'.at(''), '\uD834'); + assert.same('\uD834abc'.at('_'), '\uD834'); + assert.same('\uD834abc'.at('1'), 'a'); + // Lone low surrogates + // assert.same('\uDF06abc'.at(-Infinity), ''); + // assert.same('\uDF06abc'.at(-1), ''); + assert.same('\uDF06abc'.at(-0), '\uDF06'); + assert.same('\uDF06abc'.at(0), '\uDF06'); + assert.same('\uDF06abc'.at(1), 'a'); + // assert.same('\uDF06abc'.at(42), ''); + // assert.same('\uDF06abc'.at(Infinity), ''); + assert.same('\uDF06abc'.at(null), '\uDF06'); + assert.same('\uDF06abc'.at(undefined), '\uDF06'); + assert.same('\uDF06abc'.at(), '\uDF06'); + assert.same('\uDF06abc'.at(false), '\uDF06'); + assert.same('\uDF06abc'.at(NaN), '\uDF06'); + assert.same('\uDF06abc'.at(''), '\uDF06'); + assert.same('\uDF06abc'.at('_'), '\uDF06'); + assert.same('\uDF06abc'.at('1'), 'a'); + assert.same(at.call(42, 0), '4'); + assert.same(at.call(42, 1), '2'); + assert.same(at.call({ + toString() { + return 'abc'; + }, + }, 2), 'c'); + if (STRICT) { + assert.throws(() => at.call(null, 0), TypeError); + assert.throws(() => at.call(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-global/esnext.string.code-points.js b/tests/unit-global/esnext.string.code-points.js new file mode 100644 index 000000000000..1ed44a511600 --- /dev/null +++ b/tests/unit-global/esnext.string.code-points.js @@ -0,0 +1,52 @@ +import { GLOBAL } from '../helpers/constants.js'; + +const Symbol = GLOBAL.Symbol || {}; + +QUnit.test('String#codePoints', assert => { + const { codePoints } = String.prototype; + assert.isFunction(codePoints); + assert.arity(codePoints, 0); + assert.name(codePoints, 'codePoints'); + assert.looksNative(codePoints); + assert.nonEnumerable(String.prototype, 'codePoints'); + let iterator = 'qwe'.codePoints(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'String Iterator'); + assert.same(String(iterator), '[object String Iterator]'); + assert.deepEqual(iterator.next(), { + value: { codePoint: 113, position: 0 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: { codePoint: 119, position: 1 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: { codePoint: 101, position: 2 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + iterator = '𠮷𠮷𠮷'.codePoints(); + assert.deepEqual(iterator.next(), { + value: { codePoint: 134071, position: 0 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: { codePoint: 134071, position: 2 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: { codePoint: 134071, position: 4 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.throws(() => codePoints.call(Symbol()), 'throws on symbol context'); +}); diff --git a/tests/unit-global/esnext.string.cooked.js b/tests/unit-global/esnext.string.cooked.js new file mode 100644 index 000000000000..da4d4a838075 --- /dev/null +++ b/tests/unit-global/esnext.string.cooked.js @@ -0,0 +1,21 @@ +QUnit.test('String.cooked', assert => { + const { cooked } = String; + assert.isFunction(cooked); + assert.arity(cooked, 1); + assert.name(cooked, 'cooked'); + assert.looksNative(cooked); + assert.nonEnumerable(String, 'cooked'); + assert.same(cooked(['Hi\\n', '!'], 'Bob'), 'Hi\\nBob!', 'template is an array'); + assert.same(cooked('test', 0, 1, 2), 't0e1s2t', 'template is a string'); + assert.same(cooked('test', 0), 't0est', 'lacks substituting'); + assert.same(cooked([]), '', 'empty template'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('cooked test'); + assert.throws(() => cooked([symbol]), TypeError, 'throws on symbol #1'); + assert.throws(() => cooked('test', symbol), TypeError, 'throws on symbol #2'); + } + + assert.throws(() => cooked([undefined]), TypeError); + assert.throws(() => cooked(null), TypeError); +}); diff --git a/tests/unit-global/esnext.string.dedent.js b/tests/unit-global/esnext.string.dedent.js new file mode 100644 index 000000000000..508578e7954c --- /dev/null +++ b/tests/unit-global/esnext.string.dedent.js @@ -0,0 +1,56 @@ +const freeze = Object.freeze || Object; + +QUnit.test('String.dedent', assert => { + const { cooked, dedent } = String; + assert.isFunction(dedent); + assert.arity(dedent, 1); + assert.name(dedent, 'dedent'); + assert.looksNative(dedent); + assert.nonEnumerable(String, 'dedent'); + + assert.same(dedent` + qwe + asd + zxc + `, 'qwe\nasd\nzxc', '#1'); + + assert.same(dedent` + qwe + asd + zxc + `, ' qwe\nasd\n zxc', '#2'); + + assert.same(dedent` + qwe + asd + ${ ' zxc' } + `, ' qwe\n asd\n zxc', '#3'); + + assert.same(dedent({ raw: freeze(['\n qwe\n ']) }), 'qwe', '#4'); + assert.same(dedent({ raw: freeze(['\n qwe', '\n ']) }, 1), 'qwe1', '#5'); + + assert.same(dedent(cooked)` + qwe + asd + zxc + `, ' qwe\nasd\n zxc', '#6'); + + const tag = (it => it)` + abc + `; + + assert.same(dedent(tag), dedent(tag), '#7'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => dedent({ raw: freeze(['\n', Symbol('dedent test'), '\n']) }), TypeError, 'throws on symbol'); + } + + assert.throws(() => dedent([]), TypeError, '[]'); + assert.throws(() => dedent(['qwe']), TypeError, '[qwe]'); + assert.throws(() => dedent({ raw: freeze([]) }), TypeError, 'empty tpl'); + assert.throws(() => dedent({ raw: freeze(['qwe']) }), TypeError, 'wrong start'); + assert.throws(() => dedent({ raw: freeze(['\n', 'qwe']) }), TypeError, 'wrong start'); + assert.throws(() => dedent({ raw: freeze(['\n qwe', 5, '\n ']) }, 1, 2), TypeError, 'wrong part'); + assert.throws(() => dedent([undefined]), TypeError); + assert.throws(() => dedent(null), TypeError); +}); diff --git a/tests/unit-global/esnext.symbol.custom-matcher.js b/tests/unit-global/esnext.symbol.custom-matcher.js new file mode 100644 index 000000000000..eaa753a63125 --- /dev/null +++ b/tests/unit-global/esnext.symbol.custom-matcher.js @@ -0,0 +1,13 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.customMatcher', assert => { + assert.true('customMatcher' in Symbol, 'Symbol.customMatcher available'); + assert.nonEnumerable(Symbol, 'customMatcher'); + assert.true(Object(Symbol.customMatcher) instanceof Symbol, 'Symbol.customMatcher is symbol'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'customMatcher'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/esnext.symbol.is-registered-symbol.js b/tests/unit-global/esnext.symbol.is-registered-symbol.js new file mode 100644 index 000000000000..b80118fa1390 --- /dev/null +++ b/tests/unit-global/esnext.symbol.is-registered-symbol.js @@ -0,0 +1,21 @@ +QUnit.test('Symbol.isRegisteredSymbol', assert => { + const { isRegisteredSymbol } = Symbol; + assert.isFunction(isRegisteredSymbol, 'Symbol.isRegisteredSymbol is function'); + assert.nonEnumerable(Symbol, 'isRegisteredSymbol'); + assert.arity(isRegisteredSymbol, 1, 'Symbol.isRegisteredSymbol arity is 1'); + assert.name(isRegisteredSymbol, 'isRegisteredSymbol', 'Symbol.isRegisteredSymbol.name is "isRegisteredSymbol"'); + assert.looksNative(isRegisteredSymbol, 'isRegisteredSymbol looks like native'); + + assert.true(isRegisteredSymbol(Symbol.for('foo')), 'registered'); + assert.true(isRegisteredSymbol(Object(Symbol.for('foo'))), 'registered, boxed'); + const symbol = Symbol('Symbol.isRegisteredSymbol test'); + assert.false(isRegisteredSymbol(symbol), 'non-registered'); + assert.false(isRegisteredSymbol(Object(symbol)), 'non-registered, boxed'); + assert.false(isRegisteredSymbol(1), '1'); + assert.false(isRegisteredSymbol(true), 'true'); + assert.false(isRegisteredSymbol('1'), 'string'); + assert.false(isRegisteredSymbol(null), 'null'); + assert.false(isRegisteredSymbol(), 'undefined'); + assert.false(isRegisteredSymbol({}), 'object'); + assert.false(isRegisteredSymbol([]), 'array'); +}); diff --git a/tests/unit-global/esnext.symbol.is-registered.js b/tests/unit-global/esnext.symbol.is-registered.js new file mode 100644 index 000000000000..c168eb5b2de9 --- /dev/null +++ b/tests/unit-global/esnext.symbol.is-registered.js @@ -0,0 +1,21 @@ +QUnit.test('Symbol.isRegistered', assert => { + const { isRegistered } = Symbol; + assert.isFunction(isRegistered, 'Symbol.isRegistered is function'); + assert.nonEnumerable(Symbol, 'isRegistered'); + assert.arity(isRegistered, 1, 'Symbol.isRegistered arity is 1'); + assert.name(isRegistered, 'isRegisteredSymbol', 'Symbol.isRegistered.name is "isRegisteredSymbol"'); + assert.looksNative(isRegistered, 'isRegistered looks like native'); + + assert.true(isRegistered(Symbol.for('foo')), 'registered'); + assert.true(isRegistered(Object(Symbol.for('foo'))), 'registered, boxed'); + const symbol = Symbol('Symbol.isRegistered test'); + assert.false(isRegistered(symbol), 'non-registered'); + assert.false(isRegistered(Object(symbol)), 'non-registered, boxed'); + assert.false(isRegistered(1), '1'); + assert.false(isRegistered(true), 'true'); + assert.false(isRegistered('1'), 'string'); + assert.false(isRegistered(null), 'null'); + assert.false(isRegistered(), 'undefined'); + assert.false(isRegistered({}), 'object'); + assert.false(isRegistered([]), 'array'); +}); diff --git a/tests/unit-global/esnext.symbol.is-well-known-symbol.js b/tests/unit-global/esnext.symbol.is-well-known-symbol.js new file mode 100644 index 000000000000..f1b1dad8f8d8 --- /dev/null +++ b/tests/unit-global/esnext.symbol.is-well-known-symbol.js @@ -0,0 +1,23 @@ +QUnit.test('Symbol.isWellKnownSymbol', assert => { + const { isWellKnownSymbol } = Symbol; + assert.isFunction(isWellKnownSymbol, 'Symbol.isWellKnownSymbol is function'); + assert.nonEnumerable(Symbol, 'isWellKnownSymbol'); + assert.arity(isWellKnownSymbol, 1, 'Symbol.isWellKnownSymbol arity is 1'); + assert.name(isWellKnownSymbol, 'isWellKnownSymbol', 'Symbol.isWellKnownSymbol.name is "isWellKnownSymbol"'); + assert.looksNative(isWellKnownSymbol, 'isWellKnownSymbol looks like native'); + + assert.true(isWellKnownSymbol(Symbol.iterator), 'registered-1'); + assert.true(isWellKnownSymbol(Object(Symbol.iterator)), 'registered-2, boxed'); + assert.true(isWellKnownSymbol(Symbol.patternMatch), 'registered-3'); + assert.true(isWellKnownSymbol(Object(Symbol.patternMatch)), 'registered-4, boxed'); + const symbol = Symbol('Symbol.isWellKnownSymbol test'); + assert.false(isWellKnownSymbol(symbol), 'non-registered'); + assert.false(isWellKnownSymbol(Object(symbol)), 'non-registered, boxed'); + assert.false(isWellKnownSymbol(1), '1'); + assert.false(isWellKnownSymbol(true), 'true'); + assert.false(isWellKnownSymbol('1'), 'string'); + assert.false(isWellKnownSymbol(null), 'null'); + assert.false(isWellKnownSymbol(), 'undefined'); + assert.false(isWellKnownSymbol({}), 'object'); + assert.false(isWellKnownSymbol([]), 'array'); +}); diff --git a/tests/unit-global/esnext.symbol.is-well-known.js b/tests/unit-global/esnext.symbol.is-well-known.js new file mode 100644 index 000000000000..a7188a1dae41 --- /dev/null +++ b/tests/unit-global/esnext.symbol.is-well-known.js @@ -0,0 +1,23 @@ +QUnit.test('Symbol.isWellKnown', assert => { + const { isWellKnown } = Symbol; + assert.isFunction(isWellKnown, 'Symbol.isWellKnown is function'); + assert.nonEnumerable(Symbol, 'isWellKnown'); + assert.arity(isWellKnown, 1, 'Symbol.isWellKnown arity is 1'); + assert.name(isWellKnown, 'isWellKnownSymbol', 'Symbol.isWellKnown.name is "isWellKnownSymbol"'); + assert.looksNative(isWellKnown, 'isWellKnown looks like native'); + + assert.true(isWellKnown(Symbol.iterator), 'registered-1'); + assert.true(isWellKnown(Object(Symbol.iterator)), 'registered-2, boxed'); + assert.true(isWellKnown(Symbol.patternMatch), 'registered-3'); + assert.true(isWellKnown(Object(Symbol.patternMatch)), 'registered-4, boxed'); + const symbol = Symbol('Symbol.isWellKnown test'); + assert.false(isWellKnown(symbol), 'non-registered'); + assert.false(isWellKnown(Object(symbol)), 'non-registered, boxed'); + assert.false(isWellKnown(1), '1'); + assert.false(isWellKnown(true), 'true'); + assert.false(isWellKnown('1'), 'string'); + assert.false(isWellKnown(null), 'null'); + assert.false(isWellKnown(), 'undefined'); + assert.false(isWellKnown({}), 'object'); + assert.false(isWellKnown([]), 'array'); +}); diff --git a/tests/unit-global/esnext.symbol.matcher.js b/tests/unit-global/esnext.symbol.matcher.js new file mode 100644 index 000000000000..0824ef02202c --- /dev/null +++ b/tests/unit-global/esnext.symbol.matcher.js @@ -0,0 +1,13 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.matcher', assert => { + assert.true('matcher' in Symbol, 'Symbol.matcher available'); + assert.nonEnumerable(Symbol, 'matcher'); + assert.true(Object(Symbol.matcher) instanceof Symbol, 'Symbol.matcher is symbol'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'matcher'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/esnext.symbol.metadata-key.js b/tests/unit-global/esnext.symbol.metadata-key.js new file mode 100644 index 000000000000..4b1c5b348699 --- /dev/null +++ b/tests/unit-global/esnext.symbol.metadata-key.js @@ -0,0 +1,13 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.metadataKey', assert => { + assert.true('metadataKey' in Symbol, 'Symbol.metadataKey available'); + assert.nonEnumerable(Symbol, 'metadataKey'); + assert.true(Object(Symbol.metadataKey) instanceof Symbol, 'Symbol.metadataKey is symbol'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'metadataKey'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/esnext.symbol.metadata.js b/tests/unit-global/esnext.symbol.metadata.js new file mode 100644 index 000000000000..ee047b3e670b --- /dev/null +++ b/tests/unit-global/esnext.symbol.metadata.js @@ -0,0 +1,13 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.metadata', assert => { + assert.true('metadata' in Symbol, 'Symbol.metadata available'); + assert.nonEnumerable(Symbol, 'metadata'); + assert.true(Object(Symbol.metadata) instanceof Symbol, 'Symbol.metadata is symbol'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'metadata'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/esnext.symbol.observable.js b/tests/unit-global/esnext.symbol.observable.js new file mode 100644 index 000000000000..d325e3a330c4 --- /dev/null +++ b/tests/unit-global/esnext.symbol.observable.js @@ -0,0 +1,13 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.observable', assert => { + assert.true('observable' in Symbol, 'Symbol.observable available'); + assert.nonEnumerable(Symbol, 'observable'); + assert.true(Object(Symbol.observable) instanceof Symbol, 'Symbol.observable is symbol'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'observable'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/esnext.symbol.pattern-match.js b/tests/unit-global/esnext.symbol.pattern-match.js new file mode 100644 index 000000000000..65342dda5f4e --- /dev/null +++ b/tests/unit-global/esnext.symbol.pattern-match.js @@ -0,0 +1,13 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.patternMatch', assert => { + assert.true('patternMatch' in Symbol, 'Symbol.patternMatch available'); + assert.nonEnumerable(Symbol, 'patternMatch'); + assert.true(Object(Symbol.patternMatch) instanceof Symbol, 'Symbol.patternMatch is symbol'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'patternMatch'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/esnext.symbol.replace-all.js b/tests/unit-global/esnext.symbol.replace-all.js new file mode 100644 index 000000000000..795d99ea1843 --- /dev/null +++ b/tests/unit-global/esnext.symbol.replace-all.js @@ -0,0 +1,13 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('Symbol.replaceAll', assert => { + assert.true('replaceAll' in Symbol, 'Symbol.replaceAll is available'); + assert.nonEnumerable(Symbol, 'replaceAll'); + assert.true(Object(Symbol.replaceAll) instanceof Symbol, 'Symbol.replaceAll is symbol'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(Symbol, 'replaceAll'); + assert.false(descriptor.enumerable, 'non-enumerable'); + assert.false(descriptor.writable, 'non-writable'); + assert.false(descriptor.configurable, 'non-configurable'); + } +}); diff --git a/tests/unit-global/esnext.typed-array.filter-out.js b/tests/unit-global/esnext.typed-array.filter-out.js new file mode 100644 index 000000000000..9cdc7311a512 --- /dev/null +++ b/tests/unit-global/esnext.typed-array.filter-out.js @@ -0,0 +1,34 @@ +// TODO: Remove from `core-js@4` +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.filterOut', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { filterOut } = TypedArray.prototype; + assert.isFunction(filterOut, `${ name }::filterOut is function`); + assert.arity(filterOut, 1, `${ name }::filterOut arity is 1`); + assert.name(filterOut, 'filterOut', `${ name }::filterOut name is 'filterOut'`); + assert.looksNative(filterOut, `${ name }::filterOut looks native`); + const array = new TypedArray([1]); + const context = {}; + array.filterOut(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + const instance = new TypedArray([1, 2, 3, 4, 5, 6, 7, 8, 9]).filterOut(it => it % 2); + assert.true(instance instanceof TypedArray, 'correct instance'); + assert.arrayEqual(instance, [2, 4, 6, 8], 'works'); + let values = ''; + let keys = ''; + new TypedArray([1, 2, 3]).filterOut((value, key) => { + values += value; + keys += key; + }); + assert.same(values, '123'); + assert.same(keys, '012'); + assert.throws(() => filterOut.call([0], () => { /* empty */ }), "isn't generic"); + } +}); diff --git a/tests/unit-global/esnext.typed-array.filter-reject.js b/tests/unit-global/esnext.typed-array.filter-reject.js new file mode 100644 index 000000000000..e88c34895499 --- /dev/null +++ b/tests/unit-global/esnext.typed-array.filter-reject.js @@ -0,0 +1,33 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.filterReject', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { filterReject } = TypedArray.prototype; + assert.isFunction(filterReject, `${ name }::filterReject is function`); + assert.arity(filterReject, 1, `${ name }::filterReject arity is 1`); + assert.name(filterReject, 'filterReject', `${ name }::filterReject name is 'filterReject'`); + assert.looksNative(filterReject, `${ name }::filterReject looks native`); + const array = new TypedArray([1]); + const context = {}; + array.filterReject(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + const instance = new TypedArray([1, 2, 3, 4, 5, 6, 7, 8, 9]).filterReject(it => it % 2); + assert.true(instance instanceof TypedArray, 'correct instance'); + assert.arrayEqual(instance, [2, 4, 6, 8], 'works'); + let values = ''; + let keys = ''; + new TypedArray([1, 2, 3]).filterReject((value, key) => { + values += value; + keys += key; + }); + assert.same(values, '123'); + assert.same(keys, '012'); + assert.throws(() => filterReject.call([0], () => { /* empty */ }), "isn't generic"); + } +}); diff --git a/tests/unit-global/esnext.typed-array.from-async.js b/tests/unit-global/esnext.typed-array.from-async.js new file mode 100644 index 000000000000..119fb776288b --- /dev/null +++ b/tests/unit-global/esnext.typed-array.from-async.js @@ -0,0 +1,84 @@ +import { createAsyncIterable, createIterable } from '../helpers/helpers.js'; +import { DESCRIPTORS, STRICT_THIS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) { + // we can't implement %TypedArray% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) QUnit.test(`%TypedArray%.fromAsync, ${ name }`, assert => { + const { fromAsync } = TypedArray; + + assert.isFunction(fromAsync); + assert.arity(fromAsync, 1); + assert.name(fromAsync, 'fromAsync'); + assert.looksNative(fromAsync); + + return TypedArray.fromAsync(createAsyncIterable([1, 2, 3]), it => it ** 2).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'async iterable and mapfn'); + return TypedArray.fromAsync(createAsyncIterable([1]), function (arg, index) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(index, 0, 'index'); + }); + }).then(() => { + return TypedArray.fromAsync(createAsyncIterable([1, 2, 3])); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'async iterable without mapfn'); + return TypedArray.fromAsync(createIterable([1, 2, 3]), arg => arg ** 2); + }).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'iterable and mapfn'); + return TypedArray.fromAsync(createIterable([1, 2, 3]), arg => Promise.resolve(arg ** 2)); + }).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'iterable and async mapfn'); + return TypedArray.fromAsync(createIterable([1]), function (arg, index) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(index, 0, 'index'); + }); + }).then(() => { + return TypedArray.fromAsync(createIterable([1, 2, 3])); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'iterable and without mapfn'); + return TypedArray.fromAsync([1, Promise.resolve(2), 3]); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'array'); + return TypedArray.fromAsync('123'); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'string'); + return TypedArray.fromAsync({ length: 1, 0: 1 }); + }).then(it => { + assert.arrayEqual(it, [1], 'non-iterable'); + return TypedArray.fromAsync(createIterable([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + function C() { /* empty */ } + return TypedArray.fromAsync.call(C, [1], {}); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return TypedArray.fromAsync(undefined, () => { /* empty */ }); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return TypedArray.fromAsync(null, () => { /* empty */ }); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return TypedArray.fromAsync([1], null); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return TypedArray.fromAsync([1], {}); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + }); + }); +} diff --git a/tests/unit-global/esnext.typed-array.group-by.js b/tests/unit-global/esnext.typed-array.group-by.js new file mode 100644 index 000000000000..2e44023452fa --- /dev/null +++ b/tests/unit-global/esnext.typed-array.group-by.js @@ -0,0 +1,41 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +const { getPrototypeOf } = Object; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.groupBy', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { groupBy } = TypedArray.prototype; + assert.isFunction(groupBy, `${ name }::groupBy is function`); + assert.arity(groupBy, 1, `${ name }::groupBy arity is 1`); + assert.name(groupBy, 'groupBy', `${ name }::groupBy name is 'groupBy'`); + assert.looksNative(groupBy, `${ name }::groupBy looks native`); + const array = new TypedArray([1]); + const context = {}; + array.groupBy(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.same(getPrototypeOf(new TypedArray([1]).groupBy(it => it)), null, 'null proto'); + assert.true(new TypedArray([1]).groupBy(it => it)[1] instanceof TypedArray, 'instance'); + assert.deepEqual( + new TypedArray([1, 2, 3]).groupBy(it => it % 2), + { 1: new TypedArray([1, 3]), 0: new TypedArray([2]) }, + '#1', + ); + assert.deepEqual(new TypedArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]).groupBy(it => `i${ it % 5 }`), { + i1: new TypedArray([1, 6, 11]), + i2: new TypedArray([2, 7, 12]), + i3: new TypedArray([3, 8]), + i4: new TypedArray([4, 9]), + i0: new TypedArray([5, 10]), + }, '#2'); + + assert.throws(() => groupBy.call([0], () => { /* empty */ }), "isn't generic"); + } +}); + diff --git a/tests/unit-global/esnext.typed-array.to-spliced.js b/tests/unit-global/esnext.typed-array.to-spliced.js new file mode 100644 index 000000000000..a1d5b2c240db --- /dev/null +++ b/tests/unit-global/esnext.typed-array.to-spliced.js @@ -0,0 +1,36 @@ +// TODO: Remove from `core-js@4` +import { DESCRIPTORS, TYPED_ARRAYS_WITH_BIG_INT } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.toSpliced', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray, $ } of TYPED_ARRAYS_WITH_BIG_INT) { + const { toSpliced } = TypedArray.prototype; + + assert.isFunction(toSpliced, `${ name }::toSpliced is function`); + assert.arity(toSpliced, 2, `${ name }::toSpliced arity is 1`); + assert.name(toSpliced, 'toSpliced', `${ name }::toSpliced name is 'toSpliced'`); + assert.looksNative(toSpliced, `${ name }::toSpliced looks native`); + + let array = new TypedArray([$(1), $(2), $(3), $(4), $(5)]); + assert.notSame(array.toSpliced(2), array, 'immutable'); + + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4), $(5)]).toSpliced(2), new TypedArray([$(1), $(2)])); + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4), $(5)]).toSpliced(-2), new TypedArray([$(1), $(2), $(3)])); + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4), $(5)]).toSpliced(2, 2), new TypedArray([$(1), $(2), $(5)])); + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4), $(5)]).toSpliced(2, -2), new TypedArray([$(1), $(2), $(3), $(4), $(5)])); + assert.deepEqual(new TypedArray([$(1), $(2), $(3), $(4), $(5)]).toSpliced(2, 2, $(6), $(7)), new TypedArray([$(1), $(2), $(6), $(7), $(5)])); + + array = new TypedArray([$(1)]); + + assert.deepEqual(array.toSpliced(1, 0, { + valueOf() { + array[0] = $(2); + return $(3); + }, + }), new TypedArray([$(2), $(3)]), 'operations order'); + + assert.throws(() => toSpliced.call(null), TypeError, "isn't generic #1"); + assert.throws(() => toSpliced.call(undefined), TypeError, "isn't generic #2"); + assert.throws(() => toSpliced.call([$(1), $(2)]), TypeError, "isn't generic #3"); + } +}); diff --git a/tests/unit-global/esnext.typed-array.unique-by.js b/tests/unit-global/esnext.typed-array.unique-by.js new file mode 100644 index 000000000000..db0b04a629f6 --- /dev/null +++ b/tests/unit-global/esnext.typed-array.unique-by.js @@ -0,0 +1,23 @@ +import { DESCRIPTORS, TYPED_ARRAYS } from '../helpers/constants.js'; + +if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.uniqueBy', assert => { + // we can't implement %TypedArrayPrototype% in all engines, so run all tests for each typed array constructor + for (const { name, TypedArray } of TYPED_ARRAYS) { + const { uniqueBy } = TypedArray.prototype; + assert.isFunction(uniqueBy, `${ name }::uniqueBy is function`); + assert.arity(uniqueBy, 1, `${ name }::uniqueBy arity is 1`); + assert.name(uniqueBy, 'uniqueBy', `${ name }::uniqueBy name is 'uniqueBy'`); + assert.looksNative(uniqueBy, `${ name }::uniqueBy looks native`); + const array = new TypedArray([1, 2, 3, 2, 1]); + assert.notSame(array.uniqueBy(), array); + assert.deepEqual(array.uniqueBy(), new TypedArray([1, 2, 3])); + let values = ''; + new TypedArray([1, 2, 3]).uniqueBy(value => { + values += value; + }); + assert.same(values, '123'); + assert.throws(() => uniqueBy.call(null, () => { /* empty */ }), TypeError); + assert.throws(() => uniqueBy.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => uniqueBy.call([0], () => { /* empty */ }), "isn't generic"); + } +}); diff --git a/tests/unit-global/esnext.weak-map.delete-all.js b/tests/unit-global/esnext.weak-map.delete-all.js new file mode 100644 index 000000000000..8763aa5deeb2 --- /dev/null +++ b/tests/unit-global/esnext.weak-map.delete-all.js @@ -0,0 +1,52 @@ +QUnit.test('WeakMap#deleteAll', assert => { + const { deleteAll } = WeakMap.prototype; + + assert.isFunction(deleteAll); + assert.arity(deleteAll, 0); + assert.name(deleteAll, 'deleteAll'); + assert.looksNative(deleteAll); + assert.nonEnumerable(WeakMap.prototype, 'deleteAll'); + + const a = []; + const b = []; + const c = []; + const d = []; + const e = []; + + let set = new WeakMap([[a, 1], [b, 2], [c, 3]]); + assert.true(set.deleteAll(a, b)); + assert.false(set.has(a)); + assert.false(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakMap([[a, 1], [b, 2], [c, 3]]); + assert.false(set.deleteAll(c, d)); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.false(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakMap([[a, 1], [b, 2], [c, 3]]); + assert.false(set.deleteAll(d, e)); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakMap([[a, 1], [b, 2], [c, 3]]); + assert.true(set.deleteAll()); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + assert.throws(() => deleteAll.call({ delete() { /* empty */ } }, a, b, c)); + assert.throws(() => deleteAll.call({}, a, b, c), TypeError); + assert.throws(() => deleteAll.call(undefined, a, b, c), TypeError); + assert.throws(() => deleteAll.call(null, a, b, c), TypeError); +}); diff --git a/tests/unit-global/esnext.weak-map.emplace.js b/tests/unit-global/esnext.weak-map.emplace.js new file mode 100644 index 000000000000..cbc5750790d4 --- /dev/null +++ b/tests/unit-global/esnext.weak-map.emplace.js @@ -0,0 +1,52 @@ +QUnit.test('WeakMap#emplace', assert => { + const { emplace } = WeakMap.prototype; + assert.isFunction(emplace); + assert.arity(emplace, 2); + assert.name(emplace, 'emplace'); + assert.looksNative(emplace); + assert.nonEnumerable(WeakMap.prototype, 'emplace'); + + const a = {}; + const b = {}; + + const map = new WeakMap([[a, 2]]); + let handler = { + update(value, key, that) { + assert.same(this, handler, 'correct handler in callback'); + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, a, 'correct key in callback'); + assert.same(that, map, 'correct map in callback'); + return value ** 2; + }, + insert() { + assert.avoid(); + }, + }; + assert.same(map.emplace(a, handler), 4, 'returns a correct value'); + handler = { + update() { + assert.avoid(); + }, + insert(key, that) { + assert.same(this, handler, 'correct handler in callback'); + assert.same(arguments.length, 2, 'correct number of callback arguments'); + assert.same(key, b, 'correct key in callback'); + assert.same(that, map, 'correct map in callback'); + return 3; + }, + }; + assert.same(map.emplace(b, handler), 3, 'returns a correct value'); + assert.same(map.get(a), 4, 'correct result #1'); + assert.same(map.get(b), 3, 'correct result #2'); + + assert.same(new WeakMap([[a, 2]]).emplace(b, { insert: () => 3 }), 3); + assert.same(new WeakMap([[a, 2]]).emplace(a, { update: value => value ** 2 }), 4); + + handler = { update() { /* empty */ }, insert() { /* empty */ } }; + assert.throws(() => new WeakMap().emplace(a), TypeError); + assert.throws(() => emplace.call({}, a, handler), TypeError); + assert.throws(() => emplace.call([], a, handler), TypeError); + assert.throws(() => emplace.call(undefined, a, handler), TypeError); + assert.throws(() => emplace.call(null, a, handler), TypeError); +}); diff --git a/tests/unit-global/esnext.weak-map.from.js b/tests/unit-global/esnext.weak-map.from.js new file mode 100644 index 000000000000..bce83e3f0103 --- /dev/null +++ b/tests/unit-global/esnext.weak-map.from.js @@ -0,0 +1,22 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('WeakMap.from', assert => { + const { from } = WeakMap; + assert.isFunction(from); + assert.arity(from, 1); + assert.name(from, 'from'); + assert.looksNative(from); + assert.nonEnumerable(WeakMap, 'from'); + assert.true(from([]) instanceof WeakMap); + const array = []; + assert.same(from([[array, 2]]).get(array), 2); + assert.same(from(createIterable([[array, 2]])).get(array), 2); + const pair = [{}, 1]; + const context = {}; + from([pair], function (element, index) { + assert.same(element, pair); + assert.same(index, 0); + assert.same(this, context); + return element; + }, context); +}); diff --git a/tests/unit-global/esnext.weak-map.get-or-insert-computed.js b/tests/unit-global/esnext.weak-map.get-or-insert-computed.js new file mode 100644 index 000000000000..0188cf0b3a14 --- /dev/null +++ b/tests/unit-global/esnext.weak-map.get-or-insert-computed.js @@ -0,0 +1,49 @@ +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('WeakMap#getOrInsertComputed', assert => { + const { getOrInsertComputed } = WeakMap.prototype; + assert.isFunction(getOrInsertComputed); + assert.arity(getOrInsertComputed, 2); + assert.name(getOrInsertComputed, 'getOrInsertComputed'); + assert.looksNative(getOrInsertComputed); + assert.nonEnumerable(WeakMap.prototype, 'getOrInsertComputed'); + + const a = {}; + const b = {}; + + let map = new WeakMap([[a, 2]]); + assert.same(map.getOrInsertComputed(a, () => 3), 2, 'result#1'); + assert.same(map.get(a), 2, 'map#1'); + map = new WeakMap([[a, 2]]); + assert.same(map.getOrInsertComputed(b, () => 3), 3, 'result#2'); + assert.same(map.get(a), 2, 'map#2-1'); + assert.same(map.get(b), 3, 'map#2-2'); + + map = new WeakMap([[a, 2]]); + map.getOrInsertComputed(a, () => assert.avoid()); + + map = new WeakMap([[a, 2]]); + map.getOrInsertComputed(b, function (key) { + if (STRICT) assert.same(this, undefined, 'correct handler in callback'); + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(key, b, 'correct key in callback'); + }); + + map = new WeakMap([[a, 2]]); + assert.throws(() => { + map.getOrInsertComputed(1, () => assert.avoid()); + }, TypeError, 'key validation before call of callback'); + + assert.throws(() => new WeakMap().getOrInsertComputed(1, () => 3), TypeError, 'invalid key#1'); + assert.throws(() => new WeakMap().getOrInsertComputed(null, () => 3), TypeError, 'invalid key#2'); + assert.throws(() => new WeakMap().getOrInsertComputed(undefined, () => 3), TypeError, 'invalid key#3'); + assert.throws(() => new WeakMap().getOrInsertComputed(a, {}), TypeError, 'non-callable#1'); + assert.throws(() => new WeakMap().getOrInsertComputed(a, 1), TypeError, 'non-callable#2'); + assert.throws(() => new WeakMap().getOrInsertComputed(a, null), TypeError, 'non-callable#3'); + assert.throws(() => new WeakMap().getOrInsertComputed(a, undefined), TypeError, 'non-callable#4'); + assert.throws(() => new WeakMap().getOrInsertComputed(a), TypeError, 'non-callable#5'); + assert.throws(() => getOrInsertComputed.call({}, a, () => 3), TypeError, 'non-generic#1'); + assert.throws(() => getOrInsertComputed.call([], a, () => 3), TypeError, 'non-generic#2'); + assert.throws(() => getOrInsertComputed.call(undefined, a, () => 3), TypeError, 'non-generic#3'); + assert.throws(() => getOrInsertComputed.call(null, a, () => 3), TypeError, 'non-generic#4'); +}); diff --git a/tests/unit-global/esnext.weak-map.get-or-insert.js b/tests/unit-global/esnext.weak-map.get-or-insert.js new file mode 100644 index 000000000000..0ff2da597388 --- /dev/null +++ b/tests/unit-global/esnext.weak-map.get-or-insert.js @@ -0,0 +1,28 @@ +QUnit.test('WeakMap#getOrInsert', assert => { + const { getOrInsert } = WeakMap.prototype; + assert.isFunction(getOrInsert); + assert.arity(getOrInsert, 2); + assert.name(getOrInsert, 'getOrInsert'); + assert.looksNative(getOrInsert); + assert.nonEnumerable(WeakMap.prototype, 'getOrInsert'); + + const a = {}; + const b = {}; + + let map = new WeakMap([[a, 2]]); + assert.same(map.getOrInsert(a, 3), 2, 'result#1'); + assert.same(map.get(a), 2, 'map#1'); + map = new WeakMap([[a, 2]]); + assert.same(map.getOrInsert(b, 3), 3, 'result#2'); + assert.same(map.get(a), 2, 'map#2-1'); + assert.same(map.get(b), 3, 'map#2-2'); + + assert.throws(() => new WeakMap().getOrInsert(1, 1), TypeError, 'invalid key#1'); + assert.throws(() => new WeakMap().getOrInsert(null, 1), TypeError, 'invalid key#2'); + assert.throws(() => new WeakMap().getOrInsert(undefined, 1), TypeError, 'invalid key#3'); + assert.throws(() => new WeakMap().getOrInsert(), TypeError, 'invalid key#4'); + assert.throws(() => getOrInsert.call({}, a, 1), TypeError, 'non-generic#1'); + assert.throws(() => getOrInsert.call([], a, 1), TypeError, 'non-generic#2'); + assert.throws(() => getOrInsert.call(undefined, a, 1), TypeError, 'non-generic#3'); + assert.throws(() => getOrInsert.call(null, a, 1), TypeError, 'non-generic#4'); +}); diff --git a/tests/unit-global/esnext.weak-map.of.js b/tests/unit-global/esnext.weak-map.of.js new file mode 100644 index 000000000000..719ae24d696d --- /dev/null +++ b/tests/unit-global/esnext.weak-map.of.js @@ -0,0 +1,11 @@ +QUnit.test('WeakMap.of', assert => { + const { of } = WeakMap; + assert.isFunction(of); + assert.arity(of, 0); + assert.name(of, 'of'); + assert.looksNative(of); + assert.nonEnumerable(WeakMap, 'of'); + const array = []; + assert.true(of() instanceof WeakMap); + assert.same(of([array, 2]).get(array), 2); +}); diff --git a/tests/unit-global/esnext.weak-map.upsert.js b/tests/unit-global/esnext.weak-map.upsert.js new file mode 100644 index 000000000000..c1f829e9932e --- /dev/null +++ b/tests/unit-global/esnext.weak-map.upsert.js @@ -0,0 +1,38 @@ +QUnit.test('WeakMap#upsert', assert => { + const { upsert } = WeakMap.prototype; + assert.isFunction(upsert); + assert.arity(upsert, 2); + assert.looksNative(upsert); + assert.nonEnumerable(WeakMap.prototype, 'upsert'); + + const a = {}; + const b = {}; + + const map = new WeakMap([[a, 2]]); + assert.same(map.upsert(a, function (value) { + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + return value ** 2; + }, () => { + assert.avoid(); + return 3; + }), 4, 'returns a correct value'); + assert.same(map.upsert(b, value => { + assert.avoid(); + return value ** 2; + }, function () { + assert.same(arguments.length, 0, 'correct number of callback arguments'); + return 3; + }), 3, 'returns a correct value'); + assert.same(map.get(a), 4, 'correct result #1'); + assert.same(map.get(b), 3, 'correct result #2'); + + assert.same(new WeakMap([[a, 2]]).upsert(b, null, () => 3), 3); + assert.same(new WeakMap([[a, 2]]).upsert(a, value => value ** 2), 4); + + assert.throws(() => new WeakMap().upsert(a), TypeError); + assert.throws(() => upsert.call({}, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call([], a, () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call(undefined, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call(null, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-global/esnext.weak-set.add-all.js b/tests/unit-global/esnext.weak-set.add-all.js new file mode 100644 index 000000000000..6c5cd87676b7 --- /dev/null +++ b/tests/unit-global/esnext.weak-set.add-all.js @@ -0,0 +1,33 @@ +QUnit.test('WeakSet#addAll', assert => { + const { addAll } = WeakSet.prototype; + + assert.isFunction(addAll); + assert.arity(addAll, 0); + assert.name(addAll, 'addAll'); + assert.looksNative(addAll); + assert.nonEnumerable(WeakSet.prototype, 'addAll'); + + const a = []; + const b = []; + const c = []; + + let set = new WeakSet([a]); + assert.same(set.addAll(b), set); + + set = new WeakSet([a]).addAll(b, c); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + + set = new WeakSet([a]).addAll(a, b); + assert.true(set.has(a)); + assert.true(set.has(b)); + + set = new WeakSet([a]).addAll(); + assert.true(set.has(a)); + + assert.throws(() => addAll.call({ add() { /* empty */ } }, a, b, c)); + assert.throws(() => addAll.call({}, a, b, c), TypeError); + assert.throws(() => addAll.call(undefined, a, b, c), TypeError); + assert.throws(() => addAll.call(null, a, b, c), TypeError); +}); diff --git a/tests/unit-global/esnext.weak-set.delete-all.js b/tests/unit-global/esnext.weak-set.delete-all.js new file mode 100644 index 000000000000..67c30779f82b --- /dev/null +++ b/tests/unit-global/esnext.weak-set.delete-all.js @@ -0,0 +1,52 @@ +QUnit.test('WeakSet#deleteAll', assert => { + const { deleteAll } = WeakSet.prototype; + + assert.isFunction(deleteAll); + assert.arity(deleteAll, 0); + assert.name(deleteAll, 'deleteAll'); + assert.looksNative(deleteAll); + assert.nonEnumerable(WeakSet.prototype, 'deleteAll'); + + const a = []; + const b = []; + const c = []; + const d = []; + const e = []; + + let set = new WeakSet([a, b, c]); + assert.true(set.deleteAll(a, b)); + assert.false(set.has(a)); + assert.false(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakSet([a, b, c]); + assert.false(set.deleteAll(c, d)); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.false(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakSet([a, b, c]); + assert.false(set.deleteAll(d, e)); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakSet([a, b, c]); + assert.true(set.deleteAll()); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + assert.throws(() => deleteAll.call({ delete() { /* empty */ } }, a, b, c)); + assert.throws(() => deleteAll.call({}, a, b, c), TypeError); + assert.throws(() => deleteAll.call(undefined, a, b, c), TypeError); + assert.throws(() => deleteAll.call(null, a, b, c), TypeError); +}); diff --git a/tests/unit-global/esnext.weak-set.from.js b/tests/unit-global/esnext.weak-set.from.js new file mode 100644 index 000000000000..9be06ad5d6af --- /dev/null +++ b/tests/unit-global/esnext.weak-set.from.js @@ -0,0 +1,22 @@ +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('WeakSet.from', assert => { + const { from } = WeakSet; + assert.isFunction(from); + assert.arity(from, 1); + assert.name(from, 'from'); + assert.looksNative(from); + assert.nonEnumerable(WeakSet, 'from'); + assert.true(from([]) instanceof WeakSet); + const array = []; + assert.true(from([array]).has(array)); + assert.true(from(createIterable([array])).has(array)); + const object = {}; + const context = {}; + from([object], function (element, index) { + assert.same(element, object); + assert.same(index, 0); + assert.same(this, context); + return element; + }, context); +}); diff --git a/tests/unit-global/esnext.weak-set.of.js b/tests/unit-global/esnext.weak-set.of.js new file mode 100644 index 000000000000..056eacadeabd --- /dev/null +++ b/tests/unit-global/esnext.weak-set.of.js @@ -0,0 +1,11 @@ +QUnit.test('WeakSet.of', assert => { + const { of } = WeakSet; + assert.isFunction(of); + assert.arity(of, 0); + assert.name(of, 'of'); + assert.looksNative(of); + assert.nonEnumerable(WeakSet, 'of'); + const array = []; + assert.true(of() instanceof WeakSet); + assert.true(of(array).has(array)); +}); diff --git a/tests/unit-global/web.atob.js b/tests/unit-global/web.atob.js new file mode 100644 index 000000000000..d966f5a29a57 --- /dev/null +++ b/tests/unit-global/web.atob.js @@ -0,0 +1,35 @@ +// based on https://github.com/davidchambers/Base64.js/blob/master/test/base64.js +import { NODE } from '../helpers/constants.js'; + +QUnit.test('atob', assert => { + assert.isFunction(atob); + assert.arity(atob, 1); + assert.name(atob, 'atob'); + if (!NODE) assert.looksNative(atob); + + assert.same(atob(''), ''); + assert.same(atob('Zg=='), 'f'); + assert.same(atob('Zm8='), 'fo'); + assert.same(atob('Zm9v'), 'foo'); + assert.same(atob('cXV1eA=='), 'quux'); + assert.same(atob('ISIjJCU='), '!"#$%'); + assert.same(atob('JicoKSor'), "&'()*+"); + assert.same(atob('LC0uLzAxMg=='), ',-./012'); + assert.same(atob('MzQ1Njc4OTo='), '3456789:'); + assert.same(atob('Ozw9Pj9AQUJD'), ';<=>?@ABC'); + assert.same(atob('REVGR0hJSktMTQ=='), 'DEFGHIJKLM'); + assert.same(atob('Tk9QUVJTVFVWV1g='), 'NOPQRSTUVWX'); + assert.same(atob('WVpbXF1eX2BhYmM='), 'YZ[\\]^_`abc'); + assert.same(atob('ZGVmZ2hpamtsbW5vcA=='), 'defghijklmnop'); + assert.same(atob('cXJzdHV2d3h5ent8fX4='), 'qrstuvwxyz{|}~'); + assert.same(atob(' '), ''); + + assert.same(atob(42), atob('42')); + assert.same(atob(null), atob('null')); + + assert.throws(() => atob(), TypeError, 'no args'); + assert.throws(() => atob('a'), 'invalid #1'); + assert.throws(() => atob('a '), 'invalid #2'); + assert.throws(() => atob('aaaaa'), 'invalid #3'); + assert.throws(() => atob('[object Object]'), 'invalid #4'); +}); diff --git a/tests/unit-global/web.btoa.js b/tests/unit-global/web.btoa.js new file mode 100644 index 000000000000..f8b18edd2395 --- /dev/null +++ b/tests/unit-global/web.btoa.js @@ -0,0 +1,33 @@ +// based on https://github.com/davidchambers/Base64.js/blob/master/test/base64.js +import { NODE } from '../helpers/constants.js'; + +QUnit.test('btoa', assert => { + assert.isFunction(btoa); + assert.arity(btoa, 1); + assert.name(btoa, 'btoa'); + if (!NODE) assert.looksNative(btoa); + + assert.same(btoa(''), ''); + assert.same(btoa('f'), 'Zg=='); + assert.same(btoa('fo'), 'Zm8='); + assert.same(btoa('foo'), 'Zm9v'); + assert.same(btoa('quux'), 'cXV1eA=='); + assert.same(btoa('!"#$%'), 'ISIjJCU='); + assert.same(btoa("&'()*+"), 'JicoKSor'); + assert.same(btoa(',-./012'), 'LC0uLzAxMg=='); + assert.same(btoa('3456789:'), 'MzQ1Njc4OTo='); + assert.same(btoa(';<=>?@ABC'), 'Ozw9Pj9AQUJD'); + assert.same(btoa('DEFGHIJKLM'), 'REVGR0hJSktMTQ=='); + assert.same(btoa('NOPQRSTUVWX'), 'Tk9QUVJTVFVWV1g='); + assert.same(btoa('YZ[\\]^_`abc'), 'WVpbXF1eX2BhYmM='); + assert.same(btoa('defghijklmnop'), 'ZGVmZ2hpamtsbW5vcA=='); + assert.same(btoa('qrstuvwxyz{|}~'), 'cXJzdHV2d3h5ent8fX4='); + assert.same(btoa('qrstuvwxyz{|}~'), 'cXJzdHV2d3h5ent8fX4='); + + assert.same(btoa(42), btoa('42')); + assert.same(btoa(null), btoa('null')); + assert.same(btoa({ x: 1 }), btoa('[object Object]')); + + assert.throws(() => btoa(), TypeError, 'no args'); + assert.throws(() => btoa('✈'), 'non-ASCII'); +}); diff --git a/tests/tests/web.dom-collections.for-each.js b/tests/unit-global/web.dom-collections.for-each.js similarity index 83% rename from tests/tests/web.dom-collections.for-each.js rename to tests/unit-global/web.dom-collections.for-each.js index a7c96243a452..eb5ba8c75f42 100644 --- a/tests/tests/web.dom-collections.for-each.js +++ b/tests/unit-global/web.dom-collections.for-each.js @@ -1,4 +1,4 @@ -import { GLOBAL } from '../helpers/constants'; +import { GLOBAL } from '../helpers/constants.js'; QUnit.test('forEach method on iterable DOM collections', assert => { let absent = true; @@ -17,6 +17,6 @@ QUnit.test('forEach method on iterable DOM collections', assert => { } if (absent) { - assert.ok(true, 'DOM collections are absent'); + assert.required('DOM collections are absent'); } }); diff --git a/tests/unit-global/web.dom-collections.iterator.js b/tests/unit-global/web.dom-collections.iterator.js new file mode 100644 index 000000000000..23f0adb8b935 --- /dev/null +++ b/tests/unit-global/web.dom-collections.iterator.js @@ -0,0 +1,74 @@ +import { GLOBAL } from '../helpers/constants.js'; + +const Symbol = GLOBAL.Symbol || {}; + +QUnit.test('Iterable DOM collections', assert => { + let absent = true; + let collections = [ + 'CSSRuleList', + 'CSSStyleDeclaration', + 'CSSValueList', + 'ClientRectList', + 'DOMRectList', + 'DOMStringList', + 'DOMTokenList', + 'DataTransferItemList', + 'FileList', + 'HTMLAllCollection', + 'HTMLCollection', + 'HTMLFormElement', + 'HTMLSelectElement', + 'MediaList', + 'MimeTypeArray', + 'NamedNodeMap', + 'NodeList', + 'PaintRequestList', + 'Plugin', + 'PluginArray', + 'SVGLengthList', + 'SVGNumberList', + 'SVGPathSegList', + 'SVGPointList', + 'SVGStringList', + 'SVGTransformList', + 'SourceBufferList', + 'StyleSheetList', + 'TextTrackCueList', + 'TextTrackList', + 'TouchList', + ]; + + for (const name of collections) { + const Collection = GLOBAL[name]; + if (Collection) { + assert.same(Collection.prototype[Symbol.toStringTag], name, `${ name }::@@toStringTag is '${ name }'`); + assert.isFunction(Collection.prototype[Symbol.iterator], `${ name }::@@iterator is function`); + absent = false; + } + } + + if (GLOBAL.NodeList && GLOBAL.document && document.querySelectorAll && document.querySelectorAll('div') instanceof NodeList) { + assert.isFunction(document.querySelectorAll('div')[Symbol.iterator], 'works with document.querySelectorAll'); + } + + collections = [ + 'NodeList', + 'DOMTokenList', + ]; + + for (const name of collections) { + const Collection = GLOBAL[name]; + if (Collection) { + assert.isFunction(Collection.prototype.values, `${ name }::values is function`); + assert.same(Collection.prototype.values, Array.prototype.values, `${ name }::values is equal of Array::values`); + assert.isFunction(Collection.prototype.keys, `${ name }::keys is function`); + assert.same(Collection.prototype.keys, Array.prototype.keys, `${ name }::keys is equal of Array::keys`); + assert.isFunction(Collection.prototype.entries, `${ name }::entries is function`); + assert.same(Collection.prototype.entries, Array.prototype.entries, `${ name }::entries is equal of Array::entries`); + } + } + + if (absent) { + assert.required('DOM collections are absent'); + } +}); diff --git a/tests/unit-global/web.dom-exception.constructor.js b/tests/unit-global/web.dom-exception.constructor.js new file mode 100644 index 000000000000..79113e23f730 --- /dev/null +++ b/tests/unit-global/web.dom-exception.constructor.js @@ -0,0 +1,80 @@ +import { DESCRIPTORS, NODE } from '../helpers/constants.js'; + +const errors = { + IndexSizeError: { s: 'INDEX_SIZE_ERR', c: 1, m: 1 }, + DOMStringSizeError: { s: 'DOMSTRING_SIZE_ERR', c: 2, m: 0 }, + HierarchyRequestError: { s: 'HIERARCHY_REQUEST_ERR', c: 3, m: 1 }, + WrongDocumentError: { s: 'WRONG_DOCUMENT_ERR', c: 4, m: 1 }, + InvalidCharacterError: { s: 'INVALID_CHARACTER_ERR', c: 5, m: 1 }, + NoDataAllowedError: { s: 'NO_DATA_ALLOWED_ERR', c: 6, m: 0 }, + NoModificationAllowedError: { s: 'NO_MODIFICATION_ALLOWED_ERR', c: 7, m: 1 }, + NotFoundError: { s: 'NOT_FOUND_ERR', c: 8, m: 1 }, + NotSupportedError: { s: 'NOT_SUPPORTED_ERR', c: 9, m: 1 }, + InUseAttributeError: { s: 'INUSE_ATTRIBUTE_ERR', c: 10, m: 1 }, + InvalidStateError: { s: 'INVALID_STATE_ERR', c: 11, m: 1 }, + SyntaxError: { s: 'SYNTAX_ERR', c: 12, m: 1 }, + InvalidModificationError: { s: 'INVALID_MODIFICATION_ERR', c: 13, m: 1 }, + NamespaceError: { s: 'NAMESPACE_ERR', c: 14, m: 1 }, + InvalidAccessError: { s: 'INVALID_ACCESS_ERR', c: 15, m: 1 }, + ValidationError: { s: 'VALIDATION_ERR', c: 16, m: 0 }, + TypeMismatchError: { s: 'TYPE_MISMATCH_ERR', c: 17, m: 1 }, + SecurityError: { s: 'SECURITY_ERR', c: 18, m: 1 }, + NetworkError: { s: 'NETWORK_ERR', c: 19, m: 1 }, + AbortError: { s: 'ABORT_ERR', c: 20, m: 1 }, + URLMismatchError: { s: 'URL_MISMATCH_ERR', c: 21, m: 1 }, + // https://github.com/whatwg/webidl/pull/1465 + // QuotaExceededError: { s: 'QUOTA_EXCEEDED_ERR', c: 22, m: 1 }, + TimeoutError: { s: 'TIMEOUT_ERR', c: 23, m: 1 }, + InvalidNodeTypeError: { s: 'INVALID_NODE_TYPE_ERR', c: 24, m: 1 }, + DataCloneError: { s: 'DATA_CLONE_ERR', c: 25, m: 1 }, +}; + +const HAS_STACK = 'stack' in new Error('1'); + +QUnit.test('DOMException', assert => { + assert.isFunction(DOMException); + assert.arity(DOMException, 0); + assert.name(DOMException, 'DOMException'); + // assert.looksNative(DOMException); // FF43- bug + + let error = new DOMException({}, 'Foo'); + assert.true(error instanceof DOMException, 'new DOMException({}, "Foo") instanceof DOMException'); + assert.same(error.message, '[object Object]', 'new DOMException({}, "Foo").message'); + assert.same(error.name, 'Foo', 'new DOMException({}, "Foo").name'); + assert.same(error.code, 0, 'new DOMException({}, "Foo").code'); + assert.same(String(error), 'Foo: [object Object]', 'String(new DOMException({}, "Foo"))'); // Safari 10.1 bug + assert.same(error.constructor, DOMException, 'new DOMException({}, "Foo").constructor'); + assert.same(error[Symbol.toStringTag], 'DOMException', 'DOMException.prototype[Symbol.toStringTag]'); + if (HAS_STACK) assert.true('stack' in error, "'stack' in new DOMException()"); + + assert.same(new DOMException().message, '', 'new DOMException().message'); + assert.same(new DOMException(undefined).message, '', 'new DOMException(undefined).message'); + assert.same(new DOMException(42).name, 'Error', 'new DOMException(42).name'); + assert.same(new DOMException(42, undefined).name, 'Error', 'new DOMException(42, undefined).name'); + + for (const name in errors) { + error = new DOMException(42, name); + assert.true(error instanceof DOMException, `new DOMException({}, "${ name }") instanceof DOMException`); + assert.same(error.message, '42', `new DOMException({}, "${ name }").message`); + assert.same(error.name, name, `new DOMException({}, "${ name }").name`); + if (errors[name].m) assert.same(error.code, errors[name].c, `new DOMException({}, "${ name }").code`); + // NodeJS and Deno set codes to deprecated errors + else if (!NODE) assert.same(error.code, 0, `new DOMException({}, "${ name }").code`); + assert.same(String(error), `${ name }: 42`, `String(new DOMException({}, "${ name }"))`); // Safari 10.1 bug + if (HAS_STACK) assert.true('stack' in error, `'stack' in new DOMException({}, "${ name }")`); + + assert.same(DOMException[errors[name].s], errors[name].c, `DOMException.${ errors[name].s }`); + assert.same(DOMException.prototype[errors[name].s], errors[name].c, `DOMException.prototype.${ errors[name].s }`); + } + + assert.throws(() => DOMException(42, 'DataCloneError'), "DOMException(42, 'DataCloneError')"); + const symbol = Symbol('DOMException constructor test'); + assert.throws(() => new DOMException(symbol, 'DataCloneError'), "new DOMException(Symbol(), 'DataCloneError')"); + assert.throws(() => new DOMException(42, symbol), 'new DOMException(42, Symbol())'); + if (DESCRIPTORS) { + // assert.throws(() => DOMException.prototype.message, 'DOMException.prototype.message'); // FF55- , Safari 10.1 bug + // assert.throws(() => DOMException.prototype.name, 'DOMException.prototype.name'); // FF55-, Safari 10.1 bug bug + // assert.throws(() => DOMException.prototype.code, 'DOMException.prototype.code'); // Safari 10.1 bug + // assert.throws(() => DOMException.prototype.toString(), 'DOMException.prototype.toString()'); // FF55- bug + } +}); diff --git a/tests/unit-global/web.queue-microtask.js b/tests/unit-global/web.queue-microtask.js new file mode 100644 index 000000000000..a14d630f3a67 --- /dev/null +++ b/tests/unit-global/web.queue-microtask.js @@ -0,0 +1,20 @@ +import { NODE } from '../helpers/constants.js'; +import { timeLimitedPromise } from '../helpers/helpers.js'; + +QUnit.test('queueMicrotask', assert => { + assert.isFunction(queueMicrotask); + assert.arity(queueMicrotask, 1); + assert.name(queueMicrotask, 'queueMicrotask'); + if (!NODE) assert.looksNative(queueMicrotask); + + return timeLimitedPromise(3e3, resolve => { + let called = false; + queueMicrotask(() => { + called = true; + resolve(); + }); + assert.false(called, 'async'); + }).then(() => { + assert.required('works'); + }); +}); diff --git a/tests/unit-global/web.self.js b/tests/unit-global/web.self.js new file mode 100644 index 000000000000..dec5895fdc02 --- /dev/null +++ b/tests/unit-global/web.self.js @@ -0,0 +1,14 @@ +/* eslint-disable no-restricted-globals, unicorn/prefer-global-this -- safe */ +import { DESCRIPTORS } from '../helpers/constants.js'; + +QUnit.test('self', assert => { + assert.same(self, Object(self), 'is object'); + assert.same(self.Math, Math, 'contains globals'); + if (DESCRIPTORS) { + const descriptor = Object.getOwnPropertyDescriptor(self, 'self'); + // can't be properly defined (non-configurable) in some ancient engines like PhantomJS + // assert.isFunction(descriptor.get, 'a getter'); + // assert.true(descriptor.configurable, 'configurable'); + assert.true(descriptor.enumerable, 'enumerable'); + } +}); diff --git a/tests/unit-global/web.set-immediate.js b/tests/unit-global/web.set-immediate.js new file mode 100644 index 000000000000..40c933dcb91e --- /dev/null +++ b/tests/unit-global/web.set-immediate.js @@ -0,0 +1,42 @@ +import { timeLimitedPromise } from '../helpers/helpers.js'; + +QUnit.test('setImmediate / clearImmediate', assert => { + assert.isFunction(setImmediate, 'setImmediate is function'); + assert.isFunction(clearImmediate, 'clearImmediate is function'); + assert.name(setImmediate, 'setImmediate'); + assert.name(clearImmediate, 'clearImmediate'); + let called = false; + + const promise = timeLimitedPromise(1e3, resolve => { + setImmediate(() => { + called = true; + resolve(); + }); + }).then(() => { + assert.required('setImmediate works'); + }, () => { + assert.avoid('setImmediate works'); + }).then(() => { + return timeLimitedPromise(1e3, resolve => { + setImmediate((a, b) => { + resolve(a + b); + }, 'a', 'b'); + }); + }).then(it => { + assert.same(it, 'ab', 'setImmediate works with additional args'); + }, () => { + assert.avoid('setImmediate works with additional args'); + }).then(() => { + return timeLimitedPromise(50, resolve => { + clearImmediate(setImmediate(resolve)); + }); + }).then(() => { + assert.avoid('clearImmediate works'); + }, () => { + assert.required('clearImmediate works'); + }); + + assert.false(called, 'setImmediate is async'); + + return promise; +}); diff --git a/tests/unit-global/web.set-interval.js b/tests/unit-global/web.set-interval.js new file mode 100644 index 000000000000..276799b71d4f --- /dev/null +++ b/tests/unit-global/web.set-interval.js @@ -0,0 +1,23 @@ +import { timeLimitedPromise } from '../helpers/helpers.js'; + +QUnit.test('setInterval / clearInterval', assert => { + assert.isFunction(setInterval, 'setInterval is function'); + assert.isFunction(clearInterval, 'clearInterval is function'); + assert.name(setInterval, 'setInterval'); + assert.name(clearInterval, 'clearInterval'); + + return timeLimitedPromise(1e4, (resolve, reject) => { + let i = 0; + const interval = setInterval((a, b) => { + if (a + b !== 'ab' || i > 2) reject({ a, b, i }); + if (i++ === 2) { + clearInterval(interval); + setTimeout(resolve, 30); + } + }, 5, 'a', 'b'); + }).then(() => { + assert.required('setInterval & clearInterval works with additional args'); + }, (error = {}) => { + assert.avoid(`setInterval & clearInterval works with additional args: ${ error.a }, ${ error.b }, times: ${ error.i }`); + }); +}); diff --git a/tests/unit-global/web.set-timeout.js b/tests/unit-global/web.set-timeout.js new file mode 100644 index 000000000000..bca1fffae9fb --- /dev/null +++ b/tests/unit-global/web.set-timeout.js @@ -0,0 +1,24 @@ +import { timeLimitedPromise } from '../helpers/helpers.js'; + +QUnit.test('setTimeout / clearTimeout', assert => { + assert.isFunction(setTimeout, 'setTimeout is function'); + assert.isFunction(clearTimeout, 'clearTimeout is function'); + assert.name(setTimeout, 'setTimeout'); + assert.name(clearTimeout, 'clearTimeout'); + + return timeLimitedPromise(1e3, resolve => { + setTimeout((a, b) => { resolve(a + b); }, 10, 'a', 'b'); + }).then(it => { + assert.same(it, 'ab', 'setTimeout works with additional args'); + }, () => { + assert.avoid('setTimeout works with additional args'); + }).then(() => { + return timeLimitedPromise(50, resolve => { + clearTimeout(setTimeout(resolve, 10)); + }); + }).then(() => { + assert.avoid('clearImmediate works with wrapped setTimeout'); + }, () => { + assert.required('clearImmediate works with wrapped setTimeout'); + }); +}); diff --git a/tests/unit-global/web.structured-clone.js b/tests/unit-global/web.structured-clone.js new file mode 100644 index 000000000000..4a02398ce0b4 --- /dev/null +++ b/tests/unit-global/web.structured-clone.js @@ -0,0 +1,476 @@ +// Originally from: https://github.com/web-platform-tests/wpt/blob/4b35e758e2fc4225368304b02bcec9133965fd1a/IndexedDB/structured-clone.any.js +// Copyright © web-platform-tests contributors. Available under the 3-Clause BSD License. +import { GLOBAL, NODE, BUN } from '../helpers/constants.js'; +import { bufferToArray, fromSource } from '../helpers/helpers.js'; + +const { from } = Array; +const { assign, getPrototypeOf, keys } = Object; + +QUnit.module('structuredClone', () => { + QUnit.test('identity', assert => { + assert.isFunction(structuredClone, 'structuredClone is a function'); + assert.name(structuredClone, 'structuredClone'); + assert.arity(structuredClone, 1); + if (!NODE) assert.looksNative(structuredClone); + assert.throws(() => structuredClone(), 'throws without arguments'); + assert.same(structuredClone(1, null), 1, 'null as options'); + assert.same(structuredClone(1, undefined), 1, 'undefined as options'); + }); + + function cloneTest(value, verifyFunc) { + verifyFunc(value, structuredClone(value)); + } + + // Specialization of cloneTest() for objects, with common asserts. + function cloneObjectTest(assert, value, verifyFunc) { + cloneTest(value, (orig, clone) => { + assert.notSame(orig, clone, 'clone should have different reference'); + assert.same(typeof clone, 'object', 'clone should be an object'); + // https://github.com/qunitjs/node-qunit/issues/146 + assert.true(getPrototypeOf(orig) === getPrototypeOf(clone), 'clone should have same prototype'); + verifyFunc(orig, clone); + }); + } + + // ECMAScript types + + // Primitive values: Undefined, Null, Boolean, Number, BigInt, String + const booleans = [false, true]; + const numbers = [ + NaN, + -Infinity, + -Number.MAX_VALUE, + -0xFFFFFFFF, + -0x80000000, + -0x7FFFFFFF, + -1, + -Number.MIN_VALUE, + -0, + 0, + 1, + Number.MIN_VALUE, + 0x7FFFFFFF, + 0x80000000, + 0xFFFFFFFF, + Number.MAX_VALUE, + Infinity, + ]; + + const bigints = fromSource(`[ + -12345678901234567890n, + -1n, + 0n, + 1n, + 12345678901234567890n, + ]`) || []; + + const strings = [ + '', + 'this is a sample string', + 'null(\0)', + ]; + + QUnit.test('primitives', assert => { + const primitives = [undefined, null, ...booleans, ...numbers, ...bigints, ...strings]; + + for (const value of primitives) cloneTest(value, (orig, clone) => { + assert.same(orig, clone, 'primitives should be same after cloned'); + }); + }); + + // "Primitive" Objects (Boolean, Number, BigInt, String) + QUnit.test('primitive objects', assert => { + const primitives = [...booleans, ...numbers, ...bigints, ...strings]; + + for (const value of primitives) cloneObjectTest(assert, Object(value), (orig, clone) => { + assert.same(orig.valueOf(), clone.valueOf(), 'primitive wrappers should have same value'); + }); + }); + + // Dates + QUnit.test('Date', assert => { + const dates = [ + new Date(-1e13), + new Date(-1e12), + new Date(-1e9), + new Date(-1e6), + new Date(-1e3), + new Date(0), + new Date(1e3), + new Date(1e6), + new Date(1e9), + new Date(1e12), + new Date(1e13), + ]; + + for (const date of dates) cloneTest(date, (orig, clone) => { + assert.notSame(orig, clone); + assert.same(typeof clone, 'object'); + assert.same(getPrototypeOf(orig), getPrototypeOf(clone)); + assert.same(orig.valueOf(), clone.valueOf()); + }); + }); + + // Regular Expressions + QUnit.test('RegExp', assert => { + const regexes = [ + new RegExp(), + /abc/, + /abc/g, + /abc/i, + /abc/gi, + /abc/, + /abc/g, + /abc/i, + /abc/gi, + ]; + + const giuy = fromSource('/abc/giuy'); + if (giuy) regexes.push(giuy); + + for (const regex of regexes) cloneObjectTest(assert, regex, (orig, clone) => { + assert.same(orig.toString(), clone.toString(), `regex ${ regex }`); + }); + }); + + if (fromSource('ArrayBuffer.prototype.slice || DataView')) { + // ArrayBuffer + if (typeof Uint8Array == 'function') QUnit.test('ArrayBuffer', assert => { // Crashes + cloneObjectTest(assert, new Uint8Array([0, 1, 254, 255]).buffer, (orig, clone) => { + assert.arrayEqual(new Uint8Array(orig), new Uint8Array(clone)); + }); + }); + + // TODO SharedArrayBuffer + + // Array Buffer Views + if (typeof Int8Array != 'undefined') { + QUnit.test('%TypedArray%', assert => { + const arrays = [ + new Uint8Array([]), + new Uint8Array([0, 1, 254, 255]), + new Uint16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF]), + new Uint32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF]), + new Int8Array([0, 1, 254, 255]), + new Int16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF]), + new Int32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF]), + new Float32Array([-Infinity, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, Infinity, NaN]), + new Float64Array([-Infinity, -Number.MAX_VALUE, -Number.MIN_VALUE, 0, Number.MIN_VALUE, Number.MAX_VALUE, Infinity, NaN]), + ]; + + if (typeof Uint8ClampedArray != 'undefined') { + arrays.push(new Uint8ClampedArray([0, 1, 254, 255])); + } + + for (const array of arrays) cloneObjectTest(assert, array, (orig, clone) => { + assert.arrayEqual(orig, clone); + }); + }); + + if (typeof DataView != 'undefined') QUnit.test('DataView', assert => { + const array = new Int8Array([1, 2, 3, 4]); + const view = new DataView(array.buffer); + + cloneObjectTest(assert, array, (orig, clone) => { + assert.same(orig.byteLength, clone.byteLength); + assert.same(orig.byteOffset, clone.byteOffset); + assert.arrayEqual(new Int8Array(view.buffer), array); + }); + }); + } + + if ('resizable' in ArrayBuffer.prototype) { + QUnit.test('Resizable ArrayBuffer', assert => { + const array = [1, 2, 3, 4, 5, 6, 7, 8]; + + let buffer = new ArrayBuffer(8, { maxByteLength: 16 }); + new Int8Array(buffer).set(array); + let copy = structuredClone(buffer); + assert.arrayEqual(bufferToArray(copy), array, 'resizable-ab-1'); + assert.true(copy.resizable, 'resizable-ab-1'); + + buffer = new ArrayBuffer(8); + new Int8Array(buffer).set(array); + copy = structuredClone(buffer); + assert.arrayEqual(bufferToArray(copy), array, 'non-resizable-ab-1'); + assert.false(copy.resizable, 'non-resizable-ab-1'); + + buffer = new ArrayBuffer(8, { maxByteLength: 16 }); + let tarray = new Int8Array(buffer); + tarray.set(array); + copy = structuredClone(tarray).buffer; + assert.arrayEqual(bufferToArray(copy), array, 'resizable-ab-2'); + assert.true(copy.resizable, 'resizable-ab-2'); + + buffer = new ArrayBuffer(8); + tarray = new Int8Array(buffer); + tarray.set(array); + copy = structuredClone(tarray).buffer; + assert.arrayEqual(bufferToArray(copy), array, 'non-resizable-ab-2'); + assert.false(copy.resizable, 'non-resizable-ab-2'); + }); + } + } + + // Map + QUnit.test('Map', assert => { + cloneObjectTest(assert, new Map([[1, 2], [3, 4]]), (orig, clone) => { + assert.deepEqual(from(orig.keys()), from(clone.keys())); + assert.deepEqual(from(orig.values()), from(clone.values())); + }); + }); + + // Set + QUnit.test('Set', assert => { + cloneObjectTest(assert, new Set([1, 2, 3, 4]), (orig, clone) => { + assert.deepEqual(from(orig.values()), from(clone.values())); + }); + }); + + // Error + QUnit.test('Error', assert => { + const errors = [ + ['Error', new Error()], + ['Error', new Error('msg', { cause: 42 })], + ['EvalError', new EvalError()], + ['EvalError', new EvalError('msg', { cause: 42 })], + ['RangeError', new RangeError()], + ['RangeError', new RangeError('msg', { cause: 42 })], + ['ReferenceError', new ReferenceError()], + ['ReferenceError', new ReferenceError('msg', { cause: 42 })], + ['SyntaxError', new SyntaxError()], + ['SyntaxError', new SyntaxError('msg', { cause: 42 })], + ['TypeError', new TypeError()], + ['TypeError', new TypeError('msg', { cause: 42 })], + ['URIError', new URIError()], + ['URIError', new URIError('msg', { cause: 42 })], + ['AggregateError', new AggregateError([1, 2])], + ['AggregateError', new AggregateError([1, 2], 'msg', { cause: 42 })], + ]; + + const compile = fromSource('WebAssembly.CompileError()'); + const link = fromSource('WebAssembly.LinkError()'); + const runtime = fromSource('WebAssembly.RuntimeError()'); + + if (compile && compile.name === 'CompileError') errors.push(['CompileError', compile]); + if (link && link.name === 'LinkError') errors.push(['LinkError', link]); + if (runtime && runtime.name === 'RuntimeError') errors.push(['RuntimeError', runtime]); + + for (const [name, error] of errors) cloneObjectTest(assert, error, (orig, clone) => { + assert.same(orig.constructor, clone.constructor, `${ name }#constructor`); + assert.same(orig.name, clone.name, `${ name }#name`); + assert.same(orig.message, clone.message, `${ name }#message`); + assert.same(orig.stack, clone.stack, `${ name }#stack`); + assert.same(orig.cause, clone.cause, `${ name }#cause`); + assert.deepEqual(orig.errors, clone.errors, `${ name }#errors`); + }); + }); + + // Arrays + QUnit.test('Array', assert => { + const arrays = [ + [], + [1, 2, 3], + Array(1), + assign( + ['foo', 'bar'], + { 10: true, 11: false, 20: 123, 21: 456, 30: null }), + assign( + ['foo', 'bar'], + { a: true, b: false, foo: 123, bar: 456, '': null }), + ]; + + for (const array of arrays) cloneObjectTest(assert, array, (orig, clone) => { + assert.deepEqual(orig, clone, `array content should be same: ${ array }`); + assert.deepEqual(orig.length, clone.length, `array length should be same: ${ array }`); + assert.deepEqual(keys(orig), keys(clone), `array key should be same: ${ array }`); + for (const key of keys(orig)) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + + // Objects + QUnit.test('Object', assert => { + cloneObjectTest(assert, { foo: true, bar: false }, (orig, clone) => { + assert.deepEqual(keys(orig), keys(clone)); + for (const key of keys(orig)) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + + // [Serializable] Platform objects + + // Geometry types + if (typeof DOMMatrix == 'function') { + QUnit.test('Geometry types, DOMMatrix', assert => { + cloneObjectTest(assert, new DOMMatrix(), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMMatrixReadOnly == 'function' && typeof DOMMatrixReadOnly.fromMatrix == 'function') { + QUnit.test('Geometry types, DOMMatrixReadOnly', assert => { + cloneObjectTest(assert, new DOMMatrixReadOnly(), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMPoint == 'function') { + QUnit.test('Geometry types, DOMPoint', assert => { + cloneObjectTest(assert, new DOMPoint(1, 2, 3, 4), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMPointReadOnly == 'function' && typeof DOMPointReadOnly.fromPoint == 'function') { + QUnit.test('Geometry types, DOMPointReadOnly', assert => { + cloneObjectTest(assert, new DOMPointReadOnly(1, 2, 3, 4), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMQuad == 'function' && typeof DOMPoint == 'function') { + QUnit.test('Geometry types, DOMQuad', assert => { + cloneObjectTest(assert, new DOMQuad( + new DOMPoint(1, 2, 3, 4), + new DOMPoint(2, 2, 3, 4), + new DOMPoint(1, 3, 3, 4), + new DOMPoint(1, 2, 4, 4), + ), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.deepEqual(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (fromSource('new DOMRect(1, 2, 3, 4)')) { + QUnit.test('Geometry types, DOMRect', assert => { + cloneObjectTest(assert, new DOMRect(1, 2, 3, 4), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMRectReadOnly == 'function' && typeof DOMRectReadOnly.fromRect == 'function') { + QUnit.test('Geometry types, DOMRectReadOnly', assert => { + cloneObjectTest(assert, new DOMRectReadOnly(1, 2, 3, 4), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + // Safari 8- does not support `{ colorSpace }` option + if (fromSource('new ImageData(new ImageData(8, 8).data, 8, 8, { colorSpace: new ImageData(8, 8).colorSpace })')) { + QUnit.test('ImageData', assert => { + const imageData = new ImageData(8, 8); + for (let i = 0; i < 256; ++i) { + imageData.data[i] = i; + } + cloneObjectTest(assert, imageData, (orig, clone) => { + assert.same(orig.width, clone.width); + assert.same(orig.height, clone.height); + assert.same(orig.colorSpace, clone.colorSpace); + assert.arrayEqual(orig.data, clone.data); + }); + }); + } + + if (fromSource('new Blob(["test"])')) QUnit.test('Blob', assert => { + cloneObjectTest( + assert, + new Blob(['This is a test.'], { type: 'a/b' }), + (orig, clone) => { + assert.same(orig.size, clone.size); + assert.same(orig.type, clone.type); + // TODO: async + // assert.same(await orig.text(), await clone.text()); + }); + }); + + QUnit.test('DOMException', assert => { + const errors = [ + new DOMException(), + new DOMException('foo', 'DataCloneError'), + ]; + + for (const error of errors) cloneObjectTest(assert, error, (orig, clone) => { + assert.same(orig.name, clone.name); + assert.same(orig.message, clone.message); + assert.same(orig.code, clone.code); + assert.same(orig.stack, clone.stack); + }); + }); + + // https://github.com/oven-sh/bun/issues/11696 + if (!BUN && fromSource('new File(["test"], "foo.txt")')) QUnit.test('File', assert => { + cloneObjectTest( + assert, + new File(['This is a test.'], 'foo.txt', { type: 'c/d' }), + (orig, clone) => { + assert.same(orig.size, clone.size); + assert.same(orig.type, clone.type); + assert.same(orig.name, clone.name); + assert.same(orig.lastModified, clone.lastModified); + // TODO: async + // assert.same(await orig.text(), await clone.text()); + }); + }); + + // FileList + if (fromSource('new File(["test"], "foo.txt")') && fromSource('new DataTransfer() && "items" in DataTransfer.prototype')) QUnit.test('FileList', assert => { + const transfer = new DataTransfer(); + transfer.items.add(new File(['test'], 'foo.txt')); + cloneObjectTest( + assert, + transfer.files, + (orig, clone) => { + assert.same(1, clone.length); + assert.same(orig[0].size, clone[0].size); + assert.same(orig[0].type, clone[0].type); + assert.same(orig[0].name, clone[0].name); + assert.same(orig[0].lastModified, clone[0].lastModified); + }, + ); + }); + + // Non-serializable types + QUnit.test('Non-serializable types', assert => { + const nons = [ + function () { return 1; }, + Symbol('desc'), + GLOBAL, + ]; + + const event = fromSource('new Event("")'); + const port = fromSource('new MessageChannel().port1'); + + // NodeJS events are simple objects + if (event && !NODE) nons.push(event); + if (port) nons.push(port); + + for (const it of nons) { + // native NodeJS `structuredClone` throws a `TypeError` on transferable non-serializable instead of `DOMException` + // https://github.com/nodejs/node/issues/40841 + assert.throws(() => structuredClone(it)); + } + }); +}); diff --git a/tests/unit-global/web.url-search-params.js b/tests/unit-global/web.url-search-params.js new file mode 100644 index 000000000000..fce193df4a5d --- /dev/null +++ b/tests/unit-global/web.url-search-params.js @@ -0,0 +1,938 @@ +import { DESCRIPTORS, NODE, BUN } from '../helpers/constants.js'; +import { createIterable } from '../helpers/helpers.js'; + +const { getPrototypeOf, getOwnPropertyDescriptor } = Object; + +QUnit.test('URLSearchParams', assert => { + assert.isFunction(URLSearchParams); + assert.arity(URLSearchParams, 0); + assert.name(URLSearchParams, 'URLSearchParams'); + if (!NODE) assert.looksNative(URLSearchParams); + + assert.same(String(new URLSearchParams()), ''); + assert.same(String(new URLSearchParams('')), ''); + assert.same(String(new URLSearchParams('a=b')), 'a=b'); + assert.same(String(new URLSearchParams(new URLSearchParams('a=b'))), 'a=b'); + assert.same(String(new URLSearchParams([])), ''); + assert.same(String(new URLSearchParams([[1, 2], ['a', 'b']])), '1=2&a=b'); + assert.same(String(new URLSearchParams(createIterable([createIterable(['a', 'b']), createIterable(['c', 'd'])]))), 'a=b&c=d'); + assert.same(String(new URLSearchParams({})), ''); + assert.same(String(new URLSearchParams({ 1: 2, a: 'b' })), '1=2&a=b'); + + assert.same(String(new URLSearchParams('?a=b')), 'a=b', 'leading ? should be ignored'); + assert.same(String(new URLSearchParams('??a=b')), '%3Fa=b'); + assert.same(String(new URLSearchParams('?')), ''); + assert.same(String(new URLSearchParams('??')), '%3F='); + + assert.same(String(new URLSearchParams('a=b c')), 'a=b+c'); + assert.same(String(new URLSearchParams('a=b&b=c&a=d')), 'a=b&b=c&a=d'); + + assert.same(String(new URLSearchParams('a==')), 'a=%3D'); + assert.same(String(new URLSearchParams('a=b=')), 'a=b%3D'); + assert.same(String(new URLSearchParams('a=b=c')), 'a=b%3Dc'); + assert.same(String(new URLSearchParams('a==b')), 'a=%3Db'); + + let params = new URLSearchParams('a=b'); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.false(params.has('b'), 'search params object has not got name "b"'); + + params = new URLSearchParams('a=b&c'); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.true(params.has('c'), 'search params object has name "c"'); + + params = new URLSearchParams('&a&&& &&&&&a+b=& c&m%c3%b8%c3%b8'); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.true(params.has('a b'), 'search params object has name "a b"'); + assert.true(params.has(' '), 'search params object has name " "'); + assert.false(params.has('c'), 'search params object did not have the name "c"'); + assert.true(params.has(' c'), 'search params object has name " c"'); + assert.true(params.has('møø'), 'search params object has name "møø"'); + + params = new URLSearchParams('a=b+c'); + assert.same(params.get('a'), 'b c', 'parse +'); + params = new URLSearchParams('a+b=c'); + assert.same(params.get('a b'), 'c', 'parse +'); + + params = new URLSearchParams('a=b c'); + assert.same(params.get('a'), 'b c', 'parse " "'); + params = new URLSearchParams('a b=c'); + assert.same(params.get('a b'), 'c', 'parse " "'); + + params = new URLSearchParams('a=b%20c'); + assert.same(params.get('a'), 'b c', 'parse %20'); + params = new URLSearchParams('a%20b=c'); + assert.same(params.get('a b'), 'c', 'parse %20'); + + params = new URLSearchParams('a=b\0c'); + assert.same(params.get('a'), 'b\0c', 'parse \\0'); + params = new URLSearchParams('a\0b=c'); + assert.same(params.get('a\0b'), 'c', 'parse \\0'); + + params = new URLSearchParams('a=b%00c'); + assert.same(params.get('a'), 'b\0c', 'parse %00'); + params = new URLSearchParams('a%00b=c'); + assert.same(params.get('a\0b'), 'c', 'parse %00'); + + params = new URLSearchParams('a=b\u2384'); + assert.same(params.get('a'), 'b\u2384', 'parse \u2384'); + params = new URLSearchParams('a\u2384b=c'); + assert.same(params.get('a\u2384b'), 'c', 'parse \u2384'); + + params = new URLSearchParams('a=b%e2%8e%84'); + assert.same(params.get('a'), 'b\u2384', 'parse %e2%8e%84'); + params = new URLSearchParams('a%e2%8e%84b=c'); + assert.same(params.get('a\u2384b'), 'c', 'parse %e2%8e%84'); + + params = new URLSearchParams('a=b\uD83D\uDCA9c'); + assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse \uD83D\uDCA9'); + params = new URLSearchParams('a\uD83D\uDCA9b=c'); + assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse \uD83D\uDCA9'); + + params = new URLSearchParams('a=b%f0%9f%92%a9c'); + assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); + params = new URLSearchParams('a%f0%9f%92%a9b=c'); + assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); + + params = new URLSearchParams(); + params.set('query', '+15555555555'); + assert.same(params.toString(), 'query=%2B15555555555'); + assert.same(params.get('query'), '+15555555555', 'parse encoded +'); + params = new URLSearchParams(params.toString()); + assert.same(params.get('query'), '+15555555555', 'parse encoded +'); + + params = new URLSearchParams('b=%2sf%2a'); + assert.same(params.get('b'), '%2sf*', 'parse encoded %2sf%2a'); + params = new URLSearchParams('b=%%2a'); + assert.same(params.get('b'), '%*', 'parse encoded b=%%2a'); + + params = new URLSearchParams('a=b\u2384'); + assert.same(params.get('a'), 'b\u2384', 'parse \u2384'); + params = new URLSearchParams('a\u2384b=c'); + assert.same(params.get('a\u2384b'), 'c', 'parse \u2384'); + + params = new URLSearchParams('a=b%e2%8e%84'); + assert.same(params.get('a'), 'b\u2384', 'parse b%e2%8e%84'); + params = new URLSearchParams('a%e2%8e%84b=c'); + assert.same(params.get('a\u2384b'), 'c', 'parse b%e2%8e%84'); + + params = new URLSearchParams('a=b\uD83D\uDCA9c'); + assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse \uD83D\uDCA9'); + params = new URLSearchParams('a\uD83D\uDCA9b=c'); + assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse \uD83D\uDCA9'); + + params = new URLSearchParams('a=b%f0%9f%92%a9c'); + assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); + params = new URLSearchParams('a%f0%9f%92%a9b=c'); + assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); + + assert.same(String(new URLSearchParams('%C2')), '%EF%BF%BD='); + assert.same(String(new URLSearchParams('%F0%9F%D0%90')), '%EF%BF%BD%D0%90='); + assert.same(String(new URLSearchParams('%25')), '%25='); + assert.same(String(new URLSearchParams('%4')), '%254='); + + const testData = [ + { input: '?a=%', output: [['a', '%']], name: 'handling %' }, + { input: { '+': '%C2' }, output: [['+', '%C2']], name: 'object with +' }, + { input: { c: 'x', a: '?' }, output: [['c', 'x'], ['a', '?']], name: 'object with two keys' }, + { input: [['c', 'x'], ['a', '?']], output: [['c', 'x'], ['a', '?']], name: 'array with two keys' }, + // eslint-disable-next-line @stylistic/max-len -- ignore + // !!! { input: { 'a\0b': '42', 'c\uD83D': '23', dሴ: 'foo' }, output: [['a\0b', '42'], ['c\uFFFD', '23'], ['d\u1234', 'foo']], name: 'object with NULL, non-ASCII, and surrogate keys' }, + ]; + + for (const { input, output, name } of testData) { + params = new URLSearchParams(input); + let i = 0; + params.forEach((value, key) => { + const [reqKey, reqValue] = output[i++]; + assert.same(key, reqKey, `construct with ${ name }`); + assert.same(value, reqValue, `construct with ${ name }`); + }); + } + + // https://github.com/oven-sh/bun/issues/9253 + if (!BUN) assert.throws(() => { + URLSearchParams(''); + }, 'throws w/o `new`'); + + assert.throws(() => { + new URLSearchParams([[1, 2, 3]]); + }, 'sequence elements must be pairs #1'); + + assert.throws(() => { + new URLSearchParams([createIterable([createIterable([1, 2, 3])])]); + }, 'sequence elements must be pairs #2'); + + assert.throws(() => { + new URLSearchParams([[1]]); + }, 'sequence elements must be pairs #3'); + + assert.throws(() => { + new URLSearchParams([createIterable([createIterable([1])])]); + }, 'sequence elements must be pairs #4'); +}); + +QUnit.test('URLSearchParams#append', assert => { + const { append } = URLSearchParams.prototype; + assert.isFunction(append); + assert.arity(append, 2); + assert.name(append, 'append'); + assert.enumerable(URLSearchParams.prototype, 'append'); + if (!NODE) assert.looksNative(append); + + assert.same(new URLSearchParams().append('a', 'b'), undefined, 'void'); + + let params = new URLSearchParams(); + params.append('a', 'b'); + assert.same(String(params), 'a=b'); + params.append('a', 'b'); + assert.same(String(params), 'a=b&a=b'); + params.append('a', 'c'); + assert.same(String(params), 'a=b&a=b&a=c'); + + params = new URLSearchParams(); + params.append('', ''); + assert.same(String(params), '='); + params.append('', ''); + assert.same(String(params), '=&='); + + params = new URLSearchParams(); + params.append(undefined, undefined); + assert.same(String(params), 'undefined=undefined'); + params.append(undefined, undefined); + assert.same(String(params), 'undefined=undefined&undefined=undefined'); + + params = new URLSearchParams(); + params.append(null, null); + assert.same(String(params), 'null=null'); + params.append(null, null); + assert.same(String(params), 'null=null&null=null'); + + params = new URLSearchParams(); + params.append('first', 1); + params.append('second', 2); + params.append('third', ''); + params.append('first', 10); + assert.true(params.has('first'), 'search params object has name "first"'); + assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); + assert.same(params.get('second'), '2', 'search params object has name "second" with value "2"'); + assert.same(params.get('third'), '', 'search params object has name "third" with value ""'); + params.append('first', 10); + assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); + + assert.throws(() => { + return new URLSearchParams('').append(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#delete', assert => { + const $delete = URLSearchParams.prototype.delete; + assert.isFunction($delete); + assert.arity($delete, 1); + assert.enumerable(URLSearchParams.prototype, 'delete'); + if (!NODE) assert.looksNative($delete); + + let params = new URLSearchParams('a=b&c=d'); + params.delete('a'); + assert.same(String(params), 'c=d'); + + params = new URLSearchParams('a=a&b=b&a=a&c=c'); + params.delete('a'); + assert.same(String(params), 'b=b&c=c'); + + params = new URLSearchParams('a=a&=&b=b&c=c'); + params.delete(''); + assert.same(String(params), 'a=a&b=b&c=c'); + + params = new URLSearchParams('a=a&null=null&b=b'); + params.delete(null); + assert.same(String(params), 'a=a&b=b'); + + params = new URLSearchParams('a=a&undefined=undefined&b=b'); + params.delete(undefined); + assert.same(String(params), 'a=a&b=b'); + + params = new URLSearchParams(); + params.append('first', 1); + assert.true(params.has('first'), 'search params object has name "first"'); + assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); + params.delete('first'); + assert.false(params.has('first'), 'search params object has no "first" name'); + params.append('first', 1); + params.append('first', 10); + params.delete('first'); + assert.false(params.has('first'), 'search params object has no "first" name'); + + params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4'); + params.delete('a', 2); + assert.same(String(params), 'a=1&a=null&a=3&b=4'); + + params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4'); + params.delete('a', null); + assert.same(String(params), 'a=1&a=2&a=3&b=4'); + + params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4'); + params.delete('a', undefined); + assert.same(String(params), 'b=4'); + + if (DESCRIPTORS) { + let url = new URL('http://example.com/?param1¶m2'); + url.searchParams.delete('param1'); + url.searchParams.delete('param2'); + assert.same(String(url), 'http://example.com/', 'url.href does not have ?'); + assert.same(url.search, '', 'url.search does not have ?'); + + url = new URL('http://example.com/?'); + url.searchParams.delete('param1'); + // assert.same(String(url), 'http://example.com/', 'url.href does not have ?'); // Safari bug + assert.same(url.search, '', 'url.search does not have ?'); + } + + assert.throws(() => { + return new URLSearchParams('').delete(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#get', assert => { + const { get } = URLSearchParams.prototype; + assert.isFunction(get); + assert.arity(get, 1); + assert.name(get, 'get'); + assert.enumerable(URLSearchParams.prototype, 'get'); + if (!NODE) assert.looksNative(get); + + let params = new URLSearchParams('a=b&c=d'); + assert.same(params.get('a'), 'b'); + assert.same(params.get('c'), 'd'); + assert.same(params.get('e'), null); + + params = new URLSearchParams('a=b&c=d&a=e'); + assert.same(params.get('a'), 'b'); + + params = new URLSearchParams('=b&c=d'); + assert.same(params.get(''), 'b'); + + params = new URLSearchParams('a=&c=d&a=e'); + assert.same(params.get('a'), ''); + + params = new URLSearchParams('first=second&third&&'); + assert.true(params.has('first'), 'Search params object has name "first"'); + assert.same(params.get('first'), 'second', 'Search params object has name "first" with value "second"'); + assert.same(params.get('third'), '', 'Search params object has name "third" with the empty value.'); + assert.same(params.get('fourth'), null, 'Search params object has no "fourth" name and value.'); + + assert.same(new URLSearchParams('a=b c').get('a'), 'b c'); + assert.same(new URLSearchParams('a b=c').get('a b'), 'c'); + + assert.same(new URLSearchParams('a=b%20c').get('a'), 'b c', 'parse %20'); + assert.same(new URLSearchParams('a%20b=c').get('a b'), 'c', 'parse %20'); + + assert.same(new URLSearchParams('a=b\0c').get('a'), 'b\0c', 'parse \\0'); + assert.same(new URLSearchParams('a\0b=c').get('a\0b'), 'c', 'parse \\0'); + + assert.same(new URLSearchParams('a=b%2Bc').get('a'), 'b+c', 'parse %2B'); + assert.same(new URLSearchParams('a%2Bb=c').get('a+b'), 'c', 'parse %2B'); + + assert.same(new URLSearchParams('a=b%00c').get('a'), 'b\0c', 'parse %00'); + assert.same(new URLSearchParams('a%00b=c').get('a\0b'), 'c', 'parse %00'); + + assert.same(new URLSearchParams('a==').get('a'), '=', 'parse ='); + assert.same(new URLSearchParams('a=b=').get('a'), 'b=', 'parse ='); + assert.same(new URLSearchParams('a=b=c').get('a'), 'b=c', 'parse ='); + assert.same(new URLSearchParams('a==b').get('a'), '=b', 'parse ='); + + assert.same(new URLSearchParams('a=b\u2384').get('a'), 'b\u2384', 'parse \\u2384'); + assert.same(new URLSearchParams('a\u2384b=c').get('a\u2384b'), 'c', 'parse \\u2384'); + + assert.same(new URLSearchParams('a=b%e2%8e%84').get('a'), 'b\u2384', 'parse %e2%8e%84'); + assert.same(new URLSearchParams('a%e2%8e%84b=c').get('a\u2384b'), 'c', 'parse %e2%8e%84'); + + assert.same(new URLSearchParams('a=b\uD83D\uDCA9c').get('a'), 'b\uD83D\uDCA9c', 'parse \\uD83D\\uDCA9'); + assert.same(new URLSearchParams('a\uD83D\uDCA9b=c').get('a\uD83D\uDCA9b'), 'c', 'parse \\uD83D\\uDCA9'); + + assert.same(new URLSearchParams('a=b%f0%9f%92%a9c').get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); + assert.same(new URLSearchParams('a%f0%9f%92%a9b=c').get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); + + assert.same(new URLSearchParams('=').get(''), '', 'parse ='); + + assert.throws(() => { + return new URLSearchParams('').get(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#getAll', assert => { + const { getAll } = URLSearchParams.prototype; + assert.isFunction(getAll); + assert.arity(getAll, 1); + assert.name(getAll, 'getAll'); + assert.enumerable(URLSearchParams.prototype, 'getAll'); + if (!NODE) assert.looksNative(getAll); + + let params = new URLSearchParams('a=b&c=d'); + assert.arrayEqual(params.getAll('a'), ['b']); + assert.arrayEqual(params.getAll('c'), ['d']); + assert.arrayEqual(params.getAll('e'), []); + + params = new URLSearchParams('a=b&c=d&a=e'); + assert.arrayEqual(params.getAll('a'), ['b', 'e']); + + params = new URLSearchParams('=b&c=d'); + assert.arrayEqual(params.getAll(''), ['b']); + + params = new URLSearchParams('a=&c=d&a=e'); + assert.arrayEqual(params.getAll('a'), ['', 'e']); + + params = new URLSearchParams('a=1&a=2&a=3&a'); + assert.arrayEqual(params.getAll('a'), ['1', '2', '3', ''], 'search params object has expected name "a" values'); + params.set('a', 'one'); + assert.arrayEqual(params.getAll('a'), ['one'], 'search params object has expected name "a" values'); + + assert.throws(() => { + return new URLSearchParams('').getAll(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#has', assert => { + const { has } = URLSearchParams.prototype; + assert.isFunction(has); + assert.arity(has, 1); + assert.name(has, 'has'); + assert.enumerable(URLSearchParams.prototype, 'has'); + if (!NODE) assert.looksNative(has); + + let params = new URLSearchParams('a=b&c=d'); + assert.true(params.has('a')); + assert.true(params.has('c')); + assert.false(params.has('e')); + + params = new URLSearchParams('a=b&c=d&a=e'); + assert.true(params.has('a')); + + params = new URLSearchParams('=b&c=d'); + assert.true(params.has('')); + + params = new URLSearchParams('null=a'); + assert.true(params.has(null)); + + params = new URLSearchParams('a=b&c=d&&'); + params.append('first', 1); + params.append('first', 2); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.true(params.has('c'), 'search params object has name "c"'); + assert.true(params.has('first'), 'search params object has name "first"'); + assert.false(params.has('d'), 'search params object has no name "d"'); + params.delete('first'); + assert.false(params.has('first'), 'search params object has no name "first"'); + + params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4'); + assert.true(params.has('a', 2)); + assert.true(params.has('a', null)); + assert.false(params.has('a', 4)); + assert.true(params.has('b', 4)); + assert.false(params.has('b', null)); + assert.true(params.has('b', undefined)); + assert.false(params.has('c', undefined)); + + assert.throws(() => { + return new URLSearchParams('').has(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#set', assert => { + const { set } = URLSearchParams.prototype; + assert.isFunction(set); + assert.arity(set, 2); + assert.name(set, 'set'); + assert.enumerable(URLSearchParams.prototype, 'set'); + if (!NODE) assert.looksNative(set); + + let params = new URLSearchParams('a=b&c=d'); + params.set('a', 'B'); + assert.same(String(params), 'a=B&c=d'); + + params = new URLSearchParams('a=b&c=d&a=e'); + params.set('a', 'B'); + assert.same(String(params), 'a=B&c=d'); + params.set('e', 'f'); + assert.same(String(params), 'a=B&c=d&e=f'); + + params = new URLSearchParams('a=1&a=2&a=3'); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.same(params.get('a'), '1', 'search params object has name "a" with value "1"'); + params.set('first', 4); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.same(params.get('a'), '1', 'search params object has name "a" with value "1"'); + assert.same(String(params), 'a=1&a=2&a=3&first=4'); + params.set('a', 4); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.same(params.get('a'), '4', 'search params object has name "a" with value "4"'); + assert.same(String(params), 'a=4&first=4'); + + assert.throws(() => { + return new URLSearchParams('').set(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#sort', assert => { + const { sort } = URLSearchParams.prototype; + assert.isFunction(sort); + assert.arity(sort, 0); + assert.name(sort, 'sort'); + assert.enumerable(URLSearchParams.prototype, 'sort'); + if (!NODE) assert.looksNative(sort); + + let params = new URLSearchParams('a=1&b=4&a=3&b=2'); + params.sort(); + assert.same(String(params), 'a=1&a=3&b=4&b=2'); + params.delete('a'); + params.append('a', '0'); + params.append('b', '0'); + params.sort(); + assert.same(String(params), 'a=0&b=4&b=2&b=0'); + + const testData = [ + { + input: 'z=b&a=b&z=a&a=a', + output: [['a', 'b'], ['a', 'a'], ['z', 'b'], ['z', 'a']], + }, + { + input: '\uFFFD=x&\uFFFC&\uFFFD=a', + output: [['\uFFFC', ''], ['\uFFFD', 'x'], ['\uFFFD', 'a']], + }, + { + input: 'ffi&🌈', // 🌈 > code point, but < code unit because two code units + output: [['🌈', ''], ['ffi', '']], + }, + { + input: 'é&e\uFFFD&e\u0301', + output: [['e\u0301', ''], ['e\uFFFD', ''], ['é', '']], + }, + { + input: 'z=z&a=a&z=y&a=b&z=x&a=c&z=w&a=d&z=v&a=e&z=u&a=f&z=t&a=g', + output: [ + ['a', 'a'], + ['a', 'b'], + ['a', 'c'], + ['a', 'd'], + ['a', 'e'], + ['a', 'f'], + ['a', 'g'], + ['z', 'z'], + ['z', 'y'], + ['z', 'x'], + ['z', 'w'], + ['z', 'v'], + ['z', 'u'], + ['z', 't'], + ], + }, + { + input: 'bbb&bb&aaa&aa=x&aa=y', + output: [['aa', 'x'], ['aa', 'y'], ['aaa', ''], ['bb', ''], ['bbb', '']], + }, + { + input: 'z=z&=f&=t&=x', + output: [['', 'f'], ['', 't'], ['', 'x'], ['z', 'z']], + }, + { + input: 'a🌈&a💩', + output: [['a🌈', ''], ['a💩', '']], + }, + ]; + + for (const { input, output } of testData) { + let i = 0; + params = new URLSearchParams(input); + params.sort(); + params.forEach((value, key) => { + const [reqKey, reqValue] = output[i++]; + assert.same(key, reqKey); + assert.same(value, reqValue); + }); + + i = 0; + const url = new URL(`?${ input }`, 'https://example/'); + params = url.searchParams; + params.sort(); + params.forEach((value, key) => { + const [reqKey, reqValue] = output[i++]; + assert.same(key, reqKey); + assert.same(value, reqValue); + }); + } + + if (DESCRIPTORS) { + const url = new URL('http://example.com/?'); + url.searchParams.sort(); + assert.same(url.href, 'http://example.com/', 'Sorting non-existent params removes ? from URL'); + assert.same(url.search, '', 'Sorting non-existent params removes ? from URL'); + } +}); + +QUnit.test('URLSearchParams#toString', assert => { + const { toString } = URLSearchParams.prototype; + assert.isFunction(toString); + assert.arity(toString, 0); + assert.name(toString, 'toString'); + if (!NODE) assert.looksNative(toString); + + let params = new URLSearchParams(); + params.append('a', 'b c'); + assert.same(String(params), 'a=b+c'); + params.delete('a'); + params.append('a b', 'c'); + assert.same(String(params), 'a+b=c'); + + params = new URLSearchParams(); + params.append('a', ''); + assert.same(String(params), 'a='); + params.append('a', ''); + assert.same(String(params), 'a=&a='); + params.append('', 'b'); + assert.same(String(params), 'a=&a=&=b'); + params.append('', ''); + assert.same(String(params), 'a=&a=&=b&='); + params.append('', ''); + assert.same(String(params), 'a=&a=&=b&=&='); + + params = new URLSearchParams(); + params.append('', 'b'); + assert.same(String(params), '=b'); + params.append('', 'b'); + assert.same(String(params), '=b&=b'); + + params = new URLSearchParams(); + params.append('', ''); + assert.same(String(params), '='); + params.append('', ''); + assert.same(String(params), '=&='); + + params = new URLSearchParams(); + params.append('a', 'b+c'); + assert.same(String(params), 'a=b%2Bc'); + params.delete('a'); + params.append('a+b', 'c'); + assert.same(String(params), 'a%2Bb=c'); + + params = new URLSearchParams(); + params.append('=', 'a'); + assert.same(String(params), '%3D=a'); + params.append('b', '='); + assert.same(String(params), '%3D=a&b=%3D'); + + params = new URLSearchParams(); + params.append('&', 'a'); + assert.same(String(params), '%26=a'); + params.append('b', '&'); + assert.same(String(params), '%26=a&b=%26'); + + params = new URLSearchParams(); + params.append('a', '\r'); + assert.same(String(params), 'a=%0D'); + + params = new URLSearchParams(); + params.append('a', '\n'); + assert.same(String(params), 'a=%0A'); + + params = new URLSearchParams(); + params.append('a', '\r\n'); + assert.same(String(params), 'a=%0D%0A'); + + params = new URLSearchParams(); + params.append('a', 'b%c'); + assert.same(String(params), 'a=b%25c'); + params.delete('a'); + params.append('a%b', 'c'); + assert.same(String(params), 'a%25b=c'); + + params = new URLSearchParams(); + params.append('a', 'b\0c'); + assert.same(String(params), 'a=b%00c'); + params.delete('a'); + params.append('a\0b', 'c'); + assert.same(String(params), 'a%00b=c'); + + params = new URLSearchParams(); + params.append('a', 'b\uD83D\uDCA9c'); + assert.same(String(params), 'a=b%F0%9F%92%A9c'); + params.delete('a'); + params.append('a\uD83D\uDCA9b', 'c'); + assert.same(String(params), 'a%F0%9F%92%A9b=c'); + + params = new URLSearchParams('a=b&c=d&&e&&'); + assert.same(String(params), 'a=b&c=d&e='); + params = new URLSearchParams('a = b &a=b&c=d%20'); + assert.same(String(params), 'a+=+b+&a=b&c=d+'); + params = new URLSearchParams('a=&a=b'); + assert.same(String(params), 'a=&a=b'); +}); + +QUnit.test('URLSearchParams#forEach', assert => { + const { forEach } = URLSearchParams.prototype; + assert.isFunction(forEach); + assert.arity(forEach, 1); + assert.name(forEach, 'forEach'); + assert.enumerable(URLSearchParams.prototype, 'forEach'); + if (!NODE) assert.looksNative(forEach); + + const expectedValues = { a: '1', b: '2', c: '3' }; + let params = new URLSearchParams('a=1&b=2&c=3'); + let result = ''; + params.forEach((value, key, that) => { + assert.same(params.get(key), expectedValues[key]); + assert.same(value, expectedValues[key]); + assert.same(that, params); + result += key; + }); + assert.same(result, 'abc'); + + new URL('http://a.b/c').searchParams.forEach(() => { + assert.avoid(); + }); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); + params = url.searchParams; + result = ''; + params.forEach((val, key) => { + url.search = 'x=1&y=2&z=3'; + result += key + val; + }); + assert.same(result, 'a1y2z3'); + } + + // fails in Chrome 66- + params = new URLSearchParams('a=1&b=2&c=3'); + result = ''; + params.forEach((value, key) => { + params.delete('b'); + result += key + value; + }); + assert.same(result, 'a1c3'); +}); + +QUnit.test('URLSearchParams#entries', assert => { + const { entries } = URLSearchParams.prototype; + assert.isFunction(entries); + assert.arity(entries, 0); + assert.name(entries, 'entries'); + assert.enumerable(URLSearchParams.prototype, 'entries'); + if (!NODE) assert.looksNative(entries); + + const expectedValues = { a: '1', b: '2', c: '3' }; + let params = new URLSearchParams('a=1&b=2&c=3'); + let iterator = params.entries(); + let result = ''; + let entry; + while (!(entry = iterator.next()).done) { + const [key, value] = entry.value; + assert.same(params.get(key), expectedValues[key]); + assert.same(value, expectedValues[key]); + result += key; + } + assert.same(result, 'abc'); + + assert.true(new URL('http://a.b/c').searchParams.entries().next().done, 'should be finished'); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); + iterator = url.searchParams.entries(); + result = ''; + while (!(entry = iterator.next()).done) { + const [key, value] = entry.value; + url.search = 'x=1&y=2&z=3'; + result += key + value; + } + assert.same(result, 'a1y2z3'); + } + + // fails in Chrome 66- + params = new URLSearchParams('a=1&b=2&c=3'); + iterator = params.entries(); + result = ''; + while (!(entry = iterator.next()).done) { + params.delete('b'); + const [key, value] = entry.value; + result += key + value; + } + assert.same(result, 'a1c3'); + + if (DESCRIPTORS) assert.true(getOwnPropertyDescriptor(getPrototypeOf(new URLSearchParams().entries()), 'next').enumerable, 'enumerable .next'); +}); + +QUnit.test('URLSearchParams#keys', assert => { + const { keys } = URLSearchParams.prototype; + assert.isFunction(keys); + assert.arity(keys, 0); + assert.name(keys, 'keys'); + assert.enumerable(URLSearchParams.prototype, 'keys'); + if (!NODE) assert.looksNative(keys); + + let iterator = new URLSearchParams('a=1&b=2&c=3').keys(); + let result = ''; + let entry; + while (!(entry = iterator.next()).done) { + result += entry.value; + } + assert.same(result, 'abc'); + + assert.true(new URL('http://a.b/c').searchParams.keys().next().done, 'should be finished'); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); + iterator = url.searchParams.keys(); + result = ''; + while (!(entry = iterator.next()).done) { + const key = entry.value; + url.search = 'x=1&y=2&z=3'; + result += key; + } + assert.same(result, 'ayz'); + } + + // fails in Chrome 66- + const params = new URLSearchParams('a=1&b=2&c=3'); + iterator = params.keys(); + result = ''; + while (!(entry = iterator.next()).done) { + params.delete('b'); + const key = entry.value; + result += key; + } + assert.same(result, 'ac'); + + if (DESCRIPTORS) assert.true(getOwnPropertyDescriptor(getPrototypeOf(new URLSearchParams().keys()), 'next').enumerable, 'enumerable .next'); +}); + +QUnit.test('URLSearchParams#values', assert => { + const { values } = URLSearchParams.prototype; + assert.isFunction(values); + assert.arity(values, 0); + assert.name(values, 'values'); + assert.enumerable(URLSearchParams.prototype, 'values'); + if (!NODE) assert.looksNative(values); + + let iterator = new URLSearchParams('a=1&b=2&c=3').values(); + let result = ''; + let entry; + while (!(entry = iterator.next()).done) { + result += entry.value; + } + assert.same(result, '123'); + + assert.true(new URL('http://a.b/c').searchParams.values().next().done, 'should be finished'); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=a&b=b&c=c&d=d'); + iterator = url.searchParams.keys(); + result = ''; + while (!(entry = iterator.next()).done) { + const { value } = entry; + url.search = 'x=x&y=y&z=z'; + result += value; + } + assert.same(result, 'ayz'); + } + + // fails in Chrome 66- + const params = new URLSearchParams('a=1&b=2&c=3'); + iterator = params.values(); + result = ''; + while (!(entry = iterator.next()).done) { + params.delete('b'); + const key = entry.value; + result += key; + } + assert.same(result, '13'); + + if (DESCRIPTORS) assert.true(getOwnPropertyDescriptor(getPrototypeOf(new URLSearchParams().values()), 'next').enumerable, 'enumerable .next'); +}); + +QUnit.test('URLSearchParams#@@iterator', assert => { + const entries = URLSearchParams.prototype[Symbol.iterator]; + assert.isFunction(entries); + assert.arity(entries, 0); + assert.name(entries, 'entries'); + if (!NODE) assert.looksNative(entries); + + assert.same(entries, URLSearchParams.prototype.entries); + + const expectedValues = { a: '1', b: '2', c: '3' }; + let params = new URLSearchParams('a=1&b=2&c=3'); + let iterator = params[Symbol.iterator](); + let result = ''; + let entry; + while (!(entry = iterator.next()).done) { + const [key, value] = entry.value; + assert.same(params.get(key), expectedValues[key]); + assert.same(value, expectedValues[key]); + result += key; + } + assert.same(result, 'abc'); + + assert.true(new URL('http://a.b/c').searchParams[Symbol.iterator]().next().done, 'should be finished'); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); + iterator = url.searchParams[Symbol.iterator](); + result = ''; + while (!(entry = iterator.next()).done) { + const [key, value] = entry.value; + url.search = 'x=1&y=2&z=3'; + result += key + value; + } + assert.same(result, 'a1y2z3'); + } + + // fails in Chrome 66- + params = new URLSearchParams('a=1&b=2&c=3'); + iterator = params[Symbol.iterator](); + result = ''; + while (!(entry = iterator.next()).done) { + params.delete('b'); + const [key, value] = entry.value; + result += key + value; + } + assert.same(result, 'a1c3'); + + if (DESCRIPTORS) assert.true(getOwnPropertyDescriptor(getPrototypeOf(new URLSearchParams()[Symbol.iterator]()), 'next').enumerable, 'enumerable .next'); +}); + +QUnit.test('URLSearchParams#size', assert => { + const params = new URLSearchParams('a=1&b=2&b=3'); + assert.true('size' in params); + assert.same(params.size, 3); + + if (DESCRIPTORS) { + assert.true('size' in URLSearchParams.prototype); + + const { enumerable, configurable, get } = getOwnPropertyDescriptor(URLSearchParams.prototype, 'size'); + + assert.true(enumerable, 'enumerable'); + // https://github.com/oven-sh/bun/issues/9251 + if (!BUN) assert.true(configurable, 'configurable'); + + if (!NODE) assert.looksNative(get); + + assert.throws(() => get.call([])); + } +}); + +QUnit.test('URLSearchParams#@@toStringTag', assert => { + const params = new URLSearchParams('a=b'); + assert.same(({}).toString.call(params), '[object URLSearchParams]'); +}); + +if (typeof Request == 'function') { + QUnit.test('URLSearchParams with Request', assert => { + const async = assert.async(); + new Request('http://zloirock.ru/', { body: new URLSearchParams({ foo: 'baz' }), method: 'POST' }).text().then(text => { + assert.same(text, 'foo=baz'); + async(); + }); + }); +} diff --git a/tests/unit-global/web.url.can-parse.js b/tests/unit-global/web.url.can-parse.js new file mode 100644 index 000000000000..6df703aeadb4 --- /dev/null +++ b/tests/unit-global/web.url.can-parse.js @@ -0,0 +1,27 @@ +import { NODE } from '../helpers/constants.js'; + +QUnit.test('URL.canParse', assert => { + const { canParse } = URL; + + assert.isFunction(canParse); + assert.arity(canParse, 1); + assert.name(canParse, 'canParse'); + if (!NODE) assert.looksNative(canParse); + + assert.false(canParse(undefined), 'undefined'); + assert.false(canParse(undefined, undefined), 'undefined, undefined'); + assert.true(canParse('q:w'), 'q:w'); + assert.true(canParse('q:w', undefined), 'q:w, undefined'); + // assert.false(canParse(undefined, 'q:w'), 'undefined, q:w'); // fails in Chromium on Windows + assert.true(canParse('q:/w'), 'q:/w'); + assert.true(canParse('q:/w', undefined), 'q:/w, undefined'); + assert.true(canParse(undefined, 'q:/w'), 'undefined, q:/w'); + assert.false(canParse('https://login:password@examp:le.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'https://login:password@examp:le.com:8080/?a=1&b=2&a=3&c=4#fragment'); + assert.true(canParse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); + assert.true(canParse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment', undefined), 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment,%20undefined'); + assert.true(canParse('x', 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'x, https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); + + assert.throws(() => canParse(), 'no args'); + assert.throws(() => canParse({ toString() { throw new Error('thrower'); } }), 'conversion thrower #1'); + assert.throws(() => canParse('q:w', { toString() { throw new Error('thrower'); } }), 'conversion thrower #2'); +}); diff --git a/tests/unit-global/web.url.js b/tests/unit-global/web.url.js new file mode 100644 index 000000000000..715b823c7817 --- /dev/null +++ b/tests/unit-global/web.url.js @@ -0,0 +1,674 @@ +/* eslint-disable unicorn/relative-url-style -- required for testing */ +import { DESCRIPTORS, NODE } from '../helpers/constants.js'; +import urlTestData from '../wpt-url-resources/urltestdata.js'; +import settersTestData from '../wpt-url-resources/setters.js'; +import toASCIITestData from '../wpt-url-resources/toascii.js'; + +const { hasOwnProperty } = Object.prototype; + +QUnit.test('URL constructor', assert => { + assert.isFunction(URL); + if (!NODE) assert.arity(URL, 1); + assert.name(URL, 'URL'); + if (!NODE) assert.looksNative(URL); + + assert.same(String(new URL('http://www.domain.com/a/b')), 'http://www.domain.com/a/b'); + assert.same(String(new URL('/c/d', 'http://www.domain.com/a/b')), 'http://www.domain.com/c/d'); + assert.same(String(new URL('b/c', 'http://www.domain.com/a/b')), 'http://www.domain.com/a/b/c'); + assert.same(String(new URL('b/c', new URL('http://www.domain.com/a/b'))), 'http://www.domain.com/a/b/c'); + assert.same(String(new URL({ toString: () => 'https://example.org/' })), 'https://example.org/'); + + assert.same(String(new URL('nonspecial://example.com/')), 'nonspecial://example.com/'); + + assert.same(String(new URL('https://xn--g6w251d/')), 'https://xn--g6w251d/', 'unicode parsing'); + assert.same(String(new URL('https://xn--xx-flcmn5bht.xn--e1aybc/')), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + assert.same(String(new URL('https://xn--xx-flcmn5bht.xn--e1aybc/')), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + assert.same(String(new URL('http://example.com/', 'https://example.org/')), 'http://example.com/'); + assert.same(String(new URL('https://example.com/', 'https://example.org/')), 'https://example.com/'); + assert.same(String(new URL('nonspecial://Example.com/', 'https://example.org/')), 'nonspecial://Example.com/'); + assert.same(String(new URL('http:Example.com/', 'https://example.org/')), 'http://example.com/'); + assert.same(String(new URL('https:Example.com/', 'https://example.org/')), 'https://example.org/Example.com/'); + assert.same(String(new URL('nonspecial:Example.com/', 'https://example.org/')), 'nonspecial:Example.com/'); + + assert.same(String(new URL('http://192.168.0.240/')), 'http://192.168.0.240/'); + assert.same(String(new URL('http://[20:0:0:1::ff]/')), 'http://[20:0:0:1::ff]/'); + // assert.same(String(new URL('http://257.168.0xF0')), 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // TypeError in Chrome and Safari + assert.same(String(new URL('http://0300.168.0xg0/')), 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); + + assert.same(String(new URL('file:///var/log/system.log')), 'file:///var/log/system.log', 'file scheme'); + // assert.same(String(new URL('file://nnsc.nsf.net/bar/baz')), 'file://nnsc.nsf.net/bar/baz', 'file scheme'); // 'file:///bar/baz' in FF + // assert.same(String(new URL('file://localhost/bar/baz')), 'file:///bar/baz', 'file scheme'); // 'file://localhost/bar/baz' in Chrome + + assert.throws(() => new URL(), 'TypeError: Failed to construct URL: 1 argument required, but only 0 present.'); + assert.throws(() => new URL(''), 'TypeError: Failed to construct URL: Invalid URL'); + // Node 19.7 + // https://github.com/nodejs/node/issues/46755 + // assert.throws(() => new URL('', 'about:blank'), 'TypeError: Failed to construct URL: Invalid URL'); + assert.throws(() => new URL('abc'), 'TypeError: Failed to construct URL: Invalid URL'); + assert.throws(() => new URL('//abc'), 'TypeError: Failed to construct URL: Invalid URL'); + assert.throws(() => new URL('http://www.domain.com/', 'abc'), 'TypeError: Failed to construct URL: Invalid base URL'); + assert.throws(() => new URL('http://www.domain.com/', null), 'TypeError: Failed to construct URL: Invalid base URL'); + assert.throws(() => new URL('//abc', null), 'TypeError: Failed to construct URL: Invalid base URL'); + assert.throws(() => new URL('http://[20:0:0:1:0:0:0:ff'), 'incorrect IPv6'); + assert.throws(() => new URL('http://[20:0:0:1:0:0:0:fg]'), 'incorrect IPv6'); + // assert.throws(() => new URL('http://a%b'), 'forbidden host code point'); // no error in FF + assert.throws(() => new URL('1http://zloirock.ru'), 'incorrect scheme'); +}); + +QUnit.test('URL#href', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'href')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'href'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.href, 'http://zloirock.ru/'); + + if (DESCRIPTORS) { + url.searchParams.append('foo', 'bar'); + assert.same(url.href, 'http://zloirock.ru/?foo=bar'); + + url = new URL('http://zloirock.ru/foo'); + url.href = 'https://xn--g6w251d/'; + assert.same(url.href, 'https://xn--g6w251d/', 'unicode parsing'); + assert.same(String(url), 'https://xn--g6w251d/', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.href = 'https://xn--xx-flcmn5bht.xn--e1aybc/'; + assert.same(url.href, 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + assert.same(String(url), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.href = 'https://xn--xx-flcmn5bht.xn--e1aybc/'; + assert.same(url.href, 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + assert.same(String(url), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + + url = new URL('http://zloirock.ru/'); + url.href = 'http://192.168.0.240/'; + assert.same(url.href, 'http://192.168.0.240/'); + assert.same(String(url), 'http://192.168.0.240/'); + + url = new URL('http://zloirock.ru/'); + url.href = 'http://[20:0:0:1::ff]/'; + assert.same(url.href, 'http://[20:0:0:1::ff]/'); + assert.same(String(url), 'http://[20:0:0:1::ff]/'); + + // url = new URL('http://zloirock.ru/'); + // url.href = 'http://257.168.0xF0'; // TypeError and Safari + // assert.same(url.href, 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // `F` instead of `f` in Chrome + // assert.same(String(url), 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // `F` instead of `f` in Chrome + + url = new URL('http://zloirock.ru/'); + url.href = 'http://0300.168.0xg0/'; + assert.same(url.href, 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); + assert.same(String(url), 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); + + url = new URL('http://192.168.0.240/'); + url.href = 'file:///var/log/system.log'; + assert.same(url.href, 'file:///var/log/system.log', 'file -> ip'); + assert.same(String(url), 'file:///var/log/system.log', 'file -> ip'); + + url = new URL('file:///var/log/system.log'); + url.href = 'http://192.168.0.240/'; + // Node 19.7 + // https://github.com/nodejs/node/issues/46755 + // assert.same(url.href, 'http://192.168.0.240/', 'file -> http'); + // assert.same(String(url), 'http://192.168.0.240/', 'file -> http'); + + // assert.throws(() => new URL('http://zloirock.ru/').href = undefined, 'incorrect URL'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = '', 'incorrect URL'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = 'abc', 'incorrect URL'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = '//abc', 'incorrect URL'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://[20:0:0:1:0:0:0:ff', 'incorrect IPv6'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://[20:0:0:1:0:0:0:fg]', 'incorrect IPv6'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://a%b', 'forbidden host code point'); // no error in Chrome and FF + // assert.throws(() => new URL('http://zloirock.ru/').href = '1http://zloirock.ru', 'incorrect scheme'); // no error in Chrome + } +}); + +QUnit.test('URL#origin', assert => { + const url = new URL('http://es6.zloirock.ru/tests.html'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'origin')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'origin'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + } + + assert.same(url.origin, 'http://es6.zloirock.ru/'); + + assert.same(new URL('https://xn--g6w251d/tests').origin, 'https://xn--g6w251d/'); +}); + +QUnit.test('URL#protocol', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'protocol')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'protocol'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.protocol, 'http:'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.protocol = 'https'; + assert.same(url.protocol, 'https:'); + assert.same(String(url), 'https://zloirock.ru/'); + + // https://nodejs.org/api/url.html#url_special_schemes + // url = new URL('http://zloirock.ru/'); + // url.protocol = 'fish'; + // assert.same(url.protocol, 'http:'); + // assert.same(url.href, 'http://zloirock.ru/'); + // assert.same(String(url), 'http://zloirock.ru/'); + + url = new URL('http://zloirock.ru/'); + url.protocol = '1http'; + assert.same(url.protocol, 'http:'); + assert.same(url.href, 'http://zloirock.ru/', 'incorrect scheme'); + assert.same(String(url), 'http://zloirock.ru/', 'incorrect scheme'); + } +}); + +QUnit.test('URL#username', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'username')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'username'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.username, ''); + + url = new URL('http://username@zloirock.ru/'); + assert.same(url.username, 'username'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.username = 'username'; + assert.same(url.username, 'username'); + assert.same(String(url), 'http://username@zloirock.ru/'); + } +}); + +QUnit.test('URL#password', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'password')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'password'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.password, ''); + + url = new URL('http://username:password@zloirock.ru/'); + assert.same(url.password, 'password'); + + // url = new URL('http://:password@zloirock.ru/'); // TypeError in FF + // assert.same(url.password, 'password'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.username = 'username'; + url.password = 'password'; + assert.same(url.password, 'password'); + assert.same(String(url), 'http://username:password@zloirock.ru/'); + + // url = new URL('http://zloirock.ru/'); + // url.password = 'password'; + // assert.same(url.password, 'password'); // '' in FF + // assert.same(String(url), 'http://:password@zloirock.ru/'); // 'http://zloirock.ru/' in FF + } +}); + +QUnit.test('URL#host', assert => { + let url = new URL('http://zloirock.ru:81/path'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'host')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'host'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.host, 'zloirock.ru:81'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru:81/path'); + url.host = 'example.com:82'; + assert.same(url.host, 'example.com:82'); + assert.same(String(url), 'http://example.com:82/path'); + + // url = new URL('http://zloirock.ru:81/path'); + // url.host = 'other?domain.com'; + // assert.same(String(url), 'http://other:81/path'); // 'http://other/?domain.com/path' in Safari + + url = new URL('https://www.mydomain.com:8080/path/'); + url.host = 'www.otherdomain.com:80'; + assert.same(url.href, 'https://www.otherdomain.com:80/path/', 'set default port for another protocol'); + + // url = new URL('https://www.mydomain.com:8080/path/'); + // url.host = 'www.otherdomain.com:443'; + // assert.same(url.href, 'https://www.otherdomain.com/path/', 'set default port'); + + url = new URL('http://zloirock.ru/foo'); + url.host = '測試'; + assert.same(url.host, 'xn--g6w251d', 'unicode parsing'); + assert.same(String(url), 'http://xn--g6w251d/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.host = 'xxпривет.тест'; + assert.same(url.host, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); + assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.host = 'xxПРИВЕТ.тест'; + assert.same(url.host, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); + assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.host = '0300.168.0xF0'; + assert.same(url.host, '192.168.0.240'); + assert.same(String(url), 'http://192.168.0.240/foo'); + + // url = new URL('http://zloirock.ru/foo'); + // url.host = '[20:0:0:1:0:0:0:ff]'; + // assert.same(url.host, '[20:0:0:1::ff]'); // ':0' in Chrome, 'zloirock.ru' in Safari + // assert.same(String(url), 'http://[20:0:0:1::ff]/foo'); // 'http://[20:0/foo' in Chrome, 'http://zloirock.ru/foo' in Safari + + // url = new URL('file:///var/log/system.log'); + // url.host = 'nnsc.nsf.net'; // does not work in FF + // assert.same(url.hostname, 'nnsc.nsf.net', 'file'); + // assert.same(String(url), 'file://nnsc.nsf.net/var/log/system.log', 'file'); + + // url = new URL('http://zloirock.ru/'); + // url.host = '[20:0:0:1:0:0:0:ff'; + // assert.same(url.host, 'zloirock.ru', 'incorrect IPv6'); // ':0' in Chrome + // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0/' in Chrome + + // url = new URL('http://zloirock.ru/'); + // url.host = '[20:0:0:1:0:0:0:fg]'; + // assert.same(url.host, 'zloirock.ru', 'incorrect IPv6'); // ':0' in Chrome + // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0/' in Chrome + + // url = new URL('http://zloirock.ru/'); + // url.host = 'a%b'; + // assert.same(url.host, 'zloirock.ru', 'forbidden host code point'); // '' in Chrome, 'a%b' in FF + // assert.same(String(url), 'http://zloirock.ru/', 'forbidden host code point'); // 'http://a%25b/' in Chrome, 'http://a%b/' in FF + } +}); + +QUnit.test('URL#hostname', assert => { + let url = new URL('http://zloirock.ru:81/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'hostname')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'hostname'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.hostname, 'zloirock.ru'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru:81/'); + url.hostname = 'example.com'; + assert.same(url.hostname, 'example.com'); + assert.same(String(url), 'http://example.com:81/'); + + // url = new URL('http://zloirock.ru:81/'); + // url.hostname = 'example.com:82'; + // assert.same(url.hostname, 'example.com'); // '' in Chrome + // assert.same(String(url), 'http://example.com:81/'); // 'http://example.com:82:81/' in Chrome + + url = new URL('http://zloirock.ru/foo'); + url.hostname = '測試'; + assert.same(url.hostname, 'xn--g6w251d', 'unicode parsing'); + assert.same(String(url), 'http://xn--g6w251d/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.hostname = 'xxпривет.тест'; + assert.same(url.hostname, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); + assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.hostname = 'xxПРИВЕТ.тест'; + assert.same(url.hostname, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); + assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.hostname = '0300.168.0xF0'; + assert.same(url.hostname, '192.168.0.240'); + assert.same(String(url), 'http://192.168.0.240/foo'); + + // url = new URL('http://zloirock.ru/foo'); + // url.hostname = '[20:0:0:1:0:0:0:ff]'; + // assert.same(url.hostname, '[20:0:0:1::ff]'); // 'zloirock.ru' in Safari + // assert.same(String(url), 'http://[20:0:0:1::ff]/foo'); // 'http://zloirock.ru/foo' in Safari + + // url = new URL('file:///var/log/system.log'); + // url.hostname = 'nnsc.nsf.net'; // does not work in FF + // assert.same(url.hostname, 'nnsc.nsf.net', 'file'); + // assert.same(String(url), 'file://nnsc.nsf.net/var/log/system.log', 'file'); + + // url = new URL('http://zloirock.ru/'); + // url.hostname = '[20:0:0:1:0:0:0:ff'; + // assert.same(url.hostname, 'zloirock.ru', 'incorrect IPv6'); // '' in Chrome + // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0:0:1:0:0:0:ff' in Chrome + + // url = new URL('http://zloirock.ru/'); + // url.hostname = '[20:0:0:1:0:0:0:fg]'; + // assert.same(url.hostname, 'zloirock.ru', 'incorrect IPv6'); // '' in Chrome + // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0:0:1:0:0:0:ff/' in Chrome + + // url = new URL('http://zloirock.ru/'); + // url.hostname = 'a%b'; + // assert.same(url.hostname, 'zloirock.ru', 'forbidden host code point'); // '' in Chrome, 'a%b' in FF + // assert.same(String(url), 'http://zloirock.ru/', 'forbidden host code point'); // 'http://a%25b/' in Chrome, 'http://a%b/' in FF + } +}); + +QUnit.test('URL#port', assert => { + let url = new URL('http://zloirock.ru:1337/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'port')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'port'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.port, '1337'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.port = 80; + assert.same(url.port, ''); + assert.same(String(url), 'http://zloirock.ru/'); + url.port = 1337; + assert.same(url.port, '1337'); + assert.same(String(url), 'http://zloirock.ru:1337/'); + // url.port = 'abcd'; + // assert.same(url.port, '1337'); // '0' in Chrome + // assert.same(String(url), 'http://zloirock.ru:1337/'); // 'http://zloirock.ru:0/' in Chrome + // url.port = '5678abcd'; + // assert.same(url.port, '5678'); // '1337' in FF + // assert.same(String(url), 'http://zloirock.ru:5678/'); // 'http://zloirock.ru:1337/"' in FF + url.port = 1234.5678; + assert.same(url.port, '1234'); + assert.same(String(url), 'http://zloirock.ru:1234/'); + // url.port = 1e10; + // assert.same(url.port, '1234'); // '0' in Chrome + // assert.same(String(url), 'http://zloirock.ru:1234/'); // 'http://zloirock.ru:0/' in Chrome + } +}); + +QUnit.test('URL#pathname', assert => { + let url = new URL('http://zloirock.ru/foo/bar'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'pathname')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'pathname'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.pathname, '/foo/bar'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.pathname = 'bar/baz'; + assert.same(url.pathname, '/bar/baz'); + assert.same(String(url), 'http://zloirock.ru/bar/baz'); + } +}); + +QUnit.test('URL#search', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'search')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'search'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.search, ''); + + url = new URL('http://zloirock.ru/?foo=bar'); + assert.same(url.search, '?foo=bar'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/?'); + assert.same(url.search, ''); + assert.same(String(url), 'http://zloirock.ru/?'); + url.search = 'foo=bar'; + assert.same(url.search, '?foo=bar'); + assert.same(String(url), 'http://zloirock.ru/?foo=bar'); + url.search = '?bar=baz'; + assert.same(url.search, '?bar=baz'); + assert.same(String(url), 'http://zloirock.ru/?bar=baz'); + url.search = ''; + assert.same(url.search, ''); + assert.same(String(url), 'http://zloirock.ru/'); + } +}); + +QUnit.test('URL#searchParams', assert => { + let url = new URL('http://zloirock.ru/?foo=bar&bar=baz'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'searchParams')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'searchParams'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + } + + assert.true(url.searchParams instanceof URLSearchParams); + assert.same(url.searchParams.get('foo'), 'bar'); + assert.same(url.searchParams.get('bar'), 'baz'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.searchParams.append('foo', 'bar'); + assert.same(String(url), 'http://zloirock.ru/?foo=bar'); + + url = new URL('http://zloirock.ru/'); + url.search = 'foo=bar'; + assert.same(url.searchParams.get('foo'), 'bar'); + + url = new URL('http://zloirock.ru/?foo=bar&bar=baz'); + url.search = ''; + assert.false(url.searchParams.has('foo')); + } +}); + +QUnit.test('URL#hash', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'hash')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'hash'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.hash, ''); + + url = new URL('http://zloirock.ru/#foo'); + assert.same(url.hash, '#foo'); + + url = new URL('http://zloirock.ru/#'); + assert.same(url.hash, ''); + assert.same(String(url), 'http://zloirock.ru/#'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/#'); + url.hash = 'foo'; + assert.same(url.hash, '#foo'); + assert.same(String(url), 'http://zloirock.ru/#foo'); + url.hash = ''; + assert.same(url.hash, ''); + assert.same(String(url), 'http://zloirock.ru/'); + // url.hash = '#'; + // assert.same(url.hash, ''); + // assert.same(String(url), 'http://zloirock.ru/'); // 'http://zloirock.ru/#' in FF + url.hash = '#foo'; + assert.same(url.hash, '#foo'); + assert.same(String(url), 'http://zloirock.ru/#foo'); + url.hash = '#foo#bar'; + assert.same(url.hash, '#foo#bar'); + assert.same(String(url), 'http://zloirock.ru/#foo#bar'); + + url = new URL('http://zloirock.ru/'); + url.hash = 'абa'; + assert.same(url.hash, '#%D0%B0%D0%B1a'); + + // url = new URL('http://zloirock.ru/'); + // url.hash = '\udc01\ud802a'; + // assert.same(url.hash, '#%EF%BF%BD%EF%BF%BDa', 'unmatched surrogates'); + } +}); + +QUnit.test('URL#toJSON', assert => { + const { toJSON } = URL.prototype; + assert.isFunction(toJSON); + assert.arity(toJSON, 0); + assert.name(toJSON, 'toJSON'); + assert.enumerable(URL.prototype, 'toJSON'); + if (!NODE) assert.looksNative(toJSON); + + const url = new URL('http://zloirock.ru/'); + assert.same(url.toJSON(), 'http://zloirock.ru/'); + + if (DESCRIPTORS) { + url.searchParams.append('foo', 'bar'); + assert.same(url.toJSON(), 'http://zloirock.ru/?foo=bar'); + } +}); + +QUnit.test('URL#toString', assert => { + const { toString } = URL.prototype; + assert.isFunction(toString); + assert.arity(toString, 0); + assert.name(toString, 'toString'); + assert.enumerable(URL.prototype, 'toString'); + if (!NODE) assert.looksNative(toString); + + const url = new URL('http://zloirock.ru/'); + assert.same(url.toString(), 'http://zloirock.ru/'); + + if (DESCRIPTORS) { + url.searchParams.append('foo', 'bar'); + assert.same(url.toString(), 'http://zloirock.ru/?foo=bar'); + } +}); + +QUnit.test('URL#@@toStringTag', assert => { + const url = new URL('http://zloirock.ru/'); + assert.same(({}).toString.call(url), '[object URL]'); +}); + +QUnit.test('URL.sham', assert => { + assert.same(URL.sham, DESCRIPTORS ? undefined : true); +}); + +// `core-js` URL implementation pass all (exclude some encoding-related) tests +// from the next 3 test cases, but URLs from all of popular browsers fail a serious part of tests. +// Replacing all of them does not looks like a good idea, so next test cases disabled by default. + +// see https://github.com/web-platform-tests/wpt/blob/master/url +QUnit.skip('WPT URL constructor tests', assert => { + for (const expected of urlTestData) { + if (typeof expected == 'string') continue; + const name = `Parsing: <${ expected.input }> against <${ expected.base }>`; + if (expected.failure) { + assert.throws(() => new URL(expected.input, expected.base || 'about:blank'), name); + } else { + const url = new URL(expected.input, expected.base || 'about:blank'); + assert.same(url.href, expected.href, `${ name }: href`); + assert.same(url.protocol, expected.protocol, `${ name }: protocol`); + assert.same(url.username, expected.username, `${ name }: username`); + assert.same(url.password, expected.password, `${ name }: password`); + assert.same(url.host, expected.host, `${ name }: host`); + assert.same(url.hostname, expected.hostname, `${ name }: hostname`); + assert.same(url.port, expected.port, `${ name }: port`); + assert.same(url.pathname, expected.pathname, `${ name }: pathname`); + assert.same(url.search, expected.search, `${ name }: search`); + if ('searchParams' in expected) { + assert.same(url.searchParams.toString(), expected.searchParams, `${ name }: searchParams`); + } + assert.same(url.hash, expected.hash, `${ name }: hash`); + if ('origin' in expected) { + assert.same(url.origin, expected.origin, `${ name }: origin`); + } + } + } +}); + +// see https://github.com/web-platform-tests/wpt/blob/master/url +if (DESCRIPTORS) QUnit.skip('WPT URL setters tests', assert => { + for (const setter in settersTestData) { + const testCases = settersTestData[setter]; + for (const { href, newValue, comment, expected } of testCases) { + let name = `Setting <${ href }>.${ setter } = '${ newValue }'.`; + if (comment) name += ` ${ comment }`; + + const url = new URL(href); + url[setter] = newValue; + for (const attribute in expected) { + assert.same(url[attribute], expected[attribute], name); + } + } + } +}); + +// see https://github.com/web-platform-tests/wpt/blob/master/url +QUnit.skip('WPT conversion to ASCII tests', assert => { + for (const { comment, input, output } of toASCIITestData) { + let name = `Parsing: <${ input }>`; + if (comment) name += ` ${ comment }`; + if (output === null) { + assert.throws(() => new URL(`https://${ input }/x`), name); + } else { + const url = new URL(`https://${ input }/x`); + assert.same(url.host, output, name); + assert.same(url.hostname, output, name); + assert.same(url.pathname, '/x', name); + assert.same(url.href, `https://${ output }/x`, name); + } + } +}); diff --git a/tests/unit-global/web.url.parse.js b/tests/unit-global/web.url.parse.js new file mode 100644 index 000000000000..5f196f647ea6 --- /dev/null +++ b/tests/unit-global/web.url.parse.js @@ -0,0 +1,27 @@ +import { NODE } from '../helpers/constants.js'; + +QUnit.test('URL.parse', assert => { + const { parse } = URL; + + assert.isFunction(parse); + assert.arity(parse, 1); + assert.name(parse, 'parse'); + if (!NODE) assert.looksNative(parse); + + assert.same(parse(undefined), null, 'undefined'); + assert.same(parse(undefined, undefined), null, 'undefined, undefined'); + assert.deepEqual(parse('q:w'), new URL('q:w'), 'q:w'); + assert.deepEqual(parse('q:w', undefined), new URL('q:w'), 'q:w, undefined'); + assert.deepEqual(parse('q:/w'), new URL('q:/w'), 'q:/w'); + assert.deepEqual(parse('q:/w', undefined), new URL('q:/w', undefined), 'q:/w, undefined'); + assert.deepEqual(parse(undefined, 'q:/w'), new URL(undefined, 'q:/w'), 'undefined, q:/w'); + assert.same(parse('https://login:password@examp:le.com:8080/?a=1&b=2&a=3&c=4#fragment'), null, 'https://login:password@examp:le.com:8080/?a=1&b=2&a=3&c=4#fragment'); + assert.deepEqual(parse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), new URL('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); + assert.deepEqual(parse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment', undefined), new URL('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment', undefined), 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment,%20undefined'); + // eslint-disable-next-line unicorn/relative-url-style -- required for testing + assert.deepEqual(parse('x', 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), new URL('x', 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'x, https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); + + assert.throws(() => parse(), 'no args'); + assert.throws(() => parse({ toString() { throw new Error('thrower'); } }), 'conversion thrower #1'); + assert.throws(() => parse('q:w', { toString() { throw new Error('thrower'); } }), 'conversion thrower #2'); +}); diff --git a/tests/unit-karma/karma.conf.js b/tests/unit-karma/karma.conf.js new file mode 100644 index 000000000000..945410af3ece --- /dev/null +++ b/tests/unit-karma/karma.conf.js @@ -0,0 +1,42 @@ +'use strict'; +const { chromium, firefox, webkit } = require('playwright'); +const { sync: which } = require('which'); + +Object.assign(process.env, { + CHROMIUM_BIN: chromium.executablePath(), + FIREFOX_BIN: firefox.executablePath(), + WEBKIT_BIN: webkit.executablePath(), +}); + +const customLaunchers = { + IE_NFM: { + base: 'IE', + // prevents crash on launch of multiple IE11 instances + flags: ['-noframemerging'], + }, +}; + +const browsers = [ + 'ChromiumHeadless', + 'FirefoxHeadless', + 'WebKitHeadless', + 'PhantomJS', +]; + +if (process.env.CI || which('iexplore.exe', { nothrow: true })) { + browsers.push('IE_NFM'); +} + +module.exports = config => config.set({ + plugins: [ + 'karma-*', + '@onslip/karma-playwright-launcher', + ], + files: process.argv.find(it => it.startsWith('-f=')).slice(3).split(','), + frameworks: ['qunit'], + basePath: '.', + customLaunchers, + browsers, + logLevel: config.LOG_ERROR, + singleRun: true, +}); diff --git a/tests/unit-karma/package-lock.json b/tests/unit-karma/package-lock.json new file mode 100644 index 000000000000..e9f1485da21d --- /dev/null +++ b/tests/unit-karma/package-lock.json @@ -0,0 +1,2991 @@ +{ + "name": "tests/unit-karma", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests/unit-karma", + "devDependencies": { + "@onslip/karma-playwright-launcher": "^0.3.0", + "@playwright/browser-chromium": "^1.57.0", + "@playwright/browser-firefox": "^1.57.0", + "@playwright/browser-webkit": "^1.57.0", + "karma": "^6.4.4", + "karma-ie-launcher": "^1.0.0", + "karma-phantomjs-launcher": "~1.0.4", + "karma-qunit": "^4.2.1", + "phantomjs-prebuilt": "~2.1.16", + "playwright": "^1.57.0", + "qunit": "^2.24.3", + "which": "^6.0.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@onslip/karma-playwright-launcher": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@onslip/karma-playwright-launcher/-/karma-playwright-launcher-0.3.0.tgz", + "integrity": "sha512-myCCa/e7IhHcjHvyHbCe9U+IsYP9+pFuN5aEL2xvpsktkeX6fvzJ8aMCXQGnF5dz3VrGUexQ2UgeRNOQIO5hsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "playwright": "^1.0.0" + } + }, + "node_modules/@playwright/browser-chromium": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/@playwright/browser-chromium/-/browser-chromium-1.57.0.tgz", + "integrity": "sha512-pUg+2p6HwewLp8KCD9G6VYaS2iewdkNkyqMcSIxXBXOlp1ojTxLF6/bwyR4ixLMy6tyv75jhE8PzzMZiX5KzwQ==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.57.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@playwright/browser-firefox": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/@playwright/browser-firefox/-/browser-firefox-1.57.0.tgz", + "integrity": "sha512-Kb9CUiCDqm/1yQVyzcQfXvg8EqVW9YXwJJ/7nvr1ekeV2XX1n5FHrzm1rPiZV13Rk1mBeuWrBNook+HmwCTLpw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.57.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@playwright/browser-webkit": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/@playwright/browser-webkit/-/browser-webkit-1.57.0.tgz", + "integrity": "sha512-BiSFhr2hgt3WTAuzAZuk79Qy9KeLDjrCL2PzmKrxd+DG0kgSzwCrkl6SNFe9cMceTB8ExrP4wgFIcSZktsJnaw==", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.57.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/node": { + "version": "25.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.3.tgz", + "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/asn1": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", + "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.13.2.tgz", + "integrity": "sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/body-parser": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", + "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.14.0", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/engine.io": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", + "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/engine.io/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", + "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "punycode": "^1.4.1", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasha": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-2.2.0.tgz", + "integrity": "sha512-jZ38TU/EBiGKrmyTNNZgnvCZHNowiRI4+w/I9noMlekHTZH3KyGgvJLmhSgykeAQ9j2SYPDosM0Bg3wHfzibAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^1.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", + "dev": true, + "license": "MIT" + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true, + "license": "(AFL-2.1 OR BSD-3-Clause)" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "dev": true, + "license": "ISC" + }, + "node_modules/jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-ie-launcher": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/karma-ie-launcher/-/karma-ie-launcher-1.0.0.tgz", + "integrity": "sha512-ts71ke8pHvw6qdRtq0+7VY3ANLoZuUNNkA8abRaWV13QRPNm7TtSOqyszjHUtuwOWKcsSz4tbUtrNICrQC+SXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.6.1" + }, + "peerDependencies": { + "karma": ">=0.9" + } + }, + "node_modules/karma-phantomjs-launcher": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/karma-phantomjs-launcher/-/karma-phantomjs-launcher-1.0.4.tgz", + "integrity": "sha512-tf4P3plsE7wb5Pqh8GJ6RnElxfI/UM4MtVnjbSIZFpdFJlKnjRzfIx8MLCcSYJBwZ1+qSKFz4uBe3XNoq2t3KA==", + "deprecated": "PhantomJS development have stopped, use puppeteer or similar", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.0.1", + "phantomjs-prebuilt": "^2.1.7" + }, + "peerDependencies": { + "karma": ">=0.9" + } + }, + "node_modules/karma-qunit": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/karma-qunit/-/karma-qunit-4.2.1.tgz", + "integrity": "sha512-bd4TXH8L7i3hYelRo/5OTlyRiMrSyUpgI94pzkASaD/qjlc1j8liuZeroRS4aA5B7AmnCYQILEsKcSfuaQgcPA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "karma": "^4.0.0 || ^5.0.0 || ^6.0.0", + "qunit": ">=2.1.1" + } + }, + "node_modules/kew": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "integrity": "sha512-IG6nm0+QtAMdXt9KvbgbGdvY50RSrw+U4sGZg+KlrSKPJEwVE5JVoI3d7RWfSMdBQneRheeAOj3lIjX5VL/9RQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.9" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/log4js/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/log4js/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/node-watch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "dev": true, + "license": "MIT" + }, + "node_modules/phantomjs-prebuilt": { + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz", + "integrity": "sha512-PIiRzBhW85xco2fuj41FmsyuYHKjKuXWmhjy3A/Y+CMpN/63TV+s9uzfVhsUwFe0G77xWtHBG8xmXf5BqEUEuQ==", + "deprecated": "this package is now deprecated", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "es6-promise": "^4.0.3", + "extract-zip": "^1.6.5", + "fs-extra": "^1.0.0", + "hasha": "^2.2.0", + "kew": "^0.7.0", + "progress": "^1.1.8", + "request": "^2.81.0", + "request-progress": "^2.0.1", + "which": "^1.2.10" + }, + "bin": { + "phantomjs": "bin/phantomjs" + } + }, + "node_modules/phantomjs-prebuilt/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/phantomjs-prebuilt/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/playwright": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.57.0.tgz", + "integrity": "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.57.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.57.0.tgz", + "integrity": "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/progress": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "integrity": "sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/psl": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", + "integrity": "sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "funding": { + "url": "https://github.com/sponsors/lupomontero" + } + }, + "node_modules/psl/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/qunit": { + "version": "2.24.3", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.24.3.tgz", + "integrity": "sha512-JTHwSfHf2Cw8TqusZo2tT4F9d+XA/pp/veoxUDiPNHtB1Wc1VPctiHHIv6HA3vrXNOBu9LSzFM7YU2OV9Gz4vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "7.2.0", + "node-watch": "0.7.3", + "tiny-glob": "0.2.9" + }, + "bin": { + "qunit": "bin/qunit.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-2.0.1.tgz", + "integrity": "sha512-dxdraeZVUNEn9AvLrxkgB2k6buTlym71dJk1fk4v8j3Ou3RKNm07BcgbHdj2lLgYGfqX71F+awb1MR+tWPFJzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-adapter/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sshpk": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", + "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/streamroller/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/streamroller/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/streamroller/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/streamroller/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/throttleit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.1.tgz", + "integrity": "sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + }, + "node_modules/tmp": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/tough-cookie/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==", + "dev": true, + "license": "Unlicense" + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ua-parser-js": { + "version": "0.7.41", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.41.tgz", + "integrity": "sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/uri-js/node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "license": "MIT", + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/which": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", + "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } +} diff --git a/tests/unit-karma/package.json b/tests/unit-karma/package.json new file mode 100644 index 000000000000..1363978e421b --- /dev/null +++ b/tests/unit-karma/package.json @@ -0,0 +1,17 @@ +{ + "name": "tests/unit-karma", + "devDependencies": { + "@onslip/karma-playwright-launcher": "^0.3.0", + "@playwright/browser-chromium": "^1.57.0", + "@playwright/browser-firefox": "^1.57.0", + "@playwright/browser-webkit": "^1.57.0", + "karma": "^6.4.4", + "karma-ie-launcher": "^1.0.0", + "karma-phantomjs-launcher": "~1.0.4", + "karma-qunit": "^4.2.1", + "phantomjs-prebuilt": "~2.1.16", + "playwright": "^1.57.0", + "qunit": "^2.24.3", + "which": "^6.0.0" + } +} diff --git a/tests/unit-karma/runner.mjs b/tests/unit-karma/runner.mjs new file mode 100644 index 000000000000..f7e5901e3484 --- /dev/null +++ b/tests/unit-karma/runner.mjs @@ -0,0 +1,9 @@ +if (process.env.CI) await $`playwright install-deps`; + +$.quote = it => `'${ it }'`; + +await Promise.all([ + ['packages/core-js-bundle/index', 'tests/bundles/unit-global'], + ['packages/core-js-bundle/minified', 'tests/bundles/unit-global'], + ['tests/bundles/unit-pure'], +].map(files => $`karma start -f=${ files.map(file => `../../${ file }.js`).join(',') }`)); diff --git a/tests/unit-node/package-lock.json b/tests/unit-node/package-lock.json new file mode 100644 index 000000000000..a2571e8a132a --- /dev/null +++ b/tests/unit-node/package-lock.json @@ -0,0 +1,76 @@ +{ + "name": "tests/unit-node", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tests/unit-node", + "devDependencies": { + "qunit": "^2.24.3" + } + }, + "node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/globalyzer": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz", + "integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-watch": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/node-watch/-/node-watch-0.7.3.tgz", + "integrity": "sha512-3l4E8uMPY1HdMMryPRUAl+oIHtXtyiTlIiESNSVSNxcPfzAFzeTbXFQkZfAwBbo0B1qMSG8nUABx+Gd+YrbKrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qunit": { + "version": "2.24.3", + "resolved": "https://registry.npmjs.org/qunit/-/qunit-2.24.3.tgz", + "integrity": "sha512-JTHwSfHf2Cw8TqusZo2tT4F9d+XA/pp/veoxUDiPNHtB1Wc1VPctiHHIv6HA3vrXNOBu9LSzFM7YU2OV9Gz4vQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "7.2.0", + "node-watch": "0.7.3", + "tiny-glob": "0.2.9" + }, + "bin": { + "qunit": "bin/qunit.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tiny-glob": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", + "integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "globalyzer": "0.1.0", + "globrex": "^0.1.2" + } + } + } +} diff --git a/tests/unit-node/package.json b/tests/unit-node/package.json new file mode 100644 index 000000000000..db811f09c087 --- /dev/null +++ b/tests/unit-node/package.json @@ -0,0 +1,6 @@ +{ + "name": "tests/unit-node", + "devDependencies": { + "qunit": "^2.24.3" + } +} diff --git a/tests/unit-node/runner.mjs b/tests/unit-node/runner.mjs new file mode 100644 index 000000000000..e3f50a52ff86 --- /dev/null +++ b/tests/unit-node/runner.mjs @@ -0,0 +1,5 @@ +await Promise.all([ + ['packages/core-js/index', 'tests/bundles/unit-global'], + ['packages/core-js/index', 'packages/core-js-bundle/index', 'tests/bundles/unit-global'], + ['tests/bundles/unit-pure'], +].map(files => $`qunit ${ files.map(file => `${ file }.js`) }`)); diff --git a/tests/unit-pure/es.aggregate-error.js b/tests/unit-pure/es.aggregate-error.js new file mode 100644 index 000000000000..94188a4fa767 --- /dev/null +++ b/tests/unit-pure/es.aggregate-error.js @@ -0,0 +1,51 @@ +/* eslint-disable unicorn/throw-new-error, sonarjs/inconsistent-function-call -- required for testing */ +import AggregateError from 'core-js-pure/es/aggregate-error'; +import Symbol from 'core-js-pure/es/symbol'; +import toString from 'core-js-pure/es/object/to-string'; +import create from 'core-js-pure/es/object/create'; + +QUnit.test('AggregateError', assert => { + assert.isFunction(AggregateError); + assert.arity(AggregateError, 2); + assert.name(AggregateError, 'AggregateError'); + assert.true(new AggregateError([1]) instanceof AggregateError); + assert.true(new AggregateError([1]) instanceof Error); + assert.true(AggregateError([1]) instanceof AggregateError); + assert.true(AggregateError([1]) instanceof Error); + assert.same(AggregateError([1], 'foo').message, 'foo'); + assert.same(AggregateError([1], 123).message, '123'); + assert.same(AggregateError([1]).message, ''); + assert.deepEqual(AggregateError([1, 2, 3]).errors, [1, 2, 3]); + assert.throws(() => AggregateError([1], Symbol()), 'throws on symbol as a message'); + assert.same(toString(AggregateError([1])), '[object Error]', 'Object#toString'); + + assert.true(AggregateError([1], 1) instanceof AggregateError, 'no cause, without new'); + assert.true(new AggregateError([1], 1) instanceof AggregateError, 'no cause, with new'); + + assert.true(AggregateError([1], 1, {}) instanceof AggregateError, 'with options, without new'); + assert.true(new AggregateError([1], 1, {}) instanceof AggregateError, 'with options, with new'); + + assert.true(AggregateError([1], 1, 'foo') instanceof AggregateError, 'non-object options, without new'); + assert.true(new AggregateError([1], 1, 'foo') instanceof AggregateError, 'non-object options, with new'); + + assert.same(AggregateError([1], 1, { cause: 7 }).cause, 7, 'cause, without new'); + assert.same(new AggregateError([1], 1, { cause: 7 }).cause, 7, 'cause, with new'); + + assert.same(AggregateError([1], 1, create({ cause: 7 })).cause, 7, 'prototype cause, without new'); + assert.same(new AggregateError([1], 1, create({ cause: 7 })).cause, 7, 'prototype cause, with new'); + + let error = AggregateError([1], 1, { cause: 7 }); + assert.deepEqual(error.errors, [1]); + assert.same(error.name, 'AggregateError', 'instance name'); + assert.same(error.message, '1', 'instance message'); + assert.same(error.cause, 7, 'instance cause'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.true(error.hasOwnProperty('cause'), 'cause is own'); + + error = AggregateError([1]); + assert.deepEqual(error.errors, [1]); + assert.same(error.message, '', 'default instance message'); + assert.same(error.cause, undefined, 'default instance cause undefined'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.false(error.hasOwnProperty('cause'), 'default instance cause missed'); +}); diff --git a/tests/unit-pure/es.array.at.js b/tests/unit-pure/es.array.at.js new file mode 100644 index 000000000000..5442c3ec5cfb --- /dev/null +++ b/tests/unit-pure/es.array.at.js @@ -0,0 +1,27 @@ +import { STRICT } from '../helpers/constants.js'; + +import at from 'core-js-pure/es/array/at'; + +QUnit.test('Array#at', assert => { + assert.isFunction(at); + assert.same(1, at([1, 2, 3], 0)); + assert.same(2, at([1, 2, 3], 1)); + assert.same(3, at([1, 2, 3], 2)); + assert.same(undefined, at([1, 2, 3], 3)); + assert.same(3, at([1, 2, 3], -1)); + assert.same(2, at([1, 2, 3], -2)); + assert.same(1, at([1, 2, 3], -3)); + assert.same(undefined, at([1, 2, 3], -4)); + assert.same(1, at([1, 2, 3], 0.4)); + assert.same(1, at([1, 2, 3], 0.5)); + assert.same(1, at([1, 2, 3], 0.6)); + assert.same(1, at([1], NaN)); + assert.same(1, at([1])); + assert.same(1, at([1, 2, 3], -0)); + assert.same(undefined, at(Array(1), 0)); + assert.same(1, at({ 0: 1, length: 1 }, 0)); + if (STRICT) { + assert.throws(() => at(null, 0), TypeError); + assert.throws(() => at(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.concat.js b/tests/unit-pure/es.array.concat.js new file mode 100644 index 000000000000..ad3e54d46444 --- /dev/null +++ b/tests/unit-pure/es.array.concat.js @@ -0,0 +1,33 @@ +import Symbol from 'core-js-pure/es/symbol'; +import concat from 'core-js-pure/es/array/concat'; + +/* eslint-disable no-sparse-arrays -- required for testing */ +QUnit.test('Array#concat', assert => { + assert.isFunction(concat); + let array = [1, 2]; + const sparseArray = [1, , 2]; + const nonSpreadableArray = [1, 2]; + nonSpreadableArray[Symbol.isConcatSpreadable] = false; + const arrayLike = { 0: 1, 1: 2, length: 2 }; + const spreadableArrayLike = { 0: 1, 1: 2, length: 2, [Symbol.isConcatSpreadable]: true }; + assert.deepEqual(concat(array), [1, 2], '#1'); + assert.deepEqual(concat(sparseArray), [1, , 2], '#2'); + assert.deepEqual(concat(nonSpreadableArray), [[1, 2]], '#3'); + assert.deepEqual(concat(arrayLike), [{ 0: 1, 1: 2, length: 2 }], '#4'); + assert.deepEqual(concat(spreadableArrayLike), [1, 2], '#5'); + assert.deepEqual(concat([], array), [1, 2], '#6'); + assert.deepEqual(concat([], sparseArray), [1, , 2], '#7'); + assert.deepEqual(concat([], nonSpreadableArray), [[1, 2]], '#8'); + assert.deepEqual(concat([], arrayLike), [{ 0: 1, 1: 2, length: 2 }], '#9'); + assert.deepEqual(concat([], spreadableArrayLike), [1, 2], '#10'); + assert.deepEqual(concat(array, sparseArray, nonSpreadableArray, arrayLike, spreadableArrayLike), [ + 1, 2, 1, , 2, [1, 2], { 0: 1, 1: 2, length: 2 }, 1, 2, + ], '#11'); + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + // https://bugs.webkit.org/show_bug.cgi?id=281061 + assert.same(concat(array).foo, 1, '@@species'); +}); diff --git a/tests/unit-pure/es.array.copy-within.js b/tests/unit-pure/es.array.copy-within.js new file mode 100644 index 000000000000..9505868c8983 --- /dev/null +++ b/tests/unit-pure/es.array.copy-within.js @@ -0,0 +1,25 @@ +import { STRICT } from '../helpers/constants.js'; + +import copyWithin from 'core-js-pure/es/array/copy-within'; + +QUnit.test('Array#copyWithin', assert => { + assert.isFunction(copyWithin); + const array = [1]; + assert.same(copyWithin(array, 0), array); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 0, 3), [4, 5, 3, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 1, 3), [1, 4, 5, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 1, 2), [1, 3, 4, 5, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 2, 2), [1, 2, 3, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 0, 3, 4), [4, 2, 3, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 1, 3, 4), [1, 4, 3, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 1, 2, 4), [1, 3, 4, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 0, -2), [4, 5, 3, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], 0, -2, -1), [4, 2, 3, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], -4, -3, -2), [1, 3, 3, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], -4, -3, -1), [1, 3, 4, 4, 5]); + assert.deepEqual(copyWithin([1, 2, 3, 4, 5], -4, -3), [1, 3, 4, 5, 5]); + if (STRICT) { + assert.throws(() => copyWithin(null, 0), TypeError); + assert.throws(() => copyWithin(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.every.js b/tests/unit-pure/es.array.every.js new file mode 100644 index 000000000000..afef1bc49204 --- /dev/null +++ b/tests/unit-pure/es.array.every.js @@ -0,0 +1,32 @@ +import { STRICT } from '../helpers/constants.js'; + +import every from 'core-js-pure/es/array/every'; + +QUnit.test('Array#every', assert => { + assert.isFunction(every); + const array = [1]; + const context = {}; + every(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true(every([1, 2, 3], it => typeof it == 'number')); + assert.true(every([1, 2, 3], it => it < 4)); + assert.false(every([1, 2, 3], it => it < 3)); + assert.false(every([1, 2, 3], it => typeof it == 'string')); + assert.true(every([1, 2, 3], function () { + return +this === 1; + }, 1)); + let rez = ''; + every([1, 2, 3], (value, key) => rez += key); + assert.same(rez, '012'); + const arr = [1, 2, 3]; + assert.true(every(arr, (value, key, that) => that === arr)); + if (STRICT) { + assert.throws(() => every(null, () => { /* empty */ }), TypeError); + assert.throws(() => every(undefined, () => { /* empty */ }), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.fill.js b/tests/unit-pure/es.array.fill.js new file mode 100644 index 000000000000..5bfc4b5ba5bc --- /dev/null +++ b/tests/unit-pure/es.array.fill.js @@ -0,0 +1,19 @@ +import { STRICT } from '../helpers/constants.js'; + +import fill from 'core-js-pure/es/array/fill'; + +QUnit.test('Array#fill', assert => { + assert.isFunction(fill); + const array = fill(Array(5), 5); + assert.same(array, array); + assert.deepEqual(fill(Array(5), 5), [5, 5, 5, 5, 5]); + assert.deepEqual(fill(Array(5), 5, 1), [undefined, 5, 5, 5, 5]); + assert.deepEqual(fill(Array(5), 5, 1, 4), [undefined, 5, 5, 5, undefined]); + assert.deepEqual(fill(Array(5), 5, 6, 1), [undefined, undefined, undefined, undefined, undefined]); + assert.deepEqual(fill(Array(5), 5, -3, 4), [undefined, undefined, 5, 5, undefined]); + assert.arrayEqual(fill({ length: 5 }, 5), [5, 5, 5, 5, 5]); + if (STRICT) { + assert.throws(() => fill(null, 0), TypeError); + assert.throws(() => fill(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.filter.js b/tests/unit-pure/es.array.filter.js new file mode 100644 index 000000000000..1be7f3ea7c7a --- /dev/null +++ b/tests/unit-pure/es.array.filter.js @@ -0,0 +1,28 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import filter from 'core-js-pure/es/array/filter'; + +QUnit.test('Array#filter', assert => { + assert.isFunction(filter); + let array = [1]; + const context = {}; + filter(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.deepEqual([1, 2, 3, 4, 5], filter([1, 2, 3, 'q', {}, 4, true, 5], it => typeof it == 'number')); + if (STRICT) { + assert.throws(() => filter(null, () => { /* empty */ }), TypeError); + assert.throws(() => filter(undefined, () => { /* empty */ }), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(filter(array, Boolean).foo, 1, '@@species'); +}); diff --git a/tests/unit-pure/es.array.find-index.js b/tests/unit-pure/es.array.find-index.js new file mode 100644 index 000000000000..908594d83257 --- /dev/null +++ b/tests/unit-pure/es.array.find-index.js @@ -0,0 +1,20 @@ +import { STRICT } from '../helpers/constants.js'; + +import findIndex from 'core-js-pure/es/array/find-index'; + +QUnit.test('Array#findIndex', assert => { + assert.isFunction(findIndex); + const array = [1]; + const context = {}; + findIndex(array, function (value, key, that) { + assert.same(this, context); + assert.same(value, 1); + assert.same(key, 0); + assert.same(that, array); + }, context); + assert.same(findIndex([1, 3, NaN, 42, {}], it => it === 42), 3); + if (STRICT) { + assert.throws(() => findIndex(null, 0), TypeError); + assert.throws(() => findIndex(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.find-last-index.js b/tests/unit-pure/es.array.find-last-index.js new file mode 100644 index 000000000000..bb745df3bcdb --- /dev/null +++ b/tests/unit-pure/es.array.find-last-index.js @@ -0,0 +1,36 @@ +import { STRICT } from '../helpers/constants.js'; + +import findLastIndex from 'core-js-pure/es/array/find-last-index'; + +QUnit.test('Array#findLastIndex', assert => { + assert.isFunction(findLastIndex); + const array = [1]; + const context = {}; + findLastIndex(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same(findLastIndex([{}, 2, NaN, 42, 1], it => !(it % 2)), 3); + assert.same(findLastIndex([{}, 2, NaN, 42, 1], it => it === 43), -1); + let values = ''; + let keys = ''; + findLastIndex([1, 2, 3], (value, key) => { + values += value; + keys += key; + }); + assert.same(values, '321'); + assert.same(keys, '210'); + if (STRICT) { + assert.throws(() => findLastIndex(null, 0), TypeError); + assert.throws(() => findLastIndex(undefined, 0), TypeError); + } + assert.notThrows(() => findLastIndex({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }) === -1, 'uses ToLength'); +}); diff --git a/tests/unit-pure/es.array.find-last.js b/tests/unit-pure/es.array.find-last.js new file mode 100644 index 000000000000..cdcc22704be4 --- /dev/null +++ b/tests/unit-pure/es.array.find-last.js @@ -0,0 +1,36 @@ +import { STRICT } from '../helpers/constants.js'; + +import findLast from 'core-js-pure/es/array/find-last'; + +QUnit.test('Array#findLast', assert => { + assert.isFunction(findLast); + const array = [1]; + const context = {}; + findLast(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same(findLast([{}, 2, NaN, 42, 1], it => !(it % 2)), 42); + assert.same(findLast([{}, 2, NaN, 42, 1], it => it === 43), undefined); + let values = ''; + let keys = ''; + findLast([1, 2, 3], (value, key) => { + values += value; + keys += key; + }); + assert.same(values, '321'); + assert.same(keys, '210'); + if (STRICT) { + assert.throws(() => findLast(null, 0), TypeError); + assert.throws(() => findLast(undefined, 0), TypeError); + } + assert.notThrows(() => findLast({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }) === undefined, 'uses ToLength'); +}); diff --git a/tests/unit-pure/es.array.find.js b/tests/unit-pure/es.array.find.js new file mode 100644 index 000000000000..aa990a3a1634 --- /dev/null +++ b/tests/unit-pure/es.array.find.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; + +import find from 'core-js-pure/es/array/find'; + +QUnit.test('Array#find', assert => { + assert.isFunction(find); + const array = [1]; + const context = {}; + find(array, function (value, key, that) { + assert.same(this, context); + assert.same(value, 1); + assert.same(key, 0); + assert.same(that, array); + }, context); + assert.same(find([1, 3, NaN, 42, {}], it => it === 42), 42); + assert.same(find([1, 3, NaN, 42, {}], it => it === 43), undefined); + if (STRICT) { + assert.throws(() => find(null, 0), TypeError); + assert.throws(() => find(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.flat-map.js b/tests/unit-pure/es.array.flat-map.js new file mode 100644 index 000000000000..ee04a64d007b --- /dev/null +++ b/tests/unit-pure/es.array.flat-map.js @@ -0,0 +1,27 @@ +import { STRICT } from '../helpers/constants.js'; + +import flatMap from 'core-js-pure/es/array/flat-map'; + +QUnit.test('Array#flatMap', assert => { + assert.isFunction(flatMap); + assert.deepEqual(flatMap([], it => it), []); + assert.deepEqual(flatMap([1, 2, 3], it => it), [1, 2, 3]); + assert.deepEqual(flatMap([1, 2, 3], it => [it, it]), [1, 1, 2, 2, 3, 3]); + assert.deepEqual(flatMap([1, 2, 3], it => [[it], [it]]), [[1], [1], [2], [2], [3], [3]]); + assert.deepEqual(flatMap([1, [2, 3]], () => 1), [1, 1]); + const array = [1]; + const context = {}; + flatMap(array, function (value, index, that) { + assert.same(value, 1); + assert.same(index, 0); + assert.same(that, array); + assert.same(this, context); + }, context); + if (STRICT) { + assert.throws(() => flatMap(null, it => it), TypeError); + assert.throws(() => flatMap(undefined, it => it), TypeError); + } + assert.notThrows(() => flatMap({ length: -1 }, () => { + throw new Error(); + }).length === 0, 'uses ToLength'); +}); diff --git a/tests/unit-pure/es.array.flat.js b/tests/unit-pure/es.array.flat.js new file mode 100644 index 000000000000..de1f5ed7b757 --- /dev/null +++ b/tests/unit-pure/es.array.flat.js @@ -0,0 +1,28 @@ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +import flat from 'core-js-pure/es/array/flat'; +import defineProperty from 'core-js-pure/es/object/define-property'; + +QUnit.test('Array#flat', assert => { + assert.isFunction(flat); + assert.deepEqual(flat([]), []); + const array = [1, [2, 3], [4, [5, 6]]]; + assert.deepEqual(flat(array, 0), array); + assert.deepEqual(flat(array, 1), [1, 2, 3, 4, [5, 6]]); + assert.deepEqual(flat(array), [1, 2, 3, 4, [5, 6]]); + assert.deepEqual(flat(array, 2), [1, 2, 3, 4, 5, 6]); + assert.deepEqual(flat(array, 3), [1, 2, 3, 4, 5, 6]); + assert.deepEqual(flat(array, -1), array); + assert.deepEqual(flat(array, Infinity), [1, 2, 3, 4, 5, 6]); + if (STRICT) { + assert.throws(() => flat(null), TypeError); + assert.throws(() => flat(undefined), TypeError); + } + if (DESCRIPTORS) { + assert.notThrows(() => flat(defineProperty({ length: -1 }, 0, { + get() { + throw new Error(); + }, + })).length === 0, 'uses ToLength'); + } +}); diff --git a/tests/unit-pure/es.array.for-each.js b/tests/unit-pure/es.array.for-each.js new file mode 100644 index 000000000000..16f96ad0154a --- /dev/null +++ b/tests/unit-pure/es.array.for-each.js @@ -0,0 +1,47 @@ +import { STRICT } from '../helpers/constants.js'; + +import forEach from 'core-js-pure/es/array/for-each'; + +QUnit.test('Array#forEach', assert => { + assert.isFunction(forEach); + let array = [1]; + const context = {}; + forEach(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + let result = ''; + forEach([1, 2, 3], it => { + result += it; + }); + assert.same(result, '123'); + result = ''; + forEach([1, 2, 3], (value, key) => { + result += key; + }); + assert.same(result, '012'); + result = ''; + forEach([1, 2, 3], (value, key, that) => { + result += that; + }); + assert.same(result, '1,2,31,2,31,2,3'); + result = ''; + forEach([1, 2, 3], function () { + result += this; + }, 1); + assert.same(result, '111'); + result = ''; + array = []; + array[5] = ''; + forEach(array, (value, key) => { + result += key; + }); + assert.same(result, '5'); + if (STRICT) { + assert.throws(() => forEach(null, () => { /* empty */ }), TypeError); + assert.throws(() => forEach(undefined, () => { /* empty */ }), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.from-async.js b/tests/unit-pure/es.array.from-async.js new file mode 100644 index 000000000000..6e076fbfe896 --- /dev/null +++ b/tests/unit-pure/es.array.from-async.js @@ -0,0 +1,103 @@ +import { createAsyncIterable, createIterable/* , createIterator */ } from '../helpers/helpers.js'; +import { STRICT_THIS } from '../helpers/constants.js'; + +import Promise from 'core-js-pure/es/promise'; +import fromAsync from 'core-js-pure/es/array/from-async'; +// import Iterator from 'core-js-pure/actual/iterator'; + +QUnit.test('Array.fromAsync', assert => { + assert.isFunction(fromAsync); + assert.arity(fromAsync, 1); + assert.name(fromAsync, 'fromAsync'); + + let counter = 0; + // eslint-disable-next-line prefer-arrow-callback -- constructor + fromAsync.call(function () { + counter++; + return []; + }, { length: 0 }); + + assert.same(counter, 1, 'proper number of constructor calling'); + + function C() { /* empty */ } + + // const closableIterator = createIterator([1], { + // return() { this.closed = true; return { value: undefined, done: true }; }, + // }); + + return fromAsync(createAsyncIterable([1, 2, 3]), it => it ** 2).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'async iterable and mapfn'); + return fromAsync(createAsyncIterable([1]), function (arg, index) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(index, 0, 'index'); + }); + }).then(() => { + return fromAsync(createAsyncIterable([1, 2, 3])); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'async iterable without mapfn'); + return fromAsync(createIterable([1, 2, 3]), arg => arg ** 2); + }).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'iterable and mapfn'); + return fromAsync(createIterable([1, 2, 3]), arg => Promise.resolve(arg ** 2)); + }).then(it => { + assert.arrayEqual(it, [1, 4, 9], 'iterable and async mapfn'); + return fromAsync(createIterable([1]), function (arg, index) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(index, 0, 'index'); + }); + }).then(() => { + return fromAsync(createIterable([1, 2, 3])); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'iterable and without mapfn'); + return fromAsync([1, Promise.resolve(2), 3]); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'array'); + return fromAsync('123'); + }).then(it => { + assert.arrayEqual(it, ['1', '2', '3'], 'string'); + return fromAsync.call(C, [1]); + }).then(it => { + assert.true(it instanceof C, 'subclassable'); + return fromAsync({ length: 1, 0: 1 }); + }).then(it => { + assert.arrayEqual(it, [1], 'non-iterable'); + return fromAsync(createIterable([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + return fromAsync(undefined, () => { /* empty */ }); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return fromAsync(null, () => { /* empty */ }); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return fromAsync([1], null); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + return fromAsync([1], {}); + }).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof TypeError); + }); + /* Tests are temporarily disabled due to the lack of proper async feature detection in native implementations. + .then(() => { + return fromAsync(Iterator.from(closableIterator), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + assert.true(closableIterator.closed, 'doesn\'t close sync iterator on promise rejection'); + }); */ +}); diff --git a/tests/unit-pure/es.array.from.js b/tests/unit-pure/es.array.from.js new file mode 100644 index 000000000000..5fa36f77956c --- /dev/null +++ b/tests/unit-pure/es.array.from.js @@ -0,0 +1,126 @@ +/* eslint-disable prefer-rest-params -- required for testing */ +import { DESCRIPTORS } from '../helpers/constants.js'; +import { createIterable } from '../helpers/helpers.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import from from 'core-js-pure/es/array/from'; + +QUnit.test('Array.from', assert => { + assert.isFunction(from); + assert.arity(from, 1); + let types = { + 'array-like': { + length: '3', + 0: '1', + 1: '2', + 2: '3', + }, + arguments: function () { + return arguments; + }('1', '2', '3'), + array: ['1', '2', '3'], + iterable: createIterable(['1', '2', '3']), + string: '123', + }; + for (const type in types) { + const data = types[type]; + assert.arrayEqual(from(data), ['1', '2', '3'], `Works with ${ type }`); + assert.arrayEqual(from(data, it => it ** 2), [1, 4, 9], `Works with ${ type } + mapFn`); + } + types = { + 'array-like': { + length: 1, + 0: 1, + }, + arguments: function () { + return arguments; + }(1), + array: [1], + iterable: createIterable([1]), + string: '1', + }; + for (const type in types) { + const data = types[type]; + const context = {}; + assert.arrayEqual(from(data, function (value, key) { + assert.same(this, context, `Works with ${ type }, correct callback context`); + assert.same(value, type === 'string' ? '1' : 1, `Works with ${ type }, correct callback key`); + assert.same(key, 0, `Works with ${ type }, correct callback value`); + assert.same(arguments.length, 2, `Works with ${ type }, correct callback arguments number`); + return 42; + }, context), [42], `Works with ${ type }, correct result`); + } + const primitives = [false, true, 0]; + for (const primitive of primitives) { + assert.arrayEqual(from(primitive), [], `Works with ${ primitive }`); + } + assert.throws(() => from(null), TypeError, 'Throws on null'); + assert.throws(() => from(undefined), TypeError, 'Throws on undefined'); + assert.arrayEqual(from('𠮷𠮷𠮷'), ['𠮷', '𠮷', '𠮷'], 'Uses correct string iterator'); + let done = true; + from(createIterable([1, 2, 3], { + return() { + return done = false; + }, + }), () => false); + assert.true(done, '.return #default'); + done = false; + try { + from(createIterable([1, 2, 3], { + return() { + return done = true; + }, + }), () => { + throw new Error(); + }); + } catch { /* empty */ } + assert.true(done, '.return #throw'); + class C { /* empty */ } + let instance = from.call(C, createIterable([1, 2])); + assert.true(instance instanceof C, 'generic, iterable case, instanceof'); + assert.arrayEqual(instance, [1, 2], 'generic, iterable case, elements'); + instance = from.call(C, { + 0: 1, + 1: 2, + length: 2, + }); + assert.true(instance instanceof C, 'generic, array-like case, instanceof'); + assert.arrayEqual(instance, [1, 2], 'generic, array-like case, elements'); + let array = [1, 2, 3]; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + assert.arrayEqual(from(array), [1, 2, 3], 'Array with custom iterator, elements'); + assert.true(done, 'call @@iterator in Array with custom iterator'); + array = [1, 2, 3]; + delete array[1]; + assert.arrayEqual(from(array, String), ['1', 'undefined', '3'], 'Ignores holes'); + assert.notThrows(() => from({ + length: -1, + 0: 1, + }, () => { + throw new Error(); + }), 'Uses ToLength'); + assert.arrayEqual(from([], undefined), [], 'Works with undefined as second argument'); + assert.throws(() => from([], null), TypeError, 'Throws with null as second argument'); + assert.throws(() => from([], 0), TypeError, 'Throws with 0 as second argument'); + assert.throws(() => from([], ''), TypeError, 'Throws with "" as second argument'); + assert.throws(() => from([], false), TypeError, 'Throws with false as second argument'); + assert.throws(() => from([], {}), TypeError, 'Throws with {} as second argument'); + if (DESCRIPTORS) { + let called = false; + defineProperty(C.prototype, 0, { + set() { + called = true; + }, + }); + from.call(C, [1, 2, 3]); + assert.false(called, 'Should not call prototype accessors'); + } +}); diff --git a/tests/unit-pure/es.array.includes.js b/tests/unit-pure/es.array.includes.js new file mode 100644 index 000000000000..30a7c528fc05 --- /dev/null +++ b/tests/unit-pure/es.array.includes.js @@ -0,0 +1,22 @@ +import { STRICT } from '../helpers/constants.js'; + +import includes from 'core-js-pure/es/array/includes'; + +QUnit.test('Array#includes', assert => { + assert.isFunction(includes); + const object = {}; + const array = [1, 2, 3, -0, object]; + assert.true(includes(array, 1)); + assert.true(includes(array, -0)); + assert.true(includes(array, 0)); + assert.true(includes(array, object)); + assert.false(includes(array, 4)); + assert.false(includes(array, -0.5)); + assert.false(includes(array, {})); + assert.true(includes(Array(1), undefined)); + assert.true(includes([NaN], NaN)); + if (STRICT) { + assert.throws(() => includes(null, 0), TypeError); + assert.throws(() => includes(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.index-of.js b/tests/unit-pure/es.array.index-of.js new file mode 100644 index 000000000000..406338d8ad40 --- /dev/null +++ b/tests/unit-pure/es.array.index-of.js @@ -0,0 +1,20 @@ +import { STRICT } from '../helpers/constants.js'; + +import indexOf from 'core-js-pure/es/array/index-of'; + +QUnit.test('Array#indexOf', assert => { + assert.isFunction(indexOf); + assert.same(0, indexOf([1, 1, 1], 1)); + assert.same(-1, indexOf([1, 2, 3], 1, 1)); + assert.same(1, indexOf([1, 2, 3], 2, 1)); + assert.same(-1, indexOf([1, 2, 3], 2, -1)); + assert.same(1, indexOf([1, 2, 3], 2, -2)); + assert.same(-1, indexOf([NaN], NaN)); + assert.same(3, indexOf(Array(2).concat([1, 2, 3]), 2)); + assert.same(-1, indexOf(Array(1), undefined)); + assert.same(0, indexOf([1], 1, -0), "shouldn't return negative zero"); + if (STRICT) { + assert.throws(() => indexOf(null, 0), TypeError); + assert.throws(() => indexOf(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.is-array.js b/tests/unit-pure/es.array.is-array.js new file mode 100644 index 000000000000..143f47e27281 --- /dev/null +++ b/tests/unit-pure/es.array.is-array.js @@ -0,0 +1,11 @@ +import isArray from 'core-js-pure/es/array/is-array'; + +QUnit.test('Array.isArray', assert => { + assert.isFunction(isArray); + assert.false(isArray({})); + assert.false(isArray(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }())); + assert.true(isArray([])); +}); diff --git a/tests/unit-pure/es.array.iterator.js b/tests/unit-pure/es.array.iterator.js new file mode 100644 index 000000000000..60776a268adc --- /dev/null +++ b/tests/unit-pure/es.array.iterator.js @@ -0,0 +1,100 @@ +import Symbol from 'core-js-pure/es/symbol'; +import getIterator from 'core-js-pure/es/get-iterator'; +import { keys, values, entries } from 'core-js-pure/es/array'; + +QUnit.test('Array#@@iterator', assert => { + assert.isFunction(values); + const iterator = getIterator(['q', 'w', 'e']); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.same(String(iterator), '[object Array Iterator]'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Array#keys', assert => { + assert.isFunction(keys); + const iterator = keys(['q', 'w', 'e']); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.deepEqual(iterator.next(), { + value: 0, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 1, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 2, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Array#values', assert => { + assert.isFunction(values); + const iterator = values(['q', 'w', 'e']); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Array#entries', assert => { + assert.isFunction(entries); + const iterator = entries(['q', 'w', 'e']); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Array Iterator'); + assert.deepEqual(iterator.next(), { + value: [0, 'q'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: [1, 'w'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: [2, 'e'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-pure/es.array.join.js b/tests/unit-pure/es.array.join.js new file mode 100644 index 000000000000..156647cf7851 --- /dev/null +++ b/tests/unit-pure/es.array.join.js @@ -0,0 +1,14 @@ +import { STRICT } from '../helpers/constants.js'; + +import join from 'core-js-pure/es/array/join'; + +QUnit.test('Array#join', assert => { + assert.isFunction(join); + assert.same(join([1, 2, 3], undefined), '1,2,3'); + assert.same(join('123'), '1,2,3'); + assert.same(join('123', '|'), '1|2|3'); + if (STRICT) { + assert.throws(() => join(null), TypeError); + assert.throws(() => join(undefined), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.last-index-of.js b/tests/unit-pure/es.array.last-index-of.js new file mode 100644 index 000000000000..662e189e1b57 --- /dev/null +++ b/tests/unit-pure/es.array.last-index-of.js @@ -0,0 +1,20 @@ +import { STRICT } from '../helpers/constants.js'; + +import lastIndexOf from 'core-js-pure/es/array/last-index-of'; + +QUnit.test('Array#lastIndexOf', assert => { + assert.isFunction(lastIndexOf); + assert.same(2, lastIndexOf([1, 1, 1], 1)); + assert.same(-1, lastIndexOf([1, 2, 3], 3, 1)); + assert.same(1, lastIndexOf([1, 2, 3], 2, 1)); + assert.same(-1, lastIndexOf([1, 2, 3], 2, -3)); + assert.same(-1, lastIndexOf([1, 2, 3], 1, -4)); + assert.same(1, lastIndexOf([1, 2, 3], 2, -2)); + assert.same(-1, lastIndexOf([NaN], NaN)); + assert.same(1, lastIndexOf([1, 2, 3].concat(Array(2)), 2)); + assert.same(0, lastIndexOf([1], 1, -0), "shouldn't return negative zero"); + if (STRICT) { + assert.throws(() => lastIndexOf(null, 0), TypeError); + assert.throws(() => lastIndexOf(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.map.js b/tests/unit-pure/es.array.map.js new file mode 100644 index 000000000000..6fbcd26de5aa --- /dev/null +++ b/tests/unit-pure/es.array.map.js @@ -0,0 +1,32 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import map from 'core-js-pure/es/array/map'; + +QUnit.test('Array#map', assert => { + assert.isFunction(map); + let array = [1]; + const context = {}; + map(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.deepEqual([2, 3, 4], map([1, 2, 3], it => it + 1)); + assert.deepEqual([1, 3, 5], map([1, 2, 3], (value, key) => value + key)); + assert.deepEqual([2, 2, 2], map([1, 2, 3], function () { + return +this; + }, 2)); + if (STRICT) { + assert.throws(() => map(null, () => { /* empty */ }), TypeError); + assert.throws(() => map(undefined, () => { /* empty */ }), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(map(array, Boolean).foo, 1, '@@species'); +}); diff --git a/tests/unit-pure/es.array.of.js b/tests/unit-pure/es.array.of.js new file mode 100644 index 000000000000..b786cbcd1dd1 --- /dev/null +++ b/tests/unit-pure/es.array.of.js @@ -0,0 +1,27 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import defineProperty from 'core-js-pure/es/object/define-property'; +import of from 'core-js-pure/es/array/of'; + +QUnit.test('Array.of', assert => { + assert.isFunction(of); + assert.arity(of, 0); + assert.deepEqual(of(1), [1]); + assert.deepEqual(of(1, 2, 3), [1, 2, 3]); + class C { /* empty */ } + const instance = of.call(C, 1, 2); + assert.true(instance instanceof C); + assert.same(instance[0], 1); + assert.same(instance[1], 2); + assert.same(instance.length, 2); + if (DESCRIPTORS) { + let called = false; + defineProperty(C.prototype, 0, { + set() { + called = true; + }, + }); + of.call(C, 1, 2, 3); + assert.false(called, 'Should not call prototype accessors'); + } +}); diff --git a/tests/unit-pure/es.array.push.js b/tests/unit-pure/es.array.push.js new file mode 100644 index 000000000000..4e91c981aa8b --- /dev/null +++ b/tests/unit-pure/es.array.push.js @@ -0,0 +1,22 @@ +import { REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR, STRICT } from '../helpers/constants.js'; + +import push from 'core-js-pure/es/array/virtual/push'; +import defineProperty from 'core-js-pure/es/object/define-property'; + +QUnit.test('Array#push', assert => { + assert.isFunction(push); + + const object = { length: 0x100000000 }; + assert.same(push.call(object, 1), 0x100000001, 'proper ToLength #1'); + assert.same(object[0x100000000], 1, 'proper ToLength #2'); + + if (STRICT) { + if (REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR) { + assert.throws(() => push.call(defineProperty([], 'length', { writable: false }), 1), TypeError, 'non-writable length, with arg'); + assert.throws(() => push.call(defineProperty([], 'length', { writable: false })), TypeError, 'non-writable length, without arg'); + } + + assert.throws(() => push.call(null), TypeError); + assert.throws(() => push.call(undefined), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.reduce-right.js b/tests/unit-pure/es.array.reduce-right.js new file mode 100644 index 000000000000..890b07f7be42 --- /dev/null +++ b/tests/unit-pure/es.array.reduce-right.js @@ -0,0 +1,42 @@ +import { STRICT } from '../helpers/constants.js'; + +import reduceRight from 'core-js-pure/es/array/reduce-right'; + +QUnit.test('Array#reduceRight', assert => { + assert.isFunction(reduceRight); + const array = [1]; + const accumulator = {}; + reduceRight(array, function (memo, value, key, that) { + assert.same(arguments.length, 4, 'correct number of callback arguments'); + assert.same(memo, accumulator, 'correct callback accumulator'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + }, accumulator); + assert.same(reduceRight([1, 2, 3], ((a, b) => a + b), 1), 7, 'works with initial accumulator'); + reduceRight([1, 2], (memo, value, key) => { + assert.same(memo, 2, 'correct default accumulator'); + assert.same(value, 1, 'correct start value without initial accumulator'); + assert.same(key, 0, 'correct start index without initial accumulator'); + }); + assert.same(reduceRight([1, 2, 3], (a, b) => a + b), 6, 'works without initial accumulator'); + let values = ''; + let keys = ''; + reduceRight([1, 2, 3], (memo, value, key) => { + values += value; + keys += key; + }, 0); + assert.same(values, '321', 'correct order #1'); + assert.same(keys, '210', 'correct order #2'); + assert.same(reduceRight({ + 0: 1, + 1: 2, + length: 2, + }, (a, b) => a + b), 3, 'generic'); + assert.throws(() => reduceRight([], () => { /* empty */ }), TypeError); + assert.throws(() => reduceRight(Array(5), () => { /* empty */ }), TypeError); + if (STRICT) { + assert.throws(() => reduceRight(null, () => { /* empty */ }, 1), TypeError); + assert.throws(() => reduceRight(undefined, () => { /* empty */ }, 1), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.reduce.js b/tests/unit-pure/es.array.reduce.js new file mode 100644 index 000000000000..b1171979c60c --- /dev/null +++ b/tests/unit-pure/es.array.reduce.js @@ -0,0 +1,42 @@ +import { STRICT } from '../helpers/constants.js'; + +import reduce from 'core-js-pure/es/array/reduce'; + +QUnit.test('Array#reduce', assert => { + assert.isFunction(reduce); + const array = [1]; + const accumulator = {}; + reduce(array, function (memo, value, key, that) { + assert.same(arguments.length, 4, 'correct number of callback arguments'); + assert.same(memo, accumulator, 'correct callback accumulator'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + }, accumulator); + assert.same(reduce([1, 2, 3], ((a, b) => a + b), 1), 7, 'works with initial accumulator'); + reduce([1, 2], (memo, value, key) => { + assert.same(memo, 1, 'correct default accumulator'); + assert.same(value, 2, 'correct start value without initial accumulator'); + assert.same(key, 1, 'correct start index without initial accumulator'); + }); + assert.same(reduce([1, 2, 3], (a, b) => a + b), 6, 'works without initial accumulator'); + let values = ''; + let keys = ''; + reduce([1, 2, 3], (memo, value, key) => { + values += value; + keys += key; + }, 0); + assert.same(values, '123', 'correct order #1'); + assert.same(keys, '012', 'correct order #2'); + assert.same(reduce({ + 0: 1, + 1: 2, + length: 2, + }, (a, b) => a + b), 3, 'generic'); + assert.throws(() => reduce([], () => { /* empty */ }), TypeError); + assert.throws(() => reduce(Array(5), () => { /* empty */ }), TypeError); + if (STRICT) { + assert.throws(() => reduce(null, () => { /* empty */ }, 1), TypeError); + assert.throws(() => reduce(undefined, () => { /* empty */ }, 1), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.reverse.js b/tests/unit-pure/es.array.reverse.js new file mode 100644 index 000000000000..29232dbee381 --- /dev/null +++ b/tests/unit-pure/es.array.reverse.js @@ -0,0 +1,18 @@ +import { STRICT } from '../helpers/constants.js'; + +import reverse from 'core-js-pure/es/array/reverse'; + +QUnit.test('Array#reverse', assert => { + assert.isFunction(reverse); + const a = [1, 2.2, 3.3]; + function fn() { + +a; + reverse(a); + } + fn(); + assert.arrayEqual(a, [3.3, 2.2, 1]); + if (STRICT) { + assert.throws(() => reverse(null, () => { /* empty */ }, 1), TypeError); + assert.throws(() => reverse(undefined, () => { /* empty */ }, 1), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.slice.js b/tests/unit-pure/es.array.slice.js new file mode 100644 index 000000000000..412347c58414 --- /dev/null +++ b/tests/unit-pure/es.array.slice.js @@ -0,0 +1,33 @@ +import { GLOBAL } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import isArray from 'core-js-pure/es/array/is-array'; +import slice from 'core-js-pure/es/array/slice'; + +QUnit.test('Array#slice', assert => { + assert.isFunction(slice); + let array = ['1', '2', '3', '4', '5']; + assert.deepEqual(slice(array), array); + assert.deepEqual(slice(array, 1, 3), ['2', '3']); + assert.deepEqual(slice(array, 1, undefined), ['2', '3', '4', '5']); + assert.deepEqual(slice(array, 1, -1), ['2', '3', '4']); + assert.deepEqual(slice(array, -2, -1), ['4']); + assert.deepEqual(slice(array, -2, -3), []); + const string = '12345'; + assert.deepEqual(slice(string), array); + assert.deepEqual(slice(string, 1, 3), ['2', '3']); + assert.deepEqual(slice(string, 1, undefined), ['2', '3', '4', '5']); + assert.deepEqual(slice(string, 1, -1), ['2', '3', '4']); + assert.deepEqual(slice(string, -2, -1), ['4']); + assert.deepEqual(slice(string, -2, -3), []); + const list = GLOBAL.document && document.body && document.body.childNodes; + if (list) { + assert.notThrows(() => isArray(slice(list)), 'works with NodeList'); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(slice(array).foo, 1, '@@species'); +}); diff --git a/tests/unit-pure/es.array.some.js b/tests/unit-pure/es.array.some.js new file mode 100644 index 000000000000..17e605ad24f7 --- /dev/null +++ b/tests/unit-pure/es.array.some.js @@ -0,0 +1,35 @@ +import { STRICT } from '../helpers/constants.js'; + +import some from 'core-js-pure/es/array/some'; + +QUnit.test('Array#some', assert => { + assert.isFunction(some); + let array = [1]; + const context = {}; + some(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true(some([1, '2', 3], it => typeof it == 'number')); + assert.true(some([1, 2, 3], it => it < 3)); + assert.false(some([1, 2, 3], it => it < 0)); + assert.false(some([1, 2, 3], it => typeof it == 'string')); + assert.false(some([1, 2, 3], function () { + return +this !== 1; + }, 1)); + let result = ''; + some([1, 2, 3], (value, key) => { + result += key; + return false; + }); + assert.same(result, '012'); + array = [1, 2, 3]; + assert.false(some(array, (value, key, that) => that !== array)); + if (STRICT) { + assert.throws(() => some(null, () => { /* empty */ }), TypeError); + assert.throws(() => some(undefined, () => { /* empty */ }), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.sort.js b/tests/unit-pure/es.array.sort.js new file mode 100644 index 000000000000..8295e6e3a737 --- /dev/null +++ b/tests/unit-pure/es.array.sort.js @@ -0,0 +1,126 @@ +import { STRICT } from '../helpers/constants.js'; + +import sort from 'core-js-pure/es/array/sort'; + +QUnit.test('Array#sort', assert => { + assert.isFunction(sort); + assert.notThrows(() => sort([1, 2, 3], undefined), 'works with undefined'); + assert.throws(() => sort([1, 2, 3], null), 'throws on null'); + assert.throws(() => sort([1, 2, 3], {}), 'throws on {}'); + + assert.deepEqual(sort([1, 3, 2]), [1, 2, 3], '#1'); + assert.deepEqual(sort([1, 3, 2, 11]), [1, 11, 2, 3], '#2'); + assert.deepEqual(sort([1, -1, 3, NaN, 2, 0, 11, -0]), [-1, 0, -0, 1, 11, 2, 3, NaN], '#3'); + + let array = Array(5); + array[0] = 1; + array[2] = 3; + array[4] = 2; + let expected = Array(5); + expected[0] = 1; + expected[1] = 2; + expected[2] = 3; + assert.deepEqual(sort(array), expected, 'holes'); + + array = 'zyxwvutsrqponMLKJIHGFEDCBA'.split(''); + expected = 'ABCDEFGHIJKLMnopqrstuvwxyz'.split(''); + assert.deepEqual(sort(array), expected, 'alpha #1'); + + array = 'ёяюэьыъщшчцхфутсрПОНМЛКЙИЗЖЕДГВБА'.split(''); + expected = 'АБВГДЕЖЗИЙКЛМНОПрстуфхцчшщъыьэюяё'.split(''); + assert.deepEqual(sort(array), expected, 'alpha #2'); + + array = [undefined, 1]; + assert.notThrows(() => sort(array, () => { throw 1; }), 'undefined #1'); + assert.deepEqual(array, [1, undefined], 'undefined #2'); + + /* Safari TP ~ 17.6 issue + const object = { + valueOf: () => 1, + toString: () => -1, + }; + + array = { + 0: undefined, + 1: 2, + 2: 1, + 3: 'X', + 4: -1, + 5: 'a', + 6: true, + 7: object, + 8: NaN, + 10: Infinity, + length: 11, + }; + + expected = { + 0: -1, + 1: object, + 2: 1, + 3: 2, + 4: Infinity, + 5: NaN, + 6: 'X', + 7: 'a', + 8: true, + 9: undefined, + length: 11, + }; + + assert.deepEqual(sort(array), expected, 'custom generic'); + */ + + let index, mod, code, chr, value; + expected = Array(516); + array = Array(516); + + for (index = 0; index < 516; index++) { + mod = index % 4; + array[index] = 515 - index; + expected[index] = index - 2 * mod + 3; + } + + sort(array, (a, b) => (a / 4 | 0) - (b / 4 | 0)); + + assert.true(1 / sort([0, -0])[0] > 0, '-0'); + + assert.arrayEqual(array, expected, 'stable #1'); + + let result = ''; + array = []; + + // generate an array with more 512 elements (Chakra and old V8 fails only in this case) + for (code = 65; code < 76; code++) { + chr = String.fromCharCode(code); + + switch (code) { + case 66: case 69: case 70: case 72: value = 3; break; + case 68: case 71: value = 4; break; + default: value = 2; + } + + for (index = 0; index < 47; index++) { + array.push({ k: chr + index, v: value }); + } + } + + sort(array, (a, b) => b.v - a.v); + + for (index = 0; index < array.length; index++) { + chr = array[index].k.charAt(0); + if (result.charAt(result.length - 1) !== chr) result += chr; + } + + assert.same(result, 'DGBEFHACIJK', 'stable #2'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => sort([Symbol(1), Symbol(2)]), 'w/o cmp throws on symbols'); + } + + if (STRICT) { + assert.throws(() => sort(null), TypeError, 'ToObject(this)'); + assert.throws(() => sort(undefined), TypeError, 'ToObject(this)'); + } +}); diff --git a/tests/unit-pure/es.array.splice.js b/tests/unit-pure/es.array.splice.js new file mode 100644 index 000000000000..f8cdb4b03833 --- /dev/null +++ b/tests/unit-pure/es.array.splice.js @@ -0,0 +1,44 @@ +import { REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR, STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import splice from 'core-js-pure/es/array/splice'; +import defineProperty from 'core-js-pure/es/object/define-property'; + +QUnit.test('Array#splice', assert => { + assert.isFunction(splice); + let array = [1, 2, 3, 4, 5]; + assert.deepEqual(splice(array, 2), [3, 4, 5]); + assert.deepEqual(array, [1, 2]); + array = [1, 2, 3, 4, 5]; + assert.deepEqual(splice(array, -2), [4, 5]); + assert.deepEqual(array, [1, 2, 3]); + array = [1, 2, 3, 4, 5]; + assert.deepEqual(splice(array, 2, 2), [3, 4]); + assert.deepEqual(array, [1, 2, 5]); + array = [1, 2, 3, 4, 5]; + assert.deepEqual(splice(array, 2, -2), []); + assert.deepEqual(array, [1, 2, 3, 4, 5]); + array = [1, 2, 3, 4, 5]; + assert.deepEqual(splice(array, 2, 2, 6, 7), [3, 4]); + assert.deepEqual(array, [1, 2, 6, 7, 5]); + // ES6 semantics + array = [0, 1, 2]; + assert.deepEqual(splice(array, 0), [0, 1, 2]); + array = [0, 1, 2]; + assert.deepEqual(splice(array, 1), [1, 2]); + array = [0, 1, 2]; + assert.deepEqual(splice(array, 2), [2]); + if (STRICT) { + if (REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR) { + assert.throws(() => splice(defineProperty([1, 2, 3], 'length', { writable: false }), 1, 1), TypeError, 'non-writable length'); + } + assert.throws(() => splice(null), TypeError); + assert.throws(() => splice(undefined), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(splice(array).foo, 1, '@@species'); +}); diff --git a/tests/unit-pure/es.array.to-reversed.js b/tests/unit-pure/es.array.to-reversed.js new file mode 100644 index 000000000000..e8b1b1c540db --- /dev/null +++ b/tests/unit-pure/es.array.to-reversed.js @@ -0,0 +1,56 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import toReversed from 'core-js-pure/es/array/to-reversed'; + +QUnit.test('Array#toReversed', assert => { + assert.isFunction(toReversed); + + let array = [1, 2]; + assert.notSame(toReversed(array), array, 'immutable'); + assert.deepEqual(toReversed([1, 2.2, 3.3]), [3.3, 2.2, 1], 'basic'); + + const object = {}; + + array = { + 0: undefined, + 1: 2, + 2: 1, + 3: 'X', + 4: -1, + 5: 'a', + 6: true, + 7: object, + 8: NaN, + 10: Infinity, + length: 11, + }; + + const expected = [ + Infinity, + undefined, + NaN, + object, + true, + 'a', + -1, + 'X', + 1, + 2, + undefined, + ]; + + assert.deepEqual(toReversed(array), expected, 'non-array target'); + + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.true(toReversed(array) instanceof Array, 'non-generic'); + + if (STRICT) { + assert.throws(() => toReversed(null, () => { /* empty */ }, 1), TypeError); + assert.throws(() => toReversed(undefined, () => { /* empty */ }, 1), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.to-sorted.js b/tests/unit-pure/es.array.to-sorted.js new file mode 100644 index 000000000000..6c98b2e43766 --- /dev/null +++ b/tests/unit-pure/es.array.to-sorted.js @@ -0,0 +1,134 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import toSorted from 'core-js-pure/es/array/to-sorted'; + +QUnit.test('Array#toSorted', assert => { + assert.isFunction(toSorted); + + let array = [1]; + assert.notSame(toSorted(array), array, 'immutable'); + assert.deepEqual(toSorted([1, 3, 2]), [1, 2, 3], '#1'); + assert.deepEqual(toSorted([1, 3, 2, 11]), [1, 11, 2, 3], '#2'); + assert.deepEqual(toSorted([1, -1, 3, NaN, 2, 0, 11, -0]), [-1, 0, -0, 1, 11, 2, 3, NaN], '#1'); + + array = Array(5); + array[0] = 1; + array[2] = 3; + array[4] = 2; + let expected = Array(5); + expected[0] = 1; + expected[1] = 2; + expected[2] = 3; + assert.deepEqual(toSorted(array), expected, 'holes'); + + array = 'zyxwvutsrqponMLKJIHGFEDCBA'.split(''); + expected = 'ABCDEFGHIJKLMnopqrstuvwxyz'.split(''); + assert.deepEqual(toSorted(array), expected, 'alpha #1'); + + array = 'ёяюэьыъщшчцхфутсрПОНМЛКЙИЗЖЕДГВБА'.split(''); + expected = 'АБВГДЕЖЗИЙКЛМНОПрстуфхцчшщъыьэюяё'.split(''); + assert.deepEqual(toSorted(array), expected, 'alpha #2'); + + array = [undefined, 1]; + assert.notThrows(() => array = toSorted(array, () => { throw 1; }), 'undefined #1'); + assert.deepEqual(array, [1, undefined], 'undefined #2'); + + /* Safari TP ~ 17.6 issue + const object = { + valueOf: () => 1, + toString: () => -1, + }; + + array = { + 0: undefined, + 1: 2, + 2: 1, + 3: 'X', + 4: -1, + 5: 'a', + 6: true, + 7: object, + 8: NaN, + 10: Infinity, + length: 11, + }; + + expected = [ + -1, + object, + 1, + 2, + Infinity, + NaN, + 'X', + 'a', + true, + undefined, + undefined, + ]; + + assert.deepEqual(toSorted(array), expected, 'non-array target'); + */ + + let index, mod, code, chr, value; + expected = Array(516); + array = Array(516); + + for (index = 0; index < 516; index++) { + mod = index % 4; + array[index] = 515 - index; + expected[index] = index - 2 * mod + 3; + } + + assert.arrayEqual(toSorted(array, (a, b) => (a / 4 | 0) - (b / 4 | 0)), expected, 'stable #1'); + + assert.true(1 / toSorted([0, -0])[0] > 0, '-0'); + + let result = ''; + array = []; + + // generate an array with more 512 elements (Chakra and old V8 fails only in this case) + for (code = 65; code < 76; code++) { + chr = String.fromCharCode(code); + + switch (code) { + case 66: case 69: case 70: case 72: value = 3; break; + case 68: case 71: value = 4; break; + default: value = 2; + } + + for (index = 0; index < 47; index++) { + array.push({ k: chr + index, v: value }); + } + } + + array = toSorted(array, (a, b) => b.v - a.v); + + for (index = 0; index < array.length; index++) { + chr = array[index].k.charAt(0); + if (result.charAt(result.length - 1) !== chr) result += chr; + } + + assert.same(result, 'DGBEFHACIJK', 'stable #2'); + + assert.notThrows(() => toSorted([1, 2, 3], undefined).length === 3, 'works with undefined'); + assert.throws(() => toSorted([1, 2, 3], null), 'throws on null'); + assert.throws(() => toSorted([1, 2, 3], {}), 'throws on {}'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => toSorted([Symbol(1), Symbol(2)]), 'w/o cmp throws on symbols'); + } + + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.true(toSorted(array) instanceof Array, 'non-generic'); + + if (STRICT) { + assert.throws(() => toSorted(null), TypeError, 'ToObject(this)'); + assert.throws(() => toSorted(undefined), TypeError, 'ToObject(this)'); + } +}); diff --git a/tests/unit-pure/es.array.to-spliced.js b/tests/unit-pure/es.array.to-spliced.js new file mode 100644 index 000000000000..12491c1af11e --- /dev/null +++ b/tests/unit-pure/es.array.to-spliced.js @@ -0,0 +1,28 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import toSpliced from 'core-js-pure/es/array/to-spliced'; + +QUnit.test('Array#toSpliced', assert => { + assert.isFunction(toSpliced); + + let array = [1, 2, 3, 4, 5]; + assert.notSame(toSpliced(array, 2), array); + assert.deepEqual(toSpliced([1, 2, 3, 4, 5], 2), [1, 2]); + assert.deepEqual(toSpliced([1, 2, 3, 4, 5], -2), [1, 2, 3]); + assert.deepEqual(toSpliced([1, 2, 3, 4, 5], 2, 2), [1, 2, 5]); + assert.deepEqual(toSpliced([1, 2, 3, 4, 5], 2, -2), [1, 2, 3, 4, 5]); + assert.deepEqual(toSpliced([1, 2, 3, 4, 5], 2, 2, 6, 7), [1, 2, 6, 7, 5]); + + if (STRICT) { + assert.throws(() => toSpliced(null), TypeError); + assert.throws(() => toSpliced(undefined), TypeError); + } + + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.true(toSpliced(array) instanceof Array, 'non-generic'); +}); diff --git a/tests/unit-pure/es.array.unshift.js b/tests/unit-pure/es.array.unshift.js new file mode 100644 index 000000000000..fac026c33afe --- /dev/null +++ b/tests/unit-pure/es.array.unshift.js @@ -0,0 +1,20 @@ +import { REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR, STRICT } from '../helpers/constants.js'; + +import unshift from 'core-js-pure/es/array/virtual/unshift'; +import defineProperty from 'core-js-pure/es/object/define-property'; + +QUnit.test('Array#unshift', assert => { + assert.isFunction(unshift); + + assert.same(unshift.call([1], 0), 2, 'proper result'); + + if (STRICT) { + if (REDEFINABLE_ARRAY_LENGTH_DESCRIPTOR) { + assert.throws(() => unshift.call(defineProperty([], 'length', { writable: false }), 1), TypeError, 'non-writable length, with arg'); + assert.throws(() => unshift.call(defineProperty([], 'length', { writable: false })), TypeError, 'non-writable length, without arg'); + } + + assert.throws(() => unshift.call(null), TypeError); + assert.throws(() => unshift.call(undefined), TypeError); + } +}); diff --git a/tests/unit-pure/es.array.with.js b/tests/unit-pure/es.array.with.js new file mode 100644 index 000000000000..3ac5441fc268 --- /dev/null +++ b/tests/unit-pure/es.array.with.js @@ -0,0 +1,34 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import withAt from 'core-js-pure/es/array/with'; + +QUnit.test('Array#with', assert => { + assert.isFunction(withAt); + + let array = [1, 2, 3, 4, 5]; + assert.notSame(withAt(array, 2, 1), array); + assert.deepEqual(withAt([1, 2, 3, 4, 5], 2, 6), [1, 2, 6, 4, 5]); + assert.deepEqual(withAt([1, 2, 3, 4, 5], -2, 6), [1, 2, 3, 6, 5]); + assert.deepEqual(withAt([1, 2, 3, 4, 5], '1', 6), [1, 6, 3, 4, 5]); + + assert.throws(() => withAt([1, 2, 3, 4, 5], 5, 6), RangeError); + assert.throws(() => withAt([1, 2, 3, 4, 5], -6, 6), RangeError); + + if (STRICT) { + assert.throws(() => withAt(null, 1, 2), TypeError); + assert.throws(() => withAt(undefined, 1, 2), TypeError); + } + + array = [1, 2]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.true(withAt(array, 1, 2) instanceof Array, 'non-generic'); + + // Incorrect exception thrown when index coercion fails in Firefox + function CustomError() { /* empty */ } + const index = { valueOf() { throw new CustomError(); } }; + assert.throws(() => withAt([], index, null), CustomError, 'incorrect error'); +}); diff --git a/tests/unit-pure/es.async-disposable-stack.constructor.js b/tests/unit-pure/es.async-disposable-stack.constructor.js new file mode 100644 index 000000000000..0309a1fcc100 --- /dev/null +++ b/tests/unit-pure/es.async-disposable-stack.constructor.js @@ -0,0 +1,202 @@ +import { STRICT } from '../helpers/constants.js'; + +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; +import AsyncDisposableStack from 'core-js-pure/es/async-disposable-stack'; +import SuppressedError from 'core-js-pure/es/suppressed-error'; + +QUnit.test('AsyncDisposableStack constructor', assert => { + assert.isFunction(AsyncDisposableStack); + assert.arity(AsyncDisposableStack, 0); + assert.name(AsyncDisposableStack, 'AsyncDisposableStack'); + assert.true(new AsyncDisposableStack() instanceof AsyncDisposableStack); + + assert.same(AsyncDisposableStack.prototype.constructor, AsyncDisposableStack); + + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing + assert.throws(() => AsyncDisposableStack(), 'throws w/o `new`'); +}); + +QUnit.test('AsyncDisposableStack#disposeAsync', assert => { + assert.isFunction(AsyncDisposableStack.prototype.disposeAsync); + assert.arity(AsyncDisposableStack.prototype.disposeAsync, 0); + assert.name(AsyncDisposableStack.prototype.disposeAsync, 'disposeAsync'); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'disposeAsync'); +}); + +QUnit.test('AsyncDisposableStack#use', assert => { + assert.isFunction(AsyncDisposableStack.prototype.use); + assert.arity(AsyncDisposableStack.prototype.use, 1); + assert.name(AsyncDisposableStack.prototype.use, 'use'); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'use'); + + let result = ''; + const stack = new AsyncDisposableStack(); + const resource = { + [Symbol.asyncDispose]() { + result += '1'; + assert.same(this, resource); + assert.same(arguments.length, 0); + }, + }; + + assert.same(stack.use(resource), resource); + + return stack.disposeAsync().then(it => { + assert.same(it, undefined); + assert.same(result, '1'); + }); +}); + +QUnit.test('AsyncDisposableStack#adopt', assert => { + assert.isFunction(AsyncDisposableStack.prototype.adopt); + assert.arity(AsyncDisposableStack.prototype.adopt, 2); + assert.name(AsyncDisposableStack.prototype.adopt, 'adopt'); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'adopt'); + + let result = ''; + const stack = new AsyncDisposableStack(); + const resource = {}; + + assert.same(stack.adopt(resource, function (arg) { + result += '1'; + if (STRICT) assert.same(this, undefined); + assert.same(arguments.length, 1); + assert.same(arg, resource); + }), resource); + + return stack.disposeAsync().then(it => { + assert.same(it, undefined); + assert.same(result, '1'); + }); +}); + +QUnit.test('AsyncDisposableStack#defer', assert => { + assert.isFunction(AsyncDisposableStack.prototype.defer); + assert.arity(AsyncDisposableStack.prototype.defer, 1); + assert.name(AsyncDisposableStack.prototype.defer, 'defer'); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'defer'); + + let result = ''; + const stack = new AsyncDisposableStack(); + + assert.same(stack.defer(function () { + result += '1'; + if (STRICT) assert.same(this, undefined); + assert.same(arguments.length, 0); + }), undefined); + + return stack.disposeAsync().then(it => { + assert.same(it, undefined); + assert.same(result, '1'); + }); +}); + +QUnit.test('AsyncDisposableStack#move', assert => { + assert.isFunction(AsyncDisposableStack.prototype.move); + assert.arity(AsyncDisposableStack.prototype.move, 0); + assert.name(AsyncDisposableStack.prototype.move, 'move'); + assert.nonEnumerable(AsyncDisposableStack.prototype, 'move'); + + let result = ''; + const stack1 = new AsyncDisposableStack(); + + stack1.defer(() => result += '2'); + stack1.defer(() => result += '1'); + + const stack2 = stack1.move(); + + assert.true(stack1.disposed); + + return stack2.disposeAsync().then(() => { + assert.same(result, '12'); + }); +}); + +QUnit.test('AsyncDisposableStack#@@asyncDispose', assert => { + assert.same(AsyncDisposableStack.prototype[Symbol.asyncDispose], AsyncDisposableStack.prototype.disposeAsync); +}); + +QUnit.test('AsyncDisposableStack#@@toStringTag', assert => { + assert.same(AsyncDisposableStack.prototype[Symbol.toStringTag], 'AsyncDisposableStack', '@@toStringTag'); +}); + +QUnit.test('AsyncDisposableStack#1', assert => { + let result = ''; + const stack = new AsyncDisposableStack(); + + stack.use({ [Symbol.asyncDispose]: () => result += '6' }); + stack.adopt({}, () => result += '5'); + stack.defer(() => result += '4'); + stack.use({ [Symbol.asyncDispose]: () => Promise.resolve(result += '3') }); + stack.adopt({}, () => Promise.resolve(result += '2')); + stack.defer(() => Promise.resolve(result += '1')); + + assert.false(stack.disposed); + + return stack.disposeAsync().then(it => { + assert.same(it, undefined); + assert.same(result, '123456'); + assert.true(stack.disposed); + return stack.disposeAsync(); + }).then(it => { + assert.same(it, undefined); + }); +}); + +QUnit.test('AsyncDisposableStack#2', assert => { + let result = ''; + const stack = new AsyncDisposableStack(); + + stack.use({ [Symbol.asyncDispose]: () => result += '6' }); + stack.adopt({}, () => { throw new Error(5); }); + stack.defer(() => result += '4'); + stack.use({ [Symbol.asyncDispose]: () => Promise.resolve(result += '3') }); + stack.adopt({}, () => Promise.resolve(result += '2')); + stack.defer(() => Promise.resolve(result += '1')); + + return stack.disposeAsync().then(() => { + assert.avoid(); + }, error => { + assert.same(result, '12346'); + assert.true(error instanceof Error); + assert.same(error.message, '5'); + }); +}); + +QUnit.test('AsyncDisposableStack#3', assert => { + let result = ''; + const stack = new AsyncDisposableStack(); + + stack.use({ [Symbol.asyncDispose]: () => result += '6' }); + stack.adopt({}, () => { throw new Error(5); }); + stack.defer(() => result += '4'); + stack.use({ [Symbol.asyncDispose]: () => Promise.reject(new Error(3)) }); + stack.adopt({}, () => Promise.resolve(result += '2')); + stack.defer(() => Promise.resolve(result += '1')); + + return stack.disposeAsync().then(() => { + assert.avoid(); + }, error => { + assert.same(result, '1246'); + assert.true(error instanceof SuppressedError); + assert.same(error.error.message, '5'); + assert.same(error.suppressed.message, '3'); + }); +}); + +// https://github.com/tc39/proposal-explicit-resource-management/issues/256 +QUnit.test('AsyncDisposableStack#256', assert => { + const resume = assert.async(); + assert.expect(1); + let called = false; + const stack = new AsyncDisposableStack(); + const neverResolves = new Promise(() => { /* empty */ }); + stack.use({ [Symbol.dispose]() { return neverResolves; } }); + stack.disposeAsync().then(() => { + called = true; + assert.required('It should be called'); + resume(); + }); + setTimeout(() => called || resume(), 3e3); +}); diff --git a/tests/unit-pure/es.async-iterator.async-dispose.js b/tests/unit-pure/es.async-iterator.async-dispose.js new file mode 100644 index 000000000000..ba2b50606deb --- /dev/null +++ b/tests/unit-pure/es.async-iterator.async-dispose.js @@ -0,0 +1,26 @@ +import AsyncIterator from 'core-js-pure/full/async-iterator'; +import Symbol from 'core-js-pure/es/symbol'; +import create from 'core-js-pure/es/object/create'; + +QUnit.test('AsyncIterator#@@asyncDispose', assert => { + const asyncDispose = AsyncIterator.prototype[Symbol.asyncDispose]; + assert.isFunction(asyncDispose); + assert.arity(asyncDispose, 0); + + return create(AsyncIterator.prototype)[Symbol.asyncDispose]().then(result => { + assert.same(result, undefined); + }).then(() => { + let called = false; + const iterator2 = create(AsyncIterator.prototype); + iterator2.return = function () { + called = true; + assert.same(this, iterator2); + return 7; + }; + + return iterator2[Symbol.asyncDispose]().then(result => { + assert.same(result, undefined); + assert.true(called); + }); + }); +}); diff --git a/tests/unit-pure/es.date.get-year.js b/tests/unit-pure/es.date.get-year.js new file mode 100644 index 000000000000..366509a2802a --- /dev/null +++ b/tests/unit-pure/es.date.get-year.js @@ -0,0 +1,7 @@ +import getYear from 'core-js-pure/es/date/get-year'; + +QUnit.test('Date#getYear', assert => { + assert.isFunction(getYear); + const date = new Date(); + assert.same(getYear(date), date.getFullYear() - 1900); +}); diff --git a/tests/unit-pure/es.date.now.js b/tests/unit-pure/es.date.now.js new file mode 100644 index 000000000000..9851ec12dba9 --- /dev/null +++ b/tests/unit-pure/es.date.now.js @@ -0,0 +1,6 @@ +import now from 'core-js-pure/es/date/now'; + +QUnit.test('Date.now', assert => { + assert.isFunction(now); + assert.same(typeof now(), 'number', 'typeof'); +}); diff --git a/tests/unit-pure/es.date.set-year.js b/tests/unit-pure/es.date.set-year.js new file mode 100644 index 000000000000..c26baa279139 --- /dev/null +++ b/tests/unit-pure/es.date.set-year.js @@ -0,0 +1,8 @@ +import setYear from 'core-js-pure/es/date/set-year'; + +QUnit.test('Date#setYear', assert => { + assert.isFunction(setYear); + const date = new Date(); + setYear(date, 1); + assert.same(date.getFullYear(), 1901); +}); diff --git a/tests/unit-pure/es.date.to-gmt-string.js b/tests/unit-pure/es.date.to-gmt-string.js new file mode 100644 index 000000000000..f2ca5b3dadfb --- /dev/null +++ b/tests/unit-pure/es.date.to-gmt-string.js @@ -0,0 +1,7 @@ +import toGMTString from 'core-js-pure/es/date/to-gmt-string'; + +QUnit.test('Date#toGMTString', assert => { + assert.isFunction(toGMTString); + const date = new Date(); + assert.same(toGMTString(date), date.toUTCString()); +}); diff --git a/tests/unit-pure/es.date.to-iso-string.js b/tests/unit-pure/es.date.to-iso-string.js new file mode 100644 index 000000000000..916630d88c7e --- /dev/null +++ b/tests/unit-pure/es.date.to-iso-string.js @@ -0,0 +1,15 @@ +import toISOString from 'core-js-pure/es/date/to-iso-string'; + +QUnit.test('Date#toISOString', assert => { + assert.isFunction(toISOString); + assert.same(toISOString(new Date(0)), '1970-01-01T00:00:00.000Z'); + assert.same(toISOString(new Date(1e12 + 1)), '2001-09-09T01:46:40.001Z'); + assert.same(toISOString(new Date(-5e13 - 1)), '0385-07-25T07:06:39.999Z'); + const future = toISOString(new Date(1e15 + 1)); + const properFuture = future === '+033658-09-27T01:46:40.001Z' || future === '33658-09-27T01:46:40.001Z'; + assert.true(properFuture); + const prehistoric = toISOString(new Date(-1e15 + 1)); + const properPrehistoric = prehistoric === '-029719-04-05T22:13:20.001Z' || prehistoric === '-29719-04-05T22:13:20.001Z'; + assert.true(properPrehistoric); + assert.throws(() => toISOString(new Date(NaN)), RangeError); +}); diff --git a/tests/pure/es.date.to-json.js b/tests/unit-pure/es.date.to-json.js similarity index 75% rename from tests/pure/es.date.to-json.js rename to tests/unit-pure/es.date.to-json.js index da7fbbf6c04f..53c3293d7252 100644 --- a/tests/pure/es.date.to-json.js +++ b/tests/unit-pure/es.date.to-json.js @@ -1,4 +1,5 @@ -import { toJSON, toISOString } from 'core-js-pure/features/date'; +import toISOString from 'core-js-pure/es/date/to-iso-string'; +import toJSON from 'core-js-pure/es/date/to-json'; QUnit.test('Date#toJSON', assert => { assert.isFunction(toJSON); diff --git a/tests/unit-pure/es.disposable-stack.constructor.js b/tests/unit-pure/es.disposable-stack.constructor.js new file mode 100644 index 000000000000..c031251b4b78 --- /dev/null +++ b/tests/unit-pure/es.disposable-stack.constructor.js @@ -0,0 +1,176 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import DisposableStack from 'core-js-pure/es/disposable-stack'; +import SuppressedError from 'core-js-pure/es/suppressed-error'; + +QUnit.test('DisposableStack constructor', assert => { + assert.isFunction(DisposableStack); + assert.arity(DisposableStack, 0); + assert.name(DisposableStack, 'DisposableStack'); + + assert.true(new DisposableStack() instanceof DisposableStack); + + assert.same(DisposableStack.prototype.constructor, DisposableStack); + + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing + assert.throws(() => DisposableStack(), 'throws w/o `new`'); +}); + +QUnit.test('DisposableStack#dispose', assert => { + assert.isFunction(DisposableStack.prototype.dispose); + assert.arity(DisposableStack.prototype.dispose, 0); + assert.name(DisposableStack.prototype.dispose, 'dispose'); + assert.nonEnumerable(DisposableStack.prototype, 'dispose'); +}); + +QUnit.test('DisposableStack#use', assert => { + assert.isFunction(DisposableStack.prototype.use); + assert.arity(DisposableStack.prototype.use, 1); + assert.name(DisposableStack.prototype.use, 'use'); + assert.nonEnumerable(DisposableStack.prototype, 'use'); + + let result = ''; + const stack = new DisposableStack(); + const resource = { + [Symbol.dispose]() { + result += '1'; + assert.same(this, resource); + assert.same(arguments.length, 0); + }, + }; + + assert.same(stack.use(resource), resource); + assert.same(stack.dispose(), undefined); + assert.same(result, '1'); +}); + +QUnit.test('DisposableStack#adopt', assert => { + assert.isFunction(DisposableStack.prototype.adopt); + assert.arity(DisposableStack.prototype.adopt, 2); + assert.name(DisposableStack.prototype.adopt, 'adopt'); + assert.nonEnumerable(DisposableStack.prototype, 'adopt'); + + let result = ''; + const stack = new DisposableStack(); + const resource = {}; + + assert.same(stack.adopt(resource, function (arg) { + result += '1'; + if (STRICT) assert.same(this, undefined); + assert.same(arguments.length, 1); + assert.same(arg, resource); + }), resource); + + assert.same(stack.dispose(), undefined); + assert.same(result, '1'); +}); + +QUnit.test('DisposableStack#defer', assert => { + assert.isFunction(DisposableStack.prototype.defer); + assert.arity(DisposableStack.prototype.defer, 1); + assert.name(DisposableStack.prototype.defer, 'defer'); + assert.nonEnumerable(DisposableStack.prototype, 'defer'); + + let result = ''; + const stack = new DisposableStack(); + + assert.same(stack.defer(function () { + result += '1'; + if (STRICT) assert.same(this, undefined); + assert.same(arguments.length, 0); + }), undefined); + + assert.same(stack.dispose(), undefined); + assert.same(result, '1'); +}); + +QUnit.test('DisposableStack#move', assert => { + assert.isFunction(DisposableStack.prototype.move); + assert.arity(DisposableStack.prototype.move, 0); + assert.name(DisposableStack.prototype.move, 'move'); + assert.nonEnumerable(DisposableStack.prototype, 'move'); + + let result = ''; + const stack1 = new DisposableStack(); + + stack1.defer(() => result += '2'); + stack1.defer(() => result += '1'); + + const stack2 = stack1.move(); + + assert.true(stack1.disposed); + + stack2.dispose(); + + assert.same(result, '12'); +}); + +QUnit.test('DisposableStack#@@dispose', assert => { + assert.same(DisposableStack.prototype[Symbol.dispose], DisposableStack.prototype.dispose); +}); + +QUnit.test('DisposableStack#@@toStringTag', assert => { + assert.same(DisposableStack.prototype[Symbol.toStringTag], 'DisposableStack', '@@toStringTag'); +}); + +QUnit.test('DisposableStack', assert => { + let result1 = ''; + const stack1 = new DisposableStack(); + + stack1.use({ [Symbol.dispose]: () => result1 += '6' }); + stack1.adopt({}, () => result1 += '5'); + stack1.defer(() => result1 += '4'); + stack1.use({ [Symbol.dispose]: () => result1 += '3' }); + stack1.adopt({}, () => result1 += '2'); + stack1.defer(() => result1 += '1'); + + assert.false(stack1.disposed); + assert.same(stack1.dispose(), undefined); + assert.same(result1, '123456'); + assert.true(stack1.disposed); + assert.same(stack1.dispose(), undefined); + + let result2 = ''; + const stack2 = new DisposableStack(); + let error2; + + stack2.use({ [Symbol.dispose]: () => result2 += '6' }); + stack2.adopt({}, () => { throw new Error(5); }); + stack2.defer(() => result2 += '4'); + stack2.use({ [Symbol.dispose]: () => result2 += '3' }); + stack2.adopt({}, () => result2 += '2'); + stack2.defer(() => result2 += '1'); + + try { + stack2.dispose(); + } catch (error2$) { + error2 = error2$; + } + + assert.same(result2, '12346'); + assert.true(error2 instanceof Error); + assert.same(error2.message, '5'); + + let result3 = ''; + const stack3 = new DisposableStack(); + let error3; + + stack3.use({ [Symbol.dispose]: () => result3 += '6' }); + stack3.adopt({}, () => { throw new Error(5); }); + stack3.defer(() => result3 += '4'); + stack3.use({ [Symbol.dispose]: () => { throw new Error(3); } }); + stack3.adopt({}, () => result3 += '2'); + stack3.defer(() => result3 += '1'); + + try { + stack3.dispose(); + } catch (error3$) { + error3 = error3$; + } + + assert.same(result3, '1246'); + assert.true(error3 instanceof SuppressedError); + assert.same(error3.error.message, '5'); + assert.same(error3.suppressed.message, '3'); +}); diff --git a/tests/unit-pure/es.error.cause.js b/tests/unit-pure/es.error.cause.js new file mode 100644 index 000000000000..6ae2aaee7d81 --- /dev/null +++ b/tests/unit-pure/es.error.cause.js @@ -0,0 +1,54 @@ +/* eslint-disable sonarjs/inconsistent-function-call -- required for testing */ +import { PROTO } from '../helpers/constants.js'; + +import path from 'core-js-pure/es/error'; +import create from 'core-js-pure/es/object/create'; + +function runErrorTestCase($Error, ERROR_NAME, WEB_ASSEMBLY) { + QUnit.test(`${ ERROR_NAME } constructor with 'cause' param`, assert => { + assert.isFunction($Error); + assert.arity($Error, 1); + assert.name($Error, ERROR_NAME); + + if (PROTO && $Error !== path.Error) { + // eslint-disable-next-line no-prototype-builtins -- safe + assert.true(path.Error.isPrototypeOf($Error), 'constructor has `Error` in the prototype chain'); + } + + assert.true($Error(1) instanceof $Error, 'no cause, without new'); + assert.true(new $Error(1) instanceof $Error, 'no cause, with new'); + + assert.true($Error(1, {}) instanceof $Error, 'with options, without new'); + assert.true(new $Error(1, {}) instanceof $Error, 'with options, with new'); + + assert.true($Error(1, 'foo') instanceof $Error, 'non-object options, without new'); + assert.true(new $Error(1, 'foo') instanceof $Error, 'non-object options, with new'); + + assert.same($Error(1, { cause: 7 }).cause, 7, 'cause, without new'); + assert.same(new $Error(1, { cause: 7 }).cause, 7, 'cause, with new'); + + assert.same($Error(1, create({ cause: 7 })).cause, 7, 'prototype cause, without new'); + assert.same(new $Error(1, create({ cause: 7 })).cause, 7, 'prototype cause, with new'); + + let error = $Error(1, { cause: 7 }); + if (!WEB_ASSEMBLY) assert.same(error.name, ERROR_NAME, 'instance name'); + assert.same(error.message, '1', 'instance message'); + assert.same(error.cause, 7, 'instance cause'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.true(error.hasOwnProperty('cause'), 'cause is own'); + + error = $Error(); + assert.same(error.message, '', 'default instance message'); + assert.same(error.cause, undefined, 'default instance cause undefined'); + // eslint-disable-next-line no-prototype-builtins -- safe + assert.false(error.hasOwnProperty('cause'), 'default instance cause missed'); + }); +} + +for (const ERROR_NAME of ['Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError']) { + runErrorTestCase(path[ERROR_NAME], ERROR_NAME); +} + +if (path.WebAssembly) for (const ERROR_NAME of ['CompileError', 'LinkError', 'RuntimeError']) { + if (path.WebAssembly[ERROR_NAME]) runErrorTestCase(path.WebAssembly[ERROR_NAME], ERROR_NAME, true); +} diff --git a/tests/unit-pure/es.error.is-error.js b/tests/unit-pure/es.error.is-error.js new file mode 100644 index 000000000000..3d7f68ba902b --- /dev/null +++ b/tests/unit-pure/es.error.is-error.js @@ -0,0 +1,21 @@ +import isError from 'core-js-pure/es/error/is-error'; +import create from 'core-js-pure/es/object/create'; +import AggregateError from 'core-js-pure/es/aggregate-error'; +import SuppressedError from 'core-js-pure/actual/suppressed-error'; +import DOMException from 'core-js-pure/stable/dom-exception'; + +QUnit.test('Error.isError', assert => { + assert.isFunction(isError); + assert.arity(isError, 1); + assert.name(isError, 'isError'); + + assert.true(isError(new Error('error'))); + assert.true(isError(new TypeError('error'))); + assert.true(isError(new AggregateError([1, 2, 3], 'error'))); + assert.true(isError(new SuppressedError(1, 2, 'error'))); + assert.true(isError(new DOMException('error'))); + + assert.false(isError(null)); + assert.false(isError({})); + assert.false(isError(create(Error.prototype))); +}); diff --git a/tests/unit-pure/es.escape.js b/tests/unit-pure/es.escape.js new file mode 100644 index 000000000000..1f97d92054d0 --- /dev/null +++ b/tests/unit-pure/es.escape.js @@ -0,0 +1,14 @@ +import escape from 'core-js-pure/es/escape'; + +QUnit.test('escape', assert => { + assert.isFunction(escape); + assert.arity(escape, 1); + assert.same(escape('!q2ф'), '%21q2%u0444'); + assert.same(escape(null), 'null'); + assert.same(escape(undefined), 'undefined'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => escape(Symbol('escape test')), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-pure/es.function.bind.js b/tests/unit-pure/es.function.bind.js new file mode 100644 index 000000000000..895975b478ed --- /dev/null +++ b/tests/unit-pure/es.function.bind.js @@ -0,0 +1,26 @@ +import bind from 'core-js-pure/es/function/bind'; + +QUnit.test('Function#bind', assert => { + assert.isFunction(bind); + const object = { a: 42 }; + assert.same(bind(function () { + return this.a; + }, object)(), 42); + assert.same(new (bind(() => { /* empty */ }, object))().a, undefined); + function C(a, b) { + this.a = a; + this.b = b; + } + const instance = new (bind(C, null, 1))(2); + assert.true(instance instanceof C); + assert.same(instance.a, 1); + assert.same(instance.b, 2); + assert.same(bind((it => it), null, 42)(), 42); + const regExpTest = bind(RegExp.prototype.test, /a/); + assert.true(regExpTest('a')); + const Date2017 = bind(Date, null, 2017); + const date = new Date2017(11); + assert.true(date instanceof Date); + assert.same(date.getFullYear(), 2017); + assert.same(date.getMonth(), 11); +}); diff --git a/tests/unit-pure/es.function.has-instance.js b/tests/unit-pure/es.function.has-instance.js new file mode 100644 index 000000000000..ab9bc3097bb4 --- /dev/null +++ b/tests/unit-pure/es.function.has-instance.js @@ -0,0 +1,7 @@ +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Function#@@hasInstance', assert => { + assert.true(Symbol.hasInstance in Function.prototype); + assert.true(Function[Symbol.hasInstance](() => { /* empty */ })); + assert.false(Function[Symbol.hasInstance]({})); +}); diff --git a/tests/unit-pure/es.global-this.js b/tests/unit-pure/es.global-this.js new file mode 100644 index 000000000000..8a60670b682e --- /dev/null +++ b/tests/unit-pure/es.global-this.js @@ -0,0 +1,6 @@ +import globalThis from 'core-js-pure/es/global-this'; + +QUnit.test('globalThis', assert => { + assert.same(globalThis, Object(globalThis), 'is object'); + assert.same(globalThis.Math, Math, 'contains globals'); +}); diff --git a/tests/unit-pure/es.iterator.concat.js b/tests/unit-pure/es.iterator.concat.js new file mode 100644 index 000000000000..fccbd679bf6f --- /dev/null +++ b/tests/unit-pure/es.iterator.concat.js @@ -0,0 +1,98 @@ +import { createIterable, createIterator } from '../helpers/helpers.js'; + +import concat from 'core-js-pure/es/iterator/concat'; +import Iterator from 'core-js-pure/es/iterator'; +import Symbol from 'core-js-pure/es/symbol'; +import from from 'core-js-pure/es/array/from'; + +QUnit.test('Iterator.concat', assert => { + assert.isFunction(concat); + assert.arity(concat, 0); + assert.name(concat, 'concat'); + + let iterator = concat(); + assert.isIterable(iterator, 'iterable, no args'); + assert.isIterator(iterator, 'iterator, no args'); + assert.true(iterator instanceof Iterator, 'iterator instance, no args'); + assert.arrayEqual(from(iterator), [], 'proper values, no args'); + + iterator = concat([1, 2, 3]); + assert.isIterable(iterator, 'iterable, array'); + assert.isIterator(iterator, 'iterator, array'); + assert.true(iterator instanceof Iterator, 'iterator instance, array'); + assert.arrayEqual(from(iterator), [1, 2, 3], 'proper values, array'); + + iterator = concat([]); + assert.isIterable(iterator, 'iterable, empty array'); + assert.isIterator(iterator, 'iterator, empty array'); + assert.true(iterator instanceof Iterator, 'iterator instance, empty array'); + assert.arrayEqual(from(iterator), [], 'proper values, empty array'); + + iterator = concat(createIterable([1, 2, 3])); + assert.isIterable(iterator, 'iterable, custom iterable'); + assert.isIterator(iterator, 'iterator, custom iterable'); + assert.true(iterator instanceof Iterator, 'iterator instance, custom iterable'); + assert.arrayEqual(from(iterator), [1, 2, 3], 'proper values, custom iterable'); + + iterator = concat([1, 2, 3], [], createIterable([4, 5, 6]), createIterable([])); + assert.isIterable(iterator, 'iterable, mixed'); + assert.isIterator(iterator, 'iterator, mixed'); + assert.true(iterator instanceof Iterator, 'iterator instance, mixed'); + assert.arrayEqual(from(iterator), [1, 2, 3, 4, 5, 6], 'proper values, mixed'); + + iterator = concat(createIterable([1, 2, 3])); + iterator.next(); + assert.deepEqual(iterator.return(), { done: true, value: undefined }, '.return with no active inner iterator result'); + assert.deepEqual(iterator.next(), { done: true, value: undefined }, '.return with no active inner iterator result on closed iterator'); + + iterator = concat(createIterable([1, 2, 3])); + assert.deepEqual(iterator.next(), { done: false, value: 1 }, '.next with active inner iterator result'); + assert.deepEqual(iterator.return(), { done: true, value: undefined }, '.return with active inner iterator result'); + assert.deepEqual(iterator.next(), { done: true, value: undefined }, '.return with active inner iterator result on closed iterator'); + + let called = false; + iterator = concat(createIterable([1, 2, 3], { + return() { + called = true; + return {}; + }, + })); + iterator.next(); + assert.deepEqual(iterator.return(), { done: true, value: undefined }, '.return with active inner iterator with return result'); + assert.true(called, 'inner .return called'); + + // https://github.com/tc39/proposal-iterator-sequencing/issues/17 + const oldIterResult = { + done: false, + value: 123, + }; + const testIterator = { + next() { + return oldIterResult; + }, + }; + const iterable = { + [Symbol.iterator]() { + return testIterator; + }, + }; + iterator = concat(iterable); + const iterResult = iterator.next(); + assert.same(iterResult.done, false); + assert.same(iterResult.value, 123); + // https://github.com/tc39/proposal-iterator-sequencing/pull/26 + assert.notSame(iterResult, oldIterResult); + + assert.throws(() => concat(createIterator([1, 2, 3])), TypeError, 'non-iterable iterator #1'); + assert.throws(() => concat([], createIterator([1, 2, 3])), TypeError, 'non-iterable iterator #2'); + assert.throws(() => concat(''), TypeError, 'iterable non-object argument #1'); + assert.throws(() => concat([], ''), TypeError, 'iterable non-object argument #2'); + assert.throws(() => concat(undefined), TypeError, 'non-iterable-object argument #1'); + assert.throws(() => concat(null), TypeError, 'non-iterable-object argument #2'); + assert.throws(() => concat(1), TypeError, 'non-iterable-object argument #3'); + assert.throws(() => concat({}), TypeError, 'non-iterable-object argument #4'); + assert.throws(() => concat([], undefined), TypeError, 'non-iterable-object argument #5'); + assert.throws(() => concat([], null), TypeError, 'non-iterable-object argument #6'); + assert.throws(() => concat([], 1), TypeError, 'non-iterable-object argument #7'); + assert.throws(() => concat([], {}), TypeError, 'non-iterable-object argument #8'); +}); diff --git a/tests/unit-pure/es.iterator.constructor.js b/tests/unit-pure/es.iterator.constructor.js new file mode 100644 index 000000000000..237e96c0253f --- /dev/null +++ b/tests/unit-pure/es.iterator.constructor.js @@ -0,0 +1,28 @@ +import { createIterator, nativeSubclass } from '../helpers/helpers.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator', assert => { + assert.isFunction(Iterator); + assert.arity(Iterator, 0); + + assert.true(Iterator.from(createIterator([1, 2, 3])) instanceof Iterator, 'From Proxy'); + + if (nativeSubclass) { + const Sub = nativeSubclass(Iterator); + assert.true(new Sub() instanceof Iterator, 'abstract constructor'); + } + + assert.throws(() => new Iterator(), 'direct constructor throws'); + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing + assert.throws(() => Iterator(), 'throws w/o `new`'); +}); + +QUnit.test('Iterator#constructor', assert => { + assert.same(Iterator.prototype.constructor, Iterator, 'Iterator#constructor is Iterator'); +}); + +QUnit.test('Iterator#@@toStringTag', assert => { + assert.same(Iterator.prototype[Symbol.toStringTag], 'Iterator', 'Iterator::@@toStringTag is `Iterator`'); +}); diff --git a/tests/unit-pure/es.iterator.dispose.js b/tests/unit-pure/es.iterator.dispose.js new file mode 100644 index 000000000000..be6a485d8a2c --- /dev/null +++ b/tests/unit-pure/es.iterator.dispose.js @@ -0,0 +1,21 @@ +import Iterator from 'core-js-pure/es/iterator'; +import Symbol from 'core-js-pure/es/symbol'; +import create from 'core-js-pure/es/object/create'; + +QUnit.test('Iterator#@@dispose', assert => { + const dispose = Iterator.prototype[Symbol.dispose]; + assert.isFunction(dispose); + assert.arity(dispose, 0); + + assert.same(create(Iterator.prototype)[Symbol.dispose](), undefined); + + let called = false; + const iterator2 = create(Iterator.prototype); + iterator2.return = function () { + called = true; + assert.same(this, iterator2); + return 7; + }; + assert.same(iterator2[Symbol.dispose](), undefined); + assert.true(called); +}); diff --git a/tests/unit-pure/es.iterator.drop.js b/tests/unit-pure/es.iterator.drop.js new file mode 100644 index 000000000000..28ffaa532ed6 --- /dev/null +++ b/tests/unit-pure/es.iterator.drop.js @@ -0,0 +1,31 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#drop', assert => { + const { drop } = Iterator.prototype; + + assert.isFunction(drop); + assert.arity(drop, 1); + assert.nonEnumerable(Iterator.prototype, 'drop'); + + assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 1).toArray(), [2, 3], 'basic functionality'); + assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 1.5).toArray(), [2, 3], 'float'); + assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 4).toArray(), [], 'big'); + assert.arrayEqual(drop.call(createIterator([1, 2, 3]), 0).toArray(), [1, 2, 3], 'zero'); + + if (STRICT) { + assert.throws(() => drop.call(undefined, 1), TypeError); + assert.throws(() => drop.call(null, 1), TypeError); + } + + assert.throws(() => drop.call({}, 1).next(), TypeError); + assert.throws(() => drop.call([], 1).next(), TypeError); + assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => drop.call(it, NaN), RangeError, 'NaN'); + assert.true(it.closed, "drop doesn't close iterator on validation error"); + // https://issues.chromium.org/issues/336839115 + assert.throws(() => drop.call({ next: null }, 0).next(), TypeError); +}); diff --git a/tests/unit-pure/es.iterator.every.js b/tests/unit-pure/es.iterator.every.js new file mode 100644 index 000000000000..c4e9e15270f7 --- /dev/null +++ b/tests/unit-pure/es.iterator.every.js @@ -0,0 +1,34 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#every', assert => { + const { every } = Iterator.prototype; + + assert.isFunction(every); + assert.arity(every, 1); + assert.nonEnumerable(Iterator.prototype, 'every'); + + assert.true(every.call(createIterator([1, 2, 3]), it => typeof it == 'number'), 'basic functionality #1'); + assert.false(every.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #2'); + every.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => every.call([], () => { /* empty */ }), TypeError); + assert.throws(() => every.call(createIterator([1]), undefined), TypeError); + assert.throws(() => every.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => every.call(it, {}), TypeError); + assert.true(it.closed, "every doesn't close iterator on validation error"); +}); diff --git a/tests/unit-pure/es.iterator.filter.js b/tests/unit-pure/es.iterator.filter.js new file mode 100644 index 000000000000..27059025c2c3 --- /dev/null +++ b/tests/unit-pure/es.iterator.filter.js @@ -0,0 +1,35 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#filter', assert => { + const { filter } = Iterator.prototype; + + assert.isFunction(filter); + assert.arity(filter, 1); + assert.nonEnumerable(Iterator.prototype, 'filter'); + + assert.arrayEqual(filter.call(createIterator([1, 2, 3]), it => it % 2).toArray(), [1, 3], 'basic functionality'); + filter.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }).toArray(); + + if (STRICT) { + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => filter.call({}, () => { /* empty */ }).next(), TypeError); + assert.throws(() => filter.call([], () => { /* empty */ }).next(), TypeError); + assert.throws(() => filter.call(createIterator([1]), undefined), TypeError); + assert.throws(() => filter.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => filter.call(it, {}), TypeError); + assert.true(it.closed, "filter doesn't close iterator on validation error"); + // https://issues.chromium.org/issues/336839115 + assert.throws(() => filter.call({ next: null }, () => { /* empty */ }).next(), TypeError); +}); diff --git a/tests/unit-pure/es.iterator.find.js b/tests/unit-pure/es.iterator.find.js new file mode 100644 index 000000000000..9a021dbd80df --- /dev/null +++ b/tests/unit-pure/es.iterator.find.js @@ -0,0 +1,33 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#find', assert => { + const { find } = Iterator.prototype; + + assert.isFunction(find); + assert.arity(find, 1); + assert.nonEnumerable(Iterator.prototype, 'find'); + + assert.same(find.call(createIterator([1, 2, 3]), it => !(it % 2)), 2, 'basic functionality'); + find.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => find.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => find.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => find.call([], () => { /* empty */ }), TypeError); + assert.throws(() => find.call(createIterator([1]), undefined), TypeError); + assert.throws(() => find.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => find.call(it, {}), TypeError); + assert.true(it.closed, "find doesn't close iterator on validation error"); +}); diff --git a/tests/unit-pure/es.iterator.flat-map.js b/tests/unit-pure/es.iterator.flat-map.js new file mode 100644 index 000000000000..a9bd9ff5b5d5 --- /dev/null +++ b/tests/unit-pure/es.iterator.flat-map.js @@ -0,0 +1,41 @@ +import { createIterator, createIterable } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#flatMap', assert => { + const { flatMap } = Iterator.prototype; + + assert.isFunction(flatMap); + assert.arity(flatMap, 1); + assert.nonEnumerable(Iterator.prototype, 'flatMap'); + + assert.arrayEqual( + flatMap.call(createIterator([1, [], 2, createIterable([3, 4]), [5, 6]]), it => typeof it == 'number' ? [-it] : it).toArray(), + [-1, -2, 3, 4, 5, 6], + 'basic functionality', + ); + flatMap.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + return [arg]; + }).toArray(); + + if (STRICT) { + assert.throws(() => flatMap.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => flatMap.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => flatMap.call(createIterator([1]), it => it).next(), TypeError); + assert.throws(() => flatMap.call({}, () => { /* empty */ }).next(), TypeError); + assert.throws(() => flatMap.call([], () => { /* empty */ }).next(), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), undefined), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => flatMap.call(it, {}), TypeError); + assert.true(it.closed, "flatMap doesn't close iterator on validation error"); + // https://issues.chromium.org/issues/336839115 + assert.throws(() => flatMap.call({ next: null }, () => { /* empty */ }).next(), TypeError); +}); diff --git a/tests/unit-pure/es.iterator.for-each.js b/tests/unit-pure/es.iterator.for-each.js new file mode 100644 index 000000000000..d52eebbcece9 --- /dev/null +++ b/tests/unit-pure/es.iterator.for-each.js @@ -0,0 +1,38 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#forEach', assert => { + const { forEach } = Iterator.prototype; + + assert.isFunction(forEach); + assert.arity(forEach, 1); + assert.nonEnumerable(Iterator.prototype, 'forEach'); + + const array = []; + + forEach.call(createIterator([1, 2, 3]), it => array.push(it)); + + assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); + + forEach.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => forEach.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => forEach.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => forEach.call([], () => { /* empty */ }), TypeError); + assert.throws(() => forEach.call(createIterator([1]), undefined), TypeError); + assert.throws(() => forEach.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => forEach.call(it, {}), TypeError); + assert.true(it.closed, "forEach doesn't close iterator on validation error"); +}); diff --git a/tests/unit-pure/es.iterator.from.js b/tests/unit-pure/es.iterator.from.js new file mode 100644 index 000000000000..45ff614591b7 --- /dev/null +++ b/tests/unit-pure/es.iterator.from.js @@ -0,0 +1,29 @@ +import { createIterable, createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/es/iterator'; +import assign from 'core-js-pure/es/object/assign'; + +QUnit.test('Iterator.from', assert => { + const { from } = Iterator; + + assert.isFunction(from); + assert.arity(from, 1); + + assert.true(Iterator.from(createIterator([1, 2, 3])) instanceof Iterator, 'proxy, iterator'); + + assert.true(Iterator.from(createIterable([1, 2, 3])) instanceof Iterator, 'proxy, iterable'); + + assert.arrayEqual(Iterator.from(createIterable([1, 2, 3])).toArray(), [1, 2, 3], 'just a proxy'); + + assert.throws(() => from(undefined), TypeError); + assert.throws(() => from(null), TypeError); + assert.throws(() => from({}).next(), TypeError); + assert.throws(() => from(assign(new Iterator(), { next: 42 })).next(), TypeError); + + // Should not throw when an underlying iterator's `return` method is null + // https://bugs.webkit.org/show_bug.cgi?id=288714 + const iterator = createIterator([], { return: null }); + const result = from(iterator).return('ignored'); + assert.true(result.done, 'iterator with null next #1'); + assert.strictEqual(result.value, undefined, 'iterator with null next #2'); +}); diff --git a/tests/unit-pure/es.iterator.map.js b/tests/unit-pure/es.iterator.map.js new file mode 100644 index 000000000000..f90af42764bc --- /dev/null +++ b/tests/unit-pure/es.iterator.map.js @@ -0,0 +1,35 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#map', assert => { + const { map } = Iterator.prototype; + + assert.isFunction(map); + assert.arity(map, 1); + assert.nonEnumerable(Iterator.prototype, 'map'); + + assert.arrayEqual(map.call(createIterator([1, 2, 3]), it => it ** 2).toArray(), [1, 4, 9], 'basic functionality'); + map.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }).toArray(); + + if (STRICT) { + assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => map.call({}, () => { /* empty */ }).next(), TypeError); + assert.throws(() => map.call([], () => { /* empty */ }).next(), TypeError); + assert.throws(() => map.call(createIterator([1]), undefined), TypeError); + assert.throws(() => map.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => map.call(it, {}), TypeError); + assert.true(it.closed, "map doesn't close iterator on validation error"); + // https://issues.chromium.org/issues/336839115 + assert.throws(() => map.call({ next: null }, () => { /* empty */ }).next(), TypeError); +}); diff --git a/tests/unit-pure/es.iterator.reduce.js b/tests/unit-pure/es.iterator.reduce.js new file mode 100644 index 000000000000..2e645df8f9be --- /dev/null +++ b/tests/unit-pure/es.iterator.reduce.js @@ -0,0 +1,37 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#reduce', assert => { + const { reduce } = Iterator.prototype; + + assert.isFunction(reduce); + assert.arity(reduce, 1); + assert.nonEnumerable(Iterator.prototype, 'reduce'); + + assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1), 7, 'basic functionality'); + assert.same(reduce.call(createIterator([1, 2, 3]), (a, b) => a + b), 6, 'basic functionality, no init'); + reduce.call(createIterator([2]), function (a, b, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 3, 'arguments length'); + assert.same(a, 1, 'argument 1'); + assert.same(b, 2, 'argument 2'); + assert.same(counter, 0, 'counter'); + }, 1); + + if (STRICT) { + assert.throws(() => reduce.call(undefined, (a, b) => a + b, 0), TypeError); + assert.throws(() => reduce.call(null, (a, b) => a + b, 0), TypeError); + } + + assert.throws(() => reduce.call({}, (a, b) => a + b, 0), TypeError); + assert.throws(() => reduce.call([], (a, b) => a + b, 0), TypeError); + assert.throws(() => reduce.call(createIterator([1]), undefined, 1), TypeError); + assert.throws(() => reduce.call(createIterator([1]), null, 1), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => reduce.call(it, {}, 1), TypeError); + assert.true(it.closed, "reduce doesn't close iterator on validation error"); + assert.notThrows(() => reduce.call(createIterator([]), () => false, undefined), 'fails on undefined initial parameter'); + assert.same(reduce.call(createIterator([]), () => false, undefined), undefined, 'incorrect result on undefined initial parameter'); +}); diff --git a/tests/unit-pure/es.iterator.some.js b/tests/unit-pure/es.iterator.some.js new file mode 100644 index 000000000000..e517844cb8e2 --- /dev/null +++ b/tests/unit-pure/es.iterator.some.js @@ -0,0 +1,35 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#some', assert => { + const { some } = Iterator.prototype; + + assert.isFunction(some); + assert.arity(some, 1); + assert.nonEnumerable(Iterator.prototype, 'some'); + + assert.true(some.call(createIterator([1, 2, 3]), it => it % 2), 'basic functionality #1'); + assert.false(some.call(createIterator([1, 2, 3]), it => typeof it == 'string'), 'basic functionality #2'); + some.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + + if (STRICT) { + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => some.call([], () => { /* empty */ }), TypeError); + assert.throws(() => some.call(createIterator([1]), undefined), TypeError); + assert.throws(() => some.call(createIterator([1]), null), TypeError); + assert.throws(() => some.call(createIterator([1]), null), TypeError); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => some.call(it, {}), TypeError); + assert.true(it.closed, "some doesn't close iterator on validation error"); +}); diff --git a/tests/unit-pure/es.iterator.take.js b/tests/unit-pure/es.iterator.take.js new file mode 100644 index 000000000000..46207a20117c --- /dev/null +++ b/tests/unit-pure/es.iterator.take.js @@ -0,0 +1,29 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#take', assert => { + const { take } = Iterator.prototype; + + assert.isFunction(take); + assert.arity(take, 1); + assert.nonEnumerable(Iterator.prototype, 'take'); + + assert.arrayEqual(take.call(createIterator([1, 2, 3]), 2).toArray(), [1, 2], 'basic functionality'); + assert.arrayEqual(take.call(createIterator([1, 2, 3]), 1.5).toArray(), [1], 'float'); + assert.arrayEqual(take.call(createIterator([1, 2, 3]), 4).toArray(), [1, 2, 3], 'big'); + assert.arrayEqual(take.call(createIterator([1, 2, 3]), 0).toArray(), [], 'zero'); + + if (STRICT) { + assert.throws(() => take.call(undefined, 1), TypeError); + assert.throws(() => take.call(null, 1), TypeError); + } + + assert.throws(() => take.call({}, 1).next(), TypeError); + assert.throws(() => take.call([], 1).next(), TypeError); + assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + const it = createIterator([1], { return() { this.closed = true; } }); + assert.throws(() => take.call(it, NaN), RangeError, 'NaN'); + assert.true(it.closed, "take doesn't close iterator on validation error"); +}); diff --git a/tests/unit-pure/es.iterator.to-array.js b/tests/unit-pure/es.iterator.to-array.js new file mode 100644 index 000000000000..d4bb8de23277 --- /dev/null +++ b/tests/unit-pure/es.iterator.to-array.js @@ -0,0 +1,25 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterable, createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/es/iterator'; + +QUnit.test('Iterator#toArray', assert => { + const { toArray } = Iterator.prototype; + + assert.isFunction(toArray); + assert.arity(toArray, 0); + assert.nonEnumerable(Iterator.prototype, 'toArray'); + + assert.arrayEqual(Iterator.from('123').toArray(), ['1', '2', '3']); + assert.arrayEqual(Iterator.from(createIterable([1, 2, 3])).toArray(), [1, 2, 3]); + + assert.arrayEqual(toArray.call(createIterator([1, 2, 3])), [1, 2, 3]); + + if (STRICT) { + assert.throws(() => toArray.call(undefined), TypeError); + assert.throws(() => toArray.call(null), TypeError); + } + + assert.throws(() => toArray.call({}), TypeError); + assert.throws(() => toArray.call([]), TypeError); +}); diff --git a/tests/unit-pure/es.json.is-raw-json.js b/tests/unit-pure/es.json.is-raw-json.js new file mode 100644 index 000000000000..0b722c64768c --- /dev/null +++ b/tests/unit-pure/es.json.is-raw-json.js @@ -0,0 +1,22 @@ +import isRawJSON from 'core-js-pure/es/json/is-raw-json'; +import rawJSON from 'core-js-pure/es/json/raw-json'; +import freeze from 'core-js-pure/es/object/freeze'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('JSON.rawJSON', assert => { + assert.isFunction(isRawJSON); + assert.arity(isRawJSON, 1); + assert.name(isRawJSON, 'isRawJSON'); + + assert.true(isRawJSON(rawJSON(1)), 'raw1'); + assert.true(isRawJSON(rawJSON(null)), 'raw2'); + assert.false(isRawJSON(freeze({ rawJSON: '123' })), 'fake'); + assert.false(isRawJSON(undefined), 'undefined'); + assert.false(isRawJSON(null), 'null'); + assert.false(isRawJSON(1), 'number'); + assert.false(isRawJSON('qwe'), 'string'); + assert.false(isRawJSON(true), 'bool'); + assert.false(isRawJSON(Symbol('JSON.isRawJSON test')), 'sym'); + assert.false(isRawJSON({}), 'object'); + assert.false(isRawJSON([]), 'array'); +}); diff --git a/tests/unit-pure/es.json.parse.js b/tests/unit-pure/es.json.parse.js new file mode 100644 index 000000000000..4281150495f5 --- /dev/null +++ b/tests/unit-pure/es.json.parse.js @@ -0,0 +1,259 @@ +// Some tests adopted from Test262 project and governed by the BSD license. +// Copyright (c) 2012 Ecma International. All rights reserved. +/* eslint-disable unicorn/escape-case -- testing */ +import { DESCRIPTORS, REDEFINABLE_PROTO } from '../helpers/constants.js'; +import parse from 'core-js-pure/es/json/parse'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import hasOwn from 'core-js-pure/es/object/has-own'; +import keys from 'core-js-pure/es/object/keys'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('JSON.parse', assert => { + assert.isFunction(parse); + assert.arity(parse, 2); + assert.name(parse, 'parse'); + + for (const [reviver, note] of [[undefined, 'without reviver'], [(key, value) => value, 'with reviver']]) { + assert.throws(() => parse('12\t\r\n 34', reviver), SyntaxError, `15.12.1.1-0-1 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.throws(() => parse('\u000b1234', reviver), SyntaxError, `15.12.1.1-0-2 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\u000c1234', reviver), SyntaxError, `15.12.1.1-0-3 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\u00a01234', reviver), SyntaxError, `15.12.1.1-0-4 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\u200b1234', reviver), SyntaxError, `15.12.1.1-0-5 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\ufeff1234', reviver), SyntaxError, `15.12.1.1-0-6 ${ note }`); // should produce a syntax error + assert.throws(() => parse('\u2028\u20291234', reviver), SyntaxError, `15.12.1.1-0-8 ${ note }`); // should produce a syntax error + assert.notThrows(() => parse('\t\r \n{\t\r \n"property"\t\r \n:\t\r \n{\t\r \n}\t\r \n,\t\r \n"prop2"\t\r \n:\t\r \n' + + '[\t\r \ntrue\t\r \n,\t\r \nnull\t\r \n,123.456\t\r \n]\t\r \n}\t\r \n', reviver), SyntaxError, `15.12.1.1-0-9 ${ note }`); // should JSON parse without error + assert.same(parse('\t1234', reviver), 1234, `15.12.1.1-g1-1-1 ${ note }`); // ' should be ignored' + assert.throws(() => parse('12\t34', reviver), SyntaxError, `15.12.1.1-g1-1-2 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.same(parse('\r1234', reviver), 1234, `15.12.1.1-g1-2-1 ${ note }`); // ' should be ignored' + assert.throws(() => parse('12\r34', reviver), SyntaxError, `15.12.1.1-g1-2-2 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.same(parse('\n1234', reviver), 1234, `15.12.1.1-g1-3-1 ${ note }`); // ' should be ignored' + assert.throws(() => parse('12\n34', reviver), SyntaxError, `15.12.1.1-g1-3-2 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.same(parse(' 1234', reviver), 1234, `15.12.1.1-g1-4-1 ${ note }`); // ' should be ignored' + assert.throws(() => parse('12 34', reviver), SyntaxError, `15.12.1.1-g1-4-2 ${ note }`); // should produce a syntax error as whitespace results in two tokens + assert.same(parse('"abc"', reviver), 'abc', `15.12.1.1-g2-1 ${ note }`); + assert.throws(() => parse("'abc'", reviver), SyntaxError, `15.12.1.1-g2-2 ${ note }`); + assert.throws(() => parse('\\u0022abc\\u0022', reviver), SyntaxError, `15.12.1.1-g2-3 ${ note }`); + assert.throws(() => parse('"abc\'', reviver), SyntaxError, `15.12.1.1-g2-4 ${ note }`); + assert.same(parse('""', reviver), '', `15.12.1.1-g2-5 ${ note }`); + // invalid string characters should produce a syntax error + assert.throws(() => parse('"\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007"', reviver), SyntaxError, `15.12.1.1-g4-1 ${ note }`); + assert.throws(() => parse('"\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f"', reviver), SyntaxError, `15.12.1.1-g4-2 ${ note }`); + assert.throws(() => parse('"\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017"', reviver), SyntaxError, `15.12.1.1-g4-3 ${ note }`); + assert.throws(() => parse('"\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f"', reviver), SyntaxError, `15.12.1.1-g4-4 ${ note }`); + assert.same(parse('"\\u0058"', reviver), 'X', `15.12.1.1-g5-1 ${ note }`); + assert.throws(() => parse('"\\u005"', reviver), SyntaxError, `15.12.1.1-g5-2 ${ note }`); + assert.throws(() => parse('"\\u0X50"', reviver), SyntaxError, `15.12.1.1-g5-3 ${ note }`); + assert.same(parse('"\\/"', reviver), '/', `15.12.1.1-g6-1 ${ note }`); + assert.same(parse('"\\\\"', reviver), '\\', `15.12.1.1-g6-2 ${ note }`); + assert.same(parse('"\\b"', reviver), '\b', `15.12.1.1-g6-3 ${ note }`); + assert.same(parse('"\\f"', reviver), '\f', `15.12.1.1-g6-4 ${ note }`); + assert.same(parse('"\\n"', reviver), '\n', `15.12.1.1-g6-5 ${ note }`); + assert.same(parse('"\\r"', reviver), '\r', `15.12.1.1-g6-6 ${ note }`); + assert.same(parse('"\\t"', reviver), '\t', `15.12.1.1-g6-7 ${ note }`); + + const nullChars = [ + '"\u0000"', + '"\u0001"', + '"\u0002"', + '"\u0003"', + '"\u0004"', + '"\u0005"', + '"\u0006"', + '"\u0007"', + '"\u0008"', + '"\u0009"', + '"\u000A"', + '"\u000B"', + '"\u000C"', + '"\u000D"', + '"\u000E"', + '"\u000F"', + '"\u0010"', + '"\u0011"', + '"\u0012"', + '"\u0013"', + '"\u0014"', + '"\u0015"', + '"\u0016"', + '"\u0017"', + '"\u0018"', + '"\u0019"', + '"\u001A"', + '"\u001B"', + '"\u001C"', + '"\u001D"', + '"\u001E"', + '"\u001F"', + ]; + + for (let i = 0; i < nullChars.length; i++) { + assert.throws(() => parse(`{${ nullChars[i] } : "John" }`, reviver), SyntaxError, `15.12.2-2-1-${ i } ${ note }`); + assert.throws(() => parse(`{${ nullChars[i] }name : "John" }`, reviver), SyntaxError, `15.12.2-2-2-${ i } ${ note }`); + assert.throws(() => parse(`{name${ nullChars[i] } : "John" }`, reviver), SyntaxError, `15.12.2-2-3-${ i } ${ note }`); + assert.throws(() => parse(`{${ nullChars[i] }name${ nullChars[i] } : "John" }`, reviver), SyntaxError, `15.12.2-2-4-${ i } ${ note }`); + assert.throws(() => parse(`{na${ nullChars[i] }me : "John" }`, reviver), SyntaxError, `15.12.2-2-5-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : ${ nullChars[i] } }`, reviver), SyntaxError, `15.12.2-2-6-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : ${ nullChars[i] }John }`, reviver), SyntaxError, `15.12.2-2-7-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : John${ nullChars[i] } }`, reviver), SyntaxError, `15.12.2-2-8-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : ${ nullChars[i] }John${ nullChars[i] } }`, reviver), SyntaxError, `15.12.2-2-9-${ i } ${ note }`); + assert.throws(() => parse(`{ "name" : Jo${ nullChars[i] }hn }`, reviver), SyntaxError, `15.12.2-2-10-${ i } ${ note }`); + } + + if (REDEFINABLE_PROTO) { + // eslint-disable-next-line no-proto -- testing + assert.same(parse('{ "__proto__": 1, "__proto__": 2 }', reviver).__proto__, 2, `duplicate proto ${ note }`); + } + + assert.throws(() => parse('\u16801', reviver), SyntaxError, `15.12.1.1-0-7-1 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u180e1', reviver), SyntaxError, `15.12.1.1-0-7-2 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20001', reviver), SyntaxError, `15.12.1.1-0-7-3 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20011', reviver), SyntaxError, `15.12.1.1-0-7-4 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20021', reviver), SyntaxError, `15.12.1.1-0-7-5 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20031', reviver), SyntaxError, `15.12.1.1-0-7-6 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20041', reviver), SyntaxError, `15.12.1.1-0-7-7 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20051', reviver), SyntaxError, `15.12.1.1-0-7-8 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20061', reviver), SyntaxError, `15.12.1.1-0-7-9 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20071', reviver), SyntaxError, `15.12.1.1-0-7-10 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20081', reviver), SyntaxError, `15.12.1.1-0-7-11 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u20091', reviver), SyntaxError, `15.12.1.1-0-7-12 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u200a1', reviver), SyntaxError, `15.12.1.1-0-7-13 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u202f1', reviver), SyntaxError, `15.12.1.1-0-7-14 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u205f1', reviver), SyntaxError, `15.12.1.1-0-7-15 ${ note }`); // invalid whitespace + assert.throws(() => parse('\u30001', reviver), SyntaxError, `15.12.1.1-0-7-16 ${ note }`); // invalid whitespace + + assert.same(parse('-0', reviver), -0, `negative-zero-1 ${ note }`); + assert.same(parse(' \n-0', reviver), -0, `negative-zero-2 ${ note }`); + assert.same(parse('-0 \t', reviver), -0, `negative-zero-3 ${ note }`); + assert.same(parse('\n\t -0\n ', reviver), -0, `negative-zero-4 ${ note }`); + assert.same(parse(-0, reviver), 0, `negative-zero-5 ${ note }`); + + assert.throws(() => parse(undefined, reviver), SyntaxError, `undefined ${ note }`); + assert.throws(() => parse(Symbol('JSON.parse test'), reviver), TypeError, `symbol ${ note }`); + assert.same(parse(null, reviver), null, `null ${ note }`); + assert.same(parse(false, reviver), false, `false ${ note }`); + assert.same(parse(true, reviver), true, `true ${ note }`); + assert.same(parse(0, reviver), 0, `0 ${ note }`); + assert.same(parse(3.14, reviver), 3.14, `3.14 ${ note }`); + + assert.same(parse({ + toString() { + return '"string"'; + }, + valueOf() { + return '"default_or_number"'; + }, + }, reviver), 'string', `text-object ${ note }`); + + assert.throws(() => parse({ + toString: null, + valueOf() { + throw new EvalError('t262'); + }, + }, reviver), EvalError, `text-object-abrupt-1 ${ note }`); + + assert.throws(() => parse({ + toString() { + throw new EvalError('t262'); + }, + }, reviver), EvalError, `text-object-abrupt-2 ${ note }`); + } + + // eslint-disable-next-line no-extend-native -- testing + Array.prototype[1] = 3; + const arr1 = parse('[1, 2]', function (key, value) { + if (key === '0') delete this[1]; + return value; + }); + delete Array.prototype[1]; + assert.same(arr1[0], 1, 'reviver-array-get-prop-from-prototype-1'); + assert.true(hasOwn(arr1, '1'), 'reviver-array-get-prop-from-prototype-2'); + assert.same(arr1[1], 3, 'reviver-array-get-prop-from-prototype-3'); + + // eslint-disable-next-line no-extend-native -- testing + Object.prototype.b = 3; + const obj1 = parse('{"a": 1, "b": 2}', function (key, value) { + if (key === 'a') delete this.b; + return value; + }); + delete Object.prototype.b; + assert.same(obj1.a, 1, 'reviver-object-get-prop-from-prototype-1'); + assert.true(hasOwn(obj1, 'b'), 'reviver-object-get-prop-from-prototype-2'); + assert.same(obj1.b, 3, 'reviver-object-get-prop-from-prototype-3'); + + if (DESCRIPTORS) { + const arr2 = parse('[1, 2]', function (key, value) { + if (key === '0') defineProperty(this, '1', { configurable: false }); + if (key === '1') return 22; + return value; + }); + assert.same(arr2[0], 1, 'reviver-array-non-configurable-prop-create-1'); + assert.same(arr2[1], 2, 'reviver-array-non-configurable-prop-create-2'); + + const arr3 = parse('[1, 2]', function (key, value) { + if (key === '0') defineProperty(this, '1', { configurable: false }); + if (key === '1') return; + return value; + }); + assert.same(arr3[0], 1, 'reviver-array-non-configurable-prop-delete-1'); + assert.true(hasOwn(arr3, '1'), 'reviver-array-non-configurable-prop-delete-2'); + assert.same(arr3[1], 2, 'reviver-array-non-configurable-prop-delete-3'); + + const obj2 = parse('{"a": 1, "b": 2}', function (key, value) { + if (key === 'a') defineProperty(this, 'b', { configurable: false }); + if (key === 'b') return 22; + return value; + }); + assert.same(obj2.a, 1, 'reviver-object-non-configurable-prop-create-1'); + assert.same(obj2.b, 2, 'reviver-object-non-configurable-prop-create-2'); + + const obj3 = parse('{"a": 1, "b": 2}', function (key, value) { + if (key === 'a') defineProperty(this, 'b', { configurable: false }); + if (key === 'b') return; + return value; + }); + assert.same(obj3.a, 1, 'reviver-object-non-configurable-prop-delete-1'); + assert.true(hasOwn(obj3, 'b'), 'reviver-object-non-configurable-prop-delete-2'); + assert.same(obj3.b, 2, 'reviver-object-non-configurable-prop-delete-3'); + + assert.throws(() => parse('[0,0]', function () { + defineProperty(this, '1', { get: () => { throw new EvalError('t262'); } }); + }), EvalError, 'reviver-get-name-err'); + } + + assert.throws(() => parse('0', () => { throw new EvalError('t262'); }), EvalError, 'reviver-call-err'); + + // FF20- enumeration order issue + if (keys({ k: 1, 2: 3 })[0] === '2') { + const calls = []; + parse('{"p1":0,"p2":0,"p1":0,"2":0,"1":0}', (name, val) => { + calls.push(name); + return val; + }); + // The empty string is the _rootName_ in JSON.parse + assert.arrayEqual(calls, ['1', '2', 'p1', 'p2', ''], 'reviver-call-order'); + } + + assert.throws(() => parse(), SyntaxError, 'no args'); +}); + +QUnit.test('JSON.parse source access', assert => { + const spy = (k, v, { source: $source }) => source = $source; + let source; + parse('1234', spy); + assert.same(source, '1234', '1234'); + parse('"1234"', spy); + assert.same(source, '"1234"', '"1234"'); + parse('null', spy); + assert.same(source, 'null', 'null'); + parse('true', spy); + assert.same(source, 'true', 'true'); + parse('false', spy); + assert.same(source, 'false', 'false'); + parse('{}', spy); + assert.same(source, undefined, '{}'); + parse('[]', spy); + assert.same(source, undefined, '[]'); + parse('9007199254740993', spy); + assert.same(source, '9007199254740993', '9007199254740993'); +}); diff --git a/tests/unit-pure/es.json.raw-json.js b/tests/unit-pure/es.json.raw-json.js new file mode 100644 index 000000000000..4ce095b044b5 --- /dev/null +++ b/tests/unit-pure/es.json.raw-json.js @@ -0,0 +1,27 @@ +import { FREEZING } from '../helpers/constants.js'; +import rawJSON from 'core-js-pure/es/json/raw-json'; +import stringify from 'core-js-pure/es/json/stringify'; +import isFrozen from 'core-js-pure/es/object/is-frozen'; +import hasOwn from 'core-js-pure/es/object/has-own'; + +QUnit.test('JSON.rawJSON', assert => { + assert.isFunction(rawJSON); + assert.arity(rawJSON, 1); + assert.name(rawJSON, 'rawJSON'); + + const raw = rawJSON(1); + assert.true(hasOwn(raw, 'rawJSON'), 'own rawJSON'); + assert.same(raw.rawJSON, '1', 'is string 1'); + if (FREEZING) assert.true(isFrozen(raw), 'frozen'); + + assert.same(stringify(rawJSON('"qwe"')), '"qwe"'); + assert.same(stringify(rawJSON('null')), 'null'); + assert.same(stringify(rawJSON('true')), 'true'); + assert.same(stringify(rawJSON('9007199254740993')), '9007199254740993'); + assert.same(stringify({ key: rawJSON('9007199254740993') }), '{"key":9007199254740993}'); + assert.same(stringify([rawJSON('9007199254740993')]), '[9007199254740993]'); + + assert.throws(() => rawJSON('"qwe'), SyntaxError, 'invalid 1'); + assert.throws(() => rawJSON({}), SyntaxError, 'invalid 2'); + assert.throws(() => rawJSON(''), SyntaxError, 'invalid 3'); +}); diff --git a/tests/unit-pure/es.json.stringify.js b/tests/unit-pure/es.json.stringify.js new file mode 100644 index 000000000000..aaf7511f1f44 --- /dev/null +++ b/tests/unit-pure/es.json.stringify.js @@ -0,0 +1,528 @@ +// Some tests adopted from Test262 project and governed by the BSD license. +// Copyright (c) 2012 Ecma International. All rights reserved. +/* eslint-disable es/no-bigint,unicorn/no-hex-escape -- testing */ +import { DESCRIPTORS, GLOBAL } from '../helpers/constants.js'; +import stringify from 'core-js-pure/es/json/stringify'; +import Symbol from 'core-js-pure/es/symbol'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import keys from 'core-js-pure/es/object/keys'; +import values from 'core-js-pure/es/object/values'; + +if (GLOBAL.JSON?.stringify) { + QUnit.test('JSON.stringify', assert => { + assert.isFunction(stringify); + assert.arity(stringify, 3); + assert.name(stringify, 'stringify'); + + assert.same(stringify({ a: 1, b: 2 }, []), '{}', 'replacer-array-empty-1'); + assert.same(stringify({ a: 1, b: { c: 2 } }, []), '{}', 'replacer-array-empty-2'); + assert.same(stringify([1, { a: 2 }], []), '[1,{}]', 'replacer-array-empty-3'); + + const num1 = new Number(10); + num1.toString = () => 'toString'; + num1.valueOf = () => { throw new EvalError('should not be called'); }; + assert.same(stringify({ + 10: 1, + toString: 2, + valueOf: 3, + }, [num1]), '{"toString":2}', 'replacer-array-number-object'); + + const obj1 = { + 0: 0, + 1: 1, + '-4': 2, + 0.3: 3, + '-Infinity': 4, + NaN: 5, + }; + assert.same(stringify(obj1, [ + -0, + 1, + -4, + 0.3, + -Infinity, + NaN, + ]), stringify(obj1), 'replacer-array-number'); + + const str1 = new String('str'); + str1.toString = () => 'toString'; + str1.valueOf = () => { throw new EvalError('should not be called'); }; + assert.same(stringify({ + str: 1, + toString: 2, + valueOf: 3, + }, [str1]), '{"toString":2}', 'replacer-array-string-object'); + + assert.same(stringify({ undefined: 1 }, [undefined]), '{}', 'replacer-array-undefined-1'); + // eslint-disable-next-line no-sparse-arrays -- testing + assert.same(stringify({ key: 1, undefined: 2 }, [,,,]), '{}', 'replacer-array-undefined-2'); + const sparse = Array(3); + sparse[1] = 'key'; + assert.same(stringify({ undefined: 1, key: 2 }, sparse), '{"key":2}', 'replacer-array-undefined-3'); + + assert.throws(() => stringify({}, () => { throw new EvalError('should not be called'); }), EvalError, 'replacer-function-abrupt'); + + const calls = []; + const b1 = [1, 2]; + const b2 = { c1: true, c2: false }; + const a1 = { + b1, + b2: { + toJSON() { return b2; }, + }, + }; + const obj2 = { a1, a2: 'a2' }; + assert.same(stringify(obj2, function (key, value) { + if (key !== '') calls.push([this, key, value]); + return value; + }), stringify(obj2), 'replacer-function-arguments-1'); + assert.arrayEqual(calls[0], [obj2, 'a1', a1], 'replacer-function-arguments-2'); + assert.arrayEqual(calls[1], [a1, 'b1', b1], 'replacer-function-arguments-3'); + assert.arrayEqual(calls[2], [b1, '0', 1], 'replacer-function-arguments-4'); + assert.arrayEqual(calls[3], [b1, '1', 2], 'replacer-function-arguments-5'); + assert.arrayEqual(calls[4], [a1, 'b2', b2], 'replacer-function-arguments-6'); + assert.arrayEqual(calls[5], [b2, 'c1', true], 'replacer-function-arguments-7'); + assert.arrayEqual(calls[6], [b2, 'c2', false], 'replacer-function-arguments-8'); + assert.arrayEqual(calls[7], [obj2, 'a2', 'a2'], 'replacer-function-arguments-9'); + + const circular1 = [{}]; + assert.throws(() => stringify(circular1, () => circular1), TypeError, 'replacer-function-array-circular'); + + const direct1 = { prop: {} }; + assert.throws(() => stringify(direct1, () => direct1), TypeError, 'replacer-function-object-circular-1'); + const indirect1 = { p1: { p2: {} } }; + assert.throws(() => stringify(indirect1, (key, value) => key === 'p2' ? indirect1 : value), TypeError, 'replacer-function-object-circular-2'); + + assert.same(stringify(1, () => { /* empty */ }), undefined, 'replacer-function-result-undefined-1'); + assert.same(stringify([1], () => { /* empty */ }), undefined, 'replacer-function-result-undefined-2'); + assert.same(stringify({ prop: 1 }, () => { /* empty */ }), undefined, 'replacer-function-result-undefined-3'); + assert.same(stringify([1], (key, value) => value === 1 ? undefined : value), '[null]', 'replacer-function-result-undefined-4'); + assert.same(stringify({ prop: 1 }, (key, value) => value === 1 ? undefined : value), '{}', 'replacer-function-result-undefined-5'); + assert.same(stringify({ a: { b: [1] } }, (key, value) => value === 1 ? undefined : value), '{"a":{"b":[null]}}', 'replacer-function-result-undefined-6'); + + assert.same(stringify(null, (key, value) => { + assert.same(value, null); + switch (key) { + case '': return { a1: null, a2: null }; + case 'a1': return { b1: null, b2: null }; + case 'a2': return 'a2'; + case 'b1': return [null, null]; + case 'b2': return { c1: null, c2: null }; + case '0': return 1; + case '1': return 2; + case 'c1': return true; + case 'c2': return false; + } throw new EvalError('unreachable'); + }), stringify({ + a1: { + b1: [1, 2], + b2: { + c1: true, + c2: false, + }, + }, + a2: 'a2', + }), 'replacer-function-result'); + + assert.same(stringify({ + toJSON() { return 'toJSON'; }, + }, (_key, value) => `${ value }|replacer`), '"toJSON|replacer"', 'replacer-function-tojson-1'); + + assert.same(stringify({ + toJSON() { return { calls: 'toJSON' }; }, + }, (_key, value) => { + if (value && value.calls) value.calls += '|replacer'; + return value; + }), '{"calls":"toJSON|replacer"}', 'replacer-function-tojson-2'); + + const obj4 = { key: [1] }; + const json1 = '{"key":[1]}'; + assert.same(stringify(obj4, {}), json1, 'replacer-wrong-type-1'); + assert.same(stringify(obj4, new String('str')), json1, 'replacer-wrong-type-2'); + assert.same(stringify(obj4, new Number(6.1)), json1, 'replacer-wrong-type-3'); + assert.same(stringify(obj4, null), json1, 'replacer-wrong-type-4'); + assert.same(stringify(obj4, ''), json1, 'replacer-wrong-type-5'); + assert.same(stringify(obj4, 0), json1, 'replacer-wrong-type-6'); + assert.same(stringify(obj4, Symbol('stringify replacer test')), json1, 'replacer-wrong-type-7'); + assert.same(stringify(obj4, true), json1, 'replacer-wrong-type-8'); + + const obj5 = { + a1: { + b1: [1, 2, 3, 4], + b2: { + c1: 1, + c2: 2, + }, + }, + a2: 'a2', + }; + + assert.same(stringify(obj5, null, -1.99999), stringify(obj5, null, -1), 'space-number-float-1'); + assert.same(stringify(obj5, null, new Number(5.11111)), stringify(obj5, null, 5), 'space-number-float-2'); + assert.same(stringify(obj5, null, 6.99999), stringify(obj5, null, 6), 'space-number-float-3'); + + assert.same(stringify(obj5, null, new Number(1)), stringify(obj5, null, 1), 'space-number-object-1'); + const num2 = new Number(1); + num2.toString = () => { throw new EvalError('should not be called'); }; + num2.valueOf = () => 3; + assert.same(stringify(obj5, null, num2), stringify(obj5, null, 3), 'space-number-object-2'); + const abrupt1 = new Number(4); + abrupt1.toString = () => { throw new EvalError('t262'); }; + abrupt1.valueOf = () => { throw new EvalError('t262'); }; + assert.throws(() => stringify(obj5, null, abrupt1), EvalError, 'space-number-object-3'); + + assert.same(stringify(obj5, null, new Number(-5)), stringify(obj5, null, 0), 'space-number-range-1'); + assert.same(stringify(obj5, null, 10), stringify(obj5, null, 100), 'space-number-range-2'); + + assert.same(stringify(obj5, null, 0), stringify(obj5, null, ''), 'space-number-1'); + assert.same(stringify(obj5, null, 4), stringify(obj5, null, ' '), 'space-number-2'); + + assert.same(stringify(obj5, null, new String('xxx')), stringify(obj5, null, 'xxx'), 'space-string-object-1'); + const str2 = new String('xxx'); + str2.toString = () => '---'; + str2.valueOf = () => { throw new EvalError('should not be called'); }; + assert.same(stringify(obj5, null, str2), stringify(obj5, null, '---'), 'space-string-object-2'); + const abrupt2 = new String('xxx'); + abrupt2.toString = () => { throw new EvalError('t262'); }; + abrupt2.valueOf = () => { throw new EvalError('t262'); }; + assert.throws(() => stringify(obj5, null, abrupt2), EvalError, 'space-string-object-3'); + + assert.same(stringify(obj5, null, '0123456789xxxxxxxxx'), stringify(obj5, null, '0123456789'), 'space-string-range'); + + assert.same(stringify(obj5, null, ''), stringify(obj5), 'space-string-1'); + assert.same(stringify(obj5, null, ' '), `{ + "a1": { + "b1": [ + 1, + 2, + 3, + 4 + ], + "b2": { + "c1": 1, + "c2": 2 + } + }, + "a2": "a2" +}`, 'space-string-2'); + + assert.same(stringify(obj5), stringify(obj5, null, null), 'space-wrong-type-1'); + assert.same(stringify(obj5), stringify(obj5, null, true), 'space-wrong-type-2'); + assert.same(stringify(obj5), stringify(obj5, null, new Boolean(false)), 'space-wrong-type-3'); + assert.same(stringify(obj5), stringify(obj5, null, Symbol('stringify space test')), 'space-wrong-type-4'); + assert.same(stringify(obj5), stringify(obj5, null, {}), 'space-wrong-type-5'); + + const direct2 = []; + direct2.push(direct2); + assert.throws(() => stringify(direct2), TypeError, 'value-array-circular-1'); + const indirect2 = []; + indirect2.push([[indirect2]]); + assert.throws(() => stringify(indirect2), TypeError, 'value-array-circular-2'); + + if (typeof BigInt == 'function') { + assert.same(stringify(BigInt(0), (k, v) => typeof v === 'bigint' ? 'bigint' : v), '"bigint"', 'value-bigint-replacer-1'); + assert.same(stringify({ x: BigInt(0) }, (k, v) => typeof v === 'bigint' ? 'bigint' : v), '{"x":"bigint"}', 'value-bigint-replacer-2'); + assert.throws(() => stringify(BigInt(0)), TypeError, 'value-bigint-1'); + assert.throws(() => stringify(Object(BigInt(0))), TypeError, 'value-bigint-2'); + assert.throws(() => stringify({ x: BigInt(0) }), TypeError, 'value-bigint-3'); + } + + assert.same(stringify(new Boolean(true)), 'true', 'value-boolean-object-1'); + assert.same(stringify({ + toJSON() { + return { key: new Boolean(false) }; + }, + }), '{"key":false}', 'value-boolean-object-2'); + assert.same(stringify([1], (k, v) => v === 1 ? new Boolean(true) : v), '[true]', 'value-boolean-object-3'); + + assert.same(stringify(() => { /* empty */ }), undefined, 'value-function-1'); + assert.same(stringify([() => { /* empty */ }]), '[null]', 'value-function-2'); + assert.same(stringify({ key() { /* empty */ } }), '{}', 'value-function-3'); + + assert.same(stringify(-0), '0', 'value-number-negative-zero-1'); + assert.same(stringify(['-0', 0, -0]), '["-0",0,0]', 'value-number-negative-zero-2'); + assert.same(stringify({ key: -0 }), '{"key":0}', 'value-number-negative-zero-3'); + + assert.same(stringify(Infinity), 'null', 'value-number-non-finite-1'); + assert.same(stringify({ key: -Infinity }), '{"key":null}', 'value-number-non-finite-2'); + assert.same(stringify([NaN]), '[null]', 'value-number-non-finite-3'); + + assert.same(stringify(new Number(8.5)), '8.5', 'value-number-object-1'); + assert.same(stringify(['str'], (key, value) => { + if (value === 'str') { + const num = new Number(42); + num.toString = () => { throw new EvalError('should not be called'); }; + num.valueOf = () => 2; + return num; + } return value; + }), '[2]', 'value-number-object-2'); + assert.throws(() => stringify({ + key: { + toJSON() { + const num = new Number(3.14); + num.toString = () => { throw new EvalError('t262'); }; + num.valueOf = () => { throw new EvalError('t262'); }; + return num; + }, + }, + }), EvalError, 'value-number-object-3'); + + const direct3 = { prop: null }; + direct3.prop = direct3; + assert.throws(() => stringify(direct3), TypeError, 'value-object-circular-1'); + const indirect3 = { p1: { p2: {} } }; + indirect3.p1.p2.p3 = indirect3; + assert.throws(() => stringify(indirect3), TypeError, 'value-object-circular-2'); + + assert.same(stringify(null), 'null', 'null'); + assert.same(stringify(true), 'true', 'true'); + assert.same(stringify(false), 'false', 'false'); + assert.same(stringify('str'), '"str"', '"str"'); + assert.same(stringify(123), '123', '123'); + assert.same(stringify(undefined), undefined, 'undefined'); + + const charToJson = { + '"': '\\"', + '\\': '\\\\', + '\x00': '\\u0000', + '\x01': '\\u0001', + '\x02': '\\u0002', + '\x03': '\\u0003', + '\x04': '\\u0004', + '\x05': '\\u0005', + '\x06': '\\u0006', + '\x07': '\\u0007', + '\x08': '\\b', + '\x09': '\\t', + '\x0A': '\\n', + '\x0B': '\\u000b', + '\x0C': '\\f', + '\x0D': '\\r', + '\x0E': '\\u000e', + '\x0F': '\\u000f', + '\x10': '\\u0010', + '\x11': '\\u0011', + '\x12': '\\u0012', + '\x13': '\\u0013', + '\x14': '\\u0014', + '\x15': '\\u0015', + '\x16': '\\u0016', + '\x17': '\\u0017', + '\x18': '\\u0018', + '\x19': '\\u0019', + '\x1A': '\\u001a', + '\x1B': '\\u001b', + '\x1C': '\\u001c', + '\x1D': '\\u001d', + '\x1E': '\\u001e', + '\x1F': '\\u001f', + }; + const chars = keys(charToJson).join(''); + const charsReversed = keys(charToJson).reverse().join(''); + const jsonChars = values(charToJson).join(''); + const jsonCharsReversed = values(charToJson).reverse().join(''); + const json = stringify({ [`name${ chars }${ charsReversed }`]: `${ charsReversed }${ chars }value` }); + for (const chr in charToJson) { + const count = json.split(charToJson[chr]).length - 1; + assert.same(count, 4, `Every ASCII 0x${ chr.charCodeAt(0).toString(16) } serializes to ${ charToJson[chr] }`); + } + assert.same( + json, + `{"name${ jsonChars }${ jsonCharsReversed }":"${ jsonCharsReversed }${ jsonChars }value"}`, + 'JSON.stringify(objectUsingControlCharacters)', + ); + + assert.same(stringify('\uD834'), '"\\ud834"', 'JSON.stringify("\\uD834")'); + assert.same(stringify('\uDF06'), '"\\udf06"', 'JSON.stringify("\\uDF06")'); + assert.same(stringify('\uD834\uDF06'), '"𝌆"', 'JSON.stringify("\\uD834\\uDF06")'); + assert.same(stringify('\uD834\uD834\uDF06\uD834'), '"\\ud834𝌆\\ud834"', 'JSON.stringify("\\uD834\\uD834\\uDF06\\uD834")'); + assert.same(stringify('\uD834\uD834\uDF06\uDF06'), '"\\ud834𝌆\\udf06"', 'JSON.stringify("\\uD834\\uD834\\uDF06\\uDF06")'); + assert.same(stringify('\uDF06\uD834\uDF06\uD834'), '"\\udf06𝌆\\ud834"', 'JSON.stringify("\\uDF06\\uD834\\uDF06\\uD834")'); + assert.same(stringify('\uDF06\uD834\uDF06\uDF06'), '"\\udf06𝌆\\udf06"', 'JSON.stringify("\\uDF06\\uD834\\uDF06\\uDF06")'); + assert.same(stringify('\uDF06\uD834'), '"\\udf06\\ud834"', 'JSON.stringify("\\uDF06\\uD834")'); + assert.same(stringify('\uD834\uDF06\uD834\uD834'), '"𝌆\\ud834\\ud834"', 'JSON.stringify("\\uD834\\uDF06\\uD834\\uD834")'); + assert.same(stringify('\uD834\uDF06\uD834\uDF06'), '"𝌆𝌆"', 'JSON.stringify("\\uD834\\uDF06\\uD834\\uDF06")'); + assert.same(stringify('\uDF06\uDF06\uD834\uD834'), '"\\udf06\\udf06\\ud834\\ud834"', 'JSON.stringify("\\uDF06\\uDF06\\uD834\\uD834")'); + assert.same(stringify('\uDF06\uDF06\uD834\uDF06'), '"\\udf06\\udf06𝌆"', 'JSON.stringify("\\uDF06\\uDF06\\uD834\\uDF06")'); + + assert.same(stringify(new String('str')), '"str"', 'value-string-object-1'); + assert.same(stringify({ + key: { + toJSON() { + const str = new String('str'); + str.toString = () => 'toString'; + str.valueOf = () => { throw new EvalError('should not be called'); }; + return str; + }, + }, + }), '{"key":"toString"}', 'value-string-object-2'); + assert.throws(() => stringify([true], (key, value) => { + if (value === true) { + const str = new String('str'); + str.toString = () => { throw new EvalError('t262'); }; + str.valueOf = () => { throw new EvalError('t262'); }; + return str; + } return value; + }), 'value-string-object-3'); + + assert.throws(() => stringify({ + toJSON() { throw new EvalError('t262'); }, + }), EvalError, 'value-tojson-abrupt-1'); + + let callCount = 0; + let $this, $key; + const obj6 = { + toJSON(key) { + callCount += 1; + $this = this; + $key = key; + }, + }; + assert.same(stringify(obj6), undefined, 'value-tojson-arguments-1'); + assert.same(callCount, 1, 'value-tojson-arguments-2'); + assert.same($this, obj6, 'value-tojson-arguments-3'); + assert.same($key, '', 'value-tojson-arguments-4'); + assert.same(stringify([1, obj6, 3]), '[1,null,3]', 'value-tojson-arguments-5'); + assert.same(callCount, 2, 'value-tojson-arguments-6'); + assert.same($this, obj6, 'value-tojson-arguments-7'); + // some old implementations (like WebKit) could pass numbers as keys + // assert.same($key, '1', 'value-tojson-arguments-8'); + assert.same(stringify({ key: obj6 }), '{}', 'value-tojson-arguments-9'); + assert.same(callCount, 3, 'value-tojson-arguments-10'); + assert.same($this, obj6, 'value-tojson-arguments-11'); + assert.same($key, 'key', 'value-tojson-arguments-12'); + + const arr1 = []; + const circular2 = [arr1]; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- testing + arr1.toJSON = () => circular2; + assert.throws(() => stringify(circular2), TypeError, 'value-tojson-array-circular'); + + assert.same(stringify({ toJSON: null }), '{"toJSON":null}', 'value-tojson-not-function-1'); + assert.same(stringify({ toJSON: false }), '{"toJSON":false}', 'value-tojson-not-function-2'); + assert.same(stringify({ toJSON: [] }), '{"toJSON":[]}', 'value-tojson-not-function-3'); + assert.same(stringify({ toJSON: /re/ }), '{"toJSON":{}}', 'value-tojson-not-function-4'); + + const obj7 = {}; + const circular3 = { prop: obj7 }; + obj7.toJSON = () => circular3; + assert.throws(() => stringify(circular3), TypeError, 'value-tojson-object-circular'); + + assert.same(stringify({ toJSON() { return [false]; } }), '[false]', 'value-tojson-result-1'); + const arr2 = [true]; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- testing + arr2.toJSON = () => { /* empty */ }; + assert.same(stringify(arr2), undefined, 'value-tojson-result-2'); + const str3 = new String('str'); + // eslint-disable-next-line es/no-nonstandard-string-prototype-properties -- testing + str3.toJSON = () => null; + assert.same(stringify({ key: str3 }), '{"key":null}', 'value-tojson-result-3'); + const num3 = new Number(14); + // eslint-disable-next-line es/no-nonstandard-number-prototype-properties -- testing + num3.toJSON = () => ({ key: 7 }); + assert.same(stringify([num3]), '[{"key":7}]', 'value-tojson-result-4'); + + if (DESCRIPTORS) { + // This getter will be triggered during enumeration, but the property it adds should not be enumerated. + /* IE issue + const o = defineProperty({ + p1: 'p1', + p2: 'p2', + p3: 'p3', + }, 'add', { + enumerable: true, + get() { + o.extra = 'extra'; + return 'add'; + }, + }); + o.p4 = 'p4'; + o[2] = '2'; + o[0] = '0'; + o[1] = '1'; + delete o.p1; + delete o.p3; + o.p1 = 'p1'; + assert.same(stringify(o), '{"0":"0","1":"1","2":"2","p2":"p2","add":"add","p4":"p4","p1":"p1"}', 'property-order'); + */ + + let getCalls = 0; + assert.same(stringify(defineProperty({}, 'key', { + enumerable: true, + get() { + getCalls += 1; + return true; + }, + }), ['key', 'key']), '{"key":true}', 'replacer-array-duplicates-1'); + assert.same(getCalls, 1, 'replacer-array-duplicates-2'); + + /* old WebKit bug - however, fixing of this is not in priority + const obj3 = defineProperty({}, 'a', { + enumerable: true, + get() { + delete this.b; + return 1; + }, + }); + obj3.b = 2; + assert.same(stringify(obj3, (key, value) => { + if (key === 'b') { + assert.same(value, undefined, 'replacer-function-object-deleted-property-1'); + return ''; + } return value; + }), '{"a":1,"b":""}', 'replacer-function-object-deleted-property-2'); + */ + + assert.throws(() => stringify({ key: defineProperty(Array(1), '0', { + get() { throw new EvalError('t262'); }, + }) }), EvalError, 'value-array-abrupt'); + + assert.throws(() => stringify(defineProperty({}, 'key', { + enumerable: true, + get() { throw new EvalError('t262'); }, + })), EvalError, 'value-object-abrupt'); + + assert.throws(() => stringify(defineProperty({}, 'toJSON', { + get() { throw new EvalError('t262'); }, + })), EvalError, 'value-tojson-abrupt-2'); + } + }); + + QUnit.test('Symbols & JSON.stringify', assert => { + const symbol1 = Symbol('symbol & stringify test 1'); + const symbol2 = Symbol('symbol & stringify test 2'); + + assert.same(stringify([ + 1, + symbol1, + false, + symbol2, + {}, + ]), '[1,null,false,null,{}]', 'array value'); + assert.same(stringify({ + symbol: symbol1, + }), '{}', 'object value'); + if (DESCRIPTORS) { + const object = { bar: 2 }; + object[symbol1] = 1; + assert.same(stringify(object), '{"bar":2}', 'object key'); + } + assert.same(stringify(symbol1), undefined, 'symbol value'); + if (typeof symbol1 == 'symbol') { + assert.same(stringify(Object(symbol1)), '{}', 'boxed symbol'); + } + assert.same(stringify(undefined, () => 42), '42', 'replacer works with top-level undefined'); + }); + + QUnit.test('Well‑formed JSON.stringify', assert => { + assert.same(stringify({ foo: 'bar' }), '{"foo":"bar"}', 'basic'); + assert.same(stringify('\uDEAD'), '"\\udead"', 'r1'); + assert.same(stringify('\uDF06\uD834'), '"\\udf06\\ud834"', 'r2'); + assert.same(stringify('\uDF06ab\uD834'), '"\\udf06ab\\ud834"', 'r3'); + assert.same(stringify('𠮷'), '"𠮷"', 'r4'); + assert.same(stringify('\uD834\uDF06'), '"𝌆"', 'r5'); + assert.same(stringify('\uD834\uD834\uDF06'), '"\\ud834𝌆"', 'r6'); + assert.same(stringify('\uD834\uDF06\uDF06'), '"𝌆\\udf06"', 'r7'); + assert.same(stringify({ '𠮷': ['\uDF06\uD834'] }), '{"𠮷":["\\udf06\\ud834"]}', 'r8'); + }); +} diff --git a/tests/unit-pure/es.map.group-by.js b/tests/unit-pure/es.map.group-by.js new file mode 100644 index 000000000000..d512477e9438 --- /dev/null +++ b/tests/unit-pure/es.map.group-by.js @@ -0,0 +1,27 @@ +import { createIterable } from '../helpers/helpers.js'; + +import from from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/es/map'; + +QUnit.test('Map.groupBy', assert => { + const { groupBy } = Map; + + assert.isFunction(groupBy); + assert.arity(groupBy, 2); + assert.name(groupBy, 'groupBy'); + + assert.true(groupBy([], it => it) instanceof Map); + + assert.deepEqual(from(groupBy([], it => it)), []); + assert.deepEqual(from(groupBy([1, 2], it => it ** 2)), [[1, [1]], [4, [2]]]); + assert.deepEqual(from(groupBy([1, 2, 1], it => it ** 2)), [[1, [1, 1]], [4, [2]]]); + assert.deepEqual(from(groupBy(createIterable([1, 2]), it => it ** 2)), [[1, [1]], [4, [2]]]); + assert.deepEqual(from(groupBy('qwe', it => it)), [['q', ['q']], ['w', ['w']], ['e', ['e']]], 'iterable string'); + + const element = {}; + groupBy([element], function (it, i) { + assert.same(arguments.length, 2); + assert.same(it, element); + assert.same(i, 0); + }); +}); diff --git a/tests/unit-pure/es.map.js b/tests/unit-pure/es.map.js new file mode 100644 index 000000000000..9e07427e6571 --- /dev/null +++ b/tests/unit-pure/es.map.js @@ -0,0 +1,421 @@ +/* eslint-disable sonarjs/no-element-overwrite -- required for testing */ + +import { createIterable, is, nativeSubclass } from '../helpers/helpers.js'; +import { DESCRIPTORS } from '../helpers/constants.js'; + +import getIterator from 'core-js-pure/es/get-iterator'; +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import freeze from 'core-js-pure/es/object/freeze'; +import getOwnPropertyDescriptor from 'core-js-pure/es/object/get-own-property-descriptor'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import keys from 'core-js-pure/es/object/keys'; +import ownKeys from 'core-js-pure/es/reflect/own-keys'; +import Symbol from 'core-js-pure/es/symbol'; +import Set from 'core-js-pure/es/set'; +import Map from 'core-js-pure/es/map'; + +QUnit.test('Map', assert => { + assert.isFunction(Map); + assert.true('clear' in Map.prototype, 'clear in Map.prototype'); + assert.true('delete' in Map.prototype, 'delete in Map.prototype'); + assert.true('forEach' in Map.prototype, 'forEach in Map.prototype'); + assert.true('get' in Map.prototype, 'get in Map.prototype'); + assert.true('has' in Map.prototype, 'has in Map.prototype'); + assert.true('set' in Map.prototype, 'set in Map.prototype'); + assert.true(new Map() instanceof Map, 'new Map instanceof Map'); + assert.same(new Map(createIterable([[1, 1], [2, 2], [3, 3]])).size, 3, 'Init from iterable'); + assert.same(new Map([[freeze({}), 1], [2, 3]]).size, 2, 'Support frozen objects'); + let done = false; + try { + new Map(createIterable([null, 1, 2], { + return() { + return done = true; + }, + })); + } catch { /* empty */ } + assert.true(done, '.return #throw'); + const array = []; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + new Map(array); + assert.true(done); + const object = {}; + new Map().set(object, 1); + if (DESCRIPTORS) { + const results = []; + for (const key in object) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(object), []); + } + assert.arrayEqual(getOwnPropertyNames(object), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); + if (ownKeys) assert.arrayEqual(ownKeys(object), []); + if (nativeSubclass) { + const Subclass = nativeSubclass(Map); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof Map, 'correct subclassing with native classes #2'); + assert.same(new Subclass().set(1, 2).get(1), 2, 'correct subclassing with native classes #3'); + } + + if (typeof ArrayBuffer == 'function') { + const buffer = new ArrayBuffer(8); + const map = new Map([[buffer, 8]]); + assert.true(map.has(buffer), 'works with ArrayBuffer keys'); + } +}); + +QUnit.test('Map#clear', assert => { + assert.isFunction(Map.prototype.clear); + let map = new Map(); + map.clear(); + assert.same(map.size, 0); + map = new Map().set(1, 2).set(2, 3).set(1, 4); + map.clear(); + assert.same(map.size, 0); + assert.false(map.has(1)); + assert.false(map.has(2)); + const frozen = freeze({}); + map = new Map().set(1, 2).set(frozen, 3); + map.clear(); + assert.same(map.size, 0, 'Support frozen objects'); + assert.false(map.has(1)); + assert.false(map.has(frozen)); +}); + +QUnit.test('Map#delete', assert => { + assert.isFunction(Map.prototype.delete); + const object = {}; + const map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 7); + map.set(2, 5); + map.set(1, 4); + map.set(object, 9); + assert.same(map.size, 5); + assert.true(map.delete(NaN)); + assert.same(map.size, 4); + assert.false(map.delete(4)); + assert.same(map.size, 4); + map.delete([]); + assert.same(map.size, 4); + map.delete(object); + assert.same(map.size, 3); + const frozen = freeze({}); + map.set(frozen, 42); + assert.same(map.size, 4); + map.delete(frozen); + assert.same(map.size, 3); +}); + +QUnit.test('Map#forEach', assert => { + assert.isFunction(Map.prototype.forEach); + let result = {}; + let count = 0; + const object = {}; + let map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 7); + map.set(2, 5); + map.set(1, 4); + map.set(object, 9); + map.forEach((value, key) => { + count++; + result[value] = key; + }); + assert.same(count, 5); + assert.deepEqual(result, { + 1: NaN, + 7: 3, + 5: 2, + 4: 1, + 9: object, + }); + map = new Map(); + map.set('0', 9); + map.set('1', 9); + map.set('2', 9); + map.set('3', 9); + result = ''; + map.forEach((value, key) => { + result += key; + if (key === '2') { + map.delete('2'); + map.delete('3'); + map.delete('1'); + map.set('4', 9); + } + }); + assert.same(result, '0124'); + map = new Map([['0', 1]]); + result = ''; + map.forEach(it => { + map.delete('0'); + if (result !== '') throw new Error(); + result += it; + }); + assert.same(result, '1'); + assert.throws(() => Map.prototype.forEach.call(new Set(), () => { /* empty */ }), 'non-generic'); +}); + +QUnit.test('Map#get', assert => { + assert.isFunction(Map.prototype.get); + const object = {}; + const frozen = freeze({}); + const map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 1); + map.set(2, 5); + map.set(1, 4); + map.set(frozen, 42); + map.set(object, object); + assert.same(map.get(NaN), 1); + assert.same(map.get(4), undefined); + assert.same(map.get({}), undefined); + assert.same(map.get(object), object); + assert.same(map.get(frozen), 42); + assert.same(map.get(2), 5); +}); + +QUnit.test('Map#has', assert => { + assert.isFunction(Map.prototype.has); + const object = {}; + const frozen = freeze({}); + const map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 1); + map.set(2, 5); + map.set(1, 4); + map.set(frozen, 42); + map.set(object, object); + assert.true(map.has(NaN)); + assert.true(map.has(object)); + assert.true(map.has(2)); + assert.true(map.has(frozen)); + assert.false(map.has(4)); + assert.false(map.has({})); +}); + +QUnit.test('Map#set', assert => { + assert.isFunction(Map.prototype.set); + const object = {}; + let map = new Map(); + map.set(NaN, 1); + map.set(2, 1); + map.set(3, 1); + map.set(2, 5); + map.set(1, 4); + map.set(object, object); + assert.same(map.size, 5); + const chain = map.set(7, 2); + assert.same(chain, map); + map.set(7, 2); + assert.same(map.size, 6); + assert.same(map.get(7), 2); + assert.same(map.get(NaN), 1); + map.set(NaN, 42); + assert.same(map.size, 6); + assert.same(map.get(NaN), 42); + map.set({}, 11); + assert.same(map.size, 7); + assert.same(map.get(object), object); + map.set(object, 27); + assert.same(map.size, 7); + assert.same(map.get(object), 27); + map = new Map(); + map.set(NaN, 2); + map.set(NaN, 3); + map.set(NaN, 4); + assert.same(map.size, 1); + const frozen = freeze({}); + map = new Map().set(frozen, 42); + assert.same(map.get(frozen), 42); +}); + +QUnit.test('Map#size', assert => { + const map = new Map(); + map.set(2, 1); + const { size } = map; + assert.same(typeof size, 'number', 'size is number'); + assert.same(size, 1, 'size is correct'); + if (DESCRIPTORS) { + const sizeDescriptor = getOwnPropertyDescriptor(Map.prototype, 'size'); + const getter = sizeDescriptor && sizeDescriptor.get; + const setter = sizeDescriptor && sizeDescriptor.set; + assert.same(typeof getter, 'function', 'size is getter'); + assert.same(typeof setter, 'undefined', 'size is not setter'); + assert.throws(() => Map.prototype.size, TypeError); + } +}); + +QUnit.test('Map & -0', assert => { + let map = new Map(); + map.set(-0, 1); + assert.same(map.size, 1); + assert.true(map.has(0)); + assert.true(map.has(-0)); + assert.same(map.get(0), 1); + assert.same(map.get(-0), 1); + map.forEach((val, key) => { + assert.false(is(key, -0)); + }); + map.delete(-0); + assert.same(map.size, 0); + map = new Map([[-0, 1]]); + map.forEach((val, key) => { + assert.false(is(key, -0)); + }); + map = new Map(); + map.set(4, 4); + map.set(3, 3); + map.set(2, 2); + map.set(1, 1); + map.set(0, 0); + assert.true(map.has(-0)); +}); + +QUnit.test('Map#@@toStringTag', assert => { + assert.same(Map.prototype[Symbol.toStringTag], 'Map', 'Map::@@toStringTag is `Map`'); + assert.same(String(new Map()), '[object Map]', 'correct stringification'); +}); + +QUnit.test('Map Iterator', assert => { + const map = new Map(); + map.set('a', 1); + map.set('b', 2); + map.set('c', 3); + map.set('d', 4); + const results = []; + const iterator = map.keys(); + results.push(iterator.next().value); + assert.true(map.delete('a')); + assert.true(map.delete('b')); + assert.true(map.delete('c')); + map.set('e'); + results.push(iterator.next().value, iterator.next().value); + assert.true(iterator.next().done); + map.set('f'); + assert.true(iterator.next().done); + assert.deepEqual(results, ['a', 'd', 'e']); +}); + +QUnit.test('Map#keys', assert => { + assert.isFunction(Map.prototype.keys); + const map = new Map(); + map.set('a', 'q'); + map.set('s', 'w'); + map.set('d', 'e'); + const iterator = map.keys(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Map Iterator'); + assert.deepEqual(iterator.next(), { + value: 'a', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 's', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'd', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Map#values', assert => { + assert.isFunction(Map.prototype.values); + const map = new Map(); + map.set('a', 'q'); + map.set('s', 'w'); + map.set('d', 'e'); + const iterator = map.values(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Map Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Map#entries', assert => { + assert.isFunction(Map.prototype.entries); + const map = new Map(); + map.set('a', 'q'); + map.set('s', 'w'); + map.set('d', 'e'); + const iterator = map.entries(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Map Iterator'); + assert.deepEqual(iterator.next(), { + value: ['a', 'q'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['s', 'w'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['d', 'e'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Map#@@iterator', assert => { + const map = new Map(); + map.set('a', 'q'); + map.set('s', 'w'); + map.set('d', 'e'); + const iterator = getIterator(map); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Map Iterator'); + assert.same(String(iterator), '[object Map Iterator]'); + assert.deepEqual(iterator.next(), { + value: ['a', 'q'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['s', 'w'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['d', 'e'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-pure/es.math.acosh.js b/tests/unit-pure/es.math.acosh.js new file mode 100644 index 000000000000..6c5e62420147 --- /dev/null +++ b/tests/unit-pure/es.math.acosh.js @@ -0,0 +1,24 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import acosh from 'core-js-pure/es/math/acosh'; +import EPSILON from 'core-js-pure/es/number/epsilon'; + +QUnit.test('Math.acosh', assert => { + assert.isFunction(acosh); + assert.same(acosh(NaN), NaN); + assert.same(acosh(0.5), NaN); + assert.same(acosh(-1), NaN); + assert.same(acosh(-1e300), NaN); + assert.same(acosh(1), 0); + assert.same(acosh(Infinity), Infinity); + assert.closeTo(acosh(1234), 7.811163220849231, 1e-11); + assert.closeTo(acosh(8.88), 2.8737631531629235, 1e-11); + assert.closeTo(acosh(1e+160), 369.10676205960726, 1e-11); + assert.closeTo(acosh(Number.MAX_VALUE), 710.475860073944, 1e-11); + assert.closeTo(acosh(1 + EPSILON), 2.1073424255447017e-8, 1e-11); + + const checker = createConversionChecker(1234); + assert.closeTo(acosh(checker), 7.811163220849231, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.asinh.js b/tests/unit-pure/es.math.asinh.js new file mode 100644 index 000000000000..21a1253c0dd2 --- /dev/null +++ b/tests/unit-pure/es.math.asinh.js @@ -0,0 +1,22 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import asinh from 'core-js-pure/es/math/asinh'; + +QUnit.test('Math.asinh', assert => { + assert.isFunction(asinh); + assert.same(asinh(NaN), NaN); + assert.same(asinh(0), 0); + assert.same(asinh(-0), -0); + assert.same(asinh(Infinity), Infinity); + assert.same(asinh(-Infinity), -Infinity); + assert.closeTo(asinh(1234), 7.811163549201245, 1e-11); + assert.closeTo(asinh(9.99), 2.997227420191335, 1e-11); + assert.closeTo(asinh(1e150), 346.0809111296668, 1e-11); + assert.closeTo(asinh(1e7), 16.811242831518268, 1e-11); + assert.closeTo(asinh(-1e7), -16.811242831518268, 1e-11); + + const checker = createConversionChecker(1234); + assert.closeTo(asinh(checker), 7.811163549201245, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.atanh.js b/tests/unit-pure/es.math.atanh.js new file mode 100644 index 000000000000..d342e924cf94 --- /dev/null +++ b/tests/unit-pure/es.math.atanh.js @@ -0,0 +1,26 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import atanh from 'core-js-pure/es/math/atanh'; + +QUnit.test('Math.atanh', assert => { + assert.isFunction(atanh); + assert.same(atanh(NaN), NaN); + assert.same(atanh(-2), NaN); + assert.same(atanh(-1.5), NaN); + assert.same(atanh(2), NaN); + assert.same(atanh(1.5), NaN); + assert.same(atanh(-1), -Infinity); + assert.same(atanh(1), Infinity); + assert.same(atanh(0), 0); + assert.same(atanh(-0), -0); + assert.same(atanh(-1e300), NaN); + assert.same(atanh(1e300), NaN); + assert.closeTo(atanh(0.5), 0.5493061443340549, 1e-11); + assert.closeTo(atanh(-0.5), -0.5493061443340549, 1e-11); + assert.closeTo(atanh(0.444), 0.47720201260109457, 1e-11); + + const checker = createConversionChecker(0.5); + assert.closeTo(atanh(checker), 0.5493061443340549, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.cbrt.js b/tests/unit-pure/es.math.cbrt.js new file mode 100644 index 000000000000..8bc885bc5829 --- /dev/null +++ b/tests/unit-pure/es.math.cbrt.js @@ -0,0 +1,21 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import cbrt from 'core-js-pure/es/math/cbrt'; + +QUnit.test('Math.cbrt', assert => { + assert.isFunction(cbrt); + assert.same(cbrt(NaN), NaN); + assert.same(cbrt(0), 0); + assert.same(cbrt(-0), -0); + assert.same(cbrt(Infinity), Infinity); + assert.same(cbrt(-Infinity), -Infinity); + assert.same(cbrt(-8), -2); + assert.same(cbrt(8), 2); + assert.closeTo(cbrt(-1000), -10, 1e-11); + assert.closeTo(cbrt(1000), 10, 1e-11); + + const checker = createConversionChecker(1000); + assert.closeTo(cbrt(checker), 10, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.clz32.js b/tests/unit-pure/es.math.clz32.js new file mode 100644 index 000000000000..9dbadc5119ac --- /dev/null +++ b/tests/unit-pure/es.math.clz32.js @@ -0,0 +1,18 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import clz32 from 'core-js-pure/es/math/clz32'; + +QUnit.test('Math.clz32', assert => { + assert.isFunction(clz32); + assert.same(clz32(0), 32); + assert.same(clz32(1), 31); + assert.same(clz32(-1), 0); + assert.same(clz32(0.6), 32); + assert.same(clz32(2 ** 32 - 1), 0); + assert.same(clz32(2 ** 32), 32); + + const checker = createConversionChecker(1); + assert.same(clz32(checker), 31, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.cosh.js b/tests/unit-pure/es.math.cosh.js new file mode 100644 index 000000000000..bf13a076e576 --- /dev/null +++ b/tests/unit-pure/es.math.cosh.js @@ -0,0 +1,22 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import cosh from 'core-js-pure/es/math/cosh'; + +QUnit.test('Math.cosh', assert => { + assert.isFunction(cosh); + assert.same(cosh(NaN), NaN); + assert.same(cosh(0), 1); + assert.same(cosh(-0), 1); + assert.same(cosh(Infinity), Infinity); + assert.same(cosh(-Infinity), Infinity); + assert.closeTo(cosh(12), 81377.395712574, 1e-9); + assert.closeTo(cosh(22), 1792456423.065796, 1e-5); + assert.closeTo(cosh(-10), 11013.232920103323, 1e-11); + assert.closeTo(cosh(-23), 4872401723.124452, 1e-5); + assert.closeTo(cosh(710), 1.1169973830808557e+308, 1e+295); + + const checker = createConversionChecker(12); + assert.closeTo(cosh(checker), 81377.395712574, 1e-9, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.expm1.js b/tests/unit-pure/es.math.expm1.js new file mode 100644 index 000000000000..eafe3db77fdf --- /dev/null +++ b/tests/unit-pure/es.math.expm1.js @@ -0,0 +1,19 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import expm1 from 'core-js-pure/es/math/expm1'; + +QUnit.test('Math.expm1', assert => { + assert.isFunction(expm1); + assert.same(expm1(NaN), NaN); + assert.same(expm1(0), 0); + assert.same(expm1(-0), -0); + assert.same(expm1(Infinity), Infinity); + assert.same(expm1(-Infinity), -1); + assert.closeTo(expm1(10), 22025.465794806718, 1e-11); + assert.closeTo(expm1(-10), -0.9999546000702375, 1e-11); + + const checker = createConversionChecker(10); + assert.closeTo(expm1(checker), 22025.465794806718, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.f16round.js b/tests/unit-pure/es.math.f16round.js new file mode 100644 index 000000000000..0c74d1d6f67a --- /dev/null +++ b/tests/unit-pure/es.math.f16round.js @@ -0,0 +1,45 @@ +// some asserts based on https://github.com/petamoriken/float16/blob/master/test/f16round.js +import { createConversionChecker } from '../helpers/helpers.js'; + +import f16round from 'core-js-pure/es/math/f16round'; + +const { MAX_VALUE, MIN_VALUE } = Number; + +QUnit.test('Math.f16round', assert => { + assert.isFunction(f16round); + assert.name(f16round, 'f16round'); + assert.arity(f16round, 1); + assert.same(f16round(), NaN); + assert.same(f16round(undefined), NaN); + assert.same(f16round(NaN), NaN); + assert.same(f16round(null), 0); + assert.same(f16round(0), 0); + assert.same(f16round(-0), -0); + assert.same(f16round(MIN_VALUE), 0); + assert.same(f16round(-MIN_VALUE), -0); + assert.same(f16round(Infinity), Infinity); + assert.same(f16round(-Infinity), -Infinity); + assert.same(f16round(MAX_VALUE), Infinity); + assert.same(f16round(-MAX_VALUE), -Infinity); + + const MAX_FLOAT16 = 65504; + const MIN_FLOAT16 = 2 ** -24; + + assert.same(f16round(MAX_FLOAT16), MAX_FLOAT16); + assert.same(f16round(-MAX_FLOAT16), -MAX_FLOAT16); + assert.same(f16round(MIN_FLOAT16), MIN_FLOAT16); + assert.same(f16round(-MIN_FLOAT16), -MIN_FLOAT16); + assert.same(f16round(MIN_FLOAT16 / 2), 0); + assert.same(f16round(-MIN_FLOAT16 / 2), -0); + assert.same(f16round(2.980232238769531911744490042422139897126953655970282852649688720703125e-8), MIN_FLOAT16); + assert.same(f16round(-2.980232238769531911744490042422139897126953655970282852649688720703125e-8), -MIN_FLOAT16); + + assert.same(f16round(1.337), 1.3369140625); + assert.same(f16round(0.499994), 0.5); + assert.same(f16round(7.9999999), 8); + + const checker = createConversionChecker(1.1); + assert.same(f16round(checker), 1.099609375, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.fround.js b/tests/unit-pure/es.math.fround.js new file mode 100644 index 000000000000..2706248e0043 --- /dev/null +++ b/tests/unit-pure/es.math.fround.js @@ -0,0 +1,49 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import fround from 'core-js-pure/es/math/fround'; + +const { MAX_VALUE, MIN_VALUE } = Number; + +QUnit.test('Math.fround', assert => { + assert.isFunction(fround); + assert.same(fround(), NaN); + assert.same(fround(undefined), NaN); + assert.same(fround(NaN), NaN); + assert.same(fround(null), 0); + assert.same(fround(0), 0); + assert.same(fround(-0), -0); + assert.same(fround(MIN_VALUE), 0); + assert.same(fround(-MIN_VALUE), -0); + assert.same(fround(Infinity), Infinity); + assert.same(fround(-Infinity), -Infinity); + assert.same(fround(MAX_VALUE), Infinity); + assert.same(fround(-MAX_VALUE), -Infinity); + assert.same(fround(3.4028235677973366e+38), Infinity); + assert.same(fround(3), 3); + assert.same(fround(-3), -3); + const maxFloat32 = 3.4028234663852886e+38; + const minFloat32 = 1.401298464324817e-45; + assert.same(fround(maxFloat32), maxFloat32); + assert.same(fround(-maxFloat32), -maxFloat32); + assert.same(fround(maxFloat32 + 2 ** 102), maxFloat32); + assert.same(fround(minFloat32), minFloat32); + assert.same(fround(-minFloat32), -minFloat32); + assert.same(fround(minFloat32 / 2), 0); + assert.same(fround(-minFloat32 / 2), -0); + assert.same(fround(minFloat32 / 2 + 2 ** -202), minFloat32); + assert.same(fround(-minFloat32 / 2 - 2 ** -202), -minFloat32); + + const maxSubnormal32 = 1.1754942106924411e-38; + const minNormal32 = 1.1754943508222875e-38; + assert.same(fround(1.1754942807573642e-38), maxSubnormal32, 'fround(1.1754942807573642e-38)'); + assert.same(fround(1.1754942807573643e-38), minNormal32, 'fround(1.1754942807573643e-38)'); + assert.same(fround(1.1754942807573644e-38), minNormal32, 'fround(1.1754942807573644e-38)'); + assert.same(fround(-1.1754942807573642e-38), -maxSubnormal32, 'fround(-1.1754942807573642e-38)'); + assert.same(fround(-1.1754942807573643e-38), -minNormal32, 'fround(-1.1754942807573643e-38)'); + assert.same(fround(-1.1754942807573644e-38), -minNormal32, 'fround(-1.1754942807573644e-38)'); + + const checker = createConversionChecker(1.1754942807573642e-38); + assert.same(fround(checker), maxSubnormal32, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.hypot.js b/tests/unit-pure/es.math.hypot.js new file mode 100644 index 000000000000..17e209b3cde5 --- /dev/null +++ b/tests/unit-pure/es.math.hypot.js @@ -0,0 +1,57 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import hypot from 'core-js-pure/es/math/hypot'; + +QUnit.test('Math.hypot', assert => { + const { sqrt } = Math; + assert.isFunction(hypot); + assert.same(hypot(), 0); + assert.same(hypot(1), 1); + assert.same(hypot('', 0), 0); + assert.same(hypot(0, ''), 0); + assert.same(hypot(Infinity, 0), Infinity, 'Infinity, 0'); + assert.same(hypot(-Infinity, 0), Infinity, '-Infinity, 0'); + assert.same(hypot(0, Infinity), Infinity, '0, Infinity'); + assert.same(hypot(0, -Infinity), Infinity, '0, -Infinity'); + assert.same(hypot(Infinity, NaN), Infinity, 'Infinity, NaN'); + assert.same(hypot(NaN, -Infinity), Infinity, 'NaN, -Infinity'); + assert.same(hypot(NaN, 0), NaN, 'NaN, 0'); + assert.same(hypot(0, NaN), NaN, '0, NaN'); + assert.same(hypot(0, -0), 0); + assert.same(hypot(0, 0), 0); + assert.same(hypot(-0, -0), 0); + assert.same(hypot(-0, 0), 0); + assert.same(hypot(0, 1), 1); + assert.same(hypot(0, -1), 1); + assert.same(hypot(-0, 1), 1); + assert.same(hypot(-0, -1), 1); + assert.same(hypot(0), 0); + assert.same(hypot(1), 1); + assert.same(hypot(2), 2); + assert.same(hypot(0, 0, 1), 1); + assert.same(hypot(0, 1, 0), 1); + assert.same(hypot(1, 0, 0), 1); + assert.same(hypot(2, 3, 4), sqrt(2 ** 2 + 3 ** 2 + 4 ** 2)); + assert.same(hypot(2, 3, 4, 5), sqrt(2 ** 2 + 3 ** 2 + 4 ** 2 + 5 ** 2)); + assert.closeTo(hypot(66, 66), 93.33809511662427, 1e-11); + assert.closeTo(hypot(0.1, 100), 100.0000499999875, 1e-11); + assert.same(hypot(1e+300, 1e+300), 1.4142135623730952e+300); + assert.same(Math.floor(hypot(1e-300, 1e-300) * 1e308), 141421356); + assert.same(hypot(1e+300, 1e+300, 2, 3), 1.4142135623730952e+300); + assert.same(hypot(-3, 4), 5); + assert.same(hypot(3, -4), 5); + + const checker1 = createConversionChecker(2); + const checker2 = createConversionChecker(3); + const checker3 = createConversionChecker(4); + const checker4 = createConversionChecker(5); + assert.same(hypot(checker1, checker2, checker3, checker4), sqrt(2 ** 2 + 3 ** 2 + 4 ** 2 + 5 ** 2), 'object wrapper'); + assert.same(checker1.$valueOf, 1, 'checker1 valueOf calls'); + assert.same(checker1.$toString, 0, 'checker1 toString calls'); + assert.same(checker2.$valueOf, 1, 'checker2 valueOf calls'); + assert.same(checker2.$toString, 0, 'checker2 toString calls'); + assert.same(checker3.$valueOf, 1, 'checker3 valueOf calls'); + assert.same(checker3.$toString, 0, 'checker3 toString calls'); + assert.same(checker4.$valueOf, 1, 'checker4 valueOf calls'); + assert.same(checker4.$toString, 0, 'checker4 toString calls'); +}); diff --git a/tests/unit-pure/es.math.imul.js b/tests/unit-pure/es.math.imul.js new file mode 100644 index 000000000000..81784ee4eb22 --- /dev/null +++ b/tests/unit-pure/es.math.imul.js @@ -0,0 +1,50 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import imul from 'core-js-pure/es/math/imul'; + +QUnit.test('Math.imul', assert => { + assert.isFunction(imul); + assert.same(imul(0, 0), 0); + assert.same(imul(123, 456), 56088); + assert.same(imul(-123, 456), -56088); + assert.same(imul(123, -456), -56088); + assert.same(imul(19088743, 4275878552), 602016552); + assert.same(imul(false, 7), 0); + assert.same(imul(7, false), 0); + assert.same(imul(false, false), 0); + assert.same(imul(true, 7), 7); + assert.same(imul(7, true), 7); + assert.same(imul(true, true), 1); + assert.same(imul(undefined, 7), 0); + assert.same(imul(7, undefined), 0); + assert.same(imul(undefined, undefined), 0); + assert.same(imul('str', 7), 0); + assert.same(imul(7, 'str'), 0); + assert.same(imul({}, 7), 0); + assert.same(imul(7, {}), 0); + assert.same(imul([], 7), 0); + assert.same(imul(7, []), 0); + assert.same(imul(0xFFFFFFFF, 5), -5); + assert.same(imul(0xFFFFFFFE, 5), -10); + assert.same(imul(2, 4), 8); + assert.same(imul(-1, 8), -8); + assert.same(imul(-2, -2), 4); + assert.same(imul(-0, 7), 0); + assert.same(imul(7, -0), 0); + assert.same(imul(0.1, 7), 0); + assert.same(imul(7, 0.1), 0); + assert.same(imul(0.9, 7), 0); + assert.same(imul(7, 0.9), 0); + assert.same(imul(1.1, 7), 7); + assert.same(imul(7, 1.1), 7); + assert.same(imul(1.9, 7), 7); + assert.same(imul(7, 1.9), 7); + + const checker1 = createConversionChecker(-123); + const checker2 = createConversionChecker(456); + assert.same(imul(checker1, checker2), -56088, 'object wrapper'); + assert.same(checker1.$valueOf, 1, 'checker1 valueOf calls'); + assert.same(checker1.$toString, 0, 'checker1 toString calls'); + assert.same(checker2.$valueOf, 1, 'checker2 valueOf calls'); + assert.same(checker2.$toString, 0, 'checker2 toString calls'); +}); diff --git a/tests/unit-pure/es.math.log10.js b/tests/unit-pure/es.math.log10.js new file mode 100644 index 000000000000..7ee25ecbd937 --- /dev/null +++ b/tests/unit-pure/es.math.log10.js @@ -0,0 +1,25 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import log10 from 'core-js-pure/es/math/log10'; + +QUnit.test('Math.log10', assert => { + assert.isFunction(log10); + assert.same(log10(''), log10(0)); + assert.same(log10(NaN), NaN); + assert.same(log10(-1), NaN); + assert.same(log10(0), -Infinity); + assert.same(log10(-0), -Infinity); + assert.same(log10(1), 0); + assert.same(log10(Infinity), Infinity); + assert.closeTo(log10(0.1), -1, 1e-11); + assert.closeTo(log10(0.5), -0.3010299956639812, 1e-11); + assert.closeTo(log10(1.5), 0.17609125905568124, 1e-11); + assert.closeTo(log10(5), 0.6989700043360189, 1e-11); + assert.closeTo(log10(50), 1.6989700043360187, 1e-11); + assert.closeTo(log10(1000), 3, 1e-11); + + const checker = createConversionChecker(0.5); + assert.closeTo(log10(checker), -0.3010299956639812, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.log1p.js b/tests/unit-pure/es.math.log1p.js new file mode 100644 index 000000000000..9c1e5b2154fb --- /dev/null +++ b/tests/unit-pure/es.math.log1p.js @@ -0,0 +1,21 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import log1p from 'core-js-pure/es/math/log1p'; + +QUnit.test('Math.log1p', assert => { + assert.isFunction(log1p); + assert.same(log1p(''), log1p(0)); + assert.same(log1p(NaN), NaN); + assert.same(log1p(-2), NaN); + assert.same(log1p(-1), -Infinity); + assert.same(log1p(0), 0); + assert.same(log1p(-0), -0); + assert.same(log1p(Infinity), Infinity); + assert.closeTo(log1p(5), 1.791759469228055, 1e-11); + assert.closeTo(log1p(50), 3.9318256327243257, 1e-11); + + const checker = createConversionChecker(5); + assert.closeTo(log1p(checker), 1.791759469228055, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.log2.js b/tests/unit-pure/es.math.log2.js new file mode 100644 index 000000000000..a3dc9b6632e7 --- /dev/null +++ b/tests/unit-pure/es.math.log2.js @@ -0,0 +1,22 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import log2 from 'core-js-pure/es/math/log2'; + +QUnit.test('Math.log2', assert => { + assert.isFunction(log2); + assert.same(log2(''), log2(0)); + assert.same(log2(NaN), NaN); + assert.same(log2(-1), NaN); + assert.same(log2(0), -Infinity); + assert.same(log2(-0), -Infinity); + assert.same(log2(1), 0); + assert.same(log2(Infinity), Infinity); + assert.same(log2(0.5), -1); + assert.same(log2(32), 5); + assert.closeTo(log2(5), 2.321928094887362, 1e-11); + + const checker = createConversionChecker(5); + assert.closeTo(log2(checker), 2.321928094887362, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.sign.js b/tests/unit-pure/es.math.sign.js new file mode 100644 index 000000000000..95d698469b47 --- /dev/null +++ b/tests/unit-pure/es.math.sign.js @@ -0,0 +1,22 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import sign from 'core-js-pure/es/math/sign'; + +QUnit.test('Math.sign', assert => { + assert.isFunction(sign); + assert.same(sign(NaN), NaN); + assert.same(sign(), NaN); + assert.same(sign(-0), -0); + assert.same(sign(0), 0); + assert.same(sign(Infinity), 1); + assert.same(sign(-Infinity), -1); + assert.same(sign(13510798882111488), 1); + assert.same(sign(-13510798882111488), -1); + assert.same(sign(42.5), 1); + assert.same(sign(-42.5), -1); + + const checker = createConversionChecker(-42.5); + assert.same(sign(checker), -1, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.sinh.js b/tests/unit-pure/es.math.sinh.js new file mode 100644 index 000000000000..b04047efd226 --- /dev/null +++ b/tests/unit-pure/es.math.sinh.js @@ -0,0 +1,20 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import sinh from 'core-js-pure/es/math/sinh'; + +QUnit.test('Math.sinh', assert => { + assert.isFunction(sinh); + assert.same(sinh(NaN), NaN); + assert.same(sinh(0), 0); + assert.same(sinh(-0), -0); + assert.same(sinh(Infinity), Infinity); + assert.same(sinh(-Infinity), -Infinity); + assert.closeTo(sinh(-5), -74.20321057778875, 1e-11); + assert.closeTo(sinh(2), 3.6268604078470186, 1e-11); + assert.same(sinh(-2e-17), -2e-17); + + const checker = createConversionChecker(-5); + assert.closeTo(sinh(checker), -74.20321057778875, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.sum-precise.js b/tests/unit-pure/es.math.sum-precise.js new file mode 100644 index 000000000000..af71d303229f --- /dev/null +++ b/tests/unit-pure/es.math.sum-precise.js @@ -0,0 +1,57 @@ +/* eslint-disable @stylistic/max-len -- ok */ +import sumPrecise from 'core-js-pure/es/math/sum-precise'; +import { createIterable } from '../helpers/helpers.js'; + +QUnit.test('Math.sumPrecise', assert => { + assert.isFunction(sumPrecise); + assert.name(sumPrecise, 'sumPrecise'); + assert.arity(sumPrecise, 1); + + assert.same(sumPrecise([1, 2, 3]), 6, 'basic'); + assert.same(sumPrecise(createIterable([1, 2, 3])), 6, 'custom iterable'); + + assert.throws(() => sumPrecise(undefined), TypeError, 'undefined'); + assert.throws(() => sumPrecise(null), TypeError, 'null'); + assert.throws(() => sumPrecise({ 0: 1 }), TypeError, 'non-iterable'); + assert.throws(() => sumPrecise(1, 2), TypeError, 'non-iterable #2'); + assert.throws(() => sumPrecise([1, '2']), TypeError, 'non-number elements'); + + // Adapted from https://github.com/tc39/test262 + // Copyright (C) 2024 Kevin Gibbons. All rights reserved. + // This code is governed by the BSD license + assert.same(sumPrecise([NaN]), NaN, '[NaN]'); + assert.same(sumPrecise([Infinity, -Infinity]), NaN, '[Infinity, -Infinity]'); + assert.same(sumPrecise([-Infinity, Infinity]), NaN, '[-Infinity, Infinity]'); + assert.same(sumPrecise([Infinity]), Infinity, '[Infinity]'); + assert.same(sumPrecise([Infinity, Infinity]), Infinity, '[Infinity, Infinity]'); + assert.same(sumPrecise([-Infinity]), -Infinity, '[-Infinity]'); + assert.same(sumPrecise([-Infinity, -Infinity]), -Infinity, '[-Infinity, -Infinity]'); + assert.same(sumPrecise([]), -0, '[]'); + assert.same(sumPrecise([-0]), -0, '[-0]'); + assert.same(sumPrecise([-0, -0]), -0, '[-0, -0]'); + assert.same(sumPrecise([-0, 0]), 0, '[-0, 0]'); + assert.same(sumPrecise([1e308]), 1e308, '[1e308]'); + assert.same(sumPrecise([1e308, -1e308]), 0, '[1e308, -1e308]'); + assert.same(sumPrecise([0.1]), 0.1, '[0.1]'); + assert.same(sumPrecise([0.1, 0.1]), 0.2, '[0.1, 0.1]'); + assert.same(sumPrecise([0.1, -0.1]), 0, '[0.1, -0.1]'); + assert.same(sumPrecise([1e308, 1e308, 0.1, 0.1, 1e30, 0.1, -1e30, -1e308, -1e308]), 0.30000000000000004, '[1e308, 1e308, 0.1, 0.1, 1e30, 0.1, -1e30, -1e308, -1e308]'); + assert.same(sumPrecise([1e30, 0.1, -1e30]), 0.1, '[1e30, 0.1, -1e30]'); + assert.same(sumPrecise([8.98846567431158e+307, 8.988465674311579e+307, -Number.MAX_VALUE]), 9.9792015476736e+291, '[8.98846567431158e+307, 8.988465674311579e+307, -Number.MAX_VALUE]'); + assert.same(sumPrecise([-5.630637621603525e+255, 9.565271205476345e+307, 2.9937604643020797e+292]), 9.565271205476347e+307, '[-5.630637621603525e+255, 9.565271205476345e+307, 2.9937604643020797e+292]'); + assert.same(sumPrecise([6.739986666787661e+66, 2, -1.2689709186578243e-116, 1.7046015739467354e+308, -9.979201547673601e+291, 6.160926733208294e+307, -3.179557053031852e+234, -7.027282978772846e+307, -0.7500000000000001]), 1.61796594939028e+308, '[6.739986666787661e+66, 2, -1.2689709186578243e-116, 1.7046015739467354e+308, -9.979201547673601e+291, 6.160926733208294e+307, -3.179557053031852e+234, -7.027282978772846e+307, -0.7500000000000001]'); + assert.same(sumPrecise([0.31150493246968836, -8.988465674311582e+307, 1.8315037361673755e-270, -15.999999999999996, 2.9999999999999996, 7.345200721499384e+164, -2.033582473639399, -8.98846567431158e+307, -3.5737295155405993e+292, 4.13894772383715e-124, -3.6111186457260667e-35, 2.387234887098013e+180, 7.645295562778372e-298, 3.395189016861822e-103, -2.6331611115768973e-149]), -Infinity, '[0.31150493246968836, -8.988465674311582e+307, 1.8315037361673755e-270, -15.999999999999996, 2.9999999999999996, 7.345200721499384e+164, -2.033582473639399, -8.98846567431158e+307, -3.5737295155405993e+292, 4.13894772383715e-124, -3.6111186457260667e-35, 2.387234887098013e+180, 7.645295562778372e-298, 3.395189016861822e-103, -2.6331611115768973e-149]'); + assert.same(sumPrecise([-1.1442589134409902e+308, 9.593842098384855e+138, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565685e+308, '[-1.1442589134409902e+308, 9.593842098384855e+138, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]'); + assert.same(sumPrecise([-1.1442589134409902e+308, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565687e+308, '[-1.1442589134409902e+308, 4.494232837155791e+307, -1.3482698511467367e+308, 4.494232837155792e+307]'); + assert.same(sumPrecise([9.593842098384855e+138, -6.948356297254111e+307, -1.3482698511467367e+308, 4.494232837155792e+307]), -1.5936821971565685e+308, '[9.593842098384855e+138, -6.948356297254111e+307, -1.3482698511467367e+308, 4.494232837155792e+307]'); + assert.same(sumPrecise([-2.534858246857893e+115, 8.988465674311579e+307, 8.98846567431158e+307]), Number.MAX_VALUE, '[-2.534858246857893e+115, 8.988465674311579e+307, 8.98846567431158e+307]'); + assert.same(sumPrecise([1.3588124894186193e+308, 1.4803986201152006e+223, 6.741349255733684e+307]), Infinity, '[1.3588124894186193e+308, 1.4803986201152006e+223, 6.741349255733684e+307]'); + assert.same(sumPrecise([6.741349255733684e+307, 1.7976931348623155e+308, -7.388327292663961e+41]), Infinity, '[6.741349255733684e+307, 1.7976931348623155e+308, -7.388327292663961e+41]'); + assert.same(sumPrecise([-1.9807040628566093e+28, Number.MAX_VALUE, 9.9792015476736e+291]), Number.MAX_VALUE, '[-1.9807040628566093e+28, Number.MAX_VALUE, 9.9792015476736e+291]'); + assert.same(sumPrecise([-1.0214557991173964e+61, Number.MAX_VALUE, 8.98846567431158e+307, -8.988465674311579e+307]), Number.MAX_VALUE, '[-1.0214557991173964e+61, Number.MAX_VALUE, 8.98846567431158e+307, -8.988465674311579e+307]'); + assert.same(sumPrecise([Number.MAX_VALUE, 7.999999999999999, -1.908963895403937e-230, 1.6445950082320264e+292, 2.0734856707605806e+205]), Infinity, '[Number.MAX_VALUE, 7.999999999999999, -1.908963895403937e-230, 1.6445950082320264e+292, 2.0734856707605806e+205]'); + assert.same(sumPrecise([6.197409167220438e-223, -9.979201547673601e+291, -Number.MAX_VALUE]), -Infinity, '[6.197409167220438e-223, -9.979201547673601e+291, -Number.MAX_VALUE]'); + assert.same(sumPrecise([4.49423283715579e+307, 8.944251746776101e+307, -0.0002441406250000001, 1.1752060710043817e+308, 4.940846717201632e+292, -1.6836699406454528e+308]), 8.353845887521184e+307, '[4.49423283715579e+307, 8.944251746776101e+307, -0.0002441406250000001, 1.1752060710043817e+308, 4.940846717201632e+292, -1.6836699406454528e+308]'); + assert.same(sumPrecise([8.988465674311579e+307, 7.999999999999998, 7.029158107234023e-308, -2.2303483759420562e-172, -Number.MAX_VALUE, -8.98846567431158e+307]), -Number.MAX_VALUE, '8.988465674311579e+307, 7.999999999999998, 7.029158107234023e-308, -2.2303483759420562e-172, -Number.MAX_VALUE, -8.98846567431158e+307]'); + assert.same(sumPrecise([8.98846567431158e+307, 8.98846567431158e+307]), Infinity, '[8.98846567431158e+307, 8.98846567431158e+307]'); +}); diff --git a/tests/unit-pure/es.math.tanh.js b/tests/unit-pure/es.math.tanh.js new file mode 100644 index 000000000000..c88fa5eb1f25 --- /dev/null +++ b/tests/unit-pure/es.math.tanh.js @@ -0,0 +1,18 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import tanh from 'core-js-pure/es/math/tanh'; + +QUnit.test('Math.tanh', assert => { + assert.isFunction(tanh); + assert.same(tanh(NaN), NaN); + assert.same(tanh(0), 0); + assert.same(tanh(-0), -0); + assert.same(tanh(Infinity), 1); + assert.same(tanh(90), 1); + assert.closeTo(tanh(10), 0.9999999958776927, 1e-11); + + const checker = createConversionChecker(10); + assert.closeTo(tanh(checker), 0.9999999958776927, 1e-11); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.math.trunc.js b/tests/unit-pure/es.math.trunc.js new file mode 100644 index 000000000000..f595b33aea77 --- /dev/null +++ b/tests/unit-pure/es.math.trunc.js @@ -0,0 +1,27 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import trunc from 'core-js-pure/es/math/trunc'; + +QUnit.test('Math.trunc', assert => { + assert.isFunction(trunc); + assert.same(trunc(NaN), NaN, 'NaN -> NaN'); + assert.same(trunc(-0), -0, '-0 -> -0'); + assert.same(trunc(0), 0, '0 -> 0'); + assert.same(trunc(Infinity), Infinity, 'Infinity -> Infinity'); + assert.same(trunc(-Infinity), -Infinity, '-Infinity -> -Infinity'); + assert.same(trunc(null), 0, 'null -> 0'); + assert.same(trunc({}), NaN, '{} -> NaN'); + assert.same(trunc([]), 0, '[] -> 0'); + assert.same(trunc(1.01), 1, '1.01 -> 0'); + assert.same(trunc(1.99), 1, '1.99 -> 0'); + assert.same(trunc(-1), -1, '-1 -> -1'); + assert.same(trunc(-1.99), -1, '-1.99 -> -1'); + assert.same(trunc(-555.555), -555, '-555.555 -> -555'); + assert.same(trunc(9007199254740992), 9007199254740992, '9007199254740992 -> 9007199254740992'); + assert.same(trunc(-9007199254740992), -9007199254740992, '-9007199254740992 -> -9007199254740992'); + + const checker = createConversionChecker(-1.99); + assert.same(trunc(checker), -1, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/es.number.constructor.js b/tests/unit-pure/es.number.constructor.js new file mode 100644 index 000000000000..c5bd63a24b37 --- /dev/null +++ b/tests/unit-pure/es.number.constructor.js @@ -0,0 +1,269 @@ +/* eslint-disable sonarjs/inconsistent-function-call -- required for testing */ +import globalThis from 'core-js-pure/es/global-this'; +import create from 'core-js-pure/es/object/create'; +import Number from 'core-js-pure/es/number'; +import Symbol from 'core-js-pure/es/symbol'; + +const NativeNumber = globalThis.Number; +const whitespaces = ' \t\u000B\f\u00A0\uFEFF\n\r\u2028\u2029\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000'; + +function getCheck(assert) { + return function (a, b) { + assert.same(Number(a), b, `Number ${ typeof a } ${ a } -> ${ b }`); + const x = new Number(a); + assert.same(x, Object(x), `new Number ${ typeof a } ${ a } is object`); + assert.same({}.toString.call(x).slice(8, -1), 'Number', `classof new Number ${ typeof a } ${ a } is Number`); + assert.same(x.valueOf(), b, `new Number(${ typeof a } ${ a }).valueOf() -> ${ b }`); + }; +} + +QUnit.test('Number constructor: regression', assert => { + const check = getCheck(assert); + assert.isFunction(Number); + assert.same(Number.prototype.constructor, NativeNumber); + assert.same(1.0.constructor, NativeNumber); + const constants = ['MAX_VALUE', 'MIN_VALUE', 'NaN', 'NEGATIVE_INFINITY', 'POSITIVE_INFINITY']; + for (const constant of constants) { + assert.true(constant in Number, `Number.${ constant }`); + assert.nonEnumerable(Number, constant); + } + assert.same(Number(), 0); + assert.same(new Number().valueOf(), 0); + check(42, 42); + check(42.42, 42.42); + check(new Number(42), 42); + check(new Number(42.42), 42.42); + check('42', 42); + check('42.42', 42.42); + check('0x42', 66); + check('0X42', 66); + check('0xzzz', NaN); + check('0x1g', NaN); + check('+0x1', NaN); + check('-0x1', NaN); + check('+0X1', NaN); + check('-0X1', NaN); + check(new String('42'), 42); + check(new String('42.42'), 42.42); + check(new String('0x42'), 66); + check(null, 0); + check(undefined, NaN); + check(false, 0); + check(true, 1); + check(new Boolean(false), 0); + check(new Boolean(true), 1); + check({}, NaN); + check({ + valueOf: '1.1', + }, NaN); + check({ + valueOf: '1.1', + toString() { + return '2.2'; + }, + }, 2.2); + check({ + valueOf() { + return '1.1'; + }, + }, 1.1); + check({ + valueOf() { + return '1.1'; + }, + toString() { + return '2.2'; + }, + }, 1.1); + check({ + valueOf() { + return '-0x1a2b3c'; + }, + }, NaN); + check({ + toString() { + return '-0x1a2b3c'; + }, + }, NaN); + check({ + valueOf() { + return 42; + }, + }, 42); + check({ + valueOf() { + return '42'; + }, + }, 42); + check({ + valueOf() { + return null; + }, + }, 0); + check({ + toString() { + return 42; + }, + }, 42); + check({ + toString() { + return '42'; + }, + }, 42); + check({ + valueOf() { + return 1; + }, + toString() { + return 2; + }, + }, 1); + check({ + valueOf: 1, + toString() { + return 2; + }, + }, 2); + let number = 1; + assert.same(Number({ + valueOf() { + return ++number; + }, + }), 2, 'Number call valueOf only once #1'); + assert.same(number, 2, 'Number call valueOf only once #2'); + number = 1; + assert.same(Number({ + toString() { + return ++number; + }, + }), 2, 'Number call toString only once #1'); + assert.same(number, 2, 'Number call toString only once #2'); + number = 1; + assert.same(new Number({ + valueOf() { + return ++number; + }, + }).valueOf(), 2, 'new Number call valueOf only once #1'); + assert.same(number, 2, 'new Number call valueOf only once #2'); + number = 1; + assert.same(new Number({ + toString() { + return ++number; + }, + }).valueOf(), 2, 'new Number call toString only once #1'); + assert.same(number, 2, 'new Number call toString only once #2'); + assert.throws(() => Number(create(null)), TypeError, 'Number assert.throws on object w/o valueOf and toString'); + assert.throws(() => Number({ + valueOf: 1, + toString: 2, + }), TypeError, 'Number assert.throws on object then valueOf and toString are not functions'); + assert.throws(() => new Number(create(null)), TypeError, 'new Number assert.throws on object w/o valueOf and toString'); + assert.throws(() => new Number({ + valueOf: 1, + toString: 2, + }), TypeError, 'new Number assert.throws on object then valueOf and toString are not functions'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('Number constructor test'); + assert.throws(() => Number(symbol), 'throws on symbol argument'); + assert.throws(() => new Number(symbol), 'throws on symbol argument, new'); + } + + number = new Number(42); + assert.same(typeof number.constructor(number), 'number'); + check(`${ whitespaces }42`, 42); + check(`42${ whitespaces }`, 42); + check(`${ whitespaces }42${ whitespaces }`, 42); + check(`${ whitespaces }0x42`, 66); + check(`0x42${ whitespaces }`, 66); + check(`${ whitespaces }0x42${ whitespaces }`, 66); + check(`${ whitespaces }0X42`, 66); + check(`0X42${ whitespaces }`, 66); + check(`${ whitespaces }0X42${ whitespaces }`, 66); +}); + +QUnit.test('Number constructor: binary', assert => { + const check = getCheck(assert); + check('0b1', 1); + check('0B1', 1); + check('0b12', NaN); + check('0b234', NaN); + check('0b1!', NaN); + check('+0b1', NaN); + check('-0b1', NaN); + check(' 0b1', 1); + check('0b1\n', 1); + check('\n 0b1\n ', 1); + check(' 0B1', 1); + check('0B1\n', 1); + check('\n 0B1\n ', 1); + check({ + valueOf() { + return '0b11'; + }, + }, 3); + check({ + toString() { + return '0b111'; + }, + }, 7); + check({ + valueOf() { + return '0b101010'; + }, + }, 42); + check({ + toString() { + return '0b101010'; + }, + }, 42); + check(`${ whitespaces }0b11`, 3); + check(`0b11${ whitespaces }`, 3); + check(`${ whitespaces }0b11${ whitespaces }`, 3); + check(`${ whitespaces }0B11`, 3); + check(`0B11${ whitespaces }`, 3); + check(`${ whitespaces }0B11${ whitespaces }`, 3); +}); + +QUnit.test('Number constructor: octal', assert => { + const check = getCheck(assert); + check('0o7', 7); + check('0O7', 7); + check('0o18', NaN); + check('0o89a', NaN); + check('0o1!', NaN); + check('+0o1', NaN); + check('-0o1', NaN); + check(' 0o1', 1); + check('0o1\n', 1); + check('\n 0o1\n ', 1); + check(' 0O1', 1); + check('0O1\n', 1); + check('\n 0O1\n ', 1); + check({ + valueOf() { + return '0o77'; + }, + }, 63); + check({ + toString() { + return '0o777'; + }, + }, 511); + check({ + valueOf() { + return '0o12345'; + }, + }, 5349); + check({ + toString() { + return '0o12345'; + }, + }, 5349); + check(`${ whitespaces }0o11`, 9); + check(`0o11${ whitespaces }`, 9); + check(`${ whitespaces }0o11${ whitespaces }`, 9); + check(`${ whitespaces }0O11`, 9); + check(`0O11${ whitespaces }`, 9); + check(`${ whitespaces }0O11${ whitespaces }`, 9); +}); diff --git a/tests/unit-pure/es.number.epsilon.js b/tests/unit-pure/es.number.epsilon.js new file mode 100644 index 000000000000..804dcccecfe2 --- /dev/null +++ b/tests/unit-pure/es.number.epsilon.js @@ -0,0 +1,7 @@ +import EPSILON from 'core-js-pure/es/number/epsilon'; + +QUnit.test('Number.EPSILON', assert => { + assert.same(EPSILON, 2 ** -52, 'Is 2^-52'); + assert.notSame(1, 1 + EPSILON, '1 is not 1 + EPSILON'); + assert.same(1, 1 + EPSILON / 2, '1 is 1 + EPSILON / 2'); +}); diff --git a/tests/unit-pure/es.number.is-finite.js b/tests/unit-pure/es.number.is-finite.js new file mode 100644 index 000000000000..8bc9c5a9efe8 --- /dev/null +++ b/tests/unit-pure/es.number.is-finite.js @@ -0,0 +1,40 @@ +import create from 'core-js-pure/es/object/create'; +import isFinite from 'core-js-pure/es/number/is-finite'; + +QUnit.test('Number.isFinite', assert => { + assert.isFunction(isFinite); + const finite = [ + 1, + 0.1, + -1, + 2 ** 16, + 2 ** 16 - 1, + 2 ** 31, + 2 ** 31 - 1, + 2 ** 32, + 2 ** 32 - 1, + -0, + ]; + for (const value of finite) { + assert.true(isFinite(value), `isFinite ${ typeof value } ${ value }`); + } + const notFinite = [ + NaN, + Infinity, + 'NaN', + '5', + false, + new Number(NaN), + new Number(Infinity), + new Number(5), + new Number(0.1), + undefined, + null, + {}, + function () { /* empty */ }, + ]; + for (const value of notFinite) { + assert.false(isFinite(value), `not isFinite ${ typeof value } ${ value }`); + } + assert.false(isFinite(create(null)), 'Number.isFinite(Object.create(null)) -> false'); +}); diff --git a/tests/unit-pure/es.number.is-integer.js b/tests/unit-pure/es.number.is-integer.js new file mode 100644 index 000000000000..35b9a3d4a7a2 --- /dev/null +++ b/tests/unit-pure/es.number.is-integer.js @@ -0,0 +1,40 @@ +import create from 'core-js-pure/es/object/create'; +import isInteger from 'core-js-pure/es/number/is-integer'; + +QUnit.test('Number.isInteger', assert => { + assert.isFunction(isInteger); + const integers = [ + 1, + -1, + 2 ** 16, + 2 ** 16 - 1, + 2 ** 31, + 2 ** 31 - 1, + 2 ** 32, + 2 ** 32 - 1, + -0, + ]; + for (const value of integers) { + assert.true(isInteger(value), `isInteger ${ typeof value } ${ value }`); + } + const notIntegers = [ + NaN, + 0.1, + Infinity, + 'NaN', + '5', + false, + new Number(NaN), + new Number(Infinity), + new Number(5), + new Number(0.1), + undefined, + null, + {}, + function () { /* empty */ }, + ]; + for (const value of notIntegers) { + assert.false(isInteger(value), `not isInteger ${ typeof value } ${ value }`); + } + assert.false(isInteger(create(null)), 'Number.isInteger(Object.create(null)) -> false'); +}); diff --git a/tests/unit-pure/es.number.is-nan.js b/tests/unit-pure/es.number.is-nan.js new file mode 100644 index 000000000000..502e1fccacf8 --- /dev/null +++ b/tests/unit-pure/es.number.is-nan.js @@ -0,0 +1,35 @@ +import create from 'core-js-pure/es/object/create'; +import isNaN from 'core-js-pure/es/number/is-nan'; + +QUnit.test('Number.isNaN', assert => { + assert.isFunction(isNaN); + assert.true(isNaN(NaN), 'Number.isNaN NaN'); + const notNaNs = [ + 1, + 0.1, + -1, + 2 ** 16, + 2 ** 16 - 1, + 2 ** 31, + 2 ** 31 - 1, + 2 ** 32, + 2 ** 32 - 1, + -0, + Infinity, + 'NaN', + '5', + false, + new Number(NaN), + new Number(Infinity), + new Number(5), + new Number(0.1), + undefined, + null, + {}, + function () { /* empty */ }, + ]; + for (const value of notNaNs) { + assert.false(isNaN(value), `not Number.isNaN ${ typeof value } ${ value }`); + } + assert.false(isNaN(create(null)), 'Number.isNaN(Object.create(null)) -> false'); +}); diff --git a/tests/unit-pure/es.number.is-safe-integer.js b/tests/unit-pure/es.number.is-safe-integer.js new file mode 100644 index 000000000000..3854dcad9651 --- /dev/null +++ b/tests/unit-pure/es.number.is-safe-integer.js @@ -0,0 +1,45 @@ +import { MAX_SAFE_INTEGER, MIN_SAFE_INTEGER } from '../helpers/constants.js'; +import create from 'core-js-pure/es/object/create'; +import isSafeInteger from 'core-js-pure/es/number/is-safe-integer'; + +QUnit.test('Number.isSafeInteger', assert => { + assert.isFunction(isSafeInteger); + const safeIntegers = [ + 1, + -1, + 2 ** 16, + 2 ** 16 - 1, + 2 ** 31, + 2 ** 31 - 1, + 2 ** 32, + 2 ** 32 - 1, + -0, + MAX_SAFE_INTEGER, + MIN_SAFE_INTEGER, + ]; + for (const value of safeIntegers) { + assert.true(isSafeInteger(value), `isSafeInteger ${ typeof value } ${ value }`); + } + const notSafeIntegers = [ + MAX_SAFE_INTEGER + 1, + MIN_SAFE_INTEGER - 1, + NaN, + 0.1, + Infinity, + 'NaN', + '5', + false, + new Number(NaN), + new Number(Infinity), + new Number(5), + new Number(0.1), + undefined, + null, + {}, + function () { /* empty */ }, + ]; + for (const value of notSafeIntegers) { + assert.false(isSafeInteger(value), `not isSafeInteger ${ typeof value } ${ value }`); + } + assert.false(isSafeInteger(create(null)), 'Number.isSafeInteger(Object.create(null)) -> false'); +}); diff --git a/tests/unit-pure/es.number.max-safe-integer.js b/tests/unit-pure/es.number.max-safe-integer.js new file mode 100644 index 000000000000..ed535a190f3d --- /dev/null +++ b/tests/unit-pure/es.number.max-safe-integer.js @@ -0,0 +1,5 @@ +import MAX_SAFE_INTEGER from 'core-js-pure/es/number/max-safe-integer'; + +QUnit.test('Number.MAX_SAFE_INTEGER', assert => { + assert.same(MAX_SAFE_INTEGER, 2 ** 53 - 1, 'Is 2^53 - 1'); +}); diff --git a/tests/unit-pure/es.number.min-safe-integer.js b/tests/unit-pure/es.number.min-safe-integer.js new file mode 100644 index 000000000000..2c34e4734e0e --- /dev/null +++ b/tests/unit-pure/es.number.min-safe-integer.js @@ -0,0 +1,5 @@ +import MIN_SAFE_INTEGER from 'core-js-pure/es/number/min-safe-integer'; + +QUnit.test('Number.MIN_SAFE_INTEGER', assert => { + assert.same(MIN_SAFE_INTEGER, -(2 ** 53) + 1, 'Is -2^53 + 1'); +}); diff --git a/tests/unit-pure/es.number.parse-float.js b/tests/unit-pure/es.number.parse-float.js new file mode 100644 index 000000000000..1735bd23032c --- /dev/null +++ b/tests/unit-pure/es.number.parse-float.js @@ -0,0 +1,25 @@ +import { WHITESPACES } from '../helpers/constants.js'; + +import parseFloat from 'core-js-pure/es/number/parse-float'; + +QUnit.test('Number.parseFloat', assert => { + assert.isFunction(parseFloat); + assert.arity(parseFloat, 1); + assert.same(parseFloat('0'), 0); + assert.same(parseFloat(' 0'), 0); + assert.same(parseFloat('+0'), 0); + assert.same(parseFloat(' +0'), 0); + assert.same(parseFloat('-0'), -0); + assert.same(parseFloat(' -0'), -0); + assert.same(parseFloat(`${ WHITESPACES }+0`), 0); + assert.same(parseFloat(`${ WHITESPACES }-0`), -0); + assert.same(parseFloat(null), NaN); + assert.same(parseFloat(undefined), NaN); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('Number.parseFloat test'); + assert.throws(() => parseFloat(symbol), 'throws on symbol argument'); + assert.throws(() => parseFloat(Object(symbol)), 'throws on boxed symbol argument'); + } +}); diff --git a/tests/unit-pure/es.number.parse-int.js b/tests/unit-pure/es.number.parse-int.js new file mode 100644 index 000000000000..6d149e0ee532 --- /dev/null +++ b/tests/unit-pure/es.number.parse-int.js @@ -0,0 +1,43 @@ +/* eslint-disable prefer-numeric-literals -- required for testing */ +import { WHITESPACES } from '../helpers/constants.js'; + +import parseInt from 'core-js-pure/es/number/parse-int'; + +QUnit.test('Number.parseInt', assert => { + assert.isFunction(parseInt); + assert.arity(parseInt, 2); + for (let radix = 2; radix <= 36; ++radix) { + assert.same(parseInt('10', radix), radix, `radix ${ radix }`); + } + const strings = ['01', '08', '10', '42']; + for (const string of strings) { + assert.same(parseInt(string), parseInt(string, 10), `default radix is 10: ${ string }`); + } + assert.same(parseInt('0x16'), parseInt('0x16', 16), 'default radix is 16: 0x16'); + assert.same(parseInt(' 0x16'), parseInt('0x16', 16), 'ignores leading whitespace #1'); + assert.same(parseInt(' 42'), parseInt('42', 10), 'ignores leading whitespace #2'); + assert.same(parseInt(' 08'), parseInt('08', 10), 'ignores leading whitespace #3'); + assert.same(parseInt(`${ WHITESPACES }08`), parseInt('08', 10), 'ignores leading whitespace #4'); + assert.same(parseInt(`${ WHITESPACES }0x16`), parseInt('0x16', 16), 'ignores leading whitespace #5'); + const fakeZero = { + valueOf() { + return 0; + }, + }; + assert.same(parseInt('08', fakeZero), parseInt('08', 10), 'valueOf #1'); + assert.same(parseInt('0x16', fakeZero), parseInt('0x16', 16), 'valueOf #2'); + assert.same(parseInt('-0xF'), -15, 'signed hex #1'); + assert.same(parseInt('-0xF', 16), -15, 'signed hex #2'); + assert.same(parseInt('+0xF'), 15, 'signed hex #3'); + assert.same(parseInt('+0xF', 16), 15, 'signed hex #4'); + assert.same(parseInt('10', -4294967294), 2, 'radix uses ToUint32'); + assert.same(parseInt(null), NaN); + assert.same(parseInt(undefined), NaN); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('Number.parseInt test'); + assert.throws(() => parseInt(symbol), 'throws on symbol argument'); + assert.throws(() => parseInt(Object(symbol)), 'throws on boxed symbol argument'); + } +}); diff --git a/tests/unit-pure/es.number.to-exponential.js b/tests/unit-pure/es.number.to-exponential.js new file mode 100644 index 000000000000..b06687bd9fa6 --- /dev/null +++ b/tests/unit-pure/es.number.to-exponential.js @@ -0,0 +1,135 @@ +import toExponential from 'core-js-pure/es/number/virtual/to-exponential'; + +QUnit.test('Number#toExponential', assert => { + assert.isFunction(toExponential); + + assert.same(toExponential.call(0.00008, 3), '8.000e-5'); + assert.same(toExponential.call(0.9, 0), '9e-1'); + assert.same(toExponential.call(1.255, 2), '1.25e+0'); + assert.same(toExponential.call(1843654265.0774949, 5), '1.84365e+9'); + assert.same(toExponential.call(1000000000000000128.0, 0), '1e+18'); + + assert.same(toExponential.call(1), '1e+0'); + assert.same(toExponential.call(1, 0), '1e+0'); + assert.same(toExponential.call(1, 1), '1.0e+0'); + assert.same(toExponential.call(1, 1.1), '1.0e+0'); + assert.same(toExponential.call(1, 0.9), '1e+0'); + assert.same(toExponential.call(1, '0'), '1e+0'); + assert.same(toExponential.call(1, '1'), '1.0e+0'); + assert.same(toExponential.call(1, '1.1'), '1.0e+0'); + assert.same(toExponential.call(1, '0.9'), '1e+0'); + assert.same(toExponential.call(1, NaN), '1e+0'); + assert.same(toExponential.call(1, 'some string'), '1e+0'); + assert.notThrows(() => toExponential.call(1, -0.1) === '1e+0'); + assert.same(toExponential.call(new Number(1)), '1e+0'); + assert.same(toExponential.call(new Number(1), 0), '1e+0'); + assert.same(toExponential.call(new Number(1), 1), '1.0e+0'); + assert.same(toExponential.call(new Number(1), 1.1), '1.0e+0'); + assert.same(toExponential.call(new Number(1), 0.9), '1e+0'); + assert.same(toExponential.call(new Number(1), '0'), '1e+0'); + assert.same(toExponential.call(new Number(1), '1'), '1.0e+0'); + assert.same(toExponential.call(new Number(1), '1.1'), '1.0e+0'); + assert.same(toExponential.call(new Number(1), '0.9'), '1e+0'); + assert.same(toExponential.call(new Number(1), NaN), '1e+0'); + assert.same(toExponential.call(new Number(1), 'some string'), '1e+0'); + assert.notThrows(() => toExponential.call(new Number(1), -0.1) === '1e+0'); + assert.same(toExponential.call(NaN), 'NaN'); + assert.same(toExponential.call(NaN, 0), 'NaN'); + assert.same(toExponential.call(NaN, 1), 'NaN'); + assert.same(toExponential.call(NaN, 1.1), 'NaN'); + assert.same(toExponential.call(NaN, 0.9), 'NaN'); + assert.same(toExponential.call(NaN, '0'), 'NaN'); + assert.same(toExponential.call(NaN, '1'), 'NaN'); + assert.same(toExponential.call(NaN, '1.1'), 'NaN'); + assert.same(toExponential.call(NaN, '0.9'), 'NaN'); + assert.same(toExponential.call(NaN, NaN), 'NaN'); + assert.same(toExponential.call(NaN, 'some string'), 'NaN'); + assert.notThrows(() => toExponential.call(NaN, -0.1) === 'NaN'); + + assert.same(toExponential.call(new Number(1e21)), '1e+21'); + assert.same(toExponential.call(new Number(1e21), 0), '1e+21'); + assert.same(toExponential.call(new Number(1e21), 1), '1.0e+21'); + assert.same(toExponential.call(new Number(1e21), 1.1), '1.0e+21'); + assert.same(toExponential.call(new Number(1e21), 0.9), '1e+21'); + assert.same(toExponential.call(new Number(1e21), '0'), '1e+21'); + assert.same(toExponential.call(new Number(1e21), '1'), '1.0e+21'); + assert.same(toExponential.call(new Number(1e21), '1.1'), '1.0e+21'); + assert.same(toExponential.call(new Number(1e21), '0.9'), '1e+21'); + assert.same(toExponential.call(new Number(1e21), NaN), '1e+21'); + assert.same(toExponential.call(new Number(1e21), 'some string'), '1e+21'); + + assert.same(toExponential.call(5, 19), '5.0000000000000000000e+0'); + + // ported from tests262, the license: https://github.com/tc39/test262/blob/main/LICENSE + assert.same(toExponential.call(123.456, 0), '1e+2'); + assert.same(toExponential.call(123.456, 1), '1.2e+2'); + assert.same(toExponential.call(123.456, 2), '1.23e+2'); + assert.same(toExponential.call(123.456, 3), '1.235e+2'); + assert.same(toExponential.call(123.456, 4), '1.2346e+2'); + assert.same(toExponential.call(123.456, 5), '1.23456e+2'); + assert.same(toExponential.call(123.456, 6), '1.234560e+2'); + assert.same(toExponential.call(123.456, 7), '1.2345600e+2'); + // assert.same(toExponential.call(123.456, 17), '1.23456000000000003e+2'); + // assert.same(toExponential.call(123.456, 20), '1.23456000000000003070e+2'); + + assert.same(toExponential.call(-123.456, 0), '-1e+2'); + assert.same(toExponential.call(-123.456, 1), '-1.2e+2'); + assert.same(toExponential.call(-123.456, 2), '-1.23e+2'); + assert.same(toExponential.call(-123.456, 3), '-1.235e+2'); + assert.same(toExponential.call(-123.456, 4), '-1.2346e+2'); + assert.same(toExponential.call(-123.456, 5), '-1.23456e+2'); + assert.same(toExponential.call(-123.456, 6), '-1.234560e+2'); + assert.same(toExponential.call(-123.456, 7), '-1.2345600e+2'); + // assert.same(toExponential.call(-123.456, 17), '-1.23456000000000003e+2'); + // assert.same(toExponential.call(-123.456, 20), '-1.23456000000000003070e+2'); + + assert.same(toExponential.call(0.0001, 0), '1e-4'); + assert.same(toExponential.call(0.0001, 1), '1.0e-4'); + assert.same(toExponential.call(0.0001, 2), '1.00e-4'); + assert.same(toExponential.call(0.0001, 3), '1.000e-4'); + assert.same(toExponential.call(0.0001, 4), '1.0000e-4'); + // assert.same(toExponential.call(0.0001, 16), '1.0000000000000000e-4'); + // assert.same(toExponential.call(0.0001, 17), '1.00000000000000005e-4'); + // assert.same(toExponential.call(0.0001, 18), '1.000000000000000048e-4'); + // assert.same(toExponential.call(0.0001, 19), '1.0000000000000000479e-4'); + // assert.same(toExponential.call(0.0001, 20), '1.00000000000000004792e-4'); + + assert.same(toExponential.call(0.9999, 0), '1e+0'); + assert.same(toExponential.call(0.9999, 1), '1.0e+0'); + assert.same(toExponential.call(0.9999, 2), '1.00e+0'); + assert.same(toExponential.call(0.9999, 3), '9.999e-1'); + assert.same(toExponential.call(0.9999, 4), '9.9990e-1'); + // assert.same(toExponential.call(0.9999, 16), '9.9990000000000001e-1'); + // assert.same(toExponential.call(0.9999, 17), '9.99900000000000011e-1'); + // assert.same(toExponential.call(0.9999, 18), '9.999000000000000110e-1'); + // assert.same(toExponential.call(0.9999, 19), '9.9990000000000001101e-1'); + // assert.same(toExponential.call(0.9999, 20), '9.99900000000000011013e-1'); + + assert.same(toExponential.call(25, 0), '3e+1'); // FF86- and Chrome 49-50 bugs + assert.same(toExponential.call(12345, 3), '1.235e+4'); // FF86- and Chrome 49-50 bugs + + assert.same(toExponential.call(Number.prototype, 0), '0e+0', 'Number.prototype, 0'); + assert.same(toExponential.call(0, 0), '0e+0', '0, 0'); + assert.same(toExponential.call(-0, 0), '0e+0', '-0, 0'); + assert.same(toExponential.call(0, -0), '0e+0', '0, -0'); + assert.same(toExponential.call(-0, -0), '0e+0', '-0, -0'); + assert.same(toExponential.call(0, 1), '0.0e+0', '0 and 1'); + assert.same(toExponential.call(0, 2), '0.00e+0', '0 and 2'); + assert.same(toExponential.call(0, 7), '0.0000000e+0', '0 and 7'); + assert.same(toExponential.call(0, 20), '0.00000000000000000000e+0', '0 and 20'); + assert.same(toExponential.call(-0, 1), '0.0e+0', '-0 and 1'); + assert.same(toExponential.call(-0, 2), '0.00e+0', '-0 and 2'); + assert.same(toExponential.call(-0, 7), '0.0000000e+0', '-0 and 7'); + assert.same(toExponential.call(-0, 20), '0.00000000000000000000e+0', '-0 and 20'); + + assert.same(toExponential.call(NaN, 1000), 'NaN', 'NaN check before fractionDigits check'); + assert.same(toExponential.call(Infinity, 1000), 'Infinity', 'Infinity check before fractionDigits check'); + assert.notThrows(() => toExponential.call(new Number(1e21), -0.1) === '1e+21'); + assert.throws(() => toExponential.call(1.0, -101), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => toExponential.call(1.0, 101), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => toExponential.call({}, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toExponential.call('123', 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toExponential.call(false, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toExponential.call(null, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toExponential.call(undefined, 1), TypeError, '? thisNumberValue(this value)'); +}); diff --git a/tests/unit-pure/es.number.to-fixed.js b/tests/unit-pure/es.number.to-fixed.js new file mode 100644 index 000000000000..80ca3097f39d --- /dev/null +++ b/tests/unit-pure/es.number.to-fixed.js @@ -0,0 +1,66 @@ +import toFixed from 'core-js-pure/es/number/to-fixed'; + +QUnit.test('Number#toFixed', assert => { + assert.isFunction(toFixed); + assert.same(toFixed(0.00008, 3), '0.000'); + assert.same(toFixed(0.9, 0), '1'); + assert.same(toFixed(1.255, 2), '1.25'); + assert.same(toFixed(1843654265.0774949, 5), '1843654265.07749'); + assert.same(toFixed(1000000000000000128, 0), '1000000000000000128'); + assert.same(toFixed(1), '1'); + assert.same(toFixed(1, 0), '1'); + assert.same(toFixed(1, 1), '1.0'); + assert.same(toFixed(1, 1.1), '1.0'); + assert.same(toFixed(1, 0.9), '1'); + assert.same(toFixed(1, '0'), '1'); + assert.same(toFixed(1, '1'), '1.0'); + assert.same(toFixed(1, '1.1'), '1.0'); + assert.same(toFixed(1, '0.9'), '1'); + assert.same(toFixed(1, NaN), '1'); + assert.same(toFixed(1, 'some string'), '1'); + assert.notThrows(() => toFixed(1, -0.1) === '1'); + assert.same(toFixed(Object(1)), '1'); + assert.same(toFixed(Object(1), 0), '1'); + assert.same(toFixed(Object(1), 1), '1.0'); + assert.same(toFixed(Object(1), 1.1), '1.0'); + assert.same(toFixed(Object(1), 0.9), '1'); + assert.same(toFixed(Object(1), '0'), '1'); + assert.same(toFixed(Object(1), '1'), '1.0'); + assert.same(toFixed(Object(1), '1.1'), '1.0'); + assert.same(toFixed(Object(1), '0.9'), '1'); + assert.same(toFixed(Object(1), NaN), '1'); + assert.same(toFixed(Object(1), 'some string'), '1'); + assert.notThrows(() => toFixed(Object(1), -0.1) === '1'); + assert.same(toFixed(NaN), 'NaN'); + assert.same(toFixed(NaN, 0), 'NaN'); + assert.same(toFixed(NaN, 1), 'NaN'); + assert.same(toFixed(NaN, 1.1), 'NaN'); + assert.same(toFixed(NaN, 0.9), 'NaN'); + assert.same(toFixed(NaN, '0'), 'NaN'); + assert.same(toFixed(NaN, '1'), 'NaN'); + assert.same(toFixed(NaN, '1.1'), 'NaN'); + assert.same(toFixed(NaN, '0.9'), 'NaN'); + assert.same(toFixed(NaN, NaN), 'NaN'); + assert.same(toFixed(NaN, 'some string'), 'NaN'); + assert.notThrows(() => toFixed(NaN, -0.1) === 'NaN'); + assert.same(toFixed(1e21), String(1e21)); + assert.same(toFixed(1e21, 0), String(1e21)); + assert.same(toFixed(1e21, 1), String(1e21)); + assert.same(toFixed(1e21, 1.1), String(1e21)); + assert.same(toFixed(1e21, 0.9), String(1e21)); + assert.same(toFixed(1e21, '0'), String(1e21)); + assert.same(toFixed(1e21, '1'), String(1e21)); + assert.same(toFixed(1e21, '1.1'), String(1e21)); + assert.same(toFixed(1e21, '0.9'), String(1e21)); + assert.same(toFixed(1e21, NaN), String(1e21)); + assert.same(toFixed(1e21, 'some string'), String(1e21)); + assert.notThrows(() => toFixed(1e21, -0.1) === String(1e21)); + assert.throws(() => toFixed(1, -101), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => toFixed(1, 101), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => toFixed(NaN, Infinity), RangeError, 'If f < 0 or f > 20 (100), throw a RangeError exception.'); + assert.throws(() => toFixed({}, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toFixed('123', 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toFixed(false, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toFixed(null, 1), TypeError, '? thisNumberValue(this value)'); + assert.throws(() => toFixed(undefined, 1), TypeError, '? thisNumberValue(this value)'); +}); diff --git a/tests/pure/es.number.to-precision.js b/tests/unit-pure/es.number.to-precision.js similarity index 94% rename from tests/pure/es.number.to-precision.js rename to tests/unit-pure/es.number.to-precision.js index 606d6fa3ed20..a1f09f356546 100644 --- a/tests/pure/es.number.to-precision.js +++ b/tests/unit-pure/es.number.to-precision.js @@ -1,4 +1,4 @@ -import toPrecision from 'core-js-pure/features/number/to-precision'; +import toPrecision from 'core-js-pure/es/number/to-precision'; QUnit.test('Number#toPrecision', assert => { assert.isFunction(toPrecision); diff --git a/tests/unit-pure/es.object.assign.js b/tests/unit-pure/es.object.assign.js new file mode 100644 index 000000000000..d80e5e6b0306 --- /dev/null +++ b/tests/unit-pure/es.object.assign.js @@ -0,0 +1,66 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import keys from 'core-js-pure/es/object/keys'; +import assign from 'core-js-pure/es/object/assign'; + +QUnit.test('Object.assign', assert => { + assert.isFunction(assign); + let object = { q: 1 }; + assert.same(object, assign(object, { bar: 2 }), 'assign return target'); + assert.same(object.bar, 2, 'assign define properties'); + assert.deepEqual(assign({}, { q: 1 }, { w: 2 }), { q: 1, w: 2 }); + assert.deepEqual(assign({}, 'qwe'), { 0: 'q', 1: 'w', 2: 'e' }); + assert.throws(() => assign(null, { q: 1 }), TypeError); + assert.throws(() => assign(undefined, { q: 1 }), TypeError); + let string = assign('qwe', { q: 1 }); + assert.same(typeof string, 'object'); + assert.same(String(string), 'qwe'); + assert.same(string.q, 1); + assert.same(assign({}, { valueOf: 42 }).valueOf, 42, 'IE enum keys bug'); + if (DESCRIPTORS) { + object = { baz: 1 }; + assign(object, defineProperty({}, 'bar', { + get() { + return this.baz + 1; + }, + })); + assert.same(object.bar, undefined, "assign don't copy descriptors"); + object = { a: 'a' }; + const c = Symbol('c'); + const d = Symbol('d'); + object[c] = 'c'; + defineProperty(object, 'b', { value: 'b' }); + defineProperty(object, d, { value: 'd' }); + const object2 = assign({}, object); + assert.same(object2.a, 'a', 'a'); + assert.same(object2.b, undefined, 'b'); + assert.same(object2[c], 'c', 'c'); + assert.same(object2[d], undefined, 'd'); + try { + assert.same(Function('assign', ` + return assign({ b: 1 }, { get a() { + delete this.b; + }, b: 2 }); + `)(assign).b, 1); + } catch { /* empty */ } + try { + assert.same(Function('assign', ` + return assign({ b: 1 }, { get a() { + Object.defineProperty(this, "b", { + value: 4, + enumerable: false + }); + }, b: 2 }); + `)(assign).b, 1); + } catch { /* empty */ } + } + string = 'abcdefghijklmnopqrst'; + const result = {}; + for (let i = 0, { length } = string; i < length; ++i) { + const chr = string.charAt(i); + result[chr] = chr; + } + assert.same(keys(assign({}, result)).join(''), string); +}); diff --git a/tests/unit-pure/es.object.create.js b/tests/unit-pure/es.object.create.js new file mode 100644 index 000000000000..2589f6443713 --- /dev/null +++ b/tests/unit-pure/es.object.create.js @@ -0,0 +1,36 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import create from 'core-js-pure/es/object/create'; + +QUnit.test('Object.create', assert => { + function getPropertyNames(object) { + let result = []; + do { + result = result.concat(getOwnPropertyNames(object)); + } while (object = getPrototypeOf(object)); + return result; + } + assert.isFunction(create); + assert.arity(create, 2); + let object = { q: 1 }; + assert.true({}.isPrototypeOf.call(object, create(object))); + assert.same(create(object).q, 1); + function C() { + return this.a = 1; + } + assert.true(create(new C()) instanceof C); + assert.same(C.prototype, getPrototypeOf(getPrototypeOf(create(new C())))); + assert.same(create(new C()).a, 1); + assert.same(create({}, { a: { value: 42 } }).a, 42); + object = create(null, { w: { value: 2 } }); + assert.same(object, Object(object)); + assert.false(('toString' in object)); + assert.same(object.w, 2); + assert.deepEqual(getPropertyNames(create(null)), []); +}); + +QUnit.test('Object.create.sham flag', assert => { + assert.same(create.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-pure/es.object.define-getter.js b/tests/unit-pure/es.object.define-getter.js new file mode 100644 index 000000000000..8141a7b4dd49 --- /dev/null +++ b/tests/unit-pure/es.object.define-getter.js @@ -0,0 +1,24 @@ +/* eslint-disable id-match -- unification with global tests */ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +import __defineGetter__ from 'core-js-pure/es/object/define-getter'; +import __defineSetter__ from 'core-js-pure/es/object/define-setter'; + +if (DESCRIPTORS) { + QUnit.test('Object#__defineGetter__', assert => { + assert.isFunction(__defineGetter__); + const object = {}; + assert.same(__defineGetter__(object, 'key', () => 42), undefined, 'void'); + assert.same(object.key, 42, 'works'); + __defineSetter__(object, 'key', function () { + this.foo = 43; + }); + object.key = 44; + assert.same(object.key, 42, 'works with setter #1'); + assert.same(object.foo, 43, 'works with setter #2'); + if (STRICT) { + assert.throws(() => __defineGetter__(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); + assert.throws(() => __defineGetter__(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); + } + }); +} diff --git a/tests/unit-pure/es.object.define-properties.js b/tests/unit-pure/es.object.define-properties.js new file mode 100644 index 000000000000..0aee4cf19a5c --- /dev/null +++ b/tests/unit-pure/es.object.define-properties.js @@ -0,0 +1,25 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import defineProperties from 'core-js-pure/es/object/define-properties'; + +QUnit.test('Object.defineProperties', assert => { + assert.isFunction(defineProperties); + assert.arity(defineProperties, 2); + const source = {}; + const result = defineProperties(source, { q: { value: 42 }, w: { value: 33 } }); + assert.same(result, source); + assert.same(result.q, 42); + assert.same(result.w, 33); + + if (DESCRIPTORS) { + // eslint-disable-next-line prefer-arrow-callback -- required for testing + assert.same(defineProperties(function () { /* empty */ }, { prototype: { + value: 42, + writable: false, + } }).prototype, 42, 'function prototype with non-writable descriptor'); + } +}); + +QUnit.test('Object.defineProperties.sham flag', assert => { + assert.same(defineProperties.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-pure/es.object.define-property.js b/tests/unit-pure/es.object.define-property.js new file mode 100644 index 000000000000..f4c7a05217af --- /dev/null +++ b/tests/unit-pure/es.object.define-property.js @@ -0,0 +1,31 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import create from 'core-js-pure/es/object/create'; +import defineProperty from 'core-js-pure/es/object/define-property'; + +QUnit.test('Object.defineProperty', assert => { + assert.isFunction(defineProperty); + assert.arity(defineProperty, 3); + const source = {}; + const result = defineProperty(source, 'q', { + value: 42, + }); + assert.same(result, source); + assert.same(result.q, 42); + + if (DESCRIPTORS) { + // eslint-disable-next-line prefer-arrow-callback -- required for testing + assert.same(defineProperty(function () { /* empty */ }, 'prototype', { + value: 42, + writable: false, + }).prototype, 42, 'function prototype with non-writable descriptor'); + } + + assert.throws(() => defineProperty(42, 1, {})); + assert.throws(() => defineProperty({}, create(null), {})); + assert.throws(() => defineProperty({}, 1, 1)); +}); + +QUnit.test('Object.defineProperty.sham flag', assert => { + assert.same(defineProperty.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-pure/es.object.define-setter.js b/tests/unit-pure/es.object.define-setter.js new file mode 100644 index 000000000000..40aa1362b197 --- /dev/null +++ b/tests/unit-pure/es.object.define-setter.js @@ -0,0 +1,29 @@ +/* eslint-disable id-match -- unification with global tests */ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +import __defineGetter__ from 'core-js-pure/es/object/define-getter'; +import __defineSetter__ from 'core-js-pure/es/object/define-setter'; + +if (DESCRIPTORS) { + QUnit.test('Object#__defineSetter__', assert => { + assert.isFunction(__defineSetter__); + let object = {}; + assert.same(__defineSetter__(object, 'key', function () { + this.foo = 43; + }), undefined, 'void'); + object.key = 44; + assert.same(object.foo, 43, 'works'); + object = {}; + __defineSetter__(object, 'key', function () { + this.foo = 43; + }); + __defineGetter__(object, 'key', () => 42); + object.key = 44; + assert.same(object.key, 42, 'works with getter #1'); + assert.same(object.foo, 43, 'works with getter #2'); + if (STRICT) { + assert.throws(() => __defineSetter__(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); + assert.throws(() => __defineSetter__(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); + } + }); +} diff --git a/tests/pure/es.object.entries.js b/tests/unit-pure/es.object.entries.js similarity index 86% rename from tests/pure/es.object.entries.js rename to tests/unit-pure/es.object.entries.js index c0d1bf6ace1f..039c56e30096 100644 --- a/tests/pure/es.object.entries.js +++ b/tests/unit-pure/es.object.entries.js @@ -1,4 +1,6 @@ -import { entries, create, assign } from 'core-js-pure/features/object'; +import assign from 'core-js-pure/es/object/assign'; +import create from 'core-js-pure/es/object/create'; +import entries from 'core-js-pure/es/object/entries'; QUnit.test('Object.entries', assert => { assert.isFunction(entries); diff --git a/tests/unit-pure/es.object.freeze.js b/tests/unit-pure/es.object.freeze.js new file mode 100644 index 000000000000..9d56f12d7e0f --- /dev/null +++ b/tests/unit-pure/es.object.freeze.js @@ -0,0 +1,22 @@ +import ownKeys from 'core-js-pure/es/reflect/own-keys'; +import keys from 'core-js-pure/es/object/keys'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import freeze from 'core-js-pure/es/object/freeze'; + +QUnit.test('Object.freeze', assert => { + assert.isFunction(freeze); + assert.arity(freeze, 1); + const data = [42, 'foo', false, null, undefined, {}]; + for (const value of data) { + assert.notThrows(() => freeze(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); + assert.same(freeze(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); + } + const results = []; + for (const key in freeze({})) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(freeze({})), []); + assert.arrayEqual(getOwnPropertyNames(freeze({})), []); + assert.arrayEqual(getOwnPropertySymbols(freeze({})), []); + assert.arrayEqual(ownKeys(freeze({})), []); +}); diff --git a/tests/unit-pure/es.object.from-entries.js b/tests/unit-pure/es.object.from-entries.js new file mode 100644 index 000000000000..a1ff42e8f6af --- /dev/null +++ b/tests/unit-pure/es.object.from-entries.js @@ -0,0 +1,28 @@ +import { createIterable } from '../helpers/helpers.js'; + +import Set from 'core-js-pure/es/set'; +import fromEntries from 'core-js-pure/es/object/from-entries'; + +QUnit.test('Object.fromEntries', assert => { + assert.isFunction(fromEntries); + assert.arity(fromEntries, 1); + assert.name(fromEntries, 'fromEntries'); + + assert.true(fromEntries([]) instanceof Object); + assert.same(fromEntries([['foo', 1]]).foo, 1); + assert.same(fromEntries(createIterable([['bar', 2]])).bar, 2); + + class Unit { + constructor(id) { + this.id = id; + } + toString() { + return `unit${ this.id }`; + } + } + const units = new Set([new Unit(101), new Unit(102), new Unit(103)]); + const object = fromEntries(units.entries()); + assert.same(object.unit101.id, 101); + assert.same(object.unit102.id, 102); + assert.same(object.unit103.id, 103); +}); diff --git a/tests/unit-pure/es.object.get-own-property-descriptor.js b/tests/unit-pure/es.object.get-own-property-descriptor.js new file mode 100644 index 000000000000..b26b69d511aa --- /dev/null +++ b/tests/unit-pure/es.object.get-own-property-descriptor.js @@ -0,0 +1,25 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import getOwnPropertyDescriptor from 'core-js-pure/es/object/get-own-property-descriptor'; + +QUnit.test('Object.getOwnPropertyDescriptor', assert => { + assert.isFunction(getOwnPropertyDescriptor); + assert.arity(getOwnPropertyDescriptor, 2); + assert.deepEqual(getOwnPropertyDescriptor({ q: 42 }, 'q'), { + writable: true, + enumerable: true, + configurable: true, + value: 42, + }); + assert.same(getOwnPropertyDescriptor({}, 'toString'), undefined); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => getOwnPropertyDescriptor(value) || true, `accept ${ typeof value }`); + } + assert.throws(() => getOwnPropertyDescriptor(null), TypeError, 'throws on null'); + assert.throws(() => getOwnPropertyDescriptor(undefined), TypeError, 'throws on undefined'); +}); + +QUnit.test('Object.getOwnPropertyDescriptor.sham flag', assert => { + assert.same(getOwnPropertyDescriptor.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-pure/es.object.get-own-property-descriptors.js b/tests/unit-pure/es.object.get-own-property-descriptors.js new file mode 100644 index 000000000000..ca70731b2cb6 --- /dev/null +++ b/tests/unit-pure/es.object.get-own-property-descriptors.js @@ -0,0 +1,41 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import create from 'core-js-pure/es/object/create'; +import getOwnPropertyDescriptors from 'core-js-pure/es/object/get-own-property-descriptors'; + +QUnit.test('Object.getOwnPropertyDescriptors', assert => { + assert.isFunction(getOwnPropertyDescriptors); + const object = create({ q: 1 }, { e: { value: 3 } }); + object.w = 2; + const symbol = Symbol('4'); + object[symbol] = 4; + const descriptors = getOwnPropertyDescriptors(object); + assert.same(descriptors.q, undefined); + assert.deepEqual(descriptors.w, { + enumerable: true, + configurable: true, + writable: true, + value: 2, + }); + if (DESCRIPTORS) { + assert.deepEqual(descriptors.e, { + enumerable: false, + configurable: false, + writable: false, + value: 3, + }); + } else { + assert.deepEqual(descriptors.e, { + enumerable: true, + configurable: true, + writable: true, + value: 3, + }); + } + assert.same(descriptors[symbol].value, 4); +}); + +QUnit.test('Object.getOwnPropertyDescriptors.sham flag', assert => { + assert.same(getOwnPropertyDescriptors.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-pure/es.object.get-own-property-names.js b/tests/unit-pure/es.object.get-own-property-names.js new file mode 100644 index 000000000000..6b2198d7d411 --- /dev/null +++ b/tests/unit-pure/es.object.get-own-property-names.js @@ -0,0 +1,46 @@ +import { includes } from '../helpers/helpers.js'; + +import freeze from 'core-js-pure/es/object/freeze'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; + +QUnit.test('Object.getOwnPropertyNames', assert => { + assert.isFunction(getOwnPropertyNames); + assert.arity(getOwnPropertyNames, 1); + function F1() { + this.w = 1; + } + function F2() { + this.toString = 1; + } + F1.prototype.q = F2.prototype.q = 1; + const names = getOwnPropertyNames([1, 2, 3]); + assert.same(names.length, 4); + assert.true(includes(names, '0')); + assert.true(includes(names, '1')); + assert.true(includes(names, '2')); + assert.true(includes(names, 'length')); + assert.deepEqual(getOwnPropertyNames(new F1()), ['w']); + assert.deepEqual(getOwnPropertyNames(new F2()), ['toString']); + assert.true(includes(getOwnPropertyNames(Array.prototype), 'toString')); + assert.true(includes(getOwnPropertyNames(Object.prototype), 'toString')); + assert.true(includes(getOwnPropertyNames(Object.prototype), 'constructor')); + assert.deepEqual(getOwnPropertyNames(freeze({})), [], 'frozen'); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => getOwnPropertyNames(value), `accept ${ typeof value }`); + } + assert.throws(() => getOwnPropertyNames(null), TypeError, 'throws on null'); + assert.throws(() => getOwnPropertyNames(undefined), TypeError, 'throws on undefined'); + /* Chakra bug + if (typeof document != 'undefined' && document.createElement) { + assert.notThrows(() => { + const iframe = document.createElement('iframe'); + iframe.src = 'http://example.com/'; + document.documentElement.appendChild(iframe); + const window = iframe.contentWindow; + document.documentElement.removeChild(iframe); + return getOwnPropertyNames(window); + }, 'IE11 bug with iframe and window'); + } + */ +}); diff --git a/tests/unit-pure/es.object.get-own-property-symbols.js b/tests/unit-pure/es.object.get-own-property-symbols.js new file mode 100644 index 000000000000..8dd757dbd116 --- /dev/null +++ b/tests/unit-pure/es.object.get-own-property-symbols.js @@ -0,0 +1,25 @@ +import create from 'core-js-pure/es/object/create'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Object.getOwnPropertySymbols', assert => { + assert.isFunction(getOwnPropertySymbols); + const prototype = { q: 1, w: 2, e: 3 }; + prototype[Symbol('getOwnPropertySymbols test 1')] = 42; + prototype[Symbol('getOwnPropertySymbols test 2')] = 43; + assert.deepEqual(getOwnPropertyNames(prototype).sort(), ['e', 'q', 'w']); + assert.same(getOwnPropertySymbols(prototype).length, 2); + const object = create(prototype); + object.a = 1; + object.s = 2; + object.d = 3; + object[Symbol('getOwnPropertySymbols test 3')] = 44; + assert.deepEqual(getOwnPropertyNames(object).sort(), ['a', 'd', 's']); + assert.same(getOwnPropertySymbols(object).length, 1); + assert.same(getOwnPropertySymbols(Object.prototype).length, 0); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => getOwnPropertySymbols(value), `accept ${ typeof value }`); + } +}); diff --git a/tests/unit-pure/es.object.get-prototype-of.js b/tests/unit-pure/es.object.get-prototype-of.js new file mode 100644 index 000000000000..48430b4ee0ee --- /dev/null +++ b/tests/unit-pure/es.object.get-prototype-of.js @@ -0,0 +1,34 @@ +import { CORRECT_PROTOTYPE_GETTER } from '../helpers/constants.js'; + +import create from 'core-js-pure/es/object/create'; +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; + +QUnit.test('Object.getPrototypeOf', assert => { + assert.isFunction(getPrototypeOf); + assert.arity(getPrototypeOf, 1); + assert.same(getPrototypeOf({}), Object.prototype); + assert.same(getPrototypeOf([]), Array.prototype); + function F() { /* empty */ } + assert.same(getPrototypeOf(new F()), F.prototype); + const object = { q: 1 }; + assert.same(getPrototypeOf(create(object)), object); + assert.same(getPrototypeOf(create(null)), null); + assert.same(getPrototypeOf(getPrototypeOf({})), null); + function Foo() { /* empty */ } + Foo.prototype.foo = 'foo'; + function Bar() { /* empty */ } + Bar.prototype = create(Foo.prototype); + Bar.prototype.constructor = Bar; + assert.same(getPrototypeOf(Bar.prototype).foo, 'foo'); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => getPrototypeOf(value), `accept ${ typeof value }`); + } + assert.throws(() => getPrototypeOf(null), TypeError, 'throws on null'); + assert.throws(() => getPrototypeOf(undefined), TypeError, 'throws on undefined'); + assert.same(getPrototypeOf('foo'), String.prototype); +}); + +QUnit.test('Object.getPrototypeOf.sham flag', assert => { + assert.same(getPrototypeOf.sham, CORRECT_PROTOTYPE_GETTER ? undefined : true); +}); diff --git a/tests/unit-pure/es.object.group-by.js b/tests/unit-pure/es.object.group-by.js new file mode 100644 index 000000000000..595d0042e910 --- /dev/null +++ b/tests/unit-pure/es.object.group-by.js @@ -0,0 +1,35 @@ +import { createIterable } from '../helpers/helpers.js'; +import groupBy from 'core-js-pure/es/object/group-by'; +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; +import entries from 'core-js-pure/es/object/entries'; +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Object.groupBy', assert => { + assert.isFunction(groupBy); + assert.arity(groupBy, 2); + assert.name(groupBy, 'groupBy'); + + assert.same(getPrototypeOf(groupBy([], it => it)), null); + + assert.deepEqual(entries(groupBy([], it => it)), []); + assert.deepEqual(entries(groupBy([1, 2], it => it ** 2)), [['1', [1]], ['4', [2]]]); + assert.deepEqual(entries(groupBy([1, 2, 1], it => it ** 2)), [['1', [1, 1]], ['4', [2]]]); + assert.deepEqual(entries(groupBy(createIterable([1, 2]), it => it ** 2)), [['1', [1]], ['4', [2]]]); + assert.deepEqual(entries(groupBy('qwe', it => it)), [['q', ['q']], ['w', ['w']], ['e', ['e']]], 'iterable string'); + + const element = {}; + groupBy([element], function (it, i) { + assert.same(arguments.length, 2); + assert.same(it, element); + assert.same(i, 0); + }); + + const even = Symbol('even'); + const odd = Symbol('odd'); + const grouped = groupBy([1, 2, 3, 4, 5, 6], num => { + if (num % 2 === 0) return even; + return odd; + }); + assert.deepEqual(grouped[even], [2, 4, 6]); + assert.deepEqual(grouped[odd], [1, 3, 5]); +}); diff --git a/tests/unit-pure/es.object.has-own.js b/tests/unit-pure/es.object.has-own.js new file mode 100644 index 000000000000..c5e81c5d2c60 --- /dev/null +++ b/tests/unit-pure/es.object.has-own.js @@ -0,0 +1,19 @@ +import create from 'core-js-pure/es/object/create'; +import hasOwn from 'core-js-pure/es/object/has-own'; + +QUnit.test('Object.hasOwn', assert => { + assert.isFunction(hasOwn); + assert.arity(hasOwn, 2); + assert.name(hasOwn, 'hasOwn'); + assert.true(hasOwn({ q: 42 }, 'q')); + assert.false(hasOwn({ q: 42 }, 'w')); + assert.false(hasOwn(create({ q: 42 }), 'q')); + assert.true(hasOwn(Object.prototype, 'hasOwnProperty')); + let called = false; + try { + hasOwn(null, { toString() { called = true; } }); + } catch { /* empty */ } + assert.false(called, 'modern behaviour'); + assert.throws(() => hasOwn(null, 'foo'), TypeError, 'throws on null'); + assert.throws(() => hasOwn(undefined, 'foo'), TypeError, 'throws on undefined'); +}); diff --git a/tests/unit-pure/es.object.is-extensible.js b/tests/unit-pure/es.object.is-extensible.js new file mode 100644 index 000000000000..e1750d914693 --- /dev/null +++ b/tests/unit-pure/es.object.is-extensible.js @@ -0,0 +1,12 @@ +import isExtensible from 'core-js-pure/es/object/is-extensible'; + +QUnit.test('Object.isExtensible', assert => { + assert.isFunction(isExtensible); + assert.arity(isExtensible, 1); + const primitives = [42, 'string', false, null, undefined]; + for (const value of primitives) { + assert.notThrows(() => isExtensible(value) || true, `accept ${ value }`); + assert.false(isExtensible(value), `returns false on ${ value }`); + } + assert.true(isExtensible({})); +}); diff --git a/tests/unit-pure/es.object.is-frozen.js b/tests/unit-pure/es.object.is-frozen.js new file mode 100644 index 000000000000..2127132ad672 --- /dev/null +++ b/tests/unit-pure/es.object.is-frozen.js @@ -0,0 +1,12 @@ +import isFrozen from 'core-js-pure/es/object/is-frozen'; + +QUnit.test('Object.isFrozen', assert => { + assert.isFunction(isFrozen); + assert.arity(isFrozen, 1); + const primitives = [42, 'string', false, null, undefined]; + for (const value of primitives) { + assert.notThrows(() => isFrozen(value) || true, `accept ${ value }`); + assert.true(isFrozen(value), `returns true on ${ value }`); + } + assert.false(isFrozen({})); +}); diff --git a/tests/unit-pure/es.object.is-sealed.js b/tests/unit-pure/es.object.is-sealed.js new file mode 100644 index 000000000000..af57709ba02d --- /dev/null +++ b/tests/unit-pure/es.object.is-sealed.js @@ -0,0 +1,12 @@ +import isSealed from 'core-js-pure/es/object/is-sealed'; + +QUnit.test('Object.isSealed', assert => { + assert.isFunction(isSealed); + assert.arity(isSealed, 1); + const primitives = [42, 'string', false, null, undefined]; + for (const value of primitives) { + assert.notThrows(() => isSealed(value) || true, `accept ${ value }`); + assert.true(isSealed(value), `returns true on ${ value }`); + } + assert.false(isSealed({})); +}); diff --git a/tests/unit-pure/es.object.is.js b/tests/unit-pure/es.object.is.js new file mode 100644 index 000000000000..805396b53b06 --- /dev/null +++ b/tests/unit-pure/es.object.is.js @@ -0,0 +1,9 @@ +import is from 'core-js-pure/es/object/is'; + +QUnit.test('Object.is', assert => { + assert.isFunction(is); + assert.true(is(1, 1), '1 is 1'); + assert.true(is(NaN, NaN), '1 is 1'); + assert.false(is(0, -0), '0 is not -0'); + assert.false(is({}, {}), '{} is not {}'); +}); diff --git a/tests/unit-pure/es.object.keys.js b/tests/unit-pure/es.object.keys.js new file mode 100644 index 000000000000..6ffa89cdff56 --- /dev/null +++ b/tests/unit-pure/es.object.keys.js @@ -0,0 +1,25 @@ +import { includes } from '../helpers/helpers.js'; + +import keys from 'core-js-pure/es/object/keys'; + +QUnit.test('Object.keys', assert => { + assert.isFunction(keys); + assert.arity(keys, 1); + function F1() { + this.w = 1; + } + function F2() { + this.toString = 1; + } + F1.prototype.q = F2.prototype.q = 1; + assert.deepEqual(keys([1, 2, 3]), ['0', '1', '2']); + assert.deepEqual(keys(new F1()), ['w']); + assert.deepEqual(keys(new F2()), ['toString']); + assert.false(includes(keys(Array.prototype), 'push')); + const primitives = [42, 'foo', false]; + for (const value of primitives) { + assert.notThrows(() => keys(value), `accept ${ typeof value }`); + } + assert.throws(() => keys(null), TypeError, 'throws on null'); + assert.throws(() => keys(undefined), TypeError, 'throws on undefined'); +}); diff --git a/tests/unit-pure/es.object.lookup-getter.js b/tests/unit-pure/es.object.lookup-getter.js new file mode 100644 index 000000000000..d1f9bb01c69e --- /dev/null +++ b/tests/unit-pure/es.object.lookup-getter.js @@ -0,0 +1,24 @@ +/* eslint-disable id-match -- unification with global tests */ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +import create from 'core-js-pure/es/object/create'; +import __defineGetter__ from 'core-js-pure/es/object/define-getter'; +import __lookupGetter__ from 'core-js-pure/es/object/lookup-getter'; + +if (DESCRIPTORS) { + QUnit.test('Object#__lookupGetter__', assert => { + assert.isFunction(__lookupGetter__); + assert.same(__lookupGetter__({}, 'key'), undefined, 'empty object'); + assert.same(__lookupGetter__({ key: 42 }, 'key'), undefined, 'data descriptor'); + const object = {}; + function getter() { /* empty */ } + __defineGetter__(object, 'key', getter); + assert.same(__lookupGetter__(object, 'key'), getter, 'own getter'); + assert.same(__lookupGetter__(create(object), 'key'), getter, 'proto getter'); + assert.same(__lookupGetter__(create(object), 'foo'), undefined, 'empty proto'); + if (STRICT) { + assert.throws(() => __lookupGetter__(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); + assert.throws(() => __lookupGetter__(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); + } + }); +} diff --git a/tests/unit-pure/es.object.lookup-setter.js b/tests/unit-pure/es.object.lookup-setter.js new file mode 100644 index 000000000000..e8ce5dbcd06a --- /dev/null +++ b/tests/unit-pure/es.object.lookup-setter.js @@ -0,0 +1,24 @@ +/* eslint-disable id-match -- unification with global tests */ +import { DESCRIPTORS, STRICT } from '../helpers/constants.js'; + +import create from 'core-js-pure/es/object/create'; +import __defineSetter__ from 'core-js-pure/es/object/define-setter'; +import __lookupSetter__ from 'core-js-pure/es/object/lookup-setter'; + +if (DESCRIPTORS) { + QUnit.test('Object#__lookupSetter__', assert => { + assert.isFunction(__lookupSetter__); + assert.same(__lookupSetter__({}, 'key'), undefined, 'empty object'); + assert.same(__lookupSetter__({ key: 42 }, 'key'), undefined, 'data descriptor'); + const object = {}; + function setter() { /* empty */ } + __defineSetter__(object, 'key', setter); + assert.same(__lookupSetter__(object, 'key'), setter, 'own getter'); + assert.same(__lookupSetter__(create(object), 'key'), setter, 'proto getter'); + assert.same(__lookupSetter__(create(object), 'foo'), undefined, 'empty proto'); + if (STRICT) { + assert.throws(() => __lookupSetter__(null, 1, () => { /* empty */ }), TypeError, 'Throws on null as `this`'); + assert.throws(() => __lookupSetter__(undefined, 1, () => { /* empty */ }), TypeError, 'Throws on undefined as `this`'); + } + }); +} diff --git a/tests/unit-pure/es.object.prevent-extensions.js b/tests/unit-pure/es.object.prevent-extensions.js new file mode 100644 index 000000000000..1418c35efebc --- /dev/null +++ b/tests/unit-pure/es.object.prevent-extensions.js @@ -0,0 +1,22 @@ +import ownKeys from 'core-js-pure/es/reflect/own-keys'; +import keys from 'core-js-pure/es/object/keys'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import preventExtensions from 'core-js-pure/es/object/prevent-extensions'; + +QUnit.test('Object.preventExtensions', assert => { + assert.isFunction(preventExtensions); + assert.arity(preventExtensions, 1); + const data = [42, 'foo', false, null, undefined, {}]; + for (const value of data) { + assert.notThrows(() => preventExtensions(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); + assert.same(preventExtensions(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); + } + const results = []; + for (const key in preventExtensions({})) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(preventExtensions({})), []); + assert.arrayEqual(getOwnPropertyNames(preventExtensions({})), []); + assert.arrayEqual(getOwnPropertySymbols(preventExtensions({})), []); + assert.arrayEqual(ownKeys(preventExtensions({})), []); +}); diff --git a/tests/unit-pure/es.object.seal.js b/tests/unit-pure/es.object.seal.js new file mode 100644 index 000000000000..a4e15e2b88b2 --- /dev/null +++ b/tests/unit-pure/es.object.seal.js @@ -0,0 +1,22 @@ +import ownKeys from 'core-js-pure/es/reflect/own-keys'; +import keys from 'core-js-pure/es/object/keys'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import seal from 'core-js-pure/es/object/seal'; + +QUnit.test('Object.seal', assert => { + assert.isFunction(seal); + assert.arity(seal, 1); + const data = [42, 'foo', false, null, undefined, {}]; + for (const value of data) { + assert.notThrows(() => seal(value) || true, `accept ${ {}.toString.call(value).slice(8, -1) }`); + assert.same(seal(value), value, `returns target on ${ {}.toString.call(value).slice(8, -1) }`); + } + const results = []; + for (const key in seal({})) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(seal({})), []); + assert.arrayEqual(getOwnPropertyNames(seal({})), []); + assert.arrayEqual(getOwnPropertySymbols(seal({})), []); + assert.arrayEqual(ownKeys(seal({})), []); +}); diff --git a/tests/unit-pure/es.object.set-prototype-of.js b/tests/unit-pure/es.object.set-prototype-of.js new file mode 100644 index 000000000000..24a8818b0db4 --- /dev/null +++ b/tests/unit-pure/es.object.set-prototype-of.js @@ -0,0 +1,16 @@ +import { PROTO } from '../helpers/constants.js'; + +import setPrototypeOf from 'core-js-pure/es/object/set-prototype-of'; + +if (PROTO) QUnit.test('Object.setPrototypeOf', assert => { + assert.isFunction(setPrototypeOf); + assert.true('apply' in setPrototypeOf({}, Function.prototype), 'Parent properties in target'); + assert.same(setPrototypeOf({ a: 2 }, { + b() { + return this.a ** 2; + }, + }).b(), 4, 'Child and parent properties in target'); + const object = {}; + assert.same(setPrototypeOf(object, { a: 1 }), object, 'setPrototypeOf return target'); + assert.false(('toString' in setPrototypeOf({}, null)), 'Can set null as prototype'); +}); diff --git a/tests/pure/es.object.values.js b/tests/unit-pure/es.object.values.js similarity index 85% rename from tests/pure/es.object.values.js rename to tests/unit-pure/es.object.values.js index 88d8e3f36540..6e4ae18e5d80 100644 --- a/tests/pure/es.object.values.js +++ b/tests/unit-pure/es.object.values.js @@ -1,4 +1,6 @@ -import { values, create, assign } from 'core-js-pure/features/object'; +import assign from 'core-js-pure/es/object/assign'; +import create from 'core-js-pure/es/object/create'; +import values from 'core-js-pure/es/object/values'; QUnit.test('Object.values', assert => { assert.isFunction(values); diff --git a/tests/unit-pure/es.parse-float.js b/tests/unit-pure/es.parse-float.js new file mode 100644 index 000000000000..ee0180d1bdd6 --- /dev/null +++ b/tests/unit-pure/es.parse-float.js @@ -0,0 +1,24 @@ +import { WHITESPACES } from '../helpers/constants.js'; +import parseFloat from 'core-js-pure/es/parse-float'; + +QUnit.test('parseFloat', assert => { + assert.isFunction(parseFloat); + assert.arity(parseFloat, 1); + assert.same(parseFloat('0'), 0); + assert.same(parseFloat(' 0'), 0); + assert.same(parseFloat('+0'), 0); + assert.same(parseFloat(' +0'), 0); + assert.same(parseFloat('-0'), -0); + assert.same(parseFloat(' -0'), -0); + assert.same(parseFloat(`${ WHITESPACES }+0`), 0); + assert.same(parseFloat(`${ WHITESPACES }-0`), -0); + assert.same(parseFloat(null), NaN); + assert.same(parseFloat(undefined), NaN); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('parseFloat test'); + assert.throws(() => parseFloat(symbol), 'throws on symbol argument'); + assert.throws(() => parseFloat(Object(symbol)), 'throws on boxed symbol argument'); + } +}); diff --git a/tests/unit-pure/es.parse-int.js b/tests/unit-pure/es.parse-int.js new file mode 100644 index 000000000000..218da1edd0a4 --- /dev/null +++ b/tests/unit-pure/es.parse-int.js @@ -0,0 +1,42 @@ +/* eslint-disable prefer-numeric-literals -- required for testing */ +import { WHITESPACES } from '../helpers/constants.js'; +import parseInt from 'core-js-pure/es/parse-int'; + +QUnit.test('parseInt', assert => { + assert.isFunction(parseInt); + assert.arity(parseInt, 2); + for (let radix = 2; radix <= 36; ++radix) { + assert.same(parseInt('10', radix), radix, `radix ${ radix }`); + } + const strings = ['01', '08', '10', '42']; + for (const string of strings) { + assert.same(parseInt(string), parseInt(string, 10), `default radix is 10: ${ string }`); + } + assert.same(parseInt('0x16'), parseInt('0x16', 16), 'default radix is 16: 0x16'); + assert.same(parseInt(' 0x16'), parseInt('0x16', 16), 'ignores leading whitespace #1'); + assert.same(parseInt(' 42'), parseInt('42', 10), 'ignores leading whitespace #2'); + assert.same(parseInt(' 08'), parseInt('08', 10), 'ignores leading whitespace #3'); + assert.same(parseInt(`${ WHITESPACES }08`), parseInt('08', 10), 'ignores leading whitespace #4'); + assert.same(parseInt(`${ WHITESPACES }0x16`), parseInt('0x16', 16), 'ignores leading whitespace #5'); + const fakeZero = { + valueOf() { + return 0; + }, + }; + assert.same(parseInt('08', fakeZero), parseInt('08', 10), 'valueOf #1'); + assert.same(parseInt('0x16', fakeZero), parseInt('0x16', 16), 'valueOf #2'); + assert.same(parseInt('-0xF'), -15, 'signed hex #1'); + assert.same(parseInt('-0xF', 16), -15, 'signed hex #2'); + assert.same(parseInt('+0xF'), 15, 'signed hex #3'); + assert.same(parseInt('+0xF', 16), 15, 'signed hex #4'); + assert.same(parseInt('10', -4294967294), 2, 'radix uses ToUint32'); + assert.same(parseInt(null), NaN); + assert.same(parseInt(undefined), NaN); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('parseInt test'); + assert.throws(() => parseInt(symbol), 'throws on symbol argument'); + assert.throws(() => parseInt(Object(symbol)), 'throws on boxed symbol argument'); + } +}); diff --git a/tests/unit-pure/es.promise.all-settled.js b/tests/unit-pure/es.promise.all-settled.js new file mode 100644 index 000000000000..9f75809dabec --- /dev/null +++ b/tests/unit-pure/es.promise.all-settled.js @@ -0,0 +1,162 @@ +import { createIterable } from '../helpers/helpers.js'; + +import $allSettled from 'core-js-pure/es/promise/all-settled'; +import bind from 'core-js-pure/es/function/bind'; +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Promise.allSettled', assert => { + assert.isFunction(Promise.allSettled); + assert.arity(Promise.allSettled, 1); + assert.true(Promise.allSettled([1, 2, 3]) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.allSettled, resolved', assert => { + return Promise.allSettled([ + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [ + { value: 1, status: 'fulfilled' }, + { value: 2, status: 'fulfilled' }, + { value: 3, status: 'fulfilled' }, + ], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.allSettled, resolved with rejection', assert => { + return Promise.allSettled([ + Promise.resolve(1), + Promise.reject(2), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [ + { value: 1, status: 'fulfilled' }, + { reason: 2, status: 'rejected' }, + { value: 3, status: 'fulfilled' }, + ], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.allSettled, rejected', assert => { + // eslint-disable-next-line promise/valid-params -- required for testing + return Promise.allSettled().then(() => { + assert.avoid(); + }, () => { + assert.required('rejected as expected'); + }); +}); + +QUnit.test('Promise.allSettled, resolved with timeouts', assert => { + return Promise.allSettled([ + Promise.resolve(1), + new Promise(resolve => setTimeout(() => resolve(2), 10)), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [ + { value: 1, status: 'fulfilled' }, + { value: 2, status: 'fulfilled' }, + { value: 3, status: 'fulfilled' }, + ], 'keeps correct mapping, even with delays'); + }); +}); + +QUnit.test('Promise.allSettled, subclassing', assert => { + const { allSettled, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = bind(resolve, Promise); + assert.true(allSettled.call(SubPromise, [1, 2, 3]) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = bind(resolve, Promise); + assert.throws(() => { + allSettled.call(FakePromise1, [1, 2, 3]); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + allSettled.call(FakePromise2, [1, 2, 3]); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + allSettled.call(FakePromise3, [1, 2, 3]); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.allSettled, iterables', assert => { + const iterable = createIterable([1, 2, 3]); + Promise.allSettled(iterable).catch(() => { /* empty */ }); + assert.true(iterable.received, 'works with iterables: iterator received'); + assert.true(iterable.called, 'works with iterables: next called'); +}); + +QUnit.test('Promise.allSettled, iterables 2', assert => { + const array = []; + let done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + Promise.allSettled(array); + assert.true(done); +}); + +QUnit.test('Promise.allSettled, iterator closing', assert => { + const { resolve } = Promise; + let done = false; + try { + Promise.resolve = function () { + throw new Error(); + }; + Promise.allSettled(createIterable([1, 2, 3], { + return() { + done = true; + }, + })).catch(() => { /* empty */ }); + } catch { /* empty */ } + Promise.resolve = resolve; + assert.true(done, 'iteration closing'); +}); + +QUnit.test('Promise.allSettled, without constructor context', assert => { + const { allSettled } = Promise; + assert.throws(() => allSettled([]), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => allSettled.call(null, []), TypeError, 'Throws if called with null as this'); +}); + +QUnit.test('Promise.allSettled, method from direct entry, without constructor context', assert => { + return $allSettled([ + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [ + { value: 1, status: 'fulfilled' }, + { value: 2, status: 'fulfilled' }, + { value: 3, status: 'fulfilled' }, + ], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.allSettled, method from direct entry, with null context', assert => { + return $allSettled.call(null, [ + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [ + { value: 1, status: 'fulfilled' }, + { value: 2, status: 'fulfilled' }, + { value: 3, status: 'fulfilled' }, + ], 'resolved with a correct value'); + }); +}); diff --git a/tests/unit-pure/es.promise.all.js b/tests/unit-pure/es.promise.all.js new file mode 100644 index 000000000000..b3676cc9b434 --- /dev/null +++ b/tests/unit-pure/es.promise.all.js @@ -0,0 +1,122 @@ +import { createIterable } from '../helpers/helpers.js'; + +import bind from 'core-js-pure/es/function/bind'; +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Promise.all', assert => { + const { all } = Promise; + assert.isFunction(all); + assert.arity(all, 1); + assert.name(all, 'all'); + assert.true(Promise.all([]) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.all, resolved', assert => { + return Promise.all([ + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [1, 2, 3], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.all, resolved with rejection', assert => { + return Promise.all([ + Promise.resolve(1), + Promise.reject(2), + Promise.resolve(3), + ]).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 2, 'rejected with a correct value'); + }); +}); + +QUnit.test('Promise.all, resolved with empty array', assert => { + return Promise.all([]).then(it => { + assert.deepEqual(it, [], 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.all, resolved with timeouts', assert => { + return Promise.all([ + Promise.resolve(1), + new Promise(resolve => setTimeout(() => resolve(2), 10)), + Promise.resolve(3), + ]).then(it => { + assert.deepEqual(it, [1, 2, 3], 'keeps correct mapping, even with delays'); + }); +}); + +QUnit.test('Promise.all, subclassing', assert => { + const { all, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = bind(resolve, Promise); + assert.true(all.call(SubPromise, [1, 2, 3]) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = bind(resolve, Promise); + assert.throws(() => { + all.call(FakePromise1, [1, 2, 3]); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + all.call(FakePromise2, [1, 2, 3]); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + all.call(FakePromise3, [1, 2, 3]); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.all, iterables', assert => { + const iterable = createIterable([1, 2, 3]); + Promise.all(iterable).catch(() => { /* empty */ }); + assert.true(iterable.received, 'works with iterables: iterator received'); + assert.true(iterable.called, 'works with iterables: next called'); +}); + +QUnit.test('Promise.all, iterables 2', assert => { + const array = []; + let done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + Promise.all(array); + assert.true(done); +}); + +QUnit.test('Promise.all, iterator closing', assert => { + const { resolve } = Promise; + let done = false; + try { + Promise.resolve = function () { + throw new Error(); + }; + Promise.all(createIterable([1, 2, 3], { + return() { + done = true; + }, + })).catch(() => { /* empty */ }); + } catch { /* empty */ } + Promise.resolve = resolve; + assert.true(done, 'iteration closing'); +}); + +QUnit.test('Promise.all, without constructor context', assert => { + const { all } = Promise; + assert.throws(() => all([]), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => all.call(null, []), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-pure/es.promise.any.js b/tests/unit-pure/es.promise.any.js new file mode 100644 index 000000000000..fa78d56b4030 --- /dev/null +++ b/tests/unit-pure/es.promise.any.js @@ -0,0 +1,156 @@ +import { createIterable } from '../helpers/helpers.js'; + +import $any from 'core-js-pure/es/promise/any'; +import AggregateError from 'core-js-pure/es/aggregate-error'; +import bind from 'core-js-pure/es/function/bind'; +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Promise.any', assert => { + assert.isFunction(Promise.any); + assert.arity(Promise.any, 1); + assert.true(Promise.any([1, 2, 3]) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.any, resolved', assert => { + return Promise.any([ + Promise.resolve(1), + Promise.reject(2), + Promise.resolve(3), + ]).then(it => { + assert.same(it, 1, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.any, rejected #1', assert => { + return Promise.any([ + Promise.reject(1), + Promise.reject(2), + Promise.reject(3), + ]).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof AggregateError, 'instanceof AggregateError'); + assert.deepEqual(error.errors, [1, 2, 3], 'rejected with a correct value'); + }); +}); + +QUnit.test('Promise.any, rejected #2', assert => { + // eslint-disable-next-line promise/valid-params -- required for testing + return Promise.any().then(() => { + assert.avoid(); + }, () => { + assert.required('rejected as expected'); + }); +}); + +QUnit.test('Promise.any, rejected #3', assert => { + return Promise.any([]).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof AggregateError, 'instanceof AggregateError'); + assert.deepEqual(error.errors, [], 'rejected with a correct value'); + }); +}); + +QUnit.test('Promise.any, resolved with timeout', assert => { + return Promise.any([ + new Promise(resolve => setTimeout(() => resolve(1), 50)), + Promise.resolve(2), + ]).then(it => { + assert.same(it, 2, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.any, subclassing', assert => { + const { any, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = bind(resolve, Promise); + assert.true(any.call(SubPromise, [1, 2, 3]) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = bind(resolve, Promise); + assert.throws(() => { + any.call(FakePromise1, [1, 2, 3]); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + any.call(FakePromise2, [1, 2, 3]); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + any.call(FakePromise3, [1, 2, 3]); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.any, iterables', assert => { + const iterable = createIterable([1, 2, 3]); + Promise.any(iterable).catch(() => { /* empty */ }); + assert.true(iterable.received, 'works with iterables: iterator received'); + assert.true(iterable.called, 'works with iterables: next called'); +}); + +QUnit.test('Promise.any, empty iterables', assert => { + const array = []; + let done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + return Promise.any(array).then(() => { + assert.avoid(); + }, error => { + assert.true(error instanceof AggregateError, 'instanceof AggregateError'); + assert.true(done, 'iterator called'); + }); +}); + +QUnit.test('Promise.any, iterator closing', assert => { + const { resolve } = Promise; + let done = false; + try { + Promise.resolve = function () { + throw new Error(); + }; + Promise.any(createIterable([1, 2, 3], { + return() { + done = true; + }, + })).catch(() => { /* empty */ }); + } catch { /* empty */ } + Promise.resolve = resolve; + assert.true(done, 'iteration closing'); +}); + +QUnit.test('Promise.any, without constructor context', assert => { + const { any } = Promise; + assert.throws(() => any([]), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => any.call(null, []), TypeError, 'Throws if called with null as this'); +}); + +QUnit.test('Promise.any, method from direct entry, without constructor context', assert => { + return $any([ + Promise.resolve(1), + Promise.resolve(2), + ]).then(it => { + assert.same(it, 1, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.any, method from direct entry, with null context', assert => { + return $any.call(null, [ + Promise.resolve(1), + Promise.resolve(2), + ]).then(it => { + assert.same(it, 1, 'resolved with a correct value'); + }); +}); diff --git a/tests/unit-pure/es.promise.catch.js b/tests/unit-pure/es.promise.catch.js new file mode 100644 index 000000000000..920422c0f362 --- /dev/null +++ b/tests/unit-pure/es.promise.catch.js @@ -0,0 +1,52 @@ +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Promise#catch', assert => { + assert.isFunction(Promise.prototype.catch); + assert.nonEnumerable(Promise.prototype, 'catch'); + let promise = new Promise(resolve => { + resolve(42); + }); + const FakePromise1 = promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + const FakePromise2 = FakePromise1[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(promise.catch(() => { /* empty */ }) instanceof FakePromise2, 'subclassing, @@species pattern'); + promise = new Promise(resolve => { + resolve(42); + }); + promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(promise.catch(() => { /* empty */ }) instanceof Promise, 'subclassing, incorrect `this` pattern'); + promise = new Promise(resolve => { + resolve(42); + }); + const FakePromise3 = promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + FakePromise3[Symbol.species] = function () { /* empty */ }; + assert.throws(() => { + promise.catch(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #1'); + FakePromise3[Symbol.species] = function (executor) { + executor(null, () => { /* empty */ }); + }; + assert.throws(() => { + promise.catch(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #2'); + FakePromise3[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, null); + }; + assert.throws(() => { + promise.catch(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #3'); + assert.same(Promise.prototype.catch.call({ + // eslint-disable-next-line unicorn/no-thenable -- required for testing + then(x, y) { + return y; + }, + }, 42), 42, 'calling `.then`'); +}); diff --git a/tests/unit-pure/es.promise.constructor.js b/tests/unit-pure/es.promise.constructor.js new file mode 100644 index 000000000000..86919994175d --- /dev/null +++ b/tests/unit-pure/es.promise.constructor.js @@ -0,0 +1,217 @@ +import { DESCRIPTORS, GLOBAL, PROTO, STRICT } from '../helpers/constants.js'; + +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; +import setPrototypeOf from 'core-js-pure/es/object/set-prototype-of'; +import create from 'core-js-pure/es/object/create'; + +QUnit.test('Promise', assert => { + assert.isFunction(Promise); + new Promise(function (resolve, reject) { + assert.isFunction(resolve, 'resolver is function'); + assert.isFunction(reject, 'rejector is function'); + if (STRICT) assert.same(this, undefined, 'correct executor context'); + }); + assert.throws(() => { + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing + Promise(); + }, 'throws w/o `new`'); +}); + +if (DESCRIPTORS) QUnit.test('Promise operations order', assert => { + let $resolve, $resolve2; + assert.expect(1); + const EXPECTED_ORDER = 'DEHAFGBC'; + const async = assert.async(); + let result = ''; + const promise1 = new Promise(resolve => { + $resolve = resolve; + }); + $resolve({ + // eslint-disable-next-line unicorn/no-thenable -- required for testing + then() { + result += 'A'; + throw new Error(); + }, + }); + promise1.catch(() => { + result += 'B'; + }); + promise1.catch(() => { + result += 'C'; + assert.same(result, EXPECTED_ORDER); + async(); + }); + const promise2 = new Promise(resolve => { + $resolve2 = resolve; + }); + // eslint-disable-next-line es/no-object-defineproperty, unicorn/no-thenable -- required for testing + $resolve2(Object.defineProperty({}, 'then', { + get() { + result += 'D'; + throw new Error(); + }, + })); + result += 'E'; + promise2.catch(() => { + result += 'F'; + }); + promise2.catch(() => { + result += 'G'; + }); + result += 'H'; + setTimeout(() => { + if (!~result.indexOf('C')) { + assert.same(result, EXPECTED_ORDER); + async(); + } + }, 1e3); +}); + +QUnit.test('Promise#then', assert => { + assert.isFunction(Promise.prototype.then); + assert.nonEnumerable(Promise.prototype, 'then'); + let promise = new Promise(resolve => { + resolve(42); + }); + const FakePromise1 = promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + const FakePromise2 = FakePromise1[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(promise.then(() => { /* empty */ }) instanceof FakePromise2, 'subclassing, @@species pattern'); + promise = new Promise(resolve => { + resolve(42); + }); + promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(promise.then(() => { /* empty */ }) instanceof Promise, 'subclassing, incorrect `this` pattern'); + promise = new Promise(resolve => { + resolve(42); + }); + const FakePromise3 = promise.constructor = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + FakePromise3[Symbol.species] = function () { /* empty */ }; + assert.throws(() => { + promise.then(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #1'); + FakePromise3[Symbol.species] = function (executor) { + executor(null, () => { /* empty */ }); + }; + assert.throws(() => { + promise.then(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #2'); + FakePromise3[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, null); + }; + assert.throws(() => { + promise.then(() => { /* empty */ }); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise#@@toStringTag', assert => { + assert.same(Promise.prototype[Symbol.toStringTag], 'Promise', 'Promise::@@toStringTag is `Promise`'); + assert.same(String(new Promise(() => { /* empty */ })), '[object Promise]', 'correct stringification'); +}); + +if (PROTO) QUnit.test('Promise subclassing', assert => { + function SubPromise(executor) { + const self = new Promise(executor); + setPrototypeOf(self, SubPromise.prototype); + self.mine = 'subclass'; + return self; + } + setPrototypeOf(SubPromise, Promise); + SubPromise.prototype = create(Promise.prototype); + SubPromise.prototype.constructor = SubPromise; + let promise1 = SubPromise.resolve(5); + assert.same(promise1.mine, 'subclass'); + promise1 = promise1.then(it => { + assert.same(it, 5); + }); + assert.same(promise1.mine, 'subclass'); + let promise2 = new SubPromise(resolve => { + resolve(6); + }); + assert.same(promise2.mine, 'subclass'); + promise2 = promise2.then(it => { + assert.same(it, 6); + }); + assert.same(promise2.mine, 'subclass'); + const promise3 = SubPromise.all([promise1, promise2]); + assert.same(promise3.mine, 'subclass'); + assert.true(promise3 instanceof Promise); + assert.true(promise3 instanceof SubPromise); + promise3.then(assert.async(), error => { + assert.avoid(error); + }); +}); + +// qunit@2.5 strange bug +QUnit.skip('Unhandled rejection tracking', assert => { + let done = false; + const resume = assert.async(); + if (GLOBAL.process) { + assert.expect(3); + function onunhandledrejection(reason, promise) { + process.removeListener('unhandledRejection', onunhandledrejection); + assert.same(promise, $promise, 'unhandledRejection, promise'); + assert.same(reason, 42, 'unhandledRejection, reason'); + $promise.catch(() => { + // empty + }); + } + function onrejectionhandled(promise) { + process.removeListener('rejectionHandled', onrejectionhandled); + assert.same(promise, $promise, 'rejectionHandled, promise'); + done || resume(); + done = true; + } + process.on('unhandledRejection', onunhandledrejection); + process.on('rejectionHandled', onrejectionhandled); + } else { + if (GLOBAL.addEventListener) { + assert.expect(8); + function onunhandledrejection(it) { + assert.same(it.promise, $promise, 'addEventListener(unhandledrejection), promise'); + assert.same(it.reason, 42, 'addEventListener(unhandledrejection), reason'); + GLOBAL.removeEventListener('unhandledrejection', onunhandledrejection); + } + GLOBAL.addEventListener('rejectionhandled', onunhandledrejection); + function onrejectionhandled(it) { + assert.same(it.promise, $promise, 'addEventListener(rejectionhandled), promise'); + assert.same(it.reason, 42, 'addEventListener(rejectionhandled), reason'); + GLOBAL.removeEventListener('rejectionhandled', onrejectionhandled); + } + GLOBAL.addEventListener('rejectionhandled', onrejectionhandled); + } else assert.expect(4); + GLOBAL.onunhandledrejection = function (it) { + assert.same(it.promise, $promise, 'onunhandledrejection, promise'); + assert.same(it.reason, 42, 'onunhandledrejection, reason'); + setTimeout(() => { + $promise.catch(() => { + // empty + }); + }, 1); + GLOBAL.onunhandledrejection = null; + }; + GLOBAL.onrejectionhandled = function (it) { + assert.same(it.promise, $promise, 'onrejectionhandled, promise'); + assert.same(it.reason, 42, 'onrejectionhandled, reason'); + GLOBAL.onrejectionhandled = null; + done || resume(); + done = true; + }; + } + Promise.reject(43).catch(() => { + // empty + }); + const $promise = Promise.reject(42); + setTimeout(() => { + done || resume(); + done = true; + }, 3e3); +}); diff --git a/tests/unit-pure/es.promise.finally.js b/tests/unit-pure/es.promise.finally.js new file mode 100644 index 000000000000..ef6b0966c709 --- /dev/null +++ b/tests/unit-pure/es.promise.finally.js @@ -0,0 +1,35 @@ +import Promise from 'core-js-pure/es/promise'; + +QUnit.test('Promise#finally', assert => { + assert.isFunction(Promise.prototype.finally); + assert.arity(Promise.prototype.finally, 1); + assert.nonEnumerable(Promise.prototype, 'finally'); + assert.true(Promise.resolve(42).finally(() => { /* empty */ }) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise#finally, resolved', assert => { + let called = 0; + let argument = null; + return Promise.resolve(42).finally(it => { + called++; + argument = it; + }).then(it => { + assert.same(it, 42, 'resolved with a correct value'); + assert.same(called, 1, 'onFinally function called one time'); + assert.same(argument, undefined, 'onFinally function called with a correct argument'); + }); +}); + +QUnit.test('Promise#finally, rejected', assert => { + let called = 0; + let argument = null; + return Promise.reject(42).finally(it => { + called++; + argument = it; + }).then(() => { + assert.avoid(); + }, () => { + assert.same(called, 1, 'onFinally function called one time'); + assert.same(argument, undefined, 'onFinally function called with a correct argument'); + }); +}); diff --git a/tests/unit-pure/es.promise.race.js b/tests/unit-pure/es.promise.race.js new file mode 100644 index 000000000000..e5927c568934 --- /dev/null +++ b/tests/unit-pure/es.promise.race.js @@ -0,0 +1,113 @@ +import { createIterable } from '../helpers/helpers.js'; + +import bind from 'core-js-pure/es/function/bind'; +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Promise.race', assert => { + const { race } = Promise; + assert.isFunction(race); + assert.arity(race, 1); + assert.name(race, 'race'); + assert.true(Promise.race([]) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.race, resolved', assert => { + return Promise.race([ + Promise.resolve(1), + Promise.resolve(2), + ]).then(it => { + assert.same(it, 1, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.race, resolved with rejection', assert => { + return Promise.race([ + Promise.reject(1), + Promise.resolve(2), + ]).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 1, 'rejected with a correct value'); + }); +}); + +QUnit.test('Promise.race, resolved with timeouts', assert => { + return Promise.race([ + new Promise(resolve => setTimeout(() => resolve(1), 50)), + Promise.resolve(2), + ]).then(it => { + assert.same(it, 2, 'keeps correct mapping, even with delays'); + }); +}); + +QUnit.test('Promise.race, subclassing', assert => { + const { race, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = bind(resolve, Promise); + assert.true(race.call(SubPromise, [1, 2, 3]) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = bind(resolve, Promise); + assert.throws(() => { + race.call(FakePromise1, [1, 2, 3]); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + race.call(FakePromise2, [1, 2, 3]); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + race.call(FakePromise3, [1, 2, 3]); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.race, iterables', assert => { + const iterable = createIterable([1, 2, 3]); + Promise.race(iterable).catch(() => { /* empty */ }); + assert.true(iterable.received, 'works with iterables: iterator received'); + assert.true(iterable.called, 'works with iterables: next called'); +}); + +QUnit.test('Promise.race, iterables 2', assert => { + const array = []; + let done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + Promise.race(array); + assert.true(done); +}); + +QUnit.test('Promise.race, iterator closing', assert => { + const { resolve } = Promise; + let done = false; + try { + Promise.resolve = function () { + throw new Error(); + }; + Promise.race(createIterable([1, 2, 3], { + return() { + done = true; + }, + })).catch(() => { /* empty */ }); + } catch { /* empty */ } + Promise.resolve = resolve; + assert.true(done, 'iteration closing'); +}); + +QUnit.test('Promise.race, without constructor context', assert => { + const { race } = Promise; + assert.throws(() => race([]), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => race.call(null, []), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-pure/es.promise.reject.js b/tests/unit-pure/es.promise.reject.js new file mode 100644 index 000000000000..ca6b445b57c8 --- /dev/null +++ b/tests/unit-pure/es.promise.reject.js @@ -0,0 +1,56 @@ +import Promise from 'core-js-pure/es/promise'; + +QUnit.test('Promise.reject', assert => { + const { reject } = Promise; + assert.isFunction(reject); + assert.name(reject, 'reject'); +}); + +QUnit.test('Promise.reject, rejects with value', assert => { + return Promise.reject(42) + .then(() => { + assert.avoid('Should not resolve'); + }, error => { + assert.same(error, 42, 'rejected with correct reason'); + }); +}); + +QUnit.test('Promise.reject, rejects with undefined', assert => { + return Promise.reject() + .then(() => { + assert.avoid('Should not resolve'); + }, error => { + assert.same(error, undefined, 'rejected with correct reason'); + }); +}); + +QUnit.test('Promise.reject, subclassing', assert => { + const { reject } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + assert.true(reject.call(SubPromise, 42) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + assert.throws(() => { + reject.call(FakePromise1, 42); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + reject.call(FakePromise2, 42); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + reject.call(FakePromise3, 42); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.reject, without constructor context', assert => { + const { reject } = Promise; + assert.throws(() => reject(''), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => reject.call(null, ''), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-pure/es.promise.resolve.js b/tests/unit-pure/es.promise.resolve.js new file mode 100644 index 000000000000..80bb6630dd95 --- /dev/null +++ b/tests/unit-pure/es.promise.resolve.js @@ -0,0 +1,69 @@ +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Promise.resolve', assert => { + const { resolve } = Promise; + assert.isFunction(resolve); + assert.true(Promise.resolve(42) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.resolve, resolves with value', assert => { + return Promise.resolve(42).then(result => { + assert.same(result, 42, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.resolve, resolves with thenable', assert => { + const thenable = { + // eslint-disable-next-line unicorn/no-thenable -- safe + then(resolve) { resolve('foo'); }, + }; + return Promise.resolve(thenable).then(result => { + assert.same(result, 'foo', 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.resolve, returns input if input is already promise', assert => { + const p = Promise.resolve('ok'); + assert.same(Promise.resolve(p), p, 'resolved with a correct value'); +}); + +QUnit.test('Promise.resolve, resolves with undefined', assert => { + return Promise.resolve().then(result => { + assert.same(result, undefined, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.resolve, subclassing', assert => { + const { resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise[Symbol.species] = function (executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + }; + assert.true(resolve.call(SubPromise, 42) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + assert.throws(() => { + resolve.call(FakePromise1, 42); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + resolve.call(FakePromise2, 42); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + resolve.call(FakePromise3, 42); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.resolve, without constructor context', assert => { + const { resolve } = Promise; + assert.throws(() => resolve(''), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => resolve.call(null, ''), TypeError, 'Throws if called with null as this'); +}); diff --git a/tests/unit-pure/es.promise.try.js b/tests/unit-pure/es.promise.try.js new file mode 100644 index 000000000000..986df0e11bb6 --- /dev/null +++ b/tests/unit-pure/es.promise.try.js @@ -0,0 +1,76 @@ +import $try from 'core-js-pure/es/promise/try'; +import bind from 'core-js-pure/es/function/bind'; +import Promise from 'core-js-pure/es/promise'; + +QUnit.test('Promise.try', assert => { + assert.isFunction(Promise.try); + assert.arity(Promise.try, 1); + assert.true(Promise.try(() => 42) instanceof Promise, 'returns a promise'); +}); + +QUnit.test('Promise.try, resolved', assert => { + return Promise.try(() => 42).then(it => { + assert.same(it, 42, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.try, resolved, with args', assert => { + return Promise.try((a, b) => Promise.resolve(a + b), 1, 2).then(it => { + assert.same(it, 3, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.try, rejected', assert => { + return Promise.try(() => { + throw new Error(); + }).then(() => { + assert.avoid(); + }, () => { + assert.true(true, 'rejected as expected'); + }); +}); + +QUnit.test('Promise.try, subclassing', assert => { + const { try: promiseTry, resolve } = Promise; + function SubPromise(executor) { + executor(() => { /* empty */ }, () => { /* empty */ }); + } + SubPromise.resolve = bind(resolve, Promise); + assert.true(promiseTry.call(SubPromise, () => 42) instanceof SubPromise, 'subclassing, `this` pattern'); + + function FakePromise1() { /* empty */ } + function FakePromise2(executor) { + executor(null, () => { /* empty */ }); + } + function FakePromise3(executor) { + executor(() => { /* empty */ }, null); + } + FakePromise1.resolve = FakePromise2.resolve = FakePromise3.resolve = bind(resolve, Promise); + assert.throws(() => { + promiseTry.call(FakePromise1, () => 42); + }, 'NewPromiseCapability validations, #1'); + assert.throws(() => { + promiseTry.call(FakePromise2, () => 42); + }, 'NewPromiseCapability validations, #2'); + assert.throws(() => { + promiseTry.call(FakePromise3, () => 42); + }, 'NewPromiseCapability validations, #3'); +}); + +QUnit.test('Promise.try, without constructor context', assert => { + const { try: promiseTry } = Promise; + assert.throws(() => promiseTry(() => 42), TypeError, 'Throws if called without a constructor context'); + assert.throws(() => promiseTry.call(null, () => 42), TypeError, 'Throws if called with null as this'); +}); + +QUnit.test('Promise.try, method from direct entry, without constructor context', assert => { + return $try(() => 123).then(it => { + assert.same(it, 123, 'resolved with a correct value'); + }); +}); + +QUnit.test('Promise.try, method from direct entry, with null context', assert => { + return $try.call(null, () => 'foo').then(it => { + assert.same(it, 'foo', 'resolved with a correct value'); + }); +}); diff --git a/tests/unit-pure/es.promise.with-resolvers.js b/tests/unit-pure/es.promise.with-resolvers.js new file mode 100644 index 000000000000..b94fc22cbffe --- /dev/null +++ b/tests/unit-pure/es.promise.with-resolvers.js @@ -0,0 +1,55 @@ +import Promise from 'core-js-pure/es/promise'; +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; + +QUnit.test('Promise.withResolvers', assert => { + const { withResolvers } = Promise; + assert.isFunction(withResolvers); + assert.arity(withResolvers, 0); + assert.name(withResolvers, 'withResolvers'); + + const d1 = Promise.withResolvers(); + assert.same(getPrototypeOf(d1), Object.prototype, 'proto is Object.prototype'); + assert.true(d1.promise instanceof Promise, 'promise is promise'); + assert.isFunction(d1.resolve, 'resolve is function'); + assert.isFunction(d1.reject, 'reject is function'); + + const promise = {}; + const resolve = () => { /* empty */ }; + let reject = () => { /* empty */ }; + + function P(exec) { + exec(resolve, reject); + return promise; + } + + const d2 = withResolvers.call(P); + assert.same(d2.promise, promise, 'promise is promise #2'); + assert.same(d2.resolve, resolve, 'resolve is resolve #2'); + assert.same(d2.reject, reject, 'reject is reject #2'); + + reject = {}; + + assert.throws(() => withResolvers.call(P), TypeError, 'broken resolver'); + assert.throws(() => withResolvers.call({}), TypeError, 'broken constructor #1'); + assert.throws(() => withResolvers.call(null), TypeError, 'broken constructor #2'); +}); + +QUnit.test('Promise.withResolvers, resolve', assert => { + const d = Promise.withResolvers(); + d.resolve(42); + return d.promise.then(it => { + assert.same(it, 42, 'resolved as expected'); + }, () => { + assert.avoid(); + }); +}); + +QUnit.test('Promise.withResolvers, reject', assert => { + const d = Promise.withResolvers(); + d.reject(42); + return d.promise.then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejected as expected'); + }); +}); diff --git a/tests/unit-pure/es.reflect.apply.js b/tests/unit-pure/es.reflect.apply.js new file mode 100644 index 000000000000..8c24bed433f0 --- /dev/null +++ b/tests/unit-pure/es.reflect.apply.js @@ -0,0 +1,18 @@ +import apply from 'core-js-pure/es/reflect/apply'; + +QUnit.test('Reflect.apply', assert => { + assert.isFunction(apply); + assert.arity(apply, 3); + if ('name' in apply) { + assert.name(apply, 'apply'); + } + assert.same(apply(Array.prototype.push, [1, 2], [3, 4, 5]), 5); + function F(a, b, c) { + return a + b + c; + } + F.apply = 42; + assert.same(apply(F, null, ['foo', 'bar', 'baz']), 'foobarbaz', 'works with redefined apply'); + assert.throws(() => apply(42, null, []), TypeError, 'throws on primitive'); + assert.throws(() => apply(() => { /* empty */ }, null), TypeError, 'throws without third argument'); + assert.throws(() => apply(() => { /* empty */ }, null, '123'), TypeError, 'throws on primitive as third argument'); +}); diff --git a/tests/unit-pure/es.reflect.construct.js b/tests/unit-pure/es.reflect.construct.js new file mode 100644 index 000000000000..005e514613e7 --- /dev/null +++ b/tests/unit-pure/es.reflect.construct.js @@ -0,0 +1,27 @@ +import construct from 'core-js-pure/es/reflect/construct'; +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; + +QUnit.test('Reflect.construct', assert => { + assert.isFunction(construct); + assert.arity(construct, 2); + if ('name' in construct) { + assert.name(construct, 'construct'); + } + function A(a, b, c) { + this.qux = a + b + c; + } + assert.same(construct(A, ['foo', 'bar', 'baz']).qux, 'foobarbaz', 'basic'); + A.apply = 42; + assert.same(construct(A, ['foo', 'bar', 'baz']).qux, 'foobarbaz', 'works with redefined apply'); + const instance = construct(function () { + this.x = 42; + }, [], Array); + assert.same(instance.x, 42, 'constructor with newTarget'); + assert.true(instance instanceof Array, 'prototype with newTarget'); + assert.throws(() => construct(42, []), TypeError, 'throws on primitive'); + function B() { /* empty */ } + B.prototype = 42; + assert.notThrows(() => getPrototypeOf(construct(B, [])) === Object.prototype); + assert.notThrows(() => typeof construct(Date, []).getTime() == 'number', 'works with native constructors with 2 arguments'); + assert.throws(() => construct(() => { /* empty */ }), 'throws when the second argument is not an object'); +}); diff --git a/tests/unit-pure/es.reflect.define-property.js b/tests/unit-pure/es.reflect.define-property.js new file mode 100644 index 000000000000..5d551696d88a --- /dev/null +++ b/tests/unit-pure/es.reflect.define-property.js @@ -0,0 +1,42 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import getOwnPropertyDescriptor from 'core-js-pure/es/object/get-own-property-descriptor'; +import create from 'core-js-pure/es/object/create'; +import defineProperty from 'core-js-pure/es/reflect/define-property'; + +QUnit.test('Reflect.defineProperty', assert => { + assert.isFunction(defineProperty); + assert.arity(defineProperty, 3); + if ('name' in defineProperty) { + assert.name(defineProperty, 'defineProperty'); + } + let object = {}; + assert.true(defineProperty(object, 'foo', { value: 123 })); + assert.same(object.foo, 123); + if (DESCRIPTORS) { + object = {}; + defineProperty(object, 'foo', { + value: 123, + enumerable: true, + }); + assert.deepEqual(getOwnPropertyDescriptor(object, 'foo'), { + value: 123, + enumerable: true, + configurable: false, + writable: false, + }); + assert.false(defineProperty(object, 'foo', { + value: 42, + })); + } + assert.throws(() => defineProperty(42, 'foo', { + value: 42, + }), TypeError, 'throws on primitive'); + assert.throws(() => defineProperty(42, 1, {})); + assert.throws(() => defineProperty({}, create(null), {})); + assert.throws(() => defineProperty({}, 1, 1)); +}); + +QUnit.test('Reflect.defineProperty.sham flag', assert => { + assert.same(defineProperty.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-pure/es.reflect.delete-property.js b/tests/unit-pure/es.reflect.delete-property.js new file mode 100644 index 000000000000..1108007c5701 --- /dev/null +++ b/tests/unit-pure/es.reflect.delete-property.js @@ -0,0 +1,22 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import keys from 'core-js-pure/es/object/keys'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import deleteProperty from 'core-js-pure/es/reflect/delete-property'; + +QUnit.test('Reflect.deleteProperty', assert => { + assert.isFunction(deleteProperty); + assert.arity(deleteProperty, 2); + if ('name' in deleteProperty) { + assert.name(deleteProperty, 'deleteProperty'); + } + const object = { bar: 456 }; + assert.true(deleteProperty(object, 'bar')); + assert.same(keys(object).length, 0); + if (DESCRIPTORS) { + assert.false(deleteProperty(defineProperty({}, 'foo', { + value: 42, + }), 'foo')); + } + assert.throws(() => deleteProperty(42, 'foo'), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-pure/es.reflect.get-own-property-descriptor.js b/tests/unit-pure/es.reflect.get-own-property-descriptor.js new file mode 100644 index 000000000000..e6baac2779c8 --- /dev/null +++ b/tests/unit-pure/es.reflect.get-own-property-descriptor.js @@ -0,0 +1,19 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import getOwnPropertyDescriptor from 'core-js-pure/es/reflect/get-own-property-descriptor'; + +QUnit.test('Reflect.getOwnPropertyDescriptor', assert => { + assert.isFunction(getOwnPropertyDescriptor); + assert.arity(getOwnPropertyDescriptor, 2); + if ('name' in getOwnPropertyDescriptor) { + assert.name(getOwnPropertyDescriptor, 'getOwnPropertyDescriptor'); + } + const object = { baz: 789 }; + const descriptor = getOwnPropertyDescriptor(object, 'baz'); + assert.same(descriptor.value, 789); + assert.throws(() => getOwnPropertyDescriptor(42, 'constructor'), TypeError, 'throws on primitive'); +}); + +QUnit.test('Reflect.getOwnPropertyDescriptor.sham flag', assert => { + assert.same(getOwnPropertyDescriptor.sham, DESCRIPTORS ? undefined : true); +}); diff --git a/tests/unit-pure/es.reflect.get-prototype-of.js b/tests/unit-pure/es.reflect.get-prototype-of.js new file mode 100644 index 000000000000..ddca73ba1a95 --- /dev/null +++ b/tests/unit-pure/es.reflect.get-prototype-of.js @@ -0,0 +1,17 @@ +import { CORRECT_PROTOTYPE_GETTER } from '../helpers/constants.js'; + +import getPrototypeOf from 'core-js-pure/es/reflect/get-prototype-of'; + +QUnit.test('Reflect.getPrototypeOf', assert => { + assert.isFunction(getPrototypeOf); + assert.arity(getPrototypeOf, 1); + if ('name' in getPrototypeOf) { + assert.name(getPrototypeOf, 'getPrototypeOf'); + } + assert.same(getPrototypeOf([]), Array.prototype); + assert.throws(() => getPrototypeOf(42), TypeError, 'throws on primitive'); +}); + +QUnit.test('Reflect.getPrototypeOf.sham flag', assert => { + assert.same(getPrototypeOf.sham, CORRECT_PROTOTYPE_GETTER ? undefined : true); +}); diff --git a/tests/unit-pure/es.reflect.get.js b/tests/unit-pure/es.reflect.get.js new file mode 100644 index 000000000000..ce942b98df5b --- /dev/null +++ b/tests/unit-pure/es.reflect.get.js @@ -0,0 +1,36 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import create from 'core-js-pure/es/object/create'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import get from 'core-js-pure/es/reflect/get'; + +QUnit.test('Reflect.get', assert => { + assert.isFunction(get); + if ('name' in get) { + assert.name(get, 'get'); + } + assert.same(get({ qux: 987 }, 'qux'), 987); + if (DESCRIPTORS) { + const target = create(defineProperty({ z: 3 }, 'w', { + get() { + return this; + }, + }), { + x: { + value: 1, + }, + y: { + get() { + return this; + }, + }, + }); + const receiver = {}; + assert.same(get(target, 'x', receiver), 1, 'get x'); + assert.same(get(target, 'y', receiver), receiver, 'get y'); + assert.same(get(target, 'z', receiver), 3, 'get z'); + assert.same(get(target, 'w', receiver), receiver, 'get w'); + assert.same(get(target, 'u', receiver), undefined, 'get u'); + } + assert.throws(() => get(42, 'constructor'), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-pure/es.reflect.has.js b/tests/unit-pure/es.reflect.has.js new file mode 100644 index 000000000000..8fcba7d980b7 --- /dev/null +++ b/tests/unit-pure/es.reflect.has.js @@ -0,0 +1,14 @@ +import has from 'core-js-pure/es/reflect/has'; + +QUnit.test('Reflect.has', assert => { + assert.isFunction(has); + assert.arity(has, 2); + if ('name' in has) { + assert.name(has, 'has'); + } + const object = { qux: 987 }; + assert.true(has(object, 'qux')); + assert.false(has(object, 'qwe')); + assert.true(has(object, 'toString')); + assert.throws(() => has(42, 'constructor'), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-pure/es.reflect.is-extensible.js b/tests/unit-pure/es.reflect.is-extensible.js new file mode 100644 index 000000000000..a9cf00dcbc8c --- /dev/null +++ b/tests/unit-pure/es.reflect.is-extensible.js @@ -0,0 +1,17 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import preventExtensions from 'core-js-pure/es/object/prevent-extensions'; +import isExtensible from 'core-js-pure/es/reflect/is-extensible'; + +QUnit.test('Reflect.isExtensible', assert => { + assert.isFunction(isExtensible); + assert.arity(isExtensible, 1); + if ('name' in isExtensible) { + assert.name(isExtensible, 'isExtensible'); + } + assert.true(isExtensible({})); + if (DESCRIPTORS) { + assert.false(isExtensible(preventExtensions({}))); + } + assert.throws(() => isExtensible(42), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-pure/es.reflect.own-keys.js b/tests/unit-pure/es.reflect.own-keys.js new file mode 100644 index 000000000000..4f64d192a96b --- /dev/null +++ b/tests/unit-pure/es.reflect.own-keys.js @@ -0,0 +1,27 @@ +import { includes } from '../helpers/helpers.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import create from 'core-js-pure/es/object/create'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import ownKeys from 'core-js-pure/es/reflect/own-keys'; + +QUnit.test('Reflect.ownKeys', assert => { + assert.isFunction(ownKeys); + assert.arity(ownKeys, 1); + if ('name' in ownKeys) { + assert.name(ownKeys, 'ownKeys'); + } + const object = { a: 1 }; + defineProperty(object, 'b', { + value: 2, + }); + object[Symbol('c')] = 3; + let keys = ownKeys(object); + assert.same(keys.length, 3, 'ownKeys return all own keys'); + assert.true(includes(keys, 'a'), 'ownKeys return all own keys: simple'); + assert.true(includes(keys, 'b'), 'ownKeys return all own keys: hidden'); + assert.same(object[keys[2]], 3, 'ownKeys return all own keys: symbol'); + keys = ownKeys(create(object)); + assert.same(keys.length, 0, 'ownKeys return only own keys'); + assert.throws(() => ownKeys(42), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-pure/es.reflect.prevent-extensions.js b/tests/unit-pure/es.reflect.prevent-extensions.js new file mode 100644 index 000000000000..58344c8b124b --- /dev/null +++ b/tests/unit-pure/es.reflect.prevent-extensions.js @@ -0,0 +1,22 @@ +import { DESCRIPTORS, FREEZING } from '../helpers/constants.js'; + +import preventExtensions from 'core-js-pure/es/reflect/prevent-extensions'; +import isExtensible from 'core-js-pure/es/object/is-extensible'; + +QUnit.test('Reflect.preventExtensions', assert => { + assert.isFunction(preventExtensions); + assert.arity(preventExtensions, 1); + if ('name' in preventExtensions) { + assert.name(preventExtensions, 'preventExtensions'); + } + const object = {}; + assert.true(preventExtensions(object)); + if (DESCRIPTORS) { + assert.false(isExtensible(object)); + } + assert.throws(() => preventExtensions(42), TypeError, 'throws on primitive'); +}); + +QUnit.test('Reflect.preventExtensions.sham flag', assert => { + assert.same(preventExtensions.sham, FREEZING ? undefined : true); +}); diff --git a/tests/unit-pure/es.reflect.set-prototype-of.js b/tests/unit-pure/es.reflect.set-prototype-of.js new file mode 100644 index 000000000000..f8bfbe7df1c6 --- /dev/null +++ b/tests/unit-pure/es.reflect.set-prototype-of.js @@ -0,0 +1,17 @@ +import { PROTO } from '../helpers/constants.js'; + +import setPrototypeOf from 'core-js-pure/es/reflect/set-prototype-of'; + +if (PROTO) QUnit.test('Reflect.setPrototypeOf', assert => { + assert.isFunction(setPrototypeOf); + if ('name' in setPrototypeOf) { + assert.name(setPrototypeOf, 'setPrototypeOf'); + } + let object = {}; + assert.true(setPrototypeOf(object, Array.prototype)); + assert.true(object instanceof Array); + assert.throws(() => setPrototypeOf({}, 42), TypeError); + assert.throws(() => setPrototypeOf(42, {}), TypeError, 'throws on primitive'); + object = {}; + assert.false(setPrototypeOf(object, object), 'false on recursive __proto__'); +}); diff --git a/tests/unit-pure/es.reflect.set.js b/tests/unit-pure/es.reflect.set.js new file mode 100644 index 000000000000..f19932d008a3 --- /dev/null +++ b/tests/unit-pure/es.reflect.set.js @@ -0,0 +1,88 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; + +import create from 'core-js-pure/es/object/create'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import getOwnPropertyDescriptor from 'core-js-pure/es/object/get-own-property-descriptor'; +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; +import set from 'core-js-pure/es/reflect/set'; + +QUnit.test('Reflect.set', assert => { + assert.isFunction(set); + if ('name' in set) { + assert.name(set, 'set'); + } + const object = {}; + assert.true(set(object, 'quux', 654)); + assert.same(object.quux, 654); + let target = {}; + const receiver = {}; + set(target, 'foo', 1, receiver); + assert.same(target.foo, undefined, 'target.foo === undefined'); + assert.same(receiver.foo, 1, 'receiver.foo === 1'); + if (DESCRIPTORS) { + defineProperty(receiver, 'bar', { + value: 0, + writable: true, + enumerable: false, + configurable: true, + }); + set(target, 'bar', 1, receiver); + assert.same(receiver.bar, 1, 'receiver.bar === 1'); + assert.false(getOwnPropertyDescriptor(receiver, 'bar').enumerable, 'enumerability not overridden'); + let out; + target = create(defineProperty({ z: 3 }, 'w', { + set() { + out = this; + }, + }), { + x: { + value: 1, + writable: true, + configurable: true, + }, + y: { + set() { + out = this; + }, + }, + c: { + value: 1, + writable: false, + configurable: false, + }, + }); + assert.true(set(target, 'x', 2, target), 'set x'); + assert.same(target.x, 2, 'set x'); + out = null; + assert.true(set(target, 'y', 2, target), 'set y'); + assert.same(out, target, 'set y'); + assert.true(set(target, 'z', 4, target)); + assert.same(target.z, 4, 'set z'); + out = null; + assert.true(set(target, 'w', 1, target), 'set w'); + assert.same(out, target, 'set w'); + assert.true(set(target, 'u', 0, target), 'set u'); + assert.same(target.u, 0, 'set u'); + assert.false(set(target, 'c', 2, target), 'set c'); + assert.same(target.c, 1, 'set c'); + + // https://github.com/zloirock/core-js/issues/392 + let o = defineProperty({}, 'test', { + writable: false, + configurable: true, + }); + assert.false(set(getPrototypeOf(o), 'test', 1, o)); + + // https://github.com/zloirock/core-js/issues/393 + o = defineProperty({}, 'test', { + get() { /* empty */ }, + }); + assert.notThrows(() => !set(getPrototypeOf(o), 'test', 1, o)); + o = defineProperty({}, 'test', { + // eslint-disable-next-line no-unused-vars -- required for testing + set(v) { /* empty */ }, + }); + assert.notThrows(() => !set(getPrototypeOf(o), 'test', 1, o)); + } + assert.throws(() => set(42, 'q', 42), TypeError, 'throws on primitive'); +}); diff --git a/tests/unit-pure/es.regexp.escape.js b/tests/unit-pure/es.regexp.escape.js new file mode 100644 index 000000000000..70dfcea0d991 --- /dev/null +++ b/tests/unit-pure/es.regexp.escape.js @@ -0,0 +1,329 @@ +/* eslint-disable @stylistic/max-len -- ok*/ +import escape from 'core-js-pure/es/regexp/escape'; + +QUnit.test('RegExp.escape', assert => { + assert.isFunction(escape); + assert.arity(escape, 1); + assert.name(escape, 'escape'); + + assert.same(escape('10$'), '\\x310\\$', '10$'); + assert.same(escape('abcdefg_123456'), '\\x61bcdefg_123456', 'abcdefg_123456'); + assert.same(escape('Привет'), 'Привет', 'Привет'); + assert.same( + escape('(){}[]|,.?*+-^$=<>\\/#&!%:;@~\'"`'), + '\\(\\)\\{\\}\\[\\]\\|\\x2c\\.\\?\\*\\+\\x2d\\^\\$\\x3d\\x3c\\x3e\\\\\\/\\x23\\x26\\x21\\x25\\x3a\\x3b\\x40\\x7e\\x27\\x22\\x60', + '(){}[]|,.?*+-^$=<>\\/#&!%:;@~\'"`', + ); + assert.same( + escape('\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'), + '\\t\\n\\v\\f\\r\\x20\\xa0\\u1680\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\u2028\\u2029\\ufeff', + 'whitespaces and control', + ); + + assert.same(escape('💩'), '💩', '💩'); + assert.same(escape('\uD83D'), '\\ud83d', '\\ud83d'); + assert.same(escape('\uDCA9'), '\\udca9', '\\udca9'); + assert.same(escape('\uDCA9\uD83D'), '\\udca9\\ud83d', '\\udca9\\ud83d'); + + assert.throws(() => escape(42), TypeError, 'throws on non-string #1'); + assert.throws(() => escape({}), TypeError, 'throws on non-string #2'); + + // Test262 + // Copyright 2024 Leo Balter. All rights reserved. + // This code is governed by the BSD license found in the https://github.com/tc39/test262/blob/main/LICENSE file. + assert.same(escape('\u2028'), '\\u2028', 'line terminator \\u2028 is escaped correctly to \\\\u2028'); + assert.same(escape('\u2029'), '\\u2029', 'line terminator \\u2029 is escaped correctly to \\\\u2029'); + assert.same(escape('\u2028\u2029'), '\\u2028\\u2029', 'line terminators are escaped correctly'); + assert.same(escape('\u2028a\u2029a'), '\\u2028a\\u2029a', 'mixed line terminators are escaped correctly'); + + assert.same(escape('.a/b'), '\\.a\\/b', 'mixed string with solidus character is escaped correctly'); + assert.same(escape('/./'), '\\/\\.\\/', 'solidus character is escaped correctly - regexp similar'); + assert.same(escape('./a\\/*b+c?d^e$f|g{2}h[i]j\\k'), '\\.\\/a\\\\\\/\\*b\\+c\\?d\\^e\\$f\\|g\\{2\\}h\\[i\\]j\\\\k', 'complex string with multiple special characters is escaped correctly'); + + assert.same(escape('/'), '\\/', 'solidus character is escaped correctly'); + assert.same(escape('//'), '\\/\\/', 'solidus character is escaped correctly - multiple occurrences 1'); + assert.same(escape('///'), '\\/\\/\\/', 'solidus character is escaped correctly - multiple occurrences 2'); + assert.same(escape('////'), '\\/\\/\\/\\/', 'solidus character is escaped correctly - multiple occurrences 3'); + + assert.same(escape('.'), '\\.', 'dot character is escaped correctly'); + assert.same(escape('*'), '\\*', 'asterisk character is escaped correctly'); + assert.same(escape('+'), '\\+', 'plus character is escaped correctly'); + assert.same(escape('?'), '\\?', 'question mark character is escaped correctly'); + assert.same(escape('^'), '\\^', 'caret character is escaped correctly'); + assert.same(escape('$'), '\\$', 'dollar character is escaped correctly'); + assert.same(escape('|'), '\\|', 'pipe character is escaped correctly'); + assert.same(escape('('), '\\(', 'open parenthesis character is escaped correctly'); + assert.same(escape(')'), '\\)', 'close parenthesis character is escaped correctly'); + assert.same(escape('['), '\\[', 'open bracket character is escaped correctly'); + assert.same(escape(']'), '\\]', 'close bracket character is escaped correctly'); + assert.same(escape('{'), '\\{', 'open brace character is escaped correctly'); + assert.same(escape('}'), '\\}', 'close brace character is escaped correctly'); + assert.same(escape('\\'), '\\\\', 'backslash character is escaped correctly'); + + const codePoints = String.fromCharCode(0x100, 0x200, 0x300); + assert.same(escape(codePoints), codePoints, 'characters are correctly not escaped'); + + assert.same(escape('你好'), '你好', 'Chinese characters are correctly not escaped'); + assert.same(escape('こんにちは'), 'こんにちは', 'Japanese characters are correctly not escaped'); + assert.same(escape('안녕하세요'), '안녕하세요', 'Korean characters are correctly not escaped'); + assert.same(escape('Привет'), 'Привет', 'Cyrillic characters are correctly not escaped'); + assert.same(escape('مرحبا'), 'مرحبا', 'Arabic characters are correctly not escaped'); + assert.same(escape('हेलो'), 'हेलो', 'Devanagari characters are correctly not escaped'); + assert.same(escape('Γειά σου'), 'Γειά\\x20σου', 'Greek characters are correctly not escaped'); + assert.same(escape('שלום'), 'שלום', 'Hebrew characters are correctly not escaped'); + assert.same(escape('สวัสดี'), 'สวัสดี', 'Thai characters are correctly not escaped'); + assert.same(escape('नमस्ते'), 'नमस्ते', 'Hindi characters are correctly not escaped'); + assert.same(escape('ሰላም'), 'ሰላም', 'Amharic characters are correctly not escaped'); + assert.same(escape('हैलो'), 'हैलो', 'Hindi characters with diacritics are correctly not escaped'); + assert.same(escape('안녕!'), '안녕\\x21', 'Korean character with special character is correctly escaped'); + assert.same(escape('.hello\uD7FFworld'), '\\.hello\uD7FFworld', 'Mixed ASCII and Unicode characters are correctly escaped'); + + assert.same(escape('\uFEFF'), '\\ufeff', 'whitespace \\uFEFF is escaped correctly to \\uFEFF'); + assert.same(escape('\u0020'), '\\x20', 'whitespace \\u0020 is escaped correctly to \\x20'); + assert.same(escape('\u00A0'), '\\xa0', 'whitespace \\u00A0 is escaped correctly to \\xA0'); + assert.same(escape('\u202F'), '\\u202f', 'whitespace \\u202F is escaped correctly to \\u202F'); + assert.same(escape('\u0009'), '\\t', 'whitespace \\u0009 is escaped correctly to \\t'); + assert.same(escape('\u000B'), '\\v', 'whitespace \\u000B is escaped correctly to \\v'); + assert.same(escape('\u000C'), '\\f', 'whitespace \\u000C is escaped correctly to \\f'); + assert.same(escape('\uFEFF\u0020\u00A0\u202F\u0009\u000B\u000C'), '\\ufeff\\x20\\xa0\\u202f\\t\\v\\f', 'whitespaces are escaped correctly'); + + // Escaping initial digits + assert.same(escape('1111'), '\\x31111', 'Initial decimal digit 1 is escaped'); + assert.same(escape('2222'), '\\x32222', 'Initial decimal digit 2 is escaped'); + assert.same(escape('3333'), '\\x33333', 'Initial decimal digit 3 is escaped'); + assert.same(escape('4444'), '\\x34444', 'Initial decimal digit 4 is escaped'); + assert.same(escape('5555'), '\\x35555', 'Initial decimal digit 5 is escaped'); + assert.same(escape('6666'), '\\x36666', 'Initial decimal digit 6 is escaped'); + assert.same(escape('7777'), '\\x37777', 'Initial decimal digit 7 is escaped'); + assert.same(escape('8888'), '\\x38888', 'Initial decimal digit 8 is escaped'); + assert.same(escape('9999'), '\\x39999', 'Initial decimal digit 9 is escaped'); + assert.same(escape('0000'), '\\x30000', 'Initial decimal digit 0 is escaped'); + + // Escaping initial ASCII letters + assert.same(escape('aaa'), '\\x61aa', 'Initial ASCII letter a is escaped'); + assert.same(escape('bbb'), '\\x62bb', 'Initial ASCII letter b is escaped'); + assert.same(escape('ccc'), '\\x63cc', 'Initial ASCII letter c is escaped'); + assert.same(escape('ddd'), '\\x64dd', 'Initial ASCII letter d is escaped'); + assert.same(escape('eee'), '\\x65ee', 'Initial ASCII letter e is escaped'); + assert.same(escape('fff'), '\\x66ff', 'Initial ASCII letter f is escaped'); + assert.same(escape('ggg'), '\\x67gg', 'Initial ASCII letter g is escaped'); + assert.same(escape('hhh'), '\\x68hh', 'Initial ASCII letter h is escaped'); + assert.same(escape('iii'), '\\x69ii', 'Initial ASCII letter i is escaped'); + assert.same(escape('jjj'), '\\x6ajj', 'Initial ASCII letter j is escaped'); + assert.same(escape('kkk'), '\\x6bkk', 'Initial ASCII letter k is escaped'); + assert.same(escape('lll'), '\\x6cll', 'Initial ASCII letter l is escaped'); + assert.same(escape('mmm'), '\\x6dmm', 'Initial ASCII letter m is escaped'); + assert.same(escape('nnn'), '\\x6enn', 'Initial ASCII letter n is escaped'); + assert.same(escape('ooo'), '\\x6foo', 'Initial ASCII letter o is escaped'); + assert.same(escape('ppp'), '\\x70pp', 'Initial ASCII letter p is escaped'); + assert.same(escape('qqq'), '\\x71qq', 'Initial ASCII letter q is escaped'); + assert.same(escape('rrr'), '\\x72rr', 'Initial ASCII letter r is escaped'); + assert.same(escape('sss'), '\\x73ss', 'Initial ASCII letter s is escaped'); + assert.same(escape('ttt'), '\\x74tt', 'Initial ASCII letter t is escaped'); + assert.same(escape('uuu'), '\\x75uu', 'Initial ASCII letter u is escaped'); + assert.same(escape('vvv'), '\\x76vv', 'Initial ASCII letter v is escaped'); + assert.same(escape('www'), '\\x77ww', 'Initial ASCII letter w is escaped'); + assert.same(escape('xxx'), '\\x78xx', 'Initial ASCII letter x is escaped'); + assert.same(escape('yyy'), '\\x79yy', 'Initial ASCII letter y is escaped'); + assert.same(escape('zzz'), '\\x7azz', 'Initial ASCII letter z is escaped'); + assert.same(escape('AAA'), '\\x41AA', 'Initial ASCII letter A is escaped'); + assert.same(escape('BBB'), '\\x42BB', 'Initial ASCII letter B is escaped'); + assert.same(escape('CCC'), '\\x43CC', 'Initial ASCII letter C is escaped'); + assert.same(escape('DDD'), '\\x44DD', 'Initial ASCII letter D is escaped'); + assert.same(escape('EEE'), '\\x45EE', 'Initial ASCII letter E is escaped'); + assert.same(escape('FFF'), '\\x46FF', 'Initial ASCII letter F is escaped'); + assert.same(escape('GGG'), '\\x47GG', 'Initial ASCII letter G is escaped'); + assert.same(escape('HHH'), '\\x48HH', 'Initial ASCII letter H is escaped'); + assert.same(escape('III'), '\\x49II', 'Initial ASCII letter I is escaped'); + assert.same(escape('JJJ'), '\\x4aJJ', 'Initial ASCII letter J is escaped'); + assert.same(escape('KKK'), '\\x4bKK', 'Initial ASCII letter K is escaped'); + assert.same(escape('LLL'), '\\x4cLL', 'Initial ASCII letter L is escaped'); + assert.same(escape('MMM'), '\\x4dMM', 'Initial ASCII letter M is escaped'); + assert.same(escape('NNN'), '\\x4eNN', 'Initial ASCII letter N is escaped'); + assert.same(escape('OOO'), '\\x4fOO', 'Initial ASCII letter O is escaped'); + assert.same(escape('PPP'), '\\x50PP', 'Initial ASCII letter P is escaped'); + assert.same(escape('QQQ'), '\\x51QQ', 'Initial ASCII letter Q is escaped'); + assert.same(escape('RRR'), '\\x52RR', 'Initial ASCII letter R is escaped'); + assert.same(escape('SSS'), '\\x53SS', 'Initial ASCII letter S is escaped'); + assert.same(escape('TTT'), '\\x54TT', 'Initial ASCII letter T is escaped'); + assert.same(escape('UUU'), '\\x55UU', 'Initial ASCII letter U is escaped'); + assert.same(escape('VVV'), '\\x56VV', 'Initial ASCII letter V is escaped'); + assert.same(escape('WWW'), '\\x57WW', 'Initial ASCII letter W is escaped'); + assert.same(escape('XXX'), '\\x58XX', 'Initial ASCII letter X is escaped'); + assert.same(escape('YYY'), '\\x59YY', 'Initial ASCII letter Y is escaped'); + assert.same(escape('ZZZ'), '\\x5aZZ', 'Initial ASCII letter Z is escaped'); + + // Mixed case with special characters + assert.same(escape('1+1'), '\\x31\\+1', 'Initial decimal digit 1 with special character is escaped'); + assert.same(escape('2+2'), '\\x32\\+2', 'Initial decimal digit 2 with special character is escaped'); + assert.same(escape('3+3'), '\\x33\\+3', 'Initial decimal digit 3 with special character is escaped'); + assert.same(escape('4+4'), '\\x34\\+4', 'Initial decimal digit 4 with special character is escaped'); + assert.same(escape('5+5'), '\\x35\\+5', 'Initial decimal digit 5 with special character is escaped'); + assert.same(escape('6+6'), '\\x36\\+6', 'Initial decimal digit 6 with special character is escaped'); + assert.same(escape('7+7'), '\\x37\\+7', 'Initial decimal digit 7 with special character is escaped'); + assert.same(escape('8+8'), '\\x38\\+8', 'Initial decimal digit 8 with special character is escaped'); + assert.same(escape('9+9'), '\\x39\\+9', 'Initial decimal digit 9 with special character is escaped'); + assert.same(escape('0+0'), '\\x30\\+0', 'Initial decimal digit 0 with special character is escaped'); + + assert.same(escape('a*a'), '\\x61\\*a', 'Initial ASCII letter a with special character is escaped'); + assert.same(escape('b*b'), '\\x62\\*b', 'Initial ASCII letter b with special character is escaped'); + assert.same(escape('c*c'), '\\x63\\*c', 'Initial ASCII letter c with special character is escaped'); + assert.same(escape('d*d'), '\\x64\\*d', 'Initial ASCII letter d with special character is escaped'); + assert.same(escape('e*e'), '\\x65\\*e', 'Initial ASCII letter e with special character is escaped'); + assert.same(escape('f*f'), '\\x66\\*f', 'Initial ASCII letter f with special character is escaped'); + assert.same(escape('g*g'), '\\x67\\*g', 'Initial ASCII letter g with special character is escaped'); + assert.same(escape('h*h'), '\\x68\\*h', 'Initial ASCII letter h with special character is escaped'); + assert.same(escape('i*i'), '\\x69\\*i', 'Initial ASCII letter i with special character is escaped'); + assert.same(escape('j*j'), '\\x6a\\*j', 'Initial ASCII letter j with special character is escaped'); + assert.same(escape('k*k'), '\\x6b\\*k', 'Initial ASCII letter k with special character is escaped'); + assert.same(escape('l*l'), '\\x6c\\*l', 'Initial ASCII letter l with special character is escaped'); + assert.same(escape('m*m'), '\\x6d\\*m', 'Initial ASCII letter m with special character is escaped'); + assert.same(escape('n*n'), '\\x6e\\*n', 'Initial ASCII letter n with special character is escaped'); + assert.same(escape('o*o'), '\\x6f\\*o', 'Initial ASCII letter o with special character is escaped'); + assert.same(escape('p*p'), '\\x70\\*p', 'Initial ASCII letter p with special character is escaped'); + assert.same(escape('q*q'), '\\x71\\*q', 'Initial ASCII letter q with special character is escaped'); + assert.same(escape('r*r'), '\\x72\\*r', 'Initial ASCII letter r with special character is escaped'); + assert.same(escape('s*s'), '\\x73\\*s', 'Initial ASCII letter s with special character is escaped'); + assert.same(escape('t*t'), '\\x74\\*t', 'Initial ASCII letter t with special character is escaped'); + assert.same(escape('u*u'), '\\x75\\*u', 'Initial ASCII letter u with special character is escaped'); + assert.same(escape('v*v'), '\\x76\\*v', 'Initial ASCII letter v with special character is escaped'); + assert.same(escape('w*w'), '\\x77\\*w', 'Initial ASCII letter w with special character is escaped'); + assert.same(escape('x*x'), '\\x78\\*x', 'Initial ASCII letter x with special character is escaped'); + assert.same(escape('y*y'), '\\x79\\*y', 'Initial ASCII letter y with special character is escaped'); + assert.same(escape('z*z'), '\\x7a\\*z', 'Initial ASCII letter z with special character is escaped'); + assert.same(escape('A*A'), '\\x41\\*A', 'Initial ASCII letter A with special character is escaped'); + assert.same(escape('B*B'), '\\x42\\*B', 'Initial ASCII letter B with special character is escaped'); + assert.same(escape('C*C'), '\\x43\\*C', 'Initial ASCII letter C with special character is escaped'); + assert.same(escape('D*D'), '\\x44\\*D', 'Initial ASCII letter D with special character is escaped'); + assert.same(escape('E*E'), '\\x45\\*E', 'Initial ASCII letter E with special character is escaped'); + assert.same(escape('F*F'), '\\x46\\*F', 'Initial ASCII letter F with special character is escaped'); + assert.same(escape('G*G'), '\\x47\\*G', 'Initial ASCII letter G with special character is escaped'); + assert.same(escape('H*H'), '\\x48\\*H', 'Initial ASCII letter H with special character is escaped'); + assert.same(escape('I*I'), '\\x49\\*I', 'Initial ASCII letter I with special character is escaped'); + assert.same(escape('J*J'), '\\x4a\\*J', 'Initial ASCII letter J with special character is escaped'); + assert.same(escape('K*K'), '\\x4b\\*K', 'Initial ASCII letter K with special character is escaped'); + assert.same(escape('L*L'), '\\x4c\\*L', 'Initial ASCII letter L with special character is escaped'); + assert.same(escape('M*M'), '\\x4d\\*M', 'Initial ASCII letter M with special character is escaped'); + assert.same(escape('N*N'), '\\x4e\\*N', 'Initial ASCII letter N with special character is escaped'); + assert.same(escape('O*O'), '\\x4f\\*O', 'Initial ASCII letter O with special character is escaped'); + assert.same(escape('P*P'), '\\x50\\*P', 'Initial ASCII letter P with special character is escaped'); + assert.same(escape('Q*Q'), '\\x51\\*Q', 'Initial ASCII letter Q with special character is escaped'); + assert.same(escape('R*R'), '\\x52\\*R', 'Initial ASCII letter R with special character is escaped'); + assert.same(escape('S*S'), '\\x53\\*S', 'Initial ASCII letter S with special character is escaped'); + assert.same(escape('T*T'), '\\x54\\*T', 'Initial ASCII letter T with special character is escaped'); + assert.same(escape('U*U'), '\\x55\\*U', 'Initial ASCII letter U with special character is escaped'); + assert.same(escape('V*V'), '\\x56\\*V', 'Initial ASCII letter V with special character is escaped'); + assert.same(escape('W*W'), '\\x57\\*W', 'Initial ASCII letter W with special character is escaped'); + assert.same(escape('X*X'), '\\x58\\*X', 'Initial ASCII letter X with special character is escaped'); + assert.same(escape('Y*Y'), '\\x59\\*Y', 'Initial ASCII letter Y with special character is escaped'); + assert.same(escape('Z*Z'), '\\x5a\\*Z', 'Initial ASCII letter Z with special character is escaped'); + + assert.same(escape('_'), '_', 'Single underscore character is not escaped'); + assert.same(escape('__'), '__', 'Thunderscore character is not escaped'); + assert.same(escape('hello_world'), '\\x68ello_world', 'String starting with ASCII letter and containing underscore is not escaped'); + assert.same(escape('1_hello_world'), '\\x31_hello_world', 'String starting with digit and containing underscore is correctly escaped'); + assert.same(escape('a_b_c'), '\\x61_b_c', 'String starting with ASCII letter and containing multiple underscores is correctly escaped'); + assert.same(escape('3_b_4'), '\\x33_b_4', 'String starting with digit and containing multiple underscores is correctly escaped'); + assert.same(escape('_hello'), '_hello', 'String starting with underscore and containing other characters is not escaped'); + assert.same(escape('_1hello'), '_1hello', 'String starting with underscore and digit is not escaped'); + assert.same(escape('_a_1_2'), '_a_1_2', 'String starting with underscore and mixed characters is not escaped'); + + // Specific surrogate points + assert.same(escape('\uD800'), '\\ud800', 'High surrogate \\uD800 is correctly escaped'); + assert.same(escape('\uDBFF'), '\\udbff', 'High surrogate \\uDBFF is correctly escaped'); + assert.same(escape('\uDC00'), '\\udc00', 'Low surrogate \\uDC00 is correctly escaped'); + assert.same(escape('\uDFFF'), '\\udfff', 'Low surrogate \\uDFFF is correctly escaped'); + + // Leading Surrogates + const highSurrogatesGroup1 = '\uD800\uD801\uD802\uD803\uD804\uD805\uD806\uD807\uD808\uD809\uD80A\uD80B\uD80C\uD80D\uD80E\uD80F'; + const highSurrogatesGroup2 = '\uD810\uD811\uD812\uD813\uD814\uD815\uD816\uD817\uD818\uD819\uD81A\uD81B\uD81C\uD81D\uD81E\uD81F'; + const highSurrogatesGroup3 = '\uD820\uD821\uD822\uD823\uD824\uD825\uD826\uD827\uD828\uD829\uD82A\uD82B\uD82C\uD82D\uD82E\uD82F'; + const highSurrogatesGroup4 = '\uD830\uD831\uD832\uD833\uD834\uD835\uD836\uD837\uD838\uD839\uD83A\uD83B\uD83C\uD83D\uD83E\uD83F'; + const highSurrogatesGroup5 = '\uD840\uD841\uD842\uD843\uD844\uD845\uD846\uD847\uD848\uD849\uD84A\uD84B\uD84C\uD84D\uD84E\uD84F'; + const highSurrogatesGroup6 = '\uD850\uD851\uD852\uD853\uD854\uD855\uD856\uD857\uD858\uD859\uD85A\uD85B\uD85C\uD85D\uD85E\uD85F'; + const highSurrogatesGroup7 = '\uD860\uD861\uD862\uD863\uD864\uD865\uD866\uD867\uD868\uD869\uD86A\uD86B\uD86C\uD86D\uD86E\uD86F'; + const highSurrogatesGroup8 = '\uD870\uD871\uD872\uD873\uD874\uD875\uD876\uD877\uD878\uD879\uD87A\uD87B\uD87C\uD87D\uD87E\uD87F'; + const highSurrogatesGroup9 = '\uD880\uD881\uD882\uD883\uD884\uD885\uD886\uD887\uD888\uD889\uD88A\uD88B\uD88C\uD88D\uD88E\uD88F'; + const highSurrogatesGroup10 = '\uD890\uD891\uD892\uD893\uD894\uD895\uD896\uD897\uD898\uD899\uD89A\uD89B\uD89C\uD89D\uD89E\uD89F'; + const highSurrogatesGroup11 = '\uD8A0\uD8A1\uD8A2\uD8A3\uD8A4\uD8A5\uD8A6\uD8A7\uD8A8\uD8A9\uD8AA\uD8AB\uD8AC\uD8AD\uD8AE\uD8AF'; + const highSurrogatesGroup12 = '\uD8B0\uD8B1\uD8B2\uD8B3\uD8B4\uD8B5\uD8B6\uD8B7\uD8B8\uD8B9\uD8BA\uD8BB\uD8BC\uD8BD\uD8BE\uD8BF'; + const highSurrogatesGroup13 = '\uD8C0\uD8C1\uD8C2\uD8C3\uD8C4\uD8C5\uD8C6\uD8C7\uD8C8\uD8C9\uD8CA\uD8CB\uD8CC\uD8CD\uD8CE\uD8CF'; + const highSurrogatesGroup14 = '\uD8D0\uD8D1\uD8D2\uD8D3\uD8D4\uD8D5\uD8D6\uD8D7\uD8D8\uD8D9\uD8DA\uD8DB\uD8DC\uD8DD\uD8DE\uD8DF'; + const highSurrogatesGroup15 = '\uD8E0\uD8E1\uD8E2\uD8E3\uD8E4\uD8E5\uD8E6\uD8E7\uD8E8\uD8E9\uD8EA\uD8EB\uD8EC\uD8ED\uD8EE\uD8EF'; + const highSurrogatesGroup16 = '\uD8F0\uD8F1\uD8F2\uD8F3\uD8F4\uD8F5\uD8F6\uD8F7\uD8F8\uD8F9\uD8FA\uD8FB\uD8FC\uD8FD\uD8FE\uD8FF'; + + assert.same(escape(highSurrogatesGroup1), '\\ud800\\ud801\\ud802\\ud803\\ud804\\ud805\\ud806\\ud807\\ud808\\ud809\\ud80a\\ud80b\\ud80c\\ud80d\\ud80e\\ud80f', 'High surrogates group 1 are correctly escaped'); + assert.same(escape(highSurrogatesGroup2), '\\ud810\\ud811\\ud812\\ud813\\ud814\\ud815\\ud816\\ud817\\ud818\\ud819\\ud81a\\ud81b\\ud81c\\ud81d\\ud81e\\ud81f', 'High surrogates group 2 are correctly escaped'); + assert.same(escape(highSurrogatesGroup3), '\\ud820\\ud821\\ud822\\ud823\\ud824\\ud825\\ud826\\ud827\\ud828\\ud829\\ud82a\\ud82b\\ud82c\\ud82d\\ud82e\\ud82f', 'High surrogates group 3 are correctly escaped'); + assert.same(escape(highSurrogatesGroup4), '\\ud830\\ud831\\ud832\\ud833\\ud834\\ud835\\ud836\\ud837\\ud838\\ud839\\ud83a\\ud83b\\ud83c\\ud83d\\ud83e\\ud83f', 'High surrogates group 4 are correctly escaped'); + assert.same(escape(highSurrogatesGroup5), '\\ud840\\ud841\\ud842\\ud843\\ud844\\ud845\\ud846\\ud847\\ud848\\ud849\\ud84a\\ud84b\\ud84c\\ud84d\\ud84e\\ud84f', 'High surrogates group 5 are correctly escaped'); + assert.same(escape(highSurrogatesGroup6), '\\ud850\\ud851\\ud852\\ud853\\ud854\\ud855\\ud856\\ud857\\ud858\\ud859\\ud85a\\ud85b\\ud85c\\ud85d\\ud85e\\ud85f', 'High surrogates group 6 are correctly escaped'); + assert.same(escape(highSurrogatesGroup7), '\\ud860\\ud861\\ud862\\ud863\\ud864\\ud865\\ud866\\ud867\\ud868\\ud869\\ud86a\\ud86b\\ud86c\\ud86d\\ud86e\\ud86f', 'High surrogates group 7 are correctly escaped'); + assert.same(escape(highSurrogatesGroup8), '\\ud870\\ud871\\ud872\\ud873\\ud874\\ud875\\ud876\\ud877\\ud878\\ud879\\ud87a\\ud87b\\ud87c\\ud87d\\ud87e\\ud87f', 'High surrogates group 8 are correctly escaped'); + assert.same(escape(highSurrogatesGroup9), '\\ud880\\ud881\\ud882\\ud883\\ud884\\ud885\\ud886\\ud887\\ud888\\ud889\\ud88a\\ud88b\\ud88c\\ud88d\\ud88e\\ud88f', 'High surrogates group 9 are correctly escaped'); + assert.same(escape(highSurrogatesGroup10), '\\ud890\\ud891\\ud892\\ud893\\ud894\\ud895\\ud896\\ud897\\ud898\\ud899\\ud89a\\ud89b\\ud89c\\ud89d\\ud89e\\ud89f', 'High surrogates group 10 are correctly escaped'); + assert.same(escape(highSurrogatesGroup11), '\\ud8a0\\ud8a1\\ud8a2\\ud8a3\\ud8a4\\ud8a5\\ud8a6\\ud8a7\\ud8a8\\ud8a9\\ud8aa\\ud8ab\\ud8ac\\ud8ad\\ud8ae\\ud8af', 'High surrogates group 11 are correctly escaped'); + assert.same(escape(highSurrogatesGroup12), '\\ud8b0\\ud8b1\\ud8b2\\ud8b3\\ud8b4\\ud8b5\\ud8b6\\ud8b7\\ud8b8\\ud8b9\\ud8ba\\ud8bb\\ud8bc\\ud8bd\\ud8be\\ud8bf', 'High surrogates group 12 are correctly escaped'); + assert.same(escape(highSurrogatesGroup13), '\\ud8c0\\ud8c1\\ud8c2\\ud8c3\\ud8c4\\ud8c5\\ud8c6\\ud8c7\\ud8c8\\ud8c9\\ud8ca\\ud8cb\\ud8cc\\ud8cd\\ud8ce\\ud8cf', 'High surrogates group 13 are correctly escaped'); + assert.same(escape(highSurrogatesGroup14), '\\ud8d0\\ud8d1\\ud8d2\\ud8d3\\ud8d4\\ud8d5\\ud8d6\\ud8d7\\ud8d8\\ud8d9\\ud8da\\ud8db\\ud8dc\\ud8dd\\ud8de\\ud8df', 'High surrogates group 14 are correctly escaped'); + assert.same(escape(highSurrogatesGroup15), '\\ud8e0\\ud8e1\\ud8e2\\ud8e3\\ud8e4\\ud8e5\\ud8e6\\ud8e7\\ud8e8\\ud8e9\\ud8ea\\ud8eb\\ud8ec\\ud8ed\\ud8ee\\ud8ef', 'High surrogates group 15 are correctly escaped'); + assert.same(escape(highSurrogatesGroup16), '\\ud8f0\\ud8f1\\ud8f2\\ud8f3\\ud8f4\\ud8f5\\ud8f6\\ud8f7\\ud8f8\\ud8f9\\ud8fa\\ud8fb\\ud8fc\\ud8fd\\ud8fe\\ud8ff', 'High surrogates group 16 are correctly escaped'); + + // Trailing Surrogates + const lowSurrogatesGroup1 = '\uDC00\uDC01\uDC02\uDC03\uDC04\uDC05\uDC06\uDC07\uDC08\uDC09\uDC0A\uDC0B\uDC0C\uDC0D\uDC0E\uDC0F'; + const lowSurrogatesGroup2 = '\uDC10\uDC11\uDC12\uDC13\uDC14\uDC15\uDC16\uDC17\uDC18\uDC19\uDC1A\uDC1B\uDC1C\uDC1D\uDC1E\uDC1F'; + const lowSurrogatesGroup3 = '\uDC20\uDC21\uDC22\uDC23\uDC24\uDC25\uDC26\uDC27\uDC28\uDC29\uDC2A\uDC2B\uDC2C\uDC2D\uDC2E\uDC2F'; + const lowSurrogatesGroup4 = '\uDC30\uDC31\uDC32\uDC33\uDC34\uDC35\uDC36\uDC37\uDC38\uDC39\uDC3A\uDC3B\uDC3C\uDC3D\uDC3E\uDC3F'; + const lowSurrogatesGroup5 = '\uDC40\uDC41\uDC42\uDC43\uDC44\uDC45\uDC46\uDC47\uDC48\uDC49\uDC4A\uDC4B\uDC4C\uDC4D\uDC4E\uDC4F'; + const lowSurrogatesGroup6 = '\uDC50\uDC51\uDC52\uDC53\uDC54\uDC55\uDC56\uDC57\uDC58\uDC59\uDC5A\uDC5B\uDC5C\uDC5D\uDC5E\uDC5F'; + const lowSurrogatesGroup7 = '\uDC60\uDC61\uDC62\uDC63\uDC64\uDC65\uDC66\uDC67\uDC68\uDC69\uDC6A\uDC6B\uDC6C\uDC6D\uDC6E\uDC6F'; + const lowSurrogatesGroup8 = '\uDC70\uDC71\uDC72\uDC73\uDC74\uDC75\uDC76\uDC77\uDC78\uDC79\uDC7A\uDC7B\uDC7C\uDC7D\uDC7E\uDC7F'; + const lowSurrogatesGroup9 = '\uDC80\uDC81\uDC82\uDC83\uDC84\uDC85\uDC86\uDC87\uDC88\uDC89\uDC8A\uDC8B\uDC8C\uDC8D\uDC8E\uDC8F'; + const lowSurrogatesGroup10 = '\uDC90\uDC91\uDC92\uDC93\uDC94\uDC95\uDC96\uDC97\uDC98\uDC99\uDC9A\uDC9B\uDC9C\uDC9D\uDC9E\uDC9F'; + const lowSurrogatesGroup11 = '\uDCA0\uDCA1\uDCA2\uDCA3\uDCA4\uDCA5\uDCA6\uDCA7\uDCA8\uDCA9\uDCAA\uDCAB\uDCAC\uDCAD\uDCAE\uDCAF'; + const lowSurrogatesGroup12 = '\uDCB0\uDCB1\uDCB2\uDCB3\uDCB4\uDCB5\uDCB6\uDCB7\uDCB8\uDCB9\uDCBA\uDCBB\uDCBC\uDCBD\uDCBE\uDCBF'; + const lowSurrogatesGroup13 = '\uDCC0\uDCC1\uDCC2\uDCC3\uDCC4\uDCC5\uDCC6\uDCC7\uDCC8\uDCC9\uDCCA\uDCCB\uDCCC\uDCCD\uDCCE\uDCCF'; + const lowSurrogatesGroup14 = '\uDCD0\uDCD1\uDCD2\uDCD3\uDCD4\uDCD5\uDCD6\uDCD7\uDCD8\uDCD9\uDCDA\uDCDB\uDCDC\uDCDD\uDCDE\uDCDF'; + const lowSurrogatesGroup15 = '\uDCE0\uDCE1\uDCE2\uDCE3\uDCE4\uDCE5\uDCE6\uDCE7\uDCE8\uDCE9\uDCEA\uDCEB\uDCEC\uDCED\uDCEE\uDCEF'; + const lowSurrogatesGroup16 = '\uDCF0\uDCF1\uDCF2\uDCF3\uDCF4\uDCF5\uDCF6\uDCF7\uDCF8\uDCF9\uDCFA\uDCFB\uDCFC\uDCFD\uDCFE\uDCFF'; + + assert.same(escape(lowSurrogatesGroup1), '\\udc00\\udc01\\udc02\\udc03\\udc04\\udc05\\udc06\\udc07\\udc08\\udc09\\udc0a\\udc0b\\udc0c\\udc0d\\udc0e\\udc0f', 'Low surrogates group 1 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup2), '\\udc10\\udc11\\udc12\\udc13\\udc14\\udc15\\udc16\\udc17\\udc18\\udc19\\udc1a\\udc1b\\udc1c\\udc1d\\udc1e\\udc1f', 'Low surrogates group 2 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup3), '\\udc20\\udc21\\udc22\\udc23\\udc24\\udc25\\udc26\\udc27\\udc28\\udc29\\udc2a\\udc2b\\udc2c\\udc2d\\udc2e\\udc2f', 'Low surrogates group 3 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup4), '\\udc30\\udc31\\udc32\\udc33\\udc34\\udc35\\udc36\\udc37\\udc38\\udc39\\udc3a\\udc3b\\udc3c\\udc3d\\udc3e\\udc3f', 'Low surrogates group 4 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup5), '\\udc40\\udc41\\udc42\\udc43\\udc44\\udc45\\udc46\\udc47\\udc48\\udc49\\udc4a\\udc4b\\udc4c\\udc4d\\udc4e\\udc4f', 'Low surrogates group 5 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup6), '\\udc50\\udc51\\udc52\\udc53\\udc54\\udc55\\udc56\\udc57\\udc58\\udc59\\udc5a\\udc5b\\udc5c\\udc5d\\udc5e\\udc5f', 'Low surrogates group 6 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup7), '\\udc60\\udc61\\udc62\\udc63\\udc64\\udc65\\udc66\\udc67\\udc68\\udc69\\udc6a\\udc6b\\udc6c\\udc6d\\udc6e\\udc6f', 'Low surrogates group 7 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup8), '\\udc70\\udc71\\udc72\\udc73\\udc74\\udc75\\udc76\\udc77\\udc78\\udc79\\udc7a\\udc7b\\udc7c\\udc7d\\udc7e\\udc7f', 'Low surrogates group 8 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup9), '\\udc80\\udc81\\udc82\\udc83\\udc84\\udc85\\udc86\\udc87\\udc88\\udc89\\udc8a\\udc8b\\udc8c\\udc8d\\udc8e\\udc8f', 'Low surrogates group 9 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup10), '\\udc90\\udc91\\udc92\\udc93\\udc94\\udc95\\udc96\\udc97\\udc98\\udc99\\udc9a\\udc9b\\udc9c\\udc9d\\udc9e\\udc9f', 'Low surrogates group 10 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup11), '\\udca0\\udca1\\udca2\\udca3\\udca4\\udca5\\udca6\\udca7\\udca8\\udca9\\udcaa\\udcab\\udcac\\udcad\\udcae\\udcaf', 'Low surrogates group 11 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup12), '\\udcb0\\udcb1\\udcb2\\udcb3\\udcb4\\udcb5\\udcb6\\udcb7\\udcb8\\udcb9\\udcba\\udcbb\\udcbc\\udcbd\\udcbe\\udcbf', 'Low surrogates group 12 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup13), '\\udcc0\\udcc1\\udcc2\\udcc3\\udcc4\\udcc5\\udcc6\\udcc7\\udcc8\\udcc9\\udcca\\udccb\\udccc\\udccd\\udcce\\udccf', 'Low surrogates group 13 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup14), '\\udcd0\\udcd1\\udcd2\\udcd3\\udcd4\\udcd5\\udcd6\\udcd7\\udcd8\\udcd9\\udcda\\udcdb\\udcdc\\udcdd\\udcde\\udcdf', 'Low surrogates group 14 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup15), '\\udce0\\udce1\\udce2\\udce3\\udce4\\udce5\\udce6\\udce7\\udce8\\udce9\\udcea\\udceb\\udcec\\udced\\udcee\\udcef', 'Low surrogates group 15 are correctly escaped'); + assert.same(escape(lowSurrogatesGroup16), '\\udcf0\\udcf1\\udcf2\\udcf3\\udcf4\\udcf5\\udcf6\\udcf7\\udcf8\\udcf9\\udcfa\\udcfb\\udcfc\\udcfd\\udcfe\\udcff', 'Low surrogates group 16 are correctly escaped'); + + assert.same(escape('.a.b'), '\\.a\\.b', 'mixed string with dot character is escaped correctly'); + assert.same(escape('.1+2'), '\\.1\\+2', 'mixed string with plus character is escaped correctly'); + assert.same(escape('.a(b)c'), '\\.a\\(b\\)c', 'mixed string with parentheses is escaped correctly'); + assert.same(escape('.a*b+c'), '\\.a\\*b\\+c', 'mixed string with asterisk and plus characters is escaped correctly'); + assert.same(escape('.a?b^c'), '\\.a\\?b\\^c', 'mixed string with question mark and caret characters is escaped correctly'); + assert.same(escape('.a{2}'), '\\.a\\{2\\}', 'mixed string with curly braces is escaped correctly'); + assert.same(escape('.a|b'), '\\.a\\|b', 'mixed string with pipe character is escaped correctly'); + assert.same(escape('.a\\b'), '\\.a\\\\b', 'mixed string with backslash is escaped correctly'); + assert.same(escape('.a\\\\b'), '\\.a\\\\\\\\b', 'mixed string with backslash is escaped correctly'); + assert.same(escape('.a^b'), '\\.a\\^b', 'mixed string with caret character is escaped correctly'); + assert.same(escape('.a$b'), '\\.a\\$b', 'mixed string with dollar sign is escaped correctly'); + assert.same(escape('.a[b]'), '\\.a\\[b\\]', 'mixed string with square brackets is escaped correctly'); + assert.same(escape('.a.b(c)'), '\\.a\\.b\\(c\\)', 'mixed string with dot and parentheses is escaped correctly'); + assert.same(escape('.a*b+c?d^e$f|g{2}h[i]j\\k'), '\\.a\\*b\\+c\\?d\\^e\\$f\\|g\\{2\\}h\\[i\\]j\\\\k', 'complex string with multiple special characters is escaped correctly'); + + assert.same(escape('^$\\.*+?()[]{}|'), '\\^\\$\\\\\\.\\*\\+\\?\\(\\)\\[\\]\\{\\}\\|', 'Syntax characters are correctly escaped'); + + assert.throws(() => escape(123), TypeError, 'non-string input (number) throws TypeError'); + assert.throws(() => escape({}), TypeError, 'non-string input (object) throws TypeError'); + assert.throws(() => escape([]), TypeError, 'non-string input (array) throws TypeError'); + assert.throws(() => escape(null), TypeError, 'non-string input (null) throws TypeError'); + assert.throws(() => escape(undefined), TypeError, 'non-string input (undefined) throws TypeError'); +}); diff --git a/tests/unit-pure/es.set.difference.js b/tests/unit-pure/es.set.difference.js new file mode 100644 index 000000000000..0c10b104fa71 --- /dev/null +++ b/tests/unit-pure/es.set.difference.js @@ -0,0 +1,75 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +import from from 'core-js-pure/es/array/from'; +// TODO: use /es/ in core-js@4 +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#difference', assert => { + const { difference } = Set.prototype; + + assert.isFunction(difference); + assert.arity(difference, 1); + assert.name(difference, 'difference'); + assert.nonEnumerable(Set.prototype, 'difference'); + + const set = new Set([1]); + assert.notSame(set.difference(new Set()), set); + + assert.deepEqual(from(new Set([1, 2, 3]).difference(new Set([4, 5]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).difference(new Set([3, 4]))), [1, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).difference(createSetLike([3, 4]))), [1, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).difference(createSetLike([3, 4]))), [1, 2]); + + // TODO: drop from core-js@4 + assert.deepEqual(from(new Set([1, 2, 3]).difference([4, 5])), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).difference([3, 4])), [1, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).difference(createIterable([3, 4]))), [1, 2]); + + assert.same(new Set([42, 43]).difference({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + }).size, 0); + + assert.throws(() => new Set().difference({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).difference(), TypeError); + + assert.throws(() => difference.call({}, [1, 2, 3]), TypeError); + assert.throws(() => difference.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => difference.call(null, [1, 2, 3]), TypeError); + + // A WebKit bug occurs when `this` is updated while Set.prototype.difference is being executed + // https://bugs.webkit.org/show_bug.cgi?id=288595 + const values = [2]; + const setLike = { + size: values.length, + has() { return true; }, + keys() { + let index = 0; + return { + next() { + const done = index >= values.length; + if (baseSet.has(1)) baseSet.clear(); + return { done, value: values[index++] }; + }, + }; + }, + }; + + const baseSet = new Set([1, 2, 3, 4]); + const result = baseSet.difference(setLike); + assert.deepEqual(from(result), [1, 3, 4], 'incorrect behavior when this updated while Set#difference is being executed'); +}); diff --git a/tests/unit-pure/es.set.intersection.js b/tests/unit-pure/es.set.intersection.js new file mode 100644 index 000000000000..429905c06a97 --- /dev/null +++ b/tests/unit-pure/es.set.intersection.js @@ -0,0 +1,60 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +import from from 'core-js-pure/es/array/from'; +// TODO: use /es/ in core-js@4 +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#intersection', assert => { + const { intersection } = Set.prototype; + + assert.isFunction(intersection); + assert.arity(intersection, 1); + assert.name(intersection, 'intersection'); + assert.nonEnumerable(Set.prototype, 'intersection'); + + const set = new Set([1]); + assert.notSame(set.intersection(new Set()), set); + + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([4, 5]))), []); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([2, 3, 4]))), [2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([4, 5]))), []); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([2, 3, 4]))), [2, 3]); + + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2]))), [3, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2, 1]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(new Set([3, 2, 1, 0]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2]))), [3, 2]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2, 1]))), [1, 2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createSetLike([3, 2, 1, 0]))), [1, 2, 3]); + + // TODO: drop from core-js@4 + assert.deepEqual(from(new Set([1, 2, 3]).intersection([4, 5])), []); + assert.deepEqual(from(new Set([1, 2, 3]).intersection([2, 3, 4])), [2, 3]); + assert.deepEqual(from(new Set([1, 2, 3]).intersection(createIterable([2, 3, 4]))), [2, 3]); + + assert.deepEqual(from(new Set([42, 43]).intersection({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })), [42, 43]); + + assert.throws(() => new Set().intersection({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).intersection(), TypeError); + + assert.throws(() => intersection.call({}, [1, 2, 3]), TypeError); + assert.throws(() => intersection.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => intersection.call(null, [1, 2, 3]), TypeError); +}); diff --git a/tests/unit-pure/es.set.is-disjoint-from.js b/tests/unit-pure/es.set.is-disjoint-from.js new file mode 100644 index 000000000000..96e18d8389bc --- /dev/null +++ b/tests/unit-pure/es.set.is-disjoint-from.js @@ -0,0 +1,55 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +// TODO: use /es/ in core-js@4 +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#isDisjointFrom', assert => { + const { isDisjointFrom } = Set.prototype; + + assert.isFunction(isDisjointFrom); + assert.arity(isDisjointFrom, 1); + assert.name(isDisjointFrom, 'isDisjointFrom'); + assert.nonEnumerable(Set.prototype, 'isDisjointFrom'); + + assert.true(new Set([1]).isDisjointFrom(new Set([2]))); + assert.false(new Set([1]).isDisjointFrom(new Set([1]))); + assert.true(new Set([1, 2, 3]).isDisjointFrom(new Set([4, 5, 6]))); + assert.false(new Set([1, 2, 3]).isDisjointFrom(new Set([5, 4, 3]))); + assert.true(new Set([1]).isDisjointFrom(createSetLike([2]))); + assert.false(new Set([1]).isDisjointFrom(createSetLike([1]))); + assert.true(new Set([1, 2, 3]).isDisjointFrom(createSetLike([4, 5, 6]))); + assert.false(new Set([1, 2, 3]).isDisjointFrom(createSetLike([5, 4, 3]))); + + // TODO: drop from core-js@4 + assert.true(new Set([1]).isDisjointFrom([2])); + assert.false(new Set([1]).isDisjointFrom([1])); + assert.true(new Set([1, 2, 3]).isDisjointFrom([4, 5, 6])); + assert.false(new Set([1, 2, 3]).isDisjointFrom([5, 4, 3])); + assert.true(new Set([1]).isDisjointFrom(createIterable([2]))); + assert.false(new Set([1]).isDisjointFrom(createIterable([1]))); + + assert.false(new Set([42, 43]).isDisjointFrom({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set().isDisjointFrom({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).isDisjointFrom(), TypeError); + assert.throws(() => isDisjointFrom.call({}, [1, 2, 3]), TypeError); + assert.throws(() => isDisjointFrom.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => isDisjointFrom.call(null, [1, 2, 3]), TypeError); +}); diff --git a/tests/unit-pure/es.set.is-subset-of.js b/tests/unit-pure/es.set.is-subset-of.js new file mode 100644 index 000000000000..556e1c0d1d3f --- /dev/null +++ b/tests/unit-pure/es.set.is-subset-of.js @@ -0,0 +1,55 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +// TODO: use /es/ in core-js@4 +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#isSubsetOf', assert => { + const { isSubsetOf } = Set.prototype; + + assert.isFunction(isSubsetOf); + assert.arity(isSubsetOf, 1); + assert.name(isSubsetOf, 'isSubsetOf'); + assert.nonEnumerable(Set.prototype, 'isSubsetOf'); + + assert.true(new Set([1]).isSubsetOf(new Set([1, 2, 3]))); + assert.false(new Set([1]).isSubsetOf(new Set([2, 3, 4]))); + assert.true(new Set([1, 2, 3]).isSubsetOf(new Set([5, 4, 3, 2, 1]))); + assert.false(new Set([1, 2, 3]).isSubsetOf(new Set([5, 4, 3, 2]))); + assert.true(new Set([1]).isSubsetOf(createSetLike([1, 2, 3]))); + assert.false(new Set([1]).isSubsetOf(createSetLike([2, 3, 4]))); + assert.true(new Set([1, 2, 3]).isSubsetOf(createSetLike([5, 4, 3, 2, 1]))); + assert.false(new Set([1, 2, 3]).isSubsetOf(createSetLike([5, 4, 3, 2]))); + + // TODO: drop from core-js@4 + assert.true(new Set([1]).isSubsetOf([1, 2, 3])); + assert.false(new Set([1]).isSubsetOf([2, 3, 4])); + assert.true(new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2, 1])); + assert.false(new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2])); + assert.true(new Set([1]).isSubsetOf(createIterable([1, 2, 3]))); + assert.false(new Set([1]).isSubsetOf(createIterable([2, 3, 4]))); + + assert.true(new Set([42, 43]).isSubsetOf({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set().isSubsetOf({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).isSubsetOf(), TypeError); + assert.throws(() => isSubsetOf.call({}, [1, 2, 3]), TypeError); + assert.throws(() => isSubsetOf.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => isSubsetOf.call(null, [1, 2, 3]), TypeError); +}); diff --git a/tests/unit-pure/es.set.is-superset-of.js b/tests/unit-pure/es.set.is-superset-of.js new file mode 100644 index 000000000000..f4860ba6dd97 --- /dev/null +++ b/tests/unit-pure/es.set.is-superset-of.js @@ -0,0 +1,55 @@ +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +// TODO: use /es/ in core-js@4 +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#isSupersetOf', assert => { + const { isSupersetOf } = Set.prototype; + + assert.isFunction(isSupersetOf); + assert.arity(isSupersetOf, 1); + assert.name(isSupersetOf, 'isSupersetOf'); + assert.nonEnumerable(Set.prototype, 'isSupersetOf'); + + assert.true(new Set([1, 2, 3]).isSupersetOf(new Set([1]))); + assert.false(new Set([2, 3, 4]).isSupersetOf(new Set([1]))); + assert.true(new Set([5, 4, 3, 2, 1]).isSupersetOf(new Set([1, 2, 3]))); + assert.false(new Set([5, 4, 3, 2]).isSupersetOf(new Set([1, 2, 3]))); + assert.true(new Set([1, 2, 3]).isSupersetOf(createSetLike([1]))); + assert.false(new Set([2, 3, 4]).isSupersetOf(createSetLike([1]))); + assert.true(new Set([5, 4, 3, 2, 1]).isSupersetOf(createSetLike([1, 2, 3]))); + assert.false(new Set([5, 4, 3, 2]).isSupersetOf(createSetLike([1, 2, 3]))); + + // TODO: drop from core-js@4 + assert.true(new Set([1, 2, 3]).isSupersetOf([1])); + assert.false(new Set([2, 3, 4]).isSupersetOf([1])); + assert.true(new Set([5, 4, 3, 2, 1]).isSupersetOf([1, 2, 3])); + assert.false(new Set([5, 4, 3, 2]).isSupersetOf([1, 2, 3])); + assert.true(new Set([1, 2, 3]).isSupersetOf(createIterable([1]))); + assert.false(new Set([2, 3, 4]).isSupersetOf(createIterable([1]))); + + assert.false(new Set([42, 43]).isSupersetOf({ + size: Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set().isSupersetOf({ + size: -Infinity, + has() { + return true; + }, + keys() { + throw new Error('Unexpected call to |keys| method'); + }, + })); + + assert.throws(() => new Set([1, 2, 3]).isSupersetOf(), TypeError); + assert.throws(() => isSupersetOf.call({}, [1, 2, 3]), TypeError); + assert.throws(() => isSupersetOf.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => isSupersetOf.call(null, [1, 2, 3]), TypeError); +}); diff --git a/tests/unit-pure/es.set.js b/tests/unit-pure/es.set.js new file mode 100644 index 000000000000..75a237c83595 --- /dev/null +++ b/tests/unit-pure/es.set.js @@ -0,0 +1,415 @@ +/* eslint-disable sonarjs/no-element-overwrite -- required for testing */ + +import { createIterable, is, nativeSubclass } from '../helpers/helpers.js'; +import { DESCRIPTORS } from '../helpers/constants.js'; + +import getIterator from 'core-js-pure/es/get-iterator'; +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import from from 'core-js-pure/es/array/from'; +import freeze from 'core-js-pure/es/object/freeze'; +import getOwnPropertyDescriptor from 'core-js-pure/es/object/get-own-property-descriptor'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import keys from 'core-js-pure/es/object/keys'; +import ownKeys from 'core-js-pure/es/reflect/own-keys'; +import Symbol from 'core-js-pure/es/symbol'; +import Map from 'core-js-pure/es/map'; +import Set from 'core-js-pure/es/set'; + +QUnit.test('Set', assert => { + assert.isFunction(Set); + assert.true('add' in Set.prototype, 'add in Set.prototype'); + assert.true('clear' in Set.prototype, 'clear in Set.prototype'); + assert.true('delete' in Set.prototype, 'delete in Set.prototype'); + assert.true('forEach' in Set.prototype, 'forEach in Set.prototype'); + assert.true('has' in Set.prototype, 'has in Set.prototype'); + assert.true(new Set() instanceof Set, 'new Set instanceof Set'); + let set = new Set(); + set.add(1); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + assert.same(set.size, 3); + const result = []; + set.forEach(val => { + result.push(val); + }); + assert.deepEqual(result, [1, 2, 3]); + assert.same(new Set(createIterable([1, 2, 3])).size, 3, 'Init from iterable'); + assert.same(new Set([freeze({}), 1]).size, 2, 'Support frozen objects'); + assert.same(new Set([NaN, NaN, NaN]).size, 1); + assert.deepEqual(from(new Set([3, 4]).add(2).add(1)), [3, 4, 2, 1]); + let done = false; + const { add } = Set.prototype; + Set.prototype.add = function () { + throw new Error(); + }; + try { + new Set(createIterable([null, 1, 2], { + return() { + return done = true; + }, + })); + } catch { /* empty */ } + Set.prototype.add = add; + assert.true(done, '.return #throw'); + const array = []; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + new Set(array); + assert.true(done); + const object = {}; + new Set().add(object); + if (DESCRIPTORS) { + const results = []; + for (const key in results) keys.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(object), []); + } + assert.arrayEqual(getOwnPropertyNames(object), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); + if (ownKeys) assert.arrayEqual(ownKeys(object), []); + if (nativeSubclass) { + const Subclass = nativeSubclass(Set); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof Set, 'correct subclassing with native classes #2'); + assert.true(new Subclass().add(2).has(2), 'correct subclassing with native classes #3'); + } + + if (typeof ArrayBuffer == 'function') { + const buffer = new ArrayBuffer(8); + set = new Set([buffer]); + assert.true(set.has(buffer), 'works with ArrayBuffer keys'); + } +}); + +QUnit.test('Set#add', assert => { + assert.isFunction(Set.prototype.add); + const array = []; + let set = new Set(); + set.add(NaN); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.add(array); + assert.same(set.size, 5); + const chain = set.add(NaN); + assert.same(chain, set); + assert.same(set.size, 5); + set.add(2); + assert.same(set.size, 5); + set.add(array); + assert.same(set.size, 5); + set.add([]); + assert.same(set.size, 6); + set.add(4); + assert.same(set.size, 7); + const frozen = freeze({}); + set = new Set(); + set.add(frozen); + assert.true(set.has(frozen)); +}); + +QUnit.test('Set#clear', assert => { + assert.isFunction(Set.prototype.clear); + let set = new Set(); + set.clear(); + assert.same(set.size, 0); + set = new Set(); + set.add(1); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.clear(); + assert.same(set.size, 0); + assert.false(set.has(1)); + assert.false(set.has(2)); + assert.false(set.has(3)); + const frozen = freeze({}); + set = new Set(); + set.add(1); + set.add(frozen); + set.clear(); + assert.same(set.size, 0, 'Support frozen objects'); + assert.false(set.has(1)); + assert.false(set.has(frozen)); +}); + +QUnit.test('Set#delete', assert => { + assert.isFunction(Set.prototype.delete); + const array = []; + const set = new Set(); + set.add(NaN); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.add(array); + assert.same(set.size, 5); + assert.true(set.delete(NaN)); + assert.same(set.size, 4); + assert.false(set.delete(4)); + assert.same(set.size, 4); + set.delete([]); + assert.same(set.size, 4); + set.delete(array); + assert.same(set.size, 3); + const frozen = freeze({}); + set.add(frozen); + assert.same(set.size, 4); + set.delete(frozen); + assert.same(set.size, 3); +}); + +QUnit.test('Set#forEach', assert => { + assert.isFunction(Set.prototype.forEach); + let result = []; + let count = 0; + let set = new Set(); + set.add(1); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.forEach(value => { + count++; + result.push(value); + }); + assert.same(count, 3); + assert.deepEqual(result, [1, 2, 3]); + set = new Set(); + set.add('0'); + set.add('1'); + set.add('2'); + set.add('3'); + result = ''; + set.forEach(it => { + result += it; + if (it === '2') { + set.delete('2'); + set.delete('3'); + set.delete('1'); + set.add('4'); + } + }); + assert.same(result, '0124'); + set = new Set(); + set.add('0'); + result = ''; + set.forEach(it => { + set.delete('0'); + if (result !== '') throw new Error(); + result += it; + }); + assert.same(result, '0'); + assert.throws(() => { + Set.prototype.forEach.call(new Map(), () => { /* empty */ }); + }, 'non-generic'); +}); + +QUnit.test('Set#has', assert => { + assert.isFunction(Set.prototype.has); + const array = []; + const frozen = freeze({}); + const set = new Set(); + set.add(NaN); + set.add(2); + set.add(3); + set.add(2); + set.add(1); + set.add(frozen); + set.add(array); + assert.true(set.has(NaN)); + assert.true(set.has(array)); + assert.true(set.has(frozen)); + assert.true(set.has(2)); + assert.false(set.has(4)); + assert.false(set.has([])); +}); + +QUnit.test('Set#size', assert => { + const set = new Set(); + set.add(1); + const { size } = set; + assert.same(typeof size, 'number', 'size is number'); + assert.same(size, 1, 'size is correct'); + if (DESCRIPTORS) { + const sizeDescriptor = getOwnPropertyDescriptor(Set.prototype, 'size'); + const getter = sizeDescriptor && sizeDescriptor.get; + const setter = sizeDescriptor && sizeDescriptor.set; + assert.same(typeof getter, 'function', 'size is getter'); + assert.same(typeof setter, 'undefined', 'size is not setter'); + assert.throws(() => { + Set.prototype.size; + }, TypeError); + } +}); + +QUnit.test('Set & -0', assert => { + let set = new Set(); + set.add(-0); + assert.same(set.size, 1); + assert.true(set.has(0)); + assert.true(set.has(-0)); + set.forEach(it => { + assert.false(is(it, -0)); + }); + set.delete(-0); + assert.same(set.size, 0); + set = new Set([-0]); + set.forEach(key => { + assert.false(is(key, -0)); + }); + set = new Set(); + set.add(4); + set.add(3); + set.add(2); + set.add(1); + set.add(0); + assert.true(set.has(-0)); +}); + +QUnit.test('Set#@@toStringTag', assert => { + assert.same(Set.prototype[Symbol.toStringTag], 'Set', 'Set::@@toStringTag is `Set`'); + assert.same(String(new Set()), '[object Set]', 'correct stringification'); +}); + +QUnit.test('Set Iterator', assert => { + const set = new Set(); + set.add('a'); + set.add('b'); + set.add('c'); + set.add('d'); + const results = []; + const iterator = set.keys(); + results.push(iterator.next().value); + assert.true(set.delete('a')); + assert.true(set.delete('b')); + assert.true(set.delete('c')); + set.add('e'); + results.push(iterator.next().value, iterator.next().value); + assert.true(iterator.next().done); + set.add('f'); + assert.true(iterator.next().done); + assert.deepEqual(results, ['a', 'd', 'e']); +}); + +QUnit.test('Set#keys', assert => { + assert.isFunction(Set.prototype.keys); + const set = new Set(); + set.add('q'); + set.add('w'); + set.add('e'); + const iterator = set.keys(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Set Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Set#values', assert => { + assert.isFunction(Set.prototype.values); + const set = new Set(); + set.add('q'); + set.add('w'); + set.add('e'); + const iterator = set.values(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Set Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Set#entries', assert => { + assert.isFunction(Set.prototype.entries); + const set = new Set(); + set.add('q'); + set.add('w'); + set.add('e'); + const iterator = set.entries(); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Set Iterator'); + assert.deepEqual(iterator.next(), { + value: ['q', 'q'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['w', 'w'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: ['e', 'e'], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); + +QUnit.test('Set#@@iterator', assert => { + const set = new Set(); + set.add('q'); + set.add('w'); + set.add('e'); + const iterator = getIterator(set); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Set Iterator'); + assert.same(String(iterator), '[object Set Iterator]'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-pure/es.set.symmetric-difference.js b/tests/unit-pure/es.set.symmetric-difference.js new file mode 100644 index 000000000000..1b3b3c8e5ce4 --- /dev/null +++ b/tests/unit-pure/es.set.symmetric-difference.js @@ -0,0 +1,77 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +import from from 'core-js-pure/es/array/from'; +import defineProperty from 'core-js-pure/es/object/define-property'; +// TODO: use /es/ in core-js@4 +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#symmetricDifference', assert => { + const { symmetricDifference } = Set.prototype; + + assert.isFunction(symmetricDifference); + assert.arity(symmetricDifference, 1); + assert.name(symmetricDifference, 'symmetricDifference'); + assert.nonEnumerable(Set.prototype, 'symmetricDifference'); + + const set = new Set([1]); + assert.notSame(set.symmetricDifference(new Set()), set); + + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(new Set([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(new Set([3, 4]))), [1, 2, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createSetLike([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createSetLike([3, 4]))), [1, 2, 4]); + + // TODO: drop from core-js@4 + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference([4, 5])), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference([3, 4])), [1, 2, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createIterable([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).symmetricDifference(createIterable([3, 4]))), [1, 2, 4]); + + assert.throws(() => new Set([1, 2, 3]).symmetricDifference(), TypeError); + + assert.throws(() => symmetricDifference.call({}, [1, 2, 3]), TypeError); + assert.throws(() => symmetricDifference.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => symmetricDifference.call(null, [1, 2, 3]), TypeError); + + { + // https://github.com/WebKit/WebKit/pull/27264/files#diff-7bdbbad7ceaa222787994f2db702dd45403fa98e14d6270aa65aaf09754dcfe0R8 + const baseSet = new Set(['a', 'b', 'c', 'd', 'e']); + const values = ['f', 'g', 'h', 'i', 'j']; + const setLike = { + size: values.length, + has() { return true; }, + keys() { + let index = 0; + return { + next() { + const done = index >= values.length; + if (!baseSet.has('f')) baseSet.add('f'); + return { done, value: values[index++] }; + }, + }; + }, + }; + assert.deepEqual(from(baseSet.symmetricDifference(setLike)), ['a', 'b', 'c', 'd', 'e', 'g', 'h', 'i', 'j']); + } + + if (DESCRIPTORS) { + // Should get iterator record of a set-like object before cloning this + // https://bugs.webkit.org/show_bug.cgi?id=289430 + const baseSet = new Set(); + const setLike = { + size: 0, + has() { return true; }, + keys() { + return defineProperty({}, 'next', { get() { + baseSet.clear(); + baseSet.add(4); + return function () { + return { done: true }; + }; + } }); + }, + }; + assert.deepEqual(from(baseSet.symmetricDifference(setLike)), [4]); + } +}); diff --git a/tests/unit-pure/es.set.union.js b/tests/unit-pure/es.set.union.js new file mode 100644 index 000000000000..a15deb80b851 --- /dev/null +++ b/tests/unit-pure/es.set.union.js @@ -0,0 +1,55 @@ +import { DESCRIPTORS } from '../helpers/constants.js'; +import { createIterable, createSetLike } from '../helpers/helpers.js'; + +import from from 'core-js-pure/es/array/from'; +import defineProperty from 'core-js-pure/es/object/define-property'; +// TODO: use /es/ in core-js@4 +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#union', assert => { + const { union } = Set.prototype; + + assert.isFunction(union); + assert.arity(union, 1); + assert.name(union, 'union'); + assert.nonEnumerable(Set.prototype, 'union'); + + const set = new Set([1]); + assert.notSame(set.union(new Set()), set); + + assert.deepEqual(from(new Set([1, 2, 3]).union(new Set([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).union(new Set([3, 4]))), [1, 2, 3, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).union(createSetLike([4, 5]))), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).union(createSetLike([3, 4]))), [1, 2, 3, 4]); + + // TODO: drop from core-js@4 + assert.deepEqual(from(new Set([1, 2, 3]).union([4, 5])), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).union([3, 4])), [1, 2, 3, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).union(createIterable([3, 4]))), [1, 2, 3, 4]); + + assert.throws(() => new Set([1, 2, 3]).union(), TypeError); + + assert.throws(() => union.call({}, [1, 2, 3]), TypeError); + assert.throws(() => union.call(undefined, [1, 2, 3]), TypeError); + assert.throws(() => union.call(null, [1, 2, 3]), TypeError); + + if (DESCRIPTORS) { + // Should get iterator record of a set-like object before cloning this + // https://bugs.webkit.org/show_bug.cgi?id=289430 + const baseSet = new Set(); + const setLike = { + size: 0, + has() { return true; }, + keys() { + return defineProperty({}, 'next', { get() { + baseSet.clear(); + baseSet.add(4); + return function () { + return { done: true }; + }; + } }); + }, + }; + assert.deepEqual(from(baseSet.union(setLike)), [4]); + } +}); diff --git a/tests/unit-pure/es.string.anchor.js b/tests/unit-pure/es.string.anchor.js new file mode 100644 index 000000000000..010d02ed4852 --- /dev/null +++ b/tests/unit-pure/es.string.anchor.js @@ -0,0 +1,14 @@ +import anchor from 'core-js-pure/es/string/anchor'; + +QUnit.test('String#anchor', assert => { + assert.isFunction(anchor); + assert.same(anchor('a', 'b'), 'a', 'lower case'); + assert.same(anchor('a', '"'), 'a', 'escape quotes'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('anchor test'); + assert.throws(() => anchor(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => anchor('a', symbol), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-pure/es.string.at-alternative.js b/tests/unit-pure/es.string.at-alternative.js new file mode 100644 index 000000000000..3cde48369907 --- /dev/null +++ b/tests/unit-pure/es.string.at-alternative.js @@ -0,0 +1,32 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import at from 'core-js-pure/es/string/at'; + +QUnit.test('String#at', assert => { + assert.isFunction(at); + assert.same('1', at('123', 0)); + assert.same('2', at('123', 1)); + assert.same('3', at('123', 2)); + assert.same(undefined, at('123', 3)); + assert.same('3', at('123', -1)); + assert.same('2', at('123', -2)); + assert.same('1', at('123', -3)); + assert.same(undefined, at('123', -4)); + assert.same('1', at('123', 0.4)); + assert.same('1', at('123', 0.5)); + assert.same('1', at('123', 0.6)); + assert.same('1', at('1', NaN)); + assert.same('1', at('1')); + assert.same('1', at('123', -0)); + // TODO: disabled by default because of the conflict with old proposal + // assert.same('\uD842', at('𠮷')); + assert.same('1', at({ toString() { return '123'; } }, 0)); + + assert.throws(() => at(Symbol('at-alternative test'), 0), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => at(null, 0), TypeError); + assert.throws(() => at(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.big.js b/tests/unit-pure/es.string.big.js new file mode 100644 index 000000000000..4230806eceaa --- /dev/null +++ b/tests/unit-pure/es.string.big.js @@ -0,0 +1,11 @@ +import big from 'core-js-pure/es/string/big'; + +QUnit.test('String#big', assert => { + assert.isFunction(big); + assert.same(big('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => big(Symbol('big test')), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-pure/es.string.blink.js b/tests/unit-pure/es.string.blink.js new file mode 100644 index 000000000000..9f6cd00a6b90 --- /dev/null +++ b/tests/unit-pure/es.string.blink.js @@ -0,0 +1,11 @@ +import blink from 'core-js-pure/es/string/blink'; + +QUnit.test('String#blink', assert => { + assert.isFunction(blink); + assert.same(blink('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => blink(Symbol('blink test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-pure/es.string.bold.js b/tests/unit-pure/es.string.bold.js new file mode 100644 index 000000000000..582210eabda7 --- /dev/null +++ b/tests/unit-pure/es.string.bold.js @@ -0,0 +1,11 @@ +import bold from 'core-js-pure/es/string/bold'; + +QUnit.test('String#bold', assert => { + assert.isFunction(bold); + assert.same(bold('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => bold(Symbol('bold test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-pure/es.string.code-point-at.js b/tests/unit-pure/es.string.code-point-at.js new file mode 100644 index 000000000000..e6d6098b3f28 --- /dev/null +++ b/tests/unit-pure/es.string.code-point-at.js @@ -0,0 +1,66 @@ +import { STRICT } from '../helpers/constants.js'; + +import codePointAt from 'core-js-pure/es/string/code-point-at'; + +QUnit.test('String#codePointAt', assert => { + assert.isFunction(codePointAt); + assert.same(codePointAt('abc\uD834\uDF06def', ''), 0x61); + assert.same(codePointAt('abc\uD834\uDF06def', '_'), 0x61); + assert.same(codePointAt('abc\uD834\uDF06def'), 0x61); + assert.same(codePointAt('abc\uD834\uDF06def', -Infinity), undefined); + assert.same(codePointAt('abc\uD834\uDF06def', -1), undefined); + assert.same(codePointAt('abc\uD834\uDF06def', -0), 0x61); + assert.same(codePointAt('abc\uD834\uDF06def', 0), 0x61); + assert.same(codePointAt('abc\uD834\uDF06def', 3), 0x1D306); + assert.same(codePointAt('abc\uD834\uDF06def', 4), 0xDF06); + assert.same(codePointAt('abc\uD834\uDF06def', 5), 0x64); + assert.same(codePointAt('abc\uD834\uDF06def', 42), undefined); + assert.same(codePointAt('abc\uD834\uDF06def', Infinity), undefined); + assert.same(codePointAt('abc\uD834\uDF06def', Infinity), undefined); + assert.same(codePointAt('abc\uD834\uDF06def', NaN), 0x61); + assert.same(codePointAt('abc\uD834\uDF06def', false), 0x61); + assert.same(codePointAt('abc\uD834\uDF06def', null), 0x61); + assert.same(codePointAt('abc\uD834\uDF06def', undefined), 0x61); + assert.same(codePointAt('\uD834\uDF06def', ''), 0x1D306); + assert.same(codePointAt('\uD834\uDF06def', '1'), 0xDF06); + assert.same(codePointAt('\uD834\uDF06def', '_'), 0x1D306); + assert.same(codePointAt('\uD834\uDF06def'), 0x1D306); + assert.same(codePointAt('\uD834\uDF06def', -1), undefined); + assert.same(codePointAt('\uD834\uDF06def', -0), 0x1D306); + assert.same(codePointAt('\uD834\uDF06def', 0), 0x1D306); + assert.same(codePointAt('\uD834\uDF06def', 1), 0xDF06); + assert.same(codePointAt('\uD834\uDF06def', 42), undefined); + assert.same(codePointAt('\uD834\uDF06def', false), 0x1D306); + assert.same(codePointAt('\uD834\uDF06def', null), 0x1D306); + assert.same(codePointAt('\uD834\uDF06def', undefined), 0x1D306); + assert.same(codePointAt('\uD834abc', ''), 0xD834); + assert.same(codePointAt('\uD834abc', '_'), 0xD834); + assert.same(codePointAt('\uD834abc'), 0xD834); + assert.same(codePointAt('\uD834abc', -1), undefined); + assert.same(codePointAt('\uD834abc', -0), 0xD834); + assert.same(codePointAt('\uD834abc', 0), 0xD834); + assert.same(codePointAt('\uD834abc', false), 0xD834); + assert.same(codePointAt('\uD834abc', NaN), 0xD834); + assert.same(codePointAt('\uD834abc', null), 0xD834); + assert.same(codePointAt('\uD834abc', undefined), 0xD834); + assert.same(codePointAt('\uDF06abc', ''), 0xDF06); + assert.same(codePointAt('\uDF06abc', '_'), 0xDF06); + assert.same(codePointAt('\uDF06abc'), 0xDF06); + assert.same(codePointAt('\uDF06abc', -1), undefined); + assert.same(codePointAt('\uDF06abc', -0), 0xDF06); + assert.same(codePointAt('\uDF06abc', 0), 0xDF06); + assert.same(codePointAt('\uDF06abc', false), 0xDF06); + assert.same(codePointAt('\uDF06abc', NaN), 0xDF06); + assert.same(codePointAt('\uDF06abc', null), 0xDF06); + assert.same(codePointAt('\uDF06abc', undefined), 0xDF06); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => codePointAt(Symbol('codePointAt test'), 1), 'throws on symbol context'); + } + + if (STRICT) { + assert.throws(() => codePointAt(null, 0), TypeError); + assert.throws(() => codePointAt(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.ends-with.js b/tests/unit-pure/es.string.ends-with.js new file mode 100644 index 000000000000..13140cb88701 --- /dev/null +++ b/tests/unit-pure/es.string.ends-with.js @@ -0,0 +1,40 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import endsWith from 'core-js-pure/es/string/ends-with'; + +QUnit.test('String#endsWith', assert => { + assert.isFunction(endsWith); + assert.true(endsWith('undefined')); + assert.false(endsWith('undefined', null)); + assert.true(endsWith('abc', '')); + assert.true(endsWith('abc', 'c')); + assert.true(endsWith('abc', 'bc')); + assert.false(endsWith('abc', 'ab')); + assert.true(endsWith('abc', '', NaN)); + assert.false(endsWith('abc', 'c', -1)); + assert.true(endsWith('abc', 'a', 1)); + assert.true(endsWith('abc', 'c', Infinity)); + assert.true(endsWith('abc', 'a', true)); + assert.false(endsWith('abc', 'c', 'x')); + assert.false(endsWith('abc', 'a', 'x')); + + if (!Symbol.sham) { + const symbol = Symbol('endsWith test'); + assert.throws(() => endsWith(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => endsWith('a', symbol), 'throws on symbol argument'); + } + + if (STRICT) { + assert.throws(() => endsWith(null, '.'), TypeError); + assert.throws(() => endsWith(undefined, '.'), TypeError); + } + const regexp = /./; + assert.throws(() => endsWith('/./', regexp), TypeError); + regexp[Symbol.match] = false; + assert.notThrows(() => endsWith('/./', regexp)); + const object = {}; + assert.notThrows(() => endsWith('[object Object]', object)); + object[Symbol.match] = true; + assert.throws(() => endsWith('[object Object]', object), TypeError); +}); diff --git a/tests/unit-pure/es.string.fixed.js b/tests/unit-pure/es.string.fixed.js new file mode 100644 index 000000000000..18136900bbd7 --- /dev/null +++ b/tests/unit-pure/es.string.fixed.js @@ -0,0 +1,11 @@ +import fixed from 'core-js-pure/es/string/fixed'; + +QUnit.test('String#fixed', assert => { + assert.isFunction(fixed); + assert.same(fixed('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => fixed(Symbol('fixed test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-pure/es.string.fontcolor.js b/tests/unit-pure/es.string.fontcolor.js new file mode 100644 index 000000000000..5a33d7f6726d --- /dev/null +++ b/tests/unit-pure/es.string.fontcolor.js @@ -0,0 +1,14 @@ +import fontcolor from 'core-js-pure/es/string/fontcolor'; + +QUnit.test('String#fontcolor', assert => { + assert.isFunction(fontcolor); + assert.same(fontcolor('a', 'b'), 'a', 'lower case'); + assert.same(fontcolor('a', '"'), 'a', 'escape quotes'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('fontcolor test'); + assert.throws(() => fontcolor(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => fontcolor('a', symbol), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-pure/es.string.fontsize.js b/tests/unit-pure/es.string.fontsize.js new file mode 100644 index 000000000000..e2716d70ea00 --- /dev/null +++ b/tests/unit-pure/es.string.fontsize.js @@ -0,0 +1,14 @@ +import fontsize from 'core-js-pure/es/string/fontsize'; + +QUnit.test('String#fontsize', assert => { + assert.isFunction(fontsize); + assert.same(fontsize('a', 'b'), 'a', 'lower case'); + assert.same(fontsize('a', '"'), 'a', 'escape quotes'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('fontsize test'); + assert.throws(() => fontsize(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => fontsize('a', symbol), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-pure/es.string.from-code-point.js b/tests/unit-pure/es.string.from-code-point.js new file mode 100644 index 000000000000..1fba98599416 --- /dev/null +++ b/tests/unit-pure/es.string.from-code-point.js @@ -0,0 +1,50 @@ +/* eslint-disable prefer-spread -- required for testing */ +import fromCodePoint from 'core-js-pure/es/string/from-code-point'; + +QUnit.test('String.fromCodePoint', assert => { + assert.isFunction(fromCodePoint); + assert.arity(fromCodePoint, 1); + if ('name' in fromCodePoint) { + assert.name(fromCodePoint, 'fromCodePoint'); + } + assert.same(fromCodePoint(''), '\0'); + assert.same(fromCodePoint(), ''); + assert.same(fromCodePoint(-0), '\0'); + assert.same(fromCodePoint(0), '\0'); + assert.same(fromCodePoint(0x1D306), '\uD834\uDF06'); + assert.same(fromCodePoint(0x1D306, 0x61, 0x1D307), '\uD834\uDF06a\uD834\uDF07'); + assert.same(fromCodePoint(0x61, 0x62, 0x1D307), 'ab\uD834\uDF07'); + assert.same(fromCodePoint(false), '\0'); + assert.same(fromCodePoint(null), '\0'); + assert.throws(() => fromCodePoint('_'), RangeError); + assert.throws(() => fromCodePoint('+Infinity'), RangeError); + assert.throws(() => fromCodePoint('-Infinity'), RangeError); + assert.throws(() => fromCodePoint(-1), RangeError); + assert.throws(() => fromCodePoint(0x10FFFF + 1), RangeError); + assert.throws(() => fromCodePoint(3.14), RangeError); + assert.throws(() => fromCodePoint(3e-2), RangeError); + assert.throws(() => fromCodePoint(-Infinity), RangeError); + assert.throws(() => fromCodePoint(Infinity), RangeError); + assert.throws(() => fromCodePoint(NaN), RangeError); + assert.throws(() => fromCodePoint(undefined), RangeError); + assert.throws(() => fromCodePoint({}), RangeError); + assert.throws(() => fromCodePoint(/./), RangeError); + let number = 0x60; + assert.same(fromCodePoint({ + valueOf() { + return ++number; + }, + }), 'a'); + assert.same(number, 0x61); + // one code unit per symbol + let counter = 2 ** 15 * 3 / 2; + let result = []; + while (--counter >= 0) result.push(0); + // should not throw + fromCodePoint.apply(null, result); + counter = 2 ** 15 * 3 / 2; + result = []; + while (--counter >= 0) result.push(0xFFFF + 1); + // should not throw + fromCodePoint.apply(null, result); +}); diff --git a/tests/unit-pure/es.string.includes.js b/tests/unit-pure/es.string.includes.js new file mode 100644 index 000000000000..e2a55bb51d98 --- /dev/null +++ b/tests/unit-pure/es.string.includes.js @@ -0,0 +1,32 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import includes from 'core-js-pure/es/string/includes'; + +QUnit.test('String#includes', assert => { + assert.isFunction(includes); + assert.false(includes('abc')); + assert.true(includes('aundefinedb')); + assert.true(includes('abcd', 'b', 1)); + assert.false(includes('abcd', 'b', 2)); + + if (!Symbol.sham) { + const symbol = Symbol('includes test'); + assert.throws(() => includes(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => includes('a', symbol), 'throws on symbol argument'); + } + + if (STRICT) { + assert.throws(() => includes(null, '.'), TypeError); + assert.throws(() => includes(undefined, '.'), TypeError); + } + + const re = /./; + assert.throws(() => includes('/./', re), TypeError); + re[Symbol.match] = false; + assert.notThrows(() => includes('/./', re)); + const O = {}; + assert.notThrows(() => includes('[object Object]', O)); + O[Symbol.match] = true; + assert.throws(() => includes('[object Object]', O), TypeError); +}); diff --git a/tests/unit-pure/es.string.is-well-formed.js b/tests/unit-pure/es.string.is-well-formed.js new file mode 100644 index 000000000000..1e1694c02a7f --- /dev/null +++ b/tests/unit-pure/es.string.is-well-formed.js @@ -0,0 +1,41 @@ +import { STRICT } from '../helpers/constants.js'; +import Symbol from 'core-js-pure/es/symbol'; +import isWellFormed from 'core-js-pure/es/string/virtual/is-well-formed'; + +QUnit.test('String#isWellFormed', assert => { + assert.isFunction(isWellFormed); + + assert.true(isWellFormed.call('a'), 'a'); + assert.true(isWellFormed.call('abc'), 'abc'); + assert.true(isWellFormed.call('💩'), '💩'); + assert.true(isWellFormed.call('💩b'), '💩b'); + assert.true(isWellFormed.call('a💩'), '💩'); + assert.true(isWellFormed.call('a💩b'), 'a💩b'); + assert.true(isWellFormed.call('💩a💩'), '💩a💩'); + assert.true(!isWellFormed.call('\uD83D'), '\uD83D'); + assert.true(!isWellFormed.call('\uDCA9'), '\uDCA9'); + assert.true(!isWellFormed.call('\uDCA9\uD83D'), '\uDCA9\uD83D'); + assert.true(!isWellFormed.call('a\uD83D'), 'a\uD83D'); + assert.true(!isWellFormed.call('\uDCA9a'), '\uDCA9a'); + assert.true(!isWellFormed.call('a\uD83Da'), 'a\uD83Da'); + assert.true(!isWellFormed.call('a\uDCA9a'), 'a\uDCA9a'); + + assert.true(isWellFormed.call({ + toString() { + return 'abc'; + }, + }), 'conversion #1'); + + assert.true(!isWellFormed.call({ + toString() { + return '\uD83D'; + }, + }), 'conversion #2'); + + if (STRICT) { + assert.throws(() => isWellFormed.call(null), TypeError, 'coercible #1'); + assert.throws(() => isWellFormed.call(undefined), TypeError, 'coercible #2'); + } + + assert.throws(() => isWellFormed.call(Symbol('isWellFormed test')), 'throws on symbol context'); +}); diff --git a/tests/unit-pure/es.string.italics.js b/tests/unit-pure/es.string.italics.js new file mode 100644 index 000000000000..de2efc99e726 --- /dev/null +++ b/tests/unit-pure/es.string.italics.js @@ -0,0 +1,11 @@ +import italics from 'core-js-pure/es/string/italics'; + +QUnit.test('String#italics', assert => { + assert.isFunction(italics); + assert.same(italics('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => italics(Symbol('italics test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-pure/es.string.iterator.js b/tests/unit-pure/es.string.iterator.js new file mode 100644 index 000000000000..0a294bf29250 --- /dev/null +++ b/tests/unit-pure/es.string.iterator.js @@ -0,0 +1,48 @@ +import getIterator from 'core-js-pure/es/get-iterator'; +// import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import Symbol from 'core-js-pure/es/symbol'; +import from from 'core-js-pure/es/array/from'; + +QUnit.test('String#@@iterator', assert => { + let iterator = getIterator('qwe'); + assert.isIterator(iterator); + assert.same(iterator[Symbol.toStringTag], 'String Iterator'); + assert.same(String(iterator), '[object String Iterator]'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'w', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + assert.same(from('𠮷𠮷𠮷').length, 3); + iterator = getIterator('𠮷𠮷𠮷'); + assert.deepEqual(iterator.next(), { + value: '𠮷', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: '𠮷', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: '𠮷', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + // early FF case with native method, but polyfilled `Symbol` + // assert.throws(() => getIteratorMethod('').call(Symbol()), 'throws on symbol context'); +}); diff --git a/tests/unit-pure/es.string.link.js b/tests/unit-pure/es.string.link.js new file mode 100644 index 000000000000..58a353777882 --- /dev/null +++ b/tests/unit-pure/es.string.link.js @@ -0,0 +1,14 @@ +import link from 'core-js-pure/es/string/link'; + +QUnit.test('String#link', assert => { + assert.isFunction(link); + assert.same(link('a', 'b'), 'a', 'lower case'); + assert.same(link('a', '"'), 'a', 'escape quotes'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('link test'); + assert.throws(() => link(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => link('a', symbol), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-pure/es.string.match-all.js b/tests/unit-pure/es.string.match-all.js new file mode 100644 index 000000000000..78cfee50e440 --- /dev/null +++ b/tests/unit-pure/es.string.match-all.js @@ -0,0 +1,135 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import assign from 'core-js-pure/es/object/assign'; +import matchAll from 'core-js-pure/es/string/match-all'; + +QUnit.test('String#matchAll', assert => { + assert.isFunction(matchAll); + let data = ['aabc', { toString() { + return 'aabc'; + } }]; + for (const target of data) { + const iterator = matchAll(target, /[ac]/g); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: assign(['a'], { + input: 'aabc', + index: 0, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['a'], { + input: 'aabc', + index: 1, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['c'], { + input: 'aabc', + index: 3, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + } + let iterator = matchAll('1111a2b3cccc', /(\d)(\D)/g); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'RegExp String Iterator'); + assert.same(String(iterator), '[object RegExp String Iterator]'); + assert.deepEqual(iterator.next(), { + value: assign(['1a', '1', 'a'], { + input: '1111a2b3cccc', + index: 3, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['2b', '2', 'b'], { + input: '1111a2b3cccc', + index: 5, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['3c', '3', 'c'], { + input: '1111a2b3cccc', + index: 7, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + assert.throws(() => matchAll('1111a2b3cccc', /(\d)(\D)/), TypeError); + iterator = matchAll('1111a2b3cccc', '(\\d)(\\D)'); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: assign(['1a', '1', 'a'], { + input: '1111a2b3cccc', + index: 3, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['2b', '2', 'b'], { + input: '1111a2b3cccc', + index: 5, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign(['3c', '3', 'c'], { + input: '1111a2b3cccc', + index: 7, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + /* IE8- issue + iterator = matchAll('abc', /\B/g); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: assign([''], { + input: 'abc', + index: 1, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: assign([''], { + input: 'abc', + index: 2, + }), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + */ + data = [null, undefined, NaN, 42, {}, []]; + for (const target of data) { + assert.notThrows(() => matchAll('', target), `Not throws on ${ target } as the first argument`); + } + + assert.throws(() => matchAll(Symbol('matchAll test'), /./), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => matchAll(null, /./g), TypeError, 'Throws on null as `this`'); + assert.throws(() => matchAll(undefined, /./g), TypeError, 'Throws on undefined as `this`'); + } +}); diff --git a/tests/unit-pure/es.string.pad-end.js b/tests/unit-pure/es.string.pad-end.js new file mode 100644 index 000000000000..9cfbc9e444cc --- /dev/null +++ b/tests/unit-pure/es.string.pad-end.js @@ -0,0 +1,24 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import padEnd from 'core-js-pure/es/string/pad-end'; + +QUnit.test('String#padEnd', assert => { + assert.isFunction(padEnd); + assert.same(padEnd('abc', 5), 'abc '); + assert.same(padEnd('abc', 4, 'de'), 'abcd'); + assert.same(padEnd('abc'), 'abc'); + assert.same(padEnd('abc', 5, '_'), 'abc__'); + assert.same(padEnd('', 0), ''); + assert.same(padEnd('foo', 1), 'foo'); + assert.same(padEnd('foo', 5, ''), 'foo'); + + const symbol = Symbol('padEnd test'); + assert.throws(() => padEnd(symbol, 10, 'a'), 'throws on symbol context'); + assert.throws(() => padEnd('a', 10, symbol), 'throws on symbol argument'); + + if (STRICT) { + assert.throws(() => padEnd(null, 0), TypeError); + assert.throws(() => padEnd(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.pad-start.js b/tests/unit-pure/es.string.pad-start.js new file mode 100644 index 000000000000..073d05ed6d71 --- /dev/null +++ b/tests/unit-pure/es.string.pad-start.js @@ -0,0 +1,24 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import padStart from 'core-js-pure/es/string/pad-start'; + +QUnit.test('String#padStart', assert => { + assert.isFunction(padStart); + assert.same(padStart('abc', 5), ' abc'); + assert.same(padStart('abc', 4, 'de'), 'dabc'); + assert.same(padStart('abc'), 'abc'); + assert.same(padStart('abc', 5, '_'), '__abc'); + assert.same(padStart('', 0), ''); + assert.same(padStart('foo', 1), 'foo'); + assert.same(padStart('foo', 5, ''), 'foo'); + + const symbol = Symbol('padEnd test'); + assert.throws(() => padStart(symbol, 10, 'a'), 'throws on symbol context'); + assert.throws(() => padStart('a', 10, symbol), 'throws on symbol argument'); + + if (STRICT) { + assert.throws(() => padStart(null, 0), TypeError); + assert.throws(() => padStart(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.raw.js b/tests/unit-pure/es.string.raw.js new file mode 100644 index 000000000000..181c75e0a3d3 --- /dev/null +++ b/tests/unit-pure/es.string.raw.js @@ -0,0 +1,23 @@ +import raw from 'core-js-pure/es/string/raw'; + +QUnit.test('String.raw', assert => { + assert.isFunction(raw); + assert.arity(raw, 1); + if ('name' in raw) { + assert.name(raw, 'raw'); + } + assert.same(raw({ raw: ['Hi\\n', '!'] }, 'Bob'), 'Hi\\nBob!', 'raw is array'); + assert.same(raw({ raw: 'test' }, 0, 1, 2), 't0e1s2t', 'raw is string'); + assert.same(raw({ raw: 'test' }, 0), 't0est', 'lacks substituting'); + assert.same(raw({ raw: [] }), '', 'empty template'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + const symbol = Symbol('raw test'); + assert.throws(() => raw({ raw: [symbol] }, 0), TypeError, 'throws on symbol #1'); + assert.throws(() => raw({ raw: 'test' }, symbol), TypeError, 'throws on symbol #2'); + } + + assert.throws(() => raw({}), TypeError); + assert.throws(() => raw({ raw: null }), TypeError); +}); diff --git a/tests/unit-pure/es.string.repeat.js b/tests/unit-pure/es.string.repeat.js new file mode 100644 index 000000000000..8e42b7108f32 --- /dev/null +++ b/tests/unit-pure/es.string.repeat.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; + +import repeat from 'core-js-pure/es/string/repeat'; + +QUnit.test('String#repeat', assert => { + assert.isFunction(repeat); + assert.same(repeat('qwe', 3), 'qweqweqwe'); + assert.same(repeat('qwe', 2.5), 'qweqwe'); + assert.throws(() => repeat('qwe', -1), RangeError); + assert.throws(() => repeat('qwe', Infinity), RangeError); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => repeat(Symbol('repeat test')), 'throws on symbol context'); + } + + if (STRICT) { + assert.throws(() => repeat(null, 1), TypeError); + assert.throws(() => repeat(undefined, 1), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.replace-all.js b/tests/unit-pure/es.string.replace-all.js new file mode 100644 index 000000000000..819e184a1948 --- /dev/null +++ b/tests/unit-pure/es.string.replace-all.js @@ -0,0 +1,48 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import replaceAll from 'core-js-pure/es/string/replace-all'; + +QUnit.test('String#replaceAll', assert => { + assert.isFunction(replaceAll); + assert.same(replaceAll('q=query+string+parameters', '+', ' '), 'q=query string parameters'); + assert.same(replaceAll('foo', 'o', {}), 'f[object Object][object Object]'); + assert.same(replaceAll('[object Object]x[object Object]', {}, 'y'), 'yxy'); + assert.same(replaceAll({}, 'bject', 'lolo'), '[ololo Ololo]'); + assert.same(replaceAll('aba', 'b', (search, i, string) => { + assert.same(search, 'b', '`search` is `b`'); + assert.same(i, 1, '`i` is 1'); + assert.same(string, 'aba', '`string` is `aba`'); + return 'c'; + }), 'aca'); + const searcher = { + [Symbol.replace](O, replaceValue) { + assert.same(this, searcher, '`this` is `searcher`'); + assert.same(String(O), 'aba', '`O` is `aba`'); + assert.same(String(replaceValue), 'c', '`replaceValue` is `c`'); + return 'foo'; + }, + }; + assert.same(replaceAll('aba', searcher, 'c'), 'foo'); + assert.same(replaceAll('aba', 'b'), 'aundefineda'); + assert.same(replaceAll('xxx', '', '_'), '_x_x_x_'); + assert.same(replaceAll('121314', '1', '$$'), '$2$3$4', '$$'); + assert.same(replaceAll('121314', '1', '$&'), '121314', '$&'); + assert.same(replaceAll('121314', '1', '$`'), '212312134', '$`'); + assert.same(replaceAll('121314', '1', "$'"), '213142314344', "$'"); + + const symbol = Symbol('replaceAll test'); + assert.throws(() => replaceAll(symbol, 'a', 'b'), 'throws on symbol context'); + assert.throws(() => replaceAll('a', symbol, 'b'), 'throws on symbol argument 1'); + assert.throws(() => replaceAll('a', 'b', symbol), 'throws on symbol argument 2'); + + if (STRICT) { + assert.throws(() => replaceAll(null, 'a', 'b'), TypeError); + assert.throws(() => replaceAll(undefined, 'a', 'b'), TypeError); + } + + assert.throws(() => replaceAll('b.b.b.b.b', /\./, 'a'), TypeError); + assert.same(replaceAll('b.b.b.b.b', /\./g, 'a'), 'babababab'); + const object = {}; + assert.same(replaceAll('[object Object]', object, 'a'), 'a'); +}); diff --git a/tests/unit-pure/es.string.small.js b/tests/unit-pure/es.string.small.js new file mode 100644 index 000000000000..a4326d3b281e --- /dev/null +++ b/tests/unit-pure/es.string.small.js @@ -0,0 +1,11 @@ +import small from 'core-js-pure/es/string/small'; + +QUnit.test('String#small', assert => { + assert.isFunction(small); + assert.same(small('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => small(Symbol('small test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-pure/es.string.starts-with.js b/tests/unit-pure/es.string.starts-with.js new file mode 100644 index 000000000000..2e9a579f0bf4 --- /dev/null +++ b/tests/unit-pure/es.string.starts-with.js @@ -0,0 +1,40 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import startsWith from 'core-js-pure/es/string/starts-with'; + +QUnit.test('String#startsWith', assert => { + assert.isFunction(startsWith); + assert.true(startsWith('undefined')); + assert.false(startsWith('undefined', null)); + assert.true(startsWith('abc', '')); + assert.true(startsWith('abc', 'a')); + assert.true(startsWith('abc', 'ab')); + assert.false(startsWith('abc', 'bc')); + assert.true(startsWith('abc', '', NaN)); + assert.true(startsWith('abc', 'a', -1)); + assert.false(startsWith('abc', 'a', 1)); + assert.false(startsWith('abc', 'a', Infinity)); + assert.true(startsWith('abc', 'b', true)); + assert.true(startsWith('abc', 'a', 'x')); + + if (!Symbol.sham) { + const symbol = Symbol('startsWith test'); + assert.throws(() => startsWith(symbol, 'b'), 'throws on symbol context'); + assert.throws(() => startsWith('a', symbol), 'throws on symbol argument'); + } + + if (STRICT) { + assert.throws(() => startsWith(null, '.'), TypeError); + assert.throws(() => startsWith(undefined, '.'), TypeError); + } + + const regexp = /./; + assert.throws(() => startsWith('/./', regexp), TypeError); + regexp[Symbol.match] = false; + assert.notThrows(() => startsWith('/./', regexp)); + const object = {}; + assert.notThrows(() => startsWith('[object Object]', object)); + object[Symbol.match] = true; + assert.throws(() => startsWith('[object Object]', object), TypeError); +}); diff --git a/tests/unit-pure/es.string.strike.js b/tests/unit-pure/es.string.strike.js new file mode 100644 index 000000000000..0c6aab235d69 --- /dev/null +++ b/tests/unit-pure/es.string.strike.js @@ -0,0 +1,11 @@ +import strike from 'core-js-pure/es/string/strike'; + +QUnit.test('String#strike', assert => { + assert.isFunction(strike); + assert.same(strike('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => strike(Symbol('strike test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-pure/es.string.sub.js b/tests/unit-pure/es.string.sub.js new file mode 100644 index 000000000000..3cf8f5194501 --- /dev/null +++ b/tests/unit-pure/es.string.sub.js @@ -0,0 +1,11 @@ +import sub from 'core-js-pure/es/string/sub'; + +QUnit.test('String#sub', assert => { + assert.isFunction(sub); + assert.same(sub('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => sub(Symbol('sub test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-pure/es.string.substr.js b/tests/unit-pure/es.string.substr.js new file mode 100644 index 000000000000..d7a3912136da --- /dev/null +++ b/tests/unit-pure/es.string.substr.js @@ -0,0 +1,20 @@ +import substr from 'core-js-pure/es/string/substr'; +import { STRICT } from '../helpers/constants.js'; + +QUnit.test('String#substr', assert => { + assert.isFunction(substr); + + assert.same(substr('12345', 1, 3), '234'); + + assert.same(substr('ab', -1), 'b'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => substr(Symbol('substr test'), 1, 3), 'throws on symbol context'); + } + + if (STRICT) { + assert.throws(() => substr(null, 1, 3), TypeError, 'Throws on null as `this`'); + assert.throws(() => substr(undefined, 1, 3), TypeError, 'Throws on undefined as `this`'); + } +}); diff --git a/tests/unit-pure/es.string.sup.js b/tests/unit-pure/es.string.sup.js new file mode 100644 index 000000000000..8c81206accdc --- /dev/null +++ b/tests/unit-pure/es.string.sup.js @@ -0,0 +1,11 @@ +import sup from 'core-js-pure/es/string/sup'; + +QUnit.test('String#sup', assert => { + assert.isFunction(sup); + assert.same(sup('a'), 'a', 'lower case'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => sup(Symbol('sup test')), 'throws on symbol context'); + } +}); diff --git a/tests/unit-pure/es.string.to-well-formed.js b/tests/unit-pure/es.string.to-well-formed.js new file mode 100644 index 000000000000..144ac558a86f --- /dev/null +++ b/tests/unit-pure/es.string.to-well-formed.js @@ -0,0 +1,37 @@ +import { STRICT } from '../helpers/constants.js'; +import Symbol from 'core-js-pure/es/symbol'; +import toWellFormed from 'core-js-pure/es/string/virtual/to-well-formed'; + +QUnit.test('String#toWellFormed', assert => { + assert.isFunction(toWellFormed); + + assert.same(toWellFormed.call('a'), 'a', 'a'); + assert.same(toWellFormed.call('abc'), 'abc', 'abc'); + assert.same(toWellFormed.call('💩'), '💩', '💩'); + assert.same(toWellFormed.call('💩b'), '💩b', '💩b'); + assert.same(toWellFormed.call('a💩'), 'a💩', '💩'); + assert.same(toWellFormed.call('a💩b'), 'a💩b', 'a💩b'); + assert.same(toWellFormed.call('💩a💩'), '💩a💩'); + assert.same(toWellFormed.call('\uD83D'), '\uFFFD', '\uD83D'); + assert.same(toWellFormed.call('\uDCA9'), '\uFFFD', '\uDCA9'); + assert.same(toWellFormed.call('\uDCA9\uD83D'), '\uFFFD\uFFFD', '\uDCA9\uD83D'); + assert.same(toWellFormed.call('a\uD83D'), 'a\uFFFD', 'a\uFFFD'); + assert.same(toWellFormed.call('\uDCA9a'), '\uFFFDa', '\uDCA9a'); + assert.same(toWellFormed.call('a\uD83Da'), 'a\uFFFDa', 'a\uD83Da'); + assert.same(toWellFormed.call('a\uDCA9a'), 'a\uFFFDa', 'a\uDCA9a'); + + assert.same(toWellFormed.call({ + toString() { + return 'abc'; + }, + }), 'abc', 'conversion #1'); + + assert.same(toWellFormed.call(1), '1', 'conversion #2'); + + if (STRICT) { + assert.throws(() => toWellFormed.call(null), TypeError, 'coercible #1'); + assert.throws(() => toWellFormed.call(undefined), TypeError, 'coercible #2'); + } + + assert.throws(() => toWellFormed.call(Symbol('toWellFormed test')), 'throws on symbol context'); +}); diff --git a/tests/unit-pure/es.string.trim-end.js b/tests/unit-pure/es.string.trim-end.js new file mode 100644 index 000000000000..2a4e4acc768f --- /dev/null +++ b/tests/unit-pure/es.string.trim-end.js @@ -0,0 +1,18 @@ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import trimEnd from 'core-js-pure/es/string/trim-end'; + +QUnit.test('String#trimEnd', assert => { + assert.isFunction(trimEnd); + assert.same(trimEnd(' \n q w e \n '), ' \n q w e', 'removes whitespaces at right side of string'); + assert.same(trimEnd(WHITESPACES), '', 'removes all whitespaces'); + assert.same(trimEnd('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); + + assert.throws(() => trimEnd(Symbol('trimEnd test')), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => trimEnd(null, 0), TypeError); + assert.throws(() => trimEnd(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.trim-left.js b/tests/unit-pure/es.string.trim-left.js new file mode 100644 index 000000000000..66cbc4e98c7f --- /dev/null +++ b/tests/unit-pure/es.string.trim-left.js @@ -0,0 +1,18 @@ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import trimLeft from 'core-js-pure/es/string/trim-left'; + +QUnit.test('String#trimLeft', assert => { + assert.isFunction(trimLeft); + assert.same(trimLeft(' \n q w e \n '), 'q w e \n ', 'removes whitespaces at left side of string'); + assert.same(trimLeft(WHITESPACES), '', 'removes all whitespaces'); + assert.same(trimLeft('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); + + assert.throws(() => trimLeft(Symbol('trimLeft test')), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => trimLeft(null, 0), TypeError); + assert.throws(() => trimLeft(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.trim-right.js b/tests/unit-pure/es.string.trim-right.js new file mode 100644 index 000000000000..0841c1307a1a --- /dev/null +++ b/tests/unit-pure/es.string.trim-right.js @@ -0,0 +1,18 @@ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import trimRight from 'core-js-pure/es/string/trim-right'; + +QUnit.test('String#trimRight', assert => { + assert.isFunction(trimRight); + assert.same(trimRight(' \n q w e \n '), ' \n q w e', 'removes whitespaces at right side of string'); + assert.same(trimRight(WHITESPACES), '', 'removes all whitespaces'); + assert.same(trimRight('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); + + assert.throws(() => trimRight(Symbol('trimRight test')), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => trimRight(null, 0), TypeError); + assert.throws(() => trimRight(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.trim-start.js b/tests/unit-pure/es.string.trim-start.js new file mode 100644 index 000000000000..9fb45a00300c --- /dev/null +++ b/tests/unit-pure/es.string.trim-start.js @@ -0,0 +1,18 @@ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import trimStart from 'core-js-pure/es/string/trim-start'; + +QUnit.test('String#trimStart', assert => { + assert.isFunction(trimStart); + assert.same(trimStart(' \n q w e \n '), 'q w e \n ', 'removes whitespaces at left side of string'); + assert.same(trimStart(WHITESPACES), '', 'removes all whitespaces'); + assert.same(trimStart('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); + + assert.throws(() => trimStart(Symbol('trimStart test')), 'throws on symbol context'); + + if (STRICT) { + assert.throws(() => trimStart(null, 0), TypeError); + assert.throws(() => trimStart(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.string.trim.js b/tests/unit-pure/es.string.trim.js new file mode 100644 index 000000000000..9266fa4e5bf0 --- /dev/null +++ b/tests/unit-pure/es.string.trim.js @@ -0,0 +1,20 @@ +import { STRICT, WHITESPACES } from '../helpers/constants.js'; + +import trim from 'core-js-pure/es/string/trim'; + +QUnit.test('String#trim', assert => { + assert.isFunction(trim); + assert.same(trim(' \n q w e \n '), 'q w e', 'removes whitespaces at left & right side of string'); + assert.same(trim(WHITESPACES), '', 'removes all whitespaces'); + assert.same(trim('\u200B\u0085'), '\u200B\u0085', "shouldn't remove this symbols"); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => trim(Symbol('trim test')), 'throws on symbol context'); + } + + if (STRICT) { + assert.throws(() => trim(null, 0), TypeError); + assert.throws(() => trim(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/es.suppressed-error.constructor.js b/tests/unit-pure/es.suppressed-error.constructor.js new file mode 100644 index 000000000000..2cd423c77c60 --- /dev/null +++ b/tests/unit-pure/es.suppressed-error.constructor.js @@ -0,0 +1,48 @@ +/* eslint-disable unicorn/throw-new-error, sonarjs/inconsistent-function-call -- testing */ +import SuppressedError from 'core-js-pure/es/suppressed-error'; +import Symbol from 'core-js-pure/es/symbol'; +import toString from 'core-js-pure/es/object/to-string'; + +QUnit.test('SuppressedError', assert => { + assert.isFunction(SuppressedError); + assert.arity(SuppressedError, 3); + assert.name(SuppressedError, 'SuppressedError'); + assert.true(new SuppressedError() instanceof SuppressedError); + assert.true(new SuppressedError() instanceof Error); + assert.true(SuppressedError() instanceof SuppressedError); + assert.true(SuppressedError() instanceof Error); + + assert.same(SuppressedError().error, undefined); + assert.same(SuppressedError().suppressed, undefined); + assert.same(SuppressedError().message, ''); + assert.same(SuppressedError().cause, undefined); + assert.same(SuppressedError().name, 'SuppressedError'); + + assert.same(new SuppressedError().error, undefined); + assert.same(new SuppressedError().suppressed, undefined); + assert.same(new SuppressedError().message, ''); + assert.same(new SuppressedError().cause, undefined); + assert.same(new SuppressedError().name, 'SuppressedError'); + + const error1 = SuppressedError(1, 2, 3, { cause: 4 }); + + assert.same(error1.error, 1); + assert.same(error1.suppressed, 2); + assert.same(error1.message, '3'); + assert.same(error1.cause, undefined); + assert.same(error1.name, 'SuppressedError'); + + const error2 = new SuppressedError(1, 2, 3, { cause: 4 }); + + assert.same(error2.error, 1); + assert.same(error2.suppressed, 2); + assert.same(error2.message, '3'); + assert.same(error2.cause, undefined); + assert.same(error2.name, 'SuppressedError'); + + assert.throws(() => SuppressedError(1, 2, Symbol('SuppressedError constructor test')), 'throws on symbol as a message'); + assert.same(toString(SuppressedError()), '[object Error]', 'Object#toString'); + + // eslint-disable-next-line no-prototype-builtins -- safe + assert.false(SuppressedError.prototype.hasOwnProperty('cause'), 'prototype has not cause'); +}); diff --git a/tests/unit-pure/es.symbol.async-dispose.js b/tests/unit-pure/es.symbol.async-dispose.js new file mode 100644 index 000000000000..ebb1afa77411 --- /dev/null +++ b/tests/unit-pure/es.symbol.async-dispose.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Symbol.asyncDispose', assert => { + assert.true('asyncDispose' in Symbol, 'Symbol.asyncDispose available'); + assert.true(Object(Symbol.asyncDispose) instanceof Symbol, 'Symbol.asyncDispose is symbol'); +}); diff --git a/tests/unit-pure/es.symbol.async-iterator.js b/tests/unit-pure/es.symbol.async-iterator.js new file mode 100644 index 000000000000..910c0d093f7e --- /dev/null +++ b/tests/unit-pure/es.symbol.async-iterator.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Symbol.asyncIterator', assert => { + assert.true('asyncIterator' in Symbol, 'Symbol.asyncIterator available'); + assert.true(Object(Symbol.asyncIterator) instanceof Symbol, 'Symbol.asyncIterator is symbol'); +}); diff --git a/tests/unit-pure/es.symbol.constructor.js b/tests/unit-pure/es.symbol.constructor.js new file mode 100644 index 000000000000..5db2ef5d77a0 --- /dev/null +++ b/tests/unit-pure/es.symbol.constructor.js @@ -0,0 +1,239 @@ +import { DESCRIPTORS, GLOBAL } from '../helpers/constants.js'; + +import create from 'core-js-pure/es/object/create'; +import defineProperty from 'core-js-pure/es/object/define-property'; +import defineProperties from 'core-js-pure/es/object/define-properties'; +import getOwnPropertyDescriptor from 'core-js-pure/es/object/get-own-property-descriptor'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import keys from 'core-js-pure/es/object/keys'; +import ownKeys from 'core-js-pure/es/reflect/own-keys'; +import Map from 'core-js-pure/es/map'; +import Set from 'core-js-pure/es/set'; +import Promise from 'core-js-pure/es/promise'; +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Symbol', assert => { + assert.isFunction(Symbol); + const symbol1 = Symbol('symbol'); + const symbol2 = Symbol('symbol'); + assert.notSame(symbol1, symbol2, 'Symbol("symbol") !== Symbol("symbol")'); + const object = {}; + object[symbol1] = 42; + assert.same(object[symbol1], 42, 'Symbol() work as key'); + assert.notSame(object[symbol2], 42, 'Various symbols from one description are various keys'); + // assert.throws(() => Symbol(Symbol('foo')), 'throws on symbol argument'); + if (DESCRIPTORS) { + let count = 0; + // eslint-disable-next-line no-unused-vars -- required for testing + for (const key in object) count++; + assert.same(count, 0, 'object[Symbol()] is not enumerable'); + } +}); + +QUnit.test('Symbol as global key', assert => { + const TEXT = 'test global symbol key'; + const symbol = Symbol(TEXT); + GLOBAL[symbol] = TEXT; + assert.same(GLOBAL[symbol], TEXT, TEXT); +}); + +QUnit.test('Well-known Symbols', assert => { + const wks = [ + 'hasInstance', + 'isConcatSpreadable', + 'iterator', + 'match', + 'matchAll', + 'replace', + 'search', + 'species', + 'split', + 'toPrimitive', + 'toStringTag', + 'unscopables', + ]; + for (const name of wks) { + assert.true(name in Symbol, `Symbol.${ name } available`); + assert.true(Object(Symbol[name]) instanceof Symbol, `Symbol.${ name } is symbol`); + } +}); + +QUnit.test('Symbol#@@toPrimitive', assert => { + const symbol = Symbol('Symbol#@@toPrimitive test'); + assert.isFunction(Symbol.prototype[Symbol.toPrimitive]); + assert.same(symbol, symbol[Symbol.toPrimitive](), 'works'); +}); + +QUnit.test('Symbol#@@toStringTag', assert => { + assert.same(Symbol.prototype[Symbol.toStringTag], 'Symbol', 'Symbol::@@toStringTag is `Symbol`'); +}); + +if (DESCRIPTORS) { + QUnit.test('Symbols & descriptors', assert => { + const d = Symbol('d'); + const e = Symbol('e'); + const f = Symbol('f'); + const i = Symbol('i'); + const j = Symbol('j'); + const prototype = { g: 'g' }; + prototype[i] = 'i'; + defineProperty(prototype, 'h', { + value: 'h', + }); + defineProperty(prototype, 'j', { + value: 'j', + }); + const object = create(prototype); + object.a = 'a'; + object[d] = 'd'; + defineProperty(object, 'b', { + value: 'b', + }); + defineProperty(object, 'c', { + value: 'c', + enumerable: true, + }); + defineProperty(object, e, { + configurable: true, + writable: true, + value: 'e', + }); + const descriptor = { + value: 'f', + enumerable: true, + }; + defineProperty(object, f, descriptor); + assert.true(descriptor.enumerable, 'defineProperty not changes descriptor object'); + assert.deepEqual(getOwnPropertyDescriptor(object, 'a'), { + configurable: true, + writable: true, + enumerable: true, + value: 'a', + }, 'getOwnPropertyDescriptor a'); + assert.deepEqual(getOwnPropertyDescriptor(object, 'b'), { + configurable: false, + writable: false, + enumerable: false, + value: 'b', + }, 'getOwnPropertyDescriptor b'); + assert.deepEqual(getOwnPropertyDescriptor(object, 'c'), { + configurable: false, + writable: false, + enumerable: true, + value: 'c', + }, 'getOwnPropertyDescriptor c'); + assert.deepEqual(getOwnPropertyDescriptor(object, d), { + configurable: true, + writable: true, + enumerable: true, + value: 'd', + }, 'getOwnPropertyDescriptor d'); + assert.deepEqual(getOwnPropertyDescriptor(object, e), { + configurable: true, + writable: true, + enumerable: false, + value: 'e', + }, 'getOwnPropertyDescriptor e'); + assert.deepEqual(getOwnPropertyDescriptor(object, f), { + configurable: false, + writable: false, + enumerable: true, + value: 'f', + }, 'getOwnPropertyDescriptor f'); + assert.same(getOwnPropertyDescriptor(object, 'g'), undefined, 'getOwnPropertyDescriptor g'); + assert.same(getOwnPropertyDescriptor(object, 'h'), undefined, 'getOwnPropertyDescriptor h'); + assert.same(getOwnPropertyDescriptor(object, i), undefined, 'getOwnPropertyDescriptor i'); + assert.same(getOwnPropertyDescriptor(object, j), undefined, 'getOwnPropertyDescriptor j'); + assert.same(getOwnPropertyDescriptor(object, 'k'), undefined, 'getOwnPropertyDescriptor k'); + assert.false(getOwnPropertyDescriptor(Object.prototype, 'toString').enumerable, 'getOwnPropertyDescriptor on Object.prototype'); + assert.same(getOwnPropertyDescriptor(Object.prototype, d), undefined, 'getOwnPropertyDescriptor on Object.prototype missed symbol'); + assert.same(keys(object).length, 2, 'Object.keys'); + assert.same(getOwnPropertyNames(object).length, 3, 'Object.getOwnPropertyNames'); + assert.same(getOwnPropertySymbols(object).length, 3, 'Object.getOwnPropertySymbols'); + assert.same(ownKeys(object).length, 6, 'Reflect.ownKeys'); + delete object[e]; + object[e] = 'e'; + assert.deepEqual(getOwnPropertyDescriptor(object, e), { + configurable: true, + writable: true, + enumerable: true, + value: 'e', + }, 'redefined non-enum key'); + }); + + QUnit.test('Symbols & Object.defineProperties', assert => { + const c = Symbol('c'); + const d = Symbol('d'); + const descriptors = { + a: { + value: 'a', + }, + }; + descriptors[c] = { + value: 'c', + }; + defineProperty(descriptors, 'b', { + value: { + value: 'b', + }, + }); + defineProperty(descriptors, d, { + value: { + value: 'd', + }, + }); + const object = defineProperties({}, descriptors); + assert.same(object.a, 'a', 'a'); + assert.same(object.b, undefined, 'b'); + assert.same(object[c], 'c', 'c'); + assert.same(object[d], undefined, 'd'); + }); + + QUnit.test('Symbols & Object.create', assert => { + const c = Symbol('c'); + const d = Symbol('d'); + const descriptors = { + a: { + value: 'a', + }, + }; + descriptors[c] = { + value: 'c', + }; + defineProperty(descriptors, 'b', { + value: { + value: 'b', + }, + }); + defineProperty(descriptors, d, { + value: { + value: 'd', + }, + }); + const object = create(null, descriptors); + assert.same(object.a, 'a', 'a'); + assert.same(object.b, undefined, 'b'); + assert.same(object[c], 'c', 'c'); + assert.same(object[d], undefined, 'd'); + }); + + const constructors = { Map, Set, Promise }; + for (const name in constructors) { + QUnit.test(`${ name }@@species`, assert => { + assert.same(constructors[name][Symbol.species], constructors[name], `${ name }@@species === ${ name }`); + const Subclass = create(constructors[name]); + assert.same(Subclass[Symbol.species], Subclass, `${ name } subclass`); + }); + } + + QUnit.test('Array@@species', assert => { + assert.same(Array[Symbol.species], Array, 'Array@@species === Array'); + const Subclass = create(Array); + assert.same(Subclass[Symbol.species], Subclass, 'Array subclass'); + }); + + QUnit.test('Symbol.sham flag', assert => { + assert.same(Symbol.sham, typeof Symbol('Symbol.sham flag test') == 'symbol' ? undefined : true); + }); +} diff --git a/tests/unit-pure/es.symbol.dispose.js b/tests/unit-pure/es.symbol.dispose.js new file mode 100644 index 000000000000..2fd2ee41d5cf --- /dev/null +++ b/tests/unit-pure/es.symbol.dispose.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Symbol.dispose', assert => { + assert.true('dispose' in Symbol, 'Symbol.dispose available'); + assert.true(Object(Symbol.dispose) instanceof Symbol, 'Symbol.dispose is symbol'); +}); diff --git a/tests/unit-pure/es.symbol.for.js b/tests/unit-pure/es.symbol.for.js new file mode 100644 index 000000000000..1ab45eeba66d --- /dev/null +++ b/tests/unit-pure/es.symbol.for.js @@ -0,0 +1,9 @@ +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Symbol.for', assert => { + assert.isFunction(Symbol.for, 'Symbol.for is function'); + const symbol = Symbol.for('foo'); + assert.strictEqual(Symbol.for('foo'), symbol, 'registry'); + assert.true(Object(symbol) instanceof Symbol, 'returns symbol'); + assert.throws(() => Symbol.for(Symbol('foo')), 'throws on symbol argument'); +}); diff --git a/tests/unit-pure/es.symbol.key-for.js b/tests/unit-pure/es.symbol.key-for.js new file mode 100644 index 000000000000..3ec60899d4a1 --- /dev/null +++ b/tests/unit-pure/es.symbol.key-for.js @@ -0,0 +1,8 @@ +import Symbol from 'core-js-pure/es/symbol'; + +QUnit.test('Symbol.keyFor', assert => { + assert.isFunction(Symbol.keyFor, 'Symbol.keyFor is function'); + assert.strictEqual(Symbol.keyFor(Symbol.for('foo')), 'foo'); + assert.strictEqual(Symbol.keyFor(Symbol('foo')), undefined); + assert.throws(() => Symbol.keyFor('foo'), 'throws on non-symbol'); +}); diff --git a/tests/unit-pure/es.unescape.js b/tests/unit-pure/es.unescape.js new file mode 100644 index 000000000000..d1cd6f2de837 --- /dev/null +++ b/tests/unit-pure/es.unescape.js @@ -0,0 +1,15 @@ +import unescape from 'core-js-pure/es/unescape'; + +QUnit.test('unescape', assert => { + assert.isFunction(unescape); + assert.arity(unescape, 1); + assert.same(unescape('%21q2%u0444'), '!q2ф'); + assert.same(unescape('%u044q2%21'), '%u044q2!'); + assert.same(unescape(null), 'null'); + assert.same(unescape(undefined), 'undefined'); + + /* eslint-disable es/no-symbol -- safe */ + if (typeof Symbol == 'function') { + assert.throws(() => unescape(Symbol('unescape test')), 'throws on symbol argument'); + } +}); diff --git a/tests/unit-pure/es.weak-map.js b/tests/unit-pure/es.weak-map.js new file mode 100644 index 000000000000..834f8c64db3d --- /dev/null +++ b/tests/unit-pure/es.weak-map.js @@ -0,0 +1,165 @@ +import { createIterable, nativeSubclass } from '../helpers/helpers.js'; +import { DESCRIPTORS, FREEZING } from '../helpers/constants.js'; + +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import freeze from 'core-js-pure/es/object/freeze'; +import isFrozen from 'core-js-pure/es/object/is-frozen'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import keys from 'core-js-pure/es/object/keys'; +import ownKeys from 'core-js-pure/es/reflect/own-keys'; +import Symbol from 'core-js-pure/es/symbol'; +import WeakMap from 'core-js-pure/es/weak-map'; + +QUnit.test('WeakMap', assert => { + assert.isFunction(WeakMap); + assert.true('delete' in WeakMap.prototype, 'delete in WeakMap.prototype'); + assert.true('get' in WeakMap.prototype, 'get in WeakMap.prototype'); + assert.true('has' in WeakMap.prototype, 'has in WeakMap.prototype'); + assert.true('set' in WeakMap.prototype, 'set in WeakMap.prototype'); + assert.true(new WeakMap() instanceof WeakMap, 'new WeakMap instanceof WeakMap'); + let object = {}; + assert.same(new WeakMap(createIterable([[object, 42]])).get(object), 42, 'Init from iterable'); + let weakmap = new WeakMap(); + const frozen = freeze({}); + weakmap.set(frozen, 42); + assert.same(weakmap.get(frozen), 42, 'Support frozen objects'); + weakmap = new WeakMap(); + weakmap.set(frozen, 42); + assert.true(weakmap.has(frozen), 'works with frozen objects, #1'); + assert.same(weakmap.get(frozen), 42, 'works with frozen objects, #2'); + weakmap.delete(frozen); + assert.false(weakmap.has(frozen), 'works with frozen objects, #3'); + assert.same(weakmap.get(frozen), undefined, 'works with frozen objects, #4'); + let done = false; + try { + new WeakMap(createIterable([null, 1, 2], { + return() { + return done = true; + }, + })); + } catch { /* empty */ } + assert.true(done, '.return #throw'); + assert.false(('clear' in WeakMap.prototype), 'should not contains `.clear` method'); + const array = []; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + new WeakMap(array); + assert.true(done); + object = {}; + new WeakMap().set(object, 1); + if (DESCRIPTORS) { + const results = []; + for (const key in object) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(object), []); + } + assert.arrayEqual(getOwnPropertyNames(object), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); + if (ownKeys) assert.arrayEqual(ownKeys(object), []); + if (nativeSubclass) { + const Subclass = nativeSubclass(WeakMap); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof WeakMap, 'correct subclassing with native classes #2'); + object = {}; + assert.same(new Subclass().set(object, 2).get(object), 2, 'correct subclassing with native classes #3'); + } + + if (typeof ArrayBuffer == 'function') { + const buffer = new ArrayBuffer(8); + const map = new WeakMap([[buffer, 8]]); + assert.true(map.has(buffer), 'works with ArrayBuffer keys'); + } +}); + +QUnit.test('WeakMap#delete', assert => { + assert.isFunction(WeakMap.prototype.delete); + const a = {}; + const b = {}; + const weakmap = new WeakMap(); + weakmap.set(a, 42); + weakmap.set(b, 21); + assert.true(weakmap.has(a), 'WeakMap has values before .delete() #1'); + assert.true(weakmap.has(b), 'WeakMap has values before .delete() #2'); + weakmap.delete(a); + assert.false(weakmap.has(a), 'WeakMap has not value after .delete() #1'); + assert.true(weakmap.has(b), 'WeakMap has not value after .delete() #2'); + assert.notThrows(() => !weakmap.delete(1), 'return false on primitive'); + const object = {}; + weakmap.set(object, 42); + freeze(object); + assert.true(weakmap.has(object), 'works with frozen objects #1'); + weakmap.delete(object); + assert.false(weakmap.has(object), 'works with frozen objects #2'); +}); + +QUnit.test('WeakMap#get', assert => { + assert.isFunction(WeakMap.prototype.get); + const weakmap = new WeakMap(); + assert.same(weakmap.get({}), undefined, 'WeakMap .get() before .set() return undefined'); + let object = {}; + weakmap.set(object, 42); + assert.same(weakmap.get(object), 42, 'WeakMap .get() return value'); + weakmap.delete(object); + assert.same(weakmap.get(object), undefined, 'WeakMap .get() after .delete() return undefined'); + assert.notThrows(() => weakmap.get(1) === undefined, 'return undefined on primitive'); + object = {}; + weakmap.set(object, 42); + freeze(object); + assert.same(weakmap.get(object), 42, 'works with frozen objects #1'); + weakmap.delete(object); + assert.same(weakmap.get(object), undefined, 'works with frozen objects #2'); +}); + +QUnit.test('WeakMap#has', assert => { + assert.isFunction(WeakMap.prototype.has); + const weakmap = new WeakMap(); + assert.false(weakmap.has({}), 'WeakMap .has() before .set() return false'); + let object = {}; + weakmap.set(object, 42); + assert.true(weakmap.has(object), 'WeakMap .has() return true'); + weakmap.delete(object); + assert.false(weakmap.has(object), 'WeakMap .has() after .delete() return false'); + assert.notThrows(() => !weakmap.has(1), 'return false on primitive'); + object = {}; + weakmap.set(object, 42); + freeze(object); + assert.true(weakmap.has(object), 'works with frozen objects #1'); + weakmap.delete(object); + assert.false(weakmap.has(object), 'works with frozen objects #2'); +}); + +QUnit.test('WeakMap#set', assert => { + assert.isFunction(WeakMap.prototype.set); + const weakmap = new WeakMap(); + const object = {}; + weakmap.set(object, 33); + assert.same(weakmap.get(object), 33, 'works with object as keys'); + assert.same(weakmap.set({}, 42), weakmap, 'chaining'); + assert.throws(() => new WeakMap().set(42, 42), 'throws with primitive keys'); + const object1 = freeze({}); + const object2 = {}; + weakmap.set(object1, 42); + weakmap.set(object2, 42); + freeze(object); + assert.same(weakmap.get(object1), 42, 'works with frozen objects #1'); + assert.same(weakmap.get(object2), 42, 'works with frozen objects #2'); + weakmap.delete(object1); + weakmap.delete(object2); + assert.same(weakmap.get(object1), undefined, 'works with frozen objects #3'); + assert.same(weakmap.get(object2), undefined, 'works with frozen objects #4'); + const array = freeze([]); + weakmap.set(array, 42); + assert.same(weakmap.get(array), 42, 'works with frozen arrays #1'); + if (FREEZING) assert.true(isFrozen(array), 'works with frozen arrays #2'); +}); + +QUnit.test('WeakMap#@@toStringTag', assert => { + assert.same(WeakMap.prototype[Symbol.toStringTag], 'WeakMap', 'WeakMap::@@toStringTag is `WeakMap`'); + assert.same(String(new WeakMap()), '[object WeakMap]', 'correct stringification'); +}); diff --git a/tests/unit-pure/es.weak-set.js b/tests/unit-pure/es.weak-set.js new file mode 100644 index 000000000000..f23b0f586465 --- /dev/null +++ b/tests/unit-pure/es.weak-set.js @@ -0,0 +1,108 @@ +import { createIterable, nativeSubclass } from '../helpers/helpers.js'; +import { DESCRIPTORS } from '../helpers/constants.js'; + +import getIteratorMethod from 'core-js-pure/es/get-iterator-method'; +import freeze from 'core-js-pure/es/object/freeze'; +import getOwnPropertyNames from 'core-js-pure/es/object/get-own-property-names'; +import getOwnPropertySymbols from 'core-js-pure/es/object/get-own-property-symbols'; +import keys from 'core-js-pure/es/object/keys'; +import ownKeys from 'core-js-pure/es/reflect/own-keys'; +import Symbol from 'core-js-pure/es/symbol'; +import WeakSet from 'core-js-pure/es/weak-set'; + +QUnit.test('WeakSet', assert => { + assert.isFunction(WeakSet); + assert.true('add' in WeakSet.prototype, 'add in WeakSet.prototype'); + assert.true('delete' in WeakSet.prototype, 'delete in WeakSet.prototype'); + assert.true('has' in WeakSet.prototype, 'has in WeakSet.prototype'); + assert.true(new WeakSet() instanceof WeakSet, 'new WeakSet instanceof WeakSet'); + let object = {}; + assert.true(new WeakSet(createIterable([object])).has(object), 'Init from iterable'); + const weakset = new WeakSet(); + const frozen = freeze({}); + weakset.add(frozen); + assert.true(weakset.has(frozen), 'works with frozen objects, #1'); + weakset.delete(frozen); + assert.false(weakset.has(frozen), 'works with frozen objects, #2'); + let done = false; + try { + new WeakSet(createIterable([null, 1, 2], { + return() { + return done = true; + }, + })); + } catch { /* empty */ } + assert.true(done, '.return #throw'); + assert.false(('clear' in WeakSet.prototype), 'should not contains `.clear` method'); + const array = []; + done = false; + // eslint-disable-next-line es/no-nonstandard-array-prototype-properties -- legacy FF case + array['@@iterator'] = undefined; + array[Symbol.iterator] = function () { + done = true; + return getIteratorMethod([]).call(this); + }; + new WeakSet(array); + assert.true(done); + object = {}; + new WeakSet().add(object); + if (DESCRIPTORS) { + const results = []; + for (const key in object) results.push(key); + assert.arrayEqual(results, []); + assert.arrayEqual(keys(object), []); + } + assert.arrayEqual(getOwnPropertyNames(object), []); + if (getOwnPropertySymbols) assert.arrayEqual(getOwnPropertySymbols(object), []); + if (ownKeys) assert.arrayEqual(ownKeys(object), []); + if (nativeSubclass) { + const Subclass = nativeSubclass(WeakSet); + assert.true(new Subclass() instanceof Subclass, 'correct subclassing with native classes #1'); + assert.true(new Subclass() instanceof WeakSet, 'correct subclassing with native classes #2'); + object = {}; + assert.true(new Subclass().add(object).has(object), 'correct subclassing with native classes #3'); + } + + if (typeof ArrayBuffer == 'function') { + const buffer = new ArrayBuffer(8); + const set = new WeakSet([buffer]); + assert.true(set.has(buffer), 'works with ArrayBuffer keys'); + } +}); + +QUnit.test('WeakSet#add', assert => { + assert.isFunction(WeakSet.prototype.add); + const weakset = new WeakSet(); + assert.same(weakset.add({}), weakset, 'chaining'); + assert.throws(() => new WeakSet().add(42), 'throws with primitive keys'); +}); + +QUnit.test('WeakSet#delete', assert => { + assert.isFunction(WeakSet.prototype.delete); + const a = {}; + const b = {}; + const weakset = new WeakSet().add(a).add(b); + assert.true(weakset.has(a), 'WeakSet has values before .delete() #1'); + assert.true(weakset.has(b), 'WeakSet has values before .delete() #2'); + weakset.delete(a); + assert.false(weakset.has(a), 'WeakSet has not value after .delete() #1'); + assert.true(weakset.has(b), 'WeakSet has not value after .delete() #2'); + assert.notThrows(() => !weakset.delete(1), 'return false on primitive'); +}); + +QUnit.test('WeakSet#has', assert => { + assert.isFunction(WeakSet.prototype.has); + const weakset = new WeakSet(); + assert.false(weakset.has({}), 'WeakSet has`nt value'); + const object = {}; + weakset.add(object); + assert.true(weakset.has(object), 'WeakSet has value after .add()'); + weakset.delete(object); + assert.false(weakset.has(object), 'WeakSet has not value after .delete()'); + assert.notThrows(() => !weakset.has(1), 'return false on primitive'); +}); + +QUnit.test('WeakSet::@@toStringTag', assert => { + assert.same(WeakSet.prototype[Symbol.toStringTag], 'WeakSet', 'WeakSet::@@toStringTag is `WeakSet`'); + assert.same(String(new WeakSet()), '[object WeakSet]', 'correct stringification'); +}); diff --git a/tests/unit-pure/esnext.array.filter-out.js b/tests/unit-pure/esnext.array.filter-out.js new file mode 100644 index 000000000000..2025b33f61ba --- /dev/null +++ b/tests/unit-pure/esnext.array.filter-out.js @@ -0,0 +1,29 @@ +// TODO: Remove from `core-js@4` +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import filterOut from 'core-js-pure/full/array/filter-out'; + +QUnit.test('Array#filterOut', assert => { + assert.isFunction(filterOut); + let array = [1]; + const context = {}; + filterOut(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.deepEqual([1, 2, 3, 4, 5], filterOut([1, 2, 3, 'q', {}, 4, true, 5], it => typeof it != 'number')); + if (STRICT) { + assert.throws(() => filterOut(null, () => { /* empty */ }), TypeError); + assert.throws(() => filterOut(undefined, () => { /* empty */ }), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(filterOut(array, Boolean).foo, 1, '@@species'); +}); diff --git a/tests/unit-pure/esnext.array.filter-reject.js b/tests/unit-pure/esnext.array.filter-reject.js new file mode 100644 index 000000000000..101370e6fd6c --- /dev/null +++ b/tests/unit-pure/esnext.array.filter-reject.js @@ -0,0 +1,28 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import filterReject from 'core-js-pure/full/array/filter-reject'; + +QUnit.test('Array#filterReject', assert => { + assert.isFunction(filterReject); + let array = [1]; + const context = {}; + filterReject(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.deepEqual([1, 2, 3, 4, 5], filterReject([1, 2, 3, 'q', {}, 4, true, 5], it => typeof it != 'number')); + if (STRICT) { + assert.throws(() => filterReject(null, () => { /* empty */ }), TypeError); + assert.throws(() => filterReject(undefined, () => { /* empty */ }), TypeError); + } + array = []; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(filterReject(array, Boolean).foo, 1, '@@species'); +}); diff --git a/tests/unit-pure/esnext.array.group-by-to-map.js b/tests/unit-pure/esnext.array.group-by-to-map.js new file mode 100644 index 000000000000..b7185d973cb1 --- /dev/null +++ b/tests/unit-pure/esnext.array.group-by-to-map.js @@ -0,0 +1,37 @@ +import { STRICT } from '../helpers/constants.js'; + +import Map from 'core-js-pure/es/map'; +import Symbol from 'core-js-pure/es/symbol'; +import from from 'core-js-pure/es/array/from'; +import groupByToMap from 'core-js-pure/actual/array/group-by-to-map'; + +QUnit.test('Array#groupByToMap', assert => { + assert.isFunction(groupByToMap); + let array = [1]; + const context = {}; + groupByToMap(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true(groupByToMap([], it => it) instanceof Map, 'returns Map'); + assert.deepEqual(from(groupByToMap([1, 2, 3], it => it % 2)), [[1, [1, 3]], [0, [2]]], '#1'); + assert.deepEqual( + from(groupByToMap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], it => `i${ it % 5 }`)), + [['i1', [1, 6, 11]], ['i2', [2, 7, 12]], ['i3', [3, 8]], ['i4', [4, 9]], ['i0', [5, 10]]], + '#2', + ); + assert.deepEqual(from(groupByToMap(Array(3), it => it)), [[undefined, [undefined, undefined, undefined]]], '#3'); + if (STRICT) { + assert.throws(() => groupByToMap(null, () => { /* empty */ }), TypeError, 'null this -> TypeError'); + assert.throws(() => groupByToMap(undefined, () => { /* empty */ }), TypeError, 'undefined this -> TypeError'); + } + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(groupByToMap(array, Boolean).get(true).foo, undefined, 'no @@species'); +}); diff --git a/tests/unit-pure/esnext.array.group-by.js b/tests/unit-pure/esnext.array.group-by.js new file mode 100644 index 000000000000..7f10b6654f1f --- /dev/null +++ b/tests/unit-pure/esnext.array.group-by.js @@ -0,0 +1,36 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; +import groupBy from 'core-js-pure/actual/array/group-by'; + +QUnit.test('Array#groupBy', assert => { + assert.isFunction(groupBy); + let array = [1]; + const context = {}; + groupBy(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same(getPrototypeOf(groupBy([], it => it)), null, 'null proto'); + assert.deepEqual(groupBy([1, 2, 3], it => it % 2), { 1: [1, 3], 0: [2] }, '#1'); + assert.deepEqual( + groupBy([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], it => `i${ it % 5 }`), + { i1: [1, 6, 11], i2: [2, 7, 12], i3: [3, 8], i4: [4, 9], i0: [5, 10] }, + '#2', + ); + assert.deepEqual(groupBy(Array(3), it => it), { undefined: [undefined, undefined, undefined] }, '#3'); + if (STRICT) { + assert.throws(() => groupBy(null, () => { /* empty */ }), TypeError, 'null this -> TypeError'); + assert.throws(() => groupBy(undefined, () => { /* empty */ }), TypeError, 'undefined this -> TypeError'); + } + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(groupBy(array, Boolean).true.foo, undefined, 'no @@species'); +}); diff --git a/tests/unit-pure/esnext.array.group-to-map.js b/tests/unit-pure/esnext.array.group-to-map.js new file mode 100644 index 000000000000..ee7450928268 --- /dev/null +++ b/tests/unit-pure/esnext.array.group-to-map.js @@ -0,0 +1,37 @@ +import { STRICT } from '../helpers/constants.js'; + +import Map from 'core-js-pure/es/map'; +import Symbol from 'core-js-pure/es/symbol'; +import from from 'core-js-pure/es/array/from'; +import groupToMap from 'core-js-pure/actual/array/group-to-map'; + +QUnit.test('Array#groupToMap', assert => { + assert.isFunction(groupToMap); + let array = [1]; + const context = {}; + groupToMap(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.true(groupToMap([], it => it) instanceof Map, 'returns Map'); + assert.deepEqual(from(groupToMap([1, 2, 3], it => it % 2)), [[1, [1, 3]], [0, [2]]], '#1'); + assert.deepEqual( + from(groupToMap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], it => `i${ it % 5 }`)), + [['i1', [1, 6, 11]], ['i2', [2, 7, 12]], ['i3', [3, 8]], ['i4', [4, 9]], ['i0', [5, 10]]], + '#2', + ); + assert.deepEqual(from(groupToMap(Array(3), it => it)), [[undefined, [undefined, undefined, undefined]]], '#3'); + if (STRICT) { + assert.throws(() => groupToMap(null, () => { /* empty */ }), TypeError, 'null this -> TypeError'); + assert.throws(() => groupToMap(undefined, () => { /* empty */ }), TypeError, 'undefined this -> TypeError'); + } + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(groupToMap(array, Boolean).get(true).foo, undefined, 'no @@species'); +}); diff --git a/tests/unit-pure/esnext.array.group.js b/tests/unit-pure/esnext.array.group.js new file mode 100644 index 000000000000..8881b6790294 --- /dev/null +++ b/tests/unit-pure/esnext.array.group.js @@ -0,0 +1,36 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; +import group from 'core-js-pure/actual/array/group'; + +QUnit.test('Array#group', assert => { + assert.isFunction(group); + let array = [1]; + const context = {}; + group(array, function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 0, 'correct index in callback'); + assert.same(that, array, 'correct link to array in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + assert.same(getPrototypeOf(group([], it => it)), null, 'null proto'); + assert.deepEqual(group([1, 2, 3], it => it % 2), { 1: [1, 3], 0: [2] }, '#1'); + assert.deepEqual( + group([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], it => `i${ it % 5 }`), + { i1: [1, 6, 11], i2: [2, 7, 12], i3: [3, 8], i4: [4, 9], i0: [5, 10] }, + '#2', + ); + assert.deepEqual(group(Array(3), it => it), { undefined: [undefined, undefined, undefined] }, '#3'); + if (STRICT) { + assert.throws(() => group(null, () => { /* empty */ }), TypeError, 'null this -> TypeError'); + assert.throws(() => group(undefined, () => { /* empty */ }), TypeError, 'undefined this -> TypeError'); + } + array = [1]; + // eslint-disable-next-line object-shorthand -- constructor + array.constructor = { [Symbol.species]: function () { + return { foo: 1 }; + } }; + assert.same(group(array, Boolean).true.foo, undefined, 'no @@species'); +}); diff --git a/tests/unit-pure/esnext.array.is-template-object.js b/tests/unit-pure/esnext.array.is-template-object.js new file mode 100644 index 000000000000..22e8ea43f1ce --- /dev/null +++ b/tests/unit-pure/esnext.array.is-template-object.js @@ -0,0 +1,27 @@ +import freeze from 'core-js-pure/es/object/freeze'; +import isTemplateObject from 'core-js-pure/full/array/is-template-object'; + +QUnit.test('Array.isTemplateObject', assert => { + assert.isFunction(isTemplateObject); + assert.arity(isTemplateObject, 1); + assert.name(isTemplateObject, 'isTemplateObject'); + + assert.false(isTemplateObject(undefined)); + assert.false(isTemplateObject(null)); + assert.false(isTemplateObject({})); + assert.false(isTemplateObject(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }())); + assert.false(isTemplateObject([])); + assert.false(isTemplateObject(freeze([]))); + + const template = (() => { + try { + // eslint-disable-next-line no-template-curly-in-string -- ignore + return Function('return (it => it)`qwe${ 123 }asd`')(); + } catch { /* empty */ } + })(); + + if (template) assert.true(isTemplateObject(template)); +}); diff --git a/tests/unit-pure/esnext.array.unique-by.js b/tests/unit-pure/esnext.array.unique-by.js new file mode 100644 index 000000000000..f857111075b8 --- /dev/null +++ b/tests/unit-pure/esnext.array.unique-by.js @@ -0,0 +1,51 @@ +import { STRICT } from '../helpers/constants.js'; + +import uniqueBy from 'core-js-pure/full/array/unique-by'; + +QUnit.test('Array#uniqueBy', assert => { + assert.isFunction(uniqueBy); + + let array = [1, 2, 3, 2, 1]; + assert.notSame(uniqueBy(array), array); + assert.deepEqual(uniqueBy(array), [1, 2, 3]); + + array = [ + { + id: 1, + uid: 10000, + }, + { + id: 2, + uid: 10000, + }, + { + id: 3, + uid: 10001, + }, + ]; + + assert.deepEqual(uniqueBy(array, it => it.uid), [ + { + id: 1, + uid: 10000, + }, + { + id: 3, + uid: 10001, + }, + ]); + + assert.deepEqual(uniqueBy(array, ({ id, uid }) => `${ id }-${ uid }`), array); + + assert.deepEqual(uniqueBy([1, undefined, 2, undefined, null, 1]), [1, undefined, 2, null]); + + assert.deepEqual(uniqueBy([0, -0]), [0]); + assert.deepEqual(uniqueBy([NaN, NaN]), [NaN]); + + assert.deepEqual(uniqueBy({ length: 1, 0: 1 }), [1]); + + if (STRICT) { + assert.throws(() => uniqueBy(null), TypeError); + assert.throws(() => uniqueBy(undefined), TypeError); + } +}); diff --git a/tests/unit-pure/esnext.async-iterator.as-indexed-pairs.js b/tests/unit-pure/esnext.async-iterator.as-indexed-pairs.js new file mode 100644 index 000000000000..8fb32c0730ae --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.as-indexed-pairs.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import AsyncIterator from 'core-js-pure/full/async-iterator'; + +QUnit.test('AsyncIterator#asIndexedPairs', assert => { + const { asIndexedPairs } = AsyncIterator.prototype; + + assert.isFunction(asIndexedPairs); + assert.arity(asIndexedPairs, 0); + assert.nonEnumerable(AsyncIterator.prototype, 'asIndexedPairs'); + + if (STRICT) { + assert.throws(() => asIndexedPairs.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => asIndexedPairs.call(null, () => { /* empty */ }), TypeError); + } + + return asIndexedPairs.call(createIterator(['a', 'b', 'c'])).toArray().then(it => { + assert.same(it.toString(), '0,a,1,b,2,c', 'basic functionality'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.constructor.js b/tests/unit-pure/esnext.async-iterator.constructor.js new file mode 100644 index 000000000000..c284785026a1 --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.constructor.js @@ -0,0 +1,30 @@ +import { nativeSubclass } from '../helpers/helpers.js'; + +import Symbol from 'core-js-pure/es/symbol'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator', assert => { + assert.isFunction(AsyncIterator); + assert.arity(AsyncIterator, 0); + + assert.true(AsyncIterator.from([1, 2, 3]) instanceof AsyncIterator, 'Async From Proxy'); + assert.true(AsyncIterator.from([1, 2, 3]).drop(1) instanceof AsyncIterator, 'Async Drop Proxy'); + + if (nativeSubclass) { + const Sub = nativeSubclass(AsyncIterator); + assert.true(new Sub() instanceof AsyncIterator, 'abstract constructor'); + } + + assert.throws(() => new AsyncIterator(), 'direct constructor throws'); + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing + assert.throws(() => AsyncIterator(), 'throws w/o `new`'); +}); + +QUnit.test('AsyncIterator#constructor', assert => { + assert.same(AsyncIterator.prototype.constructor, AsyncIterator, 'AsyncIterator#constructor is AsyncIterator'); +}); + +QUnit.test('AsyncIterator#@@toStringTag', assert => { + assert.same(AsyncIterator.prototype[Symbol.toStringTag], 'AsyncIterator', 'AsyncIterator::@@toStringTag is `AsyncIterator`'); +}); diff --git a/tests/unit-pure/esnext.async-iterator.drop.js b/tests/unit-pure/esnext.async-iterator.drop.js new file mode 100644 index 000000000000..144635cf9c0c --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.drop.js @@ -0,0 +1,33 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#drop', assert => { + const { drop } = AsyncIterator.prototype; + + assert.isFunction(drop); + assert.arity(drop, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'drop'); + + if (STRICT) { + assert.throws(() => drop.call(undefined, 1), TypeError); + assert.throws(() => drop.call(null, 1), TypeError); + } + + assert.throws(() => drop.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => drop.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); + + return drop.call(createIterator([1, 2, 3]), 1).toArray().then(it => { + assert.arrayEqual(it, [2, 3], 'basic functionality'); + return drop.call(createIterator([1, 2, 3]), 1.5).toArray(); + }).then(it => { + assert.arrayEqual(it, [2, 3], 'float'); + return drop.call(createIterator([1, 2, 3]), 4).toArray(); + }).then(it => { + assert.arrayEqual(it, [], 'big'); + return drop.call(createIterator([1, 2, 3]), 0).toArray(); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'zero'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.every.js b/tests/unit-pure/esnext.async-iterator.every.js new file mode 100644 index 000000000000..3f2e6c4c265c --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.every.js @@ -0,0 +1,40 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#every', assert => { + const { every } = AsyncIterator.prototype; + + assert.isFunction(every); + assert.arity(every, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'every'); + + if (STRICT) { + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => every.call(createIterator([1]), undefined), TypeError); + assert.throws(() => every.call(createIterator([1]), null), TypeError); + assert.throws(() => every.call(createIterator([1]), {}), TypeError); + + return every.call(createIterator([1, 2, 3]), it => typeof it == 'number').then(result => { + assert.true(result, 'basic functionality, +'); + return every.call(createIterator([1, 2, 3]), it => it === 2); + }).then(result => { + assert.false(result, 'basic functionality, -'); + return every.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + }).then(() => { + return every.call(createIterator([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.filter.js b/tests/unit-pure/esnext.async-iterator.filter.js new file mode 100644 index 000000000000..33bfbfbc826b --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.filter.js @@ -0,0 +1,37 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#filter', assert => { + const { filter } = AsyncIterator.prototype; + + assert.isFunction(filter); + assert.arity(filter, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'filter'); + + if (STRICT) { + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => filter.call(createIterator([1]), undefined), TypeError); + assert.throws(() => filter.call(createIterator([1]), null), TypeError); + assert.throws(() => filter.call(createIterator([1]), {}), TypeError); + + return filter.call(createIterator([1, 2, 3]), it => it % 2).toArray().then(it => { + assert.arrayEqual(it, [1, 3], 'basic functionality'); + return filter.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }).toArray(); + }).then(() => { + return filter.call(createIterator([1]), () => { throw 42; }).toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.find.js b/tests/unit-pure/esnext.async-iterator.find.js new file mode 100644 index 000000000000..29e6d8cc2f90 --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.find.js @@ -0,0 +1,40 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#find', assert => { + const { find } = AsyncIterator.prototype; + + assert.isFunction(find); + assert.arity(find, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'find'); + + if (STRICT) { + assert.throws(() => find.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => find.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => find.call(createIterator([1]), undefined), TypeError); + assert.throws(() => find.call(createIterator([1]), null), TypeError); + assert.throws(() => find.call(createIterator([1]), {}), TypeError); + + return find.call(createIterator([2, 3, 4]), it => it % 2).then(result => { + assert.same(result, 3, 'basic functionality, +'); + return find.call(createIterator([1, 2, 3]), it => it === 4); + }).then(result => { + assert.same(result, undefined, 'basic functionality, -'); + return find.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + }).then(() => { + return find.call(createIterator([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.flat-map.js b/tests/unit-pure/esnext.async-iterator.flat-map.js new file mode 100644 index 000000000000..1f0f5c221216 --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.flat-map.js @@ -0,0 +1,38 @@ +import { createIterator, createIterable } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#flatMap', assert => { + const { flatMap } = AsyncIterator.prototype; + + assert.isFunction(flatMap); + assert.arity(flatMap, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'flatMap'); + + if (STRICT) { + assert.throws(() => flatMap.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => flatMap.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => flatMap.call(createIterator([1]), undefined), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), null), TypeError); + assert.throws(() => flatMap.call(createIterator([1]), {}), TypeError); + + return flatMap.call(createIterator([1, [], 2, createIterable([3, 4]), [5, 6]]), it => typeof it == 'number' ? [-it] : it).toArray().then(it => { + assert.arrayEqual(it, [-1, -2, 3, 4, 5, 6], 'basic functionality'); + return flatMap.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + return [arg]; + }).toArray(); + }).then(() => { + return flatMap.call(createIterator([1]), () => { throw 42; }).toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.for-each.js b/tests/unit-pure/esnext.async-iterator.for-each.js new file mode 100644 index 000000000000..5ce91215750d --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.for-each.js @@ -0,0 +1,39 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#forEach', assert => { + const { forEach } = AsyncIterator.prototype; + + assert.isFunction(forEach); + assert.arity(forEach, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'forEach'); + + if (STRICT) { + assert.throws(() => forEach.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => forEach.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => forEach.call(createIterator([1]), undefined), TypeError); + assert.throws(() => forEach.call(createIterator([1]), null), TypeError); + assert.throws(() => forEach.call(createIterator([1]), {}), TypeError); + + const array = []; + + return forEach.call(createIterator([1, 2, 3]), it => array.push(it)).then(() => { + assert.arrayEqual(array, [1, 2, 3], 'basic functionality'); + return forEach.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + }).then(() => { + return forEach.call(createIterator([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.from.js b/tests/unit-pure/esnext.async-iterator.from.js new file mode 100644 index 000000000000..fc536342ef89 --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.from.js @@ -0,0 +1,50 @@ +import Promise from 'core-js-pure/es/promise'; +import assign from 'core-js-pure/es/object/assign'; +import create from 'core-js-pure/es/object/create'; +import values from 'core-js-pure/es/array/values'; +import ITERATOR from 'core-js-pure/es/symbol/iterator'; +import AsyncIterator from 'core-js-pure/actual/async-iterator'; +import Iterator from 'core-js-pure/actual/iterator'; + +QUnit.test('AsyncIterator.from', assert => { + const { from } = AsyncIterator; + + assert.isFunction(from); + assert.arity(from, 1); + + assert.true(AsyncIterator.from(values([])) instanceof AsyncIterator, 'proxy, iterator'); + + assert.true(AsyncIterator.from([]) instanceof AsyncIterator, 'proxy, iterable'); + + const asyncIterator = assign(create(AsyncIterator.prototype), { + next: () => { /* empty */ }, + }); + + assert.same(AsyncIterator.from(asyncIterator), asyncIterator, 'does not wrap AsyncIterator instances'); + + assert.throws(() => from(undefined), TypeError); + assert.throws(() => from(null), TypeError); + + const closableIterator = { + closed: false, + [ITERATOR]() { return this; }, + next() { + return { value: Promise.reject(42), done: false }; + }, + return() { + this.closed = true; + return { value: undefined, done: true }; + }, + }; + + return AsyncIterator.from([1, Promise.resolve(2), 3]).toArray().then(result => { + assert.arrayEqual(result, [1, 2, 3], 'unwrap promises'); + }).then(() => { + return from(Iterator.from(closableIterator)).toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + assert.true(closableIterator.closed, 'doesn\'t close sync iterator on promise rejection'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.indexed.js b/tests/unit-pure/esnext.async-iterator.indexed.js new file mode 100644 index 000000000000..e46e5d2ab257 --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.indexed.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import AsyncIterator from 'core-js-pure/full/async-iterator'; + +QUnit.test('AsyncIterator#indexed', assert => { + const { indexed } = AsyncIterator.prototype; + + assert.isFunction(indexed); + assert.arity(indexed, 0); + assert.nonEnumerable(AsyncIterator.prototype, 'indexed'); + + if (STRICT) { + assert.throws(() => indexed.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => indexed.call(null, () => { /* empty */ }), TypeError); + } + + return indexed.call(createIterator(['a', 'b', 'c'])).toArray().then(it => { + assert.same(it.toString(), '0,a,1,b,2,c', 'basic functionality'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.map.js b/tests/unit-pure/esnext.async-iterator.map.js new file mode 100644 index 000000000000..ee5dbe560ec2 --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.map.js @@ -0,0 +1,37 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#map', assert => { + const { map } = AsyncIterator.prototype; + + assert.isFunction(map); + assert.arity(map, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'map'); + + if (STRICT) { + assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => map.call(createIterator([1]), undefined), TypeError); + assert.throws(() => map.call(createIterator([1]), null), TypeError); + assert.throws(() => map.call(createIterator([1]), {}), TypeError); + + return map.call(createIterator([1, 2, 3]), it => it ** 2).toArray().then(it => { + assert.arrayEqual(it, [1, 4, 9], 'basic functionality'); + return map.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }).toArray(); + }).then(() => { + return map.call(createIterator([1]), () => { throw 42; }).toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.reduce.js b/tests/unit-pure/esnext.async-iterator.reduce.js new file mode 100644 index 000000000000..aa9a460a560a --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.reduce.js @@ -0,0 +1,44 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#reduce', assert => { + const { reduce } = AsyncIterator.prototype; + + assert.isFunction(reduce); + assert.arity(reduce, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'reduce'); + + if (STRICT) { + assert.throws(() => reduce.call(undefined, () => { /* empty */ }, 1), TypeError); + assert.throws(() => reduce.call(null, () => { /* empty */ }, 1), TypeError); + } + + assert.throws(() => reduce.call(createIterator([1]), undefined, 1), TypeError); + assert.throws(() => reduce.call(createIterator([1]), null, 1), TypeError); + assert.throws(() => reduce.call(createIterator([1]), {}, 1), TypeError); + + return reduce.call(createIterator([1, 2, 3]), (a, b) => a + b, 1).then(it => { + assert.same(it, 7, 'basic functionality, initial'); + return reduce.call(createIterator([2]), function (a, b, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 3, 'arguments length'); + assert.same(a, 1, 'argument 1'); + assert.same(b, 2, 'argument 2'); + assert.same(counter, 0, 'counter'); + }, 1); + }).then(() => { + return reduce.call(createIterator([1, 2, 3]), (a, b) => a + b); + }).then(it => { + assert.same(it, 6, 'basic functionality, no initial'); + return reduce.call(createIterator([]), (a, b) => a + b); + }).catch(() => { + assert.true(true, 'reduce an empty iterable with no initial'); + return reduce.call(createIterator([1]), () => { throw 42; }, 1); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.some.js b/tests/unit-pure/esnext.async-iterator.some.js new file mode 100644 index 000000000000..e95088ea6a87 --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.some.js @@ -0,0 +1,40 @@ +import { createIterator } from '../helpers/helpers.js'; +import { STRICT, STRICT_THIS } from '../helpers/constants.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#some', assert => { + const { some } = AsyncIterator.prototype; + + assert.isFunction(some); + assert.arity(some, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'some'); + + if (STRICT) { + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); + } + + assert.throws(() => some.call(createIterator([1]), undefined), TypeError); + assert.throws(() => some.call(createIterator([1]), null), TypeError); + assert.throws(() => some.call(createIterator([1]), {}), TypeError); + + return some.call(createIterator([1, 2, 3]), it => it === 2).then(result => { + assert.true(result, 'basic functionality, +'); + return some.call(createIterator([1, 2, 3]), it => it === 4); + }).then(result => { + assert.false(result, 'basic functionality, -'); + return some.call(createIterator([1]), function (arg, counter) { + assert.same(this, STRICT_THIS, 'this'); + assert.same(arguments.length, 2, 'arguments length'); + assert.same(arg, 1, 'argument'); + assert.same(counter, 0, 'counter'); + }); + }).then(() => { + return some.call(createIterator([1]), () => { throw 42; }); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.take.js b/tests/unit-pure/esnext.async-iterator.take.js new file mode 100644 index 000000000000..095eee432560 --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.take.js @@ -0,0 +1,33 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#take', assert => { + const { take } = AsyncIterator.prototype; + + assert.isFunction(take); + assert.arity(take, 1); + assert.nonEnumerable(AsyncIterator.prototype, 'take'); + + if (STRICT) { + assert.throws(() => take.call(undefined, 1), TypeError); + assert.throws(() => take.call(null, 1), TypeError); + } + + assert.throws(() => take.call(createIterator([1, 2, 3]), -1), RangeError, 'negative'); + assert.throws(() => take.call(createIterator([1, 2, 3]), NaN), RangeError, 'NaN'); + + return take.call(createIterator([1, 2, 3]), 2).toArray().then(it => { + assert.arrayEqual(it, [1, 2], 'basic functionality'); + return take.call(createIterator([1, 2, 3]), 1.5).toArray(); + }).then(it => { + assert.arrayEqual(it, [1], 'float'); + return take.call(createIterator([1, 2, 3]), 4).toArray(); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3], 'big'); + return take.call(createIterator([1, 2, 3]), 0).toArray(); + }).then(it => { + assert.arrayEqual(it, [], 'zero'); + }); +}); diff --git a/tests/unit-pure/esnext.async-iterator.to-array.js b/tests/unit-pure/esnext.async-iterator.to-array.js new file mode 100644 index 000000000000..c21d2fe5405d --- /dev/null +++ b/tests/unit-pure/esnext.async-iterator.to-array.js @@ -0,0 +1,21 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import AsyncIterator from 'core-js-pure/actual/async-iterator'; + +QUnit.test('AsyncIterator#toArray', assert => { + const { toArray } = AsyncIterator.prototype; + + assert.isFunction(toArray); + assert.arity(toArray, 0); + assert.nonEnumerable(AsyncIterator.prototype, 'toArray'); + + if (STRICT) { + assert.throws(() => toArray.call(undefined), TypeError); + assert.throws(() => toArray.call(null), TypeError); + } + + return toArray.call(createIterator([1, 2, 3])).then(it => { + assert.arrayEqual(it, [1, 2, 3]); + }); +}); diff --git a/tests/unit-pure/esnext.bigint.range.js b/tests/unit-pure/esnext.bigint.range.js new file mode 100644 index 000000000000..bf15f9b409dd --- /dev/null +++ b/tests/unit-pure/esnext.bigint.range.js @@ -0,0 +1,61 @@ +/* eslint-disable es/no-bigint -- safe */ +import from from 'core-js-pure/es/array/from'; +import range from 'core-js-pure/full/bigint/range'; + +if (typeof BigInt == 'function') QUnit.test('BigInt.range', assert => { + assert.isFunction(range); + assert.name(range, 'range'); + assert.arity(range, 3); + + let iterator = range(BigInt(1), BigInt(2)); + + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: BigInt(1), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.deepEqual(from(range(BigInt(-1), BigInt(5))), [BigInt(-1), BigInt(0), BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + assert.deepEqual(from(range(BigInt(-5), BigInt(1))), [BigInt(-5), BigInt(-4), BigInt(-3), BigInt(-2), BigInt(-1), BigInt(0)]); + assert.deepEqual( + from(range(BigInt('9007199254740991'), BigInt('9007199254740992'), { inclusive: true })), + [BigInt('9007199254740991'), BigInt('9007199254740992')], + ); + assert.deepEqual(from(range(BigInt(0), BigInt(0))), []); + assert.deepEqual(from(range(BigInt(0), BigInt(-5), BigInt(1))), []); + + iterator = range(BigInt(1), BigInt(3)); + assert.deepEqual(iterator.start, BigInt(1)); + assert.deepEqual(iterator.end, BigInt(3)); + assert.deepEqual(iterator.step, BigInt(1)); + assert.false(iterator.inclusive); + + iterator = range(BigInt(-1), BigInt(-3), { inclusive: true }); + assert.deepEqual(iterator.start, BigInt(-1)); + assert.deepEqual(iterator.end, BigInt(-3)); + assert.same(iterator.step, BigInt(-1)); + assert.true(iterator.inclusive); + + iterator = range(BigInt(-1), BigInt(-3), { step: BigInt(4), inclusive() { /* empty */ } }); + assert.same(iterator.start, BigInt(-1)); + assert.same(iterator.end, BigInt(-3)); + assert.same(iterator.step, BigInt(4)); + assert.true(iterator.inclusive); + + iterator = range(BigInt(0), BigInt(5)); + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + assert.throws(() => Object.getOwnPropertyDescriptor(iterator, 'start').get.call({}), TypeError); + + assert.throws(() => range(Infinity, BigInt(10), BigInt(0)), TypeError); + assert.throws(() => range(-Infinity, BigInt(10), BigInt(0)), TypeError); + assert.throws(() => range(BigInt(0), BigInt(10), Infinity), TypeError); + assert.throws(() => range(BigInt(0), BigInt(10), { step: Infinity }), TypeError); + + assert.throws(() => range({}, BigInt(1)), TypeError); + assert.throws(() => range(BigInt(1), {}), TypeError); +}); diff --git a/tests/unit-pure/esnext.composite-key.js b/tests/unit-pure/esnext.composite-key.js new file mode 100644 index 000000000000..c79fa1ebd9ea --- /dev/null +++ b/tests/unit-pure/esnext.composite-key.js @@ -0,0 +1,46 @@ + +import { FREEZING } from '../helpers/constants.js'; + +import { getPrototypeOf, isFrozen } from 'core-js-pure/es/object'; +import compositeKey from 'core-js-pure/full/composite-key'; + +QUnit.test('compositeKey', assert => { + assert.isFunction(compositeKey); + if (compositeKey.name) assert.name(compositeKey, 'compositeKey'); + + const key = compositeKey({}); + assert.same(typeof key, 'object'); + assert.same({}.toString.call(key), '[object Object]'); + assert.same(getPrototypeOf(key), null); + if (FREEZING) assert.true(isFrozen(key)); + + const a = ['a']; + const b = ['b']; + const c = ['c']; + + assert.same(compositeKey(a), compositeKey(a)); + assert.notSame(compositeKey(a), compositeKey(['a'])); + assert.notSame(compositeKey(a), compositeKey(a, 1)); + assert.notSame(compositeKey(a), compositeKey(a, b)); + assert.same(compositeKey(a, 1), compositeKey(a, 1)); + assert.same(compositeKey(a, b), compositeKey(a, b)); + assert.notSame(compositeKey(a, b), compositeKey(b, a)); + assert.same(compositeKey(a, b, c), compositeKey(a, b, c)); + assert.notSame(compositeKey(a, b, c), compositeKey(c, b, a)); + assert.notSame(compositeKey(a, b, c), compositeKey(a, c, b)); + assert.notSame(compositeKey(a, b, c, 1), compositeKey(a, b, c)); + assert.same(compositeKey(a, b, c, 1), compositeKey(a, b, c, 1)); + assert.same(compositeKey(1, a), compositeKey(1, a)); + assert.notSame(compositeKey(1, a), compositeKey(a, 1)); + assert.same(compositeKey(1, a, 2, b), compositeKey(1, a, 2, b)); + assert.notSame(compositeKey(1, a, 2, b), compositeKey(1, a, b, 2)); + assert.same(compositeKey(1, 2, a, b), compositeKey(1, 2, a, b)); + assert.notSame(compositeKey(1, 2, a, b), compositeKey(1, a, b, 2)); + assert.same(compositeKey(a, a), compositeKey(a, a)); + assert.notSame(compositeKey(a, a), compositeKey(a, ['a'])); + assert.notSame(compositeKey(a, a), compositeKey(a, b)); + + assert.throws(() => compositeKey(), TypeError); + assert.throws(() => compositeKey(1, 2), TypeError); + assert.throws(() => compositeKey('foo', null, true), TypeError); +}); diff --git a/tests/unit-pure/esnext.composite-symbol.js b/tests/unit-pure/esnext.composite-symbol.js new file mode 100644 index 000000000000..064d84f33c8e --- /dev/null +++ b/tests/unit-pure/esnext.composite-symbol.js @@ -0,0 +1,40 @@ +import Symbol from 'core-js-pure/es/symbol'; +import compositeSymbol from 'core-js-pure/full/composite-symbol'; + +QUnit.test('compositeSymbol', assert => { + assert.isFunction(compositeSymbol); + if (compositeSymbol.name) assert.name(compositeSymbol, 'compositeSymbol'); + + assert.true(Object(compositeSymbol({})) instanceof Symbol); + + const a = ['a']; + const b = ['b']; + const c = ['c']; + + assert.same(compositeSymbol(a), compositeSymbol(a)); + assert.notSame(compositeSymbol(a), compositeSymbol(['a'])); + assert.notSame(compositeSymbol(a), compositeSymbol(a, 1)); + assert.notSame(compositeSymbol(a), compositeSymbol(a, b)); + assert.same(compositeSymbol(a, 1), compositeSymbol(a, 1)); + assert.same(compositeSymbol(a, b), compositeSymbol(a, b)); + assert.notSame(compositeSymbol(a, b), compositeSymbol(b, a)); + assert.same(compositeSymbol(a, b, c), compositeSymbol(a, b, c)); + assert.notSame(compositeSymbol(a, b, c), compositeSymbol(c, b, a)); + assert.notSame(compositeSymbol(a, b, c), compositeSymbol(a, c, b)); + assert.notSame(compositeSymbol(a, b, c, 1), compositeSymbol(a, b, c)); + assert.same(compositeSymbol(a, b, c, 1), compositeSymbol(a, b, c, 1)); + assert.same(compositeSymbol(1, a), compositeSymbol(1, a)); + assert.notSame(compositeSymbol(1, a), compositeSymbol(a, 1)); + assert.same(compositeSymbol(1, a, 2, b), compositeSymbol(1, a, 2, b)); + assert.notSame(compositeSymbol(1, a, 2, b), compositeSymbol(1, a, b, 2)); + assert.same(compositeSymbol(1, 2, a, b), compositeSymbol(1, 2, a, b)); + assert.notSame(compositeSymbol(1, 2, a, b), compositeSymbol(1, a, b, 2)); + assert.same(compositeSymbol(a, a), compositeSymbol(a, a)); + assert.notSame(compositeSymbol(a, a), compositeSymbol(a, ['a'])); + assert.notSame(compositeSymbol(a, a), compositeSymbol(a, b)); + assert.same(compositeSymbol(), compositeSymbol()); + assert.same(compositeSymbol(1, 2), compositeSymbol(1, 2)); + assert.notSame(compositeSymbol(1, 2), compositeSymbol(2, 1)); + assert.same(compositeSymbol('foo', null, true), compositeSymbol('foo', null, true)); + assert.same(compositeSymbol('string'), Symbol.for('string')); +}); diff --git a/tests/unit-pure/esnext.function.demethodize.js b/tests/unit-pure/esnext.function.demethodize.js new file mode 100644 index 000000000000..896e543c7a5f --- /dev/null +++ b/tests/unit-pure/esnext.function.demethodize.js @@ -0,0 +1,8 @@ +import demethodize from 'core-js-pure/full/function/demethodize'; + +QUnit.test('Function#demethodize', assert => { + assert.isFunction(demethodize); + // eslint-disable-next-line prefer-arrow-callback -- required for testing + assert.same(demethodize(function () { return 42; })(), 42); + assert.deepEqual(demethodize(Array.prototype.slice)([1, 2, 3], 1), [2, 3]); +}); diff --git a/tests/unit-pure/esnext.function.is-callable.js b/tests/unit-pure/esnext.function.is-callable.js new file mode 100644 index 000000000000..6d00baea77f6 --- /dev/null +++ b/tests/unit-pure/esnext.function.is-callable.js @@ -0,0 +1,38 @@ +import isCallable from 'core-js-pure/full/function/is-callable'; +import { fromSource } from '../helpers/helpers.js'; + +QUnit.test('Function.isCallable', assert => { + assert.isFunction(isCallable); + assert.arity(isCallable, 1); + assert.name(isCallable, 'isCallable'); + assert.false(isCallable({}), 'object'); + assert.false(isCallable(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }()), 'arguments'); + assert.false(isCallable([]), 'array'); + assert.false(isCallable(/./), 'regex'); + assert.false(isCallable(1), 'number'); + assert.false(isCallable(true), 'boolean'); + assert.false(isCallable('1'), 'string'); + assert.false(isCallable(null), 'null'); + assert.false(isCallable(), 'undefined'); + assert.true(isCallable(Function.call), 'native function'); + // eslint-disable-next-line prefer-arrow-callback -- required + assert.true(isCallable(function () { /* empty */ }), 'function'); + + const arrow = fromSource('it => it'); + if (arrow) assert.true(isCallable(arrow), 'arrow'); + const klass = fromSource('class {}'); + // Safari 9 and Edge 13- bugs + if (klass && !/constructor|function/.test(klass)) assert.false(isCallable(klass), 'class'); + const gen = fromSource('function * () {}'); + if (gen) assert.true(isCallable(gen), 'gen'); + const asyncFunc = fromSource('async function () {}'); + if (asyncFunc) assert.true(isCallable(asyncFunc), 'asyncFunc'); + const asyncGen = fromSource('async * function () {}'); + if (asyncGen) assert.true(isCallable(asyncGen), 'asyncGen'); + const method = fromSource('({f(){}}).f'); + // Safari 9 bug + if (method && !/function/.test(method)) assert.true(isCallable(method), 'method'); +}); diff --git a/tests/unit-pure/esnext.function.is-constructor.js b/tests/unit-pure/esnext.function.is-constructor.js new file mode 100644 index 000000000000..674ae7bf5977 --- /dev/null +++ b/tests/unit-pure/esnext.function.is-constructor.js @@ -0,0 +1,43 @@ +import isConstructor from 'core-js-pure/full/function/is-constructor'; +import { fromSource } from '../helpers/helpers.js'; + +QUnit.test('Function.isConstructor', assert => { + assert.isFunction(isConstructor); + assert.arity(isConstructor, 1); + assert.name(isConstructor, 'isConstructor'); + assert.false(isConstructor({}), 'object'); + assert.false(isConstructor(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }()), 'arguments'); + assert.false(isConstructor([]), 'array'); + assert.false(isConstructor(/./), 'regex'); + assert.false(isConstructor(1), 'number'); + assert.false(isConstructor(true), 'boolean'); + assert.false(isConstructor('1'), 'string'); + assert.false(isConstructor(null), 'null'); + assert.false(isConstructor(), 'undefined'); + // assert.false(isConstructor(Function.call), 'native function'); // fails in some old engines + // eslint-disable-next-line prefer-arrow-callback -- required + assert.true(isConstructor(function () { /* empty */ }), 'function'); + + const arrow = fromSource('it => it'); + if (arrow) assert.false(isConstructor(arrow), 'arrow'); + const klass = fromSource('class {}'); + // Safari 9 and Edge 13- bugs + if (klass && !/constructor|function/.test(klass)) assert.true(isConstructor(klass), 'class'); + const Gen = fromSource('function * () {}'); + // V8 ~ Chrome 49- bug + if (Gen) try { + new Gen(); + } catch { + assert.false(isConstructor(Gen), 'gen'); + } + const asyncFunc = fromSource('async function () {}'); + if (asyncFunc) assert.false(isConstructor(asyncFunc), 'asyncFunc'); + const asyncGen = fromSource('async * function () {}'); + if (asyncGen) assert.false(isConstructor(asyncGen), 'asyncGen'); + const method = fromSource('({f(){}}).f'); + // Safari 9 bug + if (method && !/function/.test(method)) assert.false(isConstructor(method), 'method'); +}); diff --git a/tests/unit-pure/esnext.function.metadata.js b/tests/unit-pure/esnext.function.metadata.js new file mode 100644 index 000000000000..b9142f8d9238 --- /dev/null +++ b/tests/unit-pure/esnext.function.metadata.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/actual/symbol'; + +QUnit.test('Function#@@metadata', assert => { + assert.true(Symbol.metadata in Function.prototype); + assert.same(Function.prototype[Symbol.metadata], null, 'is null'); +}); diff --git a/tests/unit-pure/esnext.function.un-this.js b/tests/unit-pure/esnext.function.un-this.js new file mode 100644 index 000000000000..35f567d5045d --- /dev/null +++ b/tests/unit-pure/esnext.function.un-this.js @@ -0,0 +1,8 @@ +import unThis from 'core-js-pure/full/function/un-this'; + +QUnit.test('Function#unThis', assert => { + assert.isFunction(unThis); + // eslint-disable-next-line prefer-arrow-callback -- required for testing + assert.same(unThis(function () { return 42; })(), 42); + assert.deepEqual(unThis(Array.prototype.slice)([1, 2, 3], 1), [2, 3]); +}); diff --git a/tests/unit-pure/esnext.iterator.as-indexed-pairs.js b/tests/unit-pure/esnext.iterator.as-indexed-pairs.js new file mode 100644 index 000000000000..22b8107e47df --- /dev/null +++ b/tests/unit-pure/esnext.iterator.as-indexed-pairs.js @@ -0,0 +1,22 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/full/iterator'; + +QUnit.test('Iterator#asIndexedPairs', assert => { + const { asIndexedPairs } = Iterator.prototype; + + assert.isFunction(asIndexedPairs); + assert.arity(asIndexedPairs, 0); + assert.nonEnumerable(Iterator.prototype, 'asIndexedPairs'); + + assert.arrayEqual(asIndexedPairs.call(createIterator(['a', 'b', 'c'])).toArray().toString(), '0,a,1,b,2,c', 'basic functionality'); + + if (STRICT) { + assert.throws(() => asIndexedPairs.call(undefined), TypeError); + assert.throws(() => asIndexedPairs.call(null), TypeError); + } + + assert.throws(() => asIndexedPairs.call({}).next(), TypeError); + assert.throws(() => asIndexedPairs.call([]).next(), TypeError); +}); diff --git a/tests/unit-pure/esnext.iterator.chunks.js b/tests/unit-pure/esnext.iterator.chunks.js new file mode 100644 index 000000000000..e6720172e6f0 --- /dev/null +++ b/tests/unit-pure/esnext.iterator.chunks.js @@ -0,0 +1,46 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/full/iterator/index'; +import from from 'core-js-pure/es/array/from'; + +QUnit.test('Iterator#chunks', assert => { + const { chunks } = Iterator.prototype; + assert.isFunction(chunks); + assert.arity(chunks, 1); + assert.name(chunks, 'chunks'); + assert.nonEnumerable(Iterator.prototype, 'chunks'); + + assert.arrayEqual(from(chunks.call(createIterator([1, 2, 3]), 2)), [[1, 2], [3]], 'basic functionality #1'); + assert.arrayEqual(from(chunks.call(createIterator([1, 2, 3, 4]), 2)), [[1, 2], [3, 4]], 'basic functionality #2'); + assert.arrayEqual(from(chunks.call(createIterator([]), 2)), [], 'basic functionality on empty iterable'); + + const it = createIterator([1, 2, 3]); + const result = chunks.call(it, 3); + assert.isIterable(result, 'returns iterable'); + assert.isIterator(result, 'returns iterator'); + assert.true(result instanceof Iterator, 'returns iterator'); + assert.deepEqual(result.next(), { done: false, value: [1, 2, 3] }, '.next with active inner iterator result'); + assert.deepEqual(result.return(), { done: true, value: undefined }, '.return with active inner iterator result'); + assert.deepEqual(result.next(), { done: true, value: undefined }, '.return with active inner iterator result on closed iterator'); + + if (STRICT) { + assert.throws(() => chunks.call('', 1), TypeError, 'iterable non-object this'); + assert.throws(() => chunks.call(undefined, 1), TypeError, 'non-iterable-object this #1'); + assert.throws(() => chunks.call(null, 1), TypeError, 'non-iterable-object this #2'); + assert.throws(() => chunks.call(5, 1), TypeError, 'non-iterable-object this #3'); + } + + assert.throws(() => chunks.call(it), RangeError, 'throws on empty argument'); + assert.throws(() => chunks.call(it, -1), RangeError, 'throws on negative argument'); + + const observableReturn = { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }; + const itObservable = createIterator([1, 2, 3], observableReturn); + assert.throws(() => chunks.call(itObservable, 0x100000000), RangeError, 'throws on argument more then 2^32 - 1'); + assert.true(itObservable.called, 'iterator closed on argument validation error'); +}); diff --git a/tests/unit-pure/esnext.iterator.indexed.js b/tests/unit-pure/esnext.iterator.indexed.js new file mode 100644 index 000000000000..de2ee538e9f4 --- /dev/null +++ b/tests/unit-pure/esnext.iterator.indexed.js @@ -0,0 +1,22 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/full/iterator'; + +QUnit.test('Iterator#indexed', assert => { + const { indexed } = Iterator.prototype; + + assert.isFunction(indexed); + assert.arity(indexed, 0); + assert.nonEnumerable(Iterator.prototype, 'indexed'); + + assert.arrayEqual(indexed.call(createIterator(['a', 'b', 'c'])).toArray().toString(), '0,a,1,b,2,c', 'basic functionality'); + + if (STRICT) { + assert.throws(() => indexed.call(undefined), TypeError); + assert.throws(() => indexed.call(null), TypeError); + } + + assert.throws(() => indexed.call({}).next(), TypeError); + assert.throws(() => indexed.call([]).next(), TypeError); +}); diff --git a/tests/unit-pure/esnext.iterator.range.js b/tests/unit-pure/esnext.iterator.range.js new file mode 100644 index 000000000000..7f97632a5a20 --- /dev/null +++ b/tests/unit-pure/esnext.iterator.range.js @@ -0,0 +1,128 @@ +/* eslint-disable es/no-bigint -- safe */ +import { MAX_SAFE_INTEGER } from '../helpers/constants.js'; +import from from 'core-js-pure/es/array/from'; +import range from 'core-js-pure/full/iterator/range'; + +QUnit.test('Iterator.range', assert => { + assert.isFunction(range); + assert.name(range, 'range'); + assert.arity(range, 3); + + let iterator = range(1, 2); + + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: 1, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.deepEqual(from(range(-1, 5)), [-1, 0, 1, 2, 3, 4]); + assert.deepEqual(from(range(-5, 1)), [-5, -4, -3, -2, -1, 0]); + assert.deepEqual( + from(range(0, 1, 0.1)), + [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9], + ); + assert.deepEqual( + from(range(MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1, { inclusive: true })), + [MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1], + ); + assert.deepEqual(from(range(0, 0)), []); + assert.deepEqual(from(range(0, -5, 1)), []); + + assert.deepEqual(from(range(NaN, 0)), []); + assert.deepEqual(from(range(0, NaN)), []); + assert.deepEqual(from(range(NaN, NaN)), []); + assert.deepEqual(from(range(0, 0, { step: NaN })), []); + assert.deepEqual(from(range(0, 5, NaN)), []); + + iterator = range(1, 3); + assert.deepEqual(iterator.start, 1); + assert.deepEqual(iterator.end, 3); + assert.deepEqual(iterator.step, 1); + assert.false(iterator.inclusive); + + iterator = range(-1, -3, { inclusive: true }); + assert.deepEqual(iterator.start, -1); + assert.deepEqual(iterator.end, -3); + assert.same(iterator.step, -1); + assert.true(iterator.inclusive); + + iterator = range(-1, -3, { step: 4, inclusive() { /* empty */ } }); + assert.same(iterator.start, -1); + assert.same(iterator.end, -3); + assert.same(iterator.step, 4); + assert.true(iterator.inclusive); + + iterator = range(0, 5); + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + assert.throws(() => Object.getOwnPropertyDescriptor(iterator, 'start').get.call({}), TypeError); + + assert.throws(() => range(Infinity, 10, 0), RangeError); + assert.throws(() => range(-Infinity, 10, 0), RangeError); + assert.throws(() => range(0, 10, Infinity), RangeError); + assert.throws(() => range(0, 10, { step: Infinity }), RangeError); + + assert.throws(() => range({}, 1), TypeError); + assert.throws(() => range(1, {}), TypeError); + assert.throws(() => range('1', 2), TypeError); + assert.throws(() => range({ valueOf() { return 1; } }, 2), TypeError); + + if (typeof BigInt == 'function') { + iterator = range(BigInt(1), BigInt(2)); + + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: BigInt(1), + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.deepEqual(from(range(BigInt(-1), BigInt(5))), [BigInt(-1), BigInt(0), BigInt(1), BigInt(2), BigInt(3), BigInt(4)]); + assert.deepEqual(from(range(BigInt(-5), BigInt(1))), [BigInt(-5), BigInt(-4), BigInt(-3), BigInt(-2), BigInt(-1), BigInt(0)]); + assert.deepEqual( + from(range(BigInt('9007199254740991'), BigInt('9007199254740992'), { inclusive: true })), + [BigInt('9007199254740991'), BigInt('9007199254740992')], + ); + assert.deepEqual(from(range(BigInt(0), BigInt(0))), []); + assert.deepEqual(from(range(BigInt(0), BigInt(-5), BigInt(1))), []); + + iterator = range(BigInt(1), BigInt(3)); + assert.deepEqual(iterator.start, BigInt(1)); + assert.deepEqual(iterator.end, BigInt(3)); + assert.deepEqual(iterator.step, BigInt(1)); + assert.false(iterator.inclusive); + + iterator = range(BigInt(-1), BigInt(-3), { inclusive: true }); + assert.deepEqual(iterator.start, BigInt(-1)); + assert.deepEqual(iterator.end, BigInt(-3)); + assert.same(iterator.step, BigInt(-1)); + assert.true(iterator.inclusive); + + iterator = range(BigInt(-1), BigInt(-3), { step: BigInt(4), inclusive() { /* empty */ } }); + assert.same(iterator.start, BigInt(-1)); + assert.same(iterator.end, BigInt(-3)); + assert.same(iterator.step, BigInt(4)); + assert.true(iterator.inclusive); + + iterator = range(BigInt(0), BigInt(5)); + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + assert.throws(() => Object.getOwnPropertyDescriptor(iterator, 'start').get.call({}), TypeError); + + assert.throws(() => range(Infinity, BigInt(10), BigInt(0)), TypeError); + assert.throws(() => range(-Infinity, BigInt(10), BigInt(0)), TypeError); + assert.throws(() => range(BigInt(0), BigInt(10), Infinity), TypeError); + assert.throws(() => range(BigInt(0), BigInt(10), { step: Infinity }), TypeError); + + assert.throws(() => range({}, BigInt(1)), TypeError); + assert.throws(() => range(BigInt(1), {}), TypeError); + } +}); diff --git a/tests/unit-pure/esnext.iterator.sliding.js b/tests/unit-pure/esnext.iterator.sliding.js new file mode 100644 index 000000000000..c098f55ad0e6 --- /dev/null +++ b/tests/unit-pure/esnext.iterator.sliding.js @@ -0,0 +1,47 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/full/iterator/index'; +import from from 'core-js-pure/es/array/from'; + +QUnit.test('Iterator#sliding', assert => { + const { sliding } = Iterator.prototype; + assert.isFunction(sliding); + assert.arity(sliding, 1); + assert.name(sliding, 'sliding'); + assert.nonEnumerable(Iterator.prototype, 'sliding'); + + assert.arrayEqual(from(sliding.call(createIterator([1, 2, 3]), 2)), [[1, 2], [2, 3]], 'basic functionality #1'); + assert.arrayEqual(from(sliding.call(createIterator([1, 2, 3, 4]), 2)), [[1, 2], [2, 3], [3, 4]], 'basic functionality #2'); + assert.arrayEqual(from(sliding.call(createIterator([1, 2]), 3)), [[1, 2]], 'basic functionality #3'); + assert.arrayEqual(from(sliding.call(createIterator([]), 2)), [], 'basic functionality on empty iterable'); + + const it = createIterator([1, 2, 3]); + const result = sliding.call(it, 3); + assert.isIterable(result, 'returns iterable'); + assert.isIterator(result, 'returns iterator'); + assert.true(result instanceof Iterator, 'returns iterator'); + assert.deepEqual(result.next(), { done: false, value: [1, 2, 3] }, '.next with active inner iterator result'); + assert.deepEqual(result.return(), { done: true, value: undefined }, '.return with active inner iterator result'); + assert.deepEqual(result.next(), { done: true, value: undefined }, '.return with active inner iterator result on closed iterator'); + + if (STRICT) { + assert.throws(() => sliding.call('', 1), TypeError, 'iterable non-object this'); + assert.throws(() => sliding.call(undefined, 1), TypeError, 'non-iterable-object this #1'); + assert.throws(() => sliding.call(null, 1), TypeError, 'non-iterable-object this #2'); + assert.throws(() => sliding.call(5, 1), TypeError, 'non-iterable-object this #3'); + } + + assert.throws(() => sliding.call(it), RangeError, 'throws on empty argument'); + assert.throws(() => sliding.call(it, -1), RangeError, 'throws on negative argument'); + + const observableReturn = { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }; + const itObservable = createIterator([1, 2, 3], observableReturn); + assert.throws(() => sliding.call(itObservable, 0x100000000), RangeError, 'throws on argument more then 2^32 - 1'); + assert.true(itObservable.called, 'iterator closed on argument validation error'); +}); diff --git a/tests/unit-pure/esnext.iterator.to-async.js b/tests/unit-pure/esnext.iterator.to-async.js new file mode 100644 index 000000000000..c46a5160dd22 --- /dev/null +++ b/tests/unit-pure/esnext.iterator.to-async.js @@ -0,0 +1,45 @@ +import { STRICT } from '../helpers/constants.js'; + +import Promise from 'core-js-pure/es/promise'; +import Set from 'core-js-pure/es/set'; +import ITERATOR from 'core-js-pure/es/symbol/iterator'; +import Iterator from 'core-js-pure/actual/iterator'; +import 'core-js-pure/actual/async-iterator'; + +QUnit.test('Iterator#toAsync', assert => { + const { toAsync } = Iterator.prototype; + + assert.isFunction(toAsync); + assert.arity(toAsync, 0); + + if (STRICT) { + assert.throws(() => toAsync.call(undefined), TypeError); + assert.throws(() => toAsync.call(null), TypeError); + } + + const closableIterator = { + closed: false, + [ITERATOR]() { return this; }, + next() { + return { value: Promise.reject(42), done: false }; + }, + return() { + this.closed = true; + return { value: undefined, done: true }; + }, + }; + + return Iterator.from([1, 2, 3]).toAsync().map(it => Promise.resolve(it)).toArray().then(it => { + assert.arrayEqual(it, [1, 2, 3]); + return Iterator.from(new Set([1, 2, 3])).toAsync().map(el => Promise.resolve(el)).toArray(); + }).then(it => { + assert.arrayEqual(it, [1, 2, 3]); + }).then(() => { + return Iterator.from(closableIterator).toAsync().toArray(); + }).then(() => { + assert.avoid(); + }, error => { + assert.same(error, 42, 'rejection on a callback error'); + assert.true(closableIterator.closed, 'doesn\'t close sync iterator on promise rejection'); + }); +}); diff --git a/tests/unit-pure/esnext.iterator.windows.js b/tests/unit-pure/esnext.iterator.windows.js new file mode 100644 index 000000000000..7aff209fc386 --- /dev/null +++ b/tests/unit-pure/esnext.iterator.windows.js @@ -0,0 +1,53 @@ +import { STRICT } from '../helpers/constants.js'; +import { createIterator } from '../helpers/helpers.js'; + +import Iterator from 'core-js-pure/full/iterator/index'; +import from from 'core-js-pure/es/array/from'; + +QUnit.test('Iterator#windows', assert => { + const { windows } = Iterator.prototype; + assert.isFunction(windows); + assert.arity(windows, 1); + assert.name(windows, 'windows'); + assert.nonEnumerable(Iterator.prototype, 'windows'); + + assert.arrayEqual(from(windows.call(createIterator([1, 2, 3]), 2)), [[1, 2], [2, 3]], 'basic functionality #1'); + assert.arrayEqual(from(windows.call(createIterator([1, 2, 3, 4]), 2)), [[1, 2], [2, 3], [3, 4]], 'basic functionality #2'); + assert.arrayEqual(from(windows.call(createIterator([1, 2]), 3)), [], 'basic functionality #3'); + assert.arrayEqual(from(windows.call(createIterator([]), 2)), [], 'basic functionality on empty iterable'); + + assert.arrayEqual(from(windows.call(createIterator([1, 2]), 3, 'only-full')), [], 'undersized #1'); + assert.arrayEqual(from(windows.call(createIterator([1, 2]), 3, 'allow-partial')), [[1, 2]], 'undersized #2'); + + const it = createIterator([1, 2, 3]); + const result = windows.call(it, 3); + assert.isIterable(result, 'returns iterable'); + assert.isIterator(result, 'returns iterator'); + assert.true(result instanceof Iterator, 'returns iterator'); + assert.deepEqual(result.next(), { done: false, value: [1, 2, 3] }, '.next with active inner iterator result'); + assert.deepEqual(result.return(), { done: true, value: undefined }, '.return with active inner iterator result'); + assert.deepEqual(result.next(), { done: true, value: undefined }, '.return with active inner iterator result on closed iterator'); + + if (STRICT) { + assert.throws(() => windows.call('', 1), TypeError, 'iterable non-object this'); + assert.throws(() => windows.call(undefined, 1), TypeError, 'non-iterable-object this #1'); + assert.throws(() => windows.call(null, 1), TypeError, 'non-iterable-object this #2'); + assert.throws(() => windows.call(5, 1), TypeError, 'non-iterable-object this #3'); + } + + assert.throws(() => windows.call(it), RangeError, 'throws on empty argument'); + assert.throws(() => windows.call(it, -1), RangeError, 'throws on negative argument'); + + const observableReturn = { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }; + const itObservable = createIterator([1, 2, 3], observableReturn); + assert.throws(() => windows.call(itObservable, 0x100000000), RangeError, 'throws on argument more then 2^32 - 1'); + assert.true(itObservable.called, 'iterator closed on argument validation error'); + + assert.throws(() => windows.call(createIterator([1]), 2, null), TypeError, 'incorrect `undersized` argument #1'); + assert.throws(() => windows.call(createIterator([1]), 2, 'allowpartial'), TypeError, 'incorrect `undersized` argument #2'); +}); diff --git a/tests/unit-pure/esnext.iterator.zip-keyed.js b/tests/unit-pure/esnext.iterator.zip-keyed.js new file mode 100644 index 000000000000..06bdaba30d10 --- /dev/null +++ b/tests/unit-pure/esnext.iterator.zip-keyed.js @@ -0,0 +1,101 @@ +import { createIterator } from '../helpers/helpers.js'; +import { DESCRIPTORS } from '../helpers/constants.js'; + +import defineProperty from 'core-js-pure/actual/object/define-property'; +import from from 'core-js-pure/es/array/from'; +import assign from 'core-js-pure/es/object/assign'; +import create from 'core-js-pure/es/object/create'; +import Symbol from 'core-js-pure/es/symbol'; +import zipKeyed from 'core-js-pure/actual/iterator/zip-keyed'; + +function nullProto(obj) { + return assign(create(null), obj); +} + +QUnit.test('Iterator.zipKeyed', assert => { + assert.isFunction(zipKeyed); + assert.arity(zipKeyed, 1); + assert.name(zipKeyed, 'zipKeyed'); + + let result = zipKeyed({ a: [0, 1, 2], b: [3, 4, 5], c: [7, 8, 9] }); + assert.deepEqual(from(result), [{ a: 0, b: 3, c: 7 }, { a: 1, b: 4, c: 8 }, { a: 2, b: 5, c: 9 }]); + result = zipKeyed({ a: [0, 1, 2], b: [3, 4, 5, 6], c: [7, 8, 9] }); + assert.deepEqual(from(result), [{ a: 0, b: 3, c: 7 }, { a: 1, b: 4, c: 8 }, { a: 2, b: 5, c: 9 }]); + result = zipKeyed({ a: [0, 1, 2], b: [3, 4, 5, 6], c: [7, 8, 9] }, { mode: 'longest', padding: { c: 10 } }); + assert.deepEqual(from(result), [{ a: 0, b: 3, c: 7 }, { a: 1, b: 4, c: 8 }, { a: 2, b: 5, c: 9 }, { a: undefined, b: 6, c: 10 }]); + result = zipKeyed({ a: [0, 1, 2], b: [3, 4, 5, 6], c: [7, 8, 9] }, { mode: 'strict' }); + assert.throws(() => from(result), TypeError); + + if (DESCRIPTORS) { + let obj = {}; + defineProperty(obj, 'a', { get: () => [0, 1, 2], enumerable: true }); + defineProperty(obj, 'b', { get: () => [3, 4, 5], enumerable: true }); + defineProperty(obj, 'c', { get: () => [7, 8, 9], enumerable: true }); + defineProperty(obj, Symbol('d'), { get: () => [10, 11, 12] }); + assert.deepEqual(from(zipKeyed(obj)), [{ a: 0, b: 3, c: 7 }, { a: 1, b: 4, c: 8 }, { a: 2, b: 5, c: 9 }]); + + const it = createIterator([1, 2], { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }); + obj = { a: it }; + defineProperty(obj, 'b', { get: () => { throw new Error(); }, enumerable: true }); + assert.throws(() => from(zipKeyed(obj)), Error); + assert.true(it.called, 'iterator return called'); + + const foo = Symbol('foo'); + const bar = Symbol('bar'); + const zipped = zipKeyed({ [foo]: [1, 2, 3], [bar]: [4, 5, 6], baz: [7, 8, 9] }); + result = from(zipped); + assert.same(result[0][foo], 1); + assert.same(result[0][bar], 4); + assert.same(result[0].baz, 7); + + assert.same(result[1][foo], 2); + assert.same(result[1][bar], 5); + assert.same(result[1].baz, 8); + + assert.same(result[2][foo], 3); + assert.same(result[2][bar], 6); + assert.same(result[2].baz, 9); + } + + { + const $result = zipKeyed({ + a: [0, 1, 2], + b: [3, 4, 5, 6, 7], + c: [8, 9], + }, { + mode: 'longest', + }); + + assert.deepEqual(from($result), [ + nullProto({ a: 0, b: 3, c: 8 }), + nullProto({ a: 1, b: 4, c: 9 }), + nullProto({ a: 2, b: 5, c: undefined }), + nullProto({ a: undefined, b: 6, c: undefined }), + nullProto({ a: undefined, b: 7, c: undefined }), + ]); + } + + { + const $result = zipKeyed({ + a: [0, 1, 2], + b: [3, 4, 5, 6, 7], + c: [8, 9], + }, { + mode: 'longest', + padding: { a: 'A', b: 'B', c: 'C' }, + }); + + assert.deepEqual(from($result), [ + nullProto({ a: 0, b: 3, c: 8 }), + nullProto({ a: 1, b: 4, c: 9 }), + nullProto({ a: 2, b: 5, c: 'C' }), + nullProto({ a: 'A', b: 6, c: 'C' }), + nullProto({ a: 'A', b: 7, c: 'C' }), + ]); + } +}); diff --git a/tests/unit-pure/esnext.iterator.zip.js b/tests/unit-pure/esnext.iterator.zip.js new file mode 100644 index 000000000000..87b0171e3312 --- /dev/null +++ b/tests/unit-pure/esnext.iterator.zip.js @@ -0,0 +1,100 @@ +import { createIterator } from '../helpers/helpers.js'; + +import from from 'core-js-pure/es/array/from'; +import zip from 'core-js-pure/actual/iterator/zip'; + +QUnit.test('Iterator.zip', assert => { + assert.isFunction(zip); + assert.arity(zip, 1); + assert.name(zip, 'zip'); + + let result = zip([[1, 2, 3], [4, 5, 6]]); + assert.deepEqual(from(result), [[1, 4], [2, 5], [3, 6]]); + result = zip([[1, 2, 3], [4, 5, 6, 7]]); + assert.deepEqual(from(result), [[1, 4], [2, 5], [3, 6]]); + result = zip([[1, 2, 3], [4, 5, 6, 7]], { mode: 'longest', padding: [9] }); + assert.deepEqual(from(result), [[1, 4], [2, 5], [3, 6], [9, 7]]); + result = zip([[1, 2, 3, 4], [5, 6, 7]], { mode: 'longest', padding: [1, 9] }); + assert.deepEqual(from(result), [[1, 5], [2, 6], [3, 7], [4, 9]]); + result = zip([[1, 2, 3], [4, 5, 6], [7, 8, 9]], { mode: 'strict' }); + assert.deepEqual(from(result), [[1, 4, 7], [2, 5, 8], [3, 6, 9]]); + result = zip([[1, 2, 3], [4, 5, 6, 7]], { mode: 'strict' }); + assert.throws(() => from(result), TypeError); + + const observableReturn = { + return() { + this.called = true; + return { done: true, value: undefined }; + }, + }; + + { + const it1 = createIterator([1, 2], observableReturn); + const it2 = createIterator([3, 4], observableReturn); + result = zip([it1, it2]); + assert.deepEqual(result.next().value, [1, 3]); + assert.deepEqual(result.return(), { done: true, value: undefined }); + assert.deepEqual(result.next(), { done: true, value: undefined }); + assert.true(it1.called, 'first iterator return called'); + assert.true(it2.called, 'second iterator return called'); + } + + { + const it = createIterator([1, 2, 3], observableReturn); + result = zip([it, [4, 5]], { mode: 'strict' }); + assert.throws(() => from(result), TypeError); + assert.true(it.called, 'iterator return called #1'); + } + + { + const it = createIterator([3, 4, 5], observableReturn); + result = zip([[1, 2], it], { mode: 'strict' }); + assert.throws(() => from(result), TypeError); + assert.true(it.called, 'iterator return called #2'); + } + + { + const it1 = createIterator([1, 2], { next() { throw new Error(); } }); + const it2 = createIterator([3, 4], observableReturn); + result = zip([it1, it2]); + assert.throws(() => from(result), Error); + assert.true(it2.called, 'iterator return called #4'); + } + + { + const $result = zip([ + [0, 1, 2], + [3, 4, 5, 6, 7], + [8, 9], + ], { + mode: 'longest', + }); + + assert.deepEqual(from($result), [ + [0, 3, 8], + [1, 4, 9], + [2, 5, undefined], + [undefined, 6, undefined], + [undefined, 7, undefined], + ]); + } + + { + const $result = zip([ + [0, 1, 2], + [3, 4, 5, 6, 7], + [8, 9], + ], { + mode: 'longest', + padding: ['A', 'B', 'C'], + }); + + assert.deepEqual(from($result), [ + [0, 3, 8], + [1, 4, 9], + [2, 5, 'C'], + ['A', 6, 'C'], + ['A', 7, 'C'], + ]); + } +}); diff --git a/tests/unit-pure/esnext.map.delete-all.js b/tests/unit-pure/esnext.map.delete-all.js new file mode 100644 index 000000000000..01cdf3007439 --- /dev/null +++ b/tests/unit-pure/esnext.map.delete-all.js @@ -0,0 +1,31 @@ +import from from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#deleteAll', assert => { + const { deleteAll } = Map.prototype; + + assert.isFunction(deleteAll); + assert.arity(deleteAll, 0); + assert.nonEnumerable(Map.prototype, 'deleteAll'); + + let set = new Map([[1, 2], [2, 3], [3, 4]]); + assert.true(set.deleteAll(1, 2)); + assert.deepEqual(from(set), [[3, 4]]); + + set = new Map([[1, 2], [2, 3], [3, 4]]); + assert.false(set.deleteAll(3, 4)); + assert.deepEqual(from(set), [[1, 2], [2, 3]]); + + set = new Map([[1, 2], [2, 3], [3, 4]]); + assert.false(set.deleteAll(4, 5)); + assert.deepEqual(from(set), [[1, 2], [2, 3], [3, 4]]); + + set = new Map([[1, 2], [2, 3], [3, 4]]); + assert.true(set.deleteAll()); + assert.deepEqual(from(set), [[1, 2], [2, 3], [3, 4]]); + + assert.throws(() => deleteAll.call({ delete() { /* empty */ } }, 1, 2, 3)); + assert.throws(() => deleteAll.call({}, 1, 2, 3), TypeError); + assert.throws(() => deleteAll.call(undefined, 1, 2, 3), TypeError); + assert.throws(() => deleteAll.call(null, 1, 2, 3), TypeError); +}); diff --git a/tests/unit-pure/esnext.map.emplace.js b/tests/unit-pure/esnext.map.emplace.js new file mode 100644 index 000000000000..00b411189ba5 --- /dev/null +++ b/tests/unit-pure/esnext.map.emplace.js @@ -0,0 +1,51 @@ +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#emplace', assert => { + const { emplace } = Map.prototype; + assert.isFunction(emplace); + assert.arity(emplace, 2); + assert.name(emplace, 'emplace'); + assert.nonEnumerable(Map.prototype, 'emplace'); + + const map = new Map([['a', 2]]); + let handler = { + update(value, key, that) { + assert.same(this, handler, 'correct handler in callback'); + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, 'a', 'correct key in callback'); + assert.same(that, map, 'correct map in callback'); + return value ** 2; + }, + insert() { + assert.avoid(); + }, + }; + assert.same(map.emplace('a', handler), 4, 'returns a correct value'); + handler = { + update() { + assert.avoid(); + }, + insert(key, that) { + assert.same(this, handler, 'correct handler in callback'); + assert.same(arguments.length, 2, 'correct number of callback arguments'); + assert.same(key, 'b', 'correct key in callback'); + assert.same(that, map, 'correct map in callback'); + return 3; + }, + }; + assert.same(map.emplace('b', handler), 3, 'returns a correct value'); + assert.same(map.size, 2, 'correct size'); + assert.same(map.get('a'), 4, 'correct result #1'); + assert.same(map.get('b'), 3, 'correct result #2'); + + assert.same(new Map([['a', 2]]).emplace('b', { insert: () => 3 }), 3); + assert.same(new Map([['a', 2]]).emplace('a', { update: value => value ** 2 }), 4); + + handler = { update() { /* empty */ }, insert() { /* empty */ } }; + assert.throws(() => new Map().emplace('a'), TypeError); + assert.throws(() => emplace.call({}, 'a', handler), TypeError); + assert.throws(() => emplace.call([], 'a', handler), TypeError); + assert.throws(() => emplace.call(undefined, 'a', handler), TypeError); + assert.throws(() => emplace.call(null, 'a', handler), TypeError); +}); diff --git a/tests/unit-pure/esnext.map.every.js b/tests/unit-pure/esnext.map.every.js new file mode 100644 index 000000000000..b2c08ed6318f --- /dev/null +++ b/tests/unit-pure/esnext.map.every.js @@ -0,0 +1,35 @@ +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#every', assert => { + const { every } = Map.prototype; + assert.isFunction(every); + assert.arity(every, 1); + assert.name(every, 'every'); + assert.nonEnumerable(Map.prototype, 'every'); + + let map = new Map([[9, 1]]); + const context = {}; + map.every(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 9, 'correct index in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + map = new Map([[0, 1], [1, 2], [2, 3]]); + assert.true(map.every(it => typeof it == 'number')); + assert.true(map.every(it => it < 4)); + assert.false(map.every(it => it < 3)); + assert.false(map.every(it => typeof it == 'string')); + assert.true(map.every(function () { + return +this === 1; + }, 1)); + let result = ''; + map.every((value, key) => result += key); + assert.same(result, '012'); + assert.true(map.every((value, key, that) => that === map)); + + assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.map.filter.js b/tests/unit-pure/esnext.map.filter.js new file mode 100644 index 000000000000..acc477c2f6e5 --- /dev/null +++ b/tests/unit-pure/esnext.map.filter.js @@ -0,0 +1,44 @@ +import from from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#filter', assert => { + const { filter } = Map.prototype; + + assert.isFunction(filter); + assert.arity(filter, 1); + assert.name(filter, 'filter'); + assert.nonEnumerable(Map.prototype, 'filter'); + + const map = new Map([[1, 2]]); + const context = {}; + map.filter(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.deepEqual(from(new Map([ + ['a', 1], + [1, 2], + ['b', 3], + [2, 'q'], + ['c', {}], + [3, 4], + ['d', true], + [4, 5], + ]).filter(it => typeof it == 'number')), [ + ['a', 1], + [1, 2], + ['b', 3], + [3, 4], + [4, 5], + ]); + + assert.true(new Map().filter(it => it) instanceof Map); + + assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/pure/esnext.map.find-key.js b/tests/unit-pure/esnext.map.find-key.js similarity index 95% rename from tests/pure/esnext.map.find-key.js rename to tests/unit-pure/esnext.map.find-key.js index 91fee1f87566..f7f939250c52 100644 --- a/tests/pure/esnext.map.find-key.js +++ b/tests/unit-pure/esnext.map.find-key.js @@ -1,4 +1,4 @@ -import Map from 'core-js-pure/features/map'; +import Map from 'core-js-pure/full/map'; QUnit.test('Map#findKey', assert => { const { findKey } = Map.prototype; diff --git a/tests/pure/esnext.map.find.js b/tests/unit-pure/esnext.map.find.js similarity index 95% rename from tests/pure/esnext.map.find.js rename to tests/unit-pure/esnext.map.find.js index 5783dca1cd18..960850858613 100644 --- a/tests/pure/esnext.map.find.js +++ b/tests/unit-pure/esnext.map.find.js @@ -1,4 +1,4 @@ -import Map from 'core-js-pure/features/map'; +import Map from 'core-js-pure/full/map'; QUnit.test('Map#find', assert => { const { find } = Map.prototype; diff --git a/tests/unit-pure/esnext.map.from.js b/tests/unit-pure/esnext.map.from.js new file mode 100644 index 000000000000..6c0ebf36dc27 --- /dev/null +++ b/tests/unit-pure/esnext.map.from.js @@ -0,0 +1,23 @@ +import { createIterable } from '../helpers/helpers.js'; + +import toArray from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map.from', assert => { + const { from } = Map; + assert.isFunction(from); + assert.arity(from, 1); + assert.true(from([]) instanceof Map); + assert.deepEqual(toArray(from([])), []); + assert.deepEqual(toArray(from([[1, 2]])), [[1, 2]]); + assert.deepEqual(toArray(from([[1, 2], [2, 3], [1, 4]])), [[1, 4], [2, 3]]); + assert.deepEqual(toArray(from(createIterable([[1, 2], [2, 3], [1, 4]]))), [[1, 4], [2, 3]]); + const pair = [1, 2]; + const context = {}; + from([pair], function (element, index) { + assert.same(element, pair); + assert.same(index, 0); + assert.same(this, context); + return element; + }, context); +}); diff --git a/tests/unit-pure/esnext.map.get-or-insert-computed.js b/tests/unit-pure/esnext.map.get-or-insert-computed.js new file mode 100644 index 000000000000..3de55ad6dc19 --- /dev/null +++ b/tests/unit-pure/esnext.map.get-or-insert-computed.js @@ -0,0 +1,41 @@ +import { STRICT } from '../helpers/constants.js'; +import Map from 'core-js-pure/actual/map'; +import from from 'core-js-pure/es/array/from'; + +QUnit.test('Map#getOrInsertComputed', assert => { + const { getOrInsertComputed } = Map.prototype; + assert.isFunction(getOrInsertComputed); + assert.arity(getOrInsertComputed, 2); + assert.name(getOrInsertComputed, 'getOrInsertComputed'); + assert.nonEnumerable(Map.prototype, 'getOrInsertComputed'); + + let map = new Map([['a', 2]]); + assert.same(map.getOrInsertComputed('a', () => 3), 2, 'result#1'); + assert.deepEqual(from(map), [['a', 2]], 'map#1'); + map = new Map([['a', 2]]); + assert.same(map.getOrInsertComputed('b', () => 3), 3, 'result#2'); + assert.deepEqual(from(map), [['a', 2], ['b', 3]], 'map#2'); + + map = new Map([['a', 2]]); + map.getOrInsertComputed('a', () => assert.avoid()); + + map = new Map([['a', 2]]); + map.getOrInsertComputed('b', function (key) { + if (STRICT) assert.same(this, undefined, 'correct handler in callback'); + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(key, 'b', 'correct key in callback'); + }); + + map = new Map([['a', 2]]); + map.getOrInsertComputed(-0, key => assert.same(key, 0, 'CanonicalizeKeyedCollectionKey')); + + assert.throws(() => new Map().getOrInsertComputed('a', {}), TypeError, 'non-callable#1'); + assert.throws(() => new Map().getOrInsertComputed('a', 1), TypeError, 'non-callable#2'); + assert.throws(() => new Map().getOrInsertComputed('a', null), TypeError, 'non-callable#3'); + assert.throws(() => new Map().getOrInsertComputed('a', undefined), TypeError, 'non-callable#4'); + assert.throws(() => new Map().getOrInsertComputed('a'), TypeError, 'non-callable#5'); + assert.throws(() => getOrInsertComputed.call({}, 'a', () => 3), TypeError, 'non-generic#1'); + assert.throws(() => getOrInsertComputed.call([], 'a', () => 3), TypeError, 'non-generic#2'); + assert.throws(() => getOrInsertComputed.call(undefined, 'a', () => 3), TypeError, 'non-generic#3'); + assert.throws(() => getOrInsertComputed.call(null, 'a', () => 3), TypeError, 'non-generic#4'); +}); diff --git a/tests/unit-pure/esnext.map.get-or-insert.js b/tests/unit-pure/esnext.map.get-or-insert.js new file mode 100644 index 000000000000..1ed31a1464cb --- /dev/null +++ b/tests/unit-pure/esnext.map.get-or-insert.js @@ -0,0 +1,22 @@ +import Map from 'core-js-pure/actual/map'; +import from from 'core-js-pure/es/array/from'; + +QUnit.test('Map#getOrInsert', assert => { + const { getOrInsert } = Map.prototype; + assert.isFunction(getOrInsert); + assert.arity(getOrInsert, 2); + assert.name(getOrInsert, 'getOrInsert'); + assert.nonEnumerable(Map.prototype, 'getOrInsert'); + + let map = new Map([['a', 2]]); + assert.same(map.getOrInsert('a', 3), 2, 'result#1'); + assert.deepEqual(from(map), [['a', 2]], 'map#1'); + map = new Map([['a', 2]]); + assert.same(map.getOrInsert('b', 3), 3, 'result#2'); + assert.deepEqual(from(map), [['a', 2], ['b', 3]], 'map#2'); + + assert.throws(() => getOrInsert.call({}, 'a', 1), TypeError, 'non-generic#1'); + assert.throws(() => getOrInsert.call([], 'a', 1), TypeError, 'non-generic#2'); + assert.throws(() => getOrInsert.call(undefined, 'a', 1), TypeError, 'non-generic#3'); + assert.throws(() => getOrInsert.call(null, 'a', 1), TypeError, 'non-generic#4'); +}); diff --git a/tests/unit-pure/esnext.map.includes.js b/tests/unit-pure/esnext.map.includes.js new file mode 100644 index 000000000000..a1a7ff62b405 --- /dev/null +++ b/tests/unit-pure/esnext.map.includes.js @@ -0,0 +1,24 @@ +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#includes', assert => { + const { includes } = Map.prototype; + assert.isFunction(includes); + assert.name(includes, 'includes'); + assert.arity(includes, 1); + assert.nonEnumerable(Map.prototype, 'includes'); + + const object = {}; + const map = new Map([[1, 1], [2, 2], [3, 3], [4, -0], [5, object], [6, NaN]]); + assert.true(map.includes(1)); + assert.true(map.includes(-0)); + assert.true(map.includes(0)); + assert.true(map.includes(object)); + assert.false(map.includes(4)); + assert.false(map.includes(-0.5)); + assert.false(map.includes({})); + assert.true(map.includes(NaN)); + + assert.throws(() => includes.call({}, 1), TypeError); + assert.throws(() => includes.call(undefined, 1), TypeError); + assert.throws(() => includes.call(null, 1), TypeError); +}); diff --git a/tests/unit-pure/esnext.map.key-by.js b/tests/unit-pure/esnext.map.key-by.js new file mode 100644 index 000000000000..0873f7a3f5e4 --- /dev/null +++ b/tests/unit-pure/esnext.map.key-by.js @@ -0,0 +1,24 @@ +import { createIterable } from '../helpers/helpers.js'; + +import from from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map.keyBy', assert => { + const { keyBy } = Map; + + assert.isFunction(keyBy); + assert.arity(keyBy, 2); + assert.name(keyBy, 'keyBy'); + + assert.true(Map.keyBy([], it => it) instanceof Map); + + assert.deepEqual(from(Map.keyBy([], it => it)), []); + assert.deepEqual(from(Map.keyBy([1, 2], it => it ** 2)), [[1, 1], [4, 2]]); + assert.deepEqual(from(Map.keyBy([1, 2, 1], it => it ** 2)), [[1, 1], [4, 2]]); + assert.deepEqual(from(Map.keyBy(createIterable([1, 2]), it => it ** 2)), [[1, 1], [4, 2]]); + + const element = {}; + Map.keyBy([element], it => assert.same(it, element)); + + // assert.throws(() => keyBy([1, 2], it => it)); +}); diff --git a/tests/pure/esnext.map.key-of.js b/tests/unit-pure/esnext.map.key-of.js similarity index 94% rename from tests/pure/esnext.map.key-of.js rename to tests/unit-pure/esnext.map.key-of.js index 08b0e81f7ae2..841f6d80445c 100644 --- a/tests/pure/esnext.map.key-of.js +++ b/tests/unit-pure/esnext.map.key-of.js @@ -1,4 +1,4 @@ -import Map from 'core-js-pure/features/map'; +import Map from 'core-js-pure/full/map'; QUnit.test('Map#keyOf', assert => { const { keyOf } = Map.prototype; diff --git a/tests/unit-pure/esnext.map.map-keys.js b/tests/unit-pure/esnext.map.map-keys.js new file mode 100644 index 000000000000..dcf8103f020a --- /dev/null +++ b/tests/unit-pure/esnext.map.map-keys.js @@ -0,0 +1,47 @@ +import from from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#mapKeys', assert => { + const { mapKeys } = Map.prototype; + + assert.isFunction(mapKeys); + assert.arity(mapKeys, 1); + assert.name(mapKeys, 'mapKeys'); + assert.nonEnumerable(Map.prototype, 'mapKeys'); + + const map = new Map([[1, 2]]); + const context = {}; + map.mapKeys(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Map().mapKeys(it => it) instanceof Map); + + assert.deepEqual(from(new Map([ + ['a', 1], + [1, 2], + ['b', 3], + [2, 'q'], + ['c', {}], + [3, 4], + ['d', true], + [4, 5], + ]).mapKeys((value, key) => `${ key }${ value }`)), [ + ['a1', 1], + ['12', 2], + ['b3', 3], + ['2q', 'q'], + ['c[object Object]', {}], + ['34', 4], + ['dtrue', true], + ['45', 5], + ]); + + assert.throws(() => mapKeys.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => mapKeys.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => mapKeys.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.map.map-values.js b/tests/unit-pure/esnext.map.map-values.js new file mode 100644 index 000000000000..f240e4007f9d --- /dev/null +++ b/tests/unit-pure/esnext.map.map-values.js @@ -0,0 +1,47 @@ +import from from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#mapValues', assert => { + const { mapValues } = Map.prototype; + + assert.isFunction(mapValues); + assert.arity(mapValues, 1); + assert.name(mapValues, 'mapValues'); + assert.nonEnumerable(Map.prototype, 'mapValues'); + + const map = new Map([[1, 2]]); + const context = {}; + map.mapValues(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Map().mapValues(it => it) instanceof Map); + + assert.deepEqual(from(new Map([ + ['a', 1], + [1, 2], + ['b', 3], + [2, 'q'], + ['c', {}], + [3, 4], + ['d', true], + [4, 5], + ]).mapValues((value, key) => `${ key }${ value }`)), [ + ['a', 'a1'], + [1, '12'], + ['b', 'b3'], + [2, '2q'], + ['c', 'c[object Object]'], + [3, '34'], + ['d', 'dtrue'], + [4, '45'], + ]); + + assert.throws(() => mapValues.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => mapValues.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => mapValues.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.map.merge.js b/tests/unit-pure/esnext.map.merge.js new file mode 100644 index 000000000000..a3606ded4f86 --- /dev/null +++ b/tests/unit-pure/esnext.map.merge.js @@ -0,0 +1,26 @@ +import from from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#merge', assert => { + const { merge } = Map.prototype; + + assert.isFunction(merge); + assert.arity(merge, 1); + assert.name(merge, 'merge'); + assert.nonEnumerable(Map.prototype, 'merge'); + + const map = new Map([[1, 2]]); + const result = map.merge([[3, 4]]); + assert.same(result, map); + assert.true(result instanceof Map); + + assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[5, 6]])), [[1, 2], [3, 4], [5, 6]]); + assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[3, 5], [5, 6]])), [[1, 2], [3, 5], [5, 6]]); + assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([])), [[1, 2], [3, 4]]); + + assert.deepEqual(from(new Map([[1, 2], [3, 4]]).merge([[3, 5]], [[5, 6]])), [[1, 2], [3, 5], [5, 6]]); + + assert.throws(() => merge.call({}, [[1, 2]]), TypeError); + assert.throws(() => merge.call(undefined, [[1, 2]]), TypeError); + assert.throws(() => merge.call(null, [[1, 2]]), TypeError); +}); diff --git a/tests/unit-pure/esnext.map.of.js b/tests/unit-pure/esnext.map.of.js new file mode 100644 index 000000000000..e38981493476 --- /dev/null +++ b/tests/unit-pure/esnext.map.of.js @@ -0,0 +1,11 @@ +import from from 'core-js-pure/es/array/from'; +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map.of', assert => { + const { of } = Map; + assert.isFunction(of); + assert.arity(of, 0); + assert.true(of() instanceof Map); + assert.deepEqual(from(of([1, 2])), [[1, 2]]); + assert.deepEqual(from(of([1, 2], [2, 3], [1, 4])), [[1, 4], [2, 3]]); +}); diff --git a/tests/pure/esnext.map.reduce.js b/tests/unit-pure/esnext.map.reduce.js similarity index 97% rename from tests/pure/esnext.map.reduce.js rename to tests/unit-pure/esnext.map.reduce.js index aeb7f389beae..fd925c25feca 100644 --- a/tests/pure/esnext.map.reduce.js +++ b/tests/unit-pure/esnext.map.reduce.js @@ -1,4 +1,4 @@ -import Map from 'core-js-pure/features/map'; +import Map from 'core-js-pure/full/map'; QUnit.test('Map#reduce', assert => { const { reduce } = Map.prototype; diff --git a/tests/unit-pure/esnext.map.some.js b/tests/unit-pure/esnext.map.some.js new file mode 100644 index 000000000000..5efe306c97bc --- /dev/null +++ b/tests/unit-pure/esnext.map.some.js @@ -0,0 +1,38 @@ +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#some', assert => { + const { some } = Map.prototype; + assert.isFunction(some); + assert.arity(some, 1); + assert.name(some, 'some'); + assert.nonEnumerable(Map.prototype, 'some'); + + let map = new Map([[9, 1]]); + const context = {}; + map.some(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 9, 'correct index in callback'); + assert.same(that, map, 'correct link to map in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + map = new Map([[0, 1], [1, '2'], [2, 3]]); + assert.true(map.some(it => typeof it == 'number')); + assert.true(map.some(it => it < 3)); + assert.false(map.some(it => it < 0)); + assert.true(map.some(it => typeof it == 'string')); + assert.false(map.some(function () { + return +this !== 1; + }, 1)); + let result = ''; + map.some((value, key) => { + result += key; + return false; + }); + assert.same(result, '012'); + assert.true(map.some((value, key, that) => that === map)); + + assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.map.update-or-insert.js b/tests/unit-pure/esnext.map.update-or-insert.js new file mode 100644 index 000000000000..78969b41f7f1 --- /dev/null +++ b/tests/unit-pure/esnext.map.update-or-insert.js @@ -0,0 +1,37 @@ +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#updateOrInsert', assert => { + const { updateOrInsert } = Map.prototype; + assert.isFunction(updateOrInsert); + assert.arity(updateOrInsert, 2); + assert.nonEnumerable(Map.prototype, 'updateOrInsert'); + + const map = new Map([['a', 2]]); + assert.same(map.updateOrInsert('a', function (value) { + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + return value ** 2; + }, () => { + assert.avoid(); + return 3; + }), 4, 'returns a correct value'); + assert.same(map.updateOrInsert('b', value => { + assert.avoid(); + return value ** 2; + }, function () { + assert.same(arguments.length, 0, 'correct number of callback arguments'); + return 3; + }), 3, 'returns a correct value'); + assert.same(map.size, 2, 'correct size'); + assert.same(map.get('a'), 4, 'correct result #1'); + assert.same(map.get('b'), 3, 'correct result #2'); + + assert.same(new Map([['a', 2]]).updateOrInsert('b', null, () => 3), 3); + assert.same(new Map([['a', 2]]).updateOrInsert('a', value => value ** 2), 4); + + assert.throws(() => new Map().updateOrInsert('a'), TypeError); + assert.throws(() => updateOrInsert.call({}, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => updateOrInsert.call([], 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => updateOrInsert.call(undefined, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => updateOrInsert.call(null, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); +}); diff --git a/tests/pure/esnext.map.update.js b/tests/unit-pure/esnext.map.update.js similarity index 97% rename from tests/pure/esnext.map.update.js rename to tests/unit-pure/esnext.map.update.js index 2d7a0bd7efb8..bc33446306f2 100644 --- a/tests/pure/esnext.map.update.js +++ b/tests/unit-pure/esnext.map.update.js @@ -1,4 +1,4 @@ -import Map from 'core-js-pure/features/map'; +import Map from 'core-js-pure/full/map'; QUnit.test('Map#update', assert => { const { update } = Map.prototype; diff --git a/tests/unit-pure/esnext.map.upsert.js b/tests/unit-pure/esnext.map.upsert.js new file mode 100644 index 000000000000..139f34847d44 --- /dev/null +++ b/tests/unit-pure/esnext.map.upsert.js @@ -0,0 +1,37 @@ +import Map from 'core-js-pure/full/map'; + +QUnit.test('Map#upsert', assert => { + const { upsert } = Map.prototype; + assert.isFunction(upsert); + assert.arity(upsert, 2); + assert.nonEnumerable(Map.prototype, 'upsert'); + + const map = new Map([['a', 2]]); + assert.same(map.upsert('a', function (value) { + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + return value ** 2; + }, () => { + assert.avoid(); + return 3; + }), 4, 'returns a correct value'); + assert.same(map.upsert('b', value => { + assert.avoid(); + return value ** 2; + }, function () { + assert.same(arguments.length, 0, 'correct number of callback arguments'); + return 3; + }), 3, 'returns a correct value'); + assert.same(map.size, 2, 'correct size'); + assert.same(map.get('a'), 4, 'correct result #1'); + assert.same(map.get('b'), 3, 'correct result #2'); + + assert.same(new Map([['a', 2]]).upsert('b', null, () => 3), 3); + assert.same(new Map([['a', 2]]).upsert('a', value => value ** 2), 4); + + assert.throws(() => new Map().upsert('a'), TypeError); + assert.throws(() => upsert.call({}, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call([], 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call(undefined, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call(null, 'a', () => { /* empty */ }, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.math.clamp.js b/tests/unit-pure/esnext.math.clamp.js new file mode 100644 index 000000000000..226aea316ebb --- /dev/null +++ b/tests/unit-pure/esnext.math.clamp.js @@ -0,0 +1,27 @@ +import clamp from 'core-js-pure/full/math/clamp'; + +QUnit.test('Math.clamp', assert => { + assert.isFunction(clamp); + assert.arity(clamp, 3); + + assert.same(clamp(2, 4, 6), 4); + assert.same(clamp(4, 2, 6), 4); + assert.same(clamp(6, 2, 4), 4); + + assert.same(clamp(-0, 0, 1), 0, 'If value is -0𝔽 and min is +0𝔽, return +0𝔽.'); + assert.same(clamp(0, -0, 1), 0, 'If value is +0𝔽 and min is -0𝔽, return +0𝔽.'); + assert.same(clamp(-0, -1, 0), -0, 'If value is -0𝔽 and max is +0𝔽, return -0𝔽.'); + assert.same(clamp(0, -1, -0), -0, 'If value is +0𝔽 and max is -0𝔽, return -0𝔽.'); + assert.same(clamp(0, -0, -0), -0, 'If min = max return min.'); + + assert.same(clamp(2, 0, -0), -0, 'min is +0𝔽 and max is -0𝔽'); + assert.same(clamp(2, 3, 1), 1, 'min > max'); + + assert.same(clamp(NaN, 3, 1), NaN, 'If value is NaN, return NaN.'); + assert.same(clamp(2, NaN, 1), NaN, 'If min is NaN, return NaN.'); + assert.same(clamp(2, 3, NaN), NaN, 'If max is NaN, return NaN.'); + + assert.throws(() => clamp({ valueOf: () => 2 }, 1, 3), TypeError, 'If value is not a Number, throw a TypeError exception'); + assert.throws(() => clamp(2, Object(1), 3), TypeError, 'If min is not a Number, throw a TypeError exception.'); + assert.throws(() => clamp(2, 1, Object(3)), TypeError, 'If max is not a Number, throw a TypeError exception.'); +}); diff --git a/tests/unit-pure/esnext.math.deg-per-rad.js b/tests/unit-pure/esnext.math.deg-per-rad.js new file mode 100644 index 000000000000..21cdad2b557d --- /dev/null +++ b/tests/unit-pure/esnext.math.deg-per-rad.js @@ -0,0 +1,5 @@ +import DEG_PER_RAD from 'core-js-pure/full/math/deg-per-rad'; + +QUnit.test('Math.DEG_PER_RAD', assert => { + assert.same(DEG_PER_RAD, Math.PI / 180, 'Is Math.PI / 180'); +}); diff --git a/tests/unit-pure/esnext.math.degrees.js b/tests/unit-pure/esnext.math.degrees.js new file mode 100644 index 000000000000..09429daeba4b --- /dev/null +++ b/tests/unit-pure/esnext.math.degrees.js @@ -0,0 +1,17 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import degrees from 'core-js-pure/full/math/degrees'; + +QUnit.test('Math.degrees', assert => { + assert.isFunction(degrees); + assert.arity(degrees, 1); + assert.same(degrees(0), 0); + assert.same(degrees(Math.PI / 2), 90); + assert.same(degrees(Math.PI), 180); + assert.same(degrees(3 * Math.PI / 2), 270); + + const checker = createConversionChecker(3 * Math.PI / 2); + assert.same(degrees(checker), 270, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/esnext.math.fscale.js b/tests/unit-pure/esnext.math.fscale.js new file mode 100644 index 000000000000..da6e88301ef6 --- /dev/null +++ b/tests/unit-pure/esnext.math.fscale.js @@ -0,0 +1,29 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import fscale from 'core-js-pure/full/math/fscale'; + +QUnit.test('Math.fscale', assert => { + assert.isFunction(fscale); + assert.arity(fscale, 5); + assert.same(fscale(3, 1, 2, 1, 2), 3); + assert.same(fscale(0, 3, 5, 8, 10), 5); + assert.same(fscale(1, 1, 1, 1, 1), NaN); + assert.same(fscale(-1, -1, -1, -1, -1), NaN); + + const checker1 = createConversionChecker(3); + const checker2 = createConversionChecker(1); + const checker3 = createConversionChecker(2); + const checker4 = createConversionChecker(1); + const checker5 = createConversionChecker(2); + assert.same(fscale(checker1, checker2, checker3, checker4, checker5), 3, 'object wrapper'); + assert.same(checker1.$valueOf, 1, 'checker1 valueOf calls'); + assert.same(checker1.$toString, 0, 'checker1 toString calls'); + assert.same(checker2.$valueOf, 1, 'checker2 valueOf calls'); + assert.same(checker2.$toString, 0, 'checker2 toString calls'); + assert.same(checker3.$valueOf, 1, 'checker3 valueOf calls'); + assert.same(checker3.$toString, 0, 'checker3 toString calls'); + assert.same(checker4.$valueOf, 1, 'checker4 valueOf calls'); + assert.same(checker4.$toString, 0, 'checker4 toString calls'); + assert.same(checker5.$valueOf, 1, 'checker5 valueOf calls'); + assert.same(checker5.$toString, 0, 'checker5 toString calls'); +}); diff --git a/tests/pure/esnext.math.iaddh.js b/tests/unit-pure/esnext.math.iaddh.js similarity index 84% rename from tests/pure/esnext.math.iaddh.js rename to tests/unit-pure/esnext.math.iaddh.js index a2c72112936d..bc9f8be567f1 100644 --- a/tests/pure/esnext.math.iaddh.js +++ b/tests/unit-pure/esnext.math.iaddh.js @@ -1,4 +1,4 @@ -import iaddh from 'core-js-pure/features/math/iaddh'; +import iaddh from 'core-js-pure/full/math/iaddh'; QUnit.test('Math.iaddh', assert => { assert.isFunction(iaddh); diff --git a/tests/pure/esnext.math.imulh.js b/tests/unit-pure/esnext.math.imulh.js similarity index 81% rename from tests/pure/esnext.math.imulh.js rename to tests/unit-pure/esnext.math.imulh.js index 7a6444911875..96e01346e86f 100644 --- a/tests/pure/esnext.math.imulh.js +++ b/tests/unit-pure/esnext.math.imulh.js @@ -1,4 +1,4 @@ -import imulh from 'core-js-pure/features/math/imulh'; +import imulh from 'core-js-pure/full/math/imulh'; QUnit.test('Math.imulh', assert => { assert.isFunction(imulh); diff --git a/tests/pure/esnext.math.isubh.js b/tests/unit-pure/esnext.math.isubh.js similarity index 84% rename from tests/pure/esnext.math.isubh.js rename to tests/unit-pure/esnext.math.isubh.js index 38da3102ae0b..e0e6b8e00313 100644 --- a/tests/pure/esnext.math.isubh.js +++ b/tests/unit-pure/esnext.math.isubh.js @@ -1,4 +1,4 @@ -import isubh from 'core-js-pure/features/math/isubh'; +import isubh from 'core-js-pure/full/math/isubh'; QUnit.test('Math.isubh', assert => { assert.isFunction(isubh); diff --git a/tests/unit-pure/esnext.math.rad-per-deg.js b/tests/unit-pure/esnext.math.rad-per-deg.js new file mode 100644 index 000000000000..d7cad5a883bf --- /dev/null +++ b/tests/unit-pure/esnext.math.rad-per-deg.js @@ -0,0 +1,5 @@ +import RAD_PER_DEG from 'core-js-pure/full/math/rad-per-deg'; + +QUnit.test('Math.RAD_PER_DEG', assert => { + assert.same(RAD_PER_DEG, 180 / Math.PI, 'Is 180 / Math.PI'); +}); diff --git a/tests/unit-pure/esnext.math.radians.js b/tests/unit-pure/esnext.math.radians.js new file mode 100644 index 000000000000..8cb8c1e22afb --- /dev/null +++ b/tests/unit-pure/esnext.math.radians.js @@ -0,0 +1,17 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import radians from 'core-js-pure/full/math/radians'; + +QUnit.test('Math.radians', assert => { + assert.isFunction(radians); + assert.arity(radians, 1); + assert.same(radians(0), 0); + assert.same(radians(90), Math.PI / 2); + assert.same(radians(180), Math.PI); + assert.same(radians(270), 3 * Math.PI / 2); + + const checker = createConversionChecker(270); + assert.same(radians(checker), 3 * Math.PI / 2, 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/unit-pure/esnext.math.scale.js b/tests/unit-pure/esnext.math.scale.js new file mode 100644 index 000000000000..42477bfecada --- /dev/null +++ b/tests/unit-pure/esnext.math.scale.js @@ -0,0 +1,29 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import scale from 'core-js-pure/full/math/scale'; + +QUnit.test('Math.scale', assert => { + assert.isFunction(scale); + assert.arity(scale, 5); + assert.same(scale(3, 1, 2, 1, 2), 3); + assert.same(scale(0, 3, 5, 8, 10), 5); + assert.same(scale(1, 1, 1, 1, 1), NaN); + assert.same(scale(-1, -1, -1, -1, -1), NaN); + + const checker1 = createConversionChecker(3); + const checker2 = createConversionChecker(1); + const checker3 = createConversionChecker(2); + const checker4 = createConversionChecker(1); + const checker5 = createConversionChecker(2); + assert.same(scale(checker1, checker2, checker3, checker4, checker5), 3, 'object wrapper'); + assert.same(checker1.$valueOf, 1, 'checker1 valueOf calls'); + assert.same(checker1.$toString, 0, 'checker1 toString calls'); + assert.same(checker2.$valueOf, 1, 'checker2 valueOf calls'); + assert.same(checker2.$toString, 0, 'checker2 toString calls'); + assert.same(checker3.$valueOf, 1, 'checker3 valueOf calls'); + assert.same(checker3.$toString, 0, 'checker3 toString calls'); + assert.same(checker4.$valueOf, 1, 'checker4 valueOf calls'); + assert.same(checker4.$toString, 0, 'checker4 toString calls'); + assert.same(checker5.$valueOf, 1, 'checker5 valueOf calls'); + assert.same(checker5.$toString, 0, 'checker5 toString calls'); +}); diff --git a/tests/pure/esnext.math.seeded-prng.js b/tests/unit-pure/esnext.math.seeded-prng.js similarity index 94% rename from tests/pure/esnext.math.seeded-prng.js rename to tests/unit-pure/esnext.math.seeded-prng.js index 2d20b959355c..f6556eb7ded3 100644 --- a/tests/pure/esnext.math.seeded-prng.js +++ b/tests/unit-pure/esnext.math.seeded-prng.js @@ -1,4 +1,4 @@ -import seededPRNG from 'core-js-pure/features/math/seeded-prng'; +import seededPRNG from 'core-js-pure/full/math/seeded-prng'; QUnit.test('Math.seededPRNG', assert => { assert.isFunction(seededPRNG); diff --git a/tests/unit-pure/esnext.math.signbit.js b/tests/unit-pure/esnext.math.signbit.js new file mode 100644 index 000000000000..06e51d54667a --- /dev/null +++ b/tests/unit-pure/esnext.math.signbit.js @@ -0,0 +1,22 @@ +import { createConversionChecker } from '../helpers/helpers.js'; + +import signbit from 'core-js-pure/full/math/signbit'; + +QUnit.test('Math.signbit', assert => { + assert.isFunction(signbit); + assert.false(signbit(NaN)); + assert.false(signbit()); + assert.true(signbit(-0)); + assert.false(signbit(0)); + assert.false(signbit(Infinity)); + assert.true(signbit(-Infinity)); + assert.false(signbit(13510798882111488)); + assert.true(signbit(-13510798882111488)); + assert.false(signbit(42.5)); + assert.true(signbit(-42.5)); + + const checker = createConversionChecker(-13510798882111488); + assert.true(signbit(checker), 'object wrapper'); + assert.same(checker.$valueOf, 1, 'valueOf calls'); + assert.same(checker.$toString, 0, 'toString calls'); +}); diff --git a/tests/pure/esnext.math.umulh.js b/tests/unit-pure/esnext.math.umulh.js similarity index 81% rename from tests/pure/esnext.math.umulh.js rename to tests/unit-pure/esnext.math.umulh.js index 868734f362eb..0d123a815976 100644 --- a/tests/pure/esnext.math.umulh.js +++ b/tests/unit-pure/esnext.math.umulh.js @@ -1,4 +1,4 @@ -import umulh from 'core-js-pure/features/math/umulh'; +import umulh from 'core-js-pure/full/math/umulh'; QUnit.test('Math.umulh', assert => { assert.isFunction(umulh); diff --git a/tests/unit-pure/esnext.number.clamp.js b/tests/unit-pure/esnext.number.clamp.js new file mode 100644 index 000000000000..a2b304c988f7 --- /dev/null +++ b/tests/unit-pure/esnext.number.clamp.js @@ -0,0 +1,26 @@ +import clamp from 'core-js-pure/full/number/clamp'; + +QUnit.test('Number#clamp', assert => { + assert.isFunction(clamp); + + assert.same(clamp(2, 4, 6), 4); + assert.same(clamp(4, 2, 6), 4); + assert.same(clamp(6, 2, 4), 4); + + assert.same(clamp(-0, 0, 1), 0, 'If value is -0𝔽 and min is +0𝔽, return +0𝔽.'); + assert.same(clamp(0, -0, 1), 0, 'If value is +0𝔽 and min is -0𝔽, return +0𝔽.'); + assert.same(clamp(-0, -1, 0), -0, 'If value is -0𝔽 and max is +0𝔽, return -0𝔽.'); + assert.same(clamp(0, -1, -0), -0, 'If value is +0𝔽 and max is -0𝔽, return -0𝔽.'); + assert.same(clamp(0, -0, -0), -0, 'If min = max return min.'); + + assert.same(clamp(2, 0, -0), -0, 'min is +0𝔽 and max is -0𝔽'); + assert.same(clamp(2, 3, 1), 1, 'min > max'); + + assert.same(clamp(NaN, 3, 1), NaN, 'If value is NaN, return NaN.'); + assert.same(clamp(2, NaN, 1), NaN, 'If min is NaN, return NaN.'); + assert.same(clamp(2, 3, NaN), NaN, 'If max is NaN, return NaN.'); + + assert.throws(() => clamp({ valueOf: () => 2 }, 1, 3), TypeError, 'If value is not a Number, throw a TypeError exception'); + assert.throws(() => clamp(2, Object(1), 3), TypeError, 'If min is not a Number, throw a TypeError exception.'); + assert.throws(() => clamp(2, 1, Object(3)), TypeError, 'If max is not a Number, throw a TypeError exception.'); +}); diff --git a/tests/unit-pure/esnext.number.from-string.js b/tests/unit-pure/esnext.number.from-string.js new file mode 100644 index 000000000000..0e106090be1e --- /dev/null +++ b/tests/unit-pure/esnext.number.from-string.js @@ -0,0 +1,47 @@ +import fromString from 'core-js-pure/full/number/from-string'; + +QUnit.test('Number.fromString', assert => { + assert.isFunction(fromString); + assert.name(fromString, 'fromString'); + assert.arity(fromString, 2); + assert.throws(() => fromString(undefined), TypeError, 'The first argument should be a string #1'); + assert.throws(() => fromString(Object('10')), TypeError, 'The first argument should be a string #1'); + assert.throws(() => fromString(''), SyntaxError, 'Empty string'); + assert.same(fromString('-10', 2), -2, 'Works with negative numbers'); + assert.throws(() => fromString('-'), SyntaxError, '-'); + assert.same(fromString('10'), 10, 'Default radix is 10 #1'); + assert.same(fromString('10', undefined), 10, 'Default radix is 10 #2'); + for (let radix = 2; radix <= 36; ++radix) { + assert.same(fromString('10', radix), radix, `Radix ${ radix }`); + } + assert.throws(() => fromString('10', -4294967294), RangeError, 'Radix uses ToInteger #1'); + + assert.same(fromString('10', 2.5), 2, 'Radix uses ToInteger #2'); + assert.same(fromString('42'), 42); + assert.same(fromString('42', 10), 42); + assert.same(fromString('3.14159', 10), 3.14159); + assert.same(fromString('-100.11', 2), -4.75); + assert.same(fromString('202.1', 3), 20.333333333333332); + + assert.same(fromString('0'), 0); + assert.same(fromString('0', 2), 0); + assert.same(fromString('-0'), -0); + assert.same(fromString('-0', 2), -0); + + assert.throws(() => fromString('0xc0ffee'), SyntaxError); + assert.throws(() => fromString('0o755'), SyntaxError); + assert.throws(() => fromString('0b00101010'), SyntaxError); + assert.throws(() => fromString('C0FFEE', 16), SyntaxError); + assert.same(fromString('c0ffee', 16), 12648430); + assert.same(fromString('755', 8), 493); + assert.throws(() => fromString(''), SyntaxError); + assert.throws(() => fromString(' '), SyntaxError); + assert.throws(() => fromString(' 1'), SyntaxError); + assert.throws(() => fromString(' \n '), SyntaxError); + assert.throws(() => fromString('x'), SyntaxError); + assert.throws(() => fromString('1234', 0), RangeError); + assert.throws(() => fromString('1234', 1), RangeError); + assert.throws(() => fromString('1234', 37), RangeError); + assert.throws(() => fromString('010'), SyntaxError); + assert.throws(() => fromString('1_000_000_000'), SyntaxError); +}); diff --git a/tests/unit-pure/esnext.number.range.js b/tests/unit-pure/esnext.number.range.js new file mode 100644 index 000000000000..994b9b9912dd --- /dev/null +++ b/tests/unit-pure/esnext.number.range.js @@ -0,0 +1,71 @@ +import { MAX_SAFE_INTEGER } from '../helpers/constants.js'; +import from from 'core-js-pure/es/array/from'; +import range from 'core-js-pure/full/number/range'; + +QUnit.test('range', assert => { + assert.isFunction(range); + assert.name(range, 'range'); + assert.arity(range, 3); + + let iterator = range(1, 2); + + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.deepEqual(iterator.next(), { + value: 1, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.deepEqual(from(range(-1, 5)), [-1, 0, 1, 2, 3, 4]); + assert.deepEqual(from(range(-5, 1)), [-5, -4, -3, -2, -1, 0]); + assert.deepEqual( + from(range(0, 1, 0.1)), + [0, 0.1, 0.2, 0.30000000000000004, 0.4, 0.5, 0.6000000000000001, 0.7000000000000001, 0.8, 0.9], + ); + assert.deepEqual( + from(range(MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1, { inclusive: true })), + [MAX_SAFE_INTEGER, MAX_SAFE_INTEGER + 1], + ); + assert.deepEqual(from(range(0, 0)), []); + assert.deepEqual(from(range(0, -5, 1)), []); + + assert.deepEqual(from(range(NaN, 0)), []); + assert.deepEqual(from(range(0, NaN)), []); + assert.deepEqual(from(range(NaN, NaN)), []); + assert.deepEqual(from(range(0, 0, { step: NaN })), []); + assert.deepEqual(from(range(0, 5, NaN)), []); + + iterator = range(1, 3); + assert.deepEqual(iterator.start, 1); + assert.deepEqual(iterator.end, 3); + assert.deepEqual(iterator.step, 1); + assert.false(iterator.inclusive); + + iterator = range(-1, -3, { inclusive: true }); + assert.deepEqual(iterator.start, -1); + assert.deepEqual(iterator.end, -3); + assert.same(iterator.step, -1); + assert.true(iterator.inclusive); + + iterator = range(-1, -3, { step: 4, inclusive() { /* empty */ } }); + assert.same(iterator.start, -1); + assert.same(iterator.end, -3); + assert.same(iterator.step, 4); + assert.true(iterator.inclusive); + + iterator = range(0, 5); + // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe + assert.throws(() => Object.getOwnPropertyDescriptor(iterator, 'start').get.call({}), TypeError); + + assert.throws(() => range(Infinity, 10, 0), RangeError); + assert.throws(() => range(-Infinity, 10, 0), RangeError); + assert.throws(() => range(0, 10, Infinity), RangeError); + assert.throws(() => range(0, 10, { step: Infinity }), RangeError); + + assert.throws(() => range({}, 1), TypeError); + assert.throws(() => range(1, {}), TypeError); +}); diff --git a/tests/unit-pure/esnext.object.iterate-entries.js b/tests/unit-pure/esnext.object.iterate-entries.js new file mode 100644 index 000000000000..37f3fa480010 --- /dev/null +++ b/tests/unit-pure/esnext.object.iterate-entries.js @@ -0,0 +1,31 @@ +import Symbol from 'core-js-pure/es/symbol'; +import iterateEntries from 'core-js-pure/full/object/iterate-entries'; + +QUnit.test('Object.iterateEntries', assert => { + assert.isFunction(iterateEntries); + assert.name(iterateEntries, 'iterateEntries'); + assert.arity(iterateEntries, 1); + + const object = { + q: 1, + w: 2, + e: 3, + }; + const iterator = iterateEntries(object); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Object Iterator'); + assert.deepEqual(iterator.next(), { + value: ['q', 1], + done: false, + }); + delete object.w; + assert.deepEqual(iterator.next(), { + value: ['e', 3], + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-pure/esnext.object.iterate-keys.js b/tests/unit-pure/esnext.object.iterate-keys.js new file mode 100644 index 000000000000..b020d33e92d1 --- /dev/null +++ b/tests/unit-pure/esnext.object.iterate-keys.js @@ -0,0 +1,31 @@ +import Symbol from 'core-js-pure/es/symbol'; +import iterateKeys from 'core-js-pure/full/object/iterate-keys'; + +QUnit.test('Object.iterateKeys', assert => { + assert.isFunction(iterateKeys); + assert.name(iterateKeys, 'iterateKeys'); + assert.arity(iterateKeys, 1); + + const object = { + q: 1, + w: 2, + e: 3, + }; + const iterator = iterateKeys(object); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Object Iterator'); + assert.deepEqual(iterator.next(), { + value: 'q', + done: false, + }); + delete object.w; + assert.deepEqual(iterator.next(), { + value: 'e', + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-pure/esnext.object.iterate-values.js b/tests/unit-pure/esnext.object.iterate-values.js new file mode 100644 index 000000000000..709f94e544a0 --- /dev/null +++ b/tests/unit-pure/esnext.object.iterate-values.js @@ -0,0 +1,31 @@ +import Symbol from 'core-js-pure/es/symbol'; +import iterateValues from 'core-js-pure/full/object/iterate-values'; + +QUnit.test('Object.iterateValues', assert => { + assert.isFunction(iterateValues); + assert.name(iterateValues, 'iterateValues'); + assert.arity(iterateValues, 1); + + const object = { + q: 1, + w: 2, + e: 3, + }; + const iterator = iterateValues(object); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'Object Iterator'); + assert.deepEqual(iterator.next(), { + value: 1, + done: false, + }); + delete object.w; + assert.deepEqual(iterator.next(), { + value: 3, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); +}); diff --git a/tests/unit-pure/esnext.observable.constructor.js b/tests/unit-pure/esnext.observable.constructor.js new file mode 100644 index 000000000000..c66a51ca7820 --- /dev/null +++ b/tests/unit-pure/esnext.observable.constructor.js @@ -0,0 +1,47 @@ +import { STRICT } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/full/symbol'; +import Observable from 'core-js-pure/full/observable'; + +QUnit.test('Observable', assert => { + assert.isFunction(Observable); + assert.arity(Observable, 1); + const observable = new Observable(function (subscriptionObserver) { + assert.same(typeof subscriptionObserver, 'object', 'Subscription observer is object'); + assert.same(subscriptionObserver.constructor, Object); + const { next, error, complete } = subscriptionObserver; + assert.isFunction(next); + assert.isFunction(error); + assert.isFunction(complete); + assert.arity(next, 1); + assert.arity(error, 1); + assert.arity(complete, 0); + if (STRICT) { + assert.same(this, undefined, 'correct executor context'); + } + }); + observable.subscribe({}); + assert.true(observable instanceof Observable); + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing + assert.throws(() => Observable(() => { /* empty */ }), 'throws w/o `new`'); +}); + +QUnit.test('Observable#subscribe', assert => { + assert.isFunction(Observable.prototype.subscribe); + assert.arity(Observable.prototype.subscribe, 1); + const subscription = new Observable(() => { /* empty */ }).subscribe({}); + assert.same(typeof subscription, 'object', 'Subscription is object'); + assert.same(subscription.constructor, Object); + assert.isFunction(subscription.unsubscribe); + assert.arity(subscription.unsubscribe, 0); +}); + +QUnit.test('Observable#constructor', assert => { + assert.same(Observable.prototype.constructor, Observable); +}); + +QUnit.test('Observable#@@observable', assert => { + assert.isFunction(Observable.prototype[Symbol.observable]); + const observable = new Observable(() => { /* empty*/ }); + assert.same(observable[Symbol.observable](), observable); +}); diff --git a/tests/unit-pure/esnext.observable.from.js b/tests/unit-pure/esnext.observable.from.js new file mode 100644 index 000000000000..09af00fdcab8 --- /dev/null +++ b/tests/unit-pure/esnext.observable.from.js @@ -0,0 +1,6 @@ +import Observable from 'core-js-pure/full/observable'; + +QUnit.test('Observable.from', assert => { + assert.isFunction(Observable.from); + assert.arity(Observable.from, 1); +}); diff --git a/tests/unit-pure/esnext.observable.of.js b/tests/unit-pure/esnext.observable.of.js new file mode 100644 index 000000000000..f02b52b61acc --- /dev/null +++ b/tests/unit-pure/esnext.observable.of.js @@ -0,0 +1,6 @@ +import Observable from 'core-js-pure/full/observable'; + +QUnit.test('Observable.of', assert => { + assert.isFunction(Observable.of); + assert.arity(Observable.of, 0); +}); diff --git a/tests/pure/esnext.reflect.define-metadata.js b/tests/unit-pure/esnext.reflect.define-metadata.js similarity index 82% rename from tests/pure/esnext.reflect.define-metadata.js rename to tests/unit-pure/esnext.reflect.define-metadata.js index fedadaeb09e2..d633ad0a77bd 100644 --- a/tests/pure/esnext.reflect.define-metadata.js +++ b/tests/unit-pure/esnext.reflect.define-metadata.js @@ -1,4 +1,4 @@ -import defineMetadata from 'core-js-pure/features/reflect/define-metadata'; +import defineMetadata from 'core-js-pure/full/reflect/define-metadata'; QUnit.test('Reflect.defineMetadata', assert => { assert.isFunction(defineMetadata); diff --git a/tests/unit-pure/esnext.reflect.delete-metadata.js b/tests/unit-pure/esnext.reflect.delete-metadata.js new file mode 100644 index 000000000000..9236b4fd27c2 --- /dev/null +++ b/tests/unit-pure/esnext.reflect.delete-metadata.js @@ -0,0 +1,21 @@ +import create from 'core-js-pure/full/object/create'; +import defineMetadata from 'core-js-pure/full/reflect/define-metadata'; +import hasOwnMetadata from 'core-js-pure/full/reflect/has-own-metadata'; +import deleteMetadata from 'core-js-pure/full/reflect/delete-metadata'; + +QUnit.test('Reflect.deleteMetadata', assert => { + assert.isFunction(deleteMetadata); + assert.arity(deleteMetadata, 2); + assert.throws(() => deleteMetadata('key', undefined, undefined), TypeError); + assert.false(deleteMetadata('key', {}, undefined)); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.true(deleteMetadata('key', object, undefined)); + const prototype = {}; + defineMetadata('key', 'value', prototype, undefined); + assert.false(deleteMetadata('key', create(prototype), undefined)); + object = {}; + defineMetadata('key', 'value', object, undefined); + deleteMetadata('key', object, undefined); + assert.false(hasOwnMetadata('key', object, undefined)); +}); diff --git a/tests/unit-pure/esnext.reflect.get-metadata-keys.js b/tests/unit-pure/esnext.reflect.get-metadata-keys.js new file mode 100644 index 000000000000..9275be354afc --- /dev/null +++ b/tests/unit-pure/esnext.reflect.get-metadata-keys.js @@ -0,0 +1,51 @@ +import create from 'core-js-pure/full/object/create'; +import defineMetadata from 'core-js-pure/full/reflect/define-metadata'; +import getMetadataKeys from 'core-js-pure/full/reflect/get-metadata-keys'; + +QUnit.test('Reflect.getMetadataKeys', assert => { + assert.isFunction(getMetadataKeys); + assert.arity(getMetadataKeys, 1); + assert.throws(() => getMetadataKeys(undefined, undefined), TypeError); + assert.deepEqual(getMetadataKeys({}, undefined), []); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key']); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key']); + object = {}; + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1']); + object = {}; + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + defineMetadata('key0', 'value', object, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1']); + prototype = {}; + defineMetadata('key2', 'value', prototype, undefined); + object = create(prototype); + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + assert.deepEqual(getMetadataKeys(object, undefined), ['key0', 'key1', 'key2']); + assert.deepEqual(getMetadataKeys({}, 'name'), []); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.deepEqual(getMetadataKeys(object, 'name'), ['key']); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.deepEqual(getMetadataKeys(object, 'name'), ['key']); + object = {}; + defineMetadata('key0', 'value', object, 'name'); + defineMetadata('key1', 'value', object, 'name'); + defineMetadata('key0', 'value', object, 'name'); + assert.deepEqual(getMetadataKeys(object, 'name'), ['key0', 'key1']); + prototype = {}; + defineMetadata('key2', 'value', prototype, 'name'); + object = create(prototype); + defineMetadata('key0', 'value', object, 'name'); + defineMetadata('key1', 'value', object, 'name'); + assert.deepEqual(getMetadataKeys(object, 'name'), ['key0', 'key1', 'key2']); +}); diff --git a/tests/pure/esnext.reflect.get-metadata.js b/tests/unit-pure/esnext.reflect.get-metadata.js similarity index 82% rename from tests/pure/esnext.reflect.get-metadata.js rename to tests/unit-pure/esnext.reflect.get-metadata.js index 74a47a9f77c1..caddbaf0b977 100644 --- a/tests/pure/esnext.reflect.get-metadata.js +++ b/tests/unit-pure/esnext.reflect.get-metadata.js @@ -1,5 +1,6 @@ -import { defineMetadata, getMetadata } from 'core-js-pure/features/reflect'; -import create from 'core-js-pure/features/object/create'; +import create from 'core-js-pure/full/object/create'; +import defineMetadata from 'core-js-pure/full/reflect/define-metadata'; +import getMetadata from 'core-js-pure/full/reflect/get-metadata'; QUnit.test('Reflect.getMetadata', assert => { assert.isFunction(getMetadata); diff --git a/tests/unit-pure/esnext.reflect.get-own-metadata-keys.js b/tests/unit-pure/esnext.reflect.get-own-metadata-keys.js new file mode 100644 index 000000000000..92170b4bfff0 --- /dev/null +++ b/tests/unit-pure/esnext.reflect.get-own-metadata-keys.js @@ -0,0 +1,51 @@ +import create from 'core-js-pure/full/object/create'; +import defineMetadata from 'core-js-pure/full/reflect/define-metadata'; +import getOwnMetadataKeys from 'core-js-pure/full/reflect/get-own-metadata-keys'; + +QUnit.test('Reflect.getOwnMetadataKeys', assert => { + assert.isFunction(getOwnMetadataKeys); + assert.arity(getOwnMetadataKeys, 1); + assert.throws(() => getOwnMetadataKeys(undefined, undefined), TypeError); + assert.deepEqual(getOwnMetadataKeys({}, undefined), []); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key']); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), []); + object = {}; + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); + object = {}; + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + defineMetadata('key0', 'value', object, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); + prototype = {}; + defineMetadata('key2', 'value', prototype, undefined); + object = create(prototype); + defineMetadata('key0', 'value', object, undefined); + defineMetadata('key1', 'value', object, undefined); + assert.deepEqual(getOwnMetadataKeys(object, undefined), ['key0', 'key1']); + assert.deepEqual(getOwnMetadataKeys({}, 'name'), []); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key']); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.deepEqual(getOwnMetadataKeys(object, 'name'), []); + object = {}; + defineMetadata('key0', 'value', object, 'name'); + defineMetadata('key1', 'value', object, 'name'); + defineMetadata('key0', 'value', object, 'name'); + assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key0', 'key1']); + prototype = {}; + defineMetadata('key2', 'value', prototype, 'name'); + object = create(prototype); + defineMetadata('key0', 'value', object, 'name'); + defineMetadata('key1', 'value', object, 'name'); + assert.deepEqual(getOwnMetadataKeys(object, 'name'), ['key0', 'key1']); +}); diff --git a/tests/unit-pure/esnext.reflect.get-own-metadata.js b/tests/unit-pure/esnext.reflect.get-own-metadata.js new file mode 100644 index 000000000000..19806cd3a59c --- /dev/null +++ b/tests/unit-pure/esnext.reflect.get-own-metadata.js @@ -0,0 +1,25 @@ +import create from 'core-js-pure/full/object/create'; +import defineMetadata from 'core-js-pure/full/reflect/define-metadata'; +import getOwnMetadata from 'core-js-pure/full/reflect/get-own-metadata'; + +QUnit.test('Reflect.getOwnMetadata', assert => { + assert.isFunction(getOwnMetadata); + assert.arity(getOwnMetadata, 2); + assert.throws(() => getOwnMetadata('key', undefined, undefined), TypeError); + assert.same(getOwnMetadata('key', {}, undefined), undefined); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.same(getOwnMetadata('key', object, undefined), 'value'); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.same(getOwnMetadata('key', object, undefined), undefined); + assert.same(getOwnMetadata('key', {}, 'name'), undefined); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.same(getOwnMetadata('key', object, 'name'), 'value'); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.same(getOwnMetadata('key', object, 'name'), undefined); +}); diff --git a/tests/unit-pure/esnext.reflect.has-metadata.js b/tests/unit-pure/esnext.reflect.has-metadata.js new file mode 100644 index 000000000000..98841aaf5865 --- /dev/null +++ b/tests/unit-pure/esnext.reflect.has-metadata.js @@ -0,0 +1,25 @@ +import create from 'core-js-pure/full/object/create'; +import defineMetadata from 'core-js-pure/full/reflect/define-metadata'; +import hasMetadata from 'core-js-pure/full/reflect/has-metadata'; + +QUnit.test('Reflect.hasMetadata', assert => { + assert.isFunction(hasMetadata); + assert.arity(hasMetadata, 2); + assert.throws(() => hasMetadata('key', undefined, undefined), TypeError); + assert.false(hasMetadata('key', {}, undefined)); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.true(hasMetadata('key', object, undefined)); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.true(hasMetadata('key', object, undefined)); + assert.false(hasMetadata('key', {}, 'name')); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.true(hasMetadata('key', object, 'name')); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.true(hasMetadata('key', object, 'name')); +}); diff --git a/tests/unit-pure/esnext.reflect.has-own-metadata.js b/tests/unit-pure/esnext.reflect.has-own-metadata.js new file mode 100644 index 000000000000..49fb1991112e --- /dev/null +++ b/tests/unit-pure/esnext.reflect.has-own-metadata.js @@ -0,0 +1,25 @@ +import create from 'core-js-pure/full/object/create'; +import defineMetadata from 'core-js-pure/full/reflect/define-metadata'; +import hasOwnMetadata from 'core-js-pure/full/reflect/has-own-metadata'; + +QUnit.test('Reflect.hasOwnMetadata', assert => { + assert.isFunction(hasOwnMetadata); + assert.arity(hasOwnMetadata, 2); + assert.throws(() => hasOwnMetadata('key', undefined, undefined), TypeError); + assert.false(hasOwnMetadata('key', {}, undefined)); + let object = {}; + defineMetadata('key', 'value', object, undefined); + assert.true(hasOwnMetadata('key', object, undefined)); + let prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, undefined); + assert.false(hasOwnMetadata('key', object, undefined)); + assert.false(hasOwnMetadata('key', {}, 'name')); + object = {}; + defineMetadata('key', 'value', object, 'name'); + assert.true(hasOwnMetadata('key', object, 'name')); + prototype = {}; + object = create(prototype); + defineMetadata('key', 'value', prototype, 'name'); + assert.false(hasOwnMetadata('key', object, 'name')); +}); diff --git a/tests/unit-pure/esnext.reflect.metadata.js b/tests/unit-pure/esnext.reflect.metadata.js new file mode 100644 index 000000000000..ae62e06e8ab3 --- /dev/null +++ b/tests/unit-pure/esnext.reflect.metadata.js @@ -0,0 +1,16 @@ +import hasOwnMetadata from 'core-js-pure/full/reflect/has-own-metadata'; +import metadata from 'core-js-pure/full/reflect/metadata'; + +QUnit.test('Reflect.metadata', assert => { + assert.isFunction(metadata); + assert.arity(metadata, 2); + assert.isFunction(metadata('key', 'value')); + const decorator = metadata('key', 'value'); + assert.throws(() => decorator(undefined, 'name'), TypeError); + let target = function () { /* empty */ }; + decorator(target); + assert.true(hasOwnMetadata('key', target, undefined)); + target = {}; + decorator(target, 'name'); + assert.true(hasOwnMetadata('key', target, 'name')); +}); diff --git a/tests/unit-pure/esnext.set.add-all.js b/tests/unit-pure/esnext.set.add-all.js new file mode 100644 index 000000000000..6b5306dc8987 --- /dev/null +++ b/tests/unit-pure/esnext.set.add-all.js @@ -0,0 +1,23 @@ +import from from 'core-js-pure/es/array/from'; +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#addAll', assert => { + const { addAll } = Set.prototype; + + assert.isFunction(addAll); + assert.arity(addAll, 0); + assert.name(addAll, 'addAll'); + assert.nonEnumerable(Set.prototype, 'addAll'); + + const set = new Set([1]); + assert.same(set.addAll(2), set); + + assert.deepEqual(from(new Set([1, 2, 3]).addAll(4, 5)), [1, 2, 3, 4, 5]); + assert.deepEqual(from(new Set([1, 2, 3]).addAll(3, 4)), [1, 2, 3, 4]); + assert.deepEqual(from(new Set([1, 2, 3]).addAll()), [1, 2, 3]); + + assert.throws(() => addAll.call({ add() { /* empty */ } }, 1, 2, 3)); + assert.throws(() => addAll.call({}, 1, 2, 3), TypeError); + assert.throws(() => addAll.call(undefined, 1, 2, 3), TypeError); + assert.throws(() => addAll.call(null, 1, 2, 3), TypeError); +}); diff --git a/tests/unit-pure/esnext.set.delete-all.js b/tests/unit-pure/esnext.set.delete-all.js new file mode 100644 index 000000000000..138645243f8e --- /dev/null +++ b/tests/unit-pure/esnext.set.delete-all.js @@ -0,0 +1,32 @@ +import from from 'core-js-pure/es/array/from'; +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#deleteAll', assert => { + const { deleteAll } = Set.prototype; + + assert.isFunction(deleteAll); + assert.arity(deleteAll, 0); + assert.name(deleteAll, 'deleteAll'); + assert.nonEnumerable(Set.prototype, 'deleteAll'); + + let set = new Set([1, 2, 3]); + assert.true(set.deleteAll(1, 2)); + assert.deepEqual(from(set), [3]); + + set = new Set([1, 2, 3]); + assert.false(set.deleteAll(3, 4)); + assert.deepEqual(from(set), [1, 2]); + + set = new Set([1, 2, 3]); + assert.false(set.deleteAll(4, 5)); + assert.deepEqual(from(set), [1, 2, 3]); + + set = new Set([1, 2, 3]); + assert.true(set.deleteAll()); + assert.deepEqual(from(set), [1, 2, 3]); + + assert.throws(() => deleteAll.call({ delete() { /* empty */ } }, 1, 2, 3)); + assert.throws(() => deleteAll.call({}, 1, 2, 3), TypeError); + assert.throws(() => deleteAll.call(undefined, 1, 2, 3), TypeError); + assert.throws(() => deleteAll.call(null, 1, 2, 3), TypeError); +}); diff --git a/tests/unit-pure/esnext.set.every.js b/tests/unit-pure/esnext.set.every.js new file mode 100644 index 000000000000..aea1164562ad --- /dev/null +++ b/tests/unit-pure/esnext.set.every.js @@ -0,0 +1,29 @@ +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#every', assert => { + const { every } = Set.prototype; + + assert.isFunction(every); + assert.arity(every, 1); + assert.name(every, 'every'); + assert.nonEnumerable(Set.prototype, 'every'); + + const set = new Set([1]); + const context = {}; + set.every(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, set, 'correct link to set in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Set([1, 2, 3]).every(it => typeof it == 'number')); + assert.false(new Set(['1', '2', '3']).some(it => typeof it == 'number')); + assert.false(new Set([1, '2', 3]).every(it => typeof it == 'number')); + assert.true(new Set().every(it => typeof it == 'number')); + + assert.throws(() => every.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => every.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.set.filter.js b/tests/unit-pure/esnext.set.filter.js new file mode 100644 index 000000000000..d43995ce832e --- /dev/null +++ b/tests/unit-pure/esnext.set.filter.js @@ -0,0 +1,29 @@ +import from from 'core-js-pure/es/array/from'; +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#filter', assert => { + const { filter } = Set.prototype; + + assert.isFunction(filter); + assert.arity(filter, 1); + assert.name(filter, 'filter'); + assert.nonEnumerable(Set.prototype, 'filter'); + + const set = new Set([1]); + const context = {}; + set.filter(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, set, 'correct link to set in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Set().filter(it => it) instanceof Set); + + assert.deepEqual(from(new Set([1, 2, 3, 'q', {}, 4, true, 5]).filter(it => typeof it == 'number')), [1, 2, 3, 4, 5]); + + assert.throws(() => filter.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => filter.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/pure/esnext.set.find.js b/tests/unit-pure/esnext.set.find.js similarity index 95% rename from tests/pure/esnext.set.find.js rename to tests/unit-pure/esnext.set.find.js index 31676b7894d7..c25dc602753b 100644 --- a/tests/pure/esnext.set.find.js +++ b/tests/unit-pure/esnext.set.find.js @@ -1,4 +1,4 @@ -import Set from 'core-js-pure/features/set'; +import Set from 'core-js-pure/full/set'; QUnit.test('Set#find', assert => { const { find } = Set.prototype; diff --git a/tests/unit-pure/esnext.set.from.js b/tests/unit-pure/esnext.set.from.js new file mode 100644 index 000000000000..7a842a58e45d --- /dev/null +++ b/tests/unit-pure/esnext.set.from.js @@ -0,0 +1,22 @@ +import { createIterable } from '../helpers/helpers.js'; + +import toArray from 'core-js-pure/es/array/from'; +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set.from', assert => { + const { from } = Set; + assert.isFunction(from); + assert.arity(from, 1); + assert.true(from([]) instanceof Set); + assert.deepEqual(toArray(from([])), []); + assert.deepEqual(toArray(from([1])), [1]); + assert.deepEqual(toArray(from([1, 2, 3, 2, 1])), [1, 2, 3]); + assert.deepEqual(toArray(from(createIterable([1, 2, 3, 2, 1]))), [1, 2, 3]); + const context = {}; + from([1], function (element, index) { + assert.same(element, 1); + assert.same(index, 0); + assert.same(this, context); + return element; + }, context); +}); diff --git a/tests/unit-pure/esnext.set.join.js b/tests/unit-pure/esnext.set.join.js new file mode 100644 index 000000000000..29b987d5ac45 --- /dev/null +++ b/tests/unit-pure/esnext.set.join.js @@ -0,0 +1,19 @@ +/* eslint-disable unicorn/require-array-join-separator -- required for testing */ +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#join', assert => { + const { join } = Set.prototype; + + assert.isFunction(join); + assert.arity(join, 1); + assert.name(join, 'join'); + assert.nonEnumerable(Set.prototype, 'join'); + + assert.same(new Set([1, 2, 3]).join(), '1,2,3'); + assert.same(new Set([1, 2, 3]).join(undefined), '1,2,3'); + assert.same(new Set([1, 2, 3]).join('|'), '1|2|3'); + + assert.throws(() => join.call({}), TypeError); + assert.throws(() => join.call(undefined), TypeError); + assert.throws(() => join.call(null), TypeError); +}); diff --git a/tests/unit-pure/esnext.set.map.js b/tests/unit-pure/esnext.set.map.js new file mode 100644 index 000000000000..0db65372f5f0 --- /dev/null +++ b/tests/unit-pure/esnext.set.map.js @@ -0,0 +1,30 @@ +import from from 'core-js-pure/es/array/from'; +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#map', assert => { + const { map } = Set.prototype; + + assert.isFunction(map); + assert.arity(map, 1); + assert.name(map, 'map'); + assert.nonEnumerable(Set.prototype, 'map'); + + const set = new Set([1]); + const context = {}; + set.map(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, set, 'correct link to set in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Set().map(it => it) instanceof Set); + + assert.deepEqual(from(new Set([1, 2, 3]).map(it => it ** 2)), [1, 4, 9]); + assert.deepEqual(from(new Set([1, 2, 3]).map(it => it % 2)), [1, 0]); + + assert.throws(() => map.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => map.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => map.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.set.of.js b/tests/unit-pure/esnext.set.of.js new file mode 100644 index 000000000000..1cb64ebd840b --- /dev/null +++ b/tests/unit-pure/esnext.set.of.js @@ -0,0 +1,11 @@ +import from from 'core-js-pure/es/array/from'; +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set.of', assert => { + const { of } = Set; + assert.isFunction(of); + assert.arity(of, 0); + assert.true(of() instanceof Set); + assert.deepEqual(from(of(1)), [1]); + assert.deepEqual(from(of(1, 2, 3, 2, 1)), [1, 2, 3]); +}); diff --git a/tests/pure/esnext.set.reduce.js b/tests/unit-pure/esnext.set.reduce.js similarity index 97% rename from tests/pure/esnext.set.reduce.js rename to tests/unit-pure/esnext.set.reduce.js index 565c55484d52..5e194285dfdc 100644 --- a/tests/pure/esnext.set.reduce.js +++ b/tests/unit-pure/esnext.set.reduce.js @@ -1,4 +1,4 @@ -import Set from 'core-js-pure/features/set'; +import Set from 'core-js-pure/full/set'; QUnit.test('Set#reduce', assert => { const { reduce } = Set.prototype; diff --git a/tests/unit-pure/esnext.set.some.js b/tests/unit-pure/esnext.set.some.js new file mode 100644 index 000000000000..d0005af6f1c2 --- /dev/null +++ b/tests/unit-pure/esnext.set.some.js @@ -0,0 +1,29 @@ +import Set from 'core-js-pure/full/set'; + +QUnit.test('Set#some', assert => { + const { some } = Set.prototype; + + assert.isFunction(some); + assert.arity(some, 1); + assert.name(some, 'some'); + assert.nonEnumerable(Set.prototype, 'some'); + + const set = new Set([1]); + const context = {}; + set.some(function (value, key, that) { + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 1, 'correct value in callback'); + assert.same(key, 1, 'correct key in callback'); + assert.same(that, set, 'correct link to set in callback'); + assert.same(this, context, 'correct callback context'); + }, context); + + assert.true(new Set([1, 2, 3]).some(it => typeof it == 'number')); + assert.false(new Set(['1', '2', '3']).some(it => typeof it == 'number')); + assert.true(new Set([1, '2', 3]).some(it => typeof it == 'number')); + assert.false(new Set().some(it => typeof it == 'number')); + + assert.throws(() => some.call({}, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(undefined, () => { /* empty */ }), TypeError); + assert.throws(() => some.call(null, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.string.at.js b/tests/unit-pure/esnext.string.at.js new file mode 100644 index 000000000000..69d247a3d462 --- /dev/null +++ b/tests/unit-pure/esnext.string.at.js @@ -0,0 +1,94 @@ +import { STRICT } from '../helpers/constants.js'; + +import at from 'core-js-pure/full/string/at'; + +QUnit.test('String#at', assert => { + assert.isFunction(at); + // String that starts with a BMP symbol + // assert.same(at('abc\uD834\uDF06def', -Infinity), ''); + // assert.same(at('abc\uD834\uDF06def', -1), ''); + assert.same(at('abc\uD834\uDF06def', -0), 'a'); + assert.same(at('abc\uD834\uDF06def', +0), 'a'); + assert.same(at('abc\uD834\uDF06def', 1), 'b'); + assert.same(at('abc\uD834\uDF06def', 3), '\uD834\uDF06'); + assert.same(at('abc\uD834\uDF06def', 4), '\uDF06'); + assert.same(at('abc\uD834\uDF06def', 5), 'd'); + // assert.same(at('abc\uD834\uDF06def', 42), ''); + // assert.same(at('abc\uD834\uDF06def', Infinity), ''); + assert.same(at('abc\uD834\uDF06def', null), 'a'); + assert.same(at('abc\uD834\uDF06def', undefined), 'a'); + assert.same(at('abc\uD834\uDF06def'), 'a'); + assert.same(at('abc\uD834\uDF06def', false), 'a'); + assert.same(at('abc\uD834\uDF06def', NaN), 'a'); + assert.same(at('abc\uD834\uDF06def', ''), 'a'); + assert.same(at('abc\uD834\uDF06def', '_'), 'a'); + assert.same(at('abc\uD834\uDF06def', '1'), 'b'); + assert.same(at('abc\uD834\uDF06def', []), 'a'); + assert.same(at('abc\uD834\uDF06def', {}), 'a'); + assert.same(at('abc\uD834\uDF06def', -0.9), 'a'); + assert.same(at('abc\uD834\uDF06def', 1.9), 'b'); + assert.same(at('abc\uD834\uDF06def', 7.9), 'f'); + // assert.same(at('abc\uD834\uDF06def', 2 ** 32), ''); + // String that starts with an astral symbol + // assert.same(at('\uD834\uDF06def', -Infinity), ''); + // assert.same(at('\uD834\uDF06def', -1), ''); + assert.same(at('\uD834\uDF06def', -0), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def', 0), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def', 1), '\uDF06'); + assert.same(at('\uD834\uDF06def', 2), 'd'); + assert.same(at('\uD834\uDF06def', 3), 'e'); + assert.same(at('\uD834\uDF06def', 4), 'f'); + // assert.same(at('\uD834\uDF06def', 42), ''); + // assert.same(at('\uD834\uDF06def', Infinity), ''); + assert.same(at('\uD834\uDF06def', null), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def', undefined), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def'), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def', false), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def', NaN), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def', ''), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def', '_'), '\uD834\uDF06'); + assert.same(at('\uD834\uDF06def', '1'), '\uDF06'); + // Lone high surrogates + // assert.same(at('\uD834abc', -Infinity), ''); + // assert.same(at('\uD834abc', -1), ''); + assert.same(at('\uD834abc', -0), '\uD834'); + assert.same(at('\uD834abc', 0), '\uD834'); + assert.same(at('\uD834abc', 1), 'a'); + // assert.same(at('\uD834abc', 42), ''); + // assert.same(at('\uD834abc', Infinity), ''); + assert.same(at('\uD834abc', null), '\uD834'); + assert.same(at('\uD834abc', undefined), '\uD834'); + assert.same(at('\uD834abc'), '\uD834'); + assert.same(at('\uD834abc', false), '\uD834'); + assert.same(at('\uD834abc', NaN), '\uD834'); + assert.same(at('\uD834abc', ''), '\uD834'); + assert.same(at('\uD834abc', '_'), '\uD834'); + assert.same(at('\uD834abc', '1'), 'a'); + // Lone low surrogates + // assert.same(at('\uDF06abc', -Infinity), ''); + // assert.same(at('\uDF06abc', -1), ''); + assert.same(at('\uDF06abc', -0), '\uDF06'); + assert.same(at('\uDF06abc', 0), '\uDF06'); + assert.same(at('\uDF06abc', 1), 'a'); + // assert.same(at('\uDF06abc', 42), ''); + // assert.same(at('\uDF06abc', Infinity), ''); + assert.same(at('\uDF06abc', null), '\uDF06'); + assert.same(at('\uDF06abc', undefined), '\uDF06'); + assert.same(at('\uDF06abc'), '\uDF06'); + assert.same(at('\uDF06abc', false), '\uDF06'); + assert.same(at('\uDF06abc', NaN), '\uDF06'); + assert.same(at('\uDF06abc', ''), '\uDF06'); + assert.same(at('\uDF06abc', '_'), '\uDF06'); + assert.same(at('\uDF06abc', '1'), 'a'); + assert.same(at(42, 0), '4'); + assert.same(at(42, 1), '2'); + assert.same(at({ + toString() { + return 'abc'; + }, + }, 2), 'c'); + if (STRICT) { + assert.throws(() => at(null, 0), TypeError); + assert.throws(() => at(undefined, 0), TypeError); + } +}); diff --git a/tests/unit-pure/esnext.string.code-points.js b/tests/unit-pure/esnext.string.code-points.js new file mode 100644 index 000000000000..2f7d8df171dc --- /dev/null +++ b/tests/unit-pure/esnext.string.code-points.js @@ -0,0 +1,46 @@ +import Symbol from 'core-js-pure/es/symbol'; +import codePoints from 'core-js-pure/full/string/code-points'; + +QUnit.test('String#codePoints', assert => { + assert.isFunction(codePoints); + let iterator = codePoints('qwe'); + assert.isIterator(iterator); + assert.isIterable(iterator); + assert.same(iterator[Symbol.toStringTag], 'String Iterator'); + assert.same(String(iterator), '[object String Iterator]'); + assert.deepEqual(iterator.next(), { + value: { codePoint: 113, position: 0 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: { codePoint: 119, position: 1 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: { codePoint: 101, position: 2 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + iterator = codePoints('𠮷𠮷𠮷'); + assert.deepEqual(iterator.next(), { + value: { codePoint: 134071, position: 0 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: { codePoint: 134071, position: 2 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: { codePoint: 134071, position: 4 }, + done: false, + }); + assert.deepEqual(iterator.next(), { + value: undefined, + done: true, + }); + + assert.throws(() => codePoints(Symbol()), 'throws on symbol context'); +}); diff --git a/tests/unit-pure/esnext.string.cooked.js b/tests/unit-pure/esnext.string.cooked.js new file mode 100644 index 000000000000..7dd76a1af6a2 --- /dev/null +++ b/tests/unit-pure/esnext.string.cooked.js @@ -0,0 +1,21 @@ +import Symbol from 'core-js-pure/es/symbol'; +import cooked from 'core-js-pure/full/string/cooked'; + +QUnit.test('String.cooked', assert => { + assert.isFunction(cooked); + assert.arity(cooked, 1); + assert.name(cooked, 'cooked'); + assert.same(cooked(['Hi\\n', '!'], 'Bob'), 'Hi\\nBob!', 'template is an array'); + assert.same(cooked('test', 0, 1, 2), 't0e1s2t', 'template is a string'); + assert.same(cooked('test', 0), 't0est', 'lacks substituting'); + assert.same(cooked([]), '', 'empty template'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + const symbol = Symbol('cooked test'); + assert.throws(() => cooked([symbol]), TypeError, 'throws on symbol #1'); + assert.throws(() => cooked('test', symbol), TypeError, 'throws on symbol #2'); + } + + assert.throws(() => cooked([undefined]), TypeError); + assert.throws(() => cooked(null), TypeError); +}); diff --git a/tests/unit-pure/esnext.string.dedent.js b/tests/unit-pure/esnext.string.dedent.js new file mode 100644 index 000000000000..b40af194b65b --- /dev/null +++ b/tests/unit-pure/esnext.string.dedent.js @@ -0,0 +1,56 @@ +import Symbol from 'core-js-pure/es/symbol'; +import cooked from 'core-js-pure/full/string/cooked'; +import dedent from 'core-js-pure/full/string/dedent'; +import freeze from 'core-js-pure/es/object/freeze'; + +QUnit.test('String.dedent', assert => { + assert.isFunction(dedent); + assert.arity(dedent, 1); + assert.name(dedent, 'dedent'); + + assert.same(dedent` + qwe + asd + zxc + `, 'qwe\nasd\nzxc', '#1'); + + assert.same(dedent` + qwe + asd + zxc + `, ' qwe\nasd\n zxc', '#2'); + + assert.same(dedent` + qwe + asd + ${ ' zxc' } + `, ' qwe\n asd\n zxc', '#3'); + + assert.same(dedent({ raw: freeze(['\n qwe\n ']) }), 'qwe', '#4'); + assert.same(dedent({ raw: freeze(['\n qwe', '\n ']) }, 1), 'qwe1', '#5'); + + assert.same(dedent(cooked)` + qwe + asd + zxc + `, ' qwe\nasd\n zxc', '#6'); + + const tag = (it => it)` + abc + `; + + assert.same(dedent(tag), dedent(tag), '#7'); + + if (typeof Symbol == 'function' && !Symbol.sham) { + assert.throws(() => dedent({ raw: freeze(['\n', Symbol('dedent test'), '\n']) }), TypeError, 'throws on symbol'); + } + + assert.throws(() => dedent([]), TypeError, '[]'); + assert.throws(() => dedent(['qwe']), TypeError, '[qwe]'); + assert.throws(() => dedent({ raw: freeze([]) }), TypeError, 'empty tpl'); + assert.throws(() => dedent({ raw: freeze(['qwe']) }), TypeError, 'wrong start'); + assert.throws(() => dedent({ raw: freeze(['\n', 'qwe']) }), TypeError, 'wrong start'); + assert.throws(() => dedent({ raw: freeze(['\n qwe', 5, '\n ']) }, 1, 2), TypeError, 'wrong part'); + assert.throws(() => dedent([undefined]), TypeError); + assert.throws(() => dedent(null), TypeError); +}); diff --git a/tests/unit-pure/esnext.symbol.custom-matcher.js b/tests/unit-pure/esnext.symbol.custom-matcher.js new file mode 100644 index 000000000000..68ce86f85c8a --- /dev/null +++ b/tests/unit-pure/esnext.symbol.custom-matcher.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.customMatcher', assert => { + assert.true('customMatcher' in Symbol, 'Symbol.customMatcher available'); + assert.true(Object(Symbol.customMatcher) instanceof Symbol, 'Symbol.customMatcher is symbol'); +}); diff --git a/tests/unit-pure/esnext.symbol.is-registered-symbol.js b/tests/unit-pure/esnext.symbol.is-registered-symbol.js new file mode 100644 index 000000000000..1c7ad855429a --- /dev/null +++ b/tests/unit-pure/esnext.symbol.is-registered-symbol.js @@ -0,0 +1,21 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.isRegisteredSymbol', assert => { + const { isRegisteredSymbol } = Symbol; + assert.isFunction(isRegisteredSymbol, 'Symbol.isRegisteredSymbol is function'); + assert.arity(isRegisteredSymbol, 1, 'Symbol.isRegisteredSymbol arity is 1'); + assert.name(isRegisteredSymbol, 'isRegisteredSymbol', 'Symbol.isRegisteredSymbol.name is "isRegisteredSymbol"'); + + assert.true(isRegisteredSymbol(Symbol.for('foo')), 'registered'); + assert.true(isRegisteredSymbol(Object(Symbol.for('foo'))), 'registered, boxed'); + const symbol = Symbol('Symbol.isRegisteredSymbol test'); + assert.false(isRegisteredSymbol(symbol), 'non-registered'); + assert.false(isRegisteredSymbol(Object(symbol)), 'non-registered, boxed'); + assert.false(isRegisteredSymbol(1), '1'); + assert.false(isRegisteredSymbol(true), 'true'); + assert.false(isRegisteredSymbol('1'), 'string'); + assert.false(isRegisteredSymbol(null), 'null'); + assert.false(isRegisteredSymbol(), 'undefined'); + assert.false(isRegisteredSymbol({}), 'object'); + assert.false(isRegisteredSymbol([]), 'array'); +}); diff --git a/tests/unit-pure/esnext.symbol.is-registered.js b/tests/unit-pure/esnext.symbol.is-registered.js new file mode 100644 index 000000000000..b9aeae5e8eb6 --- /dev/null +++ b/tests/unit-pure/esnext.symbol.is-registered.js @@ -0,0 +1,21 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.isRegistered', assert => { + const { isRegistered } = Symbol; + assert.isFunction(isRegistered, 'Symbol.isRegistered is function'); + assert.arity(isRegistered, 1, 'Symbol.isRegistered arity is 1'); + assert.name(isRegistered, 'isRegisteredSymbol', 'Symbol.isRegistered.name is "isRegisteredSymbol"'); + + assert.true(isRegistered(Symbol.for('foo')), 'registered'); + assert.true(isRegistered(Object(Symbol.for('foo'))), 'registered, boxed'); + const symbol = Symbol('Symbol.isRegistered test'); + assert.false(isRegistered(symbol), 'non-registered'); + assert.false(isRegistered(Object(symbol)), 'non-registered, boxed'); + assert.false(isRegistered(1), '1'); + assert.false(isRegistered(true), 'true'); + assert.false(isRegistered('1'), 'string'); + assert.false(isRegistered(null), 'null'); + assert.false(isRegistered(), 'undefined'); + assert.false(isRegistered({}), 'object'); + assert.false(isRegistered([]), 'array'); +}); diff --git a/tests/unit-pure/esnext.symbol.is-well-known-symbol.js b/tests/unit-pure/esnext.symbol.is-well-known-symbol.js new file mode 100644 index 000000000000..8cc9ff0d3a3d --- /dev/null +++ b/tests/unit-pure/esnext.symbol.is-well-known-symbol.js @@ -0,0 +1,23 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.isWellKnownSymbol', assert => { + const { isWellKnownSymbol } = Symbol; + assert.isFunction(isWellKnownSymbol, 'Symbol.isWellKnownSymbol is function'); + assert.arity(isWellKnownSymbol, 1, 'Symbol.isWellKnownSymbol arity is 1'); + assert.name(isWellKnownSymbol, 'isWellKnownSymbol', 'Symbol.isWellKnownSymbol.name is "isWellKnownSymbol"'); + + assert.true(isWellKnownSymbol(Symbol.iterator), 'registered-1'); + assert.true(isWellKnownSymbol(Object(Symbol.iterator)), 'registered-2, boxed'); + assert.true(isWellKnownSymbol(Symbol.patternMatch), 'registered-3'); + assert.true(isWellKnownSymbol(Object(Symbol.patternMatch)), 'registered-4, boxed'); + const symbol = Symbol('Symbol.isWellKnownSymbol test'); + assert.false(isWellKnownSymbol(symbol), 'non-registered'); + assert.false(isWellKnownSymbol(Object(symbol)), 'non-registered, boxed'); + assert.false(isWellKnownSymbol(1), '1'); + assert.false(isWellKnownSymbol(true), 'true'); + assert.false(isWellKnownSymbol('1'), 'string'); + assert.false(isWellKnownSymbol(null), 'null'); + assert.false(isWellKnownSymbol(), 'undefined'); + assert.false(isWellKnownSymbol({}), 'object'); + assert.false(isWellKnownSymbol([]), 'array'); +}); diff --git a/tests/unit-pure/esnext.symbol.is-well-known.js b/tests/unit-pure/esnext.symbol.is-well-known.js new file mode 100644 index 000000000000..89a1dfec0bcc --- /dev/null +++ b/tests/unit-pure/esnext.symbol.is-well-known.js @@ -0,0 +1,23 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.isWellKnown', assert => { + const { isWellKnown } = Symbol; + assert.isFunction(isWellKnown, 'Symbol.isWellKnown is function'); + assert.arity(isWellKnown, 1, 'Symbol.isWellKnown arity is 1'); + assert.name(isWellKnown, 'isWellKnownSymbol', 'Symbol.isWellKnown.name is "isWellKnownSymbol"'); + + assert.true(isWellKnown(Symbol.iterator), 'registered-1'); + assert.true(isWellKnown(Object(Symbol.iterator)), 'registered-2, boxed'); + assert.true(isWellKnown(Symbol.patternMatch), 'registered-3'); + assert.true(isWellKnown(Object(Symbol.patternMatch)), 'registered-4, boxed'); + const symbol = Symbol('Symbol.isWellKnown test'); + assert.false(isWellKnown(symbol), 'non-registered'); + assert.false(isWellKnown(Object(symbol)), 'non-registered, boxed'); + assert.false(isWellKnown(1), '1'); + assert.false(isWellKnown(true), 'true'); + assert.false(isWellKnown('1'), 'string'); + assert.false(isWellKnown(null), 'null'); + assert.false(isWellKnown(), 'undefined'); + assert.false(isWellKnown({}), 'object'); + assert.false(isWellKnown([]), 'array'); +}); diff --git a/tests/unit-pure/esnext.symbol.matcher.js b/tests/unit-pure/esnext.symbol.matcher.js new file mode 100644 index 000000000000..7fd880da45c2 --- /dev/null +++ b/tests/unit-pure/esnext.symbol.matcher.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.matcher', assert => { + assert.true('matcher' in Symbol, 'Symbol.matcher available'); + assert.true(Object(Symbol.matcher) instanceof Symbol, 'Symbol.matcher is symbol'); +}); diff --git a/tests/unit-pure/esnext.symbol.metadata-key.js b/tests/unit-pure/esnext.symbol.metadata-key.js new file mode 100644 index 000000000000..88e7a6b49d0e --- /dev/null +++ b/tests/unit-pure/esnext.symbol.metadata-key.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.metadataKey', assert => { + assert.true('metadataKey' in Symbol, 'Symbol.metadataKey available'); + assert.true(Object(Symbol.metadataKey) instanceof Symbol, 'Symbol.metadataKey is symbol'); +}); diff --git a/tests/unit-pure/esnext.symbol.metadata.js b/tests/unit-pure/esnext.symbol.metadata.js new file mode 100644 index 000000000000..3dfaa3ab9a5d --- /dev/null +++ b/tests/unit-pure/esnext.symbol.metadata.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/actual/symbol'; + +QUnit.test('Symbol.metadata', assert => { + assert.true('metadata' in Symbol, 'Symbol.metadata available'); + assert.true(Object(Symbol.metadata) instanceof Symbol, 'Symbol.metadata is symbol'); +}); diff --git a/tests/unit-pure/esnext.symbol.observable.js b/tests/unit-pure/esnext.symbol.observable.js new file mode 100644 index 000000000000..b3bbaf3d9f13 --- /dev/null +++ b/tests/unit-pure/esnext.symbol.observable.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.observable', assert => { + assert.true('observable' in Symbol, 'Symbol.observable available'); + assert.true(Object(Symbol.observable) instanceof Symbol, 'Symbol.observable is symbol'); +}); diff --git a/tests/unit-pure/esnext.symbol.pattern-match.js b/tests/unit-pure/esnext.symbol.pattern-match.js new file mode 100644 index 000000000000..a360d57f6920 --- /dev/null +++ b/tests/unit-pure/esnext.symbol.pattern-match.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.patternMatch', assert => { + assert.true('patternMatch' in Symbol, 'Symbol.patternMatch available'); + assert.true(Object(Symbol.patternMatch) instanceof Symbol, 'Symbol.patternMatch is symbol'); +}); diff --git a/tests/unit-pure/esnext.symbol.replace-all.js b/tests/unit-pure/esnext.symbol.replace-all.js new file mode 100644 index 000000000000..3ece74333794 --- /dev/null +++ b/tests/unit-pure/esnext.symbol.replace-all.js @@ -0,0 +1,6 @@ +import Symbol from 'core-js-pure/full/symbol'; + +QUnit.test('Symbol.replaceAll', assert => { + assert.true('replaceAll' in Symbol, 'Symbol.replaceAll is available'); + assert.true(Object(Symbol.replaceAll) instanceof Symbol, 'Symbol.replaceAll is symbol'); +}); diff --git a/tests/unit-pure/esnext.weak-map.delete-all.js b/tests/unit-pure/esnext.weak-map.delete-all.js new file mode 100644 index 000000000000..8a5dde77da69 --- /dev/null +++ b/tests/unit-pure/esnext.weak-map.delete-all.js @@ -0,0 +1,52 @@ +import WeakMap from 'core-js-pure/full/weak-map'; + +QUnit.test('WeakMap#deleteAll', assert => { + const { deleteAll } = WeakMap.prototype; + + assert.isFunction(deleteAll); + assert.arity(deleteAll, 0); + assert.nonEnumerable(WeakMap.prototype, 'deleteAll'); + + const a = []; + const b = []; + const c = []; + const d = []; + const e = []; + + let set = new WeakMap([[a, 1], [b, 2], [c, 3]]); + assert.true(set.deleteAll(a, b)); + assert.false(set.has(a)); + assert.false(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakMap([[a, 1], [b, 2], [c, 3]]); + assert.false(set.deleteAll(c, d)); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.false(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakMap([[a, 1], [b, 2], [c, 3]]); + assert.false(set.deleteAll(d, e)); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakMap([[a, 1], [b, 2], [c, 3]]); + assert.true(set.deleteAll()); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + assert.throws(() => deleteAll.call({ delete() { /* empty */ } }, a, b, c)); + assert.throws(() => deleteAll.call({}, a, b, c), TypeError); + assert.throws(() => deleteAll.call(undefined, a, b, c), TypeError); + assert.throws(() => deleteAll.call(null, a, b, c), TypeError); +}); diff --git a/tests/unit-pure/esnext.weak-map.emplace.js b/tests/unit-pure/esnext.weak-map.emplace.js new file mode 100644 index 000000000000..e139298e5b11 --- /dev/null +++ b/tests/unit-pure/esnext.weak-map.emplace.js @@ -0,0 +1,53 @@ +import WeakMap from 'core-js-pure/full/weak-map'; + +QUnit.test('WeakMap#emplace', assert => { + const { emplace } = WeakMap.prototype; + assert.isFunction(emplace); + assert.arity(emplace, 2); + assert.name(emplace, 'emplace'); + assert.nonEnumerable(WeakMap.prototype, 'emplace'); + + const a = {}; + const b = {}; + + const map = new WeakMap([[a, 2]]); + let handler = { + update(value, key, that) { + assert.same(this, handler, 'correct handler in callback'); + assert.same(arguments.length, 3, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + assert.same(key, a, 'correct key in callback'); + assert.same(that, map, 'correct map in callback'); + return value ** 2; + }, + insert() { + assert.avoid(); + }, + }; + assert.same(map.emplace(a, handler), 4, 'returns a correct value'); + handler = { + update() { + assert.avoid(); + }, + insert(key, that) { + assert.same(this, handler, 'correct handler in callback'); + assert.same(arguments.length, 2, 'correct number of callback arguments'); + assert.same(key, b, 'correct key in callback'); + assert.same(that, map, 'correct map in callback'); + return 3; + }, + }; + assert.same(map.emplace(b, handler), 3, 'returns a correct value'); + assert.same(map.get(a), 4, 'correct result #1'); + assert.same(map.get(b), 3, 'correct result #2'); + + assert.same(new WeakMap([[a, 2]]).emplace(b, { insert: () => 3 }), 3); + assert.same(new WeakMap([[a, 2]]).emplace(a, { update: value => value ** 2 }), 4); + + handler = { update() { /* empty */ }, insert() { /* empty */ } }; + assert.throws(() => new WeakMap().emplace(a), TypeError); + assert.throws(() => emplace.call({}, a, handler), TypeError); + assert.throws(() => emplace.call([], a, handler), TypeError); + assert.throws(() => emplace.call(undefined, a, handler), TypeError); + assert.throws(() => emplace.call(null, a, handler), TypeError); +}); diff --git a/tests/unit-pure/esnext.weak-map.from.js b/tests/unit-pure/esnext.weak-map.from.js new file mode 100644 index 000000000000..1853350d025a --- /dev/null +++ b/tests/unit-pure/esnext.weak-map.from.js @@ -0,0 +1,21 @@ +import { createIterable } from '../helpers/helpers.js'; + +import WeakMap from 'core-js-pure/full/weak-map'; + +QUnit.test('WeakMap.from', assert => { + const { from } = WeakMap; + assert.isFunction(from); + assert.arity(from, 1); + assert.true(from([]) instanceof WeakMap); + const array = []; + assert.same(from([[array, 2]]).get(array), 2); + assert.same(from(createIterable([[array, 2]])).get(array), 2); + const pair = [{}, 1]; + const context = {}; + from([pair], function (element, index) { + assert.same(element, pair); + assert.same(index, 0); + assert.same(this, context); + return element; + }, context); +}); diff --git a/tests/unit-pure/esnext.weak-map.get-or-insert-computed.js b/tests/unit-pure/esnext.weak-map.get-or-insert-computed.js new file mode 100644 index 000000000000..a42addd5e75e --- /dev/null +++ b/tests/unit-pure/esnext.weak-map.get-or-insert-computed.js @@ -0,0 +1,49 @@ +import { STRICT } from '../helpers/constants.js'; +import WeakMap from 'core-js-pure/actual/weak-map'; + +QUnit.test('WeakMap#getOrInsertComputed', assert => { + const { getOrInsertComputed } = WeakMap.prototype; + assert.isFunction(getOrInsertComputed); + assert.arity(getOrInsertComputed, 2); + assert.name(getOrInsertComputed, 'getOrInsertComputed'); + assert.nonEnumerable(WeakMap.prototype, 'getOrInsertComputed'); + + const a = {}; + const b = {}; + + let map = new WeakMap([[a, 2]]); + assert.same(map.getOrInsertComputed(a, () => 3), 2, 'result#1'); + assert.same(map.get(a), 2, 'map#1'); + map = new WeakMap([[a, 2]]); + assert.same(map.getOrInsertComputed(b, () => 3), 3, 'result#2'); + assert.same(map.get(a), 2, 'map#2-1'); + assert.same(map.get(b), 3, 'map#2-2'); + + map = new WeakMap([[a, 2]]); + map.getOrInsertComputed(a, () => assert.avoid()); + + map = new WeakMap([[a, 2]]); + map.getOrInsertComputed(b, function (key) { + if (STRICT) assert.same(this, undefined, 'correct handler in callback'); + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(key, b, 'correct key in callback'); + }); + + map = new WeakMap([[a, 2]]); + assert.throws(() => { + map.getOrInsertComputed(1, () => assert.avoid()); + }, TypeError, 'key validation before call of callback'); + + assert.throws(() => new WeakMap().getOrInsertComputed(1, () => 3), TypeError, 'invalid key#1'); + assert.throws(() => new WeakMap().getOrInsertComputed(null, () => 3), TypeError, 'invalid key#2'); + assert.throws(() => new WeakMap().getOrInsertComputed(undefined, () => 3), TypeError, 'invalid key#3'); + assert.throws(() => new WeakMap().getOrInsertComputed(a, {}), TypeError, 'non-callable#1'); + assert.throws(() => new WeakMap().getOrInsertComputed(a, 1), TypeError, 'non-callable#2'); + assert.throws(() => new WeakMap().getOrInsertComputed(a, null), TypeError, 'non-callable#3'); + assert.throws(() => new WeakMap().getOrInsertComputed(a, undefined), TypeError, 'non-callable#4'); + assert.throws(() => new WeakMap().getOrInsertComputed(a), TypeError, 'non-callable#5'); + assert.throws(() => getOrInsertComputed.call({}, a, () => 3), TypeError, 'non-generic#1'); + assert.throws(() => getOrInsertComputed.call([], a, () => 3), TypeError, 'non-generic#2'); + assert.throws(() => getOrInsertComputed.call(undefined, a, () => 3), TypeError, 'non-generic#3'); + assert.throws(() => getOrInsertComputed.call(null, a, () => 3), TypeError, 'non-generic#4'); +}); diff --git a/tests/unit-pure/esnext.weak-map.get-or-insert.js b/tests/unit-pure/esnext.weak-map.get-or-insert.js new file mode 100644 index 000000000000..7b650a69988d --- /dev/null +++ b/tests/unit-pure/esnext.weak-map.get-or-insert.js @@ -0,0 +1,29 @@ +import WeakMap from 'core-js-pure/actual/weak-map'; + +QUnit.test('WeakMap#getOrInsert', assert => { + const { getOrInsert } = WeakMap.prototype; + assert.isFunction(getOrInsert); + assert.arity(getOrInsert, 2); + assert.name(getOrInsert, 'getOrInsert'); + assert.nonEnumerable(WeakMap.prototype, 'getOrInsert'); + + const a = {}; + const b = {}; + + let map = new WeakMap([[a, 2]]); + assert.same(map.getOrInsert(a, 3), 2, 'result#1'); + assert.same(map.get(a), 2, 'map#1'); + map = new WeakMap([[a, 2]]); + assert.same(map.getOrInsert(b, 3), 3, 'result#2'); + assert.same(map.get(a), 2, 'map#2-1'); + assert.same(map.get(b), 3, 'map#2-2'); + + assert.throws(() => new WeakMap().getOrInsert(1, 1), TypeError, 'invalid key#1'); + assert.throws(() => new WeakMap().getOrInsert(null, 1), TypeError, 'invalid key#2'); + assert.throws(() => new WeakMap().getOrInsert(undefined, 1), TypeError, 'invalid key#3'); + assert.throws(() => new WeakMap().getOrInsert(), TypeError, 'invalid key#4'); + assert.throws(() => getOrInsert.call({}, a, 1), TypeError, 'non-generic#1'); + assert.throws(() => getOrInsert.call([], a, 1), TypeError, 'non-generic#2'); + assert.throws(() => getOrInsert.call(undefined, a, 1), TypeError, 'non-generic#3'); + assert.throws(() => getOrInsert.call(null, a, 1), TypeError, 'non-generic#4'); +}); diff --git a/tests/unit-pure/esnext.weak-map.of.js b/tests/unit-pure/esnext.weak-map.of.js new file mode 100644 index 000000000000..19e6a0299b18 --- /dev/null +++ b/tests/unit-pure/esnext.weak-map.of.js @@ -0,0 +1,10 @@ +import WeakMap from 'core-js-pure/full/weak-map'; + +QUnit.test('WeakMap.of', assert => { + const { of } = WeakMap; + assert.isFunction(of); + assert.arity(of, 0); + const array = []; + assert.true(of() instanceof WeakMap); + assert.same(of([array, 2]).get(array), 2); +}); diff --git a/tests/unit-pure/esnext.weak-map.upsert.js b/tests/unit-pure/esnext.weak-map.upsert.js new file mode 100644 index 000000000000..4075e0ce6961 --- /dev/null +++ b/tests/unit-pure/esnext.weak-map.upsert.js @@ -0,0 +1,39 @@ +import WeakMap from 'core-js-pure/full/weak-map'; + +QUnit.test('WeakMap#upsert', assert => { + const { upsert } = WeakMap.prototype; + assert.isFunction(upsert); + assert.arity(upsert, 2); + assert.nonEnumerable(WeakMap.prototype, 'upsert'); + + const a = {}; + const b = {}; + + const map = new WeakMap([[a, 2]]); + assert.same(map.upsert(a, function (value) { + assert.same(arguments.length, 1, 'correct number of callback arguments'); + assert.same(value, 2, 'correct value in callback'); + return value ** 2; + }, () => { + assert.avoid(); + return 3; + }), 4, 'returns a correct value'); + assert.same(map.upsert(b, value => { + assert.avoid(); + return value ** 2; + }, function () { + assert.same(arguments.length, 0, 'correct number of callback arguments'); + return 3; + }), 3, 'returns a correct value'); + assert.same(map.get(a), 4, 'correct result #1'); + assert.same(map.get(b), 3, 'correct result #2'); + + assert.same(new WeakMap([[a, 2]]).upsert(b, null, () => 3), 3); + assert.same(new WeakMap([[a, 2]]).upsert(a, value => value ** 2), 4); + + assert.throws(() => new WeakMap().upsert(a), TypeError); + assert.throws(() => upsert.call({}, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call([], a, () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call(undefined, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); + assert.throws(() => upsert.call(null, a, () => { /* empty */ }, () => { /* empty */ }), TypeError); +}); diff --git a/tests/unit-pure/esnext.weak-set.add-all.js b/tests/unit-pure/esnext.weak-set.add-all.js new file mode 100644 index 000000000000..d00ae4b572e6 --- /dev/null +++ b/tests/unit-pure/esnext.weak-set.add-all.js @@ -0,0 +1,34 @@ +import WeakSet from 'core-js-pure/full/weak-set'; + +QUnit.test('WeakSet#addAll', assert => { + const { addAll } = WeakSet.prototype; + + assert.isFunction(addAll); + assert.arity(addAll, 0); + assert.name(addAll, 'addAll'); + assert.nonEnumerable(WeakSet.prototype, 'addAll'); + + const a = []; + const b = []; + const c = []; + + let set = new WeakSet([a]); + assert.same(set.addAll(b), set); + + set = new WeakSet([a]).addAll(b, c); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + + set = new WeakSet([a]).addAll(a, b); + assert.true(set.has(a)); + assert.true(set.has(b)); + + set = new WeakSet([a]).addAll(); + assert.true(set.has(a)); + + assert.throws(() => addAll.call({ add() { /* empty */ } }, a, b, c)); + assert.throws(() => addAll.call({}, a, b, c), TypeError); + assert.throws(() => addAll.call(undefined, a, b, c), TypeError); + assert.throws(() => addAll.call(null, a, b, c), TypeError); +}); diff --git a/tests/unit-pure/esnext.weak-set.delete-all.js b/tests/unit-pure/esnext.weak-set.delete-all.js new file mode 100644 index 000000000000..03e490e7cda1 --- /dev/null +++ b/tests/unit-pure/esnext.weak-set.delete-all.js @@ -0,0 +1,53 @@ +import WeakSet from 'core-js-pure/full/weak-set'; + +QUnit.test('WeakSet#deleteAll', assert => { + const { deleteAll } = WeakSet.prototype; + + assert.isFunction(deleteAll); + assert.arity(deleteAll, 0); + assert.name(deleteAll, 'deleteAll'); + assert.nonEnumerable(WeakSet.prototype, 'deleteAll'); + + const a = []; + const b = []; + const c = []; + const d = []; + const e = []; + + let set = new WeakSet([a, b, c]); + assert.true(set.deleteAll(a, b)); + assert.false(set.has(a)); + assert.false(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakSet([a, b, c]); + assert.false(set.deleteAll(c, d)); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.false(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakSet([a, b, c]); + assert.false(set.deleteAll(d, e)); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + set = new WeakSet([a, b, c]); + assert.true(set.deleteAll()); + assert.true(set.has(a)); + assert.true(set.has(b)); + assert.true(set.has(c)); + assert.false(set.has(d)); + assert.false(set.has(e)); + + assert.throws(() => deleteAll.call({ delete() { /* empty */ } }, a, b, c)); + assert.throws(() => deleteAll.call({}, a, b, c), TypeError); + assert.throws(() => deleteAll.call(undefined, a, b, c), TypeError); + assert.throws(() => deleteAll.call(null, a, b, c), TypeError); +}); diff --git a/tests/unit-pure/esnext.weak-set.from.js b/tests/unit-pure/esnext.weak-set.from.js new file mode 100644 index 000000000000..5c975f454359 --- /dev/null +++ b/tests/unit-pure/esnext.weak-set.from.js @@ -0,0 +1,21 @@ +import { createIterable } from '../helpers/helpers.js'; + +import WeakSet from 'core-js-pure/full/weak-set'; + +QUnit.test('WeakSet.from', assert => { + const { from } = WeakSet; + assert.isFunction(from); + assert.arity(from, 1); + assert.true(from([]) instanceof WeakSet); + const array = []; + assert.true(from([array]).has(array)); + assert.true(from(createIterable([array])).has(array)); + const object = {}; + const context = {}; + from([object], function (element, index) { + assert.same(element, object); + assert.same(index, 0); + assert.same(this, context); + return element; + }, context); +}); diff --git a/tests/unit-pure/esnext.weak-set.of.js b/tests/unit-pure/esnext.weak-set.of.js new file mode 100644 index 000000000000..7d8abafdef44 --- /dev/null +++ b/tests/unit-pure/esnext.weak-set.of.js @@ -0,0 +1,10 @@ +import WeakSet from 'core-js-pure/full/weak-set'; + +QUnit.test('WeakSet.of', assert => { + const { of } = WeakSet; + assert.isFunction(of); + assert.arity(of, 0); + const array = []; + assert.true(of() instanceof WeakSet); + assert.true(of(array).has(array)); +}); diff --git a/tests/unit-pure/helpers.get-iterator-method.js b/tests/unit-pure/helpers.get-iterator-method.js new file mode 100644 index 000000000000..a92c6a4e3164 --- /dev/null +++ b/tests/unit-pure/helpers.get-iterator-method.js @@ -0,0 +1,18 @@ +import { createIterable } from '../helpers/helpers.js'; + +import getIteratorMethod from 'core-js-pure/full/get-iterator-method'; + +QUnit.test('getIteratorMethod helper', assert => { + assert.isFunction(getIteratorMethod); + const iterable = createIterable([]); + const iterFn = getIteratorMethod(iterable); + assert.isFunction(iterFn); + assert.isIterator(iterFn.call(iterable)); + assert.isFunction(getIteratorMethod([])); + assert.isFunction(getIteratorMethod(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }())); + assert.isFunction(getIteratorMethod(Array.prototype)); + assert.same(getIteratorMethod({}), undefined); +}); diff --git a/tests/unit-pure/helpers.get-iterator.js b/tests/unit-pure/helpers.get-iterator.js new file mode 100644 index 000000000000..cd59e59e242b --- /dev/null +++ b/tests/unit-pure/helpers.get-iterator.js @@ -0,0 +1,14 @@ +import { createIterable } from '../helpers/helpers.js'; + +import getIterator from 'core-js-pure/full/get-iterator'; + +QUnit.test('getIterator helper', assert => { + assert.isFunction(getIterator); + assert.isIterator(getIterator([])); + assert.isIterator(getIterator(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }())); + assert.isIterator(getIterator(createIterable([]))); + assert.throws(() => getIterator({}), TypeError); +}); diff --git a/tests/unit-pure/helpers.is-iterable.js b/tests/unit-pure/helpers.is-iterable.js new file mode 100644 index 000000000000..6089e2771046 --- /dev/null +++ b/tests/unit-pure/helpers.is-iterable.js @@ -0,0 +1,15 @@ +import { createIterable } from '../helpers/helpers.js'; + +import isIterable from 'core-js-pure/full/is-iterable'; + +QUnit.test('isIterable helper', assert => { + assert.isFunction(isIterable); + assert.true(isIterable(createIterable([]))); + assert.true(isIterable([])); + assert.true(isIterable(function () { + // eslint-disable-next-line prefer-rest-params -- required for testing + return arguments; + }())); + assert.true(isIterable(Array.prototype)); + assert.true(isIterable({})); +}); diff --git a/tests/unit-pure/web.atob.js b/tests/unit-pure/web.atob.js new file mode 100644 index 000000000000..40cfd3c9126f --- /dev/null +++ b/tests/unit-pure/web.atob.js @@ -0,0 +1,33 @@ +// based on https://github.com/davidchambers/Base64.js/blob/master/test/base64.js +import atob from 'core-js-pure/stable/atob'; + +QUnit.test('atob', assert => { + assert.isFunction(atob); + assert.arity(atob, 1); + + assert.same(atob(''), ''); + assert.same(atob('Zg=='), 'f'); + assert.same(atob('Zm8='), 'fo'); + assert.same(atob('Zm9v'), 'foo'); + assert.same(atob('cXV1eA=='), 'quux'); + assert.same(atob('ISIjJCU='), '!"#$%'); + assert.same(atob('JicoKSor'), "&'()*+"); + assert.same(atob('LC0uLzAxMg=='), ',-./012'); + assert.same(atob('MzQ1Njc4OTo='), '3456789:'); + assert.same(atob('Ozw9Pj9AQUJD'), ';<=>?@ABC'); + assert.same(atob('REVGR0hJSktMTQ=='), 'DEFGHIJKLM'); + assert.same(atob('Tk9QUVJTVFVWV1g='), 'NOPQRSTUVWX'); + assert.same(atob('WVpbXF1eX2BhYmM='), 'YZ[\\]^_`abc'); + assert.same(atob('ZGVmZ2hpamtsbW5vcA=='), 'defghijklmnop'); + assert.same(atob('cXJzdHV2d3h5ent8fX4='), 'qrstuvwxyz{|}~'); + assert.same(atob(' '), ''); + + assert.same(atob(42), atob('42')); + assert.same(atob(null), atob('null')); + + assert.throws(() => atob(), TypeError, 'no args'); + assert.throws(() => atob('a'), 'invalid #1'); + assert.throws(() => atob('a '), 'invalid #2'); + assert.throws(() => atob('aaaaa'), 'invalid #3'); + assert.throws(() => atob('[object Object]'), 'invalid #4'); +}); diff --git a/tests/unit-pure/web.btoa.js b/tests/unit-pure/web.btoa.js new file mode 100644 index 000000000000..5913ef876560 --- /dev/null +++ b/tests/unit-pure/web.btoa.js @@ -0,0 +1,31 @@ +// based on https://github.com/davidchambers/Base64.js/blob/master/test/base64.js +import btoa from 'core-js-pure/stable/btoa'; + +QUnit.test('btoa', assert => { + assert.isFunction(btoa); + assert.arity(btoa, 1); + + assert.same(btoa(''), ''); + assert.same(btoa('f'), 'Zg=='); + assert.same(btoa('fo'), 'Zm8='); + assert.same(btoa('foo'), 'Zm9v'); + assert.same(btoa('quux'), 'cXV1eA=='); + assert.same(btoa('!"#$%'), 'ISIjJCU='); + assert.same(btoa("&'()*+"), 'JicoKSor'); + assert.same(btoa(',-./012'), 'LC0uLzAxMg=='); + assert.same(btoa('3456789:'), 'MzQ1Njc4OTo='); + assert.same(btoa(';<=>?@ABC'), 'Ozw9Pj9AQUJD'); + assert.same(btoa('DEFGHIJKLM'), 'REVGR0hJSktMTQ=='); + assert.same(btoa('NOPQRSTUVWX'), 'Tk9QUVJTVFVWV1g='); + assert.same(btoa('YZ[\\]^_`abc'), 'WVpbXF1eX2BhYmM='); + assert.same(btoa('defghijklmnop'), 'ZGVmZ2hpamtsbW5vcA=='); + assert.same(btoa('qrstuvwxyz{|}~'), 'cXJzdHV2d3h5ent8fX4='); + assert.same(btoa('qrstuvwxyz{|}~'), 'cXJzdHV2d3h5ent8fX4='); + + assert.same(btoa(42), btoa('42')); + assert.same(btoa(null), btoa('null')); + assert.same(btoa({ x: 1 }), btoa('[object Object]')); + + assert.throws(() => btoa(), TypeError, 'no args'); + assert.throws(() => btoa('✈'), 'non-ASCII'); +}); diff --git a/tests/unit-pure/web.dom-collections.iterator.js b/tests/unit-pure/web.dom-collections.iterator.js new file mode 100644 index 000000000000..25da533523a2 --- /dev/null +++ b/tests/unit-pure/web.dom-collections.iterator.js @@ -0,0 +1,60 @@ +import { GLOBAL } from '../helpers/constants.js'; + +import Symbol from 'core-js-pure/es/symbol'; +import getIteratorMethod from 'core-js-pure/stable/get-iterator-method'; + +QUnit.test('Iterable DOM collections', assert => { + let absent = true; + const collections = [ + 'CSSRuleList', + 'CSSStyleDeclaration', + 'CSSValueList', + 'ClientRectList', + 'DOMRectList', + 'DOMStringList', + 'DOMTokenList', + 'DataTransferItemList', + 'FileList', + 'HTMLAllCollection', + 'HTMLCollection', + 'HTMLFormElement', + 'HTMLSelectElement', + 'MediaList', + 'MimeTypeArray', + 'NamedNodeMap', + 'NodeList', + 'PaintRequestList', + 'Plugin', + 'PluginArray', + 'SVGLengthList', + 'SVGNumberList', + 'SVGPathSegList', + 'SVGPointList', + 'SVGStringList', + 'SVGTransformList', + 'SourceBufferList', + 'StyleSheetList', + 'TextTrackCueList', + 'TextTrackList', + 'TouchList', + ]; + + for (const name of collections) { + const Collection = GLOBAL[name]; + if (Collection) { + absent = false; + assert.same(Collection.prototype[Symbol.toStringTag], name, `${ name }::@@toStringTag is '${ name }'`); + if (Object.prototype.toString.call(Collection.prototype).slice(8, -1) === name) { + assert.isFunction(getIteratorMethod(Collection.prototype), `${ name }::@@iterator is function`); + } + } + } + + if (GLOBAL.NodeList && GLOBAL.document && document.querySelectorAll && document.querySelectorAll('div') instanceof NodeList) { + assert.isFunction(getIteratorMethod(document.querySelectorAll('div')), 'works with document.querySelectorAll'); + } + + if (absent) { + assert.required('DOM collections are absent'); + } +}); diff --git a/tests/unit-pure/web.dom-exception.constructor.js b/tests/unit-pure/web.dom-exception.constructor.js new file mode 100644 index 000000000000..ab259f6d2fe6 --- /dev/null +++ b/tests/unit-pure/web.dom-exception.constructor.js @@ -0,0 +1,82 @@ +import { DESCRIPTORS, NODE } from '../helpers/constants.js'; +import DOMException from 'core-js-pure/stable/dom-exception'; +import Symbol from 'core-js-pure/es/symbol'; + +const errors = { + IndexSizeError: { s: 'INDEX_SIZE_ERR', c: 1, m: 1 }, + DOMStringSizeError: { s: 'DOMSTRING_SIZE_ERR', c: 2, m: 0 }, + HierarchyRequestError: { s: 'HIERARCHY_REQUEST_ERR', c: 3, m: 1 }, + WrongDocumentError: { s: 'WRONG_DOCUMENT_ERR', c: 4, m: 1 }, + InvalidCharacterError: { s: 'INVALID_CHARACTER_ERR', c: 5, m: 1 }, + NoDataAllowedError: { s: 'NO_DATA_ALLOWED_ERR', c: 6, m: 0 }, + NoModificationAllowedError: { s: 'NO_MODIFICATION_ALLOWED_ERR', c: 7, m: 1 }, + NotFoundError: { s: 'NOT_FOUND_ERR', c: 8, m: 1 }, + NotSupportedError: { s: 'NOT_SUPPORTED_ERR', c: 9, m: 1 }, + InUseAttributeError: { s: 'INUSE_ATTRIBUTE_ERR', c: 10, m: 1 }, + InvalidStateError: { s: 'INVALID_STATE_ERR', c: 11, m: 1 }, + SyntaxError: { s: 'SYNTAX_ERR', c: 12, m: 1 }, + InvalidModificationError: { s: 'INVALID_MODIFICATION_ERR', c: 13, m: 1 }, + NamespaceError: { s: 'NAMESPACE_ERR', c: 14, m: 1 }, + InvalidAccessError: { s: 'INVALID_ACCESS_ERR', c: 15, m: 1 }, + ValidationError: { s: 'VALIDATION_ERR', c: 16, m: 0 }, + TypeMismatchError: { s: 'TYPE_MISMATCH_ERR', c: 17, m: 1 }, + SecurityError: { s: 'SECURITY_ERR', c: 18, m: 1 }, + NetworkError: { s: 'NETWORK_ERR', c: 19, m: 1 }, + AbortError: { s: 'ABORT_ERR', c: 20, m: 1 }, + URLMismatchError: { s: 'URL_MISMATCH_ERR', c: 21, m: 1 }, + // https://github.com/whatwg/webidl/pull/1465 + // QuotaExceededError: { s: 'QUOTA_EXCEEDED_ERR', c: 22, m: 1 }, + TimeoutError: { s: 'TIMEOUT_ERR', c: 23, m: 1 }, + InvalidNodeTypeError: { s: 'INVALID_NODE_TYPE_ERR', c: 24, m: 1 }, + DataCloneError: { s: 'DATA_CLONE_ERR', c: 25, m: 1 }, +}; + +const HAS_STACK = 'stack' in new Error('1'); + +QUnit.test('DOMException', assert => { + assert.isFunction(DOMException); + assert.arity(DOMException, 0); + assert.name(DOMException, 'DOMException'); + + let error = new DOMException({}, 'Foo'); + assert.true(error instanceof DOMException, 'new DOMException({}, "Foo") instanceof DOMException'); + assert.same(error.message, '[object Object]', 'new DOMException({}, "Foo").message'); + assert.same(error.name, 'Foo', 'new DOMException({}, "Foo").name'); + assert.same(error.code, 0, 'new DOMException({}, "Foo").code'); + assert.same(String(error), 'Foo: [object Object]', 'String(new DOMException({}, "Foo"))'); // Safari 10.1 bug + // assert.same(error.constructor, DOMException, 'new DOMException({}, "Foo").constructor'); + assert.same(error[Symbol.toStringTag], 'DOMException', 'DOMException.prototype[Symbol.toStringTag]'); + if (HAS_STACK) assert.true('stack' in error, "'stack' in new DOMException()"); + + assert.same(new DOMException().message, '', 'new DOMException().message'); + assert.same(new DOMException(undefined).message, '', 'new DOMException(undefined).message'); + assert.same(new DOMException(42).name, 'Error', 'new DOMException(42).name'); + assert.same(new DOMException(42, undefined).name, 'Error', 'new DOMException(42, undefined).name'); + + for (const name in errors) { + error = new DOMException(42, name); + assert.true(error instanceof DOMException, `new DOMException({}, "${ name }") instanceof DOMException`); + assert.same(error.message, '42', `new DOMException({}, "${ name }").message`); + assert.same(error.name, name, `new DOMException({}, "${ name }").name`); + if (errors[name].m) assert.same(error.code, errors[name].c, `new DOMException({}, "${ name }").code`); + // NodeJS and Deno set codes to deprecated errors + else if (!NODE) assert.same(error.code, 0, `new DOMException({}, "${ name }").code`); + assert.same(String(error), `${ name }: 42`, `String(new DOMException({}, "${ name }"))`); // Safari 10.1 bug + if (HAS_STACK) assert.true('stack' in error, `'stack' in new DOMException({}, "${ name }")`); + + assert.same(DOMException[errors[name].s], errors[name].c, `DOMException.${ errors[name].s }`); + assert.same(DOMException.prototype[errors[name].s], errors[name].c, `DOMException.prototype.${ errors[name].s }`); + } + + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing + assert.throws(() => DOMException(42, 'DataCloneError'), "DOMException(42, 'DataCloneError')"); + const symbol = Symbol('DOMException constructor test'); + assert.throws(() => new DOMException(symbol, 'DataCloneError'), "new DOMException(Symbol(), 'DataCloneError')"); + assert.throws(() => new DOMException(42, symbol), 'new DOMException(42, Symbol())'); + if (DESCRIPTORS) { + // assert.throws(() => DOMException.prototype.message, 'DOMException.prototype.message'); // FF55- , Safari 10.1 bug + // assert.throws(() => DOMException.prototype.name, 'DOMException.prototype.name'); // FF55-, Safari 10.1 bug bug + // assert.throws(() => DOMException.prototype.code, 'DOMException.prototype.code'); // Safari 10.1 bug + // assert.throws(() => DOMException.prototype.toString(), 'DOMException.prototype.toString()'); // FF55- bug + } +}); diff --git a/tests/unit-pure/web.queue-microtask.js b/tests/unit-pure/web.queue-microtask.js new file mode 100644 index 000000000000..a6c0239ab63a --- /dev/null +++ b/tests/unit-pure/web.queue-microtask.js @@ -0,0 +1,19 @@ +import { timeLimitedPromise } from '../helpers/helpers.js'; + +import queueMicrotask from 'core-js-pure/full/queue-microtask'; + +QUnit.test('queueMicrotask', assert => { + assert.isFunction(queueMicrotask); + assert.arity(queueMicrotask, 1); + + return timeLimitedPromise(3e3, resolve => { + let called = false; + queueMicrotask(() => { + called = true; + resolve(); + }); + assert.false(called, 'async'); + }).then(() => { + assert.required('works'); + }); +}); diff --git a/tests/unit-pure/web.self.js b/tests/unit-pure/web.self.js new file mode 100644 index 000000000000..a14ca62ca528 --- /dev/null +++ b/tests/unit-pure/web.self.js @@ -0,0 +1,6 @@ +import self from 'core-js-pure/stable/self'; + +QUnit.test('self', assert => { + assert.same(self, Object(self), 'is object'); + assert.same(self.Math, Math, 'contains globals'); +}); diff --git a/tests/unit-pure/web.set-immediate.js b/tests/unit-pure/web.set-immediate.js new file mode 100644 index 000000000000..d8c7d10214b2 --- /dev/null +++ b/tests/unit-pure/web.set-immediate.js @@ -0,0 +1,43 @@ +import { timeLimitedPromise } from '../helpers/helpers.js'; + +import setImmediate from 'core-js-pure/stable/set-immediate'; +import clearImmediate from 'core-js-pure/stable/clear-immediate'; + +QUnit.test('setImmediate / clearImmediate', assert => { + assert.isFunction(setImmediate, 'setImmediate is function'); + assert.isFunction(clearImmediate, 'clearImmediate is function'); + let called = false; + + const promise = timeLimitedPromise(1e3, resolve => { + setImmediate(() => { + called = true; + resolve(); + }); + }).then(() => { + assert.required('setImmediate works'); + }, () => { + assert.avoid('setImmediate works'); + }).then(() => { + return timeLimitedPromise(1e3, resolve => { + setImmediate((a, b) => { + resolve(a + b); + }, 'a', 'b'); + }); + }).then(it => { + assert.same(it, 'ab', 'setImmediate works with additional args'); + }, () => { + assert.avoid('setImmediate works with additional args'); + }).then(() => { + return timeLimitedPromise(50, resolve => { + clearImmediate(setImmediate(resolve)); + }); + }).then(() => { + assert.avoid('clearImmediate works'); + }, () => { + assert.required('clearImmediate works'); + }); + + assert.false(called, 'setImmediate is async'); + + return promise; +}); diff --git a/tests/unit-pure/web.set-interval.js b/tests/unit-pure/web.set-interval.js new file mode 100644 index 000000000000..12ceb44a5ba4 --- /dev/null +++ b/tests/unit-pure/web.set-interval.js @@ -0,0 +1,24 @@ +import { timeLimitedPromise } from '../helpers/helpers.js'; + +import setTimeout from 'core-js-pure/stable/set-timeout'; +import setInterval from 'core-js-pure/stable/set-interval'; + +QUnit.test('setInterval / clearInterval', assert => { + assert.isFunction(setInterval, 'setInterval is function'); + assert.isFunction(clearInterval, 'clearInterval is function'); + + return timeLimitedPromise(1e4, (resolve, reject) => { + let i = 0; + const interval = setInterval((a, b) => { + if (a + b !== 'ab' || i > 2) reject({ a, b, i }); + if (i++ === 2) { + clearInterval(interval); + setTimeout(resolve, 30); + } + }, 5, 'a', 'b'); + }).then(() => { + assert.required('setInterval & clearInterval works with additional args'); + }, (error = {}) => { + assert.avoid(`setInterval & clearInterval works with additional args: ${ error.a }, ${ error.b }, times: ${ error.i }`); + }); +}); diff --git a/tests/unit-pure/web.set-timeout.js b/tests/unit-pure/web.set-timeout.js new file mode 100644 index 000000000000..c7a3ed64fb57 --- /dev/null +++ b/tests/unit-pure/web.set-timeout.js @@ -0,0 +1,24 @@ +import { timeLimitedPromise } from '../helpers/helpers.js'; + +import setTimeout from 'core-js-pure/stable/set-timeout'; + +QUnit.test('setTimeout / clearTimeout', assert => { + assert.isFunction(setTimeout, 'setTimeout is function'); + assert.isFunction(clearTimeout, 'clearTimeout is function'); + + return timeLimitedPromise(1e3, resolve => { + setTimeout((a, b) => { resolve(a + b); }, 10, 'a', 'b'); + }).then(it => { + assert.same(it, 'ab', 'setTimeout works with additional args'); + }, () => { + assert.avoid('setTimeout works with additional args'); + }).then(() => { + return timeLimitedPromise(50, resolve => { + clearTimeout(setTimeout(resolve, 10)); + }); + }).then(() => { + assert.avoid('clearImmediate works with wrapped setTimeout'); + }, () => { + assert.required('clearImmediate works with wrapped setTimeout'); + }); +}); diff --git a/tests/unit-pure/web.structured-clone.js b/tests/unit-pure/web.structured-clone.js new file mode 100644 index 000000000000..f2c365b04cf7 --- /dev/null +++ b/tests/unit-pure/web.structured-clone.js @@ -0,0 +1,486 @@ +// Originally from: https://github.com/web-platform-tests/wpt/blob/4b35e758e2fc4225368304b02bcec9133965fd1a/IndexedDB/structured-clone.any.js +// Copyright © web-platform-tests contributors. Available under the 3-Clause BSD License. +/* eslint-disable es/no-error-cause, es/no-typed-arrays -- safe */ +import { GLOBAL, NODE, BUN } from '../helpers/constants.js'; +import { bufferToArray, fromSource } from '../helpers/helpers.js'; + +import structuredClone from 'core-js-pure/stable/structured-clone'; +import from from 'core-js-pure/es/array/from'; +import assign from 'core-js-pure/es/object/assign'; +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; +import keys from 'core-js-pure/es/object/keys'; +import Symbol from 'core-js-pure/es/symbol'; +import Map from 'core-js-pure/es/map'; +import Set from 'core-js-pure/es/set'; +import AggregateError from 'core-js-pure/es/aggregate-error'; +import DOMException from 'core-js-pure/stable/dom-exception'; + +QUnit.module('structuredClone', () => { + QUnit.test('identity', assert => { + assert.isFunction(structuredClone, 'structuredClone is a function'); + assert.name(structuredClone, 'structuredClone'); + assert.arity(structuredClone, 1); + assert.throws(() => structuredClone(), 'throws without arguments'); + assert.same(structuredClone(1, null), 1, 'null as options'); + assert.same(structuredClone(1, undefined), 1, 'undefined as options'); + }); + + function cloneTest(value, verifyFunc) { + verifyFunc(value, structuredClone(value)); + } + + // Specialization of cloneTest() for objects, with common asserts. + function cloneObjectTest(assert, value, verifyFunc) { + cloneTest(value, (orig, clone) => { + assert.notSame(orig, clone, 'clone should have different reference'); + assert.same(typeof clone, 'object', 'clone should be an object'); + // https://github.com/qunitjs/node-qunit/issues/146 + assert.true(getPrototypeOf(orig) === getPrototypeOf(clone), 'clone should have same prototype'); + verifyFunc(orig, clone); + }); + } + + // ECMAScript types + + // Primitive values: Undefined, Null, Boolean, Number, BigInt, String + const booleans = [false, true]; + const numbers = [ + NaN, + -Infinity, + -Number.MAX_VALUE, + -0xFFFFFFFF, + -0x80000000, + -0x7FFFFFFF, + -1, + -Number.MIN_VALUE, + -0, + 0, + 1, + Number.MIN_VALUE, + 0x7FFFFFFF, + 0x80000000, + 0xFFFFFFFF, + Number.MAX_VALUE, + Infinity, + ]; + + const bigints = fromSource(`[ + -12345678901234567890n, + -1n, + 0n, + 1n, + 12345678901234567890n, + ]`) || []; + + const strings = [ + '', + 'this is a sample string', + 'null(\0)', + ]; + + QUnit.test('primitives', assert => { + const primitives = [undefined, null, ...booleans, ...numbers, ...bigints, ...strings]; + + for (const value of primitives) cloneTest(value, (orig, clone) => { + assert.same(orig, clone, 'primitives should be same after cloned'); + }); + }); + + // "Primitive" Objects (Boolean, Number, BigInt, String) + QUnit.test('primitive objects', assert => { + const primitives = [...booleans, ...numbers, ...bigints, ...strings]; + + for (const value of primitives) cloneObjectTest(assert, Object(value), (orig, clone) => { + assert.same(orig.valueOf(), clone.valueOf(), 'primitive wrappers should have same value'); + }); + }); + + // Dates + QUnit.test('Date', assert => { + const dates = [ + new Date(-1e13), + new Date(-1e12), + new Date(-1e9), + new Date(-1e6), + new Date(-1e3), + new Date(0), + new Date(1e3), + new Date(1e6), + new Date(1e9), + new Date(1e12), + new Date(1e13), + ]; + + for (const date of dates) cloneTest(date, (orig, clone) => { + assert.notSame(orig, clone); + assert.same(typeof clone, 'object'); + assert.same(getPrototypeOf(orig), getPrototypeOf(clone)); + assert.same(orig.valueOf(), clone.valueOf()); + }); + }); + + // Regular Expressions + QUnit.test('RegExp', assert => { + const regexes = [ + new RegExp(), + /abc/, + /abc/g, + /abc/i, + /abc/gi, + /abc/, + /abc/g, + /abc/i, + /abc/gi, + ]; + + const giuy = fromSource('/abc/giuy'); + if (giuy) regexes.push(giuy); + + for (const regex of regexes) cloneObjectTest(assert, regex, (orig, clone) => { + assert.same(orig.toString(), clone.toString(), `regex ${ regex }`); + }); + }); + + if (fromSource('ArrayBuffer.prototype.slice || DataView')) { + // ArrayBuffer + if (typeof Uint8Array == 'function') QUnit.test('ArrayBuffer', assert => { // Crashes + cloneObjectTest(assert, new Uint8Array([0, 1, 254, 255]).buffer, (orig, clone) => { + assert.arrayEqual(new Uint8Array(orig), new Uint8Array(clone)); + }); + }); + + // TODO SharedArrayBuffer + + // Array Buffer Views + if (typeof Int8Array != 'undefined') { + QUnit.test('%TypedArray%', assert => { + const arrays = [ + new Uint8Array([]), + new Uint8Array([0, 1, 254, 255]), + new Uint16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF]), + new Uint32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF]), + new Int8Array([0, 1, 254, 255]), + new Int16Array([0x0000, 0x0001, 0xFFFE, 0xFFFF]), + new Int32Array([0x00000000, 0x00000001, 0xFFFFFFFE, 0xFFFFFFFF]), + new Float32Array([-Infinity, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, Infinity, NaN]), + new Float64Array([-Infinity, -Number.MAX_VALUE, -Number.MIN_VALUE, 0, Number.MIN_VALUE, Number.MAX_VALUE, Infinity, NaN]), + ]; + + if (typeof Uint8ClampedArray != 'undefined') { + arrays.push(new Uint8ClampedArray([0, 1, 254, 255])); + } + + for (const array of arrays) cloneObjectTest(assert, array, (orig, clone) => { + assert.arrayEqual(orig, clone); + }); + }); + + if (typeof DataView != 'undefined') QUnit.test('DataView', assert => { + const array = new Int8Array([1, 2, 3, 4]); + const view = new DataView(array.buffer); + + cloneObjectTest(assert, array, (orig, clone) => { + assert.same(orig.byteLength, clone.byteLength); + assert.same(orig.byteOffset, clone.byteOffset); + assert.arrayEqual(new Int8Array(view.buffer), array); + }); + }); + } + + if ('resizable' in ArrayBuffer.prototype) { + QUnit.test('Resizable ArrayBuffer', assert => { + const array = [1, 2, 3, 4, 5, 6, 7, 8]; + + // eslint-disable-next-line es/no-resizable-and-growable-arraybuffers -- safe + let buffer = new ArrayBuffer(8, { maxByteLength: 16 }); + new Int8Array(buffer).set(array); + let copy = structuredClone(buffer); + assert.arrayEqual(bufferToArray(copy), array, 'resizable-ab-1'); + assert.true(copy.resizable, 'resizable-ab-1'); + + buffer = new ArrayBuffer(8); + new Int8Array(buffer).set(array); + copy = structuredClone(buffer); + assert.arrayEqual(bufferToArray(copy), array, 'non-resizable-ab-1'); + assert.false(copy.resizable, 'non-resizable-ab-1'); + + // eslint-disable-next-line es/no-resizable-and-growable-arraybuffers -- safe + buffer = new ArrayBuffer(8, { maxByteLength: 16 }); + let tarray = new Int8Array(buffer); + tarray.set(array); + copy = structuredClone(tarray).buffer; + assert.arrayEqual(bufferToArray(copy), array, 'resizable-ab-2'); + assert.true(copy.resizable, 'resizable-ab-2'); + + buffer = new ArrayBuffer(8); + tarray = new Int8Array(buffer); + tarray.set(array); + copy = structuredClone(tarray).buffer; + assert.arrayEqual(bufferToArray(copy), array, 'non-resizable-ab-2'); + assert.false(copy.resizable, 'non-resizable-ab-2'); + }); + } + } + + // Map + QUnit.test('Map', assert => { + cloneObjectTest(assert, new Map([[1, 2], [3, 4]]), (orig, clone) => { + assert.deepEqual(from(orig.keys()), from(clone.keys())); + assert.deepEqual(from(orig.values()), from(clone.values())); + }); + }); + + // Set + QUnit.test('Set', assert => { + cloneObjectTest(assert, new Set([1, 2, 3, 4]), (orig, clone) => { + assert.deepEqual(from(orig.values()), from(clone.values())); + }); + }); + + // Error + QUnit.test('Error', assert => { + const errors = [ + ['Error', new Error()], + ['Error', new Error('msg', { cause: 42 })], + ['EvalError', new EvalError()], + ['EvalError', new EvalError('msg', { cause: 42 })], + ['RangeError', new RangeError()], + ['RangeError', new RangeError('msg', { cause: 42 })], + ['ReferenceError', new ReferenceError()], + ['ReferenceError', new ReferenceError('msg', { cause: 42 })], + ['SyntaxError', new SyntaxError()], + ['SyntaxError', new SyntaxError('msg', { cause: 42 })], + ['TypeError', new TypeError()], + ['TypeError', new TypeError('msg', { cause: 42 })], + ['URIError', new URIError()], + ['URIError', new URIError('msg', { cause: 42 })], + ['AggregateError', new AggregateError([1, 2])], + ['AggregateError', new AggregateError([1, 2], 'msg', { cause: 42 })], + ]; + + const compile = fromSource('WebAssembly.CompileError()'); + const link = fromSource('WebAssembly.LinkError()'); + const runtime = fromSource('WebAssembly.RuntimeError()'); + + if (compile && compile.name === 'CompileError') errors.push(['CompileError', compile]); + if (link && link.name === 'LinkError') errors.push(['LinkError', link]); + if (runtime && runtime.name === 'RuntimeError') errors.push(['RuntimeError', runtime]); + + for (const [name, error] of errors) cloneObjectTest(assert, error, (orig, clone) => { + assert.same(orig.constructor, clone.constructor, `${ name }#constructor`); + assert.same(orig.name, clone.name, `${ name }#name`); + assert.same(orig.message, clone.message, `${ name }#message`); + assert.same(orig.stack, clone.stack, `${ name }#stack`); + assert.same(orig.cause, clone.cause, `${ name }#cause`); + assert.deepEqual(orig.errors, clone.errors, `${ name }#errors`); + }); + }); + + // Arrays + QUnit.test('Array', assert => { + const arrays = [ + [], + [1, 2, 3], + Array(1), + assign( + ['foo', 'bar'], + { 10: true, 11: false, 20: 123, 21: 456, 30: null }), + assign( + ['foo', 'bar'], + { a: true, b: false, foo: 123, bar: 456, '': null }), + ]; + + for (const array of arrays) cloneObjectTest(assert, array, (orig, clone) => { + assert.deepEqual(orig, clone, `array content should be same: ${ array }`); + assert.deepEqual(orig.length, clone.length, `array length should be same: ${ array }`); + assert.deepEqual(keys(orig), keys(clone), `array key should be same: ${ array }`); + for (const key of keys(orig)) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + + // Objects + QUnit.test('Object', assert => { + cloneObjectTest(assert, { foo: true, bar: false }, (orig, clone) => { + assert.deepEqual(keys(orig), keys(clone)); + for (const key of keys(orig)) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + + // [Serializable] Platform objects + + // Geometry types + if (typeof DOMMatrix == 'function') { + QUnit.test('Geometry types, DOMMatrix', assert => { + cloneObjectTest(assert, new DOMMatrix(), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMMatrixReadOnly == 'function' && typeof DOMMatrixReadOnly.fromMatrix == 'function') { + QUnit.test('Geometry types, DOMMatrixReadOnly', assert => { + cloneObjectTest(assert, new DOMMatrixReadOnly(), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMPoint == 'function') { + QUnit.test('Geometry types, DOMPoint', assert => { + cloneObjectTest(assert, new DOMPoint(1, 2, 3, 4), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMPointReadOnly == 'function' && typeof DOMPointReadOnly.fromPoint == 'function') { + QUnit.test('Geometry types, DOMPointReadOnly', assert => { + cloneObjectTest(assert, new DOMPointReadOnly(1, 2, 3, 4), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMQuad == 'function' && typeof DOMPoint == 'function') { + QUnit.test('Geometry types, DOMQuad', assert => { + cloneObjectTest(assert, new DOMQuad( + new DOMPoint(1, 2, 3, 4), + new DOMPoint(2, 2, 3, 4), + new DOMPoint(1, 3, 3, 4), + new DOMPoint(1, 2, 4, 4), + ), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.deepEqual(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (fromSource('new DOMRect(1, 2, 3, 4)')) { + QUnit.test('Geometry types, DOMRect', assert => { + cloneObjectTest(assert, new DOMRect(1, 2, 3, 4), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + if (typeof DOMRectReadOnly == 'function' && typeof DOMRectReadOnly.fromRect == 'function') { + QUnit.test('Geometry types, DOMRectReadOnly', assert => { + cloneObjectTest(assert, new DOMRectReadOnly(1, 2, 3, 4), (orig, clone) => { + for (const key of keys(getPrototypeOf(orig))) { + assert.same(orig[key], clone[key], `Property ${ key }`); + } + }); + }); + } + + // Safari 8- does not support `{ colorSpace }` option + if (fromSource('new ImageData(new ImageData(8, 8).data, 8, 8, { colorSpace: new ImageData(8, 8).colorSpace })')) { + QUnit.test('ImageData', assert => { + const imageData = new ImageData(8, 8); + for (let i = 0; i < 256; ++i) { + imageData.data[i] = i; + } + cloneObjectTest(assert, imageData, (orig, clone) => { + assert.same(orig.width, clone.width); + assert.same(orig.height, clone.height); + assert.same(orig.colorSpace, clone.colorSpace); + assert.arrayEqual(orig.data, clone.data); + }); + }); + } + + if (fromSource('new Blob(["test"])')) QUnit.test('Blob', assert => { + cloneObjectTest( + assert, + new Blob(['This is a test.'], { type: 'a/b' }), + (orig, clone) => { + assert.same(orig.size, clone.size); + assert.same(orig.type, clone.type); + // TODO: async + // assert.same(await orig.text(), await clone.text()); + }); + }); + + QUnit.test('DOMException', assert => { + const errors = [ + new DOMException(), + new DOMException('foo', 'DataCloneError'), + ]; + + for (const error of errors) cloneObjectTest(assert, error, (orig, clone) => { + assert.same(orig.name, clone.name); + assert.same(orig.message, clone.message); + assert.same(orig.code, clone.code); + assert.same(orig.stack, clone.stack); + }); + }); + + // https://github.com/oven-sh/bun/issues/11696 + if (!BUN && fromSource('new File(["test"], "foo.txt")')) QUnit.test('File', assert => { + cloneObjectTest( + assert, + new File(['This is a test.'], 'foo.txt', { type: 'c/d' }), + (orig, clone) => { + assert.same(orig.size, clone.size); + assert.same(orig.type, clone.type); + assert.same(orig.name, clone.name); + assert.same(orig.lastModified, clone.lastModified); + // TODO: async + // assert.same(await orig.text(), await clone.text()); + }); + }); + + // FileList + if (fromSource('new File(["test"], "foo.txt")') && fromSource('new DataTransfer() && "items" in DataTransfer.prototype')) QUnit.test('FileList', assert => { + const transfer = new DataTransfer(); + transfer.items.add(new File(['test'], 'foo.txt')); + cloneObjectTest( + assert, + transfer.files, + (orig, clone) => { + assert.same(1, clone.length); + assert.same(orig[0].size, clone[0].size); + assert.same(orig[0].type, clone[0].type); + assert.same(orig[0].name, clone[0].name); + assert.same(orig[0].lastModified, clone[0].lastModified); + }, + ); + }); + + // Non-serializable types + QUnit.test('Non-serializable types', assert => { + const nons = [ + function () { return 1; }, + Symbol('desc'), + GLOBAL, + ]; + + const event = fromSource('new Event("")'); + const port = fromSource('new MessageChannel().port1'); + + // NodeJS events are simple objects + if (event && !NODE) nons.push(event); + if (port) nons.push(port); + + for (const it of nons) { + // native NodeJS `structuredClone` throws a `TypeError` on transferable non-serializable instead of `DOMException` + // https://github.com/nodejs/node/issues/40841 + assert.throws(() => structuredClone(it)); + } + }); +}); diff --git a/tests/unit-pure/web.url-search-params.js b/tests/unit-pure/web.url-search-params.js new file mode 100644 index 000000000000..a8a92b7283d2 --- /dev/null +++ b/tests/unit-pure/web.url-search-params.js @@ -0,0 +1,899 @@ +import { DESCRIPTORS, BUN } from '../helpers/constants.js'; +import { createIterable } from '../helpers/helpers.js'; + +import getPrototypeOf from 'core-js-pure/es/object/get-prototype-of'; +import getOwnPropertyDescriptor from 'core-js-pure/es/object/get-own-property-descriptor'; +import Symbol from 'core-js-pure/es/symbol'; +import URL from 'core-js-pure/stable/url'; +import URLSearchParams from 'core-js-pure/stable/url-search-params'; + +QUnit.test('URLSearchParams', assert => { + assert.isFunction(URLSearchParams); + assert.arity(URLSearchParams, 0); + + assert.same(String(new URLSearchParams()), ''); + assert.same(String(new URLSearchParams('')), ''); + assert.same(String(new URLSearchParams('a=b')), 'a=b'); + assert.same(String(new URLSearchParams(new URLSearchParams('a=b'))), 'a=b'); + assert.same(String(new URLSearchParams([])), ''); + assert.same(String(new URLSearchParams([[1, 2], ['a', 'b']])), '1=2&a=b'); + assert.same(String(new URLSearchParams(createIterable([createIterable(['a', 'b']), createIterable(['c', 'd'])]))), 'a=b&c=d'); + assert.same(String(new URLSearchParams({})), ''); + assert.same(String(new URLSearchParams({ 1: 2, a: 'b' })), '1=2&a=b'); + + assert.same(String(new URLSearchParams('?a=b')), 'a=b', 'leading ? should be ignored'); + assert.same(String(new URLSearchParams('??a=b')), '%3Fa=b'); + assert.same(String(new URLSearchParams('?')), ''); + assert.same(String(new URLSearchParams('??')), '%3F='); + + assert.same(String(new URLSearchParams('a=b c')), 'a=b+c'); + assert.same(String(new URLSearchParams('a=b&b=c&a=d')), 'a=b&b=c&a=d'); + + assert.same(String(new URLSearchParams('a==')), 'a=%3D'); + assert.same(String(new URLSearchParams('a=b=')), 'a=b%3D'); + assert.same(String(new URLSearchParams('a=b=c')), 'a=b%3Dc'); + assert.same(String(new URLSearchParams('a==b')), 'a=%3Db'); + + let params = new URLSearchParams('a=b'); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.false(params.has('b'), 'search params object has not got name "b"'); + + params = new URLSearchParams('a=b&c'); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.true(params.has('c'), 'search params object has name "c"'); + + params = new URLSearchParams('&a&&& &&&&&a+b=& c&m%c3%b8%c3%b8'); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.true(params.has('a b'), 'search params object has name "a b"'); + assert.true(params.has(' '), 'search params object has name " "'); + assert.false(params.has('c'), 'search params object did not have the name "c"'); + assert.true(params.has(' c'), 'search params object has name " c"'); + assert.true(params.has('møø'), 'search params object has name "møø"'); + + params = new URLSearchParams('a=b+c'); + assert.same(params.get('a'), 'b c', 'parse +'); + params = new URLSearchParams('a+b=c'); + assert.same(params.get('a b'), 'c', 'parse +'); + + params = new URLSearchParams('a=b c'); + assert.same(params.get('a'), 'b c', 'parse " "'); + params = new URLSearchParams('a b=c'); + assert.same(params.get('a b'), 'c', 'parse " "'); + + params = new URLSearchParams('a=b%20c'); + assert.same(params.get('a'), 'b c', 'parse %20'); + params = new URLSearchParams('a%20b=c'); + assert.same(params.get('a b'), 'c', 'parse %20'); + + params = new URLSearchParams('a=b\0c'); + assert.same(params.get('a'), 'b\0c', 'parse \\0'); + params = new URLSearchParams('a\0b=c'); + assert.same(params.get('a\0b'), 'c', 'parse \\0'); + + params = new URLSearchParams('a=b%00c'); + assert.same(params.get('a'), 'b\0c', 'parse %00'); + params = new URLSearchParams('a%00b=c'); + assert.same(params.get('a\0b'), 'c', 'parse %00'); + + params = new URLSearchParams('a=b\u2384'); + assert.same(params.get('a'), 'b\u2384', 'parse \u2384'); + params = new URLSearchParams('a\u2384b=c'); + assert.same(params.get('a\u2384b'), 'c', 'parse \u2384'); + + params = new URLSearchParams('a=b%e2%8e%84'); + assert.same(params.get('a'), 'b\u2384', 'parse %e2%8e%84'); + params = new URLSearchParams('a%e2%8e%84b=c'); + assert.same(params.get('a\u2384b'), 'c', 'parse %e2%8e%84'); + + params = new URLSearchParams('a=b\uD83D\uDCA9c'); + assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse \uD83D\uDCA9'); + params = new URLSearchParams('a\uD83D\uDCA9b=c'); + assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse \uD83D\uDCA9'); + + params = new URLSearchParams('a=b%f0%9f%92%a9c'); + assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); + params = new URLSearchParams('a%f0%9f%92%a9b=c'); + assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); + + params = new URLSearchParams(); + params.set('query', '+15555555555'); + assert.same(params.toString(), 'query=%2B15555555555'); + assert.same(params.get('query'), '+15555555555', 'parse encoded +'); + params = new URLSearchParams(params.toString()); + assert.same(params.get('query'), '+15555555555', 'parse encoded +'); + + params = new URLSearchParams('b=%2sf%2a'); + assert.same(params.get('b'), '%2sf*', 'parse encoded %2sf%2a'); + params = new URLSearchParams('b=%%2a'); + assert.same(params.get('b'), '%*', 'parse encoded b=%%2a'); + + params = new URLSearchParams('a=b\u2384'); + assert.same(params.get('a'), 'b\u2384', 'parse \u2384'); + params = new URLSearchParams('a\u2384b=c'); + assert.same(params.get('a\u2384b'), 'c', 'parse \u2384'); + + params = new URLSearchParams('a=b%e2%8e%84'); + assert.same(params.get('a'), 'b\u2384', 'parse b%e2%8e%84'); + params = new URLSearchParams('a%e2%8e%84b=c'); + assert.same(params.get('a\u2384b'), 'c', 'parse b%e2%8e%84'); + + params = new URLSearchParams('a=b\uD83D\uDCA9c'); + assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse \uD83D\uDCA9'); + params = new URLSearchParams('a\uD83D\uDCA9b=c'); + assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse \uD83D\uDCA9'); + + params = new URLSearchParams('a=b%f0%9f%92%a9c'); + assert.same(params.get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); + params = new URLSearchParams('a%f0%9f%92%a9b=c'); + assert.same(params.get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); + + assert.same(String(new URLSearchParams('%C2')), '%EF%BF%BD='); + assert.same(String(new URLSearchParams('%F0%9F%D0%90')), '%EF%BF%BD%D0%90='); + assert.same(String(new URLSearchParams('%25')), '%25='); + assert.same(String(new URLSearchParams('%4')), '%254='); + + const testData = [ + { input: '?a=%', output: [['a', '%']], name: 'handling %' }, + { input: { '+': '%C2' }, output: [['+', '%C2']], name: 'object with +' }, + { input: { c: 'x', a: '?' }, output: [['c', 'x'], ['a', '?']], name: 'object with two keys' }, + { input: [['c', 'x'], ['a', '?']], output: [['c', 'x'], ['a', '?']], name: 'array with two keys' }, + // eslint-disable-next-line @stylistic/max-len -- ignore + // !!! { input: { 'a\0b': '42', 'c\uD83D': '23', dሴ: 'foo' }, output: [['a\0b', '42'], ['c\uFFFD', '23'], ['d\u1234', 'foo']], name: 'object with NULL, non-ASCII, and surrogate keys' }, + ]; + + for (const { input, output, name } of testData) { + params = new URLSearchParams(input); + let i = 0; + params.forEach((value, key) => { + const [reqKey, reqValue] = output[i++]; + assert.same(key, reqKey, `construct with ${ name }`); + assert.same(value, reqValue, `construct with ${ name }`); + }); + } + + // https://github.com/oven-sh/bun/issues/9253 + if (!BUN) assert.throws(() => { + // eslint-disable-next-line sonarjs/inconsistent-function-call -- required for testing + URLSearchParams(''); + }, 'throws w/o `new`'); + + assert.throws(() => { + new URLSearchParams([[1, 2, 3]]); + }, 'sequence elements must be pairs #1'); + + assert.throws(() => { + new URLSearchParams([createIterable([createIterable([1, 2, 3])])]); + }, 'sequence elements must be pairs #2'); + + assert.throws(() => { + new URLSearchParams([[1]]); + }, 'sequence elements must be pairs #3'); + + assert.throws(() => { + new URLSearchParams([createIterable([createIterable([1])])]); + }, 'sequence elements must be pairs #4'); +}); + +QUnit.test('URLSearchParams#append', assert => { + const { append } = URLSearchParams.prototype; + assert.isFunction(append); + assert.arity(append, 2); + assert.enumerable(URLSearchParams.prototype, 'append'); + + assert.same(new URLSearchParams().append('a', 'b'), undefined, 'void'); + + let params = new URLSearchParams(); + params.append('a', 'b'); + assert.same(String(params), 'a=b'); + params.append('a', 'b'); + assert.same(String(params), 'a=b&a=b'); + params.append('a', 'c'); + assert.same(String(params), 'a=b&a=b&a=c'); + + params = new URLSearchParams(); + params.append('', ''); + assert.same(String(params), '='); + params.append('', ''); + assert.same(String(params), '=&='); + + params = new URLSearchParams(); + params.append(undefined, undefined); + assert.same(String(params), 'undefined=undefined'); + params.append(undefined, undefined); + assert.same(String(params), 'undefined=undefined&undefined=undefined'); + + params = new URLSearchParams(); + params.append(null, null); + assert.same(String(params), 'null=null'); + params.append(null, null); + assert.same(String(params), 'null=null&null=null'); + + params = new URLSearchParams(); + params.append('first', 1); + params.append('second', 2); + params.append('third', ''); + params.append('first', 10); + assert.true(params.has('first'), 'search params object has name "first"'); + assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); + assert.same(params.get('second'), '2', 'search params object has name "second" with value "2"'); + assert.same(params.get('third'), '', 'search params object has name "third" with value ""'); + params.append('first', 10); + assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); + + assert.throws(() => { + return new URLSearchParams('').append(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#delete', assert => { + const $delete = URLSearchParams.prototype.delete; + assert.isFunction($delete); + assert.arity($delete, 1); + assert.enumerable(URLSearchParams.prototype, 'delete'); + + let params = new URLSearchParams('a=b&c=d'); + params.delete('a'); + assert.same(String(params), 'c=d'); + + params = new URLSearchParams('a=a&b=b&a=a&c=c'); + params.delete('a'); + assert.same(String(params), 'b=b&c=c'); + + params = new URLSearchParams('a=a&=&b=b&c=c'); + params.delete(''); + assert.same(String(params), 'a=a&b=b&c=c'); + + params = new URLSearchParams('a=a&null=null&b=b'); + params.delete(null); + assert.same(String(params), 'a=a&b=b'); + + params = new URLSearchParams('a=a&undefined=undefined&b=b'); + params.delete(undefined); + assert.same(String(params), 'a=a&b=b'); + + params = new URLSearchParams(); + params.append('first', 1); + assert.true(params.has('first'), 'search params object has name "first"'); + assert.same(params.get('first'), '1', 'search params object has name "first" with value "1"'); + params.delete('first'); + assert.false(params.has('first'), 'search params object has no "first" name'); + params.append('first', 1); + params.append('first', 10); + params.delete('first'); + assert.false(params.has('first'), 'search params object has no "first" name'); + + params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4'); + params.delete('a', 2); + assert.same(String(params), 'a=1&a=null&a=3&b=4'); + + params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4'); + params.delete('a', null); + assert.same(String(params), 'a=1&a=2&a=3&b=4'); + + params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4'); + params.delete('a', undefined); + assert.same(String(params), 'b=4'); + + if (DESCRIPTORS) { + let url = new URL('http://example.com/?param1¶m2'); + url.searchParams.delete('param1'); + url.searchParams.delete('param2'); + assert.same(String(url), 'http://example.com/', 'url.href does not have ?'); + assert.same(url.search, '', 'url.search does not have ?'); + + url = new URL('http://example.com/?'); + url.searchParams.delete('param1'); + // assert.same(String(url), 'http://example.com/', 'url.href does not have ?'); // Safari bug + assert.same(url.search, '', 'url.search does not have ?'); + } + + assert.throws(() => { + return new URLSearchParams('').delete(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#get', assert => { + const { get } = URLSearchParams.prototype; + assert.isFunction(get); + assert.arity(get, 1); + assert.enumerable(URLSearchParams.prototype, 'get'); + + let params = new URLSearchParams('a=b&c=d'); + assert.same(params.get('a'), 'b'); + assert.same(params.get('c'), 'd'); + assert.same(params.get('e'), null); + + params = new URLSearchParams('a=b&c=d&a=e'); + assert.same(params.get('a'), 'b'); + + params = new URLSearchParams('=b&c=d'); + assert.same(params.get(''), 'b'); + + params = new URLSearchParams('a=&c=d&a=e'); + assert.same(params.get('a'), ''); + + params = new URLSearchParams('first=second&third&&'); + assert.true(params.has('first'), 'Search params object has name "first"'); + assert.same(params.get('first'), 'second', 'Search params object has name "first" with value "second"'); + assert.same(params.get('third'), '', 'Search params object has name "third" with the empty value.'); + assert.same(params.get('fourth'), null, 'Search params object has no "fourth" name and value.'); + + assert.same(new URLSearchParams('a=b c').get('a'), 'b c'); + assert.same(new URLSearchParams('a b=c').get('a b'), 'c'); + + assert.same(new URLSearchParams('a=b%20c').get('a'), 'b c', 'parse %20'); + assert.same(new URLSearchParams('a%20b=c').get('a b'), 'c', 'parse %20'); + + assert.same(new URLSearchParams('a=b\0c').get('a'), 'b\0c', 'parse \\0'); + assert.same(new URLSearchParams('a\0b=c').get('a\0b'), 'c', 'parse \\0'); + + assert.same(new URLSearchParams('a=b%2Bc').get('a'), 'b+c', 'parse %2B'); + assert.same(new URLSearchParams('a%2Bb=c').get('a+b'), 'c', 'parse %2B'); + + assert.same(new URLSearchParams('a=b%00c').get('a'), 'b\0c', 'parse %00'); + assert.same(new URLSearchParams('a%00b=c').get('a\0b'), 'c', 'parse %00'); + + assert.same(new URLSearchParams('a==').get('a'), '=', 'parse ='); + assert.same(new URLSearchParams('a=b=').get('a'), 'b=', 'parse ='); + assert.same(new URLSearchParams('a=b=c').get('a'), 'b=c', 'parse ='); + assert.same(new URLSearchParams('a==b').get('a'), '=b', 'parse ='); + + assert.same(new URLSearchParams('a=b\u2384').get('a'), 'b\u2384', 'parse \\u2384'); + assert.same(new URLSearchParams('a\u2384b=c').get('a\u2384b'), 'c', 'parse \\u2384'); + + assert.same(new URLSearchParams('a=b%e2%8e%84').get('a'), 'b\u2384', 'parse %e2%8e%84'); + assert.same(new URLSearchParams('a%e2%8e%84b=c').get('a\u2384b'), 'c', 'parse %e2%8e%84'); + + assert.same(new URLSearchParams('a=b\uD83D\uDCA9c').get('a'), 'b\uD83D\uDCA9c', 'parse \\uD83D\\uDCA9'); + assert.same(new URLSearchParams('a\uD83D\uDCA9b=c').get('a\uD83D\uDCA9b'), 'c', 'parse \\uD83D\\uDCA9'); + + assert.same(new URLSearchParams('a=b%f0%9f%92%a9c').get('a'), 'b\uD83D\uDCA9c', 'parse %f0%9f%92%a9'); + assert.same(new URLSearchParams('a%f0%9f%92%a9b=c').get('a\uD83D\uDCA9b'), 'c', 'parse %f0%9f%92%a9'); + + assert.same(new URLSearchParams('=').get(''), '', 'parse ='); + + assert.throws(() => { + return new URLSearchParams('').get(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#getAll', assert => { + const { getAll } = URLSearchParams.prototype; + assert.isFunction(getAll); + assert.arity(getAll, 1); + assert.enumerable(URLSearchParams.prototype, 'getAll'); + + let params = new URLSearchParams('a=b&c=d'); + assert.arrayEqual(params.getAll('a'), ['b']); + assert.arrayEqual(params.getAll('c'), ['d']); + assert.arrayEqual(params.getAll('e'), []); + + params = new URLSearchParams('a=b&c=d&a=e'); + assert.arrayEqual(params.getAll('a'), ['b', 'e']); + + params = new URLSearchParams('=b&c=d'); + assert.arrayEqual(params.getAll(''), ['b']); + + params = new URLSearchParams('a=&c=d&a=e'); + assert.arrayEqual(params.getAll('a'), ['', 'e']); + + params = new URLSearchParams('a=1&a=2&a=3&a'); + assert.arrayEqual(params.getAll('a'), ['1', '2', '3', ''], 'search params object has expected name "a" values'); + params.set('a', 'one'); + assert.arrayEqual(params.getAll('a'), ['one'], 'search params object has expected name "a" values'); + + assert.throws(() => { + return new URLSearchParams('').getAll(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#has', assert => { + const { has } = URLSearchParams.prototype; + assert.isFunction(has); + assert.arity(has, 1); + assert.enumerable(URLSearchParams.prototype, 'has'); + + let params = new URLSearchParams('a=b&c=d'); + assert.true(params.has('a')); + assert.true(params.has('c')); + assert.false(params.has('e')); + + params = new URLSearchParams('a=b&c=d&a=e'); + assert.true(params.has('a')); + + params = new URLSearchParams('=b&c=d'); + assert.true(params.has('')); + + params = new URLSearchParams('null=a'); + assert.true(params.has(null)); + + params = new URLSearchParams('a=b&c=d&&'); + params.append('first', 1); + params.append('first', 2); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.true(params.has('c'), 'search params object has name "c"'); + assert.true(params.has('first'), 'search params object has name "first"'); + assert.false(params.has('d'), 'search params object has no name "d"'); + params.delete('first'); + assert.false(params.has('first'), 'search params object has no name "first"'); + + params = new URLSearchParams('a=1&a=2&a=null&a=3&b=4'); + assert.true(params.has('a', 2)); + assert.true(params.has('a', null)); + assert.false(params.has('a', 4)); + assert.true(params.has('b', 4)); + assert.false(params.has('b', null)); + assert.true(params.has('b', undefined)); + assert.false(params.has('c', undefined)); + + assert.throws(() => { + return new URLSearchParams('').has(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#set', assert => { + const { set } = URLSearchParams.prototype; + assert.isFunction(set); + assert.arity(set, 2); + assert.enumerable(URLSearchParams.prototype, 'set'); + + let params = new URLSearchParams('a=b&c=d'); + params.set('a', 'B'); + assert.same(String(params), 'a=B&c=d'); + + params = new URLSearchParams('a=b&c=d&a=e'); + params.set('a', 'B'); + assert.same(String(params), 'a=B&c=d'); + params.set('e', 'f'); + assert.same(String(params), 'a=B&c=d&e=f'); + + params = new URLSearchParams('a=1&a=2&a=3'); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.same(params.get('a'), '1', 'search params object has name "a" with value "1"'); + params.set('first', 4); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.same(params.get('a'), '1', 'search params object has name "a" with value "1"'); + assert.same(String(params), 'a=1&a=2&a=3&first=4'); + params.set('a', 4); + assert.true(params.has('a'), 'search params object has name "a"'); + assert.same(params.get('a'), '4', 'search params object has name "a" with value "4"'); + assert.same(String(params), 'a=4&first=4'); + + assert.throws(() => { + return new URLSearchParams('').set(); + }, 'throws w/o arguments'); +}); + +QUnit.test('URLSearchParams#sort', assert => { + const { sort } = URLSearchParams.prototype; + assert.isFunction(sort); + assert.arity(sort, 0); + assert.enumerable(URLSearchParams.prototype, 'sort'); + + let params = new URLSearchParams('a=1&b=4&a=3&b=2'); + params.sort(); + assert.same(String(params), 'a=1&a=3&b=4&b=2'); + params.delete('a'); + params.append('a', '0'); + params.append('b', '0'); + params.sort(); + assert.same(String(params), 'a=0&b=4&b=2&b=0'); + + const testData = [ + { + input: 'z=b&a=b&z=a&a=a', + output: [['a', 'b'], ['a', 'a'], ['z', 'b'], ['z', 'a']], + }, + { + input: '\uFFFD=x&\uFFFC&\uFFFD=a', + output: [['\uFFFC', ''], ['\uFFFD', 'x'], ['\uFFFD', 'a']], + }, + { + input: 'ffi&🌈', // 🌈 > code point, but < code unit because two code units + output: [['🌈', ''], ['ffi', '']], + }, + { + input: 'é&e\uFFFD&e\u0301', + output: [['e\u0301', ''], ['e\uFFFD', ''], ['é', '']], + }, + { + input: 'z=z&a=a&z=y&a=b&z=x&a=c&z=w&a=d&z=v&a=e&z=u&a=f&z=t&a=g', + output: [ + ['a', 'a'], + ['a', 'b'], + ['a', 'c'], + ['a', 'd'], + ['a', 'e'], + ['a', 'f'], + ['a', 'g'], + ['z', 'z'], + ['z', 'y'], + ['z', 'x'], + ['z', 'w'], + ['z', 'v'], + ['z', 'u'], + ['z', 't'], + ], + }, + { + input: 'bbb&bb&aaa&aa=x&aa=y', + output: [['aa', 'x'], ['aa', 'y'], ['aaa', ''], ['bb', ''], ['bbb', '']], + }, + { + input: 'z=z&=f&=t&=x', + output: [['', 'f'], ['', 't'], ['', 'x'], ['z', 'z']], + }, + { + input: 'a🌈&a💩', + output: [['a🌈', ''], ['a💩', '']], + }, + ]; + + for (const { input, output } of testData) { + let i = 0; + params = new URLSearchParams(input); + params.sort(); + params.forEach((value, key) => { + const [reqKey, reqValue] = output[i++]; + assert.same(key, reqKey); + assert.same(value, reqValue); + }); + + i = 0; + const url = new URL(`?${ input }`, 'https://example/'); + params = url.searchParams; + params.sort(); + params.forEach((value, key) => { + const [reqKey, reqValue] = output[i++]; + assert.same(key, reqKey); + assert.same(value, reqValue); + }); + } + + if (DESCRIPTORS) { + const url = new URL('http://example.com/?'); + url.searchParams.sort(); + assert.same(url.href, 'http://example.com/', 'Sorting non-existent params removes ? from URL'); + assert.same(url.search, '', 'Sorting non-existent params removes ? from URL'); + } +}); + +QUnit.test('URLSearchParams#toString', assert => { + const { toString } = URLSearchParams.prototype; + assert.isFunction(toString); + assert.arity(toString, 0); + + let params = new URLSearchParams(); + params.append('a', 'b c'); + assert.same(String(params), 'a=b+c'); + params.delete('a'); + params.append('a b', 'c'); + assert.same(String(params), 'a+b=c'); + + params = new URLSearchParams(); + params.append('a', ''); + assert.same(String(params), 'a='); + params.append('a', ''); + assert.same(String(params), 'a=&a='); + params.append('', 'b'); + assert.same(String(params), 'a=&a=&=b'); + params.append('', ''); + assert.same(String(params), 'a=&a=&=b&='); + params.append('', ''); + assert.same(String(params), 'a=&a=&=b&=&='); + + params = new URLSearchParams(); + params.append('', 'b'); + assert.same(String(params), '=b'); + params.append('', 'b'); + assert.same(String(params), '=b&=b'); + + params = new URLSearchParams(); + params.append('', ''); + assert.same(String(params), '='); + params.append('', ''); + assert.same(String(params), '=&='); + + params = new URLSearchParams(); + params.append('a', 'b+c'); + assert.same(String(params), 'a=b%2Bc'); + params.delete('a'); + params.append('a+b', 'c'); + assert.same(String(params), 'a%2Bb=c'); + + params = new URLSearchParams(); + params.append('=', 'a'); + assert.same(String(params), '%3D=a'); + params.append('b', '='); + assert.same(String(params), '%3D=a&b=%3D'); + + params = new URLSearchParams(); + params.append('&', 'a'); + assert.same(String(params), '%26=a'); + params.append('b', '&'); + assert.same(String(params), '%26=a&b=%26'); + + params = new URLSearchParams(); + params.append('a', '\r'); + assert.same(String(params), 'a=%0D'); + + params = new URLSearchParams(); + params.append('a', '\n'); + assert.same(String(params), 'a=%0A'); + + params = new URLSearchParams(); + params.append('a', '\r\n'); + assert.same(String(params), 'a=%0D%0A'); + + params = new URLSearchParams(); + params.append('a', 'b%c'); + assert.same(String(params), 'a=b%25c'); + params.delete('a'); + params.append('a%b', 'c'); + assert.same(String(params), 'a%25b=c'); + + params = new URLSearchParams(); + params.append('a', 'b\0c'); + assert.same(String(params), 'a=b%00c'); + params.delete('a'); + params.append('a\0b', 'c'); + assert.same(String(params), 'a%00b=c'); + + params = new URLSearchParams(); + params.append('a', 'b\uD83D\uDCA9c'); + assert.same(String(params), 'a=b%F0%9F%92%A9c'); + params.delete('a'); + params.append('a\uD83D\uDCA9b', 'c'); + assert.same(String(params), 'a%F0%9F%92%A9b=c'); + + params = new URLSearchParams('a=b&c=d&&e&&'); + assert.same(String(params), 'a=b&c=d&e='); + params = new URLSearchParams('a = b &a=b&c=d%20'); + assert.same(String(params), 'a+=+b+&a=b&c=d+'); + params = new URLSearchParams('a=&a=b'); + assert.same(String(params), 'a=&a=b'); +}); + +QUnit.test('URLSearchParams#forEach', assert => { + const { forEach } = URLSearchParams.prototype; + assert.isFunction(forEach); + assert.arity(forEach, 1); + assert.enumerable(URLSearchParams.prototype, 'forEach'); + + const expectedValues = { a: '1', b: '2', c: '3' }; + let params = new URLSearchParams('a=1&b=2&c=3'); + let result = ''; + params.forEach((value, key, that) => { + assert.same(params.get(key), expectedValues[key]); + assert.same(value, expectedValues[key]); + assert.same(that, params); + result += key; + }); + assert.same(result, 'abc'); + + new URL('http://a.b/c').searchParams.forEach(() => { + assert.avoid(); + }); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); + params = url.searchParams; + result = ''; + params.forEach((val, key) => { + url.search = 'x=1&y=2&z=3'; + result += key + val; + }); + assert.same(result, 'a1y2z3'); + } + + // fails in Chrome 66- + params = new URLSearchParams('a=1&b=2&c=3'); + result = ''; + params.forEach((value, key) => { + params.delete('b'); + result += key + value; + }); + assert.same(result, 'a1c3'); +}); + +QUnit.test('URLSearchParams#entries', assert => { + const { entries } = URLSearchParams.prototype; + assert.isFunction(entries); + assert.arity(entries, 0); + assert.enumerable(URLSearchParams.prototype, 'entries'); + + const expectedValues = { a: '1', b: '2', c: '3' }; + let params = new URLSearchParams('a=1&b=2&c=3'); + let iterator = params.entries(); + let result = ''; + let entry; + while (!(entry = iterator.next()).done) { + const [key, value] = entry.value; + assert.same(params.get(key), expectedValues[key]); + assert.same(value, expectedValues[key]); + result += key; + } + assert.same(result, 'abc'); + + assert.true(new URL('http://a.b/c').searchParams.entries().next().done, 'should be finished'); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); + iterator = url.searchParams.entries(); + result = ''; + while (!(entry = iterator.next()).done) { + const [key, value] = entry.value; + url.search = 'x=1&y=2&z=3'; + result += key + value; + } + assert.same(result, 'a1y2z3'); + } + + // fails in Chrome 66- + params = new URLSearchParams('a=1&b=2&c=3'); + iterator = params.entries(); + result = ''; + while (!(entry = iterator.next()).done) { + params.delete('b'); + const [key, value] = entry.value; + result += key + value; + } + assert.same(result, 'a1c3'); + + if (DESCRIPTORS) assert.true(getOwnPropertyDescriptor(getPrototypeOf(new URLSearchParams().entries()), 'next').enumerable, 'enumerable .next'); +}); + +QUnit.test('URLSearchParams#keys', assert => { + const { keys } = URLSearchParams.prototype; + assert.isFunction(keys); + assert.arity(keys, 0); + assert.enumerable(URLSearchParams.prototype, 'keys'); + + let iterator = new URLSearchParams('a=1&b=2&c=3').keys(); + let result = ''; + let entry; + while (!(entry = iterator.next()).done) { + result += entry.value; + } + assert.same(result, 'abc'); + + assert.true(new URL('http://a.b/c').searchParams.keys().next().done, 'should be finished'); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); + iterator = url.searchParams.keys(); + result = ''; + while (!(entry = iterator.next()).done) { + const key = entry.value; + url.search = 'x=1&y=2&z=3'; + result += key; + } + assert.same(result, 'ayz'); + } + + // fails in Chrome 66- + const params = new URLSearchParams('a=1&b=2&c=3'); + iterator = params.keys(); + result = ''; + while (!(entry = iterator.next()).done) { + params.delete('b'); + const key = entry.value; + result += key; + } + assert.same(result, 'ac'); + + if (DESCRIPTORS) assert.true(getOwnPropertyDescriptor(getPrototypeOf(new URLSearchParams().keys()), 'next').enumerable, 'enumerable .next'); +}); + +QUnit.test('URLSearchParams#values', assert => { + const { values } = URLSearchParams.prototype; + assert.isFunction(values); + assert.arity(values, 0); + assert.enumerable(URLSearchParams.prototype, 'values'); + + let iterator = new URLSearchParams('a=1&b=2&c=3').values(); + let result = ''; + let entry; + while (!(entry = iterator.next()).done) { + result += entry.value; + } + assert.same(result, '123'); + + assert.true(new URL('http://a.b/c').searchParams.values().next().done, 'should be finished'); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=a&b=b&c=c&d=d'); + iterator = url.searchParams.keys(); + result = ''; + while (!(entry = iterator.next()).done) { + const { value } = entry; + url.search = 'x=x&y=y&z=z'; + result += value; + } + assert.same(result, 'ayz'); + } + + // fails in Chrome 66- + const params = new URLSearchParams('a=1&b=2&c=3'); + iterator = params.values(); + result = ''; + while (!(entry = iterator.next()).done) { + params.delete('b'); + const key = entry.value; + result += key; + } + assert.same(result, '13'); + + if (DESCRIPTORS) assert.true(getOwnPropertyDescriptor(getPrototypeOf(new URLSearchParams().values()), 'next').enumerable, 'enumerable .next'); +}); + +QUnit.test('URLSearchParams#@@iterator', assert => { + const entries = URLSearchParams.prototype[Symbol.iterator]; + assert.isFunction(entries); + assert.arity(entries, 0); + + assert.same(entries, URLSearchParams.prototype.entries); + + const expectedValues = { a: '1', b: '2', c: '3' }; + let params = new URLSearchParams('a=1&b=2&c=3'); + let iterator = params[Symbol.iterator](); + let result = ''; + let entry; + while (!(entry = iterator.next()).done) { + const [key, value] = entry.value; + assert.same(params.get(key), expectedValues[key]); + assert.same(value, expectedValues[key]); + result += key; + } + assert.same(result, 'abc'); + + assert.true(new URL('http://a.b/c').searchParams[Symbol.iterator]().next().done, 'should be finished'); + + // fails in Chrome 66- + if (DESCRIPTORS) { + const url = new URL('http://a.b/c?a=1&b=2&c=3&d=4'); + iterator = url.searchParams[Symbol.iterator](); + result = ''; + while (!(entry = iterator.next()).done) { + const [key, value] = entry.value; + url.search = 'x=1&y=2&z=3'; + result += key + value; + } + assert.same(result, 'a1y2z3'); + } + + // fails in Chrome 66- + params = new URLSearchParams('a=1&b=2&c=3'); + iterator = params[Symbol.iterator](); + result = ''; + while (!(entry = iterator.next()).done) { + params.delete('b'); + const [key, value] = entry.value; + result += key + value; + } + assert.same(result, 'a1c3'); + + if (DESCRIPTORS) assert.true(getOwnPropertyDescriptor(getPrototypeOf(new URLSearchParams()[Symbol.iterator]()), 'next').enumerable, 'enumerable .next'); +}); + +QUnit.test('URLSearchParams#size', assert => { + const params = new URLSearchParams('a=1&b=2&b=3'); + assert.true('size' in params); + assert.same(params.size, 3); + + if (DESCRIPTORS) { + assert.true('size' in URLSearchParams.prototype); + + const { enumerable, configurable, get } = getOwnPropertyDescriptor(URLSearchParams.prototype, 'size'); + + assert.true(enumerable, 'enumerable'); + // https://github.com/oven-sh/bun/issues/9251 + if (!BUN) assert.true(configurable, 'configurable'); + + assert.throws(() => get.call([])); + } +}); diff --git a/tests/unit-pure/web.url.can-parse.js b/tests/unit-pure/web.url.can-parse.js new file mode 100644 index 000000000000..9e1ab1eba425 --- /dev/null +++ b/tests/unit-pure/web.url.can-parse.js @@ -0,0 +1,24 @@ +import canParse from 'core-js-pure/stable/url/can-parse'; + +QUnit.test('URL.canParse', assert => { + assert.isFunction(canParse); + assert.arity(canParse, 1); + assert.name(canParse, 'canParse'); + + assert.false(canParse(undefined), 'undefined'); + assert.false(canParse(undefined, undefined), 'undefined, undefined'); + assert.true(canParse('q:w'), 'q:w'); + assert.true(canParse('q:w', undefined), 'q:w, undefined'); + // assert.false(canParse(undefined, 'q:w'), 'undefined, q:w'); // fails in Chromium on Windows + assert.true(canParse('q:/w'), 'q:/w'); + assert.true(canParse('q:/w', undefined), 'q:/w, undefined'); + assert.true(canParse(undefined, 'q:/w'), 'undefined, q:/w'); + assert.false(canParse('https://login:password@examp:le.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'https://login:password@examp:le.com:8080/?a=1&b=2&a=3&c=4#fragment'); + assert.true(canParse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); + assert.true(canParse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment', undefined), 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment,%20undefined'); + assert.true(canParse('x', 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'x, https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); + + assert.throws(() => canParse(), 'no args'); + assert.throws(() => canParse({ toString() { throw new Error('thrower'); } }), 'conversion thrower #1'); + assert.throws(() => canParse('q:w', { toString() { throw new Error('thrower'); } }), 'conversion thrower #2'); +}); diff --git a/tests/unit-pure/web.url.js b/tests/unit-pure/web.url.js new file mode 100644 index 000000000000..19d66af2ca6d --- /dev/null +++ b/tests/unit-pure/web.url.js @@ -0,0 +1,666 @@ +/* eslint-disable es/no-object-getownpropertydescriptor, unicorn/relative-url-style -- required for testing */ +import { DESCRIPTORS, NODE } from '../helpers/constants.js'; +import urlTestData from '../wpt-url-resources/urltestdata.js'; +import settersTestData from '../wpt-url-resources/setters.js'; +import toASCIITestData from '../wpt-url-resources/toascii.js'; + +import URL from 'core-js-pure/stable/url'; +import URLSearchParams from 'core-js-pure/stable/url-search-params'; + +const { hasOwnProperty } = Object.prototype; + +QUnit.test('URL constructor', assert => { + assert.isFunction(URL); + if (!NODE) assert.arity(URL, 1); + + assert.same(String(new URL('http://www.domain.com/a/b')), 'http://www.domain.com/a/b'); + assert.same(String(new URL('/c/d', 'http://www.domain.com/a/b')), 'http://www.domain.com/c/d'); + assert.same(String(new URL('b/c', 'http://www.domain.com/a/b')), 'http://www.domain.com/a/b/c'); + assert.same(String(new URL('b/c', new URL('http://www.domain.com/a/b'))), 'http://www.domain.com/a/b/c'); + assert.same(String(new URL({ toString: () => 'https://example.org/' })), 'https://example.org/'); + + assert.same(String(new URL('nonspecial://example.com/')), 'nonspecial://example.com/'); + + assert.same(String(new URL('https://xn--g6w251d/')), 'https://xn--g6w251d/', 'unicode parsing'); + assert.same(String(new URL('https://xn--xx-flcmn5bht.xn--e1aybc/')), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + assert.same(String(new URL('https://xn--xx-flcmn5bht.xn--e1aybc/')), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + assert.same(String(new URL('http://example.com/', 'https://example.org/')), 'http://example.com/'); + assert.same(String(new URL('https://example.com/', 'https://example.org/')), 'https://example.com/'); + assert.same(String(new URL('nonspecial://Example.com/', 'https://example.org/')), 'nonspecial://Example.com/'); + assert.same(String(new URL('http:Example.com/', 'https://example.org/')), 'http://example.com/'); + assert.same(String(new URL('https:Example.com/', 'https://example.org/')), 'https://example.org/Example.com/'); + assert.same(String(new URL('nonspecial:Example.com/', 'https://example.org/')), 'nonspecial:Example.com/'); + + assert.same(String(new URL('http://192.168.0.240/')), 'http://192.168.0.240/'); + assert.same(String(new URL('http://[20:0:0:1::ff]/')), 'http://[20:0:0:1::ff]/'); + // assert.same(String(new URL('http://257.168.0xF0')), 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // TypeError in Chrome and Safari + assert.same(String(new URL('http://0300.168.0xg0/')), 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); + + assert.same(String(new URL('file:///var/log/system.log')), 'file:///var/log/system.log', 'file scheme'); + // assert.same(String(new URL('file://nnsc.nsf.net/bar/baz')), 'file://nnsc.nsf.net/bar/baz', 'file scheme'); // 'file:///bar/baz' in FF + // assert.same(String(new URL('file://localhost/bar/baz')), 'file:///bar/baz', 'file scheme'); // 'file://localhost/bar/baz' in Chrome + + assert.throws(() => new URL(), 'TypeError: Failed to construct URL: 1 argument required, but only 0 present.'); + assert.throws(() => new URL(''), 'TypeError: Failed to construct URL: Invalid URL'); + // Node 19.7 + // https://github.com/nodejs/node/issues/46755 + // assert.throws(() => new URL('', 'about:blank'), 'TypeError: Failed to construct URL: Invalid URL'); + assert.throws(() => new URL('abc'), 'TypeError: Failed to construct URL: Invalid URL'); + assert.throws(() => new URL('//abc'), 'TypeError: Failed to construct URL: Invalid URL'); + assert.throws(() => new URL('http://www.domain.com/', 'abc'), 'TypeError: Failed to construct URL: Invalid base URL'); + assert.throws(() => new URL('http://www.domain.com/', null), 'TypeError: Failed to construct URL: Invalid base URL'); + assert.throws(() => new URL('//abc', null), 'TypeError: Failed to construct URL: Invalid base URL'); + assert.throws(() => new URL('http://[20:0:0:1:0:0:0:ff'), 'incorrect IPv6'); + assert.throws(() => new URL('http://[20:0:0:1:0:0:0:fg]'), 'incorrect IPv6'); + // assert.throws(() => new URL('http://a%b'), 'forbidden host code point'); // no error in FF + assert.throws(() => new URL('1http://zloirock.ru'), 'incorrect scheme'); +}); + +QUnit.test('URL#href', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'href')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'href'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.href, 'http://zloirock.ru/'); + + if (DESCRIPTORS) { + url.searchParams.append('foo', 'bar'); + assert.same(url.href, 'http://zloirock.ru/?foo=bar'); + + url = new URL('http://zloirock.ru/foo'); + url.href = 'https://xn--g6w251d/'; + assert.same(url.href, 'https://xn--g6w251d/', 'unicode parsing'); + assert.same(String(url), 'https://xn--g6w251d/', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.href = 'https://xn--xx-flcmn5bht.xn--e1aybc/'; + assert.same(url.href, 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + assert.same(String(url), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.href = 'https://xn--xx-flcmn5bht.xn--e1aybc/'; + assert.same(url.href, 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + assert.same(String(url), 'https://xn--xx-flcmn5bht.xn--e1aybc/', 'unicode parsing'); + + url = new URL('http://zloirock.ru/'); + url.href = 'http://192.168.0.240/'; + assert.same(url.href, 'http://192.168.0.240/'); + assert.same(String(url), 'http://192.168.0.240/'); + + url = new URL('http://zloirock.ru/'); + url.href = 'http://[20:0:0:1::ff]/'; + assert.same(url.href, 'http://[20:0:0:1::ff]/'); + assert.same(String(url), 'http://[20:0:0:1::ff]/'); + + // url = new URL('http://zloirock.ru/'); + // url.href = 'http://257.168.0xF0'; // TypeError and Safari + // assert.same(url.href, 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // `F` instead of `f` in Chrome + // assert.same(String(url), 'http://257.168.0xf0/', 'incorrect IPv4 parsed as host'); // `F` instead of `f` in Chrome + + url = new URL('http://zloirock.ru/'); + url.href = 'http://0300.168.0xg0/'; + assert.same(url.href, 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); + assert.same(String(url), 'http://0300.168.0xg0/', 'incorrect IPv4 parsed as host'); + + url = new URL('http://192.168.0.240/'); + url.href = 'file:///var/log/system.log'; + assert.same(url.href, 'file:///var/log/system.log', 'file -> ip'); + assert.same(String(url), 'file:///var/log/system.log', 'file -> ip'); + + url = new URL('file:///var/log/system.log'); + url.href = 'http://192.168.0.240/'; + // Node 19.7 + // https://github.com/nodejs/node/issues/46755 + // assert.same(url.href, 'http://192.168.0.240/', 'file -> http'); + // assert.same(String(url), 'http://192.168.0.240/', 'file -> http'); + + // assert.throws(() => new URL('http://zloirock.ru/').href = undefined, 'incorrect URL'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = '', 'incorrect URL'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = 'abc', 'incorrect URL'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = '//abc', 'incorrect URL'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://[20:0:0:1:0:0:0:ff', 'incorrect IPv6'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://[20:0:0:1:0:0:0:fg]', 'incorrect IPv6'); // no error in Chrome + // assert.throws(() => new URL('http://zloirock.ru/').href = 'http://a%b', 'forbidden host code point'); // no error in Chrome and FF + // assert.throws(() => new URL('http://zloirock.ru/').href = '1http://zloirock.ru', 'incorrect scheme'); // no error in Chrome + } +}); + +QUnit.test('URL#origin', assert => { + const url = new URL('http://es6.zloirock.ru/tests.html'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'origin')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'origin'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + } + + assert.same(url.origin, 'http://es6.zloirock.ru/'); + + assert.same(new URL('https://xn--g6w251d/tests').origin, 'https://xn--g6w251d/'); +}); + +QUnit.test('URL#protocol', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'protocol')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'protocol'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.protocol, 'http:'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.protocol = 'https'; + assert.same(url.protocol, 'https:'); + assert.same(String(url), 'https://zloirock.ru/'); + + // https://nodejs.org/api/url.html#url_special_schemes + // url = new URL('http://zloirock.ru/'); + // url.protocol = 'fish'; + // assert.same(url.protocol, 'http:'); + // assert.same(url.href, 'http://zloirock.ru/'); + // assert.same(String(url), 'http://zloirock.ru/'); + + url = new URL('http://zloirock.ru/'); + url.protocol = '1http'; + assert.same(url.protocol, 'http:'); + assert.same(url.href, 'http://zloirock.ru/', 'incorrect scheme'); + assert.same(String(url), 'http://zloirock.ru/', 'incorrect scheme'); + } +}); + +QUnit.test('URL#username', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'username')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'username'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.username, ''); + + url = new URL('http://username@zloirock.ru/'); + assert.same(url.username, 'username'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.username = 'username'; + assert.same(url.username, 'username'); + assert.same(String(url), 'http://username@zloirock.ru/'); + } +}); + +QUnit.test('URL#password', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'password')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'password'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.password, ''); + + url = new URL('http://username:password@zloirock.ru/'); + assert.same(url.password, 'password'); + + // url = new URL('http://:password@zloirock.ru/'); // TypeError in FF + // assert.same(url.password, 'password'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.username = 'username'; + url.password = 'password'; + assert.same(url.password, 'password'); + assert.same(String(url), 'http://username:password@zloirock.ru/'); + + // url = new URL('http://zloirock.ru/'); + // url.password = 'password'; + // assert.same(url.password, 'password'); // '' in FF + // assert.same(String(url), 'http://:password@zloirock.ru/'); // 'http://zloirock.ru/' in FF + } +}); + +QUnit.test('URL#host', assert => { + let url = new URL('http://zloirock.ru:81/path'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'host')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'host'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.host, 'zloirock.ru:81'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru:81/path'); + url.host = 'example.com:82'; + assert.same(url.host, 'example.com:82'); + assert.same(String(url), 'http://example.com:82/path'); + + // url = new URL('http://zloirock.ru:81/path'); + // url.host = 'other?domain.com'; + // assert.same(String(url), 'http://other:81/path'); // 'http://other/?domain.com/path' in Safari + + url = new URL('https://www.mydomain.com:8080/path/'); + url.host = 'www.otherdomain.com:80'; + assert.same(url.href, 'https://www.otherdomain.com:80/path/', 'set default port for another protocol'); + + // url = new URL('https://www.mydomain.com:8080/path/'); + // url.host = 'www.otherdomain.com:443'; + // assert.same(url.href, 'https://www.otherdomain.com/path/', 'set default port'); + + url = new URL('http://zloirock.ru/foo'); + url.host = '測試'; + assert.same(url.host, 'xn--g6w251d', 'unicode parsing'); + assert.same(String(url), 'http://xn--g6w251d/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.host = 'xxпривет.тест'; + assert.same(url.host, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); + assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.host = 'xxПРИВЕТ.тест'; + assert.same(url.host, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); + assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.host = '0300.168.0xF0'; + assert.same(url.host, '192.168.0.240'); + assert.same(String(url), 'http://192.168.0.240/foo'); + + // url = new URL('http://zloirock.ru/foo'); + // url.host = '[20:0:0:1:0:0:0:ff]'; + // assert.same(url.host, '[20:0:0:1::ff]'); // ':0' in Chrome, 'zloirock.ru' in Safari + // assert.same(String(url), 'http://[20:0:0:1::ff]/foo'); // 'http://[20:0/foo' in Chrome, 'http://zloirock.ru/foo' in Safari + + // url = new URL('file:///var/log/system.log'); + // url.host = 'nnsc.nsf.net'; // does not work in FF + // assert.same(url.hostname, 'nnsc.nsf.net', 'file'); + // assert.same(String(url), 'file://nnsc.nsf.net/var/log/system.log', 'file'); + + // url = new URL('http://zloirock.ru/'); + // url.host = '[20:0:0:1:0:0:0:ff'; + // assert.same(url.host, 'zloirock.ru', 'incorrect IPv6'); // ':0' in Chrome + // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0/' in Chrome + + // url = new URL('http://zloirock.ru/'); + // url.host = '[20:0:0:1:0:0:0:fg]'; + // assert.same(url.host, 'zloirock.ru', 'incorrect IPv6'); // ':0' in Chrome + // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0/' in Chrome + + // url = new URL('http://zloirock.ru/'); + // url.host = 'a%b'; + // assert.same(url.host, 'zloirock.ru', 'forbidden host code point'); // '' in Chrome, 'a%b' in FF + // assert.same(String(url), 'http://zloirock.ru/', 'forbidden host code point'); // 'http://a%25b/' in Chrome, 'http://a%b/' in FF + } +}); + +QUnit.test('URL#hostname', assert => { + let url = new URL('http://zloirock.ru:81/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'hostname')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'hostname'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.hostname, 'zloirock.ru'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru:81/'); + url.hostname = 'example.com'; + assert.same(url.hostname, 'example.com'); + assert.same(String(url), 'http://example.com:81/'); + + // url = new URL('http://zloirock.ru:81/'); + // url.hostname = 'example.com:82'; + // assert.same(url.hostname, 'example.com'); // '' in Chrome + // assert.same(String(url), 'http://example.com:81/'); // 'http://example.com:82:81/' in Chrome + + url = new URL('http://zloirock.ru/foo'); + url.hostname = '測試'; + assert.same(url.hostname, 'xn--g6w251d', 'unicode parsing'); + assert.same(String(url), 'http://xn--g6w251d/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.hostname = 'xxпривет.тест'; + assert.same(url.hostname, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); + assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.hostname = 'xxПРИВЕТ.тест'; + assert.same(url.hostname, 'xn--xx-flcmn5bht.xn--e1aybc', 'unicode parsing'); + assert.same(String(url), 'http://xn--xx-flcmn5bht.xn--e1aybc/foo', 'unicode parsing'); + + url = new URL('http://zloirock.ru/foo'); + url.hostname = '0300.168.0xF0'; + assert.same(url.hostname, '192.168.0.240'); + assert.same(String(url), 'http://192.168.0.240/foo'); + + // url = new URL('http://zloirock.ru/foo'); + // url.hostname = '[20:0:0:1:0:0:0:ff]'; + // assert.same(url.hostname, '[20:0:0:1::ff]'); // 'zloirock.ru' in Safari + // assert.same(String(url), 'http://[20:0:0:1::ff]/foo'); // 'http://zloirock.ru/foo' in Safari + + // url = new URL('file:///var/log/system.log'); + // url.hostname = 'nnsc.nsf.net'; // does not work in FF + // assert.same(url.hostname, 'nnsc.nsf.net', 'file'); + // assert.same(String(url), 'file://nnsc.nsf.net/var/log/system.log', 'file'); + + // url = new URL('http://zloirock.ru/'); + // url.hostname = '[20:0:0:1:0:0:0:ff'; + // assert.same(url.hostname, 'zloirock.ru', 'incorrect IPv6'); // '' in Chrome + // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0:0:1:0:0:0:ff' in Chrome + + // url = new URL('http://zloirock.ru/'); + // url.hostname = '[20:0:0:1:0:0:0:fg]'; + // assert.same(url.hostname, 'zloirock.ru', 'incorrect IPv6'); // '' in Chrome + // assert.same(String(url), 'http://zloirock.ru/', 'incorrect IPv6'); // 'http://[20:0:0:1:0:0:0:ff/' in Chrome + + // url = new URL('http://zloirock.ru/'); + // url.hostname = 'a%b'; + // assert.same(url.hostname, 'zloirock.ru', 'forbidden host code point'); // '' in Chrome, 'a%b' in FF + // assert.same(String(url), 'http://zloirock.ru/', 'forbidden host code point'); // 'http://a%25b/' in Chrome, 'http://a%b/' in FF + } +}); + +QUnit.test('URL#port', assert => { + let url = new URL('http://zloirock.ru:1337/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'port')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'port'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.port, '1337'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.port = 80; + assert.same(url.port, ''); + assert.same(String(url), 'http://zloirock.ru/'); + url.port = 1337; + assert.same(url.port, '1337'); + assert.same(String(url), 'http://zloirock.ru:1337/'); + // url.port = 'abcd'; + // assert.same(url.port, '1337'); // '0' in Chrome + // assert.same(String(url), 'http://zloirock.ru:1337/'); // 'http://zloirock.ru:0/' in Chrome + // url.port = '5678abcd'; + // assert.same(url.port, '5678'); // '1337' in FF + // assert.same(String(url), 'http://zloirock.ru:5678/'); // 'http://zloirock.ru:1337/"' in FF + url.port = 1234.5678; + assert.same(url.port, '1234'); + assert.same(String(url), 'http://zloirock.ru:1234/'); + // url.port = 1e10; + // assert.same(url.port, '1234'); // '0' in Chrome + // assert.same(String(url), 'http://zloirock.ru:1234/'); // 'http://zloirock.ru:0/' in Chrome + } +}); + +QUnit.test('URL#pathname', assert => { + let url = new URL('http://zloirock.ru/foo/bar'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'pathname')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'pathname'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.pathname, '/foo/bar'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.pathname = 'bar/baz'; + assert.same(url.pathname, '/bar/baz'); + assert.same(String(url), 'http://zloirock.ru/bar/baz'); + } +}); + +QUnit.test('URL#search', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'search')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'search'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.search, ''); + + url = new URL('http://zloirock.ru/?foo=bar'); + assert.same(url.search, '?foo=bar'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/?'); + assert.same(url.search, ''); + assert.same(String(url), 'http://zloirock.ru/?'); + url.search = 'foo=bar'; + assert.same(url.search, '?foo=bar'); + assert.same(String(url), 'http://zloirock.ru/?foo=bar'); + url.search = '?bar=baz'; + assert.same(url.search, '?bar=baz'); + assert.same(String(url), 'http://zloirock.ru/?bar=baz'); + url.search = ''; + assert.same(url.search, ''); + assert.same(String(url), 'http://zloirock.ru/'); + } +}); + +QUnit.test('URL#searchParams', assert => { + let url = new URL('http://zloirock.ru/?foo=bar&bar=baz'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'searchParams')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'searchParams'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + } + + assert.true(url.searchParams instanceof URLSearchParams); + assert.same(url.searchParams.get('foo'), 'bar'); + assert.same(url.searchParams.get('bar'), 'baz'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/'); + url.searchParams.append('foo', 'bar'); + assert.same(String(url), 'http://zloirock.ru/?foo=bar'); + + url = new URL('http://zloirock.ru/'); + url.search = 'foo=bar'; + assert.same(url.searchParams.get('foo'), 'bar'); + + url = new URL('http://zloirock.ru/?foo=bar&bar=baz'); + url.search = ''; + assert.false(url.searchParams.has('foo')); + } +}); + +QUnit.test('URL#hash', assert => { + let url = new URL('http://zloirock.ru/'); + + if (DESCRIPTORS) { + assert.false(hasOwnProperty.call(url, 'hash')); + const descriptor = Object.getOwnPropertyDescriptor(URL.prototype, 'hash'); + assert.true(descriptor.enumerable); + assert.true(descriptor.configurable); + assert.same(typeof descriptor.get, 'function'); + assert.same(typeof descriptor.set, 'function'); + } + + assert.same(url.hash, ''); + + url = new URL('http://zloirock.ru/#foo'); + assert.same(url.hash, '#foo'); + + url = new URL('http://zloirock.ru/#'); + assert.same(url.hash, ''); + assert.same(String(url), 'http://zloirock.ru/#'); + + if (DESCRIPTORS) { + url = new URL('http://zloirock.ru/#'); + url.hash = 'foo'; + assert.same(url.hash, '#foo'); + assert.same(String(url), 'http://zloirock.ru/#foo'); + url.hash = ''; + assert.same(url.hash, ''); + assert.same(String(url), 'http://zloirock.ru/'); + // url.hash = '#'; + // assert.same(url.hash, ''); + // assert.same(String(url), 'http://zloirock.ru/'); // 'http://zloirock.ru/#' in FF + url.hash = '#foo'; + assert.same(url.hash, '#foo'); + assert.same(String(url), 'http://zloirock.ru/#foo'); + url.hash = '#foo#bar'; + assert.same(url.hash, '#foo#bar'); + assert.same(String(url), 'http://zloirock.ru/#foo#bar'); + + url = new URL('http://zloirock.ru/'); + url.hash = 'абa'; + assert.same(url.hash, '#%D0%B0%D0%B1a'); + + // url = new URL('http://zloirock.ru/'); + // url.hash = '\udc01\ud802a'; + // assert.same(url.hash, '#%EF%BF%BD%EF%BF%BDa', 'unmatched surrogates'); + } +}); + +QUnit.test('URL#toJSON', assert => { + const { toJSON } = URL.prototype; + assert.isFunction(toJSON); + assert.arity(toJSON, 0); + assert.enumerable(URL.prototype, 'toJSON'); + + const url = new URL('http://zloirock.ru/'); + assert.same(url.toJSON(), 'http://zloirock.ru/'); + + if (DESCRIPTORS) { + url.searchParams.append('foo', 'bar'); + assert.same(url.toJSON(), 'http://zloirock.ru/?foo=bar'); + } +}); + +QUnit.test('URL#toString', assert => { + const { toString } = URL.prototype; + assert.isFunction(toString); + assert.arity(toString, 0); + assert.enumerable(URL.prototype, 'toString'); + + const url = new URL('http://zloirock.ru/'); + assert.same(url.toString(), 'http://zloirock.ru/'); + + if (DESCRIPTORS) { + url.searchParams.append('foo', 'bar'); + assert.same(url.toString(), 'http://zloirock.ru/?foo=bar'); + } +}); + +QUnit.test('URL.sham', assert => { + assert.same(URL.sham, DESCRIPTORS ? undefined : true); +}); + +// `core-js` URL implementation pass all (exclude some encoding-related) tests +// from the next 3 test cases, but URLs from all of popular browsers fail a serious part of tests. +// Replacing all of them does not looks like a good idea, so next test cases disabled by default. + +// see https://github.com/web-platform-tests/wpt/blob/master/url +QUnit.skip('WPT URL constructor tests', assert => { + for (const expected of urlTestData) { + if (typeof expected == 'string') continue; + const name = `Parsing: <${ expected.input }> against <${ expected.base }>`; + if (expected.failure) { + assert.throws(() => new URL(expected.input, expected.base || 'about:blank'), name); + } else { + const url = new URL(expected.input, expected.base || 'about:blank'); + assert.same(url.href, expected.href, `${ name }: href`); + assert.same(url.protocol, expected.protocol, `${ name }: protocol`); + assert.same(url.username, expected.username, `${ name }: username`); + assert.same(url.password, expected.password, `${ name }: password`); + assert.same(url.host, expected.host, `${ name }: host`); + assert.same(url.hostname, expected.hostname, `${ name }: hostname`); + assert.same(url.port, expected.port, `${ name }: port`); + assert.same(url.pathname, expected.pathname, `${ name }: pathname`); + assert.same(url.search, expected.search, `${ name }: search`); + if ('searchParams' in expected) { + assert.same(url.searchParams.toString(), expected.searchParams, `${ name }: searchParams`); + } + assert.same(url.hash, expected.hash, `${ name }: hash`); + if ('origin' in expected) { + assert.same(url.origin, expected.origin, `${ name }: origin`); + } + } + } +}); + +// see https://github.com/web-platform-tests/wpt/blob/master/url +if (DESCRIPTORS) QUnit.skip('WPT URL setters tests', assert => { + for (const setter in settersTestData) { + const testCases = settersTestData[setter]; + for (const { href, newValue, comment, expected } of testCases) { + let name = `Setting <${ href }>.${ setter } = '${ newValue }'.`; + if (comment) name += ` ${ comment }`; + + const url = new URL(href); + url[setter] = newValue; + for (const attribute in expected) { + assert.same(url[attribute], expected[attribute], name); + } + } + } +}); + +// see https://github.com/web-platform-tests/wpt/blob/master/url +QUnit.skip('WPT conversion to ASCII tests', assert => { + for (const { comment, input, output } of toASCIITestData) { + let name = `Parsing: <${ input }>`; + if (comment) name += ` ${ comment }`; + if (output === null) { + assert.throws(() => new URL(`https://${ input }/x`), name); + } else { + const url = new URL(`https://${ input }/x`); + assert.same(url.host, output, name); + assert.same(url.hostname, output, name); + assert.same(url.pathname, '/x', name); + assert.same(url.href, `https://${ output }/x`, name); + } + } +}); diff --git a/tests/unit-pure/web.url.parse.js b/tests/unit-pure/web.url.parse.js new file mode 100644 index 000000000000..ab27a9c44d2f --- /dev/null +++ b/tests/unit-pure/web.url.parse.js @@ -0,0 +1,25 @@ +import URL from 'core-js-pure/stable/url'; +import parse from 'core-js-pure/stable/url/parse'; + +QUnit.test('URL.parse', assert => { + assert.isFunction(parse); + assert.arity(parse, 1); + assert.name(parse, 'parse'); + + assert.same(parse(undefined), null, 'undefined'); + assert.same(parse(undefined, undefined), null, 'undefined, undefined'); + assert.deepEqual(parse('q:w'), new URL('q:w'), 'q:w'); + assert.deepEqual(parse('q:w', undefined), new URL('q:w'), 'q:w, undefined'); + assert.deepEqual(parse('q:/w'), new URL('q:/w'), 'q:/w'); + assert.deepEqual(parse('q:/w', undefined), new URL('q:/w', undefined), 'q:/w, undefined'); + assert.deepEqual(parse(undefined, 'q:/w'), new URL(undefined, 'q:/w'), 'undefined, q:/w'); + assert.same(parse('https://login:password@examp:le.com:8080/?a=1&b=2&a=3&c=4#fragment'), null, 'https://login:password@examp:le.com:8080/?a=1&b=2&a=3&c=4#fragment'); + assert.deepEqual(parse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), new URL('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); + assert.deepEqual(parse('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment', undefined), new URL('https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment', undefined), 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment,%20undefined'); + // eslint-disable-next-line unicorn/relative-url-style -- required for testing + assert.deepEqual(parse('x', 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), new URL('x', 'https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'), 'x, https://login:password@example.com:8080/?a=1&b=2&a=3&c=4#fragment'); + + assert.throws(() => parse(), 'no args'); + assert.throws(() => parse({ toString() { throw new Error('thrower'); } }), 'conversion thrower #1'); + assert.throws(() => parse('q:w', { toString() { throw new Error('thrower'); } }), 'conversion thrower #2'); +}); diff --git a/tests/worker.html b/tests/worker.html deleted file mode 100644 index b2ab5e8aae2e..000000000000 --- a/tests/worker.html +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/tests/worker/index.html b/tests/worker/index.html new file mode 100644 index 000000000000..ea25f43d3def --- /dev/null +++ b/tests/worker/index.html @@ -0,0 +1,4 @@ + + +Worker test + diff --git a/tests/worker/runner.js b/tests/worker/runner.js index 301e45b30ed2..8af0dac97302 100644 --- a/tests/worker/runner.js +++ b/tests/worker/runner.js @@ -1,12 +1,13 @@ 'use strict'; importScripts('../../packages/core-js-bundle/index.js'); -postMessage(typeof core !== 'undefined'); +postMessage(typeof core != 'undefined'); -setImmediate(() => { +setImmediate(function () { postMessage('setImmediate'); }); -Promise.resolve().then(() => { +// eslint-disable-next-line es/no-promise -- safe +Promise.resolve().then(function () { postMessage('Promise.resolve'); }); diff --git a/tests/worker/test.js b/tests/worker/test.js index 8dedebb6bad9..9d4b8dacce29 100644 --- a/tests/worker/test.js +++ b/tests/worker/test.js @@ -1,10 +1,12 @@ 'use strict'; -const worker = new Worker('./worker/runner.js'); -worker.addEventListener('error', e => { - // eslint-disable-next-line no-console +var worker = new Worker('./worker/runner.js'); + +worker.addEventListener('error', function (e) { + // eslint-disable-next-line no-console -- output console.error(e); }); -worker.addEventListener('message', message => { - // eslint-disable-next-line no-console + +worker.addEventListener('message', function (message) { + // eslint-disable-next-line no-console -- output console.log(message.data); }); diff --git a/tests/wpt-url-resources/setters.js b/tests/wpt-url-resources/setters.js index 60a656b089de..2d7916cd19cb 100644 --- a/tests/wpt-url-resources/setters.js +++ b/tests/wpt-url-resources/setters.js @@ -1,4 +1,8 @@ -/* eslint-disable no-script-url */ +// Copyright © web-platform-tests contributors +// Originally from https://github.com/web-platform-tests/wpt +// Available under the 3-Clause BSD License https://github.com/web-platform-tests/wpt/blob/master/LICENSE.md + +/* eslint-disable no-script-url -- required for testing */ export default { protocol: [ { @@ -297,7 +301,7 @@ export default { { comment: 'UTF-8 percent encoding with the userinfo encode set.', href: 'http://example.net/', - newValue: "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", + newValue: "\u0000\u0001\t\n\r\u001F !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007F\u0080\u0081Éé", expected: { href: "http://%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/", username: "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9", @@ -400,7 +404,7 @@ export default { { comment: 'UTF-8 percent encoding with the userinfo encode set.', href: 'http://example.net/', - newValue: "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", + newValue: "\u0000\u0001\t\n\r\u001F !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007F\u0080\u0081Éé", expected: { href: "http://:%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9@example.net/", password: "%00%01%09%0A%0D%1F%20!%22%23$%&'()*+,-.%2F09%3A%3B%3C%3D%3E%3F%40AZ%5B%5C%5D%5E_%60az%7B%7C%7D~%7F%C2%80%C2%81%C3%89%C3%A9", @@ -1539,7 +1543,7 @@ export default { { comment: 'UTF-8 percent encoding with the default encode set. Tabs and newlines are removed.', href: 'a:/', - newValue: "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", + newValue: "\u0000\u0001\t\n\r\u001F !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007F\u0080\u0081Éé", expected: { href: "a:/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9", pathname: "/%00%01%1F%20!%22%23$%&'()*+,-./09:;%3C=%3E%3F@AZ[\\]^_%60az%7B|%7D~%7F%C2%80%C2%81%C3%89%C3%A9", @@ -1796,7 +1800,7 @@ export default { { comment: 'Simple percent-encoding; nuls, tabs, and newlines are removed', href: 'a:/', - newValue: "\u0000\u0001\t\n\r\u001f !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007f\u0080\u0081Éé", + newValue: "\u0000\u0001\t\n\r\u001F !\"#$%&'()*+,-./09:;<=>?@AZ[\\]^_`az{|}~\u007F\u0080\u0081Éé", expected: { href: "a:/#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", hash: "#%01%1F%20!%22#$%&'()*+,-./09:;%3C=%3E?@AZ[\\]^_%60az{|}~%7F%C2%80%C2%81%C3%89%C3%A9", diff --git a/tests/wpt-url-resources/toascii.js b/tests/wpt-url-resources/toascii.js index 28f6b24d02af..a71795682a9f 100644 --- a/tests/wpt-url-resources/toascii.js +++ b/tests/wpt-url-resources/toascii.js @@ -1,4 +1,8 @@ -/* eslint-disable max-len */ +// Copyright © web-platform-tests contributors +// Originally from https://github.com/web-platform-tests/wpt +// Available under the 3-Clause BSD License https://github.com/web-platform-tests/wpt/blob/master/LICENSE.md + +/* eslint-disable @stylistic/max-len -- ignore */ export default [ { comment: 'Label with hyphens in 3rd and 4th position', diff --git a/tests/wpt-url-resources/urltestdata.js b/tests/wpt-url-resources/urltestdata.js index 41a8cc18402b..aeffd775efc5 100644 --- a/tests/wpt-url-resources/urltestdata.js +++ b/tests/wpt-url-resources/urltestdata.js @@ -1,4 +1,8 @@ -/* eslint-disable no-script-url */ +// Copyright © web-platform-tests contributors +// Originally from https://github.com/web-platform-tests/wpt +// Available under the 3-Clause BSD License https://github.com/web-platform-tests/wpt/blob/master/LICENSE.md + +/* eslint-disable no-script-url -- required for testing */ export default [ '# Based on http://trac.webkit.org/browser/trunk/LayoutTests/fast/url/script-tests/segments.js', { @@ -4425,7 +4429,7 @@ export default [ failure: true, }, { - input: 'sc://te@s:t@/', + input: 'sc://tes@s:t@/', base: 'about:blank', failure: true, }, diff --git a/website/build-local.mjs b/website/build-local.mjs new file mode 100644 index 000000000000..fe29ecb38dd0 --- /dev/null +++ b/website/build-local.mjs @@ -0,0 +1,31 @@ +import { + isExists, copyBlogPosts, copyBabelStandalone, copyCommonFiles, buildWeb, getCurrentBranch, buildAndCopyCoreJS, +} from './scripts/helpers.mjs'; +import { join } from 'node:path'; + +const BUILD_SRC_DIR = './'; + +async function hasDocsLocal(srcDir) { + const target = join(srcDir, 'docs/web/docs'); + console.log(`Checking if docs exist in "${ target }"...`); + if (!await isExists(target)) { + throw new Error(`Docs not found in "${ target }".`); + } +} + +try { + console.time('Finished in'); + const targetBranch = await getCurrentBranch(BUILD_SRC_DIR); + + const version = { branch: targetBranch, label: targetBranch }; + await hasDocsLocal(BUILD_SRC_DIR); + await buildAndCopyCoreJS(version, BUILD_SRC_DIR); + + await copyBabelStandalone(BUILD_SRC_DIR); + await copyBlogPosts(BUILD_SRC_DIR); + await copyCommonFiles(BUILD_SRC_DIR); + await buildWeb(targetBranch, BUILD_SRC_DIR, true); + console.timeEnd('Finished in'); +} catch (error) { + console.error(error); +} diff --git a/website/build.mjs b/website/build.mjs new file mode 100644 index 000000000000..d5a0f3225b7b --- /dev/null +++ b/website/build.mjs @@ -0,0 +1,359 @@ +import { expandVersionsConfig, getDefaultVersion } from './scripts/helpers.mjs'; +import fm from 'front-matter'; +import { JSDOM } from 'jsdom'; +import { Marked } from 'marked'; +import { gfmHeadingId, getHeadingList } from 'marked-gfm-heading-id'; +import markedAlert from 'marked-alert'; +import config from './config/config.mjs'; +import { argv, fs } from 'zx'; + +const { copy, mkdir, readFile, readJson, readdir, writeFile } = fs; + +const branchArg = argv._.find(item => item.startsWith('branch=')); +const BRANCH = branchArg ? branchArg.slice('branch='.length) : undefined; +const LOCAL = argv._.includes('local'); +const BASE = LOCAL && BRANCH ? '/core-js/website/dist/' : BRANCH ? `/branches/${ BRANCH }/` : '/'; +const DEFAULT_VERSION = await getDefaultVersion(config.versionsFile, BRANCH); + +let htmlFileName = ''; +let docsMenu = ''; +let isBlog = false; +let isDocs = false; + +async function getAllMdFiles(dir) { + const entries = await readdir(dir, { withFileTypes: true }); + const files = []; + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + const subFiles = await getAllMdFiles(fullPath); + files.push(...subFiles); + } else if (entry.isFile() && entry.name.endsWith('.md')) { + files.push(fullPath); + } + } + return files; +} + +async function buildDocsMenu(item) { + if (Object.hasOwn(item, 'children')) { + let result = `
  • ${ item.title }
      `; + for (const child of item.children) { + result += await buildDocsMenu(child); + } + result += '
  • '; + return result; + } + + return `
  • ${ item.title }
  • `; +} + +const docsMenus = []; +const docsMenuItems = []; + +async function getDocsMenuItems(version) { + if (docsMenuItems[version]) return docsMenuItems[version]; + + echo(chalk.green(`Getting menu items from file for version: ${ version }`)); + const jsonPath = BRANCH ? `${ config.docsDir }docs/menu.json` : `${ config.docsDir }${ version }/docs/menu.json`; + try { + const docsMenuJson = await readJson(jsonPath); + docsMenuItems[version] = docsMenuJson === '' ? [] : docsMenuJson; + return docsMenuItems[version]; + } catch { + echo(chalk.yellow(`Menu JSON file not found: ${ jsonPath }`)); + return ''; + } +} + +async function buildDocsMenuForVersion(version) { + if (docsMenus[version]) return docsMenus[version]; + + echo(chalk.green(`Building docs menu for version: ${ version }`)); + const menuItems = await getDocsMenuItems(version); + if (!menuItems.length) return ''; + let menu = '
    • {versions-menu}
    • '; + for (const item of menuItems) { + menu += await buildDocsMenu(item); + } + menu += '
    '; + docsMenus[version] = menu; + return menu; +} + +function getBundlesPath(version) { + return path.join(config.bundlesPath, version.branch ?? version.tag); +} + +async function buildVersionsMenuList(versions, currentVersion, section) { + let versionsMenuHtml = ''; + + return versionsMenuHtml; +} + +async function buildVersionsMenu(versions, currentVersion, section) { + const innerMenu = await buildVersionsMenuList(versions, currentVersion, section); + + return ``; +} + +let fileMetadata = {}; + +function metadata(markdown) { + const { attributes, body } = fm(markdown); + fileMetadata = {}; + for (const prop of Object.keys(attributes)) { + fileMetadata[prop] = attributes[prop]; + } + return body; +} + +const markedInline = new Marked(); + +const linkRenderer = { + link({ href, text }) { + const htmlContent = markedInline.parseInline(text); + const isExternal = /^https?:\/\//.test(href); + const isAnchor = href.startsWith('#'); + if (isAnchor) href = htmlFileName.replace('.html', '') + href.toLowerCase(); + let html = `${ htmlContent }`; + return html; + }, +}; + +const marked = new Marked(); +marked.use(markedAlert(), gfmHeadingId({ prefix: 'h-' })); +marked.use({ hooks: { preprocess: metadata } }); +marked.use({ renderer: linkRenderer }); + +const markedWithContents = new Marked(); +markedWithContents.use(markedAlert(), gfmHeadingId({ prefix: 'h-' })); +markedWithContents.use({ + hooks: { + preprocess: metadata, + postprocess: buildMenus, + }, + renderer: linkRenderer, +}); + +function buildMenus(html) { + const headings = getHeadingList().filter(({ level }) => level > 1); + let result = '
    '; + if (isBlog || isDocs) { + result += `
    `; + } + result += `
    ${ html }
    `; + if (headings.length && !Object.hasOwn(fileMetadata, 'disableContentMenu')) { + result += `
    `; + } + return result; +} + +let blogMenuCache = ''; + +async function buildBlogMenu() { + if (blogMenuCache !== '') return blogMenuCache; + + const mdFiles = await getAllMdFiles(config.blogDir); + mdFiles.reverse(); + let index = '---\ndisableContentMenu: true\n---\n'; + let menu = '
      '; + for (const mdPath of mdFiles) { + if (mdPath.endsWith('index.md')) continue; + const content = await readFileContent(mdPath); + const tokens = marked.lexer(content); + const firstH1 = tokens.find(token => token.type === 'heading' && token.depth === 1); + + if (!firstH1) { + echo(chalk.yellow(`H1 not found in ${ mdPath }`)); + continue; + } + let htmlContent = await marked.parse(content); + htmlContent = htmlContent.replace(/

      [^<]*<\/h1>/i, ''); + const hrIndex = htmlContent.search(/
      /i); + const preview = hrIndex !== -1 ? htmlContent.slice(0, hrIndex) : htmlContent; + + const match = mdPath.match(/(?\d{4}-\d{2}-\d{2})-/); + const date = match?.groups?.date ?? ''; + const fileName = mdPath.replace(config.blogDir, '').replace(/\.md$/i, ''); + menu += `
    • ${ date }: ${ firstH1.text }
    • `; + index += `## [${ firstH1.text }](./blog/${ fileName })\n\n`; + if (date) index += `*${ date }*\n\n`; + index += `${ preview }\n\n`; + } + menu += '

    '; + blogMenuCache = menu; + const blogIndexPath = path.join(config.blogDir, 'index.md'); + await writeFile(blogIndexPath, index, 'utf8'); + echo(chalk.green(`File created: ${ blogIndexPath }`)); + + return menu; +} + +async function getVersionFromMdFile(mdPath) { + const match = mdPath.match(/\/web\/(?[^/]+)\/docs\//); + return match?.groups?.version ?? DEFAULT_VERSION; +} + +async function readFileContent(filePath) { + const content = await readFile(filePath, 'utf8'); + return content.toString(); +} + +async function buildPlaygrounds(template, versions) { + for (const version of versions) { + await buildPlayground(template, version, versions); + } +} + +async function buildPlayground(template, version, versions) { + const bundlesPath = getBundlesPath(version); + const bundleScript = ``; + const bundleESModulesScript = ``; + const babelScript = ''; + const playgroundContent = await readFileContent(`${ config.srcDir }playground.html`); + const versionsMenu = await buildVersionsMenu(versions, version.label, 'playground'); + let playground = template.replace('{content}', playgroundContent); + playground = playground.replace('{base}', BASE); + playground = playground.replace('{title}', 'Playground - '); + playground = playground.replace('{core-js-bundle}', bundleScript); + playground = playground.replace('{core-js-bundle-esmodules}', bundleESModulesScript); + playground = playground.replace('{babel-script}', babelScript); + const playgroundWithVersion = playground.replace('{versions-menu}', versionsMenu); + const playgroundFilePath = path.join(config.resultDir, version.path, 'playground.html'); + + if (version.default) { + const defaultVersionsMenu = await buildVersionsMenu(versions, version.label, 'playground'); + const defaultVersionPlayground = playground.replace('{versions-menu}', defaultVersionsMenu); + const defaultPlaygroundPath = path.join(config.resultDir, 'playground.html'); + await writeFile(defaultPlaygroundPath, defaultVersionPlayground, 'utf8'); + echo(chalk.green(`File created: ${ defaultPlaygroundPath }`)); + } else { + await mkdir(path.dirname(playgroundFilePath), { recursive: true }); + await writeFile(playgroundFilePath, playgroundWithVersion, 'utf8'); + echo(chalk.green(`File created: ${ playgroundFilePath }`)); + } +} + +async function createDocsIndexes(versions) { + if (BRANCH) versions = [{ path: '' }]; + + for (const version of versions) { + if (version.default && versions.length > 1) continue; + const versionPath = version.path; + const menuItems = await getDocsMenuItems(versionPath); + const firstDocPath = path.join(config.resultDir, + `${ menuItems[0].url }.html`.replace(`{docs-version}${ BRANCH ? '/' : '' }`, versionPath)); + const indexFilePath = path.join(config.resultDir, `${ versionPath }/docs/`, 'index.html'); + await copy(firstDocPath, indexFilePath); + echo(chalk.green(`File created: ${ indexFilePath }`)); + } +} + +async function getVersions() { + if (BRANCH) { + return [{ + branch: BRANCH, + default: true, + label: BRANCH, + path: BRANCH, + }]; + } + + const versions = await readJson(config.versionsFile); + echo(chalk.green('Got versions from file')); + + return expandVersionsConfig(versions); +} + +function getTitle(content) { + const match = /^# (?.+)$/m.exec(content); + return match?.groups?.title ? `${ match.groups.title } - ` : ''; +} + +async function build() { + const template = await readFileContent(config.templatePath); + await buildBlogMenu(); + const mdFiles = await getAllMdFiles(config.docsDir); + const versions = await getVersions(); + const [defaultVersion] = versions; + const bundlesPath = getBundlesPath(defaultVersion); + const bundleScript = `<script nomodule src="http://github.com/$%7B%20bundlesPath%20%7D/$%7B%20config.bundleName%20%7D"></script>`; + const bundleESModulesScript = `<script type="module" src="http://github.com/$%7B%20bundlesPath%20%7D/$%7B%20config.bundleNameESModules%20%7D"></script>`; + + let currentVersion = ''; + let versionsMenu = ''; + let isChangelog; + for (let i = 0; i < mdFiles.length; i++) { + const mdPath = mdFiles[i]; + const content = await readFileContent(mdPath); + isDocs = mdPath.includes('/docs'); + isChangelog = mdPath.includes('/changelog'); + isBlog = mdPath.includes('/blog'); + + const title = getTitle(content); + + const versionFromMdFile = await getVersionFromMdFile(mdPath); + if (currentVersion !== versionFromMdFile) { + currentVersion = versionFromMdFile; + docsMenu = await buildDocsMenuForVersion(currentVersion); + versionsMenu = await buildVersionsMenu(versions, currentVersion, 'docs/'); + } + + htmlFileName = mdPath.replace(config.docsDir, '').replace(/\.md$/i, '.html'); + const htmlFilePath = path.join(config.resultDir, htmlFileName); + const htmlContent = isDocs || isBlog || isChangelog ? markedWithContents.parse(content) : marked.parse(content); + + let resultHtml = template.replace('{content}', htmlContent.replaceAll('$', '$')); + + resultHtml = resultHtml.replace('{title}', title); + resultHtml = resultHtml.replace('{base}', BASE); + resultHtml = resultHtml.replace('{core-js-bundle}', bundleScript); + resultHtml = resultHtml.replace('{core-js-bundle-esmodules}', bundleESModulesScript); + resultHtml = resultHtml.replaceAll('{versions-menu}', versionsMenu); + resultHtml = resultHtml.replaceAll('{current-version}', currentVersion); + + if (isDocs || isBlog || isChangelog) { + const resultDOM = new JSDOM(resultHtml); + const { document } = resultDOM.window; + document.querySelectorAll('h2[id], h3[id], h4[id], h5[id], h6[id]').forEach(heading => { + const newHeading = heading.cloneNode(true); + const anchor = document.createElement('a'); + anchor.className = 'anchor'; + anchor.href = `${ htmlFileName.replace('.html', '') }#${ newHeading.id }`; + anchor.innerHTML = '<svg viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="m7.775 3.275 1.25-1.25a3.5 3.5 0 1 1 4.95 4.95l-2.5 2.5a3.5 3.5 0 0 1-4.95 0 .751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018 1.998 1.998 0 0 0 2.83 0l2.5-2.5a2.002 2.002 0 0 0-2.83-2.83l-1.25 1.25a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042Zm-4.69 9.64a1.998 1.998 0 0 0 2.83 0l1.25-1.25a.751.751 0 0 1 1.042.018.751.751 0 0 1 .018 1.042l-1.25 1.25a3.5 3.5 0 1 1-4.95-4.95l2.5-2.5a3.5 3.5 0 0 1 4.95 0 .751.751 0 0 1-.018 1.042.751.751 0 0 1-1.042.018 1.998 1.998 0 0 0-2.83 0l-2.5 2.5a1.998 1.998 0 0 0 0 2.83Z"></path></svg>'; + newHeading.append(anchor); + newHeading.classList.add('with-anchor'); + resultHtml = resultHtml.replace(heading.outerHTML, newHeading.outerHTML); + }); + } + + resultHtml = resultHtml.replaceAll('{docs-version}', currentVersion); + + await mkdir(path.dirname(htmlFilePath), { recursive: true }); + + await writeFile(htmlFilePath, resultHtml, 'utf8'); + echo(chalk.green(`File created: ${ htmlFilePath }`)); + } + + await buildPlaygrounds(template, versions); + await createDocsIndexes(versions); +} + +await build().catch(console.error); diff --git a/website/clean.mjs b/website/clean.mjs new file mode 100644 index 000000000000..3a042a8f5166 --- /dev/null +++ b/website/clean.mjs @@ -0,0 +1,3 @@ +await fs.rm('website/dist/', { force: true, recursive: true }); + +echo(chalk.green('Old copies removed')); diff --git a/website/config/config.mjs b/website/config/config.mjs new file mode 100644 index 000000000000..eedcb1554ffc --- /dev/null +++ b/website/config/config.mjs @@ -0,0 +1,12 @@ +export default { + docsDir: 'docs/web/', + blogDir: 'docs/web/blog/', + resultDir: 'website/dist/', + templatesDir: 'website/templates/', + templatePath: 'website/templates/index.html', + srcDir: 'website/src/', + versionsFile: 'website/config/versions.json', + bundlesPath: './bundles', + bundleName: 'core-js-bundle.js', + bundleNameESModules: 'core-js-bundle-esmodules.js', +}; diff --git a/website/config/versions.json b/website/config/versions.json new file mode 100644 index 000000000000..14dd37681adf --- /dev/null +++ b/website/config/versions.json @@ -0,0 +1,12 @@ +[ + { + "label": "v3", + "default": true, + "branch": "master" + }, + { + "label": "v4 (alpha)", + "branch": "v4", + "path": "v4" + } +] diff --git a/website/copy.mjs b/website/copy.mjs new file mode 100644 index 000000000000..1545d82c7087 --- /dev/null +++ b/website/copy.mjs @@ -0,0 +1,7 @@ +const { copy } = fs; + +await copy('website/templates/assets', 'website/dist/assets'); +await copy('website/templates/bundles', 'website/dist/bundles'); +await copy('website/templates/babel.min.js', 'website/dist/babel.min.js'); + +echo(chalk.green('Assets copied')); diff --git a/website/index.mjs b/website/index.mjs new file mode 100644 index 000000000000..aaab90fc362a --- /dev/null +++ b/website/index.mjs @@ -0,0 +1,4 @@ +await import('./clean.mjs'); +await $`npm run build --prefix website`; +await import('./build.mjs'); +await import('./copy.mjs'); diff --git a/website/package-lock.json b/website/package-lock.json new file mode 100644 index 000000000000..f60531d09cff --- /dev/null +++ b/website/package-lock.json @@ -0,0 +1,4257 @@ +{ + "name": "website", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "website", + "dependencies": { + "@babel/standalone": "^7.28.5", + "@popperjs/core": "^2.11.8", + "@vitejs/plugin-legacy": "^7.2.1", + "front-matter": "^4.0.2", + "highlight.js": "^11.11.1", + "jsdom": "^27.3.0", + "marked": "^17.0.1", + "marked-alert": "^2.1.2", + "marked-gfm-heading-id": "^4.1.3", + "sass": "^1.97.0", + "vite": "^7.3.0" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.29", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.29.tgz", + "integrity": "sha512-G90x0VW+9nW4dFajtjCoT+NM0scAfH9Mb08IcjgFHYbfiL/lU04dTF9JuVOi3/OH+DJCQdcIseSXkdCB9Ky6JA==", + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.0.tgz", + "integrity": "sha512-9xiBAtLn4aNsa4mDnpovJvBn72tNEIACyvlqaNJ+ADemR+yeMJWnBudOi2qGDviJa7SwcDOU/TRh5dnET7qk0w==", + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "lru-cache": "^11.2.2" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.7.6", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.6.tgz", + "integrity": "sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.4" + } + }, + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", + "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-member-expression-to-functions": "^7.28.5", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.28.5", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz", + "integrity": "sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "regexpu-core": "^6.3.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz", + "integrity": "sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", + "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.3", + "@babel/types": "^7.28.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz", + "integrity": "sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", + "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", + "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", + "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-remap-async-to-generator": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", + "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", + "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", + "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz", + "integrity": "sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-explicit-resource-management": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", + "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", + "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", + "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", + "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", + "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", + "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", + "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", + "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-option": "^7.27.1", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.27.1", + "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.28.0", + "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-block-scoped-functions": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.5", + "@babel/plugin-transform-class-properties": "^7.27.1", + "@babel/plugin-transform-class-static-block": "^7.28.3", + "@babel/plugin-transform-classes": "^7.28.4", + "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.5", + "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-keys": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-explicit-resource-management": "^7.28.0", + "@babel/plugin-transform-exponentiation-operator": "^7.28.5", + "@babel/plugin-transform-export-namespace-from": "^7.27.1", + "@babel/plugin-transform-for-of": "^7.27.1", + "@babel/plugin-transform-function-name": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-literals": "^7.27.1", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", + "@babel/plugin-transform-member-expression-literals": "^7.27.1", + "@babel/plugin-transform-modules-amd": "^7.27.1", + "@babel/plugin-transform-modules-commonjs": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.28.5", + "@babel/plugin-transform-modules-umd": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-new-target": "^7.27.1", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", + "@babel/plugin-transform-numeric-separator": "^7.27.1", + "@babel/plugin-transform-object-rest-spread": "^7.28.4", + "@babel/plugin-transform-object-super": "^7.27.1", + "@babel/plugin-transform-optional-catch-binding": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.28.5", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/plugin-transform-private-methods": "^7.27.1", + "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-property-literals": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.28.4", + "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-reserved-words": "^7.27.1", + "@babel/plugin-transform-shorthand-properties": "^7.27.1", + "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-sticky-regex": "^7.27.1", + "@babel/plugin-transform-template-literals": "^7.27.1", + "@babel/plugin-transform-typeof-symbol": "^7.27.1", + "@babel/plugin-transform-unicode-escapes": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.14", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "core-js-compat": "^3.43.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/standalone": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.28.5.tgz", + "integrity": "sha512-1DViPYJpRU50irpGMfLBQ9B4kyfQuL6X7SS7pwTeWeZX0mNkjzPi0XFqxCjSdddZXUQy4AhnQnnesA/ZHnvAdw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + } + }, + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.14.tgz", + "integrity": "sha512-zSlIxa20WvMojjpCSy8WrNpcZ61RqfTfX3XTaOeVlGJrt/8HF3YbzgFZa01yTbT4GWQLwfTcC3EB8i3XnB647Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "postcss": "^8.4" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.1.tgz", + "integrity": "sha512-HHB50pdsBX6k47S4u5g/CaLjqS3qwaOVE5ILsq64jyzgMhLuCuZ8rGzM9yhsAjfjkbgUPMzZEPa7DAp7yz6vuA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.1.tgz", + "integrity": "sha512-kFqa6/UcaTbGm/NncN9kzVOODjhZW8e+FRdSeypWe6j33gzclHtwlANs26JrupOntlcWmB0u8+8HZo8s7thHvg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.1.tgz", + "integrity": "sha512-45fuKmAJpxnQWixOGCrS+ro4Uvb4Re9+UTieUY2f8AEc+t7d4AaZ6eUJ3Hva7dtrxAAWHtlEFsXFMAgNnGU9uQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.1.tgz", + "integrity": "sha512-LBEpOz0BsgMEeHgenf5aqmn/lLNTFXVfoWMUox8CtWWYK9X4jmQzWjoGoNb8lmAYml/tQ/Ysvm8q7szu7BoxRQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.1.tgz", + "integrity": "sha512-veg7fL8eMSCVKL7IW4pxb54QERtedFDfY/ASrumK/SbFsXnRazxY4YykN/THYqFnFwJ0aVjiUrVG2PwcdAEqQQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.1.tgz", + "integrity": "sha512-+3ELd+nTzhfWb07Vol7EZ+5PTbJ/u74nC6iv4/lwIU99Ip5uuY6QoIf0Hn4m2HoV0qcnRivN3KSqc+FyCHjoVQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.1.tgz", + "integrity": "sha512-/8Rfgns4XD9XOSXlzUDepG8PX+AVWHliYlUkFI3K3GB6tqbdjYqdhcb4BKRd7C0BhZSoaCxhv8kTcBrcZWP+xg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.1.tgz", + "integrity": "sha512-GITpD8dK9C+r+5yRT/UKVT36h/DQLOHdwGVwwoHidlnA168oD3uxA878XloXebK4Ul3gDBBIvEdL7go9gCUFzQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.1.tgz", + "integrity": "sha512-ieMID0JRZY/ZeCrsFQ3Y3NlHNCqIhTprJfDgSB3/lv5jJZ8FX3hqPyXWhe+gvS5ARMBJ242PM+VNz/ctNj//eA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.1.tgz", + "integrity": "sha512-W9//kCrh/6in9rWIBdKaMtuTTzNj6jSeG/haWBADqLLa9P8O5YSRDzgD5y9QBok4AYlzS6ARHifAb75V6G670Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.1.tgz", + "integrity": "sha512-VIUV4z8GD8rtSVMfAj1aXFahsi/+tcoXXNYmXgzISL+KB381vbSTNdeZHHHIYqFyXcoEhu9n5cT+05tRv13rlw==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.1.tgz", + "integrity": "sha512-l4rfiiJRN7sTNI//ff65zJ9z8U+k6zcCg0LALU5iEWzY+a1mVZ8iWC1k5EsNKThZ7XCQ6YWtsZ8EWYm7r1UEsg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.1.tgz", + "integrity": "sha512-U0bEuAOLvO/DWFdygTHWY8C067FXz+UbzKgxYhXC0fDieFa0kDIra1FAhsAARRJbvEyso8aAqvPdNxzWuStBnA==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.1.tgz", + "integrity": "sha512-NzdQ/Xwu6vPSf/GkdmRNsOfIeSGnh7muundsWItmBsVpMoNPVpM61qNzAVY3pZ1glzzAxLR40UyYM23eaDDbYQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.1.tgz", + "integrity": "sha512-7zlw8p3IApcsN7mFw0O1Z1PyEk6PlKMu18roImfl3iQHTnr/yAfYv6s4hXPidbDoI2Q0pW+5xeoM4eTCC0UdrQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.1.tgz", + "integrity": "sha512-cGj5wli+G+nkVQdZo3+7FDKC25Uh4ZVwOAK6A06Hsvgr8WqBBuOy/1s+PUEd/6Je+vjfm6stX0kmib5b/O2Ykw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.1.tgz", + "integrity": "sha512-z3H/HYI9MM0HTv3hQZ81f+AKb+yEoCRlUby1F80vbQ5XdzEMyY/9iNlAmhqiBKw4MJXwfgsh7ERGEOhrM1niMA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.1.tgz", + "integrity": "sha512-wzC24DxAvk8Em01YmVXyjl96Mr+ecTPyOuADAvjGg+fyBpGmxmcr2E5ttf7Im8D0sXZihpxzO1isus8MdjMCXQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.1.tgz", + "integrity": "sha512-1YQ8ybGi2yIXswu6eNzJsrYIGFpnlzEWRl6iR5gMgmsrR0FcNoV1m9k9sc3PuP5rUBLshOZylc9nqSgymI+TYg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.1.tgz", + "integrity": "sha512-5Z+DzLCrq5wmU7RDaMDe2DVXMRm2tTDvX2KU14JJVBN2CT/qov7XVix85QoJqHltpvAOZUAc3ndU56HSMWrv8g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.1.tgz", + "integrity": "sha512-Q73ENzIdPF5jap4wqLtsfh8YbYSZ8Q0wnxplOlZUOyZy7B4ZKW8DXGWgTCZmF8VWD7Tciwv5F4NsRf6vYlZtqg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.1.tgz", + "integrity": "sha512-ajbHrGM/XiK+sXM0JzEbJAen+0E+JMQZ2l4RR4VFwvV9JEERx+oxtgkpoKv1SevhjavK2z2ReHk32pjzktWbGg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.1.tgz", + "integrity": "sha512-IPUW+y4VIjuDVn+OMzHc5FV4GubIwPnsz6ubkvN8cuhEqH81NovB53IUlrlBkPMEPxvNnf79MGBoz8rZ2iW8HA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.1.tgz", + "integrity": "sha512-RIVRWiljWA6CdVu8zkWcRmGP7iRRIIwvhDKem8UMBjPql2TXM5PkDVvvrzMtj1V+WFPB4K7zkIGM7VzRtFkjdg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.1.tgz", + "integrity": "sha512-2BR5M8CPbptC1AK5JbJT1fWrHLvejwZidKx3UMSF0ecHMa+smhi16drIrCEggkgviBwLYd5nwrFLSl5Kho96RQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.1.tgz", + "integrity": "sha512-d5X6RMYv6taIymSk8JBP+nxv8DQAMY6A51GPgusqLdK9wBz5wWIXy1KjTck6HnjE9hqJzJRdk+1p/t5soSbCtw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.5.tgz", + "integrity": "sha512-iDGS/h7D8t7tvZ1t6+WPK04KD0MwzLZrG0se1hzBjSi5fyxlsiggoJHwh18PCFNn7tG43OWb6pdZ6Y+rMlmyNQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.5.tgz", + "integrity": "sha512-wrSAViWvZHBMMlWk6EJhvg8/rjxzyEhEdgfMMjREHEq11EtJ6IP6yfcCH57YAEca2Oe3FNCE9DSTgU70EIGmVw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.5.tgz", + "integrity": "sha512-S87zZPBmRO6u1YXQLwpveZm4JfPpAa6oHBX7/ghSiGH3rz/KDgAu1rKdGutV+WUI6tKDMbaBJomhnT30Y2t4VQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.5.tgz", + "integrity": "sha512-YTbnsAaHo6VrAczISxgpTva8EkfQus0VPEVJCEaboHtZRIb6h6j0BNxRBOwnDciFTZLDPW5r+ZBmhL/+YpTZgA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.5.tgz", + "integrity": "sha512-1T8eY2J8rKJWzaznV7zedfdhD1BqVs1iqILhmHDq/bqCUZsrMt+j8VCTHhP0vdfbHK3e1IQ7VYx3jlKqwlf+vw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.5.tgz", + "integrity": "sha512-sHTiuXyBJApxRn+VFMaw1U+Qsz4kcNlxQ742snICYPrY+DDL8/ZbaC4DVIB7vgZmp3jiDaKA0WpBdP0aqPJoBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.5.tgz", + "integrity": "sha512-dV3T9MyAf0w8zPVLVBptVlzaXxka6xg1f16VAQmjg+4KMSTWDvhimI/Y6mp8oHwNrmnmVl9XxJ/w/mO4uIQONA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.5.tgz", + "integrity": "sha512-wIGYC1x/hyjP+KAu9+ewDI+fi5XSNiUi9Bvg6KGAh2TsNMA3tSEs+Sh6jJ/r4BV/bx/CyWu2ue9kDnIdRyafcQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.5.tgz", + "integrity": "sha512-Y+qVA0D9d0y2FRNiG9oM3Hut/DgODZbU9I8pLLPwAsU0tUKZ49cyV1tzmB/qRbSzGvY8lpgGkJuMyuhH7Ma+Vg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.5.tgz", + "integrity": "sha512-juaC4bEgJsyFVfqhtGLz8mbopaWD+WeSOYr5E16y+1of6KQjc0BpwZLuxkClqY1i8sco+MdyoXPNiCkQou09+g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.5.tgz", + "integrity": "sha512-rIEC0hZ17A42iXtHX+EPJVL/CakHo+tT7W0pbzdAGuWOt2jxDFh7A/lRhsNHBcqL4T36+UiAgwO8pbmn3dE8wA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.5.tgz", + "integrity": "sha512-T7l409NhUE552RcAOcmJHj3xyZ2h7vMWzcwQI0hvn5tqHh3oSoclf9WgTl+0QqffWFG8MEVZZP1/OBglKZx52Q==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.5.tgz", + "integrity": "sha512-7OK5/GhxbnrMcxIFoYfhV/TkknarkYC1hqUw1wU2xUN3TVRLNT5FmBv4KkheSG2xZ6IEbRAhTooTV2+R5Tk0lQ==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.5.tgz", + "integrity": "sha512-GwuDBE/PsXaTa76lO5eLJTyr2k8QkPipAyOrs4V/KJufHCZBJ495VCGJol35grx9xryk4V+2zd3Ri+3v7NPh+w==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.5.tgz", + "integrity": "sha512-IAE1Ziyr1qNfnmiQLHBURAD+eh/zH1pIeJjeShleII7Vj8kyEm2PF77o+lf3WTHDpNJcu4IXJxNO0Zluro8bOw==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.5.tgz", + "integrity": "sha512-Pg6E+oP7GvZ4XwgRJBuSXZjcqpIW3yCBhK4BcsANvb47qMvAbCjR6E+1a/U2WXz1JJxp9/4Dno3/iSJLcm5auw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.5.tgz", + "integrity": "sha512-txGtluxDKTxaMDzUduGP0wdfng24y1rygUMnmlUJ88fzCCULCLn7oE5kb2+tRB+MWq1QDZT6ObT5RrR8HFRKqg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.5.tgz", + "integrity": "sha512-3DFiLPnTxiOQV993fMc+KO8zXHTcIjgaInrqlG8zDp1TlhYl6WgrOHuJkJQ6M8zHEcntSJsUp1XFZSY8C1DYbg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.5.tgz", + "integrity": "sha512-nggc/wPpNTgjGg75hu+Q/3i32R00Lq1B6N1DO7MCU340MRKL3WZJMjA9U4K4gzy3dkZPXm9E1Nc81FItBVGRlA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.5.tgz", + "integrity": "sha512-U/54pTbdQpPLBdEzCT6NBCFAfSZMvmjr0twhnD9f4EIvlm9wy3jjQ38yQj1AGznrNO65EWQMgm/QUjuIVrYF9w==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.5.tgz", + "integrity": "sha512-2NqKgZSuLH9SXBBV2dWNRCZmocgSOx8OJSdpRaEcRlIfX8YrKxUT6z0F1NpvDVhOsl190UFTRh2F2WDWWCYp3A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.5.tgz", + "integrity": "sha512-JRpZUhCfhZ4keB5v0fe02gQJy05GqboPOaxvjugW04RLSYYoB/9t2lx2u/tMs/Na/1NXfY8QYjgRljRpN+MjTQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-legacy": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-legacy/-/plugin-legacy-7.2.1.tgz", + "integrity": "sha512-CaXb/y0mlfu7jQRELEJJc2/5w2bX2m1JraARgFnvSB2yfvnCNJVWWlqAo6WjnKoepOwKx8gs0ugJThPLKCOXIg==", + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-dynamic-import": "^7.27.1", + "@babel/plugin-transform-modules-systemjs": "^7.27.1", + "@babel/preset-env": "^7.28.0", + "babel-plugin-polyfill-corejs3": "^0.13.0", + "babel-plugin-polyfill-regenerator": "^0.6.5", + "browserslist": "^4.25.1", + "browserslist-to-esbuild": "^2.1.1", + "core-js": "^3.45.0", + "magic-string": "^0.30.17", + "regenerator-runtime": "^0.14.1", + "systemjs": "^6.15.1" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "peerDependencies": { + "terser": "^5.16.0", + "vite": "^7.0.0" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", + "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5", + "core-js-compat": "^3.43.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.7", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz", + "integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "optional": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/browserslist-to-esbuild": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/browserslist-to-esbuild/-/browserslist-to-esbuild-2.1.1.tgz", + "integrity": "sha512-KN+mty6C3e9AN8Z5dI1xeN15ExcRNeISoC3g7V0Kax/MMF9MSoYA2G7lkTTcVUFntiEjkpI0HNgqJC1NjdyNUw==", + "license": "MIT", + "dependencies": { + "meow": "^13.0.0" + }, + "bin": { + "browserslist-to-esbuild": "cli/index.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "browserslist": "*" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "license": "MIT" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001760", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz", + "integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "license": "MIT" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/core-js": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.47.0.tgz", + "integrity": "sha512-c3Q2VVkGAUyupsjRnaNX6u8Dq2vAdzm9iuPj5FW0fRxzlxgq9Q39MDq10IvmQSpLgHQNyQzQmOo6bgGHmH3NNg==", + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-compat": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", + "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", + "license": "MIT", + "dependencies": { + "browserslist": "^4.28.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssstyle": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.4.tgz", + "integrity": "sha512-KyOS/kJMEq5O9GdPnaf82noigg5X5DYn0kZPJTaAsCUaBizp6Xa1y9D4Qoqf/JazEXWuruErHgVXwjN5391ZJw==", + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.0", + "@csstools/css-syntax-patches-for-csstree": "1.0.14", + "css-tree": "^3.1.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/data-urls": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.0.tgz", + "integrity": "sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==", + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "license": "ISC" + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.27.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.1.tgz", + "integrity": "sha512-yY35KZckJJuVVPXpvjgxiCuVEJT67F6zDeVTv4rizyPrfGBUpZQsvmxnN+C371c2esD/hNMjj4tpBhuueLN7aA==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.1", + "@esbuild/android-arm": "0.27.1", + "@esbuild/android-arm64": "0.27.1", + "@esbuild/android-x64": "0.27.1", + "@esbuild/darwin-arm64": "0.27.1", + "@esbuild/darwin-x64": "0.27.1", + "@esbuild/freebsd-arm64": "0.27.1", + "@esbuild/freebsd-x64": "0.27.1", + "@esbuild/linux-arm": "0.27.1", + "@esbuild/linux-arm64": "0.27.1", + "@esbuild/linux-ia32": "0.27.1", + "@esbuild/linux-loong64": "0.27.1", + "@esbuild/linux-mips64el": "0.27.1", + "@esbuild/linux-ppc64": "0.27.1", + "@esbuild/linux-riscv64": "0.27.1", + "@esbuild/linux-s390x": "0.27.1", + "@esbuild/linux-x64": "0.27.1", + "@esbuild/netbsd-arm64": "0.27.1", + "@esbuild/netbsd-x64": "0.27.1", + "@esbuild/openbsd-arm64": "0.27.1", + "@esbuild/openbsd-x64": "0.27.1", + "@esbuild/openharmony-arm64": "0.27.1", + "@esbuild/sunos-x64": "0.27.1", + "@esbuild/win32-arm64": "0.27.1", + "@esbuild/win32-ia32": "0.27.1", + "@esbuild/win32-x64": "0.27.1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "optional": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/front-matter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", + "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", + "license": "MIT", + "dependencies": { + "js-yaml": "^3.13.1" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", + "license": "MIT", + "dependencies": { + "whatwg-encoding": "^3.1.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "license": "MIT" + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.3.0.tgz", + "integrity": "sha512-GtldT42B8+jefDUC4yUKAvsaOrH7PDHmZxZXNgF2xMmymjUbRYJvpAybZAKEmXDGTM0mCsz8duOa4vTm5AY2Kg==", + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/marked": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/marked/-/marked-17.0.1.tgz", + "integrity": "sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==", + "license": "MIT", + "peer": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/marked-alert": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/marked-alert/-/marked-alert-2.1.2.tgz", + "integrity": "sha512-EFNRZ08d8L/iEIPLTlQMDjvwIsj03gxWCczYTht6DCiHJIZhMk4NK5gtPY9UqAYb09eV5VGT+jD4lp396E0I+w==", + "license": "MIT", + "peerDependencies": { + "marked": ">=7.0.0" + } + }, + "node_modules/marked-gfm-heading-id": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/marked-gfm-heading-id/-/marked-gfm-heading-id-4.1.3.tgz", + "integrity": "sha512-aR0i63LmFbuxU/gAgrgz1Ir+8HK6zAIFXMlckeKHpV+qKbYaOP95L4Ux5Gi+sKmCZU5qnN2rdKpvpb7PnUBIWg==", + "license": "MIT", + "dependencies": { + "github-slugger": "^2.0.0" + }, + "peerDependencies": { + "marked": ">=13 <18" + } + }, + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "license": "CC0-1.0" + }, + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "optional": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT", + "optional": true + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" + }, + "node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz", + "integrity": "sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.4.0.tgz", + "integrity": "sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==", + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.2", + "regjsgen": "^0.8.0", + "regjsparser": "^0.13.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.2.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.13.0.tgz", + "integrity": "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.1.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/rollup": { + "version": "4.53.5", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.5.tgz", + "integrity": "sha512-iTNAbFSlRpcHeeWu73ywU/8KuU/LZmNCSxp6fjQkJBD3ivUb8tpDrXhIxEzA05HlYMEwmtaUnb3RP+YNv162OQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.5", + "@rollup/rollup-android-arm64": "4.53.5", + "@rollup/rollup-darwin-arm64": "4.53.5", + "@rollup/rollup-darwin-x64": "4.53.5", + "@rollup/rollup-freebsd-arm64": "4.53.5", + "@rollup/rollup-freebsd-x64": "4.53.5", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.5", + "@rollup/rollup-linux-arm-musleabihf": "4.53.5", + "@rollup/rollup-linux-arm64-gnu": "4.53.5", + "@rollup/rollup-linux-arm64-musl": "4.53.5", + "@rollup/rollup-linux-loong64-gnu": "4.53.5", + "@rollup/rollup-linux-ppc64-gnu": "4.53.5", + "@rollup/rollup-linux-riscv64-gnu": "4.53.5", + "@rollup/rollup-linux-riscv64-musl": "4.53.5", + "@rollup/rollup-linux-s390x-gnu": "4.53.5", + "@rollup/rollup-linux-x64-gnu": "4.53.5", + "@rollup/rollup-linux-x64-musl": "4.53.5", + "@rollup/rollup-openharmony-arm64": "4.53.5", + "@rollup/rollup-win32-arm64-msvc": "4.53.5", + "@rollup/rollup-win32-ia32-msvc": "4.53.5", + "@rollup/rollup-win32-x64-gnu": "4.53.5", + "@rollup/rollup-win32-x64-msvc": "4.53.5", + "fsevents": "~2.3.2" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.97.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.0.tgz", + "integrity": "sha512-KR0igP1z4avUJetEuIeOdDlwaUDvkH8wSx7FdSjyYBS3dpyX3TzHfAMO0G1Q4/3cdjcmi3r7idh+KCmKqS+KeQ==", + "license": "MIT", + "peer": true, + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "license": "MIT" + }, + "node_modules/systemjs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/systemjs/-/systemjs-6.15.1.tgz", + "integrity": "sha512-Nk8c4lXvMB98MtbmjX7JwJRgJOL8fluecYCfCeYBznwmpOs8Bf15hLM6z4z71EDAhQVrQrI+wt1aLWSXZq+hXA==", + "license": "MIT" + }, + "node_modules/terser": { + "version": "5.44.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", + "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", + "license": "BSD-2-Clause", + "peer": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tldts": { + "version": "7.0.19", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.19.tgz", + "integrity": "sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==", + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.19" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.19", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.19.tgz", + "integrity": "sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==", + "license": "MIT" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz", + "integrity": "sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz", + "integrity": "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz", + "integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", + "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.0.tgz", + "integrity": "sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "license": "MIT" + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" + } + } +} diff --git a/website/package.json b/website/package.json new file mode 100644 index 000000000000..f47d895911e7 --- /dev/null +++ b/website/package.json @@ -0,0 +1,21 @@ +{ + "name": "website", + "type": "module", + "scripts": { + "build": "vite build", + "dev": "vite" + }, + "dependencies": { + "@babel/standalone": "^7.28.5", + "@popperjs/core": "^2.11.8", + "@vitejs/plugin-legacy": "^7.2.1", + "front-matter": "^4.0.2", + "highlight.js": "^11.11.1", + "jsdom": "^27.3.0", + "marked": "^17.0.1", + "marked-alert": "^2.1.2", + "marked-gfm-heading-id": "^4.1.3", + "sass": "^1.97.0", + "vite": "^7.3.0" + } +} diff --git a/website/scripts/helpers.mjs b/website/scripts/helpers.mjs new file mode 100644 index 000000000000..dc1df035e9d6 --- /dev/null +++ b/website/scripts/helpers.mjs @@ -0,0 +1,176 @@ +/* eslint-disable no-console -- needed for logging */ +import childProcess from 'node:child_process'; +import { constants } from 'node:fs'; +import { cp, access, readdir, readFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { promisify } from 'node:util'; + +const exec = promisify(childProcess.exec); + +const BABEL_PATH = 'website/node_modules/@babel/standalone/babel.min.js'; + +export async function isExists(target) { + try { + await access(target, constants.F_OK); + return true; + } catch { + return false; + } +} + +export async function hasDocs(version, execDir) { + const target = version.branch ? `origin/${ version.branch }` : version.tag; + console.log(`Checking if docs exist in "${ target }"...`); + try { + await exec(`git ls-tree -r --name-only ${ target } | grep "docs/web/docs/"`, { cwd: execDir }); + } catch { + throw new Error(`Docs not found in "${ target }".`); + } +} + +export async function installDependencies(execDir) { + console.log('Installing dependencies...'); + console.time('Installed dependencies'); + const nodeModulesPath = join(execDir, 'node_modules'); + if (!await isExists(nodeModulesPath)) { + await exec('npm ci', { cwd: execDir }); + } + console.timeEnd('Installed dependencies'); +} + +export async function copyBabelStandalone(srcDir) { + console.log('Copying Babel standalone...'); + await installDependencies(`${ srcDir }website`); + console.time('Copied Babel standalone'); + const babelPath = join(srcDir, BABEL_PATH); + const destPath = join(srcDir, 'website/src/public/babel.min.js'); + await cp(babelPath, destPath); + console.timeEnd('Copied Babel standalone'); +} + +export async function copyBlogPosts(srcDir) { + console.log('Copying blog posts...'); + console.time('Copied blog posts'); + const fromDir = join(srcDir, 'docs/'); + const toDir = join(srcDir, 'docs/web/blog/'); + const entries = await readdir(fromDir, { withFileTypes: true }); + for (const entry of entries) { + if (entry.isFile()) { + const srcFile = join(fromDir, entry.name); + const destFile = join(toDir, entry.name); + await cp(srcFile, destFile); + } + } + console.timeEnd('Copied blog posts'); +} + +export async function copyCommonFiles(srcDir) { + console.log('Copying common files...'); + console.time('Copied common files'); + const toDir = join(srcDir, 'docs/web/'); + await cp(`${ srcDir }CHANGELOG.md`, `${ toDir }changelog.md`); + await cp(`${ srcDir }CONTRIBUTING.md`, `${ toDir }contributing.md`); + await cp(`${ srcDir }SECURITY.md`, `${ toDir }security.md`); + console.timeEnd('Copied common files'); +} + +export async function buildAndCopyCoreJS(version, srcDir, cacheDir = null, checkout = false) { + async function bundlePackage(esModules) { + await exec(`npm run bundle-package${ esModules ? ' esmodules' : '' }`, { cwd: srcDir }); + const bundleName = `core-js-bundle${ esModules ? '-esmodules' : '' }.js`; + const srcPath = join(srcDir, 'packages/core-js-bundle/minified.js'); + const destPath = join(srcDir, 'website/src/public/bundles/', target, bundleName); + await cp(srcPath, destPath); + if (cacheDir !== null) { + const cachePath = join(cacheDir, target, bundleName); + await cp(srcPath, cachePath); + } + } + + const target = version.branch ?? version.tag; + console.log(`Building and copying core-js for ${ target }`); + const targetBundlePath = join(cacheDir ?? '', target); + + if (cacheDir !== null && await isExists(targetBundlePath)) { + console.time('Core JS bundles copied'); + const bundlePath = join(targetBundlePath, 'core-js-bundle.js'); + const destBundlePath = join(srcDir, 'website/src/public/bundles/', target, 'core-js-bundle.js'); + await cp(bundlePath, destBundlePath); + + const esmodulesBundlePath = join(targetBundlePath, 'core-js-bundle-esmodules.js'); + const esmodulesDestBundlePath = join(srcDir, 'website/src/public/bundles/', target, 'core-js-bundle-esmodules.js'); + await cp(esmodulesBundlePath, esmodulesDestBundlePath); + console.timeEnd('Core JS bundles copied'); + return; + } + + console.time('Core JS bundles built'); + if (checkout) { + await checkoutVersion(version, srcDir); + } + await installDependencies(srcDir); + + await bundlePackage(false); + await bundlePackage(true); + + console.timeEnd('Core JS bundles built'); +} + +export async function checkoutVersion(version, execDir) { + if (version.branch) { + await exec(`git checkout origin/${ version.branch }`, { cwd: execDir }); + } else { + await exec(`git checkout ${ version.tag }`, { cwd: execDir }); + } +} + +export async function buildWeb(branch, execDir, local = false) { + console.log('Building web...'); + console.time('Built web'); + let command = 'npm run build-website'; + if (branch) command += ` branch=${ branch }`; + if (local) command += ' local'; + const stdout = await exec(command, { cwd: execDir }); + console.timeEnd('Built web'); + return stdout; +} + +export async function getCurrentBranch(execDir) { + console.log('Getting current branch...'); + console.time('Got current branch'); + const { stdout } = await exec('git rev-parse --abbrev-ref HEAD', { cwd: execDir }); + console.timeEnd('Got current branch'); + return stdout.trim(); +} + +export async function getDefaultVersion(versionFile, defaultVersion = null) { + if (defaultVersion) return defaultVersion; + + const versions = await readJSON(versionFile); + return versions.find(v => v.default)?.label; +} + +export async function readJSON(filePath) { + const buffer = await readFile(filePath); + return JSON.parse(buffer); +} + +export function expandVersionsConfig(config) { + let defaultIndex = null; + const $config = config.map(({ label, branch, path, default: $default }, index) => { + if ($default) { + if (defaultIndex !== null) throw new Error('Duplicate default'); + defaultIndex = index; + } + return { + branch, + default: false, + label, + path: path ?? label, + }; + }); + + if (defaultIndex === null) throw new Error('Missed default'); + + return [{ ...$config[defaultIndex], default: true }, ...$config]; +} diff --git a/website/scripts/runner.mjs b/website/scripts/runner.mjs new file mode 100644 index 000000000000..76603f9d81da --- /dev/null +++ b/website/scripts/runner.mjs @@ -0,0 +1,237 @@ +/* eslint-disable no-console -- needed for logging */ +import { + hasDocs, + copyBlogPosts, + copyBabelStandalone, + copyCommonFiles, + buildWeb, + getDefaultVersion, + readJSON, + buildAndCopyCoreJS, + expandVersionsConfig, +} from './helpers.mjs'; +import childProcess from 'node:child_process'; +import { cp, readdir, readlink } from 'node:fs/promises'; +import { promisify } from 'node:util'; +import { resolve, join } from 'node:path'; + +const exec = promisify(childProcess.exec); + +const SRC_DIR = 'core-js'; +const BUILDS_ROOT_DIR = 'builds'; +const BUILD_RESULT_DIR = 'result'; +const BUNDLES_DIR = 'bundles'; +const REPO = 'https://github.com/zloirock/core-js.git'; +const BUILDER_BRANCH = 'master'; + +const args = process.argv; +const lastArg = args.at(-1); +const BRANCH = lastArg.startsWith('branch=') ? lastArg.slice('branch='.length) : undefined; + +const BUILD_ID = new Date().toISOString().replaceAll(/\D/g, '-') + Math.random().toString(36).slice(2, 8); + +const BUILD_DIR = `${ BUILDS_ROOT_DIR }/${ BUILD_ID }/`; +const BUILD_SRC_DIR = `${ BUILD_DIR }${ SRC_DIR }/`; +const BUILD_DOCS_DIR = `${ BUILD_DIR }builder/`; +const SITE_FILES_DIR = `${ BUILD_SRC_DIR }/website/dist/`; +const VERSIONS_FILE = `${ BUILD_SRC_DIR }website/config/versions.json`; + +async function copyWeb() { + console.log('Copying web...'); + console.time('Copied web'); + const toDir = `${ BUILD_DIR }${ BUILD_RESULT_DIR }/`; + await cp(SITE_FILES_DIR, toDir, { recursive: true }); + console.timeEnd('Copied web'); +} + +async function createBuildDir() { + console.log(`Creating build directory "${ BUILD_DIR }"`); + console.time(`Created build directory ${ BUILD_DIR }`); + await exec(`mkdir -p ${ BUILD_DIR }`); + await exec(`mkdir -p ${ BUILD_DOCS_DIR }`); + console.timeEnd(`Created build directory ${ BUILD_DIR }`); +} + +async function installDependencies(dir = BUILD_SRC_DIR) { + console.log('Installing dependencies...'); + console.time('Installed dependencies'); + await exec('npm ci', { cwd: dir }); + console.timeEnd('Installed dependencies'); +} + +async function cloneRepo() { + console.log('Cloning core-js repository...'); + console.time('Cloned core-js repository'); + await exec(`git clone ${ REPO } ${ SRC_DIR }`, { cwd: BUILD_DIR }); + console.timeEnd('Cloned core-js repository'); +} + +async function switchToLatestBuild() { + console.log('Switching to the latest build...'); + console.time('Switched to the latest build'); + const absoluteBuildPath = resolve(`${ BUILD_DIR }${ BUILD_RESULT_DIR }`); + const absoluteLatestPath = resolve('./latest'); + console.log(absoluteBuildPath, absoluteLatestPath); + await exec('rm -f ./latest'); + await exec(`ln -sf ${ absoluteBuildPath } ${ absoluteLatestPath }`); + console.timeEnd('Switched to the latest build'); +} + +async function clearBuildDir() { + console.log(`Clearing build directory "${ BUILD_SRC_DIR }"`); + console.time(`Cleared build directories ${ BUILD_SRC_DIR } and ${ BUILD_DOCS_DIR }`); + await exec(`rm -rf ${ BUILD_SRC_DIR }`); + await exec(`rm -rf ${ BUILD_DOCS_DIR }`); + console.timeEnd(`Cleared build directories ${ BUILD_SRC_DIR } and ${ BUILD_DOCS_DIR }`); +} + +async function copyDocs(from, to, recursive = true) { + console.log(`Copying docs from "${ from }" to "${ to }"`); + console.time(`Copied docs from "${ from }" to "${ to }"`); + await cp(from, to, { recursive }); + console.timeEnd(`Copied docs from "${ from }" to "${ to }"`); +} + +async function copyDocsToBuilder(version) { + const target = version.branch ?? version.tag; + console.log(`Copying docs to builder for "${ target }"`); + console.time(`Copied docs to builder for "${ target }"`); + await checkoutVersion(version); + const fromDir = `${ BUILD_SRC_DIR }docs/web/docs/`; + const toDir = `${ BUILD_DOCS_DIR }${ version.path ?? version.label }/docs/`; + await copyDocs(fromDir, toDir); + console.timeEnd(`Copied docs to builder for "${ target }"`); +} + +async function copyBuilderDocs() { + console.log('Copying builder docs...'); + console.time('Copied builder docs'); + const fromDir = `${ BUILD_DOCS_DIR }`; + const toDir = `${ BUILD_SRC_DIR }docs/web/`; + await copyDocs(fromDir, toDir); + console.timeEnd('Copied builder docs'); +} + +async function prepareBuilder(targetBranch) { + console.log('Preparing builder...'); + console.time('Prepared builder'); + await exec(`git checkout origin/${ targetBranch }`, { cwd: BUILD_SRC_DIR }); + await installDependencies(); + if (!BRANCH) await exec(`rm -rf ${ BUILD_SRC_DIR }docs/web/docs/`); + console.timeEnd('Prepared builder'); +} + +async function switchBranchToLatestBuild(name) { + console.log(`Switching branch "${ name }" to the latest build...`); + console.time(`Switched branch "${ name }" to the latest build`); + const absoluteBuildPath = resolve(`${ BUILD_DIR }${ BUILD_RESULT_DIR }`); + const absoluteLatestPath = resolve(`./branches/${ name }`); + await exec(`rm -f ./branches/${ name }`); + await exec(`ln -sf ${ absoluteBuildPath } ${ absoluteLatestPath }`); + console.timeEnd(`Switched branch "${ name }" to the latest build`); +} + +async function checkoutVersion(version) { + if (version.branch) { + await exec(`git checkout origin/${ version.branch }`, { cwd: BUILD_SRC_DIR }); + } else { + await exec(`git checkout ${ version.tag }`, { cwd: BUILD_SRC_DIR }); + } +} + +async function getExcludedBuilds() { + const branchBuilds = await readdir('./branches/'); + const excluded = new Set(); + for (const name of branchBuilds) { + const link = await readlink(`./branches/${ name }`); + if (!link) continue; + const parts = link.split('/'); + const id = parts.at(-2); + excluded.add(id); + } + const latestBuildLink = await readlink('./latest'); + if (latestBuildLink) { + const parts = latestBuildLink.split('/'); + const id = parts.at(-2); + excluded.add(id); + } + + return Array.from(excluded); +} + +async function clearOldBuilds() { + console.log('Clearing old builds...'); + console.time('Cleared old builds'); + const excluded = await getExcludedBuilds(); + const builds = await readdir(BUILDS_ROOT_DIR); + for (const build of builds) { + if (!excluded.includes(build)) { + await exec(`rm -rf ${ join('./', BUILDS_ROOT_DIR, '/', build) }`); + console.log(`Build removed: "${ join('./', BUILDS_ROOT_DIR, '/', build) }"`); + } + } + console.timeEnd('Cleared old builds'); +} + +async function createLastDocsLink() { + console.log('Creating last docs link...'); + console.time('Created last docs link'); + const defaultVersion = await getDefaultVersion(VERSIONS_FILE); + const absoluteBuildPath = resolve(`${ BUILD_DIR }${ BUILD_RESULT_DIR }/${ defaultVersion }/docs/`); + const absoluteLastDocsPath = resolve(`${ BUILD_DIR }${ BUILD_RESULT_DIR }/docs/`); + await exec(`ln -s ${ absoluteBuildPath } ${ absoluteLastDocsPath }`); + console.timeEnd('Created last docs link'); +} + +async function getVersions(targetBranch) { + console.log('Getting versions...'); + console.time('Got versions'); + await exec(`git checkout origin/${ targetBranch }`, { cwd: BUILD_SRC_DIR }); + const versions = await readJSON(VERSIONS_FILE); + console.timeEnd('Got versions'); + + return expandVersionsConfig(versions); +} + +try { + console.time('Finished in'); + await createBuildDir(); + await cloneRepo(); + + const targetBranch = BRANCH || BUILDER_BRANCH; + if (!BRANCH) { + const versions = await getVersions(targetBranch); + for (const version of versions) { + if (version.default) continue; + await copyDocsToBuilder(version); + await buildAndCopyCoreJS(version, BUILD_SRC_DIR, BUNDLES_DIR, true); + } + } else { + const version = { branch: targetBranch, label: targetBranch }; + await hasDocs(version, BUILD_SRC_DIR); + await buildAndCopyCoreJS(version, BUILD_SRC_DIR, BUNDLES_DIR, true); + } + + await prepareBuilder(targetBranch); + await copyBabelStandalone(BUILD_SRC_DIR); + await copyBlogPosts(BUILD_SRC_DIR); + await copyCommonFiles(BUILD_SRC_DIR); + if (!BRANCH) { + await copyBuilderDocs(); + } + await buildWeb(BRANCH, BUILD_SRC_DIR); + + await copyWeb(); + await createLastDocsLink(); + + if (!BRANCH) { + await switchToLatestBuild(); + } else { + await switchBranchToLatestBuild(targetBranch); + } + await clearBuildDir(); + await clearOldBuilds(); + console.timeEnd('Finished in'); +} catch (error) { + console.error(error); +} diff --git a/website/scripts/runner.sh b/website/scripts/runner.sh new file mode 100644 index 000000000000..3672b122a658 --- /dev/null +++ b/website/scripts/runner.sh @@ -0,0 +1,64 @@ +#!/bin/bash +LOCK_FILE=./runner.lock +PID_FILE=./runner.pid + +export NVM_DIR="$HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" + +kill_old_build() { + if [ -f "$PID_FILE" ]; then + OLD_PID=$(cat "$PID_FILE") + if ps -p "$OLD_PID" > /dev/null 2>&1; then + kill -TERM -"$OLD_PID" + echo "Previous build $OLD_PID in progress. Terminating..." + sleep 2 + if ps -p "$OLD_PID" > /dev/null 2>&1; then + kill -KILL -"$OLD_PID" + echo "PID $OLD_PID still alive, sending SIGKILL!" + fi + fi + rm -f "$LOCK_FILE" "$PID_FILE" + fi +} + +kill_old_build + +if ! ln -s "$$" "$LOCK_FILE" 2>/dev/null; then + echo "Another build still running, exit" + exit 1 +fi + +CLEANED=0 +cleanup() { + if [ "$CLEANED" -eq 0 ]; then + CLEANED=1 + echo "Cleaning up from $$" + rm -f "$LOCK_FILE" "$PID_FILE" + if [ -n "$NODE_PID" ] && ps -p "$NODE_PID" > /dev/null 2>&1; then + kill -TERM -"$NODE_PID" 2>/dev/null || true + kill -KILL -"$NODE_PID" 2>/dev/null || true + fi + fi +} + +trap cleanup EXIT HUP INT TERM + +echo "Lock acquired by $$, starting build..." + +BRANCH_ARG="" +if [ -n "$1" ]; then + BRANCH_ARG="branch=$1" +fi + +if [ -z "$BRANCH_ARG" ]; then + setsid node ./runner.mjs & +else + setsid node ./runner.mjs "$BRANCH_ARG" & +fi +NODE_PID=$! +echo "$NODE_PID" > "$PID_FILE" + +wait $NODE_PID +EXIT_CODE=$? + +exit $EXIT_CODE diff --git a/website/src/apple-touch-icon.png b/website/src/apple-touch-icon.png new file mode 100644 index 000000000000..b220b10c6837 Binary files /dev/null and b/website/src/apple-touch-icon.png differ diff --git a/website/src/favicon-16x16.png b/website/src/favicon-16x16.png new file mode 100644 index 000000000000..fb22b974da1d Binary files /dev/null and b/website/src/favicon-16x16.png differ diff --git a/website/src/favicon-32x32.png b/website/src/favicon-32x32.png new file mode 100644 index 000000000000..9d3c2cb69c9c Binary files /dev/null and b/website/src/favicon-32x32.png differ diff --git a/website/src/images/core-js.png b/website/src/images/core-js.png new file mode 100644 index 000000000000..74ad6a0d36ad Binary files /dev/null and b/website/src/images/core-js.png differ diff --git a/website/src/images/license.txt b/website/src/images/license.txt new file mode 100644 index 000000000000..215c74929897 --- /dev/null +++ b/website/src/images/license.txt @@ -0,0 +1,5 @@ +Copyright (c) 2014-2025 CoreJS Company. +All rights reserved. + +The files in this directory (logos, brand assets, and their variations) +are proprietary material of CoreJS Company. diff --git a/website/src/index.html b/website/src/index.html new file mode 100644 index 000000000000..484a48462713 --- /dev/null +++ b/website/src/index.html @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<html lang="en" class="theme-dark"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>{title}core-js + + + + + + {core-js-bundle-esmodules} + {core-js-bundle} + + + + + +
    + +
    + +
    +
    + {content} +
    +
    + + + + + diff --git a/website/src/js/content-menu.js b/website/src/js/content-menu.js new file mode 100644 index 000000000000..9ca6051ace11 --- /dev/null +++ b/website/src/js/content-menu.js @@ -0,0 +1,62 @@ +import scrollToElement from './scroll-to.js'; + +document.addEventListener('DOMContentLoaded', () => { + const triggers = document.querySelectorAll('.scroll-to'); + const menuItems = document.querySelectorAll('.toc-link'); + const offset = 10; + + function unactiveAllMenuItems() { + menuItems.forEach(item => { + item.classList.remove('active'); + }); + } + + function activateMenu(targetHash) { + document.querySelector(`a[data-hash="${ targetHash }"]`).parentElement.classList.add('active'); + } + + function getBlocksBoundaries() { + const targetBoundaries = {}; + triggers.forEach(trigger => { + const targetHash = trigger.dataset.hash; + const element = document.querySelector(targetHash); + if (element) { + targetBoundaries[targetHash] = { top: element.getBoundingClientRect().top + window.scrollY }; + } + }); + return targetBoundaries; + } + + function observeMenu() { + const scroll = window.scrollY; + const targetBoundaries = getBlocksBoundaries(); + for (const [hash, target] of Object.entries(targetBoundaries)) { + if (target.top > scroll && target.top < scroll + window.innerHeight / 2) { + unactiveAllMenuItems(); + activateMenu(hash); + return; + } + } + } + + function isIE() { + return window.MSInputMethodContext && document.documentMode; + } + + triggers.forEach(trigger => { + trigger.addEventListener('click', function (e) { + if (!isIE()) { + e.preventDefault(); + const { hash } = this.dataset; + const href = this.getAttribute('href'); + const target = document.querySelector(hash); + if (target) { + scrollToElement(target, offset); + history.pushState(null, null, href); + } + } + }, false); + }); + + document.addEventListener('scroll', observeMenu); +}); diff --git a/website/src/js/hljs-run.js b/website/src/js/hljs-run.js new file mode 100644 index 000000000000..a9e2fe4c982c --- /dev/null +++ b/website/src/js/hljs-run.js @@ -0,0 +1,34 @@ +export default class RunButtonPlugin { + ORIGIN = location.origin; + PATH = location.pathname; + BASE_URL = document.querySelector('base')?.getAttribute('href'); + RELATIVE_PATH = this.PATH.replace(this.BASE_URL, ''); + PLAYGROUND_URL = 'playground'; + + text = '' + + '' + + ''; + + 'after:highlightElement'({ el, result, text }) { + if (result.language !== 'js') return; + if (el.parentElement.querySelector('.hljs-run-button')) return; + const runButton = document.createElement('a'); + runButton.href = '#'; + runButton.innerHTML = this.text; + runButton.classList.add('hljs-run-button'); + runButton.addEventListener('click', event => { + event.preventDefault(); + const urlParams = new URLSearchParams(); + urlParams.set('code', text); + const hash = urlParams.toString(); + const hasVersion = this.RELATIVE_PATH !== '' && !this.RELATIVE_PATH.startsWith('docs/') && !this.RELATIVE_PATH.startsWith('index'); + const version = hasVersion ? `${ this.RELATIVE_PATH.split('/')[0] }/` : ''; + location.href = `${ this.ORIGIN }${ this.BASE_URL }${ version }${ this.PLAYGROUND_URL }#${ hash }`; + }); + const wrapper = document.createElement('div'); + wrapper.classList.add('hljs-run'); + wrapper.appendChild(runButton); + el.appendChild(wrapper); + } +} diff --git a/website/src/js/main.js b/website/src/js/main.js new file mode 100644 index 000000000000..f9fedd9c56d4 --- /dev/null +++ b/website/src/js/main.js @@ -0,0 +1,202 @@ +import '../scss/app.scss'; +import hljs from 'highlight.js/lib/core'; +import javascript from 'highlight.js/lib/languages/javascript'; +import typescript from 'highlight.js/lib/languages/typescript'; +import json from 'highlight.js/lib/languages/json'; +import bash from 'highlight.js/lib/languages/bash'; +import plaintext from 'highlight.js/lib/languages/plaintext'; +import RunButtonPlugin from './hljs-run.js'; + +hljs.registerLanguage('js', javascript); +hljs.registerLanguage('ts', typescript); +hljs.registerLanguage('json', json); +hljs.registerLanguage('sh', bash); +hljs.registerLanguage('plaintext', plaintext); + +let initialized = false; +function init() { + if (initialized) return; + initialized = true; + const menuSwitcher = document.getElementById('menu-switcher'); + const menuBackdrop = document.querySelector('#menu > .backdrop'); + const menu = document.querySelector('#menu'); + const collapsibleTrigger = document.querySelectorAll('.collapsible > a'); + const dropdownTriggers = document.querySelectorAll('.dropdown .dropdown-wrapper > a'); + const versionsMenu = document.querySelectorAll('.versions-menu'); + const currentVersions = document.querySelectorAll('.versions-menu a.current'); + const dropdownBackdrops = document.querySelectorAll('.dropdown .backdrop'); + const themeSwitcher = document.querySelector('.theme-switcher'); + const docsVersionLinks = document.querySelectorAll('.with-docs-version'); + const docsMenuItems = document.querySelectorAll('.docs-menu li > a'); + const docsCollapsibleMenuItems = document.querySelectorAll('.docs-menu .docs-links ul > li.collapsible'); + const contentMenu = document.querySelector('.table-of-contents'); + const contentMenuTrigger = document.querySelector('.table-of-contents .mobile-trigger'); + const sectionMenu = document.querySelector('.docs-menu'); + const sectionMenuTrigger = document.querySelector('.docs-menu .mobile-trigger'); + const mainMenuItems = document.querySelectorAll('.menu-item.highlightable > a'); + let isDocs, docsVersion; + const currentPath = getRelativePath(); + + function toggleMenu() { + menu.classList.toggle('active'); + } + + menuBackdrop.addEventListener('click', () => { + toggleMenu(); + }, false); + + menuSwitcher.addEventListener('click', e => { + e.preventDefault(); + toggleMenu(); + }, false); + + collapsibleTrigger.forEach(el => { + el.addEventListener('click', function (e) { + e.preventDefault(); + this.parentElement.classList.toggle('active'); + }); + }); + + dropdownTriggers.forEach(el => { + el.addEventListener('click', function (e) { + e.preventDefault(); + this.parentElement.parentElement.classList.toggle('active'); + }); + }); + + currentVersions.length && currentVersions.forEach(version => { + version.addEventListener('click', e => { + e.preventDefault(); + }); + }); + + dropdownBackdrops.forEach(el => { + el.addEventListener('click', function () { + this.parentElement.classList.remove('active'); + }); + }); + + function getRelativePath() { + const path = location.pathname; + const base = document.querySelector('base')?.getAttribute('href') || ''; + + return path.replace(base, ''); + } + + function isDocsPage() { + if (isDocs !== undefined) return isDocs; + isDocs = currentPath.startsWith('docs/') || currentPath.includes('/docs/'); + return isDocs; + } + + function hasCurrentVersion() { + if (docsVersion !== undefined) return docsVersion; + docsVersion = !currentPath.startsWith('docs/') && !currentPath.startsWith('playground'); + return docsVersion; + } + + function setDefaultVersion() { + versionsMenu.forEach(menuItem => { + const currentVersion = menuItem.querySelector('a.current'); + currentVersion.innerHTML = `${ currentVersion.innerHTML } (default)`; + const versionsMenuLinks = menuItem.querySelectorAll('.dropdown-block a'); + versionsMenuLinks.forEach(link => link.classList.remove('active')); + versionsMenuLinks[0].classList.add('active'); + }); + } + + function processVersions() { + const hasVersion = hasCurrentVersion(); + if (!hasVersion) setDefaultVersion(); + if (!isDocsPage()) return; + if (hasVersion) return; + + docsVersionLinks.forEach(link => { + const defaultVersion = link.getAttribute('data-default-version'); + const re = new RegExp(`${ defaultVersion }/`); + const newLink = link.getAttribute('href').replace(re, ''); + link.setAttribute('href', newLink); + }); + } + + function setActiveDocsMenuItem(item) { + item.classList.add('active'); + let parent = item.parentElement; + while (parent && !parent.classList.contains('docs-menu')) { + if (parent.tagName === 'LI' && parent.classList.contains('collapsible')) { + parent.classList.add('active'); + } + parent = parent.parentElement; + } + } + + function highlightActiveDocsMenuItem() { + if (!isDocsPage()) return; + + let found = false; + for (const link of docsMenuItems) { + const href = link.getAttribute('href'); + if (href && href === currentPath) { + setActiveDocsMenuItem(link); + found = true; + break; + } + } + + !found && setActiveDocsMenuItem(docsMenuItems[0]); + } + + function openFirstCollapsibleMenuItem() { + if (!isDocsPage()) return; + docsCollapsibleMenuItems[0].classList.add('active'); + } + + function highlightMainMenu() { + const path = getRelativePath(); + for (const item of mainMenuItems) { + const href = item.getAttribute('href').replace('./', ''); + if (path.includes(href)) { + item.classList.add('active'); + return; + } + } + } + + themeSwitcher.addEventListener('click', e => { + e.preventDefault(); + const html = document.querySelector('html'); + const isDark = html.classList.contains('theme-dark'); + // eslint-disable-next-line no-undef, sonarjs/no-reference-error -- global function + isDark ? setTheme('theme-light') : setTheme('theme-dark'); + }); + + contentMenuTrigger && contentMenuTrigger.addEventListener('click', e => { + e.preventDefault(); + contentMenu.classList.toggle('active'); + if (contentMenu.classList.contains('active') && sectionMenu && sectionMenu.classList.contains('active')) { + sectionMenu.classList.remove('active'); + } + }); + + sectionMenuTrigger && sectionMenuTrigger.addEventListener('click', e => { + e.preventDefault(); + sectionMenu.classList.toggle('active'); + if (sectionMenu.classList.contains('active') && contentMenu && contentMenu.classList.contains('active')) { + contentMenu.classList.remove('active'); + } + }); + + hljs.addPlugin(new RunButtonPlugin()); + hljs.highlightAll(); + + processVersions(); + highlightActiveDocsMenuItem(); + openFirstCollapsibleMenuItem(); + highlightMainMenu(); +} + +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); +} else { + init(); +} diff --git a/website/src/js/playground.js b/website/src/js/playground.js new file mode 100644 index 000000000000..2997ba3e74af --- /dev/null +++ b/website/src/js/playground.js @@ -0,0 +1,311 @@ +/* global Babel -- global scope directive */ +import hljs from 'highlight.js/lib/core'; +import javascript from 'highlight.js/lib/languages/javascript'; +import { createPopper } from '@popperjs/core'; + +hljs.registerLanguage('javascript', javascript); + +const hash = location.hash.slice(1); +const pageParams = new URLSearchParams(hash); +const defaultCode = `import 'core-js/actual'; + +await Promise.try(() => 42); // => 42 + +Array.from(new Set([1, 2, 3]).union(new Set([3, 4, 5]))); // => [1, 2, 3, 4, 5] + +[1, 2].flatMap(it => [it, it]); // => [1, 1, 2, 2] + +Iterator.concat([1, 2], function * (i) { while (true) yield i++; }(3)) + .drop(1).take(5) + .filter(it => it % 2) + .map(it => it ** 2) + .toArray(); // => [9, 25] + +structuredClone(new Set([1, 2, 3])); // => new Set([1, 2, 3])`; + +const specSymbols = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + '\'': ''', +}; + +let initialized = false; +function init() { + if (initialized) return; + initialized = true; + + const codeInput = document.querySelector('#code-input'); + const codeOutput = document.querySelector('#code-output'); + const runButtons = document.querySelectorAll('.run-button'); + const linkButtons = document.querySelectorAll('.link-button'); + const resultBlock = document.querySelector('.result'); + const backLinkBlock = document.querySelector('.back-link'); + const backLink = document.querySelector('.back-link a'); + const tooltip = document.querySelector('#tooltip'); + const tooltipText = document.querySelector('#tooltip-text'); + + if (!codeInput) return; + + function writeResult(text, type = 'log') { + const serializedText = serializeLog(text).replaceAll(/["&'<>]/g, it => specSymbols[it]); + resultBlock.innerHTML += `
    ${ serializedText }
    `; + } + + Babel.registerPlugin('playground-plugin', babel => { + const { types: t } = babel; + return { + visitor: { + ExpressionStatement(path) { + const { expression, trailingComments } = path.node; + if (trailingComments?.[0]?.value.startsWith(' =>')) { + if ( + t.isCallExpression(expression) && + t.isMemberExpression(expression.callee) && + expression.callee.object.name === 'console' + ) return; + path.replaceWith( + t.callExpression( + t.memberExpression(t.identifier('console'), t.identifier('log')), + [t.clone(expression)], + ), + ); + } + }, + ImportDeclaration(path) { + const { node } = path; + if (!node.specifiers.length && /^core-js\/|$/.test(node.source.value)) { + path.remove(); + } + }, + }, + }; + }); + + function runCode(code) { + const origConsole = globalThis.console; + const console = { + log: (...args) => { + args.forEach(arg => { writeResult(arg, 'log'); }); + origConsole.log(...args); + }, + warn: (...args) => { + args.forEach(arg => { writeResult(arg, 'warn'); }); + origConsole.warn(...args); + }, + error: (...args) => { + args.forEach(arg => { writeResult(arg, 'error'); }); + origConsole.error(...args); + }, + }; + + try { + code = Babel.transform(code, { plugins: ['playground-plugin'] }).code; + code = Babel.transform(`(async function () { ${ code } \n})().catch(console.error)`, { presets: ['env'] }).code; + // eslint-disable-next-line no-new-func -- it's needed to run code with monkey-patched console + const executeCode = new Function('console', code); + executeCode(console); + } catch (error) { + writeResult(`Error: ${ error.message }`, 'error'); + } + } + + function serializeLog(value, visited = new WeakSet()) { + if (typeof value == 'string') return JSON.stringify(value); + if (typeof value == 'function') return `[Function ${ value.name || 'anonymous' }]`; + if (typeof value != 'object' || value === null) return String(value); + + if (value instanceof Promise) { + return 'Promise { }'; + } + + if (typeof value === 'object') { + if (visited.has(value)) return '[Circular]'; + visited.add(value); + } + + if (value instanceof Set) { + const arr = Array.from(value, v => serializeLog(v, visited)); + return `Set { ${ arr.join(', ') } }`; + } + + if (value instanceof Map) { + const arr = Array.from( + value, + ([k, v]) => `${ serializeLog(k, visited) } => ${ serializeLog(v, visited) }`, + ); + return `Map { ${ arr.join(', ') } }`; + } + + if (value instanceof ArrayBuffer) { + return `ArrayBuffer(${ value.byteLength })`; + } + + if (value instanceof DataView) { + return `DataView(${ value.byteLength })`; + } + + if (value instanceof Blob) { + return `Blob { size: ${ value.size }, type: "${ value.type }" }`; + } + + if (ArrayBuffer.isView(value)) { + const type = value.constructor.name; + const objFormat = Array.from(value, (v, i) => `"${ i }": ${ serializeLog(v, visited) }`); + return `${ type } { ${ objFormat.join(', ') } }`; + } + + if (Array.isArray(value)) { + const arr = value.map(v => serializeLog(v, visited)); + return `[${ arr.join(', ') }]`; + } + + if (value instanceof Error) { + return `${ value.name || 'Error' }: ${ value.message }`; + } + + if (value instanceof Date) { + return `Date "${ value.toString() }"`; + } + + if (value instanceof RegExp) { + return `RegExp ${ value.toString() }`; + } + + if (typeof value === 'object') { + const isPlain = Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null; + const keys = Reflect.ownKeys(value); + const props = keys.map(k => { + // eslint-disable-next-line unicorn/no-instanceof-builtins -- it's needed here + const displayKey = Object(k) instanceof Symbol ? `[${ k.toString() }]` : k; + return `${ displayKey }: ${ serializeLog(value[k], visited) }`; + }); + if (visited.has(value)) visited.delete(value); + + return isPlain + ? `{ ${ props.join(', ') } }` + : `${ value.constructor?.name ?? 'Object' } { ${ props.join(', ') } }`; + } + + return String(value); + } + + function elementInViewport(el) { + const rect = el.getBoundingClientRect(); + + return ( + rect.top >= 0 && + rect.left >= 0 && + rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && + rect.right <= (window.innerWidth || document.documentElement.clientWidth) + ); + } + + function copyToClipboard(text) { + if (navigator.clipboard && window.isSecureContext) { + return navigator.clipboard.writeText(text); + } + + const textArea = document.createElement('textarea'); + textArea.value = text; + textArea.classList.add('copy-fallback'); + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + if (!document.execCommand('copy')) { + throw new Error('Copy command was unsuccessful'); + } + } finally { + document.body.removeChild(textArea); + } + } + + function showTooltip(element, message, time = 3000) { + tooltipText.innerHTML = message; + tooltip.setAttribute('data-show', ''); + createPopper(element, tooltip, { placement: 'bottom' }); + setTimeout(() => { + tooltip.removeAttribute('data-show'); + }, time); + } + + codeInput.addEventListener('input', () => { + codeOutput.removeAttribute('data-highlighted'); + let val = codeInput.value; + if (val.at(-1) === '\n') val += ' '; + codeOutput.textContent = val; + hljs.highlightElement(codeOutput); + }); + + codeInput.addEventListener('scroll', () => { + codeOutput.scrollTop = codeInput.scrollTop; + codeOutput.scrollLeft = codeInput.scrollLeft; + }); + + runButtons.forEach(runButton => { + runButton.addEventListener('click', e => { + e.preventDefault(); + resultBlock.innerHTML = ''; + runCode(codeInput.value); + if (!elementInViewport(resultBlock)) { + window.scrollTo({ + top: resultBlock.getBoundingClientRect().top, + behavior: 'smooth', + }); + } + }); + }); + + linkButtons.forEach(linkButton => { + linkButton.addEventListener('click', e => { + e.preventDefault(); + pageParams.set('code', codeInput.value); + location.hash = pageParams.toString(); + try { + copyToClipboard(location.toString()); + showTooltip(linkButton, 'Link copied'); + } catch { + showTooltip(linkButton, 'Can\'t copy link. Please copy the link manually'); + } + }); + }); + + setInterval(() => { + localStorage.setItem('code', codeInput.value); + }, 2000); + + codeOutput.textContent = codeInput.value; + hljs.highlightElement(codeOutput); + let event; + if (typeof Event === 'function') { + event = new Event('input', { bubbles: true }); + } else { + event = document.createEvent('Event'); + event.initEvent('input', true, true); + } + if (pageParams.has('code')) { + codeInput.value = pageParams.get('code'); + codeInput.dispatchEvent(event); + } else { + const code = localStorage.getItem('code'); + codeInput.value = code && code !== '' ? code : defaultCode; + codeInput.dispatchEvent(event); + } + + if (document.referrer !== '') { + backLinkBlock.classList.add('active'); + backLink.addEventListener('click', e => { + e.preventDefault(); + history.back(); + }); + } +} + +if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); +} else { + init(); +} diff --git a/website/src/js/scroll-to.js b/website/src/js/scroll-to.js new file mode 100644 index 000000000000..cd4ec5ebfbd6 --- /dev/null +++ b/website/src/js/scroll-to.js @@ -0,0 +1,9 @@ +export default function scrollToElement(element, offset = 0) { + if (typeof element !== 'object') { + element = document.querySelector(element); + } + if (element) { + const y = element.getBoundingClientRect().top + window.scrollY - offset; + window.scrollTo({ top: y, behavior: 'smooth' }); + } +} diff --git a/website/src/playground.html b/website/src/playground.html new file mode 100644 index 000000000000..75e4809ef16e --- /dev/null +++ b/website/src/playground.html @@ -0,0 +1,44 @@ +
    +
    + +
    {versions-menu}
    +
    +
    + + +
    +
    + + + + Use console.log() or // => for output +
    +
    + +
    +
    + +
    + +
    +
    +
    +{babel-script} diff --git a/website/src/scss/app.scss b/website/src/scss/app.scss new file mode 100644 index 000000000000..c62802301db7 --- /dev/null +++ b/website/src/scss/app.scss @@ -0,0 +1,17 @@ +@use "includes/variables-dark"; +@use "includes/themes"; +@use "includes/themify"; +@use "includes/themed"; +@use "includes/reset"; +@use "includes/forms"; +@use "includes/mixins"; + +@use "includes/base"; +@use "includes/markdown"; + +@use "parts/header"; +@use "parts/main"; +@use "parts/footer"; +@use "parts/code"; +@use "parts/playground"; +@use "parts/tooltip"; diff --git a/website/src/scss/includes/base.scss b/website/src/scss/includes/base.scss new file mode 100644 index 000000000000..fab7f5c9fd71 --- /dev/null +++ b/website/src/scss/includes/base.scss @@ -0,0 +1,218 @@ +@use "../includes/mixins" as *; +@use "../includes/themes" as *; +@use "../includes/themify" as *; +@use "../includes/themed" as *; + +html { + font-size: 14px; + line-height: 1.8; + + @include media("min", "lg") { + font-size: 16px; + } + + @include media("min", "xxl") { + font-size: 18px; + } +} + +body { + display: flex; + flex-direction: column; + min-height: 100vh; + + font-family: Helvetica, sans-serif; + font-weight: 400; + font-style: normal; + @include themify($themes) { + background-color: themed('background-color'); + color: themed('font-color'); + } +} + +a { + @include themify($themes) { + color: themed('link-color'); + } + + &:hover, &:focus { + @include themify($themes) { + color: themed('link-color-hover'); + } + } +} + +h1, h2, h3, h4, h5, h6 { + position: relative; + font-weight: 600; + text-align: left; + @include themify($themes) { + color: themed('font-color-light'); + } + + &.with-anchor { + .anchor { + display: none; + width: 1.2rem; + margin-left: 0.5rem; + height: 1.5rem; + + svg { + @include themify($themes) { + fill: themed('link-color2'); + } + } + + &:hover svg { + @include themify($themes) { + fill: themed('link-color2-hover'); + } + } + } + + &:hover .anchor { + display: inline-block; + } + } +} + +h1 { + font-size: 2.25rem; + margin: 0 1rem 1rem; + text-align: center; + @include themify($themes) { + border-bottom: 1px solid themed('border-color-lighter'); + } +} + +h2 { + font-size: 2rem; +} + +h3 { + font-size: 1.875rem; +} + +h4 { + font-size: 1.5rem; +} + +p { + padding: 0.5rem 0; +} + +pre { + padding: 1rem 0; +} + +blockquote { + padding: 0 1rem; + margin-bottom: 1rem; + @include themify($themes) { + background-color: themed('box-light'); + border-left: 1px solid themed('success'); + } +} + +ul { + padding-left: 1rem; + list-style-type: disc; +} + +svg { + width: 100%; + height: auto; +} + +table { + tr { + &:nth-child(odd) { + @include themify($themes) { + background-color: themed('background-highlight'); + } + } + + &:nth-child(even) { + @include themify($themes) { + background-color: themed('background-light'); + } + } + + th { + padding: 0.25rem 0.375rem; + } + } + + @include media("max", "lg") { + display: block; + overflow-x: auto; + white-space: nowrap; + } +} + +.box { + border-radius: 1rem; + @include themify($themes) { + background-color: themed('box-color'); + } +} + +.icon { + display: block; + line-height: 0; + width: 24px; + height: 24px; + + &.icon-md { + width: 1rem; + height: 1rem; + } +} + +details { + summary { + cursor: pointer; + + @include themify($themes) { + color: themed('link-color2'); + } + } + + summary:after { + content: ''; + display: inline-block; + line-height: 0; + width: 0.5rem; + height: 0.5rem; + transform: rotate(45deg); + margin-left: 0.5rem; + vertical-align: 2px; + + @include themify($themes) { + border-right: 2px solid themed('link-color2'); + border-bottom: 2px solid themed('link-color2'); + } + } + + &[open] summary:after { + vertical-align: -3px; + transform: rotate(-135deg); + } + + summary:hover { + @include themify($themes) { + color: themed('link-color2-hover'); + } + + &:after { + @include themify($themes) { + border-right: 2px solid themed('link-color2-hover'); + border-bottom: 2px solid themed('link-color2-hover'); + } + } + } +} + +hr { + margin: 2rem; +} diff --git a/website/src/scss/includes/forms.scss b/website/src/scss/includes/forms.scss new file mode 100644 index 000000000000..1b52460b8471 --- /dev/null +++ b/website/src/scss/includes/forms.scss @@ -0,0 +1,100 @@ +@use "../includes/themes" as *; +@use "../includes/themify" as *; +@use "../includes/themed" as *; + +button { + border-radius: 0.5rem; + cursor: pointer; + padding: 1rem; + line-height: 1; + + font-weight: 600; + + @include themify($themes) { + background-color: transparent; + border: 1px solid themed('background-highlight'); + color: themed('link-color'); + } + + &:focus, + &:hover { + @include themify($themes) { + background-color: themed('button-color-hover'); + color: themed('link-color-hover'); + } + } + + &.big { + border-radius: 2rem; + font-size: 1.25rem; + padding: 1rem; + } + + &.full-width { + width: 100%; + } +} + +input { + width: 100%; + padding: 0 2rem 0 0; + + font-size: 1rem; + line-height: 3rem; + + border-radius: 8px; + border: 0; + outline: 0; + + @include themify($themes) { + color: themed('form-font-color'); + background-color: themed('background-light'); + } +} + +.form-item { + display: flex; + align-items: center; + + padding: 0 2rem; + margin-bottom: 0.5rem; + + border-radius: 8px; + + @include themify($themes) { + background-color: themed('background-light'); + } + + .icon { + width: 1.25rem; + height: 1.25rem; + margin-right: 0.75rem; + + svg { + width: 100%; + height: auto; + opacity: 0.3; + @include themify($themes) { + color: themed('form-font-color'); + } + } + } +} + +select { + width: 100%; + height: 3rem; + + font-size: 1rem; + + border-radius: 8px; + border: 0; + outline: 0; + + appearance: none; + + @include themify($themes) { + color: themed('form-font-color'); + background-color: themed('background-light'); + } +} diff --git a/website/src/scss/includes/markdown.scss b/website/src/scss/includes/markdown.scss new file mode 100644 index 000000000000..1a6fac673bd5 --- /dev/null +++ b/website/src/scss/includes/markdown.scss @@ -0,0 +1,110 @@ +@use "../includes/mixins" as *; +@use "../includes/themes" as *; +@use "../includes/themify" as *; +@use "../includes/themed" as *; + +.markdown-alert { + padding-left: 1rem; + margin-bottom: 1rem; + + &.markdown-alert-note { + @include themify($themes) { + border-left: 1px solid themed('neutral'); + } + + .markdown-alert-title { + @include themify($themes) { + color: themed('neutral'); + } + } + + svg { + @include themify($themes) { + fill: themed('neutral'); + } + } + } + + &.markdown-alert-tip { + @include themify($themes) { + border-left: 1px solid themed('success'); + } + + .markdown-alert-title { + @include themify($themes) { + color: themed('success'); + } + } + + svg { + @include themify($themes) { + fill: themed('success'); + } + } + } + + &.markdown-alert-important { + @include themify($themes) { + border-left: 1px solid themed('success'); + } + + .markdown-alert-title { + @include themify($themes) { + color: themed('success'); + } + } + + svg { + @include themify($themes) { + fill: themed('success'); + } + } + } + + &.markdown-alert-warning { + @include themify($themes) { + border-left: 1px solid themed('warning'); + } + + .markdown-alert-title { + @include themify($themes) { + color: themed('warning'); + } + } + + svg { + @include themify($themes) { + fill: themed('warning'); + } + } + } + + &.markdown-alert-caution { + @include themify($themes) { + border-left: 1px solid themed('warning'); + } + + .markdown-alert-title { + @include themify($themes) { + color: themed('warning'); + } + } + + svg { + @include themify($themes) { + fill: themed('warning'); + } + } + } + + .markdown-alert-title { + font-weight: 700; + vertical-align: middle; + + svg { + width: 16px; + height: 16px; + padding-right: 0.5rem; + } + } +} diff --git a/website/src/scss/includes/mixins.scss b/website/src/scss/includes/mixins.scss new file mode 100644 index 000000000000..e3ce8472a61c --- /dev/null +++ b/website/src/scss/includes/mixins.scss @@ -0,0 +1,49 @@ +$sizes: ( + "xs": 0px, + "sm": 480px, + "md": 767px, + "lg": 1024px, + "xl": 1439px, + "xxl": 1920px, +); + +@function getPreviousSize($currentSize) { + $keys: map-keys($sizes); + $index: index($keys, $currentSize) - 1; + $value: map-values($sizes); + @return nth($value, $index); +} + +@mixin media($minmax, $media) { + @each $size, $resolution in $sizes { + @if $media == $size { + @if ($minmax == "max") { + @media only screen and (#{$minmax}-width: $resolution) { + @content; + } + } @else if ($minmax == "min") { + @media only screen and (#{$minmax}-width: $resolution + 1) { + @content; + } + } @else { + @if (index(map-keys($sizes), $media) > 1) { + @media only screen and (min-width: getPreviousSize($media) + 1) and (max-width: $resolution + 1) { + @content; + } + } @else { + @media only screen and (max-width: $resolution) { + @content; + } + } + } + } + } +} + +@mixin wrapper() { + width: 100%; + + @include media('min', 'xl') { + max-width: 90%; + } +} diff --git a/website/src/scss/includes/reset.scss b/website/src/scss/includes/reset.scss new file mode 100644 index 000000000000..9cb3236f2f4e --- /dev/null +++ b/website/src/scss/includes/reset.scss @@ -0,0 +1,85 @@ +html, body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, form, fieldset, input, textarea, p, blockquote, th, td, +figure, figcaption, address { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + overflow-y: scroll; +} + +article, aside, details, figcaption, figure, footer, header, hgroup, nav, section, summary { + display: block; + margin: 0; + padding: 0; +} + +table { + border-spacing: 1px; + margin: 1rem 0; + + th, + td { + vertical-align: middle; + padding: 0.25rem; + } +} + +caption, th { + text-align: left; +} + +ul, ol { + list-style: none; +} + +a { + text-decoration: none; +} + +a:link, a:visited, a:active { + -webkit-transition: 0.1s color ease; + -moz-transition: 0.1s color ease; + -o-transition: 0.1s color ease; + transition: 0.1s color ease; +} + +a:hover, a:focus { + cursor: pointer; + text-decoration: none; +} + +input[type="text"], +input[type="password"], +input[type="number"], +input[type="email"], +input[type="tel"], +textarea { + appearance: none; + outline: none; +} + +@-webkit-keyframes autofill { + to { + background: transparent; + } +} + +input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill { + -webkit-animation-name: autofill; + -webkit-animation-fill-mode: both; +} + +svg { + overflow: auto; + vertical-align: inherit; +} + +img { + max-width: 100%; +} + +* { + outline: none; +} diff --git a/website/src/scss/includes/themed.scss b/website/src/scss/includes/themed.scss new file mode 100644 index 000000000000..2e1026f52766 --- /dev/null +++ b/website/src/scss/includes/themed.scss @@ -0,0 +1,6 @@ +@use "sass:map"; +@use "../includes/themify" as *; + +@function themed($key) { + @return map.get($theme-map, $key); +} diff --git a/website/src/scss/includes/themes.scss b/website/src/scss/includes/themes.scss new file mode 100644 index 000000000000..c8612c2e38f7 --- /dev/null +++ b/website/src/scss/includes/themes.scss @@ -0,0 +1,76 @@ +@use 'variables-dark' as dark; +@use 'variables-light' as light; +@use "mixins" as *; + +$themes: ( + 'dark': ( + 'font-color': dark.$foreground, + 'font-color-light': dark.$font, + 'font-color-dark': dark.$dark, + 'comment-color': dark.$comment, + 'font-success': dark.$green, + 'font-warning': dark.$orange, + 'font-error': dark.$red, + 'font-note': rgba(dark.$foreground, 0.7), + + 'button-color': dark.$bg, + 'button-color-hover': dark.$selection, + 'box-color': dark.$bg, + 'box-light': dark.$selection, + 'background-color': dark.$dark, + 'background-light': dark.$secondary, + 'background-highlight': dark.$highlight, + 'link-color': rgba(dark.$foreground, 0.7), + 'link-color-hover': dark.$foreground, + 'link-color2': rgba(dark.$link, 0.7), + 'link-color2-hover': dark.$link, + 'border-color': dark.$dark, + 'border-color-light': dark.$secondary, + 'border-color-lighter': dark.$selection, + 'form-font-color': dark.$foreground, + 'form-hint-color': dark.$foreground, + + 'success': dark.$green, + 'warning': dark.$orange, + 'error': dark.$red, + 'neutral': dark.$comment, + 'section': dark.$pink, + 'meta': dark.$purple, + 'function': dark.$cyan, + ), + 'light': ( + 'font-color': light.$foreground, + 'font-color-light': light.$font, + 'font-color-dark': light.$dark, + 'comment-color': light.$comment, + 'font-success': light.$green, + 'font-warning': light.$orange, + 'font-error': light.$red, + 'font-note': rgba(light.$foreground, 0.7), + + 'button-color': light.$foreground, + 'button-color-hover': light.$selection, + 'box-color': light.$bg, + 'box-light': light.$selection, + 'background-color': light.$dark, + 'background-light': light.$secondary, + 'background-highlight': light.$highlight, + 'link-color': rgba(light.$foreground, 0.7), + 'link-color-hover': light.$foreground, + 'link-color2': rgba(light.$link, 0.7), + 'link-color2-hover': light.$link, + 'border-color': light.$dark, + 'border-color-light': light.$secondary, + 'border-color-lighter': light.$highlight, + 'form-font-color': light.$foreground, + 'form-hint-color': light.$foreground, + + 'success': light.$green, + 'warning': light.$orange, + 'error': light.$red, + 'neutral': light.$comment, + 'section': light.$pink, + 'meta': light.$purple, + 'function': light.$cyan, + ) +); diff --git a/website/src/scss/includes/themify.scss b/website/src/scss/includes/themify.scss new file mode 100644 index 000000000000..ebc083c2d675 --- /dev/null +++ b/website/src/scss/includes/themify.scss @@ -0,0 +1,19 @@ +$theme-map: (); + +@use "sass:map"; +@use 'themes' as *; + +@mixin themify($themes: $themes) { + @each $theme, $map in $themes { + .theme-#{$theme} & { + $theme-map: () !global; + @each $key, $submap in $map { + $value: map.get(map.get($themes, $theme), '#{$key}'); + $theme-map: map.merge($theme-map, ($key: $value)) !global; + } + + @content; + $theme-map: null !global; + } + } +} diff --git a/website/src/scss/includes/variables-dark.scss b/website/src/scss/includes/variables-dark.scss new file mode 100644 index 000000000000..52087c67c237 --- /dev/null +++ b/website/src/scss/includes/variables-dark.scss @@ -0,0 +1,18 @@ +$bg: #282a36; +$current_line: #44475a; +$foreground: #fafaf4; +$comment: #6272a4; +$cyan: #8be9fd; +$green: #50fa7b; +$orange: #ffb86c; +$pink: #ff79c6; +$purple: #bd93f9; +$red: #ff5555; +$link: #f1fa8c; +$font: #ffffff; + +$selection: #44475a; +$secondary: #2e313f; +$dark: #191a21; +$highlight: #44475a; +$disabled: #6D6D6D; diff --git a/website/src/scss/includes/variables-light.scss b/website/src/scss/includes/variables-light.scss new file mode 100644 index 000000000000..8c8c39b41da1 --- /dev/null +++ b/website/src/scss/includes/variables-light.scss @@ -0,0 +1,18 @@ +$bg: #eceff4; +$current_line: #e5e9f0; +$foreground: #1f232c; +$comment: #4c566a; +$cyan: #0184bc; +$green: #50a14f; +$orange: #c18401; +$pink: #a626a4; +$purple: #986801; +$red: #e45649; +$link: #286ff3; +$font: #1f232c; + +$selection: #fafafa; +$secondary: #ffffff; +$dark: #eceff4; +$highlight: #d8dee9; +$disabled: #a3be8c40; diff --git a/website/src/scss/parts/code.scss b/website/src/scss/parts/code.scss new file mode 100644 index 000000000000..877dd613905b --- /dev/null +++ b/website/src/scss/parts/code.scss @@ -0,0 +1,144 @@ +@use "../includes/themed" as *; +@use "../includes/themes" as *; +@use "../includes/themify" as *; + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + @include themify($themes) { + background-color: themed('box-color'); + color: themed('font-color'); + } +} + +.hljs-comment, .hljs-quote { + font-style: italic; + @include themify($themes) { + color: themed('comment-color'); + } +} + +.hljs-keyword, .hljs-selector-tag, .hljs-literal, .hljs-section, .hljs-link { + @include themify($themes) { + color: themed('section'); + } +} + +.hljs-string, .hljs-title, .hljs-name, .hljs-type, .hljs-attribute, .hljs-symbol, .hljs-bullet, .hljs-addition { + @include themify($themes) { + color: themed('success'); + } +} + +.hljs-number, .hljs-meta, .hljs-built_in, .hljs-builtin-name, .hljs-params { + @include themify($themes) { + color: themed('meta'); + } +} + +.hljs-class .hljs-title, .hljs-strong { + font-weight: bold; + @include themify($themes) { + color: themed('link-color2-hover'); + } +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-function .hljs-title { + @include themify($themes) { + color: themed('function'); + } +} + +.hljs-tag, .hljs-deletion { + @include themify($themes) { + color: themed('font-error'); + } +} + +.hljs-variable, .hljs-template-variable, .hljs-selector-attr, .hljs-selector-pseudo { + @include themify($themes) { + color: themed('font-warning'); + } +} + +.hljs-doctag { + @include themify($themes) { + color: themed('font-warning'); + } +} + +.hljs-bullet { + @include themify($themes) { + color: themed('meta'); + } +} + +.hljs-code, .hljs-formula { + @include themify($themes) { + color: themed('section'); + } +} + +.hljs-link { + text-decoration: underline; +} + +.hljs-selector-id { + @include themify($themes) { + color: themed('link-color2-hover'); + } +} + +.hljs-selector-class { + @include themify($themes) { + color: themed('function'); + } +} + +.hljs::selection, .hljs span::selection { + @include themify($themes) { + background: themed('button-color-hover'); + } +} + +code { + position: relative; + overflow-x: auto; + max-width: 100%; + display: inline-block; + vertical-align: middle; + scrollbar-width: thin; + padding: 0 0.25rem; + @include themify($themes) { + background: themed('button-color-hover'); + scrollbar-color: themed('background-light') themed('button-color-hover'); + } +} + +pre code { + scrollbar-width: thin; + font-size: 0.85rem; + line-height: 1.375rem; + @include themify($themes) { + scrollbar-color: themed('background-light') themed('background-highlight'); + } +} + +.hljs-run { + position: absolute; + top: 0.25rem; + right: 0.25rem; + width: 24px; + height: 24px; + + .hljs-run-button { + display: block; + width: 100%; + height: 100%; + } +} diff --git a/website/src/scss/parts/footer.scss b/website/src/scss/parts/footer.scss new file mode 100644 index 000000000000..5c229c43ea06 --- /dev/null +++ b/website/src/scss/parts/footer.scss @@ -0,0 +1,49 @@ +@use "../includes/mixins" as *; +@use "../includes/themed" as *; +@use "../includes/themes" as *; +@use "../includes/themify" as *; + +footer { + display: flex; + padding: 2rem; + justify-content: center; + + @include themify($themes) { + border-top: 1px solid themed('border-color-light'); + } + + .footer { + display: flex; + justify-content: space-between; + align-items: start; + flex-direction: column; + + @include wrapper; + + @include media('min', 'sm') { + flex-direction: row; + } + + .footer-logo { + width: 144px; + } + + .title { + font-size: 1.125rem; + font-weight: 600; + @include themify($themes) { + color: themed('font-color'); + } + } + + .copyright { + order: 3; + margin-top: 1rem; + + @include media('min', 'sm') { + order: unset; + margin-top: 0; + } + } + } +} diff --git a/website/src/scss/parts/header.scss b/website/src/scss/parts/header.scss new file mode 100644 index 000000000000..1a49c6c22242 --- /dev/null +++ b/website/src/scss/parts/header.scss @@ -0,0 +1,287 @@ +@use "../includes/mixins" as *; +@use "../includes/themed" as *; +@use "../includes/themes" as *; +@use "../includes/themify" as *; + +header { + display: flex; + justify-content: center; + + @include themify($themes) { + background-color: themed('background-color'); + } + + @include media("min", "xl") { + padding: 0 1rem; + } +} + +nav { + display: flex; + justify-content: space-between; + align-items: center; + + padding: 1rem; + + max-height: 86px; + + @include wrapper; + + .logo { + max-width: 60%; + + @include media('min', 'sm') { + width: 360px; + max-width: unset; + } + + a { + display: flex; + + img { + width: 100%; + height: auto; + } + } + } + + #menu { + display: flex; + align-items: center; + + .menu-items { + display: none; + + @include media("min", "lg") { + display: flex; + align-items: center; + } + + .menu-item { + padding-right: 1rem; + + &:last-child { + padding-right: 0; + } + + .theme-switcher { + display: flex; + align-items: center; + } + + .theme-switcher-title { + margin-right: 0.5rem; + + @include media("min", "lg") { + display: none; + } + } + } + + a { + font-size: 1.5rem; + display: block; + overflow-wrap: break-word; + @include themify($themes) { + color: themed('link-color'); + } + + &:hover { + @include themify($themes) { + color: themed('link-color-hover'); + } + } + + &.active { + @include themify($themes) { + color: themed('link-color2'); + } + } + + .icon { + width: 26px; + height: 26px; + } + } + + .mobile-docs-menu { + display: none; + } + } + + &.active { + align-items: center; + overflow-y: auto; + + & > .backdrop { + display: block; + } + + @include media("max", "lg") { + .menu-items { + z-index: 5; + display: flex; + flex-direction: column; + position: absolute; + top: 0; + right: 0; + min-height: 40vh; + width: 75%; + max-height: 100vh; + max-width: 350px; + + overflow-y: auto; + scrollbar-width: thin; + @include themify($themes) { + scrollbar-color: themed('background-light') themed('background-highlight'); + } + + border-top-left-radius: 20px; + border-bottom-left-radius: 20px; + + padding: 50px 20px 30px 30px; + + @include themify($themes) { + background-color: themed('box-color'); + box-shadow: -1px 1px 5px themed('background-light'); + } + + .mobile-docs-menu { + display: block; + + ul { + list-style: circle; + } + + .menu-header { + font-size: 1.25rem; + } + } + } + + .menu-item { + line-height: 2rem; + + a::after { + top: 0.75rem; + } + } + + .burger { + position: absolute; + top: 25px; + right: 15px; + z-index: 6; + + a { + display: block; + -webkit-tap-highlight-color: transparent; + -webkit-touch-callout: none; + + span { + height: 1px; + @include themify($themes) { + background-color: themed('font-color'); + } + + &:nth-child(1) { + margin-top: 11px; + transform: rotate(-45deg); + } + + &:nth-child(2) { + margin-top: -1px; + transform: rotate(45deg); + } + + &:nth-child(3) { + display: none; + } + } + } + } + } + } + + .burger { + @include media("min", "lg") { + display: none; + } + + a { + display: flex; + width: 26px; + height: 22px; + padding: 5px; + flex-direction: column; + justify-content: space-between; + + span { + display: block; + width: 100%; + height: 2px; + border-radius: 2px; + @include themify($themes) { + background-color: themed('link-color'); + } + } + } + } + + .backdrop { + display: none; + + content: ''; + position: absolute; + width: 100%; + height: 100vh; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 4; + } + + .socials { + display: flex; + align-items: center; + margin-right: 1rem; + + @include media("max", "lg") { + width: 100%; + justify-content: center; + margin: auto 0 0; + order: 99; + padding-top: 2rem; + } + + @include media("min", "lg") { + padding: 0 1rem; + @include themify($themes) { + border-left: 1px solid themed('link-color'); + border-right: 1px solid themed('link-color'); + } + } + } + } +} + +.theme-light { + .icon.light { + display: none; + } + + .icon.dark { + display: block; + } +} + +.theme-dark { + .icon.light { + display: block; + } + + .icon.dark { + display: none; + } +} diff --git a/website/src/scss/parts/main.scss b/website/src/scss/parts/main.scss new file mode 100644 index 000000000000..40a761f2051c --- /dev/null +++ b/website/src/scss/parts/main.scss @@ -0,0 +1,541 @@ +@use "../includes/mixins" as *; +@use "../includes/themed" as *; +@use "../includes/themes" as *; +@use "../includes/themify" as *; + +.collapsible { + a { + position: relative; + } + + & > ul { + display: none; + } + + &.active { + & > a::after { + transform: rotate(-135deg); + top: 0.625rem; + } + + & > ul { + display: block; + } + } + + & > a::after { + position: absolute; + width: 5px; + height: 5px; + transform: rotate(45deg); + content: ''; + margin-left: 0.5rem; + top: 0.375rem; + + @include themify($themes) { + border-right: 1px solid themed('link-color'); + border-bottom: 1px solid themed('link-color'); + } + } +} + +main { + display: flex; + justify-content: center; + flex-grow: 1; + margin-bottom: 2rem; + + @include media('min', 'sm') { + padding: 0 1rem 1rem; + } + + a { + @include themify($themes) { + color: themed('link-color2'); + } + &:focus { + @include themify($themes) { + color: themed('link-color2'); + } + } + + &:hover { + @include themify($themes) { + color: themed('link-color2-hover'); + } + } + } + + .main { + padding: 1rem 1rem; + @include themify($themes) { + background-color: themed('background-light'); + } + + @include wrapper; + + .wrapper { + display: flex; + position: relative; + + .docs-menu { + position: sticky; + top: 1rem; + align-self: flex-start; + + padding: 0 0.5rem 150px 0; + + font-size: 0.875rem; + flex-basis: 20%; + min-width: 160px; + flex-shrink: 0; + line-height: 1.3; + + min-height: 100vh; + min-height: 100dvh; + max-height: 100vh; + max-height: 100dvh; + overflow-y: auto; + overflow-x: hidden; + scrollbar-width: thin; + + @include themify($themes) { + border-right: 1px solid themed('border-color-lighter'); + scrollbar-color: themed('background-light') themed('background-highlight'); + } + + ul { + list-style: none; + padding: 0; + + li { + padding: 0.25rem 0 0.5rem 0; + + &:last-child { + padding-bottom: 0; + } + } + } + + @include media('max', 'md') { + position: absolute; + left: -1rem; + top: 1rem; + bottom: 1rem; + min-width: 1.75rem; + z-index: 3; + overflow-y: unset; + padding: 0; + height: 100%; + min-height: unset; + max-height: unset; + overflow-x: unset; + @include themify($themes) { + background-color: themed('background-light'); + box-shadow: 5px 5px 7px -6px themed('background-highlight'); + } + + .container { + position: sticky; + display: flex; + top: 1rem; + max-height: 100dvh; + height: 100%; + padding-bottom: 1rem; + } + + .docs-links { + max-height: 100dvh; + height: 100%; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; + padding-bottom: 1rem; + } + + .mobile-trigger { + display: flex; + width: 1.75rem; + min-width: 1.75rem; + cursor: pointer; + align-items: center; + justify-content: center; + max-height: 100vh; + max-height: 100dvh; + + &:after { + content: ''; + display: block; + width: 10px; + height: 10px; + transform: rotate(-45deg); + margin-left: -2px; + @include themify($themes) { + border-right: 2px solid themed('link-color'); + border-bottom: 2px solid themed('link-color'); + } + } + &:hover { + &:after { + @include themify($themes) { + border-right: 2px solid themed('link-color-hover'); + border-bottom: 2px solid themed('link-color-hover'); + } + } + } + } + + li { + @include media('max', 'md') { + display: none; + } + } + + &.active { + min-width: 180px; + max-width: 270px; + padding-left: 1rem; + + li { + display: block; + } + + .mobile-trigger { + &:after { + transform: rotate(135deg); + margin-left: 5px; + } + } + } + } + + a { + &.active { + @include themify($themes) { + color: themed('link-color2-hover'); + } + } + } + + .collapsible { + & > ul { + padding: 0.75rem 0 0 1rem; + } + + &.active { + & > a::after { + top: 0.5rem; + } + } + + & > a::after { + top: 0.125rem; + } + } + + .menu-header { + padding: 0 0 0.75rem 0; + font-weight: 600; + } + + .menu-item { + padding: 0 0.5rem 0.5rem 0.5rem; + @include themify($themes) { + border-right: 1px solid themed('border-color-lighter'); + } + } + } + + .content { + width: 100%; + padding: 1rem 1rem 0; + min-width: 0; + text-align: justify; + + @include media("min", "md") { + padding: 0 1rem; + } + } + + .table-of-contents { + position: sticky; + top: 1rem; + align-self: flex-start; + font-size: 0.875rem; + max-width: 20%; + min-width: 20%; + height: 100vh; + height: 100dvh; + overflow-y: auto; + scrollbar-width: none; + @include themify($themes) { + border-left: 1px solid themed('border-color-lighter'); + } + + .mobile-trigger { + display: none; + } + + @include media('max', 'xl') { + position: absolute; + right: -1rem; + top: 1rem; + bottom: 1rem; + min-width: 1.75rem; + z-index: 3; + overflow-y: unset; + height: 100%; + @include themify($themes) { + background-color: themed('background-light'); + box-shadow: -5px 5px 7px -6px themed('background-highlight'); + } + + .container { + position: sticky; + display: flex; + top: 1rem; + max-height: 100dvh; + height: 100%; + padding-bottom: 1rem; + } + + .toc-links { + max-height: 100dvh; + height: 100%; + overflow-y: auto; + scrollbar-width: none; + -ms-overflow-style: none; + } + + .mobile-trigger { + display: flex; + width: 1.75rem; + min-width: 1.75rem; + cursor: pointer; + align-items: center; + justify-content: center; + max-height: 100vh; + max-height: 100dvh; + + &:after { + content: ''; + display: block; + transform: rotate(135deg); + width: 10px; + height: 10px; + margin-left: 5px; + @include themify($themes) { + border-right: 2px solid themed('link-color'); + border-bottom: 2px solid themed('link-color'); + } + } + &:hover { + &:after { + @include themify($themes) { + border-right: 2px solid themed('link-color-hover'); + border-bottom: 2px solid themed('link-color-hover'); + } + } + } + } + + &.active { + min-width: 180px; + + .toc-link { + display: block; + padding-left: 0; + padding-right: 1rem; + } + + .mobile-trigger { + &:after { + transform: rotate(-45deg); + margin-left: -2px; + } + } + } + } + + .toc-link { + padding: 0 0 0.5rem 1rem; + + @include media('max', 'xl') { + display: none; + } + + a { + display: block; + } + + &.active { + a { + @include themify($themes) { + color: themed('link-color2-hover'); + } + } + } + + .h3 { + margin-left: 0.5rem; + } + .h4, .h5, .h6, .h7 { + margin-left: 1rem; + } + } + } + } + + .sponsors { + display: flex; + flex-wrap: wrap; + + a { + flex-basis: 33%; + + @include media("min", "md") { + flex-basis: 25%; + } + } + } + + .features { + display: flex; + flex-wrap: wrap; + align-content: stretch; + align-items: stretch; + justify-content: center; + margin: 1rem 0; + text-align: start; + gap: 2rem; + + .feature { + flex-basis: 100%; + padding: 1rem; + border-radius: 1rem; + max-width: 400px; + + @include themify($themes) { + background-color: themed('box-color'); + border: 1px solid themed('box-light'); + } + + @include media("min", "md") { + flex-basis: 48%; + } + + @include media("min", "lg") { + flex-basis: 31%; + } + + @include media("min", "xxl") { + flex-basis: 23%; + } + + .title { + font-size: 1.5rem; + display: flex; + align-items: center; + gap: 0.5rem; + + svg { + @include themify($themes) { + color: themed('font-success'); + } + } + } + + .desc { + + } + } + } + } +} +.dropdown { + a { + white-space: nowrap; + } + + .dropdown-wrapper { + position: relative; + + & > a { + display: block; + overflow: hidden; + width: 90%; + + &::after { + content: ''; + + width: 5px; + height: 5px; + + transform: rotate(45deg); + + position: absolute; + right: 5px; + top: 3px; + @include themify($themes) { + border-right: 2px solid themed('link-color'); + border-bottom: 2px solid themed('link-color'); + } + } + } + + .dropdown-block { + display: none; + + a { + display: block; + line-height: 2; + } + } + } + + &.active { + .dropdown-block { + display: block; + position: absolute; + z-index: 6; + left: -1rem; + margin-top: 0.625rem; + padding: 0.5rem 1rem; + border-radius: 0.5rem; + @include themify($themes) { + border: 1px solid themed('border-color-lighter'); + background-color: themed('background-color'); + } + + a.active { + font-weight: 500; + @include themify($themes) { + color: themed('link-color2-hover'); + } + } + } + + .backdrop { + display: block; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + } + + @include media("max", "lg") { + .backdrop { + height: 100%; + } + } +} +.versions-menu { + padding: 0.5rem 1rem; + border-radius: 0.5rem; + @include themify($themes) { + border: 1px solid themed('border-color-lighter'); + background-color: themed('background-light'); + } +} diff --git a/website/src/scss/parts/playground.scss b/website/src/scss/parts/playground.scss new file mode 100644 index 000000000000..4113412c2c7c --- /dev/null +++ b/website/src/scss/parts/playground.scss @@ -0,0 +1,264 @@ +@use "../includes/mixins" as *; +@use "../includes/themed" as *; +@use "../includes/themes" as *; +@use "../includes/themify" as *; + +.sandbox-wrapper { + margin: 1rem 0 0; + + @include media("min", "lg") { + display: flex; + } + + .editor { + position: relative; + flex-basis: 800px; + flex-grow: 1; + + height: 30rem; + padding: 0; + border: none; + @include media("min", "lg") { + margin-right: 1rem; + } + + .input, .output { + box-sizing: border-box; + position: absolute; + height: 100%; + width: 100%; + + font-family: monospace; + padding: 0.5em; + border: none; + font-size: 0.85rem; + line-height: 1.375rem; + white-space: pre; + word-wrap: break-word; + overflow: auto; + + scrollbar-width: thin; + @include themify($themes) { + scrollbar-color: themed('background-light') themed('background-highlight'); + } + } + + .input { + z-index: 1; + color: transparent; + background-color: transparent; + resize: none; + @include themify($themes) { + caret-color: themed('font-color'); + } + } + + .output { + z-index: 0; + padding-bottom: 7px; + @include themify($themes) { + background-color: themed('box-color'); + } + } + + .controls-float { + position: absolute; + position: sticky; + width: fit-content; + display: flex; + top: 0.25rem; + right: 0.5rem; + margin-left: auto; + padding-right: 0.5rem; + padding-top: 0.25rem; + z-index: 3; + + a { + display: block; + width: 24px; + height: 24px; + + margin-right: 0.5rem; + + &.link-button { + width: 22px; + height: 22px; + } + } + } + } + + .result { + margin-top: 2rem; + padding: 0.5em; + + font-family: monospace; + font-size: 0.85rem; + line-height: 1.375rem; + white-space: pre; + word-wrap: break-word; + + scrollbar-width: thin; + @include themify($themes) { + background-color: themed('box-color'); + scrollbar-color: themed('background-light') themed('background-highlight'); + } + + @include media("min", "lg") { + flex-basis: 400px; + flex-shrink: 0; + margin-top: 0; + overflow: auto; + height: 30rem; + } + + .console { + &.log { + @include themify($themes) { + color: themed('font-success'); + } + } + + &.warn { + @include themify($themes) { + color: themed('font-warning'); + } + } + + &.error { + @include themify($themes) { + color: themed('font-error'); + } + } + } + } +} + +.playground-menu { + display: flex; + flex-direction: column; + align-items: center; + + @include media("min", "md") { + flex-direction: row; + } + + .title { + display: flex; + align-items: center; + margin-bottom: 1rem; + + @include media("min", "md") { + margin: 0 1.5rem 0 0; + } + + .back-link { + flex-basis: 68px; + flex-shrink: 0; + margin-right: 1.5rem; + padding-left: 0.25rem; + + a { + align-items: center; + display: none; + + .icon { + margin-right: 0.5rem; + } + } + + .dummy { + width: 36px; + height: 36px; + margin-left: auto; + + svg { + @include themify($themes) { + fill: themed('font-color'); + } + } + } + + &.active { + a { + display: flex; + } + + .dummy { + display: none; + } + } + } + + h1 { + border-bottom: 0; + margin: 0; + } + } + + .playground-versions { + min-width: 200px; + width: 100%; + + @include media("min", "md") { + max-width: 200px; + } + + .dropdown .dropdown-wrapper > a:after { + top: 8px; + } + + .backdrop { + z-index: 3; + } + } + + .playground-controls { + display: flex; + margin-bottom: 1rem; + + @include media("min", "md") { + margin-bottom: 0; + } + + button { + margin-right: 1rem; + + &:last-child { + margin-right: 0; + } + } + } + + .playground-notes { + display: flex; + align-items: center; + font-size: 0.75rem; + padding: 0 0.5rem; + + @include themify($themes) { + color: themed('font-note'); + } + + @include media("min", "md") { + margin-left: auto; + } + + .icon { + margin-right: 0.5rem; + + svg { + @include themify($themes) { + fill: themed('font-note'); + } + } + } + } +} + +.copy-fallback { + position: fixed; + top: 0; + left: 0; + opacity: 0; +} diff --git a/website/src/scss/parts/tooltip.scss b/website/src/scss/parts/tooltip.scss new file mode 100644 index 000000000000..d4615eb4b651 --- /dev/null +++ b/website/src/scss/parts/tooltip.scss @@ -0,0 +1,54 @@ +@use "../includes/mixins" as *; +@use "../includes/themed" as *; +@use "../includes/themes" as *; +@use "../includes/themify" as *; + +#tooltip { + position: absolute; + font-weight: bold; + padding: 4px 8px; + border-radius: 4px; + opacity: 0; + transition: opacity 0.3s ease; + @include themify($themes) { + background: themed('font-color'); + color: themed('background-highlight'); + } + + &[data-show] { + opacity: 1; + } + + #tooltip-arrow, #tooltip-arrow::before { + position: absolute; + width: 8px; + height: 8px; + background: inherit; + } + + #tooltip-arrow { + visibility: hidden; + } + + #tooltip-arrow::before { + visibility: visible; + content: ''; + transform: rotate(45deg); + } + + &[data-popper-placement^='top'] > #tooltip-arrow { + bottom: -4px; + } + + &[data-popper-placement^='bottom'] > #tooltip-arrow { + top: -4px; + } + + &[data-popper-placement^='left'] > #tooltip-arrow { + right: -4px; + } + + &[data-popper-placement^='right'] > #tooltip-arrow { + left: -4px; + } +} diff --git a/website/vite.config.mjs b/website/vite.config.mjs new file mode 100644 index 000000000000..4b6608f473ac --- /dev/null +++ b/website/vite.config.mjs @@ -0,0 +1,28 @@ +import { defineConfig } from 'vite'; +import legacy from '@vitejs/plugin-legacy'; + +export default defineConfig({ + root: 'src', + publicDir: 'public', + base: '', + build: { + rollupOptions: { + input: { + main: 'src/index.html', + playground: 'src/playground.html', + }, + }, + outDir: '../templates', + emptyOutDir: true, + minify: true, + cssTarget: [ + 'ie11', + ], + }, + plugins: [ + legacy({ + targets: 'IE 11, Chrome>=38, Safari>=7.1, FF>=15', + polyfills: false, + }), + ], +});