summaryrefslogtreecommitdiffstats
path: root/tests/test_init.py
blob: 832343fe7b037504bca3f2dfd13727b5203c487e (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
import builtins
from contextlib import contextmanager
from pathlib import Path
from tempfile import TemporaryDirectory
from testpath import assert_isfile
from unittest.mock import patch
import pytest

try:
    import tomllib
except ImportError:
    import tomli as tomllib

from flit import init


@contextmanager
def patch_data_dir():
    with TemporaryDirectory() as td:
        with patch.object(init, 'get_data_dir', lambda: Path(td)):
            yield td

def test_store_defaults():
    with patch_data_dir():
        assert init.get_defaults() == {}
        d = {'author': 'Test'}
        init.store_defaults(d)
        assert init.get_defaults() == d

def fake_input(entries):
    it = iter(entries)
    def inner(prompt):
        try:
            return next(it)
        except StopIteration:
            raise EOFError

    return inner

def faking_input(entries):
    return patch.object(builtins, 'input', fake_input(entries))

def test_prompt_options():
    ti = init.TerminalIniter()
    with faking_input(['4', '1']):
        res = ti.prompt_options('Pick one', [('A', 'Apple'), ('B', 'Banana')])
    assert res == 'A'

    # Test with a default
    with faking_input(['']):
        res = ti.prompt_options('Pick one', [('A', 'Apple'), ('B', 'Banana')],
                                default='B')
    assert res == 'B'

@contextmanager
def make_dir(files=(), dirs=()):
    with TemporaryDirectory() as td:
        tdp = Path(td)
        for d in dirs:
            (tdp / d).mkdir()
        for f in files:
            (tdp / f).touch()
        yield td

def test_guess_module_name():
    with make_dir(['foo.py', 'foo-bar.py', 'test_foo.py', 'setup.py']) as td:
        ib = init.IniterBase(td)
        assert ib.guess_module_name() == 'foo'

    with make_dir(['baz/__init__.py', 'tests/__init__.py'], ['baz', 'tests']) as td:
        ib = init.IniterBase(td)
        assert ib.guess_module_name() == 'baz'

    with make_dir(['src/foo.py', 'src/foo-bar.py', 'test_foo.py', 'setup.py'],
                  ['src',]) as td:
        ib = init.IniterBase(td)
        assert ib.guess_module_name() == 'foo'

    with make_dir(['src/baz/__init__.py', 'tests/__init__.py'], ['src', 'src/baz', 'tests']) as td:
        ib = init.IniterBase(td)
        assert ib.guess_module_name() == 'baz'

    with make_dir(['foo.py', 'bar.py']) as td:
        ib = init.IniterBase(td)
        assert ib.guess_module_name() is None

    with make_dir(['src/foo.py', 'src/bar.py'], ['src']) as td:
        ib = init.IniterBase(td)
        assert ib.guess_module_name() is None

def test_write_license():
    with TemporaryDirectory() as td:
        ib = init.IniterBase(td)
        ib.write_license('mit', 'Thomas Kluyver')
        assert_isfile(Path(td, 'LICENSE'))

def test_init():
    responses = ['foo', # Module name
                 'Test Author',      # Author
                 'test@example.com',  # Author email
                 'http://example.com/', # Home page
                 '1'    # License (1 -> MIT)
                ]
    with TemporaryDirectory() as td, \
          patch_data_dir(), \
          faking_input(responses):
        ti = init.TerminalIniter(td)
        ti.initialise()

        generated = Path(td) / 'pyproject.toml'
        assert_isfile(generated)
        with generated.open('rb') as f:
            data = tomllib.load(f)
        assert data['project']['authors'][0]['email'] == "test@example.com"
        license = Path(td) / 'LICENSE'
        assert data['project']['license']['file'] == 'LICENSE'
        assert_isfile(license)
        with license.open() as f:
            license_text = f.read()
        assert license_text.startswith("The MIT License (MIT)")
        assert "{year}" not in license_text
        assert "Test Author" in license_text

def test_init_homepage_and_license_are_optional():
    responses = ['test_module_name',
                 'Test Author',
                 'test_email@example.com',
                 '',   # Home page omitted
                 '4',  # Skip - choose a license later
                ]
    with TemporaryDirectory() as td, \
          patch_data_dir(), \
          faking_input(responses):
        ti = init.TerminalIniter(td)
        ti.initialise()
        with Path(td, 'pyproject.toml').open('rb') as f:
            data = tomllib.load(f)
        assert not Path(td, 'LICENSE').exists()
    assert data['project'] == {
        'authors': [{'name': 'Test Author', 'email': 'test_email@example.com'}],
        'name': 'test_module_name',
        'dynamic': ['version', 'description'],
    }

def test_init_homepage_validator():
    responses = ['test_module_name',
                 'Test Author',
                 'test_email@example.com',
                 'www.uh-oh-spagghetti-o.com',  # fails validation
                 'https://www.example.org',  # passes
                 '4',  # Skip - choose a license later
                ]
    with TemporaryDirectory() as td, \
          patch_data_dir(), \
          faking_input(responses):
        ti = init.TerminalIniter(td)
        ti.initialise()
        with Path(td, 'pyproject.toml').open('rb') as f:
            data = tomllib.load(f)
    assert data['project'] == {
        'authors': [{'name': 'Test Author', 'email': 'test_email@example.com'}],
        'name': 'test_module_name',
        'urls': {'Home': 'https://www.example.org'},
        'dynamic': ['version', 'description'],
    }

def test_author_email_field_is_optional():
    responses = ['test_module_name',
                 'Test Author',
                 '',  # Author-email field is skipped
                 'https://www.example.org',
                 '4',
                ]
    with TemporaryDirectory() as td, \
          patch_data_dir(), \
          faking_input(responses):
        ti = init.TerminalIniter(td)
        ti.initialise()
        with Path(td, 'pyproject.toml').open('rb') as f:
            data = tomllib.load(f)
        assert not Path(td, 'LICENSE').exists()

    assert data['project'] == {
        'authors': [{'name': 'Test Author'}],
        'name': 'test_module_name',
        'urls': {'Home': 'https://www.example.org'},
        'dynamic': ['version', 'description'],
    }


@pytest.mark.parametrize(
    "readme_file",
    ["readme.md", "README.MD", "README.md",
     "Readme.md", "readme.MD", "readme.rst",
     "readme.txt"])
def test_find_readme(readme_file):
    with make_dir([readme_file]) as td:
        ib = init.IniterBase(td)
        assert ib.find_readme() == readme_file


def test_find_readme_not_found():
    with make_dir() as td:
        ib = init.IniterBase(td)
        assert ib.find_readme() is None


def test_init_readme_found_yes_choosen():
    responses = ['test_module_name',
                 'Test Author',
                 'test_email@example.com',
                 '',   # Home page omitted
                 '4',  # Skip - choose a license later
                ]
    with make_dir(["readme.md"]) as td, \
          patch_data_dir(), \
          faking_input(responses):
        ti = init.TerminalIniter(td)
        ti.initialise()
        with Path(td, 'pyproject.toml').open('rb') as f:
            data = tomllib.load(f)

    assert data['project'] == {
        'authors': [{'name': 'Test Author', 'email': 'test_email@example.com'}],
        'name': 'test_module_name',
        'readme': 'readme.md',
        'dynamic': ['version', 'description'],
    }


def test_init_non_ascii_author_name():
    responses = ['foo', # Module name
                 'Test Authôr',      # Author
                 '',  # Author email omitted
                 '', # Home page omitted
                 '1'    # License (1 -> MIT)
                ]
    with TemporaryDirectory() as td, \
          patch_data_dir(), \
          faking_input(responses):
        ti = init.TerminalIniter(td)
        ti.initialise()

        generated = Path(td) / 'pyproject.toml'
        assert_isfile(generated)
        with generated.open('r', encoding='utf-8') as f:
            raw_text = f.read()
            print(raw_text)
            assert "Test Authôr" in raw_text
            assert "\\u00f4" not in raw_text
        license = Path(td) / 'LICENSE'
        assert_isfile(license)
        with license.open(encoding='utf-8') as f:
            license_text = f.read()
        assert "Test Authôr" in license_text