speiidev 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/tests/test_cli.py CHANGED
@@ -62,7 +62,20 @@ class TestCLIHelpers(unittest.TestCase):
62
62
  self.assertEqual(res.returncode, 0)
63
63
  self.assertTrue(len(res.stdout.strip()) > 0)
64
64
 
65
- def test_block_font_executable(self):
65
+ def test_versions_consistent(self):
66
+ """All version fields must agree (single source of truth)."""
67
+ res = subprocess.run(
68
+ [sys.executable, "scripts/bump_version.py", "--check"],
69
+ capture_output=True,
70
+ text=True,
71
+ cwd=str(ROOT_DIR),
72
+ )
73
+ self.assertEqual(
74
+ res.returncode,
75
+ 0,
76
+ msg=f"Version mismatch:\n{res.stdout}\n{res.stderr}",
77
+ )
78
+ def test_block_font_runner_script(self):
66
79
  """Running block-font runner script should exit with 0."""
67
80
  block_font_script = ROOT_DIR / "bin" / "block-font"
68
81
  if not block_font_script.exists():
@@ -77,6 +90,120 @@ class TestCLIHelpers(unittest.TestCase):
77
90
  self.assertEqual(res.returncode, 0)
78
91
  self.assertIn("█", res.stdout)
79
92
 
93
+ def test_print_banner_responsive_widths(self):
94
+ """Banner must dynamically scale and never overflow terminal width on resize."""
95
+ from rich.console import Console
96
+ import autodev.cli as cli
97
+
98
+ state = cli.AgentState()
99
+ for width in [120, 86, 80, 75, 60, 48, 35]:
100
+ c = Console(width=width, height=24, color_system=None)
101
+ cli.console = c
102
+ with c.capture() as cap:
103
+ cli.print_banner(state)
104
+ out = cap.get()
105
+ for line in out.splitlines():
106
+ self.assertLessEqual(
107
+ len(line),
108
+ width,
109
+ f"Banner line exceeded terminal width {width}: {repr(line)}",
110
+ )
111
+
112
+ # Specifically verify 80-column terminal layout displays Claude 3D title art
113
+ c80 = Console(width=80, height=24, color_system=None)
114
+ cli.console = c80
115
+ with c80.capture() as cap:
116
+ cli.print_banner(state)
117
+ out80 = cap.get()
118
+ self.assertIn("▄██████╗", out80, "Expected Claude 3D font at 80 columns")
119
+ self.assertIn("repo", out80)
120
+ self.assertIn("plan", out80)
121
+ self.assertIn("build", out80)
122
+
123
+ def test_interactive_repl_resize_hook(self):
124
+ """Interactive REPL resize hook must debounce and re-render without exception."""
125
+ import asyncio
126
+ from prompt_toolkit import PromptSession
127
+ from prompt_toolkit.input import create_pipe_input
128
+ import autodev.cli as cli
129
+
130
+ with create_pipe_input() as pipe_input:
131
+ session = PromptSession(input=pipe_input)
132
+ orig_on_resize = session.app._on_resize
133
+ resize_timer = [None]
134
+ called = [0]
135
+
136
+ def _do_redraw():
137
+ called[0] += 1
138
+ if getattr(session.app, "is_running", False):
139
+ try:
140
+ session.app.renderer.erase(leave_alternate_screen=False)
141
+ session.app._request_absolute_cursor_position()
142
+ session.app._redraw()
143
+ except Exception:
144
+ orig_on_resize()
145
+
146
+ def _handle_resize():
147
+ try:
148
+ loop = asyncio.get_running_loop()
149
+ if resize_timer[0] is not None:
150
+ resize_timer[0].cancel()
151
+ resize_timer[0] = loop.call_later(0.01, _do_redraw)
152
+ except Exception:
153
+ _do_redraw()
154
+
155
+ session.app._on_resize = _handle_resize
156
+
157
+ pipe_input.send_text("test_cmd\n")
158
+ res = session.prompt("❯ ")
159
+ self.assertEqual(res, "test_cmd")
160
+ # Verify handler can be called directly safely
161
+ session.app._on_resize()
162
+
163
+ def test_agent_stream_view_responsive_dimensions(self):
164
+ """Live stream panel must fit within both terminal width and height on resize."""
165
+ from rich.console import Console
166
+ from collections import deque
167
+ import autodev.cli as cli
168
+
169
+ lines = deque(maxlen=18)
170
+ for i in range(25):
171
+ lines.append(
172
+ f"Step {i}: processing /long/path/to/nested/module/that/could/cause/wrapping/on/narrow/screens/code.py"
173
+ )
174
+
175
+ state = cli.AgentState()
176
+ view = cli._AgentStreamView(
177
+ cmd=["agy", "--mode=accept-edits", "-p", "Execute tasks step-by-step with safety checks"],
178
+ title="Building Application",
179
+ border_color=cli.THEME["builder"],
180
+ badge="[BUILDER]",
181
+ attempt=1,
182
+ state=state,
183
+ lines=lines,
184
+ activity=[("Read", "lib/main.py"), ("Write", "lib/out.py")],
185
+ )
186
+
187
+ for w, h in [(120, 30), (80, 24), (70, 20), (55, 16), (40, 12)]:
188
+ c = Console(width=w, height=h, color_system=None)
189
+ cli.console = c
190
+ with c.capture() as cap:
191
+ c.print(view)
192
+ out = cap.get()
193
+ rendered = out.splitlines()
194
+ self.assertGreater(len(rendered), 0)
195
+ self.assertLessEqual(
196
+ len(rendered),
197
+ h,
198
+ f"Stream view panel height {len(rendered)} exceeded terminal height {h} at {w}x{h}",
199
+ )
200
+ for line in rendered:
201
+ self.assertLessEqual(
202
+ len(line),
203
+ w,
204
+ f"Stream view panel line width {len(line)} exceeded terminal width {w} at {w}x{h}",
205
+ )
206
+
80
207
 
81
208
  if __name__ == "__main__":
82
209
  unittest.main()