diagrams-opus-qt/tests/test_app.py
Ilya 35a465f088 feat(edit): clipboard copy/paste of nodes
Add an internal clipboard on the controller with undoable macro paste, and
Copy/Paste menu actions and shortcuts in the main window. Covered by a test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-02 23:26:52 +02:00

107 lines
3.2 KiB
Python

"""Integration tests for the main window: sample, calc, IO, undo, config."""
import json
import pytest
from pipeline_editor.main_window import MainWindow
@pytest.fixture
def win(qtbot):
w = MainWindow()
qtbot.addWidget(w)
return w
def test_sample_builds_network(win):
win.load_sample()
assert len(list(win.document.nodes())) == 7
assert len(list(win.document.edges())) == 6
assert len(win.scene.node_items) == 7
assert len(win.scene.edge_items) == 6
def test_solve_flow_sets_edge_flows(win):
win.load_sample()
win.solve_flow()
flows = [e.flow for e in win.document.edges()]
assert any(f > 0 for f in flows)
# source edge should carry the sum of downstream demand (50 + 45)
assert max(flows) == pytest.approx(95)
def test_animation_toggle(win):
win.load_sample()
win.toggle_flow(True)
assert win.animator.running is True
win.animator.step()
win.toggle_flow(False)
assert win.animator.running is False
def test_delete_and_undo_via_controller(win):
win.load_sample()
node = next(win.document.nodes())
win.scene.node_items[node.node_id].setSelected(True)
n_before = len(list(win.document.nodes()))
win.delete_selection()
assert len(list(win.document.nodes())) == n_before - 1
win.controller.undo()
assert len(list(win.document.nodes())) == n_before
def test_duplicate_selection(win):
win.load_sample()
node = next(win.document.nodes())
win.scene.node_items[node.node_id].setSelected(True)
n_before = len(list(win.document.nodes()))
win.duplicate_selection()
assert len(list(win.document.nodes())) == n_before + 1
def test_copy_paste(win):
win.load_sample()
node = next(win.document.nodes())
win.scene.node_items[node.node_id].setSelected(True)
n_before = len(list(win.document.nodes()))
win.copy_selection()
win.paste_clipboard()
assert len(list(win.document.nodes())) == n_before + 1
win.controller.undo() # paste is one macro step
assert len(list(win.document.nodes())) == n_before
def test_save_and_open_roundtrip(win, tmp_path):
win.load_sample()
path = tmp_path / "diagram.pipe"
win._current_path = str(path)
win.save_document()
assert path.exists()
data = json.loads(path.read_text())
assert len(data["nodes"]) == 7
# open into a fresh window
win2 = MainWindow()
with open(path) as fh:
win2.document.load_dict(json.load(fh))
assert len(list(win2.document.nodes())) == 7
assert len(win2.scene.node_items) == 7 # scene rebuilt from 'cleared' signal
def test_config_change_applies_scheme(win):
win.load_sample()
win.config.color_scheme = "high_contrast"
win.config.emit_changed()
assert win.document.relations.active_scheme == "high_contrast"
assert win.document.relations.color("water") == "#0000ff"
def test_property_edit_through_panel_is_undoable(win):
win.load_sample()
node = next(n for n in win.document.nodes() if n.template_key == "consumer")
win.scene.node_items[node.node_id].setSelected(True)
win._on_property_edited("node", node.node_id, "demand", 123.0)
assert node.properties.value("demand") == 123.0
win.controller.undo()
assert node.properties.value("demand") != 123.0