Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- Manifest: tools/lint/test/python.toml
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
import importlib
import mozunit
import pytest
from mozlint.result import ResultSummary
LINTER = "spidermonkey"
@pytest.fixture(autouse=True)
def _result_root(monkeypatch):
monkeypatch.setattr(ResultSummary, "root", "/src")
@pytest.fixture
def module():
return importlib.import_module("spidermonkey")
@pytest.fixture
def config():
return {"name": "spidermonkey-style", "description": "fallback description"}
@pytest.fixture
def canned(module, monkeypatch):
def _canned(retcode, stdout):
# _run_check strips its output, so canned output must be stripped too.
monkeypatch.setattr(
module, "_run_check", lambda script, lintargs: (retcode, stdout.strip())
)
return _canned
def test_strips_test_harness_prefixes(module, monkeypatch):
class Proc:
returncode = 1
stdout = (
"TEST-PASS | check_js_opcode.py | ok\n"
"TEST-UNEXPECTED-FAIL | check_js_opcode.py | Category is not specified\n"
)
stderr = ""
monkeypatch.setattr(module.subprocess, "run", lambda *a, **kw: Proc())
retcode, output = module._run_check("check_js_opcode.py", {"root": "/src"})
assert retcode == 1
assert output == "Category is not specified"
@pytest.mark.parametrize("check", ["style", "macroassembler", "opcode"])
def test_no_issues_when_check_passes(module, config, canned, check):
canned(0, "")
assert getattr(module, check)([], config) == []
def test_style_reports_each_error_with_a_location(module, config, canned):
canned(
1,
"--- check_spidermonkey_style.py expected output\n"
"+++ check_spidermonkey_style.py actual output\n"
"@@ -1,4 +1,9 @@\n"
" js/src/tests/style/BadIncludes.h:3: error:\n"
" the file includes itself\n"
"+js/src/vm/Interpreter.cpp:9: error:\n"
'+ "stdio.h" is included using the wrong path;\n'
"+ did you forget a prefix?\n"
"+\n"
"+js/src/vm/Stack.h:12: error:\n"
"+ vanilla header includes an inline-header file\n"
"+\n"
" \n",
)
issues = module.style([], config)
assert [(i.relpath, i.lineno) for i in issues] == [
("js/src/vm/Interpreter.cpp", 9),
("js/src/vm/Stack.h", 12),
]
assert issues[0].message == (
'"stdio.h" is included using the wrong path; did you forget a prefix?'
)
assert issues[1].message == "vanilla header includes an inline-header file"
def test_style_maps_header_cycles_to_js_src(module, config, canned):
canned(
1,
"@@ -1,2 +1,6 @@\n"
"+(multiple files): error:\n"
"+ header files form one or more cycles\n"
"+\n"
"+ vm/A.h\n"
"+ -> vm/B.h\n",
)
(issue,) = module.style([], config)
assert issue.relpath == "js/src"
assert issue.lineno == 0
assert "header files form one or more cycles" in issue.message
assert "-> vm/B.h" in issue.message
def test_style_falls_back_to_the_raw_diff(module, config, canned):
# Only removed lines: the js/src/tests/style/ fixtures no longer produce the
# output expected by the check itself.
diff = (
"@@ -1,6 +1,2 @@\n"
"-js/src/tests/style/BadIncludes.h:6: error:\n"
'- "BadIncludes2.h" is included using the wrong path;\n'
)
canned(1, diff)
(issue,) = module.style([], config)
assert issue.relpath == "js/src/tests/style"
assert issue.message == diff.strip()
assert "expected_output" in issue.hint
def test_macroassembler_reports_the_whole_diff(module, config, canned):
canned(1, "-void PushFlags() DEFINED_ON(arm, x86_shared);")
(issue,) = module.macroassembler([], config)
assert issue.relpath == "js/src/jit/MacroAssembler.h"
assert issue.message == "-void PushFlags() DEFINED_ON(arm, x86_shared);"
def test_opcode_reports_the_check_output(module, config, canned):
canned(1, "Category is not specified for Undefined")
(issue,) = module.opcode([], config)
assert issue.relpath == "js/src/vm/Opcodes.h"
assert issue.message == "Category is not specified for Undefined"
if __name__ == "__main__":
mozunit.main()