12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
14
import logging
15
+ import textwrap
15
16
17
+ import build
16
18
import pretend
17
19
import pytest
18
20
19
- from twine import commands
20
- from twine import package as package_file
21
21
from twine .commands import check
22
22
23
23
@@ -38,10 +38,8 @@ def test_str_representation(self):
38
38
assert str (self .stream ) == "line 2: Warning: Title underline too short."
39
39
40
40
41
- def test_check_no_distributions (monkeypatch , caplog ):
42
- monkeypatch .setattr (commands , "_find_dists" , lambda a : [])
43
-
44
- assert not check .check (["dist/*" ])
41
+ def test_fails_no_distributions (caplog ):
42
+ assert not check .check ([])
45
43
assert caplog .record_tuples == [
46
44
(
47
45
"twine.commands.check" ,
@@ -51,75 +49,51 @@ def test_check_no_distributions(monkeypatch, caplog):
51
49
]
52
50
53
51
54
- def test_check_passing_distribution (monkeypatch , capsys ):
55
- renderer = pretend .stub (render = pretend .call_recorder (lambda * a , ** kw : "valid" ))
56
- package = pretend .stub (
57
- metadata_dictionary = lambda : {
58
- "description" : "blah" ,
59
- "description_content_type" : "text/markdown" ,
60
- }
61
- )
62
- warning_stream = ""
63
-
64
- monkeypatch .setattr (check , "_RENDERERS" , {None : renderer })
65
- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
66
- monkeypatch .setattr (
67
- package_file ,
68
- "PackageFile" ,
69
- pretend .stub (from_filename = lambda * a , ** kw : package ),
70
- )
71
- monkeypatch .setattr (check , "_WarningStream" , lambda : warning_stream )
72
-
73
- assert not check .check (["dist/*" ])
74
- assert capsys .readouterr ().out == "Checking dist/dist.tar.gz: PASSED\n "
75
- assert renderer .render .calls == [pretend .call ("blah" , stream = warning_stream )]
76
-
77
-
78
- @pytest .mark .parametrize ("content_type" , ["text/plain" , "text/markdown" ])
79
- def test_check_passing_distribution_with_none_renderer (
80
- content_type ,
81
- monkeypatch ,
82
- capsys ,
83
- ):
84
- """Pass when rendering a content type can't fail."""
85
- package = pretend .stub (
86
- metadata_dictionary = lambda : {
87
- "description" : "blah" ,
88
- "description_content_type" : content_type ,
89
- }
90
- )
52
+ def build_sdist (src_path , project_files ):
53
+ """
54
+ Build a source distribution similar to `python3 -m build --sdist`.
91
55
92
- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
93
- monkeypatch .setattr (
94
- package_file ,
95
- "PackageFile" ,
96
- pretend .stub (from_filename = lambda * a , ** kw : package ),
56
+ Returns the absolute path of the built distribution.
57
+ """
58
+ project_files = {
59
+ "pyproject.toml" : (
60
+ """
61
+ [build-system]
62
+ requires = ["setuptools"]
63
+ build-backend = "setuptools.build_meta"
64
+ """
65
+ ),
66
+ ** project_files ,
67
+ }
68
+
69
+ for filename , content in project_files .items ():
70
+ (src_path / filename ).write_text (textwrap .dedent (content ))
71
+
72
+ builder = build .ProjectBuilder (src_path )
73
+ return builder .build ("sdist" , str (src_path / "dist" ))
74
+
75
+
76
+ @pytest .mark .parametrize ("strict" , [False , True ])
77
+ def test_warns_missing_description (strict , tmp_path , capsys , caplog ):
78
+ sdist = build_sdist (
79
+ tmp_path ,
80
+ {
81
+ "setup.cfg" : (
82
+ """
83
+ [metadata]
84
+ name = test-package
85
+ version = 0.0.1
86
+ """
87
+ ),
88
+ },
97
89
)
98
90
99
- assert not check .check (["dist/*" ])
100
- assert capsys .readouterr ().out == "Checking dist/dist.tar.gz: PASSED\n "
91
+ assert check .check ([sdist ], strict = strict ) is strict
101
92
102
-
103
- def test_check_no_description (monkeypatch , capsys , caplog ):
104
- package = pretend .stub (
105
- metadata_dictionary = lambda : {
106
- "description" : None ,
107
- "description_content_type" : None ,
108
- }
109
- )
110
-
111
- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
112
- monkeypatch .setattr (
113
- package_file ,
114
- "PackageFile" ,
115
- pretend .stub (from_filename = lambda * a , ** kw : package ),
93
+ assert capsys .readouterr ().out == f"Checking { sdist } : " + (
94
+ "FAILED due to warnings\n " if strict else "PASSED with warnings\n "
116
95
)
117
96
118
- assert not check .check (["dist/*" ])
119
-
120
- assert capsys .readouterr ().out == (
121
- "Checking dist/dist.tar.gz: PASSED with warnings\n "
122
- )
123
97
assert caplog .record_tuples == [
124
98
(
125
99
"twine.commands.check" ,
@@ -134,71 +108,167 @@ def test_check_no_description(monkeypatch, capsys, caplog):
134
108
]
135
109
136
110
137
- def test_strict_fails_on_warnings (monkeypatch , capsys , caplog ):
138
- package = pretend .stub (
139
- metadata_dictionary = lambda : {
140
- "description" : None ,
141
- "description_content_type" : None ,
142
- }
111
+ def test_warns_missing_file (tmp_path , capsys , caplog ):
112
+ sdist = build_sdist (
113
+ tmp_path ,
114
+ {
115
+ "setup.cfg" : (
116
+ """
117
+ [metadata]
118
+ name = test-package
119
+ version = 0.0.1
120
+ long_description = file:README.rst
121
+ long_description_content_type = text/x-rst
122
+ """
123
+ ),
124
+ },
143
125
)
144
126
145
- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
146
- monkeypatch .setattr (
147
- package_file ,
148
- "PackageFile" ,
149
- pretend .stub (from_filename = lambda * a , ** kw : package ),
150
- )
127
+ assert not check .check ([sdist ])
151
128
152
- assert check . check ([ "dist/*" ], strict = True )
129
+ assert capsys . readouterr (). out == f"Checking { sdist } : PASSED with warnings \n "
153
130
154
- assert capsys .readouterr ().out == (
155
- "Checking dist/dist.tar.gz: FAILED due to warnings\n "
156
- )
157
131
assert caplog .record_tuples == [
158
132
(
159
133
"twine.commands.check" ,
160
134
logging .WARNING ,
161
- "`long_description_content_type ` missing. defaulting to `text/x-rst` ." ,
135
+ "`long_description ` missing." ,
162
136
),
137
+ ]
138
+
139
+
140
+ def test_fails_rst_syntax_error (tmp_path , capsys , caplog ):
141
+ sdist = build_sdist (
142
+ tmp_path ,
143
+ {
144
+ "setup.cfg" : (
145
+ """
146
+ [metadata]
147
+ name = test-package
148
+ version = 0.0.1
149
+ long_description = file:README.rst
150
+ long_description_content_type = text/x-rst
151
+ """
152
+ ),
153
+ "README.rst" : (
154
+ """
155
+ ============
156
+ """
157
+ ),
158
+ },
159
+ )
160
+
161
+ assert check .check ([sdist ])
162
+
163
+ assert capsys .readouterr ().out == f"Checking { sdist } : FAILED\n "
164
+
165
+ assert caplog .record_tuples == [
163
166
(
164
167
"twine.commands.check" ,
165
- logging .WARNING ,
166
- "`long_description` missing." ,
168
+ logging .ERROR ,
169
+ "`long_description` has syntax errors in markup "
170
+ "and would not be rendered on PyPI.\n "
171
+ "line 2: Error: Document or section may not begin with a transition." ,
167
172
),
168
173
]
169
174
170
175
171
- def test_check_failing_distribution (monkeypatch , capsys , caplog ):
172
- renderer = pretend .stub (render = pretend .call_recorder (lambda * a , ** kw : None ))
173
- package = pretend .stub (
174
- metadata_dictionary = lambda : {
175
- "description" : "blah" ,
176
- "description_content_type" : "text/markdown" ,
177
- }
176
+ def test_fails_rst_no_content (tmp_path , capsys , caplog ):
177
+ sdist = build_sdist (
178
+ tmp_path ,
179
+ {
180
+ "setup.cfg" : (
181
+ """
182
+ [metadata]
183
+ name = test-package
184
+ version = 0.0.1
185
+ long_description = file:README.rst
186
+ long_description_content_type = text/x-rst
187
+ """
188
+ ),
189
+ "README.rst" : (
190
+ """
191
+ test-package
192
+ ============
193
+ """
194
+ ),
195
+ },
178
196
)
179
- warning_stream = "Syntax error"
180
-
181
- monkeypatch .setattr (check , "_RENDERERS" , {None : renderer })
182
- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
183
- monkeypatch .setattr (
184
- package_file ,
185
- "PackageFile" ,
186
- pretend .stub (from_filename = lambda * a , ** kw : package ),
187
- )
188
- monkeypatch .setattr (check , "_WarningStream" , lambda : warning_stream )
189
197
190
- assert check .check (["dist/*" ])
198
+ assert check .check ([sdist ])
199
+
200
+ assert capsys .readouterr ().out == f"Checking { sdist } : FAILED\n "
191
201
192
- assert capsys .readouterr ().out == "Checking dist/dist.tar.gz: FAILED\n "
193
202
assert caplog .record_tuples == [
194
203
(
195
204
"twine.commands.check" ,
196
205
logging .ERROR ,
197
- "`long_description` has syntax errors in markup and would not be rendered "
198
- "on PyPI.\n Syntax error " ,
206
+ "`long_description` has syntax errors in markup "
207
+ "and would not be rendered on PyPI.\n " ,
199
208
),
200
209
]
201
- assert renderer .render .calls == [pretend .call ("blah" , stream = warning_stream )]
210
+
211
+
212
+ def test_passes_rst_description (tmp_path , capsys , caplog ):
213
+ sdist = build_sdist (
214
+ tmp_path ,
215
+ {
216
+ "setup.cfg" : (
217
+ """
218
+ [metadata]
219
+ name = test-package
220
+ version = 0.0.1
221
+ long_description = file:README.rst
222
+ long_description_content_type = text/x-rst
223
+ """
224
+ ),
225
+ "README.rst" : (
226
+ """
227
+ test-package
228
+ ============
229
+
230
+ A test package.
231
+ """
232
+ ),
233
+ },
234
+ )
235
+
236
+ assert not check .check ([sdist ])
237
+
238
+ assert capsys .readouterr ().out == f"Checking { sdist } : PASSED\n "
239
+
240
+ assert not caplog .record_tuples
241
+
242
+
243
+ @pytest .mark .parametrize ("content_type" , ["text/markdown" , "text/plain" ])
244
+ def test_passes_markdown_description (content_type , tmp_path , capsys , caplog ):
245
+ sdist = build_sdist (
246
+ tmp_path ,
247
+ {
248
+ "setup.cfg" : (
249
+ f"""
250
+ [metadata]
251
+ name = test-package
252
+ version = 0.0.1
253
+ long_description = file:README.md
254
+ long_description_content_type = { content_type }
255
+ """
256
+ ),
257
+ "README.md" : (
258
+ """
259
+ # test-package
260
+
261
+ A test package.
262
+ """
263
+ ),
264
+ },
265
+ )
266
+
267
+ assert not check .check ([sdist ])
268
+
269
+ assert capsys .readouterr ().out == f"Checking { sdist } : PASSED\n "
270
+
271
+ assert not caplog .record_tuples
202
272
203
273
204
274
def test_main (monkeypatch ):
0 commit comments