Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions tabcmd/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@

try:
from tabcmd.tabcmd import main
except ImportError as e:
print("Exception thrown running program: `{}`, `{}`".format(e, e.__context__), file=sys.stderr)

except Exception as e:
ctx = ", caused by: {}".format(e.__context__) if e.__context__ else ""
print("Exception thrown importing tabcmd: {}{}".format(e, ctx), file=sys.stderr)
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
print("Application is running in an executable bundle")
print("sys.argv[0] is", sys.argv[0])
print("sys.executable is", sys.executable)
print("Application is running in an executable bundle", file=sys.stderr)
print("sys.argv[0] is", sys.argv[0], file=sys.stderr)
print("sys.executable is", sys.executable, file=sys.stderr)
else:
print("[Possible cause: Tabcmd needs to be run as a module, try running `python -m tabcmd`]", file=sys.stderr)
print(
"[Possible cause: tabcmd is installed but broken, try `pip install --force-reinstall tabcmd`]",
file=sys.stderr,
)
sys.exit(1)


if __name__ == "__main__":
Expand Down
79 changes: 79 additions & 0 deletions tests/test_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import os
import subprocess
import sys
import tempfile
import textwrap
import unittest

_REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))


def _repo_env():
env = dict(os.environ)
env["PYTHONPATH"] = _REPO_ROOT
return env


class TestPythonMTabcmd(unittest.TestCase):
def test_python_m_tabcmd_no_args_exits_zero(self):
result = subprocess.run(
[sys.executable, "-m", "tabcmd"],
capture_output=True,
text=True,
timeout=30,
env=_repo_env(),
)
self.assertEqual(result.returncode, 0, msg="stderr: {}\nstdout: {}".format(result.stderr, result.stdout))

def test_python_m_tabcmd_help_exits_zero(self):
result = subprocess.run(
[sys.executable, "-m", "tabcmd", "--help"],
capture_output=True,
text=True,
timeout=30,
env=_repo_env(),
)
self.assertEqual(result.returncode, 0, msg="stderr: {}\nstdout: {}".format(result.stderr, result.stdout))
self.assertIn("usage:", result.stdout.lower())

def test_python_m_tabcmd_help_subcommand_exits_zero(self):
result = subprocess.run(
[sys.executable, "-m", "tabcmd", "help"],
capture_output=True,
text=True,
timeout=30,
env=_repo_env(),
)
self.assertEqual(result.returncode, 0, msg="stderr: {}\nstdout: {}".format(result.stderr, result.stdout))

def test_import_error_exits_one(self):
# Inject a broken tabcmd.tabcmd into sys.modules before running __main__,
# so the ImportError handler is exercised without relying on sys.path ordering.
script = textwrap.dedent(
"""\
import sys
class _BrokenTabcmd:
def __getattr__(self, _):
raise ImportError("injected failure")
sys.modules["tabcmd.tabcmd"] = _BrokenTabcmd()
import runpy
runpy.run_module("tabcmd", run_name="__main__")
"""
)
with tempfile.TemporaryDirectory() as tmpdir:
script_path = os.path.join(tmpdir, "run.py")
with open(script_path, "w") as f:
f.write(script)
result = subprocess.run(
[sys.executable, script_path],
capture_output=True,
text=True,
timeout=30,
env=_repo_env(),
)
self.assertEqual(result.returncode, 1, msg="stderr: {}\nstdout: {}".format(result.stderr, result.stdout))
self.assertIn("Exception thrown importing tabcmd", result.stderr)


if __name__ == "__main__":
unittest.main()
Loading