예제 #1
0
def test_diagnostic_formatter() -> None:
    path = Path("/path/to/file")
    formatter = FLCMFormatter
    err = formatter.format(
        Diagnostic(
            start_line=10,
            end_line=12,
            start_column=3,
            file_path=path,
            message="line1\nline2",
        ),
        "my_command",
    )
    assert err == f"{path.resolve()}:10:3:my_command: line1\\nline2"

    err = formatter.format(
        Diagnostic(
            start_line=10,
            end_line=12,
            start_column=3,
            file_path=path,
            diff="-line1\n+line2\n",
        ),
        "my_command2",
    )
    assert err == f"{path.resolve()}:10:3:my_command2: -line1\\n+line2\\n"
예제 #2
0
def test__format_diagnostic_position() -> None:
    path = Path("/path/to/file")
    position = _format_diagnostic_position(
        Diagnostic(start_line=10, end_line=12, start_column=3, file_path=path, diff="")
    )
    assert position == f"{path.resolve()}:10:3"

    position = _format_diagnostic_position(Diagnostic(file_path=path, diff=""))
    assert position == f"{path.resolve()}:1:1"
예제 #3
0
def test_reporter_report_diagnostics() -> None:
    r = Reporter("foo")
    d1 = Diagnostic(pathlib.Path("hoge").resolve(), 1, 2, 3, message="hoge")
    d2 = Diagnostic(pathlib.Path("fuga").resolve(), 4, 5, 6, message="fuga")
    d3 = Diagnostic(pathlib.Path("piyo").resolve(), 7, 8, 9, message="piyo")

    with r:
        r.report_diagnostics([d1])
        assert r.diagnostics == [d1]

        r.report_diagnostics([d2, d3])
        assert r.diagnostics == [d1, d2, d3]
예제 #4
0
def test_reporter_factory() -> None:
    factory = ReporterFactory()
    assert len(factory.reporters) == 0

    with factory.create("foo") as r:
        r.set_result(True, 0)
        r.report_diagnostics(
            [Diagnostic(BASE_DIR / "hoge.py", 1, 2, 3, message="error")])

    assert len(factory.reporters) == 1
    assert not factory.has_error()
    out = factory.format_summary()
    assert "foo" in out

    with factory.create("bar") as r:
        r.set_result(False, 128)

    assert len(factory.reporters) == 2
    assert factory.has_error()
    out = factory.format_summary()
    assert "foo" in out and "bar" in out

    err_summary = factory.format_error_summary()
    assert "\n - bar\n" in err_summary and "foo" not in err_summary

    out = factory.format_diagnostic_summary(FLCMFormatter)
    assert f"{BASE_DIR / 'hoge.py'}:1:3:foo: error" in out
예제 #5
0
파일: error_lines.py 프로젝트: pfnet/pysen
def parse_error_lines(
        errors: str,
        logger: Optional[logging.Logger] = None) -> Iterable[Diagnostic]:
    """
    Compatible with flake8, mypy
    """
    number = r"(?:0|[1-9]\d*)"
    _file_path = r"^(?P<file_path>.*?)"
    _line = fr":(?P<line>{number})"
    _column = fr"(:(?P<column>{number}))?"
    _message = r": (?P<message>.*$)"
    pattern = _file_path + _line + _column + _message
    invalid_lines = []
    for el in errors.splitlines():
        m = re.match(pattern, el)
        if m is None:
            invalid_lines.append(el)
            continue
        line = int(m.group("line"))
        if m.group("column") is None:
            column = None
        else:
            column = int(m.group("column"))
        yield Diagnostic(
            start_line=line,
            end_line=line,
            start_column=column,
            message=m.group("message").lstrip(" ").rstrip("\n"),
            file_path=Path(m.group("file_path")),
        )
    if invalid_lines:
        _warn_parse_error("\n".join(invalid_lines), logger)
예제 #6
0
파일: error_lines.py 프로젝트: pfnet/pysen
def parse_error_diffs(
    errors: str,
    file_path_parser: FilePathParserType,
    logger: Optional[logging.Logger] = None,
) -> Iterable[Diagnostic]:
    """
    Compatible with isort, black
    """
    def _is_changed(line: unidiff.patch.Line) -> bool:
        return not line.is_context

    try:
        patches = unidiff.PatchSet(errors)
    except unidiff.errors.UnidiffParseError:
        _warn_parse_error(errors, logger)
        return
    for patch in patches:
        for hunk in patch:
            source_changes = list(filter(_is_changed, hunk.source_lines()))
            if source_changes:
                start_line = source_changes[0].source_line_no
                end_line = source_changes[-1].source_line_no
            else:
                target_changes = list(filter(_is_changed, hunk.target_lines()))
                assert target_changes, "expected either source or target line number"
                start_line = target_changes[0].target_line_no
                end_line = target_changes[-1].target_line_no

            try:
                file_path = file_path_parser(patch.source_file)
            except UnexpectedErrorFormat:
                _warn_parse_error(patch, logger)
                continue

            def filter_hunk(
                hunk: unidiff.patch.Hunk,
            ) -> Generator[unidiff.patch.Line, None, None]:
                for line in hunk:
                    if _is_changed(line):
                        yield line
                    elif line.source_line_no is not None:
                        if start_line <= line.source_line_no <= end_line:
                            yield line

            yield Diagnostic(
                start_line=start_line,
                end_line=end_line,
                start_column=1,
                file_path=file_path,
                diff="".join(map(str, filter_hunk(hunk))),
            )
예제 #7
0
def test_diagnostic_post_init() -> None:
    path = Path("/path/to/file")
    Diagnostic(file_path=path, message="error")
    Diagnostic(file_path=path, diff="diff")
    with pytest.raises(ValueError):
        Diagnostic(file_path=path)
예제 #8
0
def test_single_file_format_command_base() -> None:
    with TemporaryDirectory() as t:
        base_dir = pathlib.Path(t)

        for file_path in {"foo.py", "bar.pyi", "baz.txt"}:
            (base_dir / file_path).touch()

        command = FakeSingleFileFormatCommand(
            base_dir, FakeSource(), inplace_edit=False
        )
        with mock.patch.object(command, "format", return_value="") as format_method:
            reporter = Reporter("fake")
            handler = FakeHandler()
            reporter.process_output.addHandler(handler)
            assert command(reporter) == 0
            assert format_method.call_count == 2
            assert len(handler.messages) == 0
            assert len(reporter.diagnostics) == 0

        with mock.patch.object(command, "format", return_value="diff") as format_method:
            reporter = Reporter("fake")
            handler = FakeHandler()
            reporter.process_output.addHandler(handler)
            assert command(reporter) == 1
            assert format_method.call_count == 2
            assert len(handler.messages) == 2
            assert len(reporter.diagnostics) == 2
            for file_path in {"foo.py", "bar.pyi"}:
                assert (
                    f"--- {base_dir / file_path}\n"
                    f"+++ {base_dir / file_path}\n"
                    "@@ -0,0 +1 @@\n"
                    "+diff"
                ) in handler.messages
                assert (
                    Diagnostic(
                        start_line=1,
                        end_line=1,
                        start_column=1,
                        file_path=base_dir / file_path,
                        diff="+diff",
                    )
                    in reporter.diagnostics
                )

        command = FakeSingleFileFormatCommand(base_dir, FakeSource(), inplace_edit=True)
        with mock.patch.object(command, "format", return_value=None) as format_method:
            reporter = Reporter("fake")
            handler = FakeHandler()
            reporter.process_output.addHandler(handler)
            assert command(reporter) == 1
            assert format_method.call_count == 2
            assert len(handler.messages) == 0
            assert len(reporter.diagnostics) == 0
            with (base_dir / "foo.py").open() as f:
                assert f.read() == ""
            with (base_dir / "bar.pyi").open() as f:
                assert f.read() == ""

        with mock.patch.object(command, "format", return_value="diff") as format_method:
            reporter = Reporter("fake")
            handler = FakeHandler()
            reporter.process_output.addHandler(handler)
            assert command(reporter) == 0
            assert format_method.call_count == 2
            assert len(handler.messages) == 0
            assert len(reporter.diagnostics) == 0
            with (base_dir / "foo.py").open() as f:
                assert f.read() == "diff"
            with (base_dir / "bar.pyi").open() as f:
                assert f.read() == "diff"