|
| 1 | +import os |
| 2 | +import subprocess |
| 3 | +import sys |
| 4 | +import tempfile |
| 5 | +from pathlib import Path |
| 6 | + |
| 7 | +import pytest |
| 8 | + |
| 9 | +import spin as libspin |
| 10 | +from spin.cmds.util import run |
| 11 | + |
| 12 | +skip_on_windows = pytest.mark.skipif( |
| 13 | + sys.platform.startswith("win"), reason="Skipped; platform is Windows" |
| 14 | +) |
| 15 | + |
| 16 | +on_linux = pytest.mark.skipif( |
| 17 | + not sys.platform.startswith("linux"), reason="Skipped; platform not Linux" |
| 18 | +) |
| 19 | + |
| 20 | + |
| 21 | +def spin(*args, **user_kwargs): |
| 22 | + default_kwargs = { |
| 23 | + "stdout": subprocess.PIPE, |
| 24 | + "stderr": subprocess.PIPE, |
| 25 | + "sys_exit": True, |
| 26 | + } |
| 27 | + return run(["spin"] + list(args), **{**default_kwargs, **user_kwargs}) |
| 28 | + |
| 29 | + |
| 30 | +def stdout(p): |
| 31 | + return p.stdout.decode("utf-8").strip() |
| 32 | + |
| 33 | + |
| 34 | +def stderr(p): |
| 35 | + return p.stderr.decode("utf-8").strip() |
| 36 | + |
| 37 | + |
| 38 | +def test_get_version(): |
| 39 | + p = spin("--version") |
| 40 | + assert stdout(p) == f"spin {libspin.__version__}" |
| 41 | + |
| 42 | + |
| 43 | +def test_basic_build(): |
| 44 | + """Does the package build?""" |
| 45 | + spin("build") |
| 46 | + |
| 47 | + assert Path("build").exists(), "`build` folder not created after `spin build`" |
| 48 | + assert Path( |
| 49 | + "build-install" |
| 50 | + ).exists(), "`build-install` folder not created after `spin build`" |
| 51 | + |
| 52 | + |
| 53 | +def test_debug_builds(): |
| 54 | + """Does spin generate gcov debug output files?""" |
| 55 | + spin("build", "--gcov") |
| 56 | + |
| 57 | + debug_files = Path(".").rglob("*.gcno") |
| 58 | + assert len(list(debug_files)) != 0, "debug files not generated for gcov build" |
| 59 | + |
| 60 | + |
| 61 | +def test_expand_pythonpath(): |
| 62 | + """Does an $ENV_VAR get expanded in `spin run`?""" |
| 63 | + output = spin("run", "echo $PYTHONPATH") |
| 64 | + assert any( |
| 65 | + p in stdout(output) for p in ("site-packages", "dist-packages") |
| 66 | + ), f"Expected value of $PYTHONPATH, got {stdout(output)} instead" |
| 67 | + |
| 68 | + |
| 69 | +def test_run_stdout(): |
| 70 | + """Ensure `spin run` only includes command output on stdout.""" |
| 71 | + p = spin( |
| 72 | + "run", |
| 73 | + sys.executable, |
| 74 | + "-c", |
| 75 | + "import sys; del sys.path[0]; import example_pkg; print(example_pkg.__version__)", |
| 76 | + ) |
| 77 | + assert ( |
| 78 | + stdout(p) == "0.0.0dev0" |
| 79 | + ), f"`spin run` stdout did not yield version, but {stdout(p)}" |
| 80 | + |
| 81 | + |
| 82 | +def test_editable_conflict(): |
| 83 | + """Do we warn when a conflicting editable install is present?""" |
| 84 | + try: |
| 85 | + run(["pip", "install", "--quiet", "-e", "."]) |
| 86 | + assert "Warning! An editable installation" in stdout( |
| 87 | + spin("run", "ls") |
| 88 | + ), "Failed to detect and warn about editable install" |
| 89 | + finally: |
| 90 | + run(["pip", "uninstall", "--quiet", "-y", "example_pkg"]) |
| 91 | + |
| 92 | + |
| 93 | +# Detecting whether a file is executable is not that easy on Windows, |
| 94 | +# as it seems to take into consideration whether that file is associated as an executable. |
| 95 | +@skip_on_windows |
| 96 | +def test_recommend_run_python(): |
| 97 | + """If `spin run file.py` is called, is `spin run python file.py` recommended?""" |
| 98 | + with tempfile.NamedTemporaryFile(suffix=".py") as f: |
| 99 | + p = spin("run", f.name, sys_exit=False) |
| 100 | + assert "Did you mean to call" in stdout( |
| 101 | + p |
| 102 | + ), "Failed to recommend `python run python file.py`" |
| 103 | + |
| 104 | + |
| 105 | +def test_test(): |
| 106 | + """Does the test command run?""" |
| 107 | + spin("test") |
| 108 | + |
| 109 | + |
| 110 | +def test_test_with_pythonpath(): |
| 111 | + """Does `spin test` work when PYTHONPATH is set?""" |
| 112 | + spin("test", env={**os.environ, "PYTHONPATH": "/tmp"}) |
| 113 | + |
| 114 | + |
| 115 | +def test_sdist(): |
| 116 | + spin("sdist") |
| 117 | + |
| 118 | + |
| 119 | +def test_example(): |
| 120 | + spin("example") |
| 121 | + |
| 122 | + |
| 123 | +def test_docs(): |
| 124 | + run(["pip", "install", "--quiet", "sphinx"]) |
| 125 | + spin("docs") |
| 126 | + |
| 127 | + |
| 128 | +def test_spin_install(): |
| 129 | + cwd = os.getcwd() |
| 130 | + spin("install") |
| 131 | + with tempfile.TemporaryDirectory() as d: |
| 132 | + try: |
| 133 | + os.chdir(d) |
| 134 | + p = run( |
| 135 | + [ |
| 136 | + sys.executable, |
| 137 | + "-c", |
| 138 | + "import example_pkg; print(example_pkg.__version__)", |
| 139 | + ], |
| 140 | + stdout=subprocess.PIPE, |
| 141 | + ) |
| 142 | + assert stdout(p) == "0.0.0dev0" |
| 143 | + finally: |
| 144 | + os.chdir(cwd) |
| 145 | + run(["pip", "uninstall", "-y", "--quiet", "example_pkg"]) |
| 146 | + |
| 147 | + |
| 148 | +@on_linux |
| 149 | +def test_gdb(): |
| 150 | + p = spin( |
| 151 | + "gdb", |
| 152 | + "-c", |
| 153 | + 'import example_pkg; example_pkg.echo("hi")', |
| 154 | + "--", |
| 155 | + "--eval", |
| 156 | + "run", |
| 157 | + "--batch", |
| 158 | + ) |
| 159 | + assert "hi" in stdout(p) |
0 commit comments