#pragma once // ───────────────────────────────────────────────────────────────────────────── // test_basic_module — universal C++ provider fixture. // // The point of this module is COVERAGE: it declares one method per // return type, per parameter type and per argument count (0–5) the SDK has to // carry over the wire, so a codec regression shows up here before it shows up // in a real module. That matrix is preserved 1:1 across the move to // `interface: "universal"`; this plain C++ class is now the contract. // `logos-cpp-generator --header-to-lidl` derives the LIDL from it, // `logos-cpp-generator --lidl ... --backend cdylib` emits the Qt-free C-ABI // exports, and logos-plugin-qt's `logos-qt-host-generator --backend cdylib` // emits the Qt plugin glue. // // ── Type choices that are NOT arbitrary ───────────────────────────────────── // * `nlohmann::json` (NOT LogosMap / LogosList) for the returnVariant* // family. The parser maps the bare alias-expanded spelling to LIDL `any`, // which is `QVariant` on the Qt surface — exactly what those four methods // returned before. LogosMap/LogosList would have narrowed them to // QVariantMap/QVariantList. // * `LogosList` for the JSON-array pair: `[any]` → QVariantList. The old // declared type, QJsonArray, has no universal spelling. The VALUE on the // wire is the same JSON array; only the declared Qt type moves. The whole // set of types that moved is the table under "Universal migration — the // Qt types that moved" in this repo's README. // * `std::vector` → bstr → QByteArray, so byteArraySize keeps its // exact parameter type. // * `std::vector` → [tstr] → QStringList, so joinStrings / // returnStringList / splitString keep theirs. // // ── Strings ───────────────────────────────────────────────────────────────── // Every `std::string` here is UTF-8, and every "length" this module reports is // a number of CHARACTERS (Unicode code points) — see stringLength and // validateInput. byteArraySize is the deliberate contrast: it takes a bstr and // answers in bytes, so "héllo" is 5 to the first two and 6 to it. // // NO trailing `// comments` on declaration lines (the parser needs a `;`). // ───────────────────────────────────────────────────────────────────────────── #include #include #include #include // LogosMap / LogosList (nlohmann::json aliases) #include // LogosModuleContext base; pulls in `logos_events` #include // StdLogosResult class TestBasicModuleImpl : public LogosModuleContext { public: TestBasicModuleImpl() = default; ~TestBasicModuleImpl() = default; // ── Return type: void ──────────────────────────────────────────────────── void doNothing(); void doNothingWithArgs(const std::string& a, int64_t b); // ── Return type: bool ──────────────────────────────────────────────────── bool returnTrue(); bool returnFalse(); bool isPositive(int64_t value); // ── Return type: int ───────────────────────────────────────────────────── int64_t returnInt(); int64_t addInts(int64_t a, int64_t b); // Length of `s` in CHARACTERS (Unicode code points), the string being // UTF-8: stringLength("hello") == 5 and stringLength("héllo") == 5 too. // An emoji outside the BMP is one character and counts 1 — the byte count // says 4 and Qt's UTF-16 QString said 2, neither of which is a length of // any text. int64_t stringLength(const std::string& s); // ── Return type: string ────────────────────────────────────────────────── std::string returnString(); std::string echo(const std::string& input); std::string concat(const std::string& a, const std::string& b); // ── Return type: result ────────────────────────────────────────────────── StdLogosResult successResult(); StdLogosResult errorResult(); StdLogosResult resultWithMap(); StdLogosResult resultWithList(); // {success, {input, length}} for a non-empty input, an error otherwise. // `length` is the same quantity stringLength returns — CHARACTERS. StdLogosResult validateInput(const std::string& input); // ── Return type: any (QVariant) ────────────────────────────────────────── nlohmann::json returnVariantInt(); nlohmann::json returnVariantString(); nlohmann::json returnVariantMap(); nlohmann::json returnVariantList(); // ── Return type: JSON array ────────────────────────────────────────────── LogosList returnJsonArray(); LogosList makeJsonArray(const std::string& a, const std::string& b); // ── Return type: string list ───────────────────────────────────────────── std::vector returnStringList(); std::vector splitString(const std::string& input); // ── Parameter types ────────────────────────────────────────────────────── int64_t echoInt(int64_t n); bool echoBool(bool b); std::string joinStrings(const std::vector& list); int64_t byteArraySize(const std::vector& data); // Normalise the case-insensitive parts of a URL and return it as a string: // the scheme and the host are lowercased, everything else is left exactly // as given (the path and query are case-SENSITIVE, so "/a/../b?x=1" stays // "/a/../b?x=1" — normalising those would change what the URL means). // urlToString("HTTP://Example.COM/a/../b?x=1") // == "http://example.com/a/../b?x=1" std::string urlToString(const std::string& url); // ── Argument counts 0–5 ────────────────────────────────────────────────── std::string noArgs(); std::string oneArg(const std::string& a); std::string twoArgs(const std::string& a, int64_t b); std::string threeArgs(const std::string& a, int64_t b, bool c); std::string fourArgs(const std::string& a, int64_t b, bool c, const std::string& d); std::string fiveArgs(const std::string& a, int64_t b, bool c, const std::string& d, int64_t e); // ── Events ─────────────────────────────────────────────────────────────── // Drivers kept as methods with their original names and arity: consumers // (test_ipc_new_api_module, and the event-system group in run_tests.sh) // call them BY NAME to make this module emit. test_ipc_module was a third // such caller until af567c1 retired it. void emitTestEvent(const std::string& data); void emitMultiArgEvent(const std::string& name, int64_t count); // ── Async helpers ──────────────────────────────────────────────────────── std::string echoWithDelay(const std::string& value, int64_t delayMs); // ── Crash testing ──────────────────────────────────────────────────────── void crashOnDemand(); // The two events this module emits. They were previously emitted // dynamically by name through the Qt `eventResponse` signal; declaring // them here keeps the SAME wire names ("testEvent" / "multiArgEvent") // while making them typed and discoverable by consumer-side codegen. logos_events: void testEvent(const std::string& data); void multiArgEvent(const std::string& name, int64_t count); };