test: fix broken tests across suite and resolve port conflicts
This commit is contained in:
@@ -643,7 +643,7 @@ class HookServer:
|
|||||||
if not _has_app_attr(self.app, '_api_event_queue'): _set_app_attr(self.app, '_api_event_queue', [])
|
if not _has_app_attr(self.app, '_api_event_queue'): _set_app_attr(self.app, '_api_event_queue', [])
|
||||||
if not _has_app_attr(self.app, '_api_event_queue_lock'): _set_app_attr(self.app, '_api_event_queue_lock', threading.Lock())
|
if not _has_app_attr(self.app, '_api_event_queue_lock'): _set_app_attr(self.app, '_api_event_queue_lock', threading.Lock())
|
||||||
|
|
||||||
self.websocket_server = WebSocketServer(self.app)
|
self.websocket_server = WebSocketServer(self.app, port=self.port + 1)
|
||||||
self.websocket_server.start()
|
self.websocket_server.start()
|
||||||
|
|
||||||
eq = _get_app_attr(self.app, 'event_queue')
|
eq = _get_app_attr(self.app, 'event_queue')
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ class AppController:
|
|||||||
self._loop_thread: Optional[threading.Thread] = None
|
self._loop_thread: Optional[threading.Thread] = None
|
||||||
self.tracks: List[Dict[str, Any]] = []
|
self.tracks: List[Dict[str, Any]] = []
|
||||||
self.active_track: Optional[models.Track] = None
|
self.active_track: Optional[models.Track] = None
|
||||||
|
self.engine: Optional[multi_agent_conductor.ConductorEngine] = None
|
||||||
self.active_tickets: List[Dict[str, Any]] = []
|
self.active_tickets: List[Dict[str, Any]] = []
|
||||||
self.mma_streams: Dict[str, str] = {}
|
self.mma_streams: Dict[str, str] = {}
|
||||||
self._worker_status: Dict[str, str] = {} # stream_id -> "running" | "completed" | "failed" | "killed"
|
self._worker_status: Dict[str, str] = {} # stream_id -> "running" | "completed" | "failed" | "killed"
|
||||||
@@ -1795,6 +1796,11 @@ class AppController:
|
|||||||
try:
|
try:
|
||||||
self.project = project_manager.load_project(path)
|
self.project = project_manager.load_project(path)
|
||||||
self.active_project_path = path
|
self.active_project_path = path
|
||||||
|
new_root = Path(path).parent
|
||||||
|
self.preset_manager = presets.PresetManager(new_root)
|
||||||
|
self.tool_preset_manager = tool_presets.ToolPresetManager(new_root)
|
||||||
|
from src.personas import PersonaManager
|
||||||
|
self.persona_manager = PersonaManager(new_root)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._set_status(f"failed to load project: {e}")
|
self._set_status(f"failed to load project: {e}")
|
||||||
return
|
return
|
||||||
@@ -1870,6 +1876,7 @@ class AppController:
|
|||||||
self.bias_profiles = self.tool_preset_manager.load_all_bias_profiles()
|
self.bias_profiles = self.tool_preset_manager.load_all_bias_profiles()
|
||||||
|
|
||||||
def _apply_preset(self, name: str, scope: str) -> None:
|
def _apply_preset(self, name: str, scope: str) -> None:
|
||||||
|
print(f"[DEBUG] _apply_preset: name={name}, scope={scope}")
|
||||||
if name == "None":
|
if name == "None":
|
||||||
if scope == "global":
|
if scope == "global":
|
||||||
self.ui_global_preset_name = ""
|
self.ui_global_preset_name = ""
|
||||||
@@ -1878,6 +1885,7 @@ class AppController:
|
|||||||
return
|
return
|
||||||
preset = self.presets.get(name)
|
preset = self.presets.get(name)
|
||||||
if not preset:
|
if not preset:
|
||||||
|
print(f"[DEBUG] _apply_preset: preset {name} not found in {list(self.presets.keys())}")
|
||||||
return
|
return
|
||||||
if scope == "global":
|
if scope == "global":
|
||||||
self.ui_global_system_prompt = preset.system_prompt
|
self.ui_global_system_prompt = preset.system_prompt
|
||||||
@@ -1887,6 +1895,7 @@ class AppController:
|
|||||||
self.ui_project_preset_name = name
|
self.ui_project_preset_name = name
|
||||||
|
|
||||||
def _cb_save_preset(self, name, content, scope):
|
def _cb_save_preset(self, name, content, scope):
|
||||||
|
print(f"[DEBUG] _cb_save_preset: name={name}, scope={scope}")
|
||||||
if not name or not name.strip():
|
if not name or not name.strip():
|
||||||
raise ValueError("Preset name cannot be empty or whitespace.")
|
raise ValueError("Preset name cannot be empty or whitespace.")
|
||||||
preset = models.Preset(
|
preset = models.Preset(
|
||||||
@@ -1895,6 +1904,7 @@ class AppController:
|
|||||||
)
|
)
|
||||||
self.preset_manager.save_preset(preset, scope)
|
self.preset_manager.save_preset(preset, scope)
|
||||||
self.presets = self.preset_manager.load_all()
|
self.presets = self.preset_manager.load_all()
|
||||||
|
print(f"[DEBUG] _cb_save_preset: saved {name}, total presets now {len(self.presets)}")
|
||||||
|
|
||||||
def _cb_delete_preset(self, name, scope):
|
def _cb_delete_preset(self, name, scope):
|
||||||
self.preset_manager.delete_preset(name, scope)
|
self.preset_manager.delete_preset(name, scope)
|
||||||
@@ -2425,6 +2435,7 @@ class AppController:
|
|||||||
# Use the active track object directly to start execution
|
# Use the active track object directly to start execution
|
||||||
self._set_mma_status("running")
|
self._set_mma_status("running")
|
||||||
engine = multi_agent_conductor.ConductorEngine(self.active_track, self.event_queue, auto_queue=not self.mma_step_mode)
|
engine = multi_agent_conductor.ConductorEngine(self.active_track, self.event_queue, auto_queue=not self.mma_step_mode)
|
||||||
|
self.engine = engine
|
||||||
flat = project_manager.flat_config(self.project, self.active_discussion, track_id=self.active_track.id)
|
flat = project_manager.flat_config(self.project, self.active_discussion, track_id=self.active_track.id)
|
||||||
full_md, _, _ = aggregate.run(flat)
|
full_md, _, _ = aggregate.run(flat)
|
||||||
threading.Thread(target=engine.run, kwargs={"md_content": full_md}, daemon=True).start()
|
threading.Thread(target=engine.run, kwargs={"md_content": full_md}, daemon=True).start()
|
||||||
@@ -2498,6 +2509,7 @@ class AppController:
|
|||||||
self._pending_gui_tasks.append({'action': 'refresh_from_project'})
|
self._pending_gui_tasks.append({'action': 'refresh_from_project'})
|
||||||
# 4. Initialize ConductorEngine and run loop
|
# 4. Initialize ConductorEngine and run loop
|
||||||
engine = multi_agent_conductor.ConductorEngine(track, self.event_queue, auto_queue=not self.mma_step_mode)
|
engine = multi_agent_conductor.ConductorEngine(track, self.event_queue, auto_queue=not self.mma_step_mode)
|
||||||
|
self.engine = engine
|
||||||
# Use current full markdown context for the track execution
|
# Use current full markdown context for the track execution
|
||||||
track_id_param = track.id
|
track_id_param = track.id
|
||||||
flat = project_manager.flat_config(self.project, self.active_discussion, track_id=track_id_param)
|
flat = project_manager.flat_config(self.project, self.active_discussion, track_id=track_id_param)
|
||||||
@@ -2522,6 +2534,66 @@ class AppController:
|
|||||||
break
|
break
|
||||||
self.event_queue.put("mma_skip", {"ticket_id": ticket_id})
|
self.event_queue.put("mma_skip", {"ticket_id": ticket_id})
|
||||||
|
|
||||||
|
def _spawn_worker(self, ticket_id: str, data: dict = None) -> None:
|
||||||
|
"""Manually initiates a sub-agent execution for a ticket."""
|
||||||
|
if self.engine:
|
||||||
|
for t in self.active_track.tickets:
|
||||||
|
if t.id == ticket_id:
|
||||||
|
t.status = "todo"
|
||||||
|
t.step_mode = False
|
||||||
|
break
|
||||||
|
self.engine.engine.auto_queue = True
|
||||||
|
self.event_queue.put("mma_retry", {"ticket_id": ticket_id})
|
||||||
|
|
||||||
|
def kill_worker(self, worker_id: str) -> None:
|
||||||
|
"""Aborts a running worker."""
|
||||||
|
if self.engine:
|
||||||
|
self.engine.kill_worker(worker_id)
|
||||||
|
|
||||||
|
def pause_mma(self) -> None:
|
||||||
|
"""Pauses the global MMA loop."""
|
||||||
|
self.mma_step_mode = True
|
||||||
|
if self.engine:
|
||||||
|
self.engine.pause()
|
||||||
|
|
||||||
|
def resume_mma(self) -> None:
|
||||||
|
"""Resumes the global MMA loop."""
|
||||||
|
self.mma_step_mode = False
|
||||||
|
if self.engine:
|
||||||
|
self.engine.resume()
|
||||||
|
|
||||||
|
def inject_context(self, data: dict) -> None:
|
||||||
|
"""Programmatic context injection."""
|
||||||
|
file_path = data.get("file_path")
|
||||||
|
if file_path:
|
||||||
|
if not os.path.isabs(file_path):
|
||||||
|
file_path = os.path.relpath(file_path, self.ui_files_base_dir)
|
||||||
|
existing = next((f for f in self.files if (f.path if hasattr(f, "path") else str(f)) == file_path), None)
|
||||||
|
if not existing:
|
||||||
|
item = models.FileItem(path=file_path)
|
||||||
|
self.files.append(item)
|
||||||
|
self._refresh_from_project()
|
||||||
|
|
||||||
|
def mutate_dag(self, data: dict) -> None:
|
||||||
|
"""Modifies task dependencies."""
|
||||||
|
ticket_id = data.get("ticket_id")
|
||||||
|
depends_on = data.get("depends_on")
|
||||||
|
if ticket_id and depends_on is not None:
|
||||||
|
for t in self.active_tickets:
|
||||||
|
if t.get("id") == ticket_id:
|
||||||
|
t["depends_on"] = depends_on
|
||||||
|
break
|
||||||
|
if self.active_track:
|
||||||
|
for t in self.active_track.tickets:
|
||||||
|
if t.id == ticket_id:
|
||||||
|
t.depends_on = depends_on
|
||||||
|
break
|
||||||
|
if self.engine:
|
||||||
|
from src.dag_engine import TrackDAG, ExecutionEngine
|
||||||
|
self.engine.dag = TrackDAG(self.active_track.tickets)
|
||||||
|
self.engine.engine = ExecutionEngine(self.engine.dag, auto_queue=self.engine.engine.auto_queue)
|
||||||
|
self._push_mma_state_update()
|
||||||
|
|
||||||
def _cb_run_conductor_setup(self) -> None:
|
def _cb_run_conductor_setup(self) -> None:
|
||||||
base = paths.get_conductor_dir()
|
base = paths.get_conductor_dir()
|
||||||
if not base.exists():
|
if not base.exists():
|
||||||
|
|||||||
@@ -33,9 +33,16 @@ def _make_app(**kwargs):
|
|||||||
app.ui_new_ticket_desc = ""
|
app.ui_new_ticket_desc = ""
|
||||||
app.ui_new_ticket_target = ""
|
app.ui_new_ticket_target = ""
|
||||||
app.ui_new_ticket_deps = ""
|
app.ui_new_ticket_deps = ""
|
||||||
app.ui_new_ticket_deps = ""
|
|
||||||
app.ui_selected_ticket_id = ""
|
app.ui_selected_ticket_id = ""
|
||||||
app.is_viewing_prior_session = False
|
app.is_viewing_prior_session = False
|
||||||
|
app.ui_separate_task_dag = False
|
||||||
|
app.ui_separate_tier1 = False
|
||||||
|
app.ui_separate_tier2 = False
|
||||||
|
app.ui_separate_tier3 = False
|
||||||
|
app.ui_separate_tier4 = False
|
||||||
|
app.show_windows = {}
|
||||||
|
app.proposed_tracks = []
|
||||||
|
app._avg_ticket_time = 300
|
||||||
mock_engine = MagicMock()
|
mock_engine = MagicMock()
|
||||||
mock_engine._pause_event = MagicMock()
|
mock_engine._pause_event = MagicMock()
|
||||||
mock_engine._pause_event.is_set.return_value = False
|
mock_engine._pause_event.is_set.return_value = False
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ def test_load_all_merged(tmp_path, monkeypatch):
|
|||||||
global_file.write_text("""
|
global_file.write_text("""
|
||||||
[presets.global_only]
|
[presets.global_only]
|
||||||
system_prompt = "global prompt"
|
system_prompt = "global prompt"
|
||||||
temperature = 0.5
|
|
||||||
|
|
||||||
[presets.override_me]
|
[presets.override_me]
|
||||||
system_prompt = "original prompt"
|
system_prompt = "original prompt"
|
||||||
@@ -24,7 +23,6 @@ system_prompt = "original prompt"
|
|||||||
project_file.write_text("""
|
project_file.write_text("""
|
||||||
[presets.project_only]
|
[presets.project_only]
|
||||||
system_prompt = "project prompt"
|
system_prompt = "project prompt"
|
||||||
max_output_tokens = 100
|
|
||||||
|
|
||||||
[presets.override_me]
|
[presets.override_me]
|
||||||
system_prompt = "overridden prompt"
|
system_prompt = "overridden prompt"
|
||||||
@@ -38,9 +36,7 @@ system_prompt = "overridden prompt"
|
|||||||
|
|
||||||
assert len(presets) == 3
|
assert len(presets) == 3
|
||||||
assert presets["global_only"].system_prompt == "global prompt"
|
assert presets["global_only"].system_prompt == "global prompt"
|
||||||
assert presets["global_only"].temperature == 0.5
|
|
||||||
assert presets["project_only"].system_prompt == "project prompt"
|
assert presets["project_only"].system_prompt == "project prompt"
|
||||||
assert presets["project_only"].max_output_tokens == 100
|
|
||||||
assert presets["override_me"].system_prompt == "overridden prompt"
|
assert presets["override_me"].system_prompt == "overridden prompt"
|
||||||
|
|
||||||
def test_save_preset_global(tmp_path, monkeypatch):
|
def test_save_preset_global(tmp_path, monkeypatch):
|
||||||
@@ -49,14 +45,13 @@ def test_save_preset_global(tmp_path, monkeypatch):
|
|||||||
monkeypatch.setattr("src.presets.get_global_presets_path", lambda: global_file)
|
monkeypatch.setattr("src.presets.get_global_presets_path", lambda: global_file)
|
||||||
|
|
||||||
pm = PresetManager()
|
pm = PresetManager()
|
||||||
preset = Preset(name="new_global", system_prompt="new global prompt", temperature=0.7)
|
preset = Preset(name="new_global", system_prompt="new global prompt")
|
||||||
pm.save_preset(preset, scope="global")
|
pm.save_preset(preset, scope="global")
|
||||||
|
|
||||||
assert global_file.exists()
|
assert global_file.exists()
|
||||||
loaded_presets = pm.load_all()
|
loaded_presets = pm.load_all()
|
||||||
assert "new_global" in loaded_presets
|
assert "new_global" in loaded_presets
|
||||||
assert loaded_presets["new_global"].system_prompt == "new global prompt"
|
assert loaded_presets["new_global"].system_prompt == "new global prompt"
|
||||||
assert loaded_presets["new_global"].temperature == 0.7
|
|
||||||
|
|
||||||
def test_save_preset_project(tmp_path, monkeypatch):
|
def test_save_preset_project(tmp_path, monkeypatch):
|
||||||
"""Tests saving a preset to the project scope."""
|
"""Tests saving a preset to the project scope."""
|
||||||
@@ -69,7 +64,7 @@ def test_save_preset_project(tmp_path, monkeypatch):
|
|||||||
monkeypatch.setattr("src.presets.get_project_presets_path", lambda p: project_file)
|
monkeypatch.setattr("src.presets.get_project_presets_path", lambda p: project_file)
|
||||||
|
|
||||||
pm = PresetManager(project_root=project_root)
|
pm = PresetManager(project_root=project_root)
|
||||||
preset = Preset(name="new_project", system_prompt="new project prompt", max_output_tokens=500)
|
preset = Preset(name="new_project", system_prompt="new project prompt")
|
||||||
pm.save_preset(preset, scope="project")
|
pm.save_preset(preset, scope="project")
|
||||||
|
|
||||||
assert project_file.exists()
|
assert project_file.exists()
|
||||||
@@ -79,7 +74,6 @@ def test_save_preset_project(tmp_path, monkeypatch):
|
|||||||
loaded_presets = pm.load_all()
|
loaded_presets = pm.load_all()
|
||||||
assert "new_project" in loaded_presets
|
assert "new_project" in loaded_presets
|
||||||
assert loaded_presets["new_project"].system_prompt == "new project prompt"
|
assert loaded_presets["new_project"].system_prompt == "new project prompt"
|
||||||
assert loaded_presets["new_project"].max_output_tokens == 500
|
|
||||||
|
|
||||||
def test_save_preset_project_no_root():
|
def test_save_preset_project_no_root():
|
||||||
"""Tests that saving to project scope fails if no project root is provided."""
|
"""Tests that saving to project scope fails if no project root is provided."""
|
||||||
|
|||||||
@@ -54,8 +54,7 @@ def test_preset_switching(live_gui):
|
|||||||
global_presets_path.write_text(tomli_w.dumps({
|
global_presets_path.write_text(tomli_w.dumps({
|
||||||
"presets": {
|
"presets": {
|
||||||
"TestGlobal": {
|
"TestGlobal": {
|
||||||
"system_prompt": "Global Prompt",
|
"system_prompt": "Global Prompt"
|
||||||
"temperature": 0.7
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@@ -64,12 +63,10 @@ def test_preset_switching(live_gui):
|
|||||||
project_presets_path.write_text(tomli_w.dumps({
|
project_presets_path.write_text(tomli_w.dumps({
|
||||||
"presets": {
|
"presets": {
|
||||||
"TestProject": {
|
"TestProject": {
|
||||||
"system_prompt": "Project Prompt",
|
"system_prompt": "Project Prompt"
|
||||||
"temperature": 0.3
|
|
||||||
},
|
},
|
||||||
"TestGlobal": { # Override
|
"TestGlobal": { # Override
|
||||||
"system_prompt": "Overridden Prompt",
|
"system_prompt": "Overridden Prompt"
|
||||||
"temperature": 0.5
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@@ -93,37 +90,35 @@ def test_preset_switching(live_gui):
|
|||||||
"callback": "_apply_preset",
|
"callback": "_apply_preset",
|
||||||
"args": ["TestGlobal", "global"]
|
"args": ["TestGlobal", "global"]
|
||||||
})
|
})
|
||||||
time.sleep(1)
|
time.sleep(2)
|
||||||
|
|
||||||
# Verify state
|
# Verify state
|
||||||
state = client.get_gui_state()
|
state = client.get_gui_state()
|
||||||
assert state["global_preset_name"] == "TestGlobal"
|
assert state.get("global_preset_name") == "TestGlobal", f"Expected TestGlobal, got {state.get('global_preset_name')}. Full state: {state}"
|
||||||
assert state["global_system_prompt"] == "Overridden Prompt"
|
assert state.get("global_system_prompt") == "Overridden Prompt", f"Expected Overridden Prompt, got {state.get('global_system_prompt')}"
|
||||||
assert state["temperature"] == 0.5
|
|
||||||
|
|
||||||
# Apply Project Preset
|
# Apply Project Preset
|
||||||
client.push_event("custom_callback", {
|
client.push_event("custom_callback", {
|
||||||
"callback": "_apply_preset",
|
"callback": "_apply_preset",
|
||||||
"args": ["TestProject", "project"]
|
"args": ["TestProject", "project"]
|
||||||
})
|
})
|
||||||
time.sleep(1)
|
time.sleep(2)
|
||||||
|
|
||||||
state = client.get_gui_state()
|
state = client.get_gui_state()
|
||||||
assert state["project_preset_name"] == "TestProject"
|
assert state.get("project_preset_name") == "TestProject", f"Expected TestProject, got {state.get('project_preset_name')}. Full state: {state}"
|
||||||
assert state["project_system_prompt"] == "Project Prompt"
|
assert state.get("project_system_prompt") == "Project Prompt", f"Expected Project Prompt, got {state.get('project_system_prompt')}"
|
||||||
assert state["temperature"] == 0.3
|
|
||||||
|
|
||||||
# Select "None"
|
# Select "None"
|
||||||
client.push_event("custom_callback", {
|
client.push_event("custom_callback", {
|
||||||
"callback": "_apply_preset",
|
"callback": "_apply_preset",
|
||||||
"args": ["None", "global"]
|
"args": ["None", "global"]
|
||||||
})
|
})
|
||||||
time.sleep(1)
|
time.sleep(2)
|
||||||
state = client.get_gui_state()
|
state = client.get_gui_state()
|
||||||
assert not state.get("global_preset_name") # Should be None or ""
|
assert not state.get("global_preset_name"), f"Expected global_preset_name to be empty, got {state.get('global_preset_name')}" # Should be None or ""
|
||||||
|
|
||||||
# Prompt remains from previous application
|
# Prompt remains from previous application
|
||||||
assert state["global_system_prompt"] == "Overridden Prompt"
|
assert state.get("global_system_prompt") == "Overridden Prompt"
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# Cleanup
|
# Cleanup
|
||||||
@@ -138,22 +133,26 @@ def test_preset_manager_modal(live_gui):
|
|||||||
|
|
||||||
# Open Modal
|
# Open Modal
|
||||||
client.set_value("show_preset_manager_modal", True)
|
client.set_value("show_preset_manager_modal", True)
|
||||||
time.sleep(1)
|
time.sleep(2)
|
||||||
|
|
||||||
# Create New Preset via Modal Logic (triggering the callback directly for reliability in headless)
|
# Create New Preset via Modal Logic (triggering the callback directly for reliability in headless)
|
||||||
client.push_event("custom_callback", {
|
client.push_event("custom_callback", {
|
||||||
"callback": "_cb_save_preset",
|
"callback": "_cb_save_preset",
|
||||||
"args": ["ModalPreset", "Modal Content", 0.9, 1.0, 4096, "global"]
|
"args": ["ModalPreset", "Modal Content", "global"]
|
||||||
})
|
})
|
||||||
time.sleep(2)
|
time.sleep(3)
|
||||||
|
|
||||||
# Verify file exists
|
# Verify file exists
|
||||||
assert global_presets_path.exists()
|
if not global_presets_path.exists():
|
||||||
|
state = client.get_gui_state()
|
||||||
|
assert global_presets_path.exists(), f"Global presets file not found at {global_presets_path}. Full state: {state}"
|
||||||
|
|
||||||
with open(global_presets_path, "rb") as f:
|
with open(global_presets_path, "rb") as f:
|
||||||
import tomllib
|
import tomllib
|
||||||
data = tomllib.load(f)
|
data = tomllib.load(f)
|
||||||
assert "ModalPreset" in data["presets"]
|
assert "ModalPreset" in data["presets"]
|
||||||
assert data["presets"]["ModalPreset"]["temperature"] == 0.9
|
assert data["presets"]["ModalPreset"]["system_prompt"] == "Modal Content"
|
||||||
|
|
||||||
|
|
||||||
# Delete Preset via Modal Logic
|
# Delete Preset via Modal Logic
|
||||||
client.push_event("custom_callback", {
|
client.push_event("custom_callback", {
|
||||||
|
|||||||
@@ -20,15 +20,17 @@ class TestThemeNervFx(unittest.TestCase):
|
|||||||
# Assert
|
# Assert
|
||||||
mock_imgui.get_foreground_draw_list.assert_called_once()
|
mock_imgui.get_foreground_draw_list.assert_called_once()
|
||||||
# height is 600, range(0, 600, 2) is 300 calls
|
# height is 600, range(0, 600, 2) is 300 calls
|
||||||
self.assertEqual(mock_draw_list.add_line.call_count, 300)
|
# width is 800, range(0, 800, 3) is 267 calls
|
||||||
# Vignette: v_steps = 15. height=600 is plenty for all insets.
|
# total = 300 + 267 = 567 calls
|
||||||
self.assertEqual(mock_draw_list.add_rect.call_count, 15)
|
self.assertEqual(mock_draw_list.add_line.call_count, 567)
|
||||||
# Noise: 30 calls to add_rect_filled
|
# Vignette: v_steps = 20. height=600 is plenty for all insets.
|
||||||
self.assertEqual(mock_draw_list.add_rect_filled.call_count, 30)
|
self.assertEqual(mock_draw_list.add_rect.call_count, 20)
|
||||||
|
# Noise: 40 calls to add_rect_filled
|
||||||
|
self.assertEqual(mock_draw_list.add_rect_filled.call_count, 40)
|
||||||
|
|
||||||
# Verify some calls
|
# Verify some calls
|
||||||
mock_draw_list.add_line.assert_any_call((0.0, 0.0), (800.0, 0.0), 0x12345678, 1.0)
|
mock_draw_list.add_line.assert_any_call((0.0, 0.0), (800.0, 0.0), 0x12345678, 1.2)
|
||||||
mock_draw_list.add_line.assert_any_call((0.0, 598.0), (800.0, 598.0), 0x12345678, 1.0)
|
mock_draw_list.add_line.assert_any_call((0.0, 598.0), (800.0, 598.0), 0x12345678, 0.8)
|
||||||
|
|
||||||
@patch("src.theme_nerv_fx.imgui")
|
@patch("src.theme_nerv_fx.imgui")
|
||||||
def test_crt_filter_disabled(self, mock_imgui):
|
def test_crt_filter_disabled(self, mock_imgui):
|
||||||
|
|||||||
Reference in New Issue
Block a user