summaryrefslogtreecommitdiff
path: root/tests/unit/test_api.py
blob: 7fe73ab937e5cbc954ec0a974b1d2a42e8f55e4c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""Tests the isort API module"""
import os
from io import StringIO
from unittest.mock import MagicMock, patch

import pytest

from isort import ImportKey, api
from isort.settings import Config

imperfect_content = "import b\nimport a\n"
fixed_content = "import a\nimport b\n"
fixed_diff = "+import a\n import b\n-import a\n"


@pytest.fixture
def imperfect(tmpdir):
    imperfect_file = tmpdir.join("test_needs_changes.py")
    imperfect_file.write_text(imperfect_content, "utf8")
    return imperfect_file


def test_sort_file_with_bad_syntax(tmpdir) -> None:
    tmp_file = tmpdir.join("test_bad_syntax.py")
    tmp_file.write_text("""print('mismatching quotes")""", "utf8")
    with pytest.warns(UserWarning):
        api.sort_file(tmp_file, atomic=True)
    with pytest.warns(UserWarning):
        api.sort_file(tmp_file, atomic=True, write_to_stdout=True)


def test_sort_file(imperfect) -> None:
    assert api.sort_file(imperfect)
    assert imperfect.read() == fixed_content


def test_sort_file_in_place(imperfect) -> None:
    assert api.sort_file(imperfect, overwrite_in_place=True)
    assert imperfect.read() == fixed_content


def test_sort_file_to_stdout(capsys, imperfect) -> None:
    assert api.sort_file(imperfect, write_to_stdout=True)
    out, _ = capsys.readouterr()
    assert out == fixed_content.replace("\n", os.linesep)


def test_other_ask_to_apply(imperfect) -> None:
    # First show diff, but ensure change wont get written by asking to apply
    # and ensuring answer is no.
    with patch("isort.format.input", MagicMock(return_value="n")):
        assert not api.sort_file(imperfect, ask_to_apply=True)
        assert imperfect.read() == imperfect_content

    # Then run again, but apply the change (answer is yes)
    with patch("isort.format.input", MagicMock(return_value="y")):
        assert api.sort_file(imperfect, ask_to_apply=True)
        assert imperfect.read() == fixed_content


def test_check_file_no_changes(capsys, tmpdir) -> None:
    perfect = tmpdir.join("test_no_changes.py")
    perfect.write_text("import a\nimport b\n", "utf8")
    assert api.check_file(perfect, show_diff=True)
    out, _ = capsys.readouterr()
    assert not out


def test_check_file_with_changes(capsys, imperfect) -> None:
    assert not api.check_file(imperfect, show_diff=True)
    out, _ = capsys.readouterr()
    assert fixed_diff.replace("\n", os.linesep) in out


def test_sorted_imports_multiple_configs() -> None:
    with pytest.raises(ValueError):
        api.sort_code_string("import os", config=Config(line_length=80), line_length=80)


def test_diff_stream() -> None:
    output = StringIO()
    assert api.sort_stream(StringIO("import b\nimport a\n"), output, show_diff=True)
    output.seek(0)
    assert fixed_diff in output.read()


def test_sort_code_string_mixed_newlines():
    assert api.sort_code_string("import A\n\r\nimportA\n\n") == "import A\r\n\r\nimportA\r\n\n"


def test_find_imports_in_file(imperfect):
    found_imports = list(api.find_imports_in_file(imperfect))
    assert "b" in [found_import.module for found_import in found_imports]


def test_find_imports_in_code():
    code = """
from x.y import z as a
from x.y import z as a
from x.y import z
import x.y
import x
"""
    assert len(list(api.find_imports_in_code(code))) == 5
    assert len(list(api.find_imports_in_code(code, unique=True))) == 4
    assert len(list(api.find_imports_in_code(code, unique=ImportKey.ATTRIBUTE))) == 3
    assert len(list(api.find_imports_in_code(code, unique=ImportKey.MODULE))) == 2
    assert len(list(api.find_imports_in_code(code, unique=ImportKey.PACKAGE))) == 1