Files
essim/tests/test_export.cpp
François 63ca17d048 build: split core/ from frontends/; prepare for multiple GUI/TUI targets
Reorganise the tree into business vs frontend as separate directories:
  src/core/{domain,imports,app}   (was system/, imports/, app/)
  src/frontends/tui/              (was tui/ + main.cpp)
  tests/tui/                      (the FTXUI-coupled helper test)
All cross-dir #include paths rewritten; same-dir includes untouched.

CMake: essim_core is the frontend-agnostic business library — links libzip,
pugixml and bsdl, NO GUI toolkit. Each frontend is a self-contained
src/frontends/<name>/ (own CMakeLists, toolkit, main.cpp) that links
essim_core, selected with -DESSIM_FRONTEND=<name> (default tui; 'none' = core +
tests only, no toolkit fetched). FTXUI moved into the tui frontend. Tests are
split: essim_tests links essim_core (no FTXUI), essim_tui_tests links essim_tui.

Verified: default tui build green (ctest 2/2); ESSIM_FRONTEND=none builds the
core + tests with FTXUI never fetched and no `essim` binary.

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

77 lines
2.4 KiB
C++

#include <doctest/doctest.h>
#include "core/app/export.hpp"
#include "core/domain/connect.hpp"
#include "core/domain/modules.hpp"
#include "core/domain/parts.hpp"
#include "core/domain/pins.hpp"
#include "core/domain/signals.hpp"
#include "core/domain/system.hpp"
#include <cstdio>
#include <fstream>
#include <sstream>
#include <string>
namespace {
std::string slurp(const std::string &path)
{
std::ifstream f(path);
std::stringstream ss;
ss << f.rdbuf();
return ss.str();
}
} // namespace
TEST_CASE("export_format_from_path maps extensions") {
app::ExportFormat f;
CHECK(app::export_format_from_path("a.csv", f));
CHECK(f == app::ExportFormat::Csv);
CHECK(app::export_format_from_path("a.ODS", f));
CHECK(f == app::ExportFormat::Ods);
CHECK_FALSE(app::export_format_from_path("a.txt", f));
CHECK_FALSE(app::export_format_from_path("noext", f));
}
TEST_CASE("export_connections writes a flat CSV (no UI needed)") {
// Two cards, one wired pin pair via a connection.
System sys;
Module *a = sys.modules()->merge("A");
Module *b = sys.modules()->merge("B");
Part *ja = new Part("J1"); a->add(ja);
Part *jb = new Part("P1"); b->add(jb);
Pin *pa = new Pin("1"); ja->add(pa);
Pin *pb = new Pin("1"); jb->add(pb);
Signal *sa = a->signals->merge("NETA"); sa->add(pa); pa->connect(sa);
Signal *sb = b->signals->merge("NETB"); sb->add(pb); pb->connect(sb);
Connection *c = new Connection("A.J1<->B.P1", a, ja, b, jb);
c->transform_name = "identity";
c->pin_map.emplace_back(pa, pb);
sys.connections()->add(c);
const char *path = "test_export_out.csv";
app::ExportResult r = app::export_connections(&sys, path, app::ExportFormat::Csv);
CHECK(r.ok);
CHECK(r.rows == 1);
std::string out = slurp(path);
CHECK(out.find("connection,transform,") == 0); // header present
CHECK(out.find("A.J1<->B.P1") != std::string::npos); // connection name
CHECK(out.find("identity") != std::string::npos); // transform
CHECK(out.find("NETA") != std::string::npos); // left signal
CHECK(out.find("NETB") != std::string::npos); // right signal
std::remove(path);
}
TEST_CASE("export_connections reports a bad path instead of crashing") {
System sys;
app::ExportResult r = app::export_connections(
&sys, "/nonexistent-dir-xyz/out.csv", app::ExportFormat::Csv);
CHECK_FALSE(r.ok);
CHECK_FALSE(r.error.empty());
}