-
Notifications
You must be signed in to change notification settings - Fork 0
feat(reporting): vitest-style TUI reporter with real-time file streaming #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… stdout Separates diagnostic output from test results for a cleaner terminal: - LogRedirect: redirects stderr (fd 2) to /tmp/tach_<uuid>.log so [tach:*] and [worker:*] diagnostic messages are captured to file - TachReporter: all render methods (file list, summary, failures) now output to stdout via println!() instead of eprintln!() - Spinner draw target set to stdout so progress is visible - Color detection uses stdout (supports_colors_stdout) since stderr may be redirected to a log file - ProgressReporter::should_use_progress_bar checks stdout terminal - Log file path printed after test run completes Only TachReporter is changed; other reporters (Dots, Progress, Human, Json) remain on stderr for backward compatibility.
- LogRedirect now uses /tmp/tach.log instead of /tmp/tach_<uuid>.log, preventing stale log file accumulation across runs - Document in main.rs that child processes (Zygote/workers) inherit the stderr redirect intentionally; parent handles fatal errors via reporter - Document in TachReporter::on_error that println! is safe because TachReporter and JsonReporter are mutually exclusive
Files scroll up above the spinner as each file's tests complete, instead of buffering everything until the end (vitest-style UX). - Add on_session_setup() to Reporter trait with per-file test counts - Extract format_file_line() from render_file_list() for reuse - Stream completed files via bar.println() in on_test_finished() - Skip already-streamed files in on_run_finished() (crash edge case) - Wire file count computation in main.rs before run_tests()
- Add test verifying unstreamed files (from worker crashes) are printed in on_run_finished via render_file_list - Change spinner format from "Running tests... 42/1996 (2%)" to "Running 1996 tests · 42 passed · 0 failed" - Add log_path field to TachReporter with set_log_path() setter, displayed as 4th line in summary block - Remove duplicate log path printing from execute_session in main.rs
- H1: Move set_log_path() after LogRedirect::new() succeeds so summary only shows log path when redirect actually works. Add set_log_path to Reporter trait (default no-op) and MultiReporter (forwards to children). - H3: Check dup(2) return value in test_stderr_captured_to_log_file before passing to File::from_raw_fd. - M6: Use fcntl(F_DUPFD_CLOEXEC) instead of dup(2) to prevent saved stderr fd from leaking into child processes (Zygote, workers).
…rence - Fix extra blank line when all files were already streamed in real-time by only printing the newline if there are unstreamed files to display - Align summary labels to consistent 13-char column width (Tests, Duration, Log file were 1 char short vs Test Files) - Change Reporter::on_session_setup to take &HashMap instead of owned HashMap, eliminating unnecessary clones in MultiReporter - Change Reporter::set_log_path to take &str instead of String, only TachReporter calls .to_owned() - Update stale doc comment in logredirect.rs to reflect fcntl(F_DUPFD_CLOEXEC) usage instead of dup
|
Caution Review failedThe pull request is closed. 📝 WalkthroughWalkthroughThis pull request implements the first phase of a TUI-like reporting system by adding stderr log redirection, per-file test count tracking, and real-time streaming of file results to stdout. New LogRedirect module handles fd-level redirection; Reporter trait expanded with session setup and log path methods; TachReporter refactored to stream results incrementally during test execution. Changes
Sequence Diagram(s)sequenceDiagram
participant Main as Main<br/>Session
participant LogRedir as LogRedirect<br/>(fd 2)
participant Reporter as TachReporter<br/>Reporter
participant TestRunner as Test<br/>Scheduler
participant Stdout as Stdout
Main->>LogRedir: new() create log redirect
LogRedir->>LogRedir: dup2(fd 2 → log file)
LogRedir-->>Main: return LogRedirect
Main->>Reporter: on_session_setup(file_counts)
Reporter->>Reporter: store file_expected map
Main->>Reporter: set_log_path(path)
Reporter->>Reporter: store log_path
TestRunner->>TestRunner: run tests per file
TestRunner->>Stdout: (diagnostics via fd 2<br/>redirected to log)
rect rgba(100, 200, 100, 0.5)
TestRunner->>Reporter: on_test_finished(file_result)
Reporter->>Reporter: check files_streamed
Reporter->>Stdout: format_file_line(per-file<br/>summary)
Reporter->>Stdout: render failures<br/>with icons
Reporter->>Reporter: mark file as streamed
end
Main->>LogRedir: drop()
LogRedir->>LogRedir: dup2(fd 2 → original)
LogRedir->>Stdout: restore stderr
Main->>Stdout: final summary<br/>(with log path)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
[tach:*]and[worker:*]stderr logs to/tmp/tach.logusing fd-level redirection (fcntl(F_DUPFD_CLOEXEC)/dup2)bar.println()as each test file completes — files scroll up above a sticky spinnerRunning N tests · X passed · Y failedChanges
src/reporting/logredirect.rs— stderr-to-file redirect with RAII restoresrc/reporting/reporter.rs— TachReporter gains real-time streaming, per-file tracking, improved spinner, aligned summarysrc/main.rs— wire log redirect and per-file test countssrc/reporting/mod.rs,src/lib.rs— module exportsTest plan
Summary by CodeRabbit
New Features
Bug Fixes