mirror of
https://github.com/tc39/test262.git
synced 2025-05-23 16:20:34 +02:00
Merge pull request #2367 from bocoup/unnecessary-includes-lint
lint: add rule to verify use of harness files
This commit is contained in:
commit
a1acc23cd8
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Verify that a subArray is contained within an array.
|
Verify that a subArray is contained within an array.
|
||||||
|
defines: [arrayContains]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Collection of assertion functions used throughout test262
|
Collection of assertion functions used throughout test262
|
||||||
|
defines: [assert]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ description: |
|
|||||||
Verify that the given date object's Number representation describes the
|
Verify that the given date object's Number representation describes the
|
||||||
correct number of milliseconds since the Unix epoch relative to the local
|
correct number of milliseconds since the Unix epoch relative to the local
|
||||||
time zone (as interpreted at the specified date).
|
time zone (as interpreted at the specified date).
|
||||||
|
defines: [assertRelativeDateMs]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,6 +6,7 @@ description: >
|
|||||||
features: [Symbol, async-functions]
|
features: [Symbol, async-functions]
|
||||||
flags: [non-deterministic]
|
flags: [non-deterministic]
|
||||||
features: [FinalizationGroup]
|
features: [FinalizationGroup]
|
||||||
|
defines: [asyncGC, asyncGCDeref, resolveAsyncGC]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function asyncGC(...targets) {
|
function asyncGC(...targets) {
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
/*---
|
/*---
|
||||||
description: >
|
description: >
|
||||||
Collection of functions used to interact with Atomics.* operations across agent boundaries.
|
Collection of functions used to interact with Atomics.* operations across agent boundaries.
|
||||||
|
defines:
|
||||||
|
- $262.agent.getReport
|
||||||
|
- $262.agent.safeBroadcast
|
||||||
|
- $262.agent.tryYield
|
||||||
|
- $262.trySleep
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,7 @@ description: |
|
|||||||
This helper is mostly used on tests for TypedArray and DataView, and each
|
This helper is mostly used on tests for TypedArray and DataView, and each
|
||||||
array from the expected values must match the original values array on every
|
array from the expected values must match the original values array on every
|
||||||
index containing its original value.
|
index containing its original value.
|
||||||
|
defines: [byteConversionValues]
|
||||||
---*/
|
---*/
|
||||||
var byteConversionValues = {
|
var byteConversionValues = {
|
||||||
values: [
|
values: [
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Compare the contents of two arrays
|
Compare the contents of two arrays
|
||||||
|
defines: [compareArray]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
/*---
|
/*---
|
||||||
description: Compare the values of an iterator with an array of expected values
|
description: Compare the values of an iterator with an array of expected values
|
||||||
|
defines: [assert.compareIterator]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// Example:
|
// Example:
|
||||||
|
@ -3,6 +3,17 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Collection of date-centric values
|
Collection of date-centric values
|
||||||
|
defines:
|
||||||
|
- date_1899_end
|
||||||
|
- date_1900_start
|
||||||
|
- date_1969_end
|
||||||
|
- date_1970_start
|
||||||
|
- date_1999_end
|
||||||
|
- date_2000_start
|
||||||
|
- date_2099_end
|
||||||
|
- date_2100_start
|
||||||
|
- start_of_time
|
||||||
|
- end_of_time
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
var date_1899_end = -2208988800001;
|
var date_1899_end = -2208988800001;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Collection of functions used to assert the correctness of various encoding operations.
|
Collection of functions used to assert the correctness of various encoding operations.
|
||||||
|
defines: [decimalToHexString, decimalToPercentHexString]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function decimalToHexString(n) {
|
function decimalToHexString(n) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Compare two values structurally
|
Compare two values structurally
|
||||||
|
defines: [assert.deepEqual]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
@ -5,7 +5,7 @@ description: |
|
|||||||
A function used in the process of asserting correctness of TypedArray objects.
|
A function used in the process of asserting correctness of TypedArray objects.
|
||||||
|
|
||||||
$262.detachArrayBuffer is defined by a host.
|
$262.detachArrayBuffer is defined by a host.
|
||||||
|
defines: [$DETACHBUFFER]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function $DETACHBUFFER(buffer) {
|
function $DETACHBUFFER(buffer) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// This code is governed by the BSD license found in the LICENSE file.
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
|
defines: [$DONE]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function __consolePrintHandle__(msg) {
|
function __consolePrintHandle__(msg) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Produce a reliable global object
|
Produce a reliable global object
|
||||||
|
defines: [fnGlobalObject]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
var __globalObject = Function("return this;")();
|
var __globalObject = Function("return this;")();
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Test if a given function is a constructor function.
|
Test if a given function is a constructor function.
|
||||||
|
defines: [isConstructor]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function isConstructor(f) {
|
function isConstructor(f) {
|
||||||
|
@ -6,6 +6,7 @@ description: |
|
|||||||
to create distinct bit representations on various platforms. These provide a
|
to create distinct bit representations on various platforms. These provide a
|
||||||
weak basis for assertions regarding the consistent canonicalization of NaN
|
weak basis for assertions regarding the consistent canonicalization of NaN
|
||||||
values in Array buffers.
|
values in Array buffers.
|
||||||
|
defines: [NaNs]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
var NaNs = [
|
var NaNs = [
|
||||||
|
@ -8,7 +8,10 @@ info: |
|
|||||||
|
|
||||||
NativeFunction :
|
NativeFunction :
|
||||||
function _IdentifierName_ opt ( _FormalParameters_ ) { [ native code ] }
|
function _IdentifierName_ opt ( _FormalParameters_ ) { [ native code ] }
|
||||||
|
defines:
|
||||||
|
- NATIVE_FUNCTION_RE
|
||||||
|
- assertToStringOrNativeFunction
|
||||||
|
- assertNativeFunction
|
||||||
---*/
|
---*/
|
||||||
const NATIVE_FUNCTION_RE = /\bfunction\b[\s\S]*\([\s\S]*\)[\s\S]*\{[\s\S]*\[[\s\S]*\bnative\b[\s\S]+\bcode\b[\s\S]*\][\s\S]*\}/;
|
const NATIVE_FUNCTION_RE = /\bfunction\b[\s\S]*\([\s\S]*\)[\s\S]*\{[\s\S]*\[[\s\S]*\bnative\b[\s\S]+\bcode\b[\s\S]*\][\s\S]*\}/;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ description: |
|
|||||||
and incrementing by 1 for each entry in the array. Used by
|
and incrementing by 1 for each entry in the array. Used by
|
||||||
Promise tests to assert the order of execution in deep Promise
|
Promise tests to assert the order of execution in deep Promise
|
||||||
resolution pipelines.
|
resolution pipelines.
|
||||||
|
defines: [checkSequence, checkSettledPromises]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function checkSequence(arr, message) {
|
function checkSequence(arr, message) {
|
||||||
|
@ -4,6 +4,15 @@
|
|||||||
description: |
|
description: |
|
||||||
Collection of functions used to safely verify the correctness of
|
Collection of functions used to safely verify the correctness of
|
||||||
property descriptors.
|
property descriptors.
|
||||||
|
defines:
|
||||||
|
- verifyProperty
|
||||||
|
- verifyEqualTo
|
||||||
|
- verifyWritable
|
||||||
|
- verifyNotWritable
|
||||||
|
- verifyEnumerable
|
||||||
|
- verifyNotEnumerable
|
||||||
|
- verifyConfigurable
|
||||||
|
- verifyNotConfigurable
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// @ts-check
|
// @ts-check
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
description: |
|
description: |
|
||||||
Used to assert the correctness of object behavior in the presence
|
Used to assert the correctness of object behavior in the presence
|
||||||
and context of Proxy objects.
|
and context of Proxy objects.
|
||||||
|
defines: [allowProxyTraps]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function allowProxyTraps(overrides) {
|
function allowProxyTraps(overrides) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Collection of functions used to assert the correctness of RegExp objects.
|
Collection of functions used to assert the correctness of RegExp objects.
|
||||||
|
defines: [buildString, testPropertyEscapes, matchValidator]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function buildString({ loneCodePoints, ranges }) {
|
function buildString({ loneCodePoints, ranges }) {
|
||||||
|
@ -6,6 +6,7 @@ description: |
|
|||||||
|
|
||||||
- An error class to avoid false positives when testing for thrown exceptions
|
- An error class to avoid false positives when testing for thrown exceptions
|
||||||
- A function to explicitly throw an exception using the Test262Error class
|
- A function to explicitly throw an exception using the Test262Error class
|
||||||
|
defines: [Test262Error, $ERROR, $DONOTEVALUATE]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ description: |
|
|||||||
This defines the number of consecutive recursive function calls that must be
|
This defines the number of consecutive recursive function calls that must be
|
||||||
made in order to prove that stack frames are properly destroyed according to
|
made in order to prove that stack frames are properly destroyed according to
|
||||||
ES2015 tail call optimization semantics.
|
ES2015 tail call optimization semantics.
|
||||||
|
defines: [$MAX_ITERATIONS]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Collection of functions used to assert the correctness of SharedArrayBuffer objects.
|
Collection of functions used to assert the correctness of SharedArrayBuffer objects.
|
||||||
|
defines:
|
||||||
|
- testWithAtomicsOutOfBoundsIndices
|
||||||
|
- testWithAtomicsInBoundsIndices
|
||||||
|
- testWithAtomicsNonViewValues
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Collection of functions used to assert the correctness of BigInt TypedArray objects.
|
Collection of functions used to assert the correctness of BigInt TypedArray objects.
|
||||||
|
defines: [TypedArray, testWithBigIntTypedArrayConstructors]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -6,8 +6,24 @@ description: |
|
|||||||
This file contains shared functions for the tests in the conformance test
|
This file contains shared functions for the tests in the conformance test
|
||||||
suite for the ECMAScript Internationalization API.
|
suite for the ECMAScript Internationalization API.
|
||||||
author: Norbert Lindenberg
|
author: Norbert Lindenberg
|
||||||
|
defines:
|
||||||
|
- testWithIntlConstructors
|
||||||
|
- taintDataProperty
|
||||||
|
- taintMethod
|
||||||
|
- taintProperties
|
||||||
|
- taintArray
|
||||||
|
- getLocaleSupportInfo
|
||||||
|
- getInvalidLanguageTags
|
||||||
|
- isCanonicalizedStructurallyValidLanguageTag
|
||||||
|
- getInvalidLocaleArguments
|
||||||
|
- testOption
|
||||||
|
- testForUnwantedRegExpChanges
|
||||||
|
- isValidNumberingSystem
|
||||||
|
- testNumberFormat
|
||||||
|
- getDateTimeComponents
|
||||||
|
- getDateTimeComponentValues
|
||||||
|
- isCanonicalizedStructurallyValidTimeZoneName
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -3,6 +3,13 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Collection of functions used to assert the correctness of TypedArray objects.
|
Collection of functions used to assert the correctness of TypedArray objects.
|
||||||
|
defines:
|
||||||
|
- typedArrayConstructors
|
||||||
|
- floatArrayConstructors
|
||||||
|
- intArrayConstructors
|
||||||
|
- TypedArray
|
||||||
|
- testWithTypedArrayConstructors
|
||||||
|
- testTypedArrayConversions
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
Used in website/scripts/sth.js
|
Used in website/scripts/sth.js
|
||||||
|
defines: [setTimeout]
|
||||||
---*/
|
---*/
|
||||||
//setTimeout is not available, hence this script was loaded
|
//setTimeout is not available, hence this script was loaded
|
||||||
if (Promise === undefined && this.setTimeout === undefined) {
|
if (Promise === undefined && this.setTimeout === undefined) {
|
||||||
|
@ -4,6 +4,30 @@
|
|||||||
description: |
|
description: |
|
||||||
Functions to help generate test cases for testing type coercion abstract
|
Functions to help generate test cases for testing type coercion abstract
|
||||||
operations like ToNumber.
|
operations like ToNumber.
|
||||||
|
defines:
|
||||||
|
- testCoercibleToIndexZero
|
||||||
|
- testCoercibleToIndexOne
|
||||||
|
- testCoercibleToIndexFromIndex
|
||||||
|
- testCoercibleToIntegerZero
|
||||||
|
- testCoercibleToIntegerOne
|
||||||
|
- testCoercibleToNumberZero
|
||||||
|
- testCoercibleToNumberNan
|
||||||
|
- testCoercibleToNumberOne
|
||||||
|
- testCoercibleToIntegerFromInteger
|
||||||
|
- testPrimitiveWrappers
|
||||||
|
- testCoercibleToPrimitiveWithMethod
|
||||||
|
- testNotCoercibleToIndex
|
||||||
|
- testNotCoercibleToInteger
|
||||||
|
- testNotCoercibleToNumber
|
||||||
|
- testNotCoercibleToPrimitive
|
||||||
|
- testCoercibleToString
|
||||||
|
- testNotCoercibleToString
|
||||||
|
- testCoercibleToBooleanTrue
|
||||||
|
- testCoercibleToBooleanFalse
|
||||||
|
- testCoercibleToBigIntZero
|
||||||
|
- testCoercibleToBigIntOne
|
||||||
|
- testCoercibleToBigIntFromBigInt
|
||||||
|
- testNotCoercibleToBigInt
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
function testCoercibleToIndexZero(test) {
|
function testCoercibleToIndexZero(test) {
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
/*---
|
/*---
|
||||||
description: |
|
description: |
|
||||||
An Array of all representable Well-Known Intrinsic Objects
|
An Array of all representable Well-Known Intrinsic Objects
|
||||||
|
defines: [WellKnownIntrinsicObjects]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
const WellKnownIntrinsicObjects = [
|
const WellKnownIntrinsicObjects = [
|
||||||
|
65
tools/lint/lib/checks/includes.py
Normal file
65
tools/lint/lib/checks/includes.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import os
|
||||||
|
import re
|
||||||
|
|
||||||
|
from ..check import Check
|
||||||
|
from ..frontmatter import parse
|
||||||
|
|
||||||
|
class CheckIncludes(Check):
|
||||||
|
'''Ensure tests make use of the harness files that they require via the
|
||||||
|
`includes` directive.'''
|
||||||
|
ID = 'INCLUDES'
|
||||||
|
_cache = dict()
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _remove_frontmatter(source):
|
||||||
|
return re.sub(
|
||||||
|
r'/\*---.*---\*/', '', source, flags=re.DOTALL
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _load(include_name):
|
||||||
|
if include_name not in CheckIncludes._cache:
|
||||||
|
with open(os.path.join('harness', include_name), 'r') as f:
|
||||||
|
source = f.read()
|
||||||
|
|
||||||
|
CheckIncludes._cache[include_name] = {
|
||||||
|
'name': include_name,
|
||||||
|
'source': CheckIncludes._remove_frontmatter(source),
|
||||||
|
'defines': parse(source)['defines']
|
||||||
|
}
|
||||||
|
|
||||||
|
return CheckIncludes._cache.get(include_name)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _has_reference(source, names):
|
||||||
|
for name in names:
|
||||||
|
if name in source:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def run(self, name, meta, source):
|
||||||
|
if not meta or 'includes' not in meta:
|
||||||
|
return
|
||||||
|
|
||||||
|
harness_files = [self._load(name) for name in meta['includes']]
|
||||||
|
|
||||||
|
if len(harness_files) == 0:
|
||||||
|
return 'If present, the `includes` tag must have at least one member'
|
||||||
|
|
||||||
|
without_frontmatter = self._remove_frontmatter(source)
|
||||||
|
|
||||||
|
for harness_file in harness_files:
|
||||||
|
if self._has_reference(without_frontmatter, harness_file['defines']):
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If the test file does not reference a value defined by a given
|
||||||
|
# include file, inspect each of the other include files for such a
|
||||||
|
# reference.
|
||||||
|
for other_harness_file in harness_files:
|
||||||
|
if other_harness_file == harness_file:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if self._has_reference(other_harness_file['source'], harness_file['defines']):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return 'Unused include: "%s"' % harness_file['name']
|
@ -37,6 +37,7 @@ from lib.checks.features import CheckFeatures
|
|||||||
from lib.checks.frontmatter import CheckFrontmatter
|
from lib.checks.frontmatter import CheckFrontmatter
|
||||||
from lib.checks.harnessfeatures import CheckHarnessFeatures
|
from lib.checks.harnessfeatures import CheckHarnessFeatures
|
||||||
from lib.checks.harness import CheckHarness
|
from lib.checks.harness import CheckHarness
|
||||||
|
from lib.checks.includes import CheckIncludes
|
||||||
from lib.checks.license import CheckLicense
|
from lib.checks.license import CheckLicense
|
||||||
from lib.checks.negative import CheckNegative
|
from lib.checks.negative import CheckNegative
|
||||||
from lib.checks.filename import CheckFileName
|
from lib.checks.filename import CheckFileName
|
||||||
@ -61,6 +62,7 @@ checks = [
|
|||||||
CheckFeatures('features.txt'),
|
CheckFeatures('features.txt'),
|
||||||
CheckHarnessFeatures(),
|
CheckHarnessFeatures(),
|
||||||
CheckHarness(),
|
CheckHarness(),
|
||||||
|
CheckIncludes(),
|
||||||
CheckLicense(),
|
CheckLicense(),
|
||||||
CheckNegative(),
|
CheckNegative(),
|
||||||
CheckNoPadding(),
|
CheckNoPadding(),
|
||||||
|
5
tools/lint/test/fixtures/features.txt
vendored
Normal file
5
tools/lint/test/fixtures/features.txt
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
async-functions
|
||||||
|
object-spread
|
||||||
|
generators
|
||||||
|
BigInt
|
||||||
|
TypedArray
|
16
tools/lint/test/fixtures/harness/detachArrayBuffer.js
vendored
Normal file
16
tools/lint/test/fixtures/harness/detachArrayBuffer.js
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (C) 2016 the V8 project authors. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
description: |
|
||||||
|
A function used in the process of asserting correctness of TypedArray objects.
|
||||||
|
|
||||||
|
$262.detachArrayBuffer is defined by a host.
|
||||||
|
defines: [$DETACHBUFFER]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function $DETACHBUFFER(buffer) {
|
||||||
|
if (!$262 || typeof $262.detachArrayBuffer !== "function") {
|
||||||
|
throw new Test262Error("No method available to detach an ArrayBuffer");
|
||||||
|
}
|
||||||
|
$262.detachArrayBuffer(buffer);
|
||||||
|
}
|
2
tools/lint/test/fixtures/harness/features.yml
vendored
Normal file
2
tools/lint/test/fixtures/harness/features.yml
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
typeCoercion.js: [Symbol.toPrimitive, BigInt]
|
||||||
|
testTypedArray.js: [TypedArray]
|
229
tools/lint/test/fixtures/harness/propertyHelper.js
vendored
Normal file
229
tools/lint/test/fixtures/harness/propertyHelper.js
vendored
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
// Copyright (C) 2017 Ecma International. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
description: |
|
||||||
|
Collection of functions used to safely verify the correctness of
|
||||||
|
property descriptors.
|
||||||
|
defines:
|
||||||
|
- verifyProperty
|
||||||
|
- verifyEqualTo
|
||||||
|
- verifyWritable
|
||||||
|
- verifyNotWritable
|
||||||
|
- verifyEnumerable
|
||||||
|
- verifyNotEnumerable
|
||||||
|
- verifyConfigurable
|
||||||
|
- verifyNotConfigurable
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {object} obj
|
||||||
|
* @param {string|symbol} name
|
||||||
|
* @param {PropertyDescriptor|undefined} desc
|
||||||
|
* @param {object} [options]
|
||||||
|
* @param {boolean} [options.restore]
|
||||||
|
*/
|
||||||
|
function verifyProperty(obj, name, desc, options) {
|
||||||
|
assert(
|
||||||
|
arguments.length > 2,
|
||||||
|
'verifyProperty should receive at least 3 arguments: obj, name, and descriptor'
|
||||||
|
);
|
||||||
|
|
||||||
|
var originalDesc = Object.getOwnPropertyDescriptor(obj, name);
|
||||||
|
var nameStr = String(name);
|
||||||
|
|
||||||
|
// Allows checking for undefined descriptor if it's explicitly given.
|
||||||
|
if (desc === undefined) {
|
||||||
|
assert.sameValue(
|
||||||
|
originalDesc,
|
||||||
|
undefined,
|
||||||
|
"obj['" + nameStr + "'] descriptor should be undefined"
|
||||||
|
);
|
||||||
|
|
||||||
|
// desc and originalDesc are both undefined, problem solved;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(
|
||||||
|
Object.prototype.hasOwnProperty.call(obj, name),
|
||||||
|
"obj should have an own property " + nameStr
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.notSameValue(
|
||||||
|
desc,
|
||||||
|
null,
|
||||||
|
"The desc argument should be an object or undefined, null"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.sameValue(
|
||||||
|
typeof desc,
|
||||||
|
"object",
|
||||||
|
"The desc argument should be an object or undefined, " + String(desc)
|
||||||
|
);
|
||||||
|
|
||||||
|
var failures = [];
|
||||||
|
|
||||||
|
if (Object.prototype.hasOwnProperty.call(desc, 'value')) {
|
||||||
|
if (!isSameValue(desc.value, originalDesc.value)) {
|
||||||
|
failures.push("descriptor value should be " + desc.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.prototype.hasOwnProperty.call(desc, 'enumerable')) {
|
||||||
|
if (desc.enumerable !== originalDesc.enumerable ||
|
||||||
|
desc.enumerable !== isEnumerable(obj, name)) {
|
||||||
|
failures.push('descriptor should ' + (desc.enumerable ? '' : 'not ') + 'be enumerable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.prototype.hasOwnProperty.call(desc, 'writable')) {
|
||||||
|
if (desc.writable !== originalDesc.writable ||
|
||||||
|
desc.writable !== isWritable(obj, name)) {
|
||||||
|
failures.push('descriptor should ' + (desc.writable ? '' : 'not ') + 'be writable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Object.prototype.hasOwnProperty.call(desc, 'configurable')) {
|
||||||
|
if (desc.configurable !== originalDesc.configurable ||
|
||||||
|
desc.configurable !== isConfigurable(obj, name)) {
|
||||||
|
failures.push('descriptor should ' + (desc.configurable ? '' : 'not ') + 'be configurable');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!failures.length, failures.join('; '));
|
||||||
|
|
||||||
|
if (options && options.restore) {
|
||||||
|
Object.defineProperty(obj, name, originalDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isConfigurable(obj, name) {
|
||||||
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||||
|
try {
|
||||||
|
delete obj[name];
|
||||||
|
} catch (e) {
|
||||||
|
if (!(e instanceof TypeError)) {
|
||||||
|
$ERROR("Expected TypeError, got " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !hasOwnProperty.call(obj, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEnumerable(obj, name) {
|
||||||
|
var stringCheck = false;
|
||||||
|
|
||||||
|
if (typeof name === "string") {
|
||||||
|
for (var x in obj) {
|
||||||
|
if (x === name) {
|
||||||
|
stringCheck = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// skip it if name is not string, works for Symbol names.
|
||||||
|
stringCheck = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringCheck &&
|
||||||
|
Object.prototype.hasOwnProperty.call(obj, name) &&
|
||||||
|
Object.prototype.propertyIsEnumerable.call(obj, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSameValue(a, b) {
|
||||||
|
if (a === 0 && b === 0) return 1 / a === 1 / b;
|
||||||
|
if (a !== a && b !== b) return true;
|
||||||
|
|
||||||
|
return a === b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isWritable(obj, name, verifyProp, value) {
|
||||||
|
var newValue = value || "unlikelyValue";
|
||||||
|
var hadValue = Object.prototype.hasOwnProperty.call(obj, name);
|
||||||
|
var oldValue = obj[name];
|
||||||
|
var writeSucceeded;
|
||||||
|
|
||||||
|
try {
|
||||||
|
obj[name] = newValue;
|
||||||
|
} catch (e) {
|
||||||
|
if (!(e instanceof TypeError)) {
|
||||||
|
$ERROR("Expected TypeError, got " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
writeSucceeded = isSameValue(obj[verifyProp || name], newValue);
|
||||||
|
|
||||||
|
// Revert the change only if it was successful (in other cases, reverting
|
||||||
|
// is unnecessary and may trigger exceptions for certain property
|
||||||
|
// configurations)
|
||||||
|
if (writeSucceeded) {
|
||||||
|
if (hadValue) {
|
||||||
|
obj[name] = oldValue;
|
||||||
|
} else {
|
||||||
|
delete obj[name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeSucceeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyEqualTo(obj, name, value) {
|
||||||
|
if (!isSameValue(obj[name], value)) {
|
||||||
|
$ERROR("Expected obj[" + String(name) + "] to equal " + value +
|
||||||
|
", actually " + obj[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyWritable(obj, name, verifyProp, value) {
|
||||||
|
if (!verifyProp) {
|
||||||
|
assert(Object.getOwnPropertyDescriptor(obj, name).writable,
|
||||||
|
"Expected obj[" + String(name) + "] to have writable:true.");
|
||||||
|
}
|
||||||
|
if (!isWritable(obj, name, verifyProp, value)) {
|
||||||
|
$ERROR("Expected obj[" + String(name) + "] to be writable, but was not.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyNotWritable(obj, name, verifyProp, value) {
|
||||||
|
if (!verifyProp) {
|
||||||
|
assert(!Object.getOwnPropertyDescriptor(obj, name).writable,
|
||||||
|
"Expected obj[" + String(name) + "] to have writable:false.");
|
||||||
|
}
|
||||||
|
if (isWritable(obj, name, verifyProp)) {
|
||||||
|
$ERROR("Expected obj[" + String(name) + "] NOT to be writable, but was.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyEnumerable(obj, name) {
|
||||||
|
assert(Object.getOwnPropertyDescriptor(obj, name).enumerable,
|
||||||
|
"Expected obj[" + String(name) + "] to have enumerable:true.");
|
||||||
|
if (!isEnumerable(obj, name)) {
|
||||||
|
$ERROR("Expected obj[" + String(name) + "] to be enumerable, but was not.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyNotEnumerable(obj, name) {
|
||||||
|
assert(!Object.getOwnPropertyDescriptor(obj, name).enumerable,
|
||||||
|
"Expected obj[" + String(name) + "] to have enumerable:false.");
|
||||||
|
if (isEnumerable(obj, name)) {
|
||||||
|
$ERROR("Expected obj[" + String(name) + "] NOT to be enumerable, but was.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyConfigurable(obj, name) {
|
||||||
|
assert(Object.getOwnPropertyDescriptor(obj, name).configurable,
|
||||||
|
"Expected obj[" + String(name) + "] to have configurable:true.");
|
||||||
|
if (!isConfigurable(obj, name)) {
|
||||||
|
$ERROR("Expected obj[" + String(name) + "] to be configurable, but was not.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyNotConfigurable(obj, name) {
|
||||||
|
assert(!Object.getOwnPropertyDescriptor(obj, name).configurable,
|
||||||
|
"Expected obj[" + String(name) + "] to have configurable:false.");
|
||||||
|
if (isConfigurable(obj, name)) {
|
||||||
|
$ERROR("Expected obj[" + String(name) + "] NOT to be configurable, but was.");
|
||||||
|
}
|
||||||
|
}
|
89
tools/lint/test/fixtures/harness/testTypedArray.js
vendored
Normal file
89
tools/lint/test/fixtures/harness/testTypedArray.js
vendored
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright (C) 2015 André Bargull. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
description: |
|
||||||
|
Collection of functions used to assert the correctness of TypedArray objects.
|
||||||
|
defines:
|
||||||
|
- typedArrayConstructors
|
||||||
|
- floatArrayConstructors
|
||||||
|
- intArrayConstructors
|
||||||
|
- TypedArray
|
||||||
|
- testWithTypedArrayConstructors
|
||||||
|
- testTypedArrayConversions
|
||||||
|
---*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array containing every typed array constructor.
|
||||||
|
*/
|
||||||
|
var typedArrayConstructors = [
|
||||||
|
Float64Array,
|
||||||
|
Float32Array,
|
||||||
|
Int32Array,
|
||||||
|
Int16Array,
|
||||||
|
Int8Array,
|
||||||
|
Uint32Array,
|
||||||
|
Uint16Array,
|
||||||
|
Uint8Array,
|
||||||
|
Uint8ClampedArray
|
||||||
|
];
|
||||||
|
|
||||||
|
var floatArrayConstructors = typedArrayConstructors.slice(0, 2);
|
||||||
|
var intArrayConstructors = typedArrayConstructors.slice(2, 7);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The %TypedArray% intrinsic constructor function.
|
||||||
|
*/
|
||||||
|
var TypedArray = Object.getPrototypeOf(Int8Array);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for testing a typed array constructor.
|
||||||
|
*
|
||||||
|
* @callback typedArrayConstructorCallback
|
||||||
|
* @param {Function} Constructor the constructor object to test with.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the provided function for every typed array constructor.
|
||||||
|
*
|
||||||
|
* @param {typedArrayConstructorCallback} f - the function to call for each typed array constructor.
|
||||||
|
* @param {Array} selected - An optional Array with filtered typed arrays
|
||||||
|
*/
|
||||||
|
function testWithTypedArrayConstructors(f, selected) {
|
||||||
|
var constructors = selected || typedArrayConstructors;
|
||||||
|
for (var i = 0; i < constructors.length; ++i) {
|
||||||
|
var constructor = constructors[i];
|
||||||
|
try {
|
||||||
|
f(constructor);
|
||||||
|
} catch (e) {
|
||||||
|
e.message += " (Testing with " + constructor.name + ".)";
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper for conversion operations on TypedArrays, the expected values
|
||||||
|
* properties are indexed in order to match the respective value for each
|
||||||
|
* TypedArray constructor
|
||||||
|
* @param {Function} fn - the function to call for each constructor and value.
|
||||||
|
* will be called with the constructor, value, expected
|
||||||
|
* value, and a initial value that can be used to avoid
|
||||||
|
* a false positive with an equivalent expected value.
|
||||||
|
*/
|
||||||
|
function testTypedArrayConversions(byteConversionValues, fn) {
|
||||||
|
var values = byteConversionValues.values;
|
||||||
|
var expected = byteConversionValues.expected;
|
||||||
|
|
||||||
|
testWithTypedArrayConstructors(function(TA) {
|
||||||
|
var name = TA.name.slice(0, -5);
|
||||||
|
|
||||||
|
return values.forEach(function(value, index) {
|
||||||
|
var exp = expected[name][index];
|
||||||
|
var initial = 0;
|
||||||
|
if (exp === 0) {
|
||||||
|
initial = 1;
|
||||||
|
}
|
||||||
|
fn(TA, value, exp, initial);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
451
tools/lint/test/fixtures/harness/typeCoercion.js
vendored
Normal file
451
tools/lint/test/fixtures/harness/typeCoercion.js
vendored
Normal file
@ -0,0 +1,451 @@
|
|||||||
|
// Copyright (C) 2017 Josh Wolfe. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
description: |
|
||||||
|
Functions to help generate test cases for testing type coercion abstract
|
||||||
|
operations like ToNumber.
|
||||||
|
defines:
|
||||||
|
- testCoercibleToIndexZero
|
||||||
|
- testCoercibleToIndexOne
|
||||||
|
- testCoercibleToIndexFromIndex
|
||||||
|
- testCoercibleToIntegerZero
|
||||||
|
- testCoercibleToIntegerOne
|
||||||
|
- testCoercibleToNumberZero
|
||||||
|
- testCoercibleToNumberNan
|
||||||
|
- testCoercibleToNumberOne
|
||||||
|
- testCoercibleToIntegerFromInteger
|
||||||
|
- testPrimitiveWrappers
|
||||||
|
- testCoercibleToPrimitiveWithMethod
|
||||||
|
- testNotCoercibleToIndex
|
||||||
|
- testNotCoercibleToInteger
|
||||||
|
- testNotCoercibleToNumber
|
||||||
|
- testNotCoercibleToPrimitive
|
||||||
|
- testCoercibleToString
|
||||||
|
- testNotCoercibleToString
|
||||||
|
- testCoercibleToBooleanTrue
|
||||||
|
- testCoercibleToBooleanFalse
|
||||||
|
- testCoercibleToBigIntZero
|
||||||
|
- testCoercibleToBigIntOne
|
||||||
|
- testCoercibleToBigIntFromBigInt
|
||||||
|
- testNotCoercibleToBigInt
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function testCoercibleToIndexZero(test) {
|
||||||
|
testCoercibleToIntegerZero(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToIndexOne(test) {
|
||||||
|
testCoercibleToIntegerOne(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToIndexFromIndex(nominalIndex, test) {
|
||||||
|
assert(Number.isInteger(nominalIndex));
|
||||||
|
assert(0 <= nominalIndex && nominalIndex <= 2**53 - 1);
|
||||||
|
testCoercibleToIntegerFromInteger(nominalIndex, test);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToIntegerZero(test) {
|
||||||
|
testCoercibleToNumberZero(test);
|
||||||
|
|
||||||
|
testCoercibleToIntegerFromInteger(0, test);
|
||||||
|
|
||||||
|
// NaN -> +0
|
||||||
|
testCoercibleToNumberNan(test);
|
||||||
|
|
||||||
|
// When toString() returns a string that parses to NaN:
|
||||||
|
test({});
|
||||||
|
test([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToIntegerOne(test) {
|
||||||
|
testCoercibleToNumberOne(test);
|
||||||
|
|
||||||
|
testCoercibleToIntegerFromInteger(1, test);
|
||||||
|
|
||||||
|
// When toString() returns "1"
|
||||||
|
test([1]);
|
||||||
|
test(["1"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToNumberZero(test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
testPrimitiveValue(null);
|
||||||
|
testPrimitiveValue(false);
|
||||||
|
testPrimitiveValue(0);
|
||||||
|
testPrimitiveValue("0");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToNumberNan(test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
testPrimitiveValue(undefined);
|
||||||
|
testPrimitiveValue(NaN);
|
||||||
|
testPrimitiveValue("");
|
||||||
|
testPrimitiveValue("foo");
|
||||||
|
testPrimitiveValue("true");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToNumberOne(test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
testPrimitiveValue(true);
|
||||||
|
testPrimitiveValue(1);
|
||||||
|
testPrimitiveValue("1");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToIntegerFromInteger(nominalInteger, test) {
|
||||||
|
assert(Number.isInteger(nominalInteger));
|
||||||
|
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", test);
|
||||||
|
|
||||||
|
// Non-primitive values that coerce to the nominal integer:
|
||||||
|
// toString() returns a string that parsers to a primitive value.
|
||||||
|
test([value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPrimitiveNumber(number) {
|
||||||
|
testPrimitiveValue(number);
|
||||||
|
// ToNumber: String -> Number
|
||||||
|
testPrimitiveValue(number.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
testPrimitiveNumber(nominalInteger);
|
||||||
|
|
||||||
|
// ToInteger: floor(abs(number))
|
||||||
|
if (nominalInteger >= 0) {
|
||||||
|
testPrimitiveNumber(nominalInteger + 0.9);
|
||||||
|
}
|
||||||
|
if (nominalInteger <= 0) {
|
||||||
|
testPrimitiveNumber(nominalInteger - 0.9);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function testPrimitiveWrappers(primitiveValue, hint, test) {
|
||||||
|
if (primitiveValue != null) {
|
||||||
|
// null and undefined result in {} rather than a proper wrapper,
|
||||||
|
// so skip this case for those values.
|
||||||
|
test(Object(primitiveValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
testCoercibleToPrimitiveWithMethod(hint, function() {
|
||||||
|
return primitiveValue;
|
||||||
|
}, test);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToPrimitiveWithMethod(hint, method, test) {
|
||||||
|
var methodNames;
|
||||||
|
if (hint === "number") {
|
||||||
|
methodNames = ["valueOf", "toString"];
|
||||||
|
} else if (hint === "string") {
|
||||||
|
methodNames = ["toString", "valueOf"];
|
||||||
|
} else {
|
||||||
|
throw new Test262Error();
|
||||||
|
}
|
||||||
|
// precedence order
|
||||||
|
test({
|
||||||
|
[Symbol.toPrimitive]: method,
|
||||||
|
[methodNames[0]]: function() { throw new Test262Error(); },
|
||||||
|
[methodNames[1]]: function() { throw new Test262Error(); },
|
||||||
|
});
|
||||||
|
test({
|
||||||
|
[methodNames[0]]: method,
|
||||||
|
[methodNames[1]]: function() { throw new Test262Error(); },
|
||||||
|
});
|
||||||
|
if (hint === "number") {
|
||||||
|
// The default valueOf returns an object, which is unsuitable.
|
||||||
|
// The default toString returns a String, which is suitable.
|
||||||
|
// Therefore this test only works for valueOf falling back to toString.
|
||||||
|
test({
|
||||||
|
// this is toString:
|
||||||
|
[methodNames[1]]: method,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMethod: if func is undefined or null, return undefined.
|
||||||
|
test({
|
||||||
|
[Symbol.toPrimitive]: undefined,
|
||||||
|
[methodNames[0]]: method,
|
||||||
|
[methodNames[1]]: method,
|
||||||
|
});
|
||||||
|
test({
|
||||||
|
[Symbol.toPrimitive]: null,
|
||||||
|
[methodNames[0]]: method,
|
||||||
|
[methodNames[1]]: method,
|
||||||
|
});
|
||||||
|
|
||||||
|
// if methodNames[0] is not callable, fallback to methodNames[1]
|
||||||
|
test({
|
||||||
|
[methodNames[0]]: null,
|
||||||
|
[methodNames[1]]: method,
|
||||||
|
});
|
||||||
|
test({
|
||||||
|
[methodNames[0]]: 1,
|
||||||
|
[methodNames[1]]: method,
|
||||||
|
});
|
||||||
|
test({
|
||||||
|
[methodNames[0]]: {},
|
||||||
|
[methodNames[1]]: method,
|
||||||
|
});
|
||||||
|
|
||||||
|
// if methodNames[0] returns an object, fallback to methodNames[1]
|
||||||
|
test({
|
||||||
|
[methodNames[0]]: function() { return {}; },
|
||||||
|
[methodNames[1]]: method,
|
||||||
|
});
|
||||||
|
test({
|
||||||
|
[methodNames[0]]: function() { return Object(1); },
|
||||||
|
[methodNames[1]]: method,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNotCoercibleToIndex(test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(RangeError, value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", function(value) {
|
||||||
|
test(RangeError, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let integerIndex be ? ToInteger(value).
|
||||||
|
testNotCoercibleToInteger(test);
|
||||||
|
|
||||||
|
// If integerIndex < 0, throw a RangeError exception.
|
||||||
|
testPrimitiveValue(-1);
|
||||||
|
testPrimitiveValue(-2.5);
|
||||||
|
testPrimitiveValue("-2.5");
|
||||||
|
testPrimitiveValue(-Infinity);
|
||||||
|
|
||||||
|
// Let index be ! ToLength(integerIndex).
|
||||||
|
// If SameValueZero(integerIndex, index) is false, throw a RangeError exception.
|
||||||
|
testPrimitiveValue(2 ** 53);
|
||||||
|
testPrimitiveValue(Infinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNotCoercibleToInteger(test) {
|
||||||
|
// ToInteger only throws from ToNumber.
|
||||||
|
testNotCoercibleToNumber(test);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNotCoercibleToNumber(test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(TypeError, value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", function(value) {
|
||||||
|
test(TypeError, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToNumber: Symbol -> TypeError
|
||||||
|
testPrimitiveValue(Symbol("1"));
|
||||||
|
|
||||||
|
if (typeof BigInt !== "undefined") {
|
||||||
|
// ToNumber: BigInt -> TypeError
|
||||||
|
testPrimitiveValue(BigInt(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToPrimitive
|
||||||
|
testNotCoercibleToPrimitive("number", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNotCoercibleToPrimitive(hint, test) {
|
||||||
|
function MyError() {}
|
||||||
|
|
||||||
|
// ToPrimitive: input[@@toPrimitive] is not callable (and non-null)
|
||||||
|
test(TypeError, {[Symbol.toPrimitive]: 1});
|
||||||
|
test(TypeError, {[Symbol.toPrimitive]: {}});
|
||||||
|
|
||||||
|
// ToPrimitive: input[@@toPrimitive] returns object
|
||||||
|
test(TypeError, {[Symbol.toPrimitive]: function() { return Object(1); }});
|
||||||
|
test(TypeError, {[Symbol.toPrimitive]: function() { return {}; }});
|
||||||
|
|
||||||
|
// ToPrimitive: input[@@toPrimitive] throws
|
||||||
|
test(MyError, {[Symbol.toPrimitive]: function() { throw new MyError(); }});
|
||||||
|
|
||||||
|
// OrdinaryToPrimitive: method throws
|
||||||
|
testCoercibleToPrimitiveWithMethod(hint, function() {
|
||||||
|
throw new MyError();
|
||||||
|
}, function(value) {
|
||||||
|
test(MyError, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
// OrdinaryToPrimitive: both methods are unsuitable
|
||||||
|
function testUnsuitableMethod(method) {
|
||||||
|
test(TypeError, {valueOf:method, toString:method});
|
||||||
|
}
|
||||||
|
// not callable:
|
||||||
|
testUnsuitableMethod(null);
|
||||||
|
testUnsuitableMethod(1);
|
||||||
|
testUnsuitableMethod({});
|
||||||
|
// returns object:
|
||||||
|
testUnsuitableMethod(function() { return Object(1); });
|
||||||
|
testUnsuitableMethod(function() { return {}; });
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToString(test) {
|
||||||
|
function testPrimitiveValue(value, expectedString) {
|
||||||
|
test(value, expectedString);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "string", function(value) {
|
||||||
|
test(value, expectedString);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
testPrimitiveValue(undefined, "undefined");
|
||||||
|
testPrimitiveValue(null, "null");
|
||||||
|
testPrimitiveValue(true, "true");
|
||||||
|
testPrimitiveValue(false, "false");
|
||||||
|
testPrimitiveValue(0, "0");
|
||||||
|
testPrimitiveValue(-0, "0");
|
||||||
|
testPrimitiveValue(Infinity, "Infinity");
|
||||||
|
testPrimitiveValue(-Infinity, "-Infinity");
|
||||||
|
testPrimitiveValue(123.456, "123.456");
|
||||||
|
testPrimitiveValue(-123.456, "-123.456");
|
||||||
|
testPrimitiveValue("", "");
|
||||||
|
testPrimitiveValue("foo", "foo");
|
||||||
|
|
||||||
|
if (typeof BigInt !== "undefined") {
|
||||||
|
// BigInt -> TypeError
|
||||||
|
testPrimitiveValue(BigInt(0), "0");
|
||||||
|
}
|
||||||
|
|
||||||
|
// toString of a few objects
|
||||||
|
test([], "");
|
||||||
|
test(["foo", "bar"], "foo,bar");
|
||||||
|
test({}, "[object Object]");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNotCoercibleToString(test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(TypeError, value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "string", function(value) {
|
||||||
|
test(TypeError, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Symbol -> TypeError
|
||||||
|
testPrimitiveValue(Symbol("1"));
|
||||||
|
|
||||||
|
// ToPrimitive
|
||||||
|
testNotCoercibleToPrimitive("string", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToBooleanTrue(test) {
|
||||||
|
test(true);
|
||||||
|
test(1);
|
||||||
|
test("string");
|
||||||
|
test(Symbol("1"));
|
||||||
|
test({});
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToBooleanFalse(test) {
|
||||||
|
test(undefined);
|
||||||
|
test(null);
|
||||||
|
test(false);
|
||||||
|
test(0);
|
||||||
|
test(-0);
|
||||||
|
test(NaN);
|
||||||
|
test("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToBigIntZero(test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
testCoercibleToBigIntFromBigInt(BigInt(0), test);
|
||||||
|
testPrimitiveValue(-BigInt(0));
|
||||||
|
testPrimitiveValue("-0");
|
||||||
|
testPrimitiveValue(false);
|
||||||
|
testPrimitiveValue("");
|
||||||
|
testPrimitiveValue(" ");
|
||||||
|
|
||||||
|
// toString() returns ""
|
||||||
|
test([]);
|
||||||
|
|
||||||
|
// toString() returns "0"
|
||||||
|
test([0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToBigIntOne(test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
testCoercibleToBigIntFromBigInt(BigInt(1), test);
|
||||||
|
testPrimitiveValue(true);
|
||||||
|
|
||||||
|
// toString() returns "1"
|
||||||
|
test([1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testCoercibleToBigIntFromBigInt(nominalBigInt, test) {
|
||||||
|
function testPrimitiveValue(value) {
|
||||||
|
test(value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", test);
|
||||||
|
}
|
||||||
|
|
||||||
|
testPrimitiveValue(nominalBigInt);
|
||||||
|
testPrimitiveValue(nominalBigInt.toString());
|
||||||
|
testPrimitiveValue("0b" + nominalBigInt.toString(2));
|
||||||
|
testPrimitiveValue("0o" + nominalBigInt.toString(8));
|
||||||
|
testPrimitiveValue("0x" + nominalBigInt.toString(16));
|
||||||
|
testPrimitiveValue(" " + nominalBigInt.toString() + " ");
|
||||||
|
|
||||||
|
// toString() returns the decimal string representation
|
||||||
|
test([nominalBigInt]);
|
||||||
|
test([nominalBigInt.toString()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testNotCoercibleToBigInt(test) {
|
||||||
|
function testPrimitiveValue(error, value) {
|
||||||
|
test(error, value);
|
||||||
|
// ToPrimitive
|
||||||
|
testPrimitiveWrappers(value, "number", function(value) {
|
||||||
|
test(error, value);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Undefined, Null, Number, Symbol -> TypeError
|
||||||
|
testPrimitiveValue(TypeError, undefined);
|
||||||
|
testPrimitiveValue(TypeError, null);
|
||||||
|
testPrimitiveValue(TypeError, 0);
|
||||||
|
testPrimitiveValue(TypeError, NaN);
|
||||||
|
testPrimitiveValue(TypeError, Infinity);
|
||||||
|
testPrimitiveValue(TypeError, Symbol("1"));
|
||||||
|
|
||||||
|
// when a String parses to NaN -> SyntaxError
|
||||||
|
function testStringValue(string) {
|
||||||
|
testPrimitiveValue(SyntaxError, string);
|
||||||
|
testPrimitiveValue(SyntaxError, " " + string);
|
||||||
|
testPrimitiveValue(SyntaxError, string + " ");
|
||||||
|
testPrimitiveValue(SyntaxError, " " + string + " ");
|
||||||
|
}
|
||||||
|
testStringValue("a");
|
||||||
|
testStringValue("0b2");
|
||||||
|
testStringValue("0o8");
|
||||||
|
testStringValue("0xg");
|
||||||
|
testStringValue("1n");
|
||||||
|
}
|
13
tools/lint/test/fixtures/harness/usesDetachArrayBuffer.js
vendored
Normal file
13
tools/lint/test/fixtures/harness/usesDetachArrayBuffer.js
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (C) 2019 Mike Pennisi. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
description: |
|
||||||
|
A function used in the process of asserting correctness of TypedArray objects.
|
||||||
|
|
||||||
|
$262.detachArrayBuffer is defined by a host.
|
||||||
|
defines: [modifiedDetachArrayBuffer]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
function modifiedDetachArrayBuffer(buffer) {
|
||||||
|
return $DETACHBUFFER(buffer);
|
||||||
|
}
|
@ -8,4 +8,4 @@ features: [TypedArray]
|
|||||||
includes: [testTypedArray.js]
|
includes: [testTypedArray.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
// empty
|
intArrayConstructors;
|
||||||
|
@ -5,7 +5,7 @@ HARNESS - verifyConfigurable & verifyProperty may not be used in the same file
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-whatever
|
esid: sec-whatever
|
||||||
description: Minimal test
|
description: Minimal test
|
||||||
includes: [verifyProperty.js]
|
includes: [propertyHelper.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
verifyConfigurable(Object, '');
|
verifyConfigurable(Object, '');
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
/*---
|
/*---
|
||||||
esid: sec-whatever
|
esid: sec-whatever
|
||||||
description: Minimal test
|
description: Minimal test
|
||||||
includes: [verifyProperty.js]
|
includes: [propertyHelper.js]
|
||||||
---*/
|
---*/
|
||||||
|
|
||||||
verifyConfigurable(Object, '');
|
verifyConfigurable(Object, '');
|
||||||
|
11
tools/lint/test/fixtures/includes_invalid_empty.js
vendored
Normal file
11
tools/lint/test/fixtures/includes_invalid_empty.js
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
INCLUDES
|
||||||
|
^ expected errors | v input
|
||||||
|
// Copyright (C) 2019 Mike Pennisi. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-assignment-operators-static-semantics-early-errors
|
||||||
|
description: Minimal test
|
||||||
|
includes: []
|
||||||
|
---*/
|
||||||
|
|
||||||
|
void 0;
|
16
tools/lint/test/fixtures/includes_invalid_noref.js
vendored
Normal file
16
tools/lint/test/fixtures/includes_invalid_noref.js
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
INCLUDES
|
||||||
|
^ expected errors | v input
|
||||||
|
// Copyright (C) 2019 Mike Pennisi. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-assignment-operators-static-semantics-early-errors
|
||||||
|
description: Minimal test
|
||||||
|
includes: [detachArrayBuffer.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// This file doesn't reference any names defined by the "include" file. It
|
||||||
|
// contains some references that don't match exactly in order to verify that
|
||||||
|
// the linter is not susceptible to false positives.
|
||||||
|
DETACHBUFFER();
|
||||||
|
$DETACHBUFFE();
|
||||||
|
$DETACH_BUFFER();
|
10
tools/lint/test/fixtures/includes_valid_direct.js
vendored
Normal file
10
tools/lint/test/fixtures/includes_valid_direct.js
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
^ expected errors | v input
|
||||||
|
// Copyright (C) 2019 Mike Pennisi. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-assignment-operators-static-semantics-early-errors
|
||||||
|
description: Minimal test
|
||||||
|
includes: [detachArrayBuffer.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
$DETACHBUFFER();
|
13
tools/lint/test/fixtures/includes_valid_indirect.js
vendored
Normal file
13
tools/lint/test/fixtures/includes_valid_indirect.js
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
^ expected errors | v input
|
||||||
|
// Copyright (C) 2019 Mike Pennisi. All rights reserved.
|
||||||
|
// This code is governed by the BSD license found in the LICENSE file.
|
||||||
|
/*---
|
||||||
|
esid: sec-assignment-operators-static-semantics-early-errors
|
||||||
|
description: Minimal test
|
||||||
|
includes: [detachArrayBuffer.js, usesDetachArrayBuffer.js]
|
||||||
|
---*/
|
||||||
|
|
||||||
|
// This file doesn't reference any names defined by the first "include" file,
|
||||||
|
// but the second "include" file does.
|
||||||
|
|
||||||
|
modifiedDetachArrayBuffer();
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import shutil, subprocess, sys, os, unittest, tempfile
|
import shutil, subprocess, sys, os, unittest, tempfile
|
||||||
|
|
||||||
testDir = os.path.dirname(os.path.relpath(__file__))
|
testDir = os.path.dirname(os.path.abspath(__file__))
|
||||||
OUT_DIR = os.path.join(testDir, 'out')
|
OUT_DIR = os.path.join(testDir, 'out')
|
||||||
ex = os.path.join(testDir, '..', 'lint.py')
|
ex = os.path.join(testDir, '..', 'lint.py')
|
||||||
|
|
||||||
@ -19,7 +19,11 @@ class TestLinter(unittest.TestCase):
|
|||||||
|
|
||||||
def lint(self, args):
|
def lint(self, args):
|
||||||
args[:0] = [ex]
|
args[:0] = [ex]
|
||||||
sp = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
sp = subprocess.Popen(args,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE,
|
||||||
|
cwd=os.path.join(testDir, 'fixtures')
|
||||||
|
)
|
||||||
stdout, stderr = sp.communicate()
|
stdout, stderr = sp.communicate()
|
||||||
return dict(stdout=stdout, stderr=stderr, returncode=sp.returncode)
|
return dict(stdout=stdout, stderr=stderr, returncode=sp.returncode)
|
||||||
|
|
||||||
@ -85,16 +89,17 @@ def create_file_test(name, fspath):
|
|||||||
for err in expected:
|
for err in expected:
|
||||||
self.assertIn(err, stderr)
|
self.assertIn(err, stderr)
|
||||||
|
|
||||||
|
test.__name__ = 'test_' + file_name.split('.')[0]
|
||||||
return test
|
return test
|
||||||
|
|
||||||
dirname = os.path.join(os.path.abspath(testDir), 'fixtures')
|
dirname = os.path.join(os.path.abspath(testDir), 'fixtures')
|
||||||
for file_name in os.listdir(dirname):
|
for file_name in os.listdir(dirname):
|
||||||
full_path = os.path.join(dirname, file_name)
|
full_path = os.path.join(dirname, file_name)
|
||||||
if not os.path.isfile(full_path) or file_name.startswith('.'):
|
if (not os.path.isfile(full_path) or file_name.startswith('.') or
|
||||||
|
not file_name.endswith('.js')):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
t = create_file_test(file_name, full_path)
|
t = create_file_test(file_name, full_path)
|
||||||
t.__name__ = 'test_' + file_name
|
|
||||||
setattr(TestLinter, t.__name__, t)
|
setattr(TestLinter, t.__name__, t)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
x
Reference in New Issue
Block a user