1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414import logging
15+ import textwrap
1516
17+ import build
1618import pretend
1719import pytest
1820
19- from twine import commands
20- from twine import package as package_file
2121from twine .commands import check
2222
2323
@@ -45,10 +45,17 @@ def test_str_representation(self):
4545 assert str (self .stream ) == "result"
4646
4747
48- def test_check_no_distributions (monkeypatch , caplog ):
49- monkeypatch .setattr (commands , "_find_dists" , lambda a : [])
48+ def test_main (monkeypatch ):
49+ check_result = pretend .stub ()
50+ check_stub = pretend .call_recorder (lambda a , strict = False : check_result )
51+ monkeypatch .setattr (check , "check" , check_stub )
52+
53+ assert check .main (["dist/*" ]) == check_result
54+ assert check_stub .calls == [pretend .call (["dist/*" ], strict = False )]
55+
5056
51- assert not check .check (["dist/*" ])
57+ def test_fails_no_distributions (caplog ):
58+ assert not check .check ([])
5259 assert caplog .record_tuples == [
5360 (
5461 "twine.commands.check" ,
@@ -58,76 +65,51 @@ def test_check_no_distributions(monkeypatch, caplog):
5865 ]
5966
6067
61- def test_check_passing_distribution (monkeypatch , capsys ):
62- renderer = pretend .stub (render = pretend .call_recorder (lambda * a , ** kw : "valid" ))
63- package = pretend .stub (
64- metadata_dictionary = lambda : {
65- "description" : "blah" ,
66- "description_content_type" : "text/markdown" ,
67- }
68- )
69- warning_stream = ""
70-
71- monkeypatch .setattr (check , "_RENDERERS" , {None : renderer })
72- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
73- monkeypatch .setattr (
74- package_file ,
75- "PackageFile" ,
76- pretend .stub (from_filename = lambda * a , ** kw : package ),
77- )
78- monkeypatch .setattr (check , "_WarningStream" , lambda : warning_stream )
79-
80- assert not check .check (["dist/*" ])
81- assert capsys .readouterr ().out == "Checking dist/dist.tar.gz: PASSED\n "
82- assert renderer .render .calls == [pretend .call ("blah" , stream = warning_stream )]
83-
84-
85- @pytest .mark .parametrize ("content_type" , ["text/plain" , "text/markdown" ])
86- def test_check_passing_distribution_with_none_renderer (
87- content_type ,
88- monkeypatch ,
89- capsys ,
90- ):
91- """Pass when rendering a content type can't fail."""
92- package = pretend .stub (
93- metadata_dictionary = lambda : {
94- "description" : "blah" ,
95- "description_content_type" : content_type ,
96- }
97- )
68+ def build_sdist (src_path , project_files ):
69+ """
70+ Build a source distribution similar to `python3 -m build --sdist`.
9871
99- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
100- monkeypatch .setattr (
101- package_file ,
102- "PackageFile" ,
103- pretend .stub (from_filename = lambda * a , ** kw : package ),
72+ Returns the absolute path of the built distribution.
73+ """
74+ project_files = {
75+ "pyproject.toml" : (
76+ """
77+ [build-system]
78+ requires = ["setuptools"]
79+ build-backend = "setuptools.build_meta"
80+ """
81+ ),
82+ ** project_files ,
83+ }
84+
85+ for filename , content in project_files .items ():
86+ (src_path / filename ).write_text (textwrap .dedent (content ))
87+
88+ builder = build .ProjectBuilder (src_path )
89+ return builder .build ("sdist" , str (src_path / "dist" ))
90+
91+
92+ @pytest .mark .parametrize ("strict" , [False , True ])
93+ def test_warns_missing_description (strict , tmp_path , capsys , caplog ):
94+ sdist = build_sdist (
95+ tmp_path ,
96+ {
97+ "setup.cfg" : (
98+ """
99+ [metadata]
100+ name = test-package
101+ version = 0.0.1
102+ """
103+ ),
104+ },
104105 )
105106
106- assert not check .check (["dist/*" ])
107- assert capsys .readouterr ().out == "Checking dist/dist.tar.gz: PASSED\n "
108-
109-
110- @pytest .mark .parametrize ("description" , [None , "UNKNOWN\n \n " , "UNKNOWN\n \n \n " ])
111- def test_check_no_description (description , monkeypatch , capsys , caplog ):
112- package = pretend .stub (
113- metadata_dictionary = lambda : {
114- "description" : description ,
115- "description_content_type" : None ,
116- }
117- )
107+ assert check .check ([sdist ], strict = strict ) is strict
118108
119- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
120- monkeypatch .setattr (
121- package_file ,
122- "PackageFile" ,
123- pretend .stub (from_filename = lambda * a , ** kw : package ),
109+ assert capsys .readouterr ().out == f"Checking { sdist } : " + (
110+ "FAILED due to warnings\n " if strict else "PASSED with warnings\n "
124111 )
125112
126- assert not check .check (["dist/*" ])
127-
128- assert capsys .readouterr ().out == (
129- "Checking dist/dist.tar.gz: PASSED with warnings\n "
130- )
131113 assert caplog .record_tuples == [
132114 (
133115 "twine.commands.check" ,
@@ -142,80 +124,138 @@ def test_check_no_description(description, monkeypatch, capsys, caplog):
142124 ]
143125
144126
145- def test_strict_fails_on_warnings (monkeypatch , capsys , caplog ):
146- package = pretend .stub (
147- metadata_dictionary = lambda : {
148- "description" : None ,
149- "description_content_type" : None ,
150- }
127+ def test_fails_rst_syntax_error (tmp_path , capsys , caplog ):
128+ sdist = build_sdist (
129+ tmp_path ,
130+ {
131+ "setup.cfg" : (
132+ """
133+ [metadata]
134+ name = test-package
135+ version = 0.0.1
136+ long_description = file:README.rst
137+ long_description_content_type = text/x-rst
138+ """
139+ ),
140+ "README.rst" : (
141+ """
142+ ============
143+ """
144+ ),
145+ },
151146 )
152147
153- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
154- monkeypatch .setattr (
155- package_file ,
156- "PackageFile" ,
157- pretend .stub (from_filename = lambda * a , ** kw : package ),
158- )
148+ assert check .check ([sdist ])
159149
160- assert check . check ([ "dist/*" ], strict = True )
150+ assert capsys . readouterr (). out == f"Checking { sdist } : FAILED \n "
161151
162- assert capsys .readouterr ().out == (
163- "Checking dist/dist.tar.gz: FAILED due to warnings\n "
164- )
165152 assert caplog .record_tuples == [
166153 (
167154 "twine.commands.check" ,
168- logging .WARNING ,
169- "`long_description_content_type` missing. defaulting to `text/x-rst`." ,
170- ),
171- (
172- "twine.commands.check" ,
173- logging .WARNING ,
174- "`long_description` missing." ,
155+ logging .ERROR ,
156+ "`long_description` has syntax errors in markup "
157+ "and would not be rendered on PyPI.\n "
158+ "line 2: Error: Document or section may not begin with a transition." ,
175159 ),
176160 ]
177161
178162
179- def test_check_failing_distribution (monkeypatch , capsys , caplog ):
180- renderer = pretend .stub (render = pretend .call_recorder (lambda * a , ** kw : None ))
181- package = pretend .stub (
182- metadata_dictionary = lambda : {
183- "description" : "blah" ,
184- "description_content_type" : "text/markdown" ,
185- }
186- )
187- warning_stream = "Syntax error"
188-
189- monkeypatch .setattr (check , "_RENDERERS" , {None : renderer })
190- monkeypatch .setattr (commands , "_find_dists" , lambda a : ["dist/dist.tar.gz" ])
191- monkeypatch .setattr (
192- package_file ,
193- "PackageFile" ,
194- pretend .stub (from_filename = lambda * a , ** kw : package ),
163+ def test_fails_rst_no_content (tmp_path , capsys , caplog ):
164+ sdist = build_sdist (
165+ tmp_path ,
166+ {
167+ "setup.cfg" : (
168+ """
169+ [metadata]
170+ name = test-package
171+ version = 0.0.1
172+ long_description = file:README.rst
173+ long_description_content_type = text/x-rst
174+ """
175+ ),
176+ "README.rst" : (
177+ """
178+ test-package
179+ ============
180+ """
181+ ),
182+ },
195183 )
196- monkeypatch .setattr (check , "_WarningStream" , lambda : warning_stream )
197184
198- assert check .check (["dist/*" ])
185+ assert check .check ([sdist ])
186+
187+ assert capsys .readouterr ().out == f"Checking { sdist } : FAILED\n "
199188
200- assert capsys .readouterr ().out == "Checking dist/dist.tar.gz: FAILED\n "
201189 assert caplog .record_tuples == [
202190 (
203191 "twine.commands.check" ,
204192 logging .ERROR ,
205- "`long_description` has syntax errors in markup and would not be rendered "
206- "on PyPI.\n Syntax error " ,
193+ "`long_description` has syntax errors in markup "
194+ "and would not be rendered on PyPI.\n " ,
207195 ),
208196 ]
209- assert renderer .render .calls == [pretend .call ("blah" , stream = warning_stream )]
210197
211198
212- def test_main (monkeypatch ):
213- check_result = pretend .stub ()
214- check_stub = pretend .call_recorder (lambda a , strict = False : check_result )
215- monkeypatch .setattr (check , "check" , check_stub )
199+ def test_passes_rst_description (tmp_path , capsys , caplog ):
200+ sdist = build_sdist (
201+ tmp_path ,
202+ {
203+ "setup.cfg" : (
204+ """
205+ [metadata]
206+ name = test-package
207+ version = 0.0.1
208+ long_description = file:README.rst
209+ long_description_content_type = text/x-rst
210+ """
211+ ),
212+ "README.rst" : (
213+ """
214+ test-package
215+ ============
216+
217+ A test package.
218+ """
219+ ),
220+ },
221+ )
216222
217- assert check .main (["dist/*" ]) == check_result
218- assert check_stub .calls == [pretend .call (["dist/*" ], strict = False )]
223+ assert not check .check ([sdist ])
224+
225+ assert capsys .readouterr ().out == f"Checking { sdist } : PASSED\n "
226+
227+ assert not caplog .record_tuples
228+
229+
230+ @pytest .mark .parametrize ("content_type" , ["text/markdown" , "text/plain" ])
231+ def test_passes_markdown_description (content_type , tmp_path , capsys , caplog ):
232+ sdist = build_sdist (
233+ tmp_path ,
234+ {
235+ "setup.cfg" : (
236+ f"""
237+ [metadata]
238+ name = test-package
239+ version = 0.0.1
240+ long_description = file:README.md
241+ long_description_content_type = { content_type }
242+ """
243+ ),
244+ "README.md" : (
245+ """
246+ # test-package
247+
248+ A test package.
249+ """
250+ ),
251+ },
252+ )
253+
254+ assert not check .check ([sdist ])
255+
256+ assert capsys .readouterr ().out == f"Checking { sdist } : PASSED\n "
257+
258+ assert not caplog .record_tuples
219259
220260
221261# TODO: Test print() color output
0 commit comments