#include #include "core/app/script.hpp" #include "core/domain/modules.hpp" #include "core/domain/system.hpp" #include #include #include #include #include // app::run_script is pure core: it drives the app::* operations from a command // script and writes their output to a stream. No UI. TEST_CASE("run_script builds a system from a command script") { const char *net = "test_script_in.net"; { std::ofstream f(net); f << "COMP: 'C1' 'J1'\n" " Explicit Pin: '1' 'x' 'NETA'\n" " Explicit Pin: '2' 'x' 'NETB'\n" "COMP: 'C2' 'J2'\n" " Explicit Pin: '1' 'x' 'NETA'\n" " Explicit Pin: '2' 'x' 'NETB'\n"; } const char *scr = "test_script_in.essim"; { std::ofstream f(scr); f << "# a comment\n" "\n" "set NET " << net << "\n" "new\n" "load M $NET mentor\n" "set-signal-type M NETA power\n" "verify\n"; } std::unique_ptr sys; std::ostringstream out; app::ScriptResult r = app::run_script(sys, scr, out); CHECK(r.ok); CHECK(r.errors == 0); REQUIRE(sys != nullptr); CHECK(sys->modules()->size() == 1); const std::string log = out.str(); CHECK(log.find("loaded 'M'") != std::string::npos); // load ran CHECK(log.find("signal type = power") != std::string::npos); // $NET expanded + set CHECK(log.find("verify:") != std::string::npos); // verify ran std::remove(net); std::remove(scr); } TEST_CASE("run_script reports a missing top-level file") { std::unique_ptr sys; std::ostringstream out; app::ScriptResult r = app::run_script(sys, "/nonexistent-xyz/none.essim", out); CHECK_FALSE(r.ok); CHECK(r.error.find("cannot open") != std::string::npos); } TEST_CASE("run_script flags an unsupported command and keeps going") { const char *scr = "test_script_unsup.essim"; { std::ofstream f(scr); f << "new\nfrobnicate widgets\nnew\n"; } std::unique_ptr sys; std::ostringstream out; app::ScriptResult r = app::run_script(sys, scr, out); CHECK(r.ok); CHECK(r.errors == 1); CHECK(out.str().find("unsupported command 'frobnicate'") != std::string::npos); REQUIRE(sys != nullptr); // the two `new` lines still ran std::remove(scr); }