Option C Tools
Loading...
Searching...
No Matches
test_progress.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# tests/tests_core/test_progress.py
4
5"""
6Purpose
7-------
8Regression tests for :class:`oct.core.progress.ProgressTracker` and
9:class:`oct.core.progress.Dashboard`.
10
11Responsibilities
12----------------
13- Verify ProgressTracker lifecycle (start, complete, fail, skip) and markers.
14- Verify Dashboard in-place updates, timer, quiet mode, and non-TTY fallback.
15
16Diagnostics
17-----------
18Domain: CORE-TESTS
19Levels:
20 L2 — test lifecycle
21 L3 — assertion details
22 L4 — deep tracing
23
24Contracts
25---------
26- All output is captured via ``io.StringIO``; no real terminal writes.
27"""
28
29import io
30import threading
31import time
32
33from oct.core.progress import Dashboard, ProgressTracker
34
35
36def _make_tracker(tasks, **kwargs):
37 buf = io.StringIO()
38 kwargs.setdefault("stream", buf)
39 return ProgressTracker(tasks, **kwargs), buf
40
41
43
45 tracker, buf = _make_tracker(["A", "B", "C"])
46 for name in ("A", "B", "C"):
47 tracker.start_task(name)
48 tracker.complete_task(name, summary=f"{name} done")
49 output = buf.getvalue()
50 assert "[x] A A done" in output
51 assert "[x] B B done" in output
52 assert "[x] C C done" in output
53
54 def test_fail_task(self):
55 tracker, buf = _make_tracker(["X"])
56 tracker.start_task("X")
57 tracker.fail_task("X", summary="TIMEOUT")
58 assert "[!] X TIMEOUT" in buf.getvalue()
59
60 def test_skip_task(self):
61 tracker, buf = _make_tracker(["X"])
62 tracker.start_task("X")
63 tracker.skip_task("X", summary="skipped")
64 assert "[-] X skipped" in buf.getvalue()
65
66
68
70 tracker, buf = _make_tracker(["T"])
71 with tracker.task("T"):
72 pass
73 assert "[x] T" in buf.getvalue()
74
76 tracker, buf = _make_tracker(["T"])
77 try:
78 with tracker.task("T"):
79 raise ValueError("boom")
80 except ValueError:
81 pass
82 assert "[!] T" in buf.getvalue()
83
84
86
87 def test_quiet_mode(self):
88 tracker, buf = _make_tracker(["A"], quiet=True)
89 tracker.start_task("A")
90 tracker.complete_task("A", summary="done")
91 tracker.finish()
92 assert buf.getvalue() == ""
93
94
96
98 tracker, buf = _make_tracker(["Counter"])
99 tracker.start_task("Counter", total=1000)
100
101 def tick_100():
102 for _ in range(100):
103 tracker.tick()
104
105 threads = [threading.Thread(target=tick_100) for _ in range(10)]
106 for t in threads:
107 t.start()
108 for t in threads:
109 t.join()
110
111 assert tracker._progress == 1000
112
113
115
117 tracker, buf = _make_tracker(["Slow"])
118 tracker.start_task("Slow", total=0)
119 output = buf.getvalue()
120 assert "[start] Slow" in output
121
123 tracker, buf = _make_tracker(["X"])
124 tracker.start_task("X", total=10)
125 tracker.tick(0)
126 assert tracker._progress == 0
127
128
130
132 tracker, buf = _make_tracker(["A"])
133 tracker.start_task("A")
134 tracker.complete_task("A", summary="ok")
135 output = buf.getvalue()
136 assert "[start] A" in output
137 assert "[x] A ok" in output
138 assert "\033" not in output
139
140
142
144 tracker, buf = _make_tracker(["A"])
145 tracker.complete_task("nonexistent")
146 tracker.fail_task("nonexistent")
147 tracker.skip_task("nonexistent")
148 assert buf.getvalue() == ""
149
151 tracker, buf = _make_tracker(["A"], title="oct health")
152 assert "oct health" in buf.getvalue()
153
155 tracker, buf = _make_tracker(["A", "B"])
156 tracker.start_task("A")
157 tracker.complete_task("A")
158 tracker.finish()
159 output = buf.getvalue()
160 assert "[x] A" in output
161 assert "[ ] B" in output
162
163
164# ============================================================================
165# Dashboard tests
166# ============================================================================
167
168
169def _make_dashboard(**kwargs):
170 buf = io.StringIO()
171 kwargs.setdefault("stream", buf)
172 return Dashboard(**kwargs), buf
173
174
176
178 db, buf = _make_dashboard()
179 db.render(["line0", "line1", "line2"], tasks_total=1)
180 assert len(db._lines) == 3
181
183 db, buf = _make_dashboard()
184 db.render(["aaa", "bbb"], tasks_total=1)
185 assert buf.getvalue() == ""
186
188 db, buf = _make_dashboard()
189 db.render(["[ ] A", "footer", "==="], footer_line=1, tasks_total=1)
190 db.update_line(0, "[x] A done")
191 db.complete_task()
192 db.finish()
193 output = buf.getvalue()
194 assert "[x] A done" in output
195 assert "===" in output
196
197
199
201 db, buf = _make_dashboard()
202 db.render(["old0", "old1", "old2"], tasks_total=1)
203 db.update_line(1, "new1")
204 assert db._lines[1] == "new1"
205
207 db, buf = _make_dashboard()
208 db.render(["a", "b"], tasks_total=1)
209 db.update_line(5, "nope")
210 db.update_line(-1, "nope")
211 assert db._lines == ["a", "b"]
212
213
215
217 db, buf = _make_dashboard(quiet=True)
218 db.render(["a", "b", "c"], tasks_total=1)
219 db.set_task("X")
220 db.update_line(0, "changed")
221 db.complete_task()
222 db.finish()
223 assert buf.getvalue() == ""
224
225
227
229 db, buf = _make_dashboard()
230 db.render(["a", "footer", "end"], footer_line=1, tasks_total=3)
231 db.complete_task()
232 db.complete_task()
233 assert db._tasks_done == 2
234
236 db, buf = _make_dashboard()
237 db.render(["a", "footer", "end"], footer_line=1, tasks_total=1)
238 db.set_task("Test suite")
239 assert db._task_name == "Test suite"
240
242 db, buf = _make_dashboard()
243 db.render(["a", "footer", "end"], footer_line=1, tasks_total=1)
244 db.set_task("X")
245 db.complete_task()
246 assert db._task_name is None
247
248
250
252 db, buf = _make_dashboard()
253 db.render(["header", "footer", "==="], footer_line=1, tasks_total=2)
254 db.complete_task()
255 db.complete_task()
256 db.finish()
257 output = buf.getvalue()
258 assert "All 2 checks completed" in output
259
261 db, buf = _make_dashboard()
262 db.render(["a", "b", "c"], tasks_total=1)
263 db.finish()
264 assert db._timer_thread is None
265
266
268
270 db, buf = _make_dashboard()
271 db.render(["header", "footer", "==="], footer_line=1, tasks_total=1)
272 db.set_task("Slow")
273 time.sleep(0.05)
274 db._update_footer()
275 assert "Slow" in db._lines[1]
276 assert "elapsed" in db._lines[1]
277 db.finish()
_make_tracker(tasks, **kwargs)