| 1 | """ |
| 2 | Pytest configuration and fixtures for interactive tests. |
| 3 | """ |
| 4 | |
| 5 | import os |
| 6 | import pytest |
| 7 | from pathlib import Path |
| 8 | |
| 9 | # Add current directory to path for imports |
| 10 | import sys |
| 11 | sys.path.insert(0, str(Path(__file__).parent)) |
| 12 | |
| 13 | from shell_pty import ShellPTY, FortshTestSession |
| 14 | |
| 15 | |
| 16 | def find_shell_binary() -> str: |
| 17 | """Find the fortsh binary.""" |
| 18 | candidates = [ |
| 19 | "./bin/fortsh", |
| 20 | "../bin/fortsh", |
| 21 | "../../bin/fortsh", |
| 22 | "../fortsh/bin/fortsh", |
| 23 | ] |
| 24 | |
| 25 | env_path = os.environ.get('FORTSH') |
| 26 | if env_path: |
| 27 | candidates.insert(0, env_path) |
| 28 | |
| 29 | for path in candidates: |
| 30 | if os.path.isfile(path) and os.access(path, os.X_OK): |
| 31 | return path |
| 32 | |
| 33 | return "./bin/fortsh" |
| 34 | |
| 35 | |
| 36 | @pytest.fixture |
| 37 | def shell_path(): |
| 38 | """Fixture providing the path to fortsh binary.""" |
| 39 | return find_shell_binary() |
| 40 | |
| 41 | |
| 42 | @pytest.fixture |
| 43 | def shell(shell_path): |
| 44 | """ |
| 45 | Fixture providing a running fortsh session. |
| 46 | |
| 47 | The session is automatically started and stopped. |
| 48 | |
| 49 | Usage: |
| 50 | def test_something(fortsh): |
| 51 | fortsh.send_line("echo hello") |
| 52 | output = fortsh.wait_for_prompt() |
| 53 | assert "hello" in output |
| 54 | """ |
| 55 | pty = ShellPTY(shell_path=shell_path) |
| 56 | pty.start(rc_file="/dev/null") |
| 57 | yield pty |
| 58 | pty.stop() |
| 59 | |
| 60 | |
| 61 | @pytest.fixture |
| 62 | def shell_with_rc(shell_path): |
| 63 | """ |
| 64 | Fixture providing a fortsh session with default rc file. |
| 65 | |
| 66 | Uses the user's .shellrc for testing rc-dependent features. |
| 67 | """ |
| 68 | pty = ShellPTY(shell_path=shell_path) |
| 69 | pty.start() # Uses default rc |
| 70 | yield pty |
| 71 | pty.stop() |
| 72 | |
| 73 | |
| 74 | @pytest.fixture |
| 75 | def shell_factory(shell_path): |
| 76 | """ |
| 77 | Fixture factory for creating multiple fortsh sessions. |
| 78 | |
| 79 | Usage: |
| 80 | def test_multiple_shells(shell_factory): |
| 81 | shell1 = shell_factory() |
| 82 | shell2 = shell_factory() |
| 83 | # Test interaction between shells |
| 84 | """ |
| 85 | sessions = [] |
| 86 | |
| 87 | def create(**kwargs): |
| 88 | pty = ShellPTY(shell_path=shell_path, **kwargs) |
| 89 | pty.start(rc_file="/dev/null") |
| 90 | sessions.append(pty) |
| 91 | return pty |
| 92 | |
| 93 | yield create |
| 94 | |
| 95 | # Cleanup all sessions |
| 96 | for pty in sessions: |
| 97 | try: |
| 98 | pty.stop() |
| 99 | except: |
| 100 | pass |
| 101 | |
| 102 | |
| 103 | # Markers for test categorization |
| 104 | def pytest_configure(config): |
| 105 | """Register custom markers.""" |
| 106 | config.addinivalue_line( |
| 107 | "markers", "line_editing: tests for line editing features" |
| 108 | ) |
| 109 | config.addinivalue_line( |
| 110 | "markers", "history: tests for history features" |
| 111 | ) |
| 112 | config.addinivalue_line( |
| 113 | "markers", "completion: tests for tab completion" |
| 114 | ) |
| 115 | config.addinivalue_line( |
| 116 | "markers", "signals: tests for signal handling" |
| 117 | ) |
| 118 | config.addinivalue_line( |
| 119 | "markers", "job_control: tests for job control" |
| 120 | ) |
| 121 | config.addinivalue_line( |
| 122 | "markers", "prompt: tests for prompt features" |
| 123 | ) |
| 124 | config.addinivalue_line( |
| 125 | "markers", "slow: marks tests as slow" |
| 126 | ) |