diff --git a/harness/features.yml b/harness/features.yml new file mode 100644 index 0000000000..34a3a0bfa9 --- /dev/null +++ b/harness/features.yml @@ -0,0 +1,3 @@ +propertyHelper.js: [template] +typeCoercion.js: [Symbol.toPrimitive,BigInt] +testTypedArray.js: [TypedArray] diff --git a/tools/lint/lib/check.py b/tools/lint/lib/check.py index 3130728224..45bbaa3140 100644 --- a/tools/lint/lib/check.py +++ b/tools/lint/lib/check.py @@ -1,5 +1,5 @@ class Check(object): - '''Base class for defining linting checks.''' + '''Base class for defining linting checks.''' ID = None def run(self, name, meta, source): diff --git a/tools/lint/lib/checks/harnessfeatures.py b/tools/lint/lib/checks/harnessfeatures.py new file mode 100644 index 0000000000..8115b51cd5 --- /dev/null +++ b/tools/lint/lib/checks/harnessfeatures.py @@ -0,0 +1,59 @@ +import yaml + +from ..check import Check + +class CheckHarnessFeatures(Check): + '''Ensure tests that use harnesses with explicit features flag requirements + specify only `features` from a list of valid values.''' + ID = 'HARNESS_FEATURES' + + def __init__(self): + with open('./harness/features.yml', 'r') as f: + self.include_has_features = yaml.load(f.read()) + + def comparison_result_lists(self, meta): + + result = {'features': set(), 'missing': set()} + meta_features = meta['features'] if 'features' in meta else [] + meta_includes = meta['includes'] + features = [] + + if not meta or 'includes' not in meta: + return result + + if len(meta_includes) == 0: + return result + + for meta_include in meta_includes: + if meta_include in self.include_has_features: + features = self.include_has_features[meta_include] + + if len(features) == 0: + return result + + if 'features' not in meta or len(meta['features']) == 0: + result['missing'].update(features) + else: + meta_features = meta['features'] + + for feature in features: + if feature not in meta_features: + result['missing'].add(feature) + + result['features'].update(meta_features); + + return result + + + def run(self, name, meta, source): + + result = self.comparison_result_lists(meta) + + if len(result['features']) == 0 and len(result['missing']) == 0: + return + + if len(result['missing']) > 0: + if len(result['features']) == 0: + return 'Missing: `features: [%s]`' % ', '.join(list(result['missing'])) + else: + return 'Missing from `features`: %s' % ', '.join(list(result['missing'])) diff --git a/tools/lint/lint.py b/tools/lint/lint.py index 09e22507a0..9c446b5bb9 100755 --- a/tools/lint/lint.py +++ b/tools/lint/lint.py @@ -7,6 +7,7 @@ import sys from lib.collect_files import collect_files from lib.checks.features import CheckFeatures +from lib.checks.harnessfeatures import CheckHarnessFeatures from lib.checks.frontmatter import CheckFrontmatter from lib.checks.license import CheckLicense from lib.checks.negative import CheckNegative @@ -23,7 +24,10 @@ parser.add_argument('path', help='file name or directory of files to lint') checks = [ - CheckFrontmatter(), CheckFeatures('features.txt'), CheckLicense(), + CheckFrontmatter(), + CheckFeatures('features.txt'), + CheckHarnessFeatures(), + CheckLicense(), CheckNegative() ] diff --git a/tools/lint/test/fixtures/harness_features_empty.js b/tools/lint/test/fixtures/harness_features_empty.js new file mode 100644 index 0000000000..2fc5bae129 --- /dev/null +++ b/tools/lint/test/fixtures/harness_features_empty.js @@ -0,0 +1,12 @@ +HARNESS_FEATURES - Missing Frontmatter: `features: [TypedArray]` +^ expected errors | v input +// Copyright (C) 2017 Rick Waldron. 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 +features: [] +includes: [testTypedArray.js] +---*/ + +// empty diff --git a/tools/lint/test/fixtures/harness_features_multiple_includes.js b/tools/lint/test/fixtures/harness_features_multiple_includes.js new file mode 100644 index 0000000000..c9cabb8d71 --- /dev/null +++ b/tools/lint/test/fixtures/harness_features_multiple_includes.js @@ -0,0 +1,11 @@ +HARNESS_FEATURES - Missing Frontmatter: `features: [TypedArray, template] +^ expected errors | v input +// Copyright (C) 2017 Rick Waldron. 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: [testTypedArray.js, compareArray.js] +---*/ + +// empty diff --git a/tools/lint/test/fixtures/harness_features_partial.js b/tools/lint/test/fixtures/harness_features_partial.js new file mode 100644 index 0000000000..4d6a15c551 --- /dev/null +++ b/tools/lint/test/fixtures/harness_features_partial.js @@ -0,0 +1,12 @@ +HARNESS_FEATURES - Missing from `features`: Symbol.toPrimitive +^ expected errors | v input +// Copyright (C) 2017 Rick Waldron. 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 +features: [BigInt] +includes: [typeCoercion.js] +---*/ + +// empty diff --git a/tools/lint/test/fixtures/harness_features_valid.js b/tools/lint/test/fixtures/harness_features_valid.js new file mode 100644 index 0000000000..4f92cf54eb --- /dev/null +++ b/tools/lint/test/fixtures/harness_features_valid.js @@ -0,0 +1,11 @@ +^ expected errors | v input +// Copyright (C) 2017 Rick Waldron. 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 +features: [TypedArray] +includes: [testTypedArray.js] +---*/ + +// empty