8f11340b38
Per post_module_taxonomy_de_cruft_20260627 Phase 2 (FR7). Each
'from src.models import X' for a moved class is rewritten to
'from src.<destination> import X':
Ticket, Track, WorkerContext, TrackState, TrackMetadata,
ThinkingSegment, EMPTY_TRACK_STATE -> src.mma
ProjectContext, ProjectMeta, ProjectOutput, ProjectFiles,
ProjectScreenshots, ProjectDiscussion, EMPTY_PROJECT_CONTEXT -> src.project
FileItem, Preset, ContextPreset, ContextFileEntry,
NamedViewPreset -> src.project_files
Tool, ToolPreset -> src.tool_presets
BiasProfile -> src.tool_bias
TextEditorConfig, ExternalEditorConfig,
EMPTY_TEXT_EDITOR_CONFIG -> src.external_editor
Persona -> src.personas
WorkspaceProfile -> src.workspace_manager
MCPServerConfig, MCPConfiguration, VectorStoreConfig,
RAGConfig, load_mcp_config -> src.mcp_client
NOT touched (kept on src.models; Phase 3 or Phase 4 will move them):
GenerateRequest, ConfirmRequest, DEFAULT_TOOL_CATEGORIES, Metadata, PROVIDERS
Migration was performed by the one-time script
scripts/tier2/artifacts/post_module_taxonomy_de_cruft_20260627/migrate_imports.py
which uses a class-to-module map and re.sub() to rewrite each
'from src.models import X' line.
Total: 85 import lines rewritten across 71 files.
Note: this commit depends on the v2 SHIPPED work
(origin/tier2/module_taxonomy_refactor_20260627) being merged into
this branch NEXT. On master (without the v2 SHIPPED commits), the
destination modules do not exist and these imports would fail.
89 lines
3.8 KiB
Python
89 lines
3.8 KiB
Python
import pytest
|
|
from unittest.mock import MagicMock, patch
|
|
from src import gui_2
|
|
from src.gui_2 import App, C_LBL, C_VAL
|
|
from src.mma import Ticket
|
|
|
|
def test_render_mma_dashboard_progress():
|
|
# Create a mock for the imgui module used in gui_2
|
|
mock_imgui = MagicMock()
|
|
|
|
# Configure ImVec4 and ImVec2
|
|
mock_imgui.ImVec2 = MagicMock(side_effect=lambda x, y: (float(x), float(y)))
|
|
mock_imgui.ImVec4 = MagicMock(side_effect=lambda r, g, b, a: (float(r), float(g), float(b), float(a)))
|
|
|
|
# Configure calls that return tuples
|
|
mock_imgui.input_text_multiline.return_value = (False, "")
|
|
mock_imgui.input_text.return_value = (False, "")
|
|
mock_imgui.checkbox.return_value = (False, False)
|
|
mock_imgui.begin_combo.return_value = (False, "")
|
|
mock_imgui.selectable.return_value = (False, False)
|
|
mock_imgui.begin_table.return_value = True
|
|
mock_imgui.begin_tab_item.return_value = (True, True)
|
|
mock_imgui.collapsing_header.return_value = False
|
|
# Patch where it is actually used
|
|
with patch('src.gui_2.imgui', mock_imgui), \
|
|
patch('src.imgui_scopes.imgui', new=mock_imgui), \
|
|
patch('src.theme_2.imgui', new=mock_imgui), \
|
|
patch('src.gui_2.cost_tracker.estimate_cost', return_value=0.0):
|
|
|
|
# Mock App instance - no spec because of delegation
|
|
app = MagicMock()
|
|
|
|
# Setup mock state
|
|
app.active_track = MagicMock()
|
|
app.active_track.description = "Test Track"
|
|
|
|
# Mock self.active_track.tickets as a list of src.models.Ticket objects
|
|
app.active_track.tickets = [
|
|
Ticket(id='T1', description='desc', status='completed'),
|
|
Ticket(id='T2', description='desc', status='in_progress'),
|
|
Ticket(id='T3', description='desc', status='blocked'),
|
|
Ticket(id='T4', description='desc', status='todo')
|
|
]
|
|
|
|
app.is_viewing_prior_session = False
|
|
app.perf_profiling_enabled = False
|
|
app.mma_tier_usage = {}
|
|
app.mma_status = "idle"
|
|
app.active_tier = None
|
|
app._pending_mma_spawn = None
|
|
app._pending_mma_approval = None
|
|
app._pending_ask_dialog = False
|
|
app.tracks = []
|
|
app.ui_epic_input = ""
|
|
app.ui_conductor_setup_summary = ""
|
|
app.ui_new_track_name = ""
|
|
app.ui_new_track_desc = ""
|
|
app.ui_new_track_type = "feature"
|
|
app.mma_step_mode = False
|
|
app.node_editor_ctx = None
|
|
app._avg_ticket_time = 60
|
|
|
|
# Call the method
|
|
# Dashboard now delegates to sub-methods, so we wire them up to execute their real logic on the mock instance.
|
|
app._render_mma_focus_selector.side_effect = lambda: gui_2.render_mma_focus_selector(app)
|
|
app._render_mma_track_summary.side_effect = lambda: gui_2.render_mma_track_summary(app)
|
|
app._render_mma_epic_planner.side_effect = lambda: gui_2.render_mma_epic_planner(app)
|
|
app._render_mma_conductor_setup.side_effect = lambda: gui_2.render_mma_conductor_setup(app)
|
|
app._render_mma_track_browser.side_effect = lambda: gui_2.render_mma_track_browser(app)
|
|
app._render_mma_global_controls.side_effect = lambda: gui_2.render_mma_global_controls(app)
|
|
app._render_mma_usage_section.side_effect = lambda: gui_2.render_mma_usage_section(app)
|
|
app._render_mma_agent_streams.side_effect = lambda: gui_2.render_mma_agent_streams(app)
|
|
|
|
gui_2.render_mma_dashboard(app)
|
|
# Assertions
|
|
# 1 completed out of 4 tickets = 25.0% progress
|
|
# Update assertions: imgui.progress_bar is called with (0.25, (-1.0, 0.0), '25.0%')
|
|
mock_imgui.progress_bar.assert_any_call(0.25, (-1.0, 0.0), "25.0%")
|
|
|
|
# Verify status breakdown counts are asserted via imgui.text_colored calls
|
|
mock_imgui.text_colored.assert_any_call(C_LBL(), "Completed:")
|
|
mock_imgui.text_colored.assert_any_call(C_VAL(), "1")
|
|
mock_imgui.text_colored.assert_any_call(C_LBL(), "In Progress:")
|
|
mock_imgui.text_colored.assert_any_call(C_VAL(), "1")
|
|
mock_imgui.text_colored.assert_any_call(C_LBL(), "Blocked:")
|
|
mock_imgui.text_colored.assert_any_call(C_VAL(), "1")
|
|
mock_imgui.text_colored.assert_any_call(C_LBL(), "Todo:")
|
|
mock_imgui.text_colored.assert_any_call(C_VAL(), "1")
|