mirror of
https://github.com/tc39/test262.git
synced 2025-11-12 17:59:44 +01:00
Fixes error when linting the `json-modules` feature which points to test/language/import/import-attributes, containing .json fixture files. The linter's file_is_test() function was only filtering out FIXTURE.js files but not .json files, so it tried to read frontmatter from the JSON files and failed.
115 lines
3.4 KiB
Python
Executable File
115 lines
3.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import re
|
|
import yaml
|
|
|
|
def read_features(filename):
|
|
'''Get a list of string feature names from a test file's YAML-formatted
|
|
frontmatter.'''
|
|
with open(filename, 'r') as handle:
|
|
frontmatter = None
|
|
for line in handle:
|
|
if frontmatter is not None:
|
|
if line.strip() == '---*/':
|
|
break
|
|
frontmatter += line
|
|
if line.strip() == '/*---':
|
|
frontmatter = ''
|
|
|
|
assert frontmatter is not None, f'File has frontmatter: {filename}'
|
|
|
|
return yaml.safe_load(frontmatter).get('features', [])
|
|
|
|
def file_is_test(filename):
|
|
return not (filename.endswith('FIXTURE.js') or filename.endswith('.json'))
|
|
|
|
def pattern_from_path_spec(path_spec):
|
|
return re.compile(re.sub('\*', '.*', path_spec))
|
|
|
|
def get_filenames(path_spec):
|
|
pattern = pattern_from_path_spec(path_spec)
|
|
|
|
# path_spec is a literal path, not a pattern
|
|
if pattern.pattern == path_spec:
|
|
if os.path.isfile(path_spec):
|
|
yield path_spec
|
|
elif os.path.isdir(path_spec):
|
|
for root, _, files in os.walk(path_spec):
|
|
test_files = filter(file_is_test, files)
|
|
yield from [os.path.join(root, file) for file in test_files]
|
|
else:
|
|
raise AssertionError(f'No such file/directory: "{path_spec}"')
|
|
return
|
|
|
|
# Choose the optimal directory from which to conduct the search by using
|
|
# all available static directory names in the path spec (e.g. `a/b/c` in
|
|
# the path spec `a/b/c/*/d`)
|
|
search_root = '.'
|
|
for part in path_spec.split('/'):
|
|
if '*' in part:
|
|
break
|
|
search_root = f'{search_root}/{part}'
|
|
|
|
matched = False
|
|
|
|
for root, _, files in os.walk(search_root):
|
|
for file in files:
|
|
file = os.path.join(root, file)
|
|
|
|
if pattern.search(file):
|
|
matched = True
|
|
yield file
|
|
|
|
assert matched, 'At least one matching file for "{path_spec}"'
|
|
|
|
def get_filenames_from_path_specs(path_specs):
|
|
filenames = set()
|
|
for path_spec in path_specs:
|
|
if path_spec.startswith('!'):
|
|
pattern = pattern_from_path_spec(path_spec[1:])
|
|
used = False
|
|
|
|
for filename in list(filenames):
|
|
if pattern.search(filename):
|
|
filenames.remove(filename)
|
|
used = True
|
|
|
|
assert used, f'Pathspec used at least once: "{path_spec}"'
|
|
else:
|
|
filenames.update(get_filenames(path_spec))
|
|
return filenames
|
|
|
|
def match(file_path, tag_specs):
|
|
tags = read_features(file_path)
|
|
|
|
for tag_filter in tag_specs:
|
|
if tag_filter.startswith('!'):
|
|
if tag_filter[1:] in tags:
|
|
return False
|
|
else:
|
|
if tag_filter not in tags:
|
|
return False
|
|
return True
|
|
|
|
def main(web_features_filename):
|
|
with open(web_features_filename, 'r') as handle:
|
|
features = yaml.safe_load(handle)['features']
|
|
|
|
for feature in features:
|
|
name = feature['name']
|
|
path_specs = feature['files']
|
|
tag_specs = feature.get('tags', [])
|
|
|
|
tests = [*filter(
|
|
lambda candidate: match(candidate, tag_specs),
|
|
get_filenames_from_path_specs(path_specs)
|
|
)]
|
|
|
|
print(f'{name},{len(tests)}')
|
|
|
|
print(f'{web_features_filename} is conformant')
|
|
|
|
if __name__ == '__main__':
|
|
main('./WEB_FEATURES.yml')
|