refactor to improve testability and modularization of the mainline terminal application #24

Merged
genewildish merged 4 commits from klubhaus/sideline:testability_modularization into main 2026-03-16 09:11:14 +00:00
Contributor

Summary

Changes

Phase 1 - Testability Improvements

  • Extract configuration to engine/config.py with full type hints
  • Add centralized Config dataclass with CLI argument parsing
  • Create comprehensive test suite for configuration

Phase 2 - Modularization of Scroll Engine

  • Refactor engine/scroll.py - cleaner separation of concerns
  • Extract viewport handling to engine/viewport.py
  • Extract frame timing to engine/frame.py
  • Add viewport and frame tests

Phase 3 - API Efficiency

  • Optimize rendering pipeline to reduce redundant passes
  • Improve layer composition in engine/layers.py
  • Add layer rendering tests

Phase 4 - Event-Driven Architecture

  • Add engine/eventbus.py - thread-safe event publishing
  • Add engine/events.py - event type definitions
  • Add engine/emitters.py - emitter protocols
  • Add engine/controller.py - coordinates ntfy/mic monitoring

Testing

  • 29 files changed, +2261 -185 lines
  • Added comprehensive test coverage:
    • test_config.py - Config dataclass and CLI parsing
    • test_controller.py - StreamController
    • test_emitters.py - Emitter protocols
    • test_eventbus.py - EventBus thread-safety
    • test_events.py - Event types
    • test_frame.py - Frame timing
    • test_layers.py - Layer rendering
    • test_mic.py - Microphone monitor
    • test_ntfy.py - NTFY poller
    • test_types.py - Type definitions
    • test_viewport.py - Terminal dimensions

All existing tests pass.

## Summary ## Changes ### Phase 1 - Testability Improvements - Extract configuration to `engine/config.py` with full type hints - Add centralized Config dataclass with CLI argument parsing - Create comprehensive test suite for configuration ### Phase 2 - Modularization of Scroll Engine - Refactor `engine/scroll.py` - cleaner separation of concerns - Extract viewport handling to `engine/viewport.py` - Extract frame timing to `engine/frame.py` - Add viewport and frame tests ### Phase 3 - API Efficiency - Optimize rendering pipeline to reduce redundant passes - Improve layer composition in `engine/layers.py` - Add layer rendering tests ### Phase 4 - Event-Driven Architecture - Add `engine/eventbus.py` - thread-safe event publishing - Add `engine/events.py` - event type definitions - Add `engine/emitters.py` - emitter protocols - Add `engine/controller.py` - coordinates ntfy/mic monitoring ## Testing - **29 files changed, +2261 -185 lines** - Added comprehensive test coverage: - `test_config.py` - Config dataclass and CLI parsing - `test_controller.py` - StreamController - `test_emitters.py` - Emitter protocols - `test_eventbus.py` - EventBus thread-safety - `test_events.py` - Event types - `test_frame.py` - Frame timing - `test_layers.py` - Layer rendering - `test_mic.py` - Microphone monitor - `test_ntfy.py` - NTFY poller - `test_types.py` - Type definitions - `test_viewport.py` - Terminal dimensions All existing tests pass.
david added 4 commits 2026-03-16 02:07:30 +00:00
- Add Config dataclass with get_config()/set_config() for injection
- Add Config.from_args() for CLI argument parsing (testable)
- Add platform font path detection (Darwin/Linux)
- Bound translate cache with @lru_cache(maxsize=500)
- Add fixtures for external dependencies (network, feeds, config)
- Add 15 tests for Config class, from_args, and platform detection

This enables testability by:
- Allowing config injection instead of global mutable state
- Supporting custom argv in from_args() for testing
- Providing reusable fixtures for mocking network/filesystem
- Preventing unbounded memory growth in translation cache

Fixes: _arg_value/_arg_int not accepting custom argv
Split monolithic scroll.py into focused modules:
- viewport.py: terminal size (tw/th), ANSI positioning helpers
- frame.py: FrameTimer class, scroll step calculation
- layers.py: message overlay, ticker zone, firehose rendering
- scroll.py: simplified orchestrator, imports from new modules

Add stream controller and event types for future event-driven architecture:
- controller.py: StreamController for source initialization and stream lifecycle
- events.py: EventType enum and event dataclasses (HeadlineEvent, FrameTickEvent, etc.)

Added tests for new modules:
- test_viewport.py: 8 tests for viewport utilities
- test_frame.py: 10 tests for frame timing
- test_layers.py: 13 tests for layer compositing
- test_events.py: 11 tests for event types
- test_controller.py: 6 tests for stream controller

This enables:
- Testable chunks with clear responsibilities
- Reusable viewport utilities across modules
- Better separation of concerns in render pipeline
- Foundation for future event-driven architecture

Also includes Phase 1 documentation updates in code comments.
Add typed dataclasses for tuple returns:
- types.py: HeadlineItem, FetchResult, Block dataclasses with legacy tuple converters
- fetch.py: Add type hints and HeadlineTuple type alias

Add pyright for static type checking:
- Add pyright to dependencies
- Verify type coverage with pyright (0 errors in core modules)

This enables:
- Named types instead of raw tuples (better IDE support, self-documenting)
- Type-safe APIs across modules
- Backward compatibility via to_tuple/from_tuple methods

Note: Lazy imports skipped for render.py - startup impact is minimal.
- Add EventBus class with pub/sub messaging (thread-safe)
- Add emitter Protocol classes (EventEmitter, Startable, Stoppable)
- Add event emission to NtfyPoller (NtfyMessageEvent)
- Add event emission to MicMonitor (MicLevelEvent)
- Update StreamController to publish stream start/end events
- Add comprehensive tests for eventbus and emitters modules
david added 4 commits 2026-03-16 02:15:40 +00:00
- Add Config dataclass with get_config()/set_config() for injection
- Add Config.from_args() for CLI argument parsing (testable)
- Add platform font path detection (Darwin/Linux)
- Bound translate cache with @lru_cache(maxsize=500)
- Add fixtures for external dependencies (network, feeds, config)
- Add 15 tests for Config class, from_args, and platform detection

This enables testability by:
- Allowing config injection instead of global mutable state
- Supporting custom argv in from_args() for testing
- Providing reusable fixtures for mocking network/filesystem
- Preventing unbounded memory growth in translation cache

Fixes: _arg_value/_arg_int not accepting custom argv
Split monolithic scroll.py into focused modules:
- viewport.py: terminal size (tw/th), ANSI positioning helpers
- frame.py: FrameTimer class, scroll step calculation
- layers.py: message overlay, ticker zone, firehose rendering
- scroll.py: simplified orchestrator, imports from new modules

Add stream controller and event types for future event-driven architecture:
- controller.py: StreamController for source initialization and stream lifecycle
- events.py: EventType enum and event dataclasses (HeadlineEvent, FrameTickEvent, etc.)

Added tests for new modules:
- test_viewport.py: 8 tests for viewport utilities
- test_frame.py: 10 tests for frame timing
- test_layers.py: 13 tests for layer compositing
- test_events.py: 11 tests for event types
- test_controller.py: 6 tests for stream controller

This enables:
- Testable chunks with clear responsibilities
- Reusable viewport utilities across modules
- Better separation of concerns in render pipeline
- Foundation for future event-driven architecture

Also includes Phase 1 documentation updates in code comments.
Add typed dataclasses for tuple returns:
- types.py: HeadlineItem, FetchResult, Block dataclasses with legacy tuple converters
- fetch.py: Add type hints and HeadlineTuple type alias

Add pyright for static type checking:
- Add pyright to dependencies
- Verify type coverage with pyright (0 errors in core modules)

This enables:
- Named types instead of raw tuples (better IDE support, self-documenting)
- Type-safe APIs across modules
- Backward compatibility via to_tuple/from_tuple methods

Note: Lazy imports skipped for render.py - startup impact is minimal.
- Add EventBus class with pub/sub messaging (thread-safe)
- Add emitter Protocol classes (EventEmitter, Startable, Stoppable)
- Add event emission to NtfyPoller (NtfyMessageEvent)
- Add event emission to MicMonitor (MicLevelEvent)
- Update StreamController to publish stream start/end events
- Add comprehensive tests for eventbus and emitters modules
genewildish merged commit 7ff78c66ed into main 2026-03-16 09:11:14 +00:00
david deleted branch testability_modularization 2026-03-19 18:48:57 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: genewildish/Mainline#24