Ver código fonte

TASK-5: Add exit command

Registers 'exit' in the command registry — prints "Goodbye!" then sys.exit(0).
Updates Ctrl+C handler to also print "Goodbye!" before breaking.
Adds 4 new tests; updates stale empty-input test to allow Goodbye! on exit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Marius 1 semana atrás
pai
commit
c5a1c34814
5 arquivos alterados com 38 adições e 5 exclusões
  1. 1 1
      README.md
  2. 10 0
      src/commands.py
  3. 1 1
      src/main.py
  4. 23 0
      tests/test_commands.py
  5. 3 3
      tests/test_main.py

+ 1 - 1
README.md

@@ -29,7 +29,7 @@ welcome to the best testapp ever
 | Command | Description |
 |---|---|
 | `help` | Show available commands |
-| `exit` | Exit the application |
+| `exit` | Print "Goodbye!" and exit the application |
 
 Type any unrecognised command and the app will tell you what's available.
 

+ 10 - 0
src/commands.py

@@ -1,8 +1,17 @@
 COMMAND_DESCRIPTIONS = {
     "help": "show available commands",
+    "exit": "exit the application",
 }
 
 
+import sys
+
+
+def _exit():
+    print("Goodbye!")
+    sys.exit(0)
+
+
 def _help():
     lines = ["Available commands:"]
     for name, description in sorted(COMMAND_DESCRIPTIONS.items()):
@@ -12,4 +21,5 @@ def _help():
 
 COMMANDS = {
     "help": _help,
+    "exit": _exit,
 }

+ 1 - 1
src/main.py

@@ -14,7 +14,7 @@ def run():
             else:
                 print(f"Unknown command: {user_input}. Type 'help' for available commands.")
         except KeyboardInterrupt:
-            print("")
+            print("\nGoodbye!")
             break
 
 

+ 23 - 0
tests/test_commands.py

@@ -1,3 +1,4 @@
+import pytest
 from src.commands import COMMANDS
 
 
@@ -19,3 +20,25 @@ def test_unknown_command_not_in_registry():
 def test_all_commands_are_callable():
     for name, handler in COMMANDS.items():
         assert callable(handler), f"Command '{name}' is not callable"
+
+
+def test_exit_raises_system_exit(capsys):
+    with pytest.raises(SystemExit) as exc_info:
+        COMMANDS["exit"]()
+    assert exc_info.value.code == 0
+
+
+def test_exit_prints_goodbye(capsys):
+    with pytest.raises(SystemExit):
+        COMMANDS["exit"]()
+    captured = capsys.readouterr()
+    assert "Goodbye!" in captured.out
+
+
+def test_exit_is_in_registry():
+    assert "exit" in COMMANDS
+
+
+def test_help_mentions_exit():
+    result = COMMANDS["help"]()
+    assert "exit" in result

+ 3 - 3
tests/test_main.py

@@ -51,9 +51,9 @@ def test_repl_empty_input_is_ignored(capsys):
         run()
 
     captured = capsys.readouterr()
-    # Only the welcome message — no "Unknown command" line
-    lines = [l for l in captured.out.strip().splitlines() if l]
-    assert lines == ["welcome to the best testapp ever"]
+    # Welcome message present, no "Unknown command" line
+    assert "welcome to the best testapp ever" in captured.out
+    assert "Unknown command" not in captured.out
 
 
 def test_repl_input_is_case_insensitive(capsys):