Files
essim/tests/test_edit.cpp
François 19dbec9672 Extract set-signal-type into core; add it to the wx GUI.
Fourth editing op into the wx frontend. Extract the type-name parse + apply
into core/app/edit.hpp::set_signal_type(Signal*, name) -> {ok, error, type},
failing without mutation on an unrecognised name. The interactive sigtype modal
keeps its own SignalType-cycling path (different interaction, trivial mutation).

The TUI `set-signal-type` command now renders that result (output unchanged).
The wx GUI gains Edit ▸ Set signal type…: a shared PickModule() helper (PickPart
now builds on it) + inline signal choice + a power/gnd/other dropdown, then the
core op, logged as "module/signal: signal type = …" and reflected.

tests/test_edit.cpp: name parsed and applied; unknown name refused without
mutation. 387 core assertions green; tui + wx build clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 21:27:44 +02:00

76 lines
2.4 KiB
C++

#include <doctest/doctest.h>
#include "core/app/edit.hpp"
#include "core/domain/parts.hpp"
#include "core/domain/pins.hpp"
#include "core/domain/signal_type.hpp"
#include "core/domain/signals.hpp"
// app::set_connector_type is pure core: validate the kind, tag the part and
// apply the connector model. No Print/dialog/FTXUI.
TEST_CASE("set_connector_type tags a part with a free-form kind") {
Part p("J1");
p.add(new Pin("1"));
p.add(new Pin("2"));
app::SetConnectorTypeResult r = app::set_connector_type(&p, "myconn");
CHECK(r.ok);
CHECK(r.error.empty());
CHECK(p.connector_type == "myconn");
}
TEST_CASE("set_connector_type refuses a kind the part doesn't fit — no mutation") {
Part p("J1");
p.add(new Pin("1"));
p.add(new Pin("2"));
p.add(new Pin("3")); // numeric pins don't fit the VPX single-letter columns
app::SetConnectorTypeResult r = app::set_connector_type(&p, "vpx-3u-bkp-p0");
CHECK_FALSE(r.ok);
CHECK_FALSE(r.error.empty());
CHECK(p.connector_type.empty()); // refused before any change
}
TEST_CASE("set_connector_type on a null part fails cleanly") {
app::SetConnectorTypeResult r = app::set_connector_type(nullptr, "x");
CHECK_FALSE(r.ok);
CHECK_FALSE(r.error.empty());
}
TEST_CASE("attach_bsdl reports a parse failure without mutating the part") {
Part p("J1");
p.add(new Pin("1"));
app::AttachBsdlResult r = app::attach_bsdl(&p, "/nonexistent-xyz/none.bsd");
CHECK_FALSE(r.ok);
CHECK(r.error.find("cannot parse") != std::string::npos);
CHECK(p.bsdl_path.empty()); // failure leaves the part untouched
}
TEST_CASE("attach_bsdl on a null part fails cleanly") {
app::AttachBsdlResult r = app::attach_bsdl(nullptr, "x.bsd");
CHECK_FALSE(r.ok);
CHECK_FALSE(r.error.empty());
}
TEST_CASE("set_signal_type parses the name and sets the type") {
Signal s("NET");
app::SetSignalTypeResult r = app::set_signal_type(&s, "power");
CHECK(r.ok);
CHECK(r.type == SignalType::Power);
CHECK(s.type == SignalType::Power);
}
TEST_CASE("set_signal_type rejects an unknown name without mutating") {
Signal s("NET");
s.type = SignalType::Other;
app::SetSignalTypeResult r = app::set_signal_type(&s, "bogus");
CHECK_FALSE(r.ok);
CHECK(r.error.find("power, gnd, other") != std::string::npos);
CHECK(s.type == SignalType::Other); // unchanged
}