From c1c374bbccadca9cbe3d7ed38be7dfd4c09b57d8 Mon Sep 17 00:00:00 2001 From: Logos Workspace Date: Wed, 25 Mar 2026 13:39:23 -0400 Subject: [PATCH] remove proxy api (moved to logos-module-client) --- cpp/CMakeLists.txt | 9 - cpp/logos_core_client.cpp | 85 ---------- cpp/logos_core_client.h | 62 ------- cpp/logos_json_utils.cpp | 115 ------------- cpp/logos_json_utils.h | 44 ----- cpp/logos_sdk_c.cpp | 62 ------- cpp/logos_sdk_c.h | 57 ------- nix/include.nix | 5 +- tests/sdk/CMakeLists.txt | 3 - tests/sdk/test_logos_core_client.cpp | 127 -------------- tests/sdk/test_logos_json_utils.cpp | 236 --------------------------- tests/sdk/test_logos_sdk_c.cpp | 160 ------------------ 12 files changed, 1 insertion(+), 964 deletions(-) delete mode 100644 cpp/logos_core_client.cpp delete mode 100644 cpp/logos_core_client.h delete mode 100644 cpp/logos_json_utils.cpp delete mode 100644 cpp/logos_json_utils.h delete mode 100644 cpp/logos_sdk_c.cpp delete mode 100644 cpp/logos_sdk_c.h delete mode 100644 tests/sdk/test_logos_core_client.cpp delete mode 100644 tests/sdk/test_logos_json_utils.cpp delete mode 100644 tests/sdk/test_logos_sdk_c.cpp diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index a8aa602..8d1bd90 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -51,12 +51,6 @@ set(SDK_SOURCES implementations/mock/mock_transport.h implementations/mock/mock_registry.h implementations/mock/logos_mock.h - logos_json_utils.cpp - logos_json_utils.h - logos_core_client.cpp - logos_core_client.h - logos_sdk_c.cpp - logos_sdk_c.h ) # Create the SDK library as STATIC instead of SHARED @@ -104,9 +98,6 @@ install(FILES logos_transport_factory.h logos_registry.h logos_registry_factory.h - logos_json_utils.h - logos_core_client.h - logos_sdk_c.h DESTINATION include ) diff --git a/cpp/logos_core_client.cpp b/cpp/logos_core_client.cpp deleted file mode 100644 index ce08d3e..0000000 --- a/cpp/logos_core_client.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "logos_core_client.h" -#include "logos_api.h" -#include "logos_api_client.h" -#include "logos_object.h" -#include "logos_json_utils.h" -#include - -LogosCoreClient::LogosCoreClient(QObject* parent) - : QObject(parent) - , m_api(new LogosAPI("core", this)) -{ -} - -LogosCoreClient::~LogosCoreClient() -{ -} - -LogosAPIClient* LogosCoreClient::clientFor(const QString& pluginName) -{ - return m_api->getClient(pluginName); -} - -void LogosCoreClient::callMethodAsync(const QString& pluginName, - const QString& methodName, - const QString& paramsJson, - AsyncCallback callback) -{ - if (!callback) return; - - bool ok = false; - QString errorMessage; - QVariantList args = LogosJsonUtils::parseMethodParams(paramsJson, &ok, &errorMessage); - - if (!ok) { - callback(false, errorMessage); - return; - } - - LogosAPIClient* client = m_api->getClient(pluginName); - if (!client) { - callback(false, QString("Failed to get client for plugin: %1").arg(pluginName)); - return; - } - - client->invokeRemoteMethodAsync( - pluginName, methodName, args, - [callback, pluginName, methodName](QVariant result) { - if (result.isValid()) { - QString resultStr; - if (result.canConvert()) { - resultStr = result.toString(); - } else { - resultStr = QString("Result of type: %1").arg(result.typeName()); - } - callback(true, QString("Method call successful. Result: %1").arg(resultStr)); - } else { - callback(false, QStringLiteral("Method call returned invalid result")); - } - }); -} - -void LogosCoreClient::subscribeEvent(const QString& pluginName, - const QString& eventName, - AsyncCallback callback) -{ - if (!callback) return; - - LogosAPIClient* client = m_api->getClient(pluginName); - if (!client) { - qWarning() << "LogosCoreClient: Failed to get client for event subscription:" << pluginName; - return; - } - - LogosObject* obj = client->requestObject(pluginName); - if (!obj) { - qWarning() << "LogosCoreClient: Failed to get object for event subscription:" << pluginName; - return; - } - - client->onEvent(obj, eventName, - [callback](const QString& evName, const QVariantList& evData) { - QString json = LogosJsonUtils::formatEventJson(evName, evData); - callback(true, json); - }); -} diff --git a/cpp/logos_core_client.h b/cpp/logos_core_client.h deleted file mode 100644 index b9d40cc..0000000 --- a/cpp/logos_core_client.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef LOGOS_CORE_CLIENT_H -#define LOGOS_CORE_CLIENT_H - -#include -#include -#include -#include -#include -#include - -class LogosAPI; -class LogosAPIClient; -class LogosObject; - -/** - * @brief LogosCoreClient provides a high-level async interface for calling - * plugin methods and subscribing to events from the "core" (host) perspective. - * - * Unlike creating ephemeral LogosAPI instances per call, this class maintains - * a single persistent LogosAPI("core") and reuses cached client connections. - * - * It uses LogosAPIClient::invokeRemoteMethodAsync for connection-aware calls, - * eliminating manual QTimer-based connection delays. - */ -class LogosCoreClient : public QObject -{ - Q_OBJECT - -public: - using AsyncCallback = std::function; - - explicit LogosCoreClient(QObject* parent = nullptr); - ~LogosCoreClient(); - - /** - * Call a plugin method asynchronously, with parameters provided as a JSON - * string in the [{name,value,type},...] format used by FFI consumers. - * The callback receives (success, resultMessage). - */ - void callMethodAsync(const QString& pluginName, - const QString& methodName, - const QString& paramsJson, - AsyncCallback callback); - - /** - * Subscribe to an event from a plugin. The callback fires each time - * the event is emitted, with a JSON-formatted message. - */ - void subscribeEvent(const QString& pluginName, - const QString& eventName, - AsyncCallback callback); - - /** - * Get (or lazily create) a LogosAPIClient for the named plugin. - */ - LogosAPIClient* clientFor(const QString& pluginName); - -private: - LogosAPI* m_api; -}; - -#endif // LOGOS_CORE_CLIENT_H diff --git a/cpp/logos_json_utils.cpp b/cpp/logos_json_utils.cpp deleted file mode 100644 index ffe44d7..0000000 --- a/cpp/logos_json_utils.cpp +++ /dev/null @@ -1,115 +0,0 @@ -#include "logos_json_utils.h" -#include -#include -#include -#include - -namespace LogosJsonUtils { - -QVariant jsonParamToVariant(const QJsonObject& param) -{ - QString name = param.value("name").toString(); - QString value = param.value("value").toString(); - QString type = param.value("type").toString(); - - qDebug() << "LogosJsonUtils: Converting param:" << name << "value:" << value << "type:" << type; - - if (type == "string" || type == "QString") { - return QVariant(value); - } else if (type == "int" || type == "integer") { - bool ok; - int intValue = value.toInt(&ok); - return ok ? QVariant(intValue) : QVariant(); - } else if (type == "bool" || type == "boolean") { - if (value.toLower() == "true" || value == "1") { - return QVariant(true); - } else if (value.toLower() == "false" || value == "0") { - return QVariant(false); - } - return QVariant(); - } else if (type == "double" || type == "float") { - bool ok; - double doubleValue = value.toDouble(&ok); - return ok ? QVariant(doubleValue) : QVariant(); - } else { - qWarning() << "LogosJsonUtils: Unknown parameter type:" << type << "- treating as string"; - return QVariant(value); - } -} - -QVariantList parseMethodParams(const QString& json, bool* ok, QString* errorMessage) -{ - QVariantList args; - - QJsonParseError parseError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(json.toUtf8(), &parseError); - - if (parseError.error != QJsonParseError::NoError) { - if (ok) *ok = false; - if (errorMessage) *errorMessage = QString("JSON parse error: %1").arg(parseError.errorString()); - return args; - } - - QJsonArray paramsArray = jsonDoc.array(); - - for (const QJsonValue& paramValue : paramsArray) { - if (paramValue.isObject()) { - QJsonObject paramObj = paramValue.toObject(); - QVariant variant = jsonParamToVariant(paramObj); - if (variant.isValid()) { - args.append(variant); - } else { - if (ok) *ok = false; - if (errorMessage) *errorMessage = QString("Invalid parameter: %1").arg(paramObj.value("name").toString()); - return QVariantList(); - } - } - } - - if (ok) *ok = true; - return args; -} - -QString variantToJsonString(const QVariant& value) -{ - if (!value.isValid()) - return QStringLiteral("null"); - - switch (value.userType()) { - case QMetaType::Bool: - return value.toBool() ? QStringLiteral("true") : QStringLiteral("false"); - case QMetaType::Int: - case QMetaType::LongLong: - return QString::number(value.toLongLong()); - case QMetaType::Double: - case QMetaType::Float: - return QString::number(value.toDouble()); - case QMetaType::QString: - return value.toString(); - case QMetaType::QVariantMap: { - QJsonDocument doc(QJsonObject::fromVariantMap(value.toMap())); - return QString::fromUtf8(doc.toJson(QJsonDocument::Compact)); - } - case QMetaType::QVariantList: { - QJsonDocument doc(QJsonArray::fromVariantList(value.toList())); - return QString::fromUtf8(doc.toJson(QJsonDocument::Compact)); - } - default: - break; - } - - return value.toString(); -} - -QString formatEventJson(const QString& eventName, const QVariantList& data) -{ - QString result = QString("{\"event\":\"%1\",\"data\":[").arg(eventName); - for (int i = 0; i < data.size(); ++i) { - if (i > 0) result += ","; - result += QString("\"%1\"").arg(data[i].toString()); - } - result += "]}"; - return result; -} - -} // namespace LogosJsonUtils diff --git a/cpp/logos_json_utils.h b/cpp/logos_json_utils.h deleted file mode 100644 index 0e97eb7..0000000 --- a/cpp/logos_json_utils.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef LOGOS_JSON_UTILS_H -#define LOGOS_JSON_UTILS_H - -#include -#include -#include -#include - -namespace LogosJsonUtils { - - /** - * Convert a single JSON parameter object {name, value, type} to a QVariant. - * Supports types: string, QString, int, integer, bool, boolean, double, float. - * Unknown types are treated as strings. - * Returns invalid QVariant for unparseable values (e.g. "abc" as int). - */ - QVariant jsonParamToVariant(const QJsonObject& param); - - /** - * Parse a JSON string containing an array of {name, value, type} objects - * into a QVariantList. This is the format used by FFI consumers (e.g. logos-js-sdk). - * - * On success, sets ok=true and returns the converted arguments. - * On failure (JSON parse error or invalid parameter), sets ok=false and - * fills errorMessage with a description. - */ - QVariantList parseMethodParams(const QString& json, bool* ok = nullptr, QString* errorMessage = nullptr); - - /** - * Convert a QVariant result into a JSON-formatted string suitable for - * returning through the C callback API. - */ - QString variantToJsonString(const QVariant& value); - - /** - * Format event data (event name + QVariantList payload) as a JSON string - * matching the format expected by FFI consumers: - * {"event":"","data":["","",...]} - */ - QString formatEventJson(const QString& eventName, const QVariantList& data); - -} - -#endif // LOGOS_JSON_UTILS_H diff --git a/cpp/logos_sdk_c.cpp b/cpp/logos_sdk_c.cpp deleted file mode 100644 index 4eed92a..0000000 --- a/cpp/logos_sdk_c.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "logos_sdk_c.h" -#include "logos_core_client.h" -#include -#include - -static LogosCoreClient* s_coreClient = nullptr; - -static LogosCoreClient* ensureClient() -{ - if (!s_coreClient) - s_coreClient = new LogosCoreClient(); - return s_coreClient; -} - -void logos_sdk_call_method_async( - const char* plugin_name, - const char* method_name, - const char* params_json, - LogosSdkCallback callback, - void* user_data) -{ - if (!callback) return; - - if (!plugin_name || !method_name) { - callback(0, "Plugin name or method name is null", user_data); - return; - } - - QString pluginStr = QString::fromUtf8(plugin_name); - QString methodStr = QString::fromUtf8(method_name); - QString paramsStr = params_json ? QString::fromUtf8(params_json) : QStringLiteral("[]"); - - ensureClient()->callMethodAsync(pluginStr, methodStr, paramsStr, - [callback, user_data](bool success, const QString& message) { - QByteArray msgBytes = message.toUtf8(); - callback(success ? 1 : 0, msgBytes.constData(), user_data); - }); -} - -void logos_sdk_register_event( - const char* plugin_name, - const char* event_name, - LogosSdkCallback callback, - void* user_data) -{ - if (!plugin_name || !event_name || !callback) return; - - QString pluginStr = QString::fromUtf8(plugin_name); - QString eventStr = QString::fromUtf8(event_name); - - ensureClient()->subscribeEvent(pluginStr, eventStr, - [callback, user_data](bool success, const QString& message) { - QByteArray msgBytes = message.toUtf8(); - callback(success ? 1 : 0, msgBytes.constData(), user_data); - }); -} - -void logos_sdk_shutdown() -{ - delete s_coreClient; - s_coreClient = nullptr; -} diff --git a/cpp/logos_sdk_c.h b/cpp/logos_sdk_c.h deleted file mode 100644 index e86647a..0000000 --- a/cpp/logos_sdk_c.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef LOGOS_SDK_C_H -#define LOGOS_SDK_C_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * C callback type matching the AsyncCallback in logos_core.h: - * void(int result, const char* message, void* user_data) - */ -typedef void (*LogosSdkCallback)(int result, const char* message, void* user_data); - -/** - * Call a plugin method asynchronously. - * - * @param plugin_name Target plugin name - * @param method_name Method to call - * @param params_json JSON array of [{name,value,type},...] parameters (may be NULL for "[]") - * @param callback Receives (1=success/0=failure, message, user_data) on completion - * @param user_data Opaque pointer passed through to callback - */ -void logos_sdk_call_method_async( - const char* plugin_name, - const char* method_name, - const char* params_json, - LogosSdkCallback callback, - void* user_data -); - -/** - * Register an event listener for a specific event from a plugin. - * - * @param plugin_name Plugin that emits the event - * @param event_name Event name to listen for - * @param callback Receives (1, json_event_data, user_data) each time event fires - * @param user_data Opaque pointer passed through to callback - */ -void logos_sdk_register_event( - const char* plugin_name, - const char* event_name, - LogosSdkCallback callback, - void* user_data -); - -/** - * Shut down the SDK's internal core client, releasing connections. - * Safe to call multiple times. After this, async calls will lazily re-create - * the client on next use. - */ -void logos_sdk_shutdown(void); - -#ifdef __cplusplus -} -#endif - -#endif // LOGOS_SDK_C_H diff --git a/nix/include.nix b/nix/include.nix index c367735..91dd285 100644 --- a/nix/include.nix +++ b/nix/include.nix @@ -36,10 +36,7 @@ pkgs.stdenv.mkDerivation { qt_provider_object.h qt_provider_object.cpp \ logos_transport.h logos_transport_factory.h logos_transport_factory.cpp \ logos_registry.h logos_registry_factory.h logos_registry_factory.cpp \ - plugin_registry.h \ - logos_json_utils.h logos_json_utils.cpp \ - logos_core_client.h logos_core_client.cpp \ - logos_sdk_c.h logos_sdk_c.cpp; do + plugin_registry.h; do if [ -f cpp/$file ]; then cp cpp/$file $out/include/cpp/ fi diff --git a/tests/sdk/CMakeLists.txt b/tests/sdk/CMakeLists.txt index 85ae186..5058607 100644 --- a/tests/sdk/CMakeLists.txt +++ b/tests/sdk/CMakeLists.txt @@ -38,9 +38,6 @@ add_executable(sdk_tests test_local_transport_integration.cpp test_event_system.cpp test_provider_dispatch.cpp - test_logos_json_utils.cpp - test_logos_core_client.cpp - test_logos_sdk_c.cpp fixtures/sample_provider.cpp ${GENERATED_DISPATCH} ) diff --git a/tests/sdk/test_logos_core_client.cpp b/tests/sdk/test_logos_core_client.cpp deleted file mode 100644 index a5a0cc6..0000000 --- a/tests/sdk/test_logos_core_client.cpp +++ /dev/null @@ -1,127 +0,0 @@ -#include -#include -#include "logos_mock.h" -#include "logos_core_client.h" - -class LogosCoreClientTest : public ::testing::Test { -protected: - void SetUp() override { m_mock = new LogosMockSetup(); } - void TearDown() override { delete m_mock; } - LogosMockSetup* m_mock = nullptr; - - void processEvents() { - for (int i = 0; i < 10; ++i) - QCoreApplication::processEvents(); - } -}; - -TEST_F(LogosCoreClientTest, CallMethodAsync_SuccessfulCall) -{ - m_mock->when("test_module", "greet").thenReturn(QVariant("hello world")); - - LogosCoreClient client; - bool called = false; - bool success = false; - QString message; - - client.callMethodAsync("test_module", "greet", "[]", - [&](bool s, const QString& m) { called = true; success = s; message = m; }); - - processEvents(); - - EXPECT_TRUE(called); - EXPECT_TRUE(success); - EXPECT_TRUE(message.contains("hello world")); -} - -TEST_F(LogosCoreClientTest, CallMethodAsync_WithJsonParams) -{ - m_mock->when("math", "add").thenReturn(QVariant(30)); - - LogosCoreClient client; - bool called = false; - bool success = false; - - QString params = R"([{"name":"a","value":"10","type":"int"},{"name":"b","value":"20","type":"int"}])"; - client.callMethodAsync("math", "add", params, - [&](bool s, const QString&) { called = true; success = s; }); - - processEvents(); - - EXPECT_TRUE(called); - EXPECT_TRUE(success); - EXPECT_TRUE(m_mock->wasCalled("math", "add")); -} - -TEST_F(LogosCoreClientTest, CallMethodAsync_InvalidJsonReportsError) -{ - LogosCoreClient client; - bool called = false; - bool success = true; - QString message; - - client.callMethodAsync("mod", "fn", "not valid json", - [&](bool s, const QString& m) { called = true; success = s; message = m; }); - - EXPECT_TRUE(called); - EXPECT_FALSE(success); - EXPECT_TRUE(message.contains("JSON parse error")); -} - -TEST_F(LogosCoreClientTest, CallMethodAsync_InvalidParamReportsError) -{ - LogosCoreClient client; - bool called = false; - bool success = true; - QString message; - - QString params = R"([{"name":"a","value":"abc","type":"int"}])"; - client.callMethodAsync("mod", "fn", params, - [&](bool s, const QString& m) { called = true; success = s; message = m; }); - - EXPECT_TRUE(called); - EXPECT_FALSE(success); - EXPECT_TRUE(message.contains("Invalid parameter")); -} - -TEST_F(LogosCoreClientTest, CallMethodAsync_NullCallbackIsNoOp) -{ - LogosCoreClient client; - client.callMethodAsync("mod", "fn", "[]", nullptr); -} - -TEST_F(LogosCoreClientTest, CallMethodAsync_InvalidResultReportsError) -{ - // No expectation set -> mock returns invalid QVariant - m_mock->when("mod", "other").thenReturn(QVariant(1)); - - LogosCoreClient client; - bool called = false; - bool success = true; - QString message; - - client.callMethodAsync("mod", "missing_fn", "[]", - [&](bool s, const QString& m) { called = true; success = s; message = m; }); - - processEvents(); - - EXPECT_TRUE(called); - EXPECT_FALSE(success); - EXPECT_TRUE(message.contains("invalid result")); -} - -TEST_F(LogosCoreClientTest, ClientFor_ReturnsSameClientForSamePlugin) -{ - LogosCoreClient client; - auto* c1 = client.clientFor("mod"); - auto* c2 = client.clientFor("mod"); - EXPECT_EQ(c1, c2); -} - -TEST_F(LogosCoreClientTest, ClientFor_ReturnsDifferentForDifferentPlugins) -{ - LogosCoreClient client; - auto* c1 = client.clientFor("mod_a"); - auto* c2 = client.clientFor("mod_b"); - EXPECT_NE(c1, c2); -} diff --git a/tests/sdk/test_logos_json_utils.cpp b/tests/sdk/test_logos_json_utils.cpp deleted file mode 100644 index cd2ef1f..0000000 --- a/tests/sdk/test_logos_json_utils.cpp +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include "logos_json_utils.h" -#include - -// ============================================================================= -// jsonParamToVariant tests -// ============================================================================= - -TEST(LogosJsonUtilsTest, ConvertsStringType) -{ - QJsonObject p; - p["name"] = "arg0"; p["value"] = "hello"; p["type"] = "string"; - QVariant v = LogosJsonUtils::jsonParamToVariant(p); - EXPECT_TRUE(v.isValid()); - EXPECT_EQ(v.toString(), "hello"); -} - -TEST(LogosJsonUtilsTest, ConvertsQStringType) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "qt"; p["type"] = "QString"; - EXPECT_EQ(LogosJsonUtils::jsonParamToVariant(p).toString(), "qt"); -} - -TEST(LogosJsonUtilsTest, ConvertsIntType) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "42"; p["type"] = "int"; - QVariant v = LogosJsonUtils::jsonParamToVariant(p); - EXPECT_TRUE(v.isValid()); - EXPECT_EQ(v.toInt(), 42); -} - -TEST(LogosJsonUtilsTest, ConvertsIntegerType) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "99"; p["type"] = "integer"; - EXPECT_EQ(LogosJsonUtils::jsonParamToVariant(p).toInt(), 99); -} - -TEST(LogosJsonUtilsTest, ConvertsBoolTrue) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "true"; p["type"] = "bool"; - EXPECT_TRUE(LogosJsonUtils::jsonParamToVariant(p).toBool()); - - p["value"] = "1"; - EXPECT_TRUE(LogosJsonUtils::jsonParamToVariant(p).toBool()); -} - -TEST(LogosJsonUtilsTest, ConvertsBoolFalse) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "false"; p["type"] = "bool"; - EXPECT_FALSE(LogosJsonUtils::jsonParamToVariant(p).toBool()); - - p["value"] = "0"; - EXPECT_FALSE(LogosJsonUtils::jsonParamToVariant(p).toBool()); -} - -TEST(LogosJsonUtilsTest, ConvertsBooleanType) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "true"; p["type"] = "boolean"; - EXPECT_TRUE(LogosJsonUtils::jsonParamToVariant(p).toBool()); -} - -TEST(LogosJsonUtilsTest, ConvertsDoubleType) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "3.14"; p["type"] = "double"; - EXPECT_NEAR(LogosJsonUtils::jsonParamToVariant(p).toDouble(), 3.14, 0.001); -} - -TEST(LogosJsonUtilsTest, ConvertsFloatType) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "2.718"; p["type"] = "float"; - EXPECT_NEAR(LogosJsonUtils::jsonParamToVariant(p).toDouble(), 2.718, 0.001); -} - -TEST(LogosJsonUtilsTest, InvalidIntReturnsInvalid) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "abc"; p["type"] = "int"; - EXPECT_FALSE(LogosJsonUtils::jsonParamToVariant(p).isValid()); -} - -TEST(LogosJsonUtilsTest, InvalidBoolReturnsInvalid) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "maybe"; p["type"] = "bool"; - EXPECT_FALSE(LogosJsonUtils::jsonParamToVariant(p).isValid()); -} - -TEST(LogosJsonUtilsTest, InvalidDoubleReturnsInvalid) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "xyz"; p["type"] = "double"; - EXPECT_FALSE(LogosJsonUtils::jsonParamToVariant(p).isValid()); -} - -TEST(LogosJsonUtilsTest, UnknownTypeTreatedAsString) -{ - QJsonObject p; - p["name"] = "a"; p["value"] = "data"; p["type"] = "custom_thing"; - QVariant v = LogosJsonUtils::jsonParamToVariant(p); - EXPECT_TRUE(v.isValid()); - EXPECT_EQ(v.toString(), "data"); -} - -// ============================================================================= -// parseMethodParams tests -// ============================================================================= - -TEST(LogosJsonUtilsTest, ParseMixedParams) -{ - QString json = R"([ - {"name":"arg0","value":"hello","type":"string"}, - {"name":"arg1","value":"42","type":"int"}, - {"name":"arg2","value":"true","type":"bool"}, - {"name":"arg3","value":"3.14","type":"double"} - ])"; - bool ok = false; - QString err; - QVariantList args = LogosJsonUtils::parseMethodParams(json, &ok, &err); - EXPECT_TRUE(ok); - EXPECT_TRUE(err.isEmpty()); - ASSERT_EQ(args.size(), 4); - EXPECT_EQ(args[0].toString(), "hello"); - EXPECT_EQ(args[1].toInt(), 42); - EXPECT_TRUE(args[2].toBool()); - EXPECT_NEAR(args[3].toDouble(), 3.14, 0.001); -} - -TEST(LogosJsonUtilsTest, ParseEmptyArray) -{ - bool ok = false; - QVariantList args = LogosJsonUtils::parseMethodParams("[]", &ok); - EXPECT_TRUE(ok); - EXPECT_EQ(args.size(), 0); -} - -TEST(LogosJsonUtilsTest, ParseInvalidJson) -{ - bool ok = true; - QString err; - QVariantList args = LogosJsonUtils::parseMethodParams("not json", &ok, &err); - EXPECT_FALSE(ok); - EXPECT_TRUE(err.contains("JSON parse error")); - EXPECT_EQ(args.size(), 0); -} - -TEST(LogosJsonUtilsTest, ParseInvalidParamValue) -{ - QString json = R"([{"name":"a","value":"abc","type":"int"}])"; - bool ok = true; - QString err; - QVariantList args = LogosJsonUtils::parseMethodParams(json, &ok, &err); - EXPECT_FALSE(ok); - EXPECT_TRUE(err.contains("Invalid parameter")); -} - -TEST(LogosJsonUtilsTest, ParseSingleString) -{ - QString json = R"([{"name":"arg0","value":"test","type":"string"}])"; - bool ok = false; - QVariantList args = LogosJsonUtils::parseMethodParams(json, &ok); - EXPECT_TRUE(ok); - ASSERT_EQ(args.size(), 1); - EXPECT_EQ(args[0].toString(), "test"); -} - -TEST(LogosJsonUtilsTest, ParseNullOkPointer) -{ - QVariantList args = LogosJsonUtils::parseMethodParams("[]"); - EXPECT_EQ(args.size(), 0); -} - -// ============================================================================= -// variantToJsonString tests -// ============================================================================= - -TEST(LogosJsonUtilsTest, VariantToJson_Invalid) -{ - EXPECT_EQ(LogosJsonUtils::variantToJsonString(QVariant()), "null"); -} - -TEST(LogosJsonUtilsTest, VariantToJson_String) -{ - EXPECT_EQ(LogosJsonUtils::variantToJsonString(QVariant("hello")), "hello"); -} - -TEST(LogosJsonUtilsTest, VariantToJson_Int) -{ - EXPECT_EQ(LogosJsonUtils::variantToJsonString(QVariant(42)), "42"); -} - -TEST(LogosJsonUtilsTest, VariantToJson_Bool) -{ - EXPECT_EQ(LogosJsonUtils::variantToJsonString(QVariant(true)), "true"); - EXPECT_EQ(LogosJsonUtils::variantToJsonString(QVariant(false)), "false"); -} - -TEST(LogosJsonUtilsTest, VariantToJson_Double) -{ - QString result = LogosJsonUtils::variantToJsonString(QVariant(3.14)); - EXPECT_TRUE(result.startsWith("3.14")); -} - -TEST(LogosJsonUtilsTest, VariantToJson_Map) -{ - QVariantMap map; - map["key"] = "value"; - QString result = LogosJsonUtils::variantToJsonString(QVariant(map)); - EXPECT_TRUE(result.contains("key")); - EXPECT_TRUE(result.contains("value")); -} - -// ============================================================================= -// formatEventJson tests -// ============================================================================= - -TEST(LogosJsonUtilsTest, FormatEventJson_Basic) -{ - QVariantList data; - data << QVariant("hello") << QVariant(42); - QString result = LogosJsonUtils::formatEventJson("myEvent", data); - EXPECT_EQ(result, R"({"event":"myEvent","data":["hello","42"]})"); -} - -TEST(LogosJsonUtilsTest, FormatEventJson_Empty) -{ - QString result = LogosJsonUtils::formatEventJson("evt", {}); - EXPECT_EQ(result, R"({"event":"evt","data":[]})"); -} diff --git a/tests/sdk/test_logos_sdk_c.cpp b/tests/sdk/test_logos_sdk_c.cpp deleted file mode 100644 index 6ee10da..0000000 --- a/tests/sdk/test_logos_sdk_c.cpp +++ /dev/null @@ -1,160 +0,0 @@ -#include -#include -#include "logos_mock.h" -#include "logos_sdk_c.h" -#include - -static bool s_called = false; -static int s_result = -1; -static std::string s_message; -static void* s_user_data = nullptr; - -static void resetState() -{ - s_called = false; - s_result = -1; - s_message.clear(); - s_user_data = nullptr; -} - -static void testCCallback(int result, const char* message, void* user_data) -{ - s_called = true; - s_result = result; - s_message = message ? message : ""; - s_user_data = user_data; -} - -class LogosSdkCTest : public ::testing::Test { -protected: - void SetUp() override - { - m_mock = new LogosMockSetup(); - resetState(); - } - void TearDown() override - { - logos_sdk_shutdown(); - delete m_mock; - } - LogosMockSetup* m_mock = nullptr; - - void processEvents() { - for (int i = 0; i < 10; ++i) - QCoreApplication::processEvents(); - } -}; - -TEST_F(LogosSdkCTest, CallMethodAsync_Success) -{ - m_mock->when("mod", "fn").thenReturn(QVariant("ok")); - - logos_sdk_call_method_async("mod", "fn", "[]", testCCallback, nullptr); - processEvents(); - - EXPECT_TRUE(s_called); - EXPECT_EQ(s_result, 1); - EXPECT_TRUE(s_message.find("ok") != std::string::npos); -} - -TEST_F(LogosSdkCTest, CallMethodAsync_WithParams) -{ - m_mock->when("mod", "fn").thenReturn(QVariant(42)); - - const char* params = R"([{"name":"a","value":"hello","type":"string"}])"; - logos_sdk_call_method_async("mod", "fn", params, testCCallback, nullptr); - processEvents(); - - EXPECT_TRUE(s_called); - EXPECT_EQ(s_result, 1); -} - -TEST_F(LogosSdkCTest, CallMethodAsync_NullPluginName) -{ - logos_sdk_call_method_async(nullptr, "fn", "[]", testCCallback, nullptr); - - EXPECT_TRUE(s_called); - EXPECT_EQ(s_result, 0); - EXPECT_TRUE(s_message.find("null") != std::string::npos); -} - -TEST_F(LogosSdkCTest, CallMethodAsync_NullMethodName) -{ - logos_sdk_call_method_async("mod", nullptr, "[]", testCCallback, nullptr); - - EXPECT_TRUE(s_called); - EXPECT_EQ(s_result, 0); -} - -TEST_F(LogosSdkCTest, CallMethodAsync_NullCallback) -{ - logos_sdk_call_method_async("mod", "fn", "[]", nullptr, nullptr); - EXPECT_FALSE(s_called); -} - -TEST_F(LogosSdkCTest, CallMethodAsync_InvalidJson) -{ - logos_sdk_call_method_async("mod", "fn", "bad json", testCCallback, nullptr); - - EXPECT_TRUE(s_called); - EXPECT_EQ(s_result, 0); - EXPECT_TRUE(s_message.find("JSON parse error") != std::string::npos); -} - -TEST_F(LogosSdkCTest, CallMethodAsync_NullParamsDefaultsToEmptyArray) -{ - m_mock->when("mod", "fn").thenReturn(QVariant("ok")); - - logos_sdk_call_method_async("mod", "fn", nullptr, testCCallback, nullptr); - processEvents(); - - EXPECT_TRUE(s_called); - EXPECT_EQ(s_result, 1); -} - -TEST_F(LogosSdkCTest, CallMethodAsync_PassesUserData) -{ - m_mock->when("mod", "fn").thenReturn(QVariant("ok")); - - int data = 999; - logos_sdk_call_method_async("mod", "fn", "[]", testCCallback, &data); - processEvents(); - - EXPECT_TRUE(s_called); - EXPECT_EQ(s_user_data, &data); -} - -TEST_F(LogosSdkCTest, RegisterEvent_NullParams) -{ - logos_sdk_register_event(nullptr, "evt", testCCallback, nullptr); - EXPECT_FALSE(s_called); - - logos_sdk_register_event("mod", nullptr, testCCallback, nullptr); - EXPECT_FALSE(s_called); - - logos_sdk_register_event("mod", "evt", nullptr, nullptr); - EXPECT_FALSE(s_called); -} - -TEST_F(LogosSdkCTest, Shutdown_SafeToCallMultipleTimes) -{ - logos_sdk_shutdown(); - logos_sdk_shutdown(); -} - -TEST_F(LogosSdkCTest, Shutdown_ThenCallRecreatesClient) -{ - m_mock->when("mod", "fn").thenReturn(QVariant("first")); - logos_sdk_call_method_async("mod", "fn", "[]", testCCallback, nullptr); - processEvents(); - EXPECT_EQ(s_result, 1); - - logos_sdk_shutdown(); - resetState(); - - m_mock->when("mod", "fn").thenReturn(QVariant("second")); - logos_sdk_call_method_async("mod", "fn", "[]", testCCallback, nullptr); - processEvents(); - EXPECT_EQ(s_result, 1); - EXPECT_TRUE(s_message.find("second") != std::string::npos); -}