Skip to content

Commit

Permalink
Rewrite tests using build
Browse files Browse the repository at this point in the history
  • Loading branch information
bhrutledge committed Mar 27, 2022
1 parent cd9e29f commit ec6e8d9
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 120 deletions.
9 changes: 9 additions & 0 deletions tests/conftest.py
Expand Up @@ -2,11 +2,20 @@
import textwrap

import pytest
import rich

from twine import settings
from twine import utils


def pytest_configure(config):
# Disable color codes and wrapping during tests
rich.reconfigure(
no_color=True,
width=500,
)


@pytest.fixture()
def config_file(tmpdir, monkeypatch):
path = tmpdir / ".pypirc"
Expand Down
280 changes: 160 additions & 120 deletions tests/test_check.py
Expand Up @@ -12,12 +12,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import logging
import textwrap

import build
import pretend
import pytest

from twine import commands
from twine import package as package_file
from twine.commands import check


Expand Down Expand Up @@ -45,10 +45,17 @@ def test_str_representation(self):
assert str(self.stream) == "result"


def test_check_no_distributions(monkeypatch, caplog):
monkeypatch.setattr(commands, "_find_dists", lambda a: [])
def test_main(monkeypatch):
check_result = pretend.stub()
check_stub = pretend.call_recorder(lambda a, strict=False: check_result)
monkeypatch.setattr(check, "check", check_stub)

assert check.main(["dist/*"]) == check_result
assert check_stub.calls == [pretend.call(["dist/*"], strict=False)]


assert not check.check(["dist/*"])
def test_fails_no_distributions(caplog):
assert not check.check([])
assert caplog.record_tuples == [
(
"twine.commands.check",
Expand All @@ -58,76 +65,51 @@ def test_check_no_distributions(monkeypatch, caplog):
]


def test_check_passing_distribution(monkeypatch, capsys):
renderer = pretend.stub(render=pretend.call_recorder(lambda *a, **kw: "valid"))
package = pretend.stub(
metadata_dictionary=lambda: {
"description": "blah",
"description_content_type": "text/markdown",
}
)
warning_stream = ""

monkeypatch.setattr(check, "_RENDERERS", {None: renderer})
monkeypatch.setattr(commands, "_find_dists", lambda a: ["dist/dist.tar.gz"])
monkeypatch.setattr(
package_file,
"PackageFile",
pretend.stub(from_filename=lambda *a, **kw: package),
)
monkeypatch.setattr(check, "_WarningStream", lambda: warning_stream)

assert not check.check(["dist/*"])
assert capsys.readouterr().out == "Checking dist/dist.tar.gz: PASSED\n"
assert renderer.render.calls == [pretend.call("blah", stream=warning_stream)]


@pytest.mark.parametrize("content_type", ["text/plain", "text/markdown"])
def test_check_passing_distribution_with_none_renderer(
content_type,
monkeypatch,
capsys,
):
"""Pass when rendering a content type can't fail."""
package = pretend.stub(
metadata_dictionary=lambda: {
"description": "blah",
"description_content_type": content_type,
}
)
def build_sdist(src_path, project_files):
"""
Build a source distribution similar to `python3 -m build --sdist`.
monkeypatch.setattr(commands, "_find_dists", lambda a: ["dist/dist.tar.gz"])
monkeypatch.setattr(
package_file,
"PackageFile",
pretend.stub(from_filename=lambda *a, **kw: package),
Returns the absolute path of the built distribution.
"""
project_files = {
"pyproject.toml": (
"""
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
"""
),
**project_files,
}

for filename, content in project_files.items():
(src_path / filename).write_text(textwrap.dedent(content))

builder = build.ProjectBuilder(src_path)
return builder.build("sdist", str(src_path / "dist"))


@pytest.mark.parametrize("strict", [False, True])
def test_warns_missing_description(strict, tmp_path, capsys, caplog):
sdist = build_sdist(
tmp_path,
{
"setup.cfg": (
"""
[metadata]
name = test-package
version = 0.0.1
"""
),
},
)

assert not check.check(["dist/*"])
assert capsys.readouterr().out == "Checking dist/dist.tar.gz: PASSED\n"


@pytest.mark.parametrize("description", [None, "UNKNOWN\n\n", "UNKNOWN\n\n\n"])
def test_check_no_description(description, monkeypatch, capsys, caplog):
package = pretend.stub(
metadata_dictionary=lambda: {
"description": description,
"description_content_type": None,
}
)
assert check.check([sdist], strict=strict) is strict

monkeypatch.setattr(commands, "_find_dists", lambda a: ["dist/dist.tar.gz"])
monkeypatch.setattr(
package_file,
"PackageFile",
pretend.stub(from_filename=lambda *a, **kw: package),
assert capsys.readouterr().out == f"Checking {sdist}: " + (
"FAILED due to warnings\n" if strict else "PASSED with warnings\n"
)

assert not check.check(["dist/*"])

assert capsys.readouterr().out == (
"Checking dist/dist.tar.gz: PASSED with warnings\n"
)
assert caplog.record_tuples == [
(
"twine.commands.check",
Expand All @@ -142,80 +124,138 @@ def test_check_no_description(description, monkeypatch, capsys, caplog):
]


def test_strict_fails_on_warnings(monkeypatch, capsys, caplog):
package = pretend.stub(
metadata_dictionary=lambda: {
"description": None,
"description_content_type": None,
}
def test_fails_rst_syntax_error(tmp_path, capsys, caplog):
sdist = build_sdist(
tmp_path,
{
"setup.cfg": (
"""
[metadata]
name = test-package
version = 0.0.1
long_description = file:README.rst
long_description_content_type = text/x-rst
"""
),
"README.rst": (
"""
============
"""
),
},
)

monkeypatch.setattr(commands, "_find_dists", lambda a: ["dist/dist.tar.gz"])
monkeypatch.setattr(
package_file,
"PackageFile",
pretend.stub(from_filename=lambda *a, **kw: package),
)
assert check.check([sdist])

assert check.check(["dist/*"], strict=True)
assert capsys.readouterr().out == f"Checking {sdist}: FAILED\n"

assert capsys.readouterr().out == (
"Checking dist/dist.tar.gz: FAILED due to warnings\n"
)
assert caplog.record_tuples == [
(
"twine.commands.check",
logging.WARNING,
"`long_description_content_type` missing. defaulting to `text/x-rst`.",
),
(
"twine.commands.check",
logging.WARNING,
"`long_description` missing.",
logging.ERROR,
"`long_description` has syntax errors in markup "
"and would not be rendered on PyPI.\n"
"line 2: Error: Document or section may not begin with a transition.",
),
]


def test_check_failing_distribution(monkeypatch, capsys, caplog):
renderer = pretend.stub(render=pretend.call_recorder(lambda *a, **kw: None))
package = pretend.stub(
metadata_dictionary=lambda: {
"description": "blah",
"description_content_type": "text/markdown",
}
)
warning_stream = "Syntax error"

monkeypatch.setattr(check, "_RENDERERS", {None: renderer})
monkeypatch.setattr(commands, "_find_dists", lambda a: ["dist/dist.tar.gz"])
monkeypatch.setattr(
package_file,
"PackageFile",
pretend.stub(from_filename=lambda *a, **kw: package),
def test_fails_rst_no_content(tmp_path, capsys, caplog):
sdist = build_sdist(
tmp_path,
{
"setup.cfg": (
"""
[metadata]
name = test-package
version = 0.0.1
long_description = file:README.rst
long_description_content_type = text/x-rst
"""
),
"README.rst": (
"""
test-package
============
"""
),
},
)
monkeypatch.setattr(check, "_WarningStream", lambda: warning_stream)

assert check.check(["dist/*"])
assert check.check([sdist])

assert capsys.readouterr().out == f"Checking {sdist}: FAILED\n"

assert capsys.readouterr().out == "Checking dist/dist.tar.gz: FAILED\n"
assert caplog.record_tuples == [
(
"twine.commands.check",
logging.ERROR,
"`long_description` has syntax errors in markup and would not be rendered "
"on PyPI.\nSyntax error",
"`long_description` has syntax errors in markup "
"and would not be rendered on PyPI.\n",
),
]
assert renderer.render.calls == [pretend.call("blah", stream=warning_stream)]


def test_main(monkeypatch):
check_result = pretend.stub()
check_stub = pretend.call_recorder(lambda a, strict=False: check_result)
monkeypatch.setattr(check, "check", check_stub)
def test_passes_rst_description(tmp_path, capsys, caplog):
sdist = build_sdist(
tmp_path,
{
"setup.cfg": (
"""
[metadata]
name = test-package
version = 0.0.1
long_description = file:README.rst
long_description_content_type = text/x-rst
"""
),
"README.rst": (
"""
test-package
============
A test package.
"""
),
},
)

assert check.main(["dist/*"]) == check_result
assert check_stub.calls == [pretend.call(["dist/*"], strict=False)]
assert not check.check([sdist])

assert capsys.readouterr().out == f"Checking {sdist}: PASSED\n"

assert not caplog.record_tuples


@pytest.mark.parametrize("content_type", ["text/markdown", "text/plain"])
def test_passes_markdown_description(content_type, tmp_path, capsys, caplog):
sdist = build_sdist(
tmp_path,
{
"setup.cfg": (
f"""
[metadata]
name = test-package
version = 0.0.1
long_description = file:README.md
long_description_content_type = {content_type}
"""
),
"README.md": (
"""
# test-package
A test package.
"""
),
},
)

assert not check.check([sdist])

assert capsys.readouterr().out == f"Checking {sdist}: PASSED\n"

assert not caplog.record_tuples


# TODO: Test print() color output
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Expand Up @@ -9,6 +9,7 @@ deps =
pytest
pytest-cov
pytest-socket
build
passenv =
PYTEST_ADDOPTS
commands =
Expand Down

0 comments on commit ec6e8d9

Please sign in to comment.