import abc import inspect import os import re from typing import Any, List, Match, Optional, Pattern, Text, Tuple, cast Error = Tuple[str, str, str, Optional[int]] def collapse(text: Text) -> Text: return inspect.cleandoc(str(text)).replace("\n", " ") class Rule(metaclass=abc.ABCMeta): @abc.abstractproperty def name(self) -> Text: pass @abc.abstractproperty def description(self) -> Text: pass to_fix: Optional[Text] = None @classmethod def error(cls, path: Text, context: Tuple[Any, ...] = (), line_no: Optional[int] = None) -> Error: name = cast(str, cls.name) description = cast(str, cls.description) % context return (name, description, path, line_no) class MissingLink(Rule): name = "MISSING-LINK" description = "Testcase file must have a link to a spec" to_fix = """ Ensure that there is a `` for the spec. `MISSING-LINK` is designed to ensure that the CSS build tool can find the tests. Note that the CSS build system is primarily used by [test.csswg.org/](http://test.csswg.org/), which doesn't use `wptserve`, so `*.any.js` and similar tests won't work there; stick with the `.html` equivalent. """ class PathLength(Rule): name = "PATH LENGTH" description = "/%s longer than maximum path length (%d > 150)" to_fix = "use shorter filename to rename the test file" class FileType(Rule): name = "FILE TYPE" description = "/%s is an unsupported file type (%s)" class WorkerCollision(Rule): name = "WORKER COLLISION" description = collapse(""" path ends with %s which collides with generated tests from %s files """) class GitIgnoreFile(Rule): name = "GITIGNORE" description = ".gitignore found outside the root" class MojomJSFile(Rule): name = "MOJOM-JS" description = "Don't check *.mojom.js files into WPT" to_fix = """ Check if the file is already included in mojojs.zip: https://source.chromium.org/chromium/chromium/src/+/master:chrome/tools/build/linux/FILES.cfg If yes, use `loadMojoResources` from `resources/test-only-api.js` to load it; if not, contact ecosystem-infra@chromium.org for adding new files to mojojs.zip. """ class AhemCopy(Rule): name = "AHEM COPY" description = "Don't add extra copies of Ahem, use /fonts/Ahem.ttf" class AhemSystemFont(Rule): name = "AHEM SYSTEM FONT" description = "Don't use Ahem as a system font, use /fonts/ahem.css" # TODO: Add tests for this rule class IgnoredPath(Rule): name = "IGNORED PATH" description = collapse(""" %s matches an ignore filter in .gitignore - please add a .gitignore exception """) class ParseFailed(Rule): name = "PARSE-FAILED" description = "Unable to parse file" to_fix = """ examine the file to find the causes of any parse errors, and fix them. """ class ContentManual(Rule): name = "CONTENT-MANUAL" description = "Manual test whose filename doesn't end in '-manual'" class ContentVisual(Rule): name = "CONTENT-VISUAL" description = "Visual test whose filename doesn't end in '-visual'" class AbsoluteUrlRef(Rule): name = "ABSOLUTE-URL-REF" description = collapse(""" Reference test with a reference file specified via an absolute URL: '%s' """) class SameFileRef(Rule): name = "SAME-FILE-REF" description = "Reference test which points at itself as a reference" class NonexistentRef(Rule): name = "NON-EXISTENT-REF" description = collapse(""" Reference test with a non-existent '%s' relationship reference: '%s' """) class MultipleTimeout(Rule): name = "MULTIPLE-TIMEOUT" description = "More than one meta name='timeout'" to_fix = """ ensure each test file has only one instance of a `` element """ class InvalidTimeout(Rule): name = "INVALID-TIMEOUT" description = collapse(""" Test file with `` element that has a `content` attribute whose value is not `long`: %s """) to_fix = "replace the value of the `content` attribute with `long`" class MultipleTestharness(Rule): name = "MULTIPLE-TESTHARNESS" description = "More than one `