mirror of
https://github.com/logos-co/logos-package-manager-module.git
synced 2026-08-27 10:31:10 +00:00
add tests using the module testing framework
This commit is contained in:
+1
-9
@@ -8,7 +8,7 @@ else()
|
||||
message(FATAL_ERROR "LogosModule.cmake not found. Set LOGOS_MODULE_BUILDER_ROOT.")
|
||||
endif()
|
||||
|
||||
# Define the module (uses LogosProviderBase / LOGOS_METHOD API)
|
||||
# LogosProviderBase / LOGOS_METHOD — dispatch is generated under generated_code/
|
||||
logos_module(
|
||||
NAME package_manager
|
||||
SOURCES
|
||||
@@ -19,11 +19,3 @@ logos_module(
|
||||
package_manager_lib
|
||||
lgx
|
||||
)
|
||||
|
||||
# Provider dispatch file (generated by logos-cpp-generator --provider-header
|
||||
# during preConfigure). Added separately without GENERATED property to avoid
|
||||
# an AUTOMOC dependency cycle with ninja.
|
||||
set(_DISPATCH "${CMAKE_CURRENT_SOURCE_DIR}/generated_code/logos_provider_dispatch.cpp")
|
||||
if(EXISTS "${_DISPATCH}")
|
||||
target_sources(package_manager_module_plugin PRIVATE "${_DISPATCH}")
|
||||
endif()
|
||||
|
||||
Generated
+6
-6
@@ -256,11 +256,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775676249,
|
||||
"narHash": "sha256-ipOQ5e9Xs4JGROrt1dH5DteXPbU91IpBipRppxG5dsE=",
|
||||
"lastModified": 1775684846,
|
||||
"narHash": "sha256-Dz2EnyIe5STjXevvmhTJz29VR5cGanwQwjHvvgi9iJg=",
|
||||
"owner": "logos-co",
|
||||
"repo": "logos-module-builder",
|
||||
"rev": "cea2766106dbe1b25b25b5ba16f4f93ef1107aa0",
|
||||
"rev": "4f53bc34b884c5f1fc23021a7ffe4c381574994d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -1539,11 +1539,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1775163659,
|
||||
"narHash": "sha256-6gk164iURa+emkY30WA9sIUCEA9ByavuBEveC5sfa08=",
|
||||
"lastModified": 1775684803,
|
||||
"narHash": "sha256-BnnrAjYJHW994WYAhd6e6/T7igLqJm4utjhqx1a6kLw=",
|
||||
"owner": "logos-co",
|
||||
"repo": "logos-test-framework",
|
||||
"rev": "a1bcd3608847535975ba4a2da473c03257a82412",
|
||||
"rev": "55b15075b5990b3c043030a3e404c7f11d57c32b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -11,9 +11,6 @@
|
||||
src = ./.;
|
||||
configFile = ./metadata.json;
|
||||
flakeInputs = inputs;
|
||||
# logos-package-manager is a pre-built flake providing
|
||||
# libpackage_manager_lib and liblgx. Use structured format to map
|
||||
# variants: #lib links dev libs, #lib-portable links portable libs.
|
||||
externalLibInputs = {
|
||||
logos_pm = {
|
||||
input = inputs.logos-package-manager;
|
||||
@@ -23,17 +20,10 @@
|
||||
};
|
||||
};
|
||||
};
|
||||
# preConfigure as a function receives { externalLibs } with resolved
|
||||
# store paths — no env vars or store globbing needed.
|
||||
preConfigure = { externalLibs }: let pm = externalLibs.logos_pm; in ''
|
||||
mkdir -p lib
|
||||
cp ${pm}/lib/libpackage_manager_lib.* lib/ 2>/dev/null || true
|
||||
cp ${pm}/lib/liblgx.* lib/ 2>/dev/null || true
|
||||
cp ${pm}/include/*.h lib/ 2>/dev/null || true
|
||||
|
||||
echo "Generating provider dispatch for package_manager..."
|
||||
logos-cpp-generator --provider-header "$(pwd)/src/package_manager_impl.h" \
|
||||
--output-dir ./generated_code
|
||||
'';
|
||||
tests = {
|
||||
dir = ./tests;
|
||||
# Same key as nix.external_libraries[].name — documents intent; go_static filtering is N/A here.
|
||||
mockCLibs = [ "logos_pm" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"description": "Plugin manager for the Logos system",
|
||||
"author": "Logos Core Team",
|
||||
"type": "core",
|
||||
"interface": "provider",
|
||||
"category": "management",
|
||||
"main": "package_manager_plugin",
|
||||
"dependencies": [],
|
||||
|
||||
+66
-12
@@ -3,27 +3,81 @@ project(PackageManagerModuleTests LANGUAGES CXX)
|
||||
|
||||
include(LogosTest)
|
||||
|
||||
# Find the external libraries (copied to lib/ by preConfigure)
|
||||
find_library(PM_LIB package_manager_lib PATHS "${CMAKE_CURRENT_SOURCE_DIR}/../lib" NO_DEFAULT_PATH REQUIRED)
|
||||
find_library(LGX_LIB lgx PATHS "${CMAKE_CURRENT_SOURCE_DIR}/../lib" NO_DEFAULT_PATH REQUIRED)
|
||||
|
||||
# Unit tests (mocked PackageManagerLib)
|
||||
logos_test(
|
||||
NAME package_manager_module_tests
|
||||
MODULE_SOURCES
|
||||
../src/package_manager_impl.cpp
|
||||
TEST_SOURCES
|
||||
main.cpp
|
||||
test_directory_config.cpp
|
||||
test_scanning.cpp
|
||||
test_signature.cpp
|
||||
test_keyring.cpp
|
||||
test_package_manager.cpp
|
||||
MOCK_C_SOURCES
|
||||
mocks/mock_package_manager_lib.cpp
|
||||
EXTRA_INCLUDES
|
||||
../lib
|
||||
stubs
|
||||
GENERATED_SOURCES
|
||||
../generated_code/logos_provider_dispatch.cpp
|
||||
GENERATED_DIR
|
||||
../generated_code
|
||||
EXTRA_LINK_LIBS
|
||||
${PM_LIB}
|
||||
${LGX_LIB}
|
||||
)
|
||||
|
||||
# Integration tests (real PackageManagerLib + lgx)
|
||||
find_library(LIBPM_PATH
|
||||
NAMES libpackage_manager_lib.so libpackage_manager_lib.dylib
|
||||
package_manager_lib
|
||||
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
find_library(LIBLGX_PATH
|
||||
NAMES liblgx.so liblgx.dylib lgx
|
||||
PATHS ${CMAKE_CURRENT_SOURCE_DIR}/../lib
|
||||
NO_DEFAULT_PATH)
|
||||
|
||||
if(LIBPM_PATH)
|
||||
set(_pm_integration_libs "${LIBPM_PATH}")
|
||||
if(LIBLGX_PATH)
|
||||
list(APPEND _pm_integration_libs "${LIBLGX_PATH}")
|
||||
endif()
|
||||
|
||||
message(STATUS "[PackageManagerTests] package manager lib found: ${LIBPM_PATH} — building integration tests")
|
||||
if(LIBLGX_PATH)
|
||||
message(STATUS "[PackageManagerTests] lgx found: ${LIBLGX_PATH}")
|
||||
else()
|
||||
message(STATUS "[PackageManagerTests] lgx not found in ../lib — linking package_manager_lib only")
|
||||
endif()
|
||||
|
||||
logos_test(
|
||||
NAME package_manager_module_integration_tests
|
||||
MODULE_SOURCES
|
||||
../src/package_manager_impl.cpp
|
||||
TEST_SOURCES
|
||||
main.cpp
|
||||
test_package_manager_integration.cpp
|
||||
test_directory_config.cpp
|
||||
test_scanning.cpp
|
||||
test_signature.cpp
|
||||
test_keyring.cpp
|
||||
EXTRA_INCLUDES
|
||||
../lib
|
||||
EXTRA_LINK_LIBS
|
||||
${_pm_integration_libs}
|
||||
GENERATED_SOURCES
|
||||
../generated_code/logos_provider_dispatch.cpp
|
||||
GENERATED_DIR
|
||||
../generated_code
|
||||
)
|
||||
|
||||
set(_rpath_dirs "")
|
||||
get_filename_component(_pm_dir "${LIBPM_PATH}" DIRECTORY)
|
||||
list(APPEND _rpath_dirs "${_pm_dir}")
|
||||
if(LIBLGX_PATH)
|
||||
get_filename_component(_lgx_dir "${LIBLGX_PATH}" DIRECTORY)
|
||||
list(APPEND _rpath_dirs "${_lgx_dir}")
|
||||
endif()
|
||||
list(REMOVE_DUPLICATES _rpath_dirs)
|
||||
string(REPLACE ";" ":" _rpath_joined "${_rpath_dirs}")
|
||||
set_target_properties(package_manager_module_integration_tests PROPERTIES
|
||||
BUILD_RPATH "${_rpath_joined}")
|
||||
else()
|
||||
message(STATUS "[PackageManagerTests] package_manager_lib not found in ../lib — skipping integration tests")
|
||||
endif()
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
// Mock PackageManagerLib for package_manager_module unit tests (link-time substitution).
|
||||
|
||||
#include <logos_clib_mock.h>
|
||||
#include <package_manager_lib.h>
|
||||
|
||||
static std::string mockDupCStr(const char* key, const char* fallback) {
|
||||
const char* ret = LOGOS_CMOCK_RETURN_STRING(key);
|
||||
if (ret && ret[0])
|
||||
return std::string(ret);
|
||||
return fallback ? std::string(fallback) : std::string();
|
||||
}
|
||||
|
||||
PackageManagerLib::PackageManagerLib() {
|
||||
LOGOS_CMOCK_RECORD("PackageManagerLib_ctor");
|
||||
}
|
||||
|
||||
PackageManagerLib::~PackageManagerLib() {
|
||||
LOGOS_CMOCK_RECORD("PackageManagerLib_dtor");
|
||||
}
|
||||
|
||||
void PackageManagerLib::setEmbeddedModulesDirectory(const std::string& dir) {
|
||||
LOGOS_CMOCK_RECORD("setEmbeddedModulesDirectory");
|
||||
(void)dir;
|
||||
}
|
||||
|
||||
void PackageManagerLib::addEmbeddedModulesDirectory(const std::string& dir) {
|
||||
LOGOS_CMOCK_RECORD("addEmbeddedModulesDirectory");
|
||||
(void)dir;
|
||||
}
|
||||
|
||||
void PackageManagerLib::setEmbeddedUiPluginsDirectory(const std::string& dir) {
|
||||
LOGOS_CMOCK_RECORD("setEmbeddedUiPluginsDirectory");
|
||||
(void)dir;
|
||||
}
|
||||
|
||||
void PackageManagerLib::addEmbeddedUiPluginsDirectory(const std::string& dir) {
|
||||
LOGOS_CMOCK_RECORD("addEmbeddedUiPluginsDirectory");
|
||||
(void)dir;
|
||||
}
|
||||
|
||||
void PackageManagerLib::setUserModulesDirectory(const std::string& dir) {
|
||||
LOGOS_CMOCK_RECORD("setUserModulesDirectory");
|
||||
(void)dir;
|
||||
}
|
||||
|
||||
void PackageManagerLib::setUserUiPluginsDirectory(const std::string& dir) {
|
||||
LOGOS_CMOCK_RECORD("setUserUiPluginsDirectory");
|
||||
(void)dir;
|
||||
}
|
||||
|
||||
std::string PackageManagerLib::installPluginFile(const std::string& pluginPath, std::string& errorMsg,
|
||||
bool skipIfNotNewerVersion,
|
||||
std::string* installedPluginPath,
|
||||
bool* isCoreModule) {
|
||||
LOGOS_CMOCK_RECORD("installPluginFile");
|
||||
if (skipIfNotNewerVersion) {
|
||||
LOGOS_CMOCK_RECORD("installPluginFile_skipIfNotNewer_true");
|
||||
} else {
|
||||
LOGOS_CMOCK_RECORD("installPluginFile_skipIfNotNewer_false");
|
||||
}
|
||||
(void)pluginPath;
|
||||
|
||||
errorMsg = mockDupCStr("installPluginFile_error", "");
|
||||
|
||||
if (installedPluginPath) {
|
||||
*installedPluginPath = mockDupCStr("installPluginFile_installedPath", "");
|
||||
}
|
||||
if (isCoreModule) {
|
||||
*isCoreModule = LOGOS_CMOCK_RETURN(bool, "installPluginFile_isCore");
|
||||
}
|
||||
|
||||
return mockDupCStr("installPluginFile_result", "");
|
||||
}
|
||||
|
||||
std::string PackageManagerLib::getInstalledPackages() {
|
||||
LOGOS_CMOCK_RECORD("getInstalledPackages");
|
||||
return mockDupCStr("getInstalledPackages", "[]");
|
||||
}
|
||||
|
||||
std::string PackageManagerLib::getInstalledModules() {
|
||||
LOGOS_CMOCK_RECORD("getInstalledModules");
|
||||
return mockDupCStr("getInstalledModules", "[]");
|
||||
}
|
||||
|
||||
std::string PackageManagerLib::getInstalledUiPlugins() {
|
||||
LOGOS_CMOCK_RECORD("getInstalledUiPlugins");
|
||||
return mockDupCStr("getInstalledUiPlugins", "[]");
|
||||
}
|
||||
|
||||
std::vector<std::string> PackageManagerLib::platformVariantsToTry() {
|
||||
LOGOS_CMOCK_RECORD("platformVariantsToTry");
|
||||
const char* v = LOGOS_CMOCK_RETURN_STRING("platformVariantsToTry_first");
|
||||
if (v && v[0]) {
|
||||
return {std::string(v)};
|
||||
}
|
||||
return {"mock-variant"};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Stub header for unit tests — matches the subset of PackageManagerLib used by
|
||||
// PackageManagerImpl. The real header is installed under lib/ from logos-package-manager.
|
||||
|
||||
class PackageManagerLib {
|
||||
public:
|
||||
PackageManagerLib();
|
||||
~PackageManagerLib();
|
||||
|
||||
void setEmbeddedModulesDirectory(const std::string& dir);
|
||||
void addEmbeddedModulesDirectory(const std::string& dir);
|
||||
void setEmbeddedUiPluginsDirectory(const std::string& dir);
|
||||
void addEmbeddedUiPluginsDirectory(const std::string& dir);
|
||||
void setUserModulesDirectory(const std::string& dir);
|
||||
void setUserUiPluginsDirectory(const std::string& dir);
|
||||
|
||||
std::string installPluginFile(const std::string& pluginPath, std::string& errorMsg,
|
||||
bool skipIfNotNewerVersion = false,
|
||||
std::string* installedPluginPath = nullptr,
|
||||
bool* isCoreModule = nullptr);
|
||||
|
||||
std::string getInstalledPackages();
|
||||
std::string getInstalledModules();
|
||||
std::string getInstalledUiPlugins();
|
||||
|
||||
static std::vector<std::string> platformVariantsToTry();
|
||||
};
|
||||
@@ -0,0 +1,211 @@
|
||||
// Unit tests for PackageManagerImpl — PackageManagerLib is mocked (mock_package_manager_lib.cpp).
|
||||
|
||||
#include <logos_test.h>
|
||||
#include "package_manager_impl.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
LOGOS_TEST(onInit_does_not_throw) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
LOGOS_ASSERT_FALSE(t.moduleCalled("any_module", "any_method"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(installPlugin_success_core_emits_core_event) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
t.captureEvents();
|
||||
t.mockCFunction("installPluginFile_result").returns("/installed/core.dylib");
|
||||
t.mockCFunction("installPluginFile_installedPath").returns("/installed/core.dylib");
|
||||
t.mockCFunction("installPluginFile_error").returns("");
|
||||
t.mockCFunction("installPluginFile_isCore").returns(true);
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
QVariantMap m = impl.installPlugin(QStringLiteral("/path/to/foo.lgx"), false);
|
||||
LOGOS_ASSERT_EQ(m[QStringLiteral("path")].toString(), QStringLiteral("/installed/core.dylib"));
|
||||
LOGOS_ASSERT_TRUE(m[QStringLiteral("isCoreModule")].toBool());
|
||||
LOGOS_ASSERT_FALSE(m.contains(QStringLiteral("error")));
|
||||
LOGOS_ASSERT_EQ(m[QStringLiteral("name")].toString(), QStringLiteral("foo"));
|
||||
LOGOS_ASSERT_TRUE(t.eventEmitted("corePluginFileInstalled"));
|
||||
LOGOS_ASSERT_FALSE(t.eventEmitted("uiPluginFileInstalled"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("installPluginFile"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(installPlugin_success_ui_emits_ui_event) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
t.captureEvents();
|
||||
t.mockCFunction("installPluginFile_result").returns("/ui/plugin.qml");
|
||||
t.mockCFunction("installPluginFile_installedPath").returns("/ui/plugin.qml");
|
||||
t.mockCFunction("installPluginFile_error").returns("");
|
||||
t.mockCFunction("installPluginFile_isCore").returns(false);
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
QVariantMap m = impl.installPlugin(QStringLiteral("/path/bar.lgx"), false);
|
||||
LOGOS_ASSERT_FALSE(m[QStringLiteral("isCoreModule")].toBool());
|
||||
LOGOS_ASSERT_TRUE(t.eventEmitted("uiPluginFileInstalled"));
|
||||
LOGOS_ASSERT_FALSE(t.eventEmitted("corePluginFileInstalled"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(installPlugin_failure_sets_error_no_event) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
t.captureEvents();
|
||||
t.mockCFunction("installPluginFile_result").returns("");
|
||||
t.mockCFunction("installPluginFile_error").returns("invalid lgx");
|
||||
t.mockCFunction("installPluginFile_installedPath").returns("");
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
QVariantMap m = impl.installPlugin(QStringLiteral("/bad.lgx"), false);
|
||||
LOGOS_ASSERT_TRUE(m[QStringLiteral("path")].toString().isEmpty());
|
||||
LOGOS_ASSERT_EQ(m[QStringLiteral("error")].toString(), QStringLiteral("invalid lgx"));
|
||||
LOGOS_ASSERT_FALSE(t.eventEmitted("corePluginFileInstalled"));
|
||||
LOGOS_ASSERT_FALSE(t.eventEmitted("uiPluginFileInstalled"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(installPlugin_skipIfNotNewerVersion_passed_to_mock) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
t.mockCFunction("installPluginFile_result").returns("/ok");
|
||||
t.mockCFunction("installPluginFile_installedPath").returns("/ok");
|
||||
t.mockCFunction("installPluginFile_error").returns("");
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
impl.installPlugin(QStringLiteral("/x.lgx"), true);
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("installPluginFile_skipIfNotNewer_true"));
|
||||
|
||||
impl.installPlugin(QStringLiteral("/y.lgx"), false);
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("installPluginFile_skipIfNotNewer_false"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(setEmbeddedModulesDirectory_forwards_to_lib) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
impl.setEmbeddedModulesDirectory(QStringLiteral("/emb/mod"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("setEmbeddedModulesDirectory"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(addEmbeddedModulesDirectory_forwards_to_lib) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
impl.addEmbeddedModulesDirectory(QStringLiteral("/emb/m2"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("addEmbeddedModulesDirectory"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(setEmbeddedUiPluginsDirectory_forwards_to_lib) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
impl.setEmbeddedUiPluginsDirectory(QStringLiteral("/emb/ui"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("setEmbeddedUiPluginsDirectory"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(addEmbeddedUiPluginsDirectory_forwards_to_lib) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
impl.addEmbeddedUiPluginsDirectory(QStringLiteral("/emb/ui2"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("addEmbeddedUiPluginsDirectory"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(setUserModulesDirectory_forwards_to_lib) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
impl.setUserModulesDirectory(QStringLiteral("/user/mod"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("setUserModulesDirectory"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(setUserUiPluginsDirectory_forwards_to_lib) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
impl.setUserUiPluginsDirectory(QStringLiteral("/user/ui"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("setUserUiPluginsDirectory"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(getInstalledPackages_parses_json_array) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
t.mockCFunction("getInstalledPackages").returns(R"([{"name":"pkg1","version":"1.0.0"}])");
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
QVariantList list = impl.getInstalledPackages();
|
||||
LOGOS_ASSERT_EQ(list.size(), 1);
|
||||
QVariantMap row = list[0].toMap();
|
||||
LOGOS_ASSERT_EQ(row[QStringLiteral("name")].toString(), QStringLiteral("pkg1"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("getInstalledPackages"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(getInstalledModules_parses_json) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
t.mockCFunction("getInstalledModules").returns(R"([{"name":"mod_a"}])");
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
QVariantList list = impl.getInstalledModules();
|
||||
LOGOS_ASSERT_EQ(list.size(), 1);
|
||||
LOGOS_ASSERT_EQ(list[0].toMap()[QStringLiteral("name")].toString(), QStringLiteral("mod_a"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(getInstalledUiPlugins_parses_json) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
t.mockCFunction("getInstalledUiPlugins").returns(R"([{"name":"ui_z"}])");
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
QVariantList list = impl.getInstalledUiPlugins();
|
||||
LOGOS_ASSERT_EQ(list.size(), 1);
|
||||
LOGOS_ASSERT_EQ(list[0].toMap()[QStringLiteral("name")].toString(), QStringLiteral("ui_z"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(getInstalledPackages_empty_json_array) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
// Default mock returns "[]" when getInstalledPackages string not set; force explicit
|
||||
t.mockCFunction("getInstalledPackages").returns("[]");
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
LOGOS_ASSERT_TRUE(impl.getInstalledPackages().isEmpty());
|
||||
}
|
||||
|
||||
LOGOS_TEST(getValidVariants_uses_platformVariantsToTry) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
t.mockCFunction("platformVariantsToTry_first").returns("custom-variant");
|
||||
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
QStringList v = impl.getValidVariants();
|
||||
LOGOS_ASSERT_EQ(v.size(), 1);
|
||||
LOGOS_ASSERT_EQ(v[0], QStringLiteral("custom-variant"));
|
||||
LOGOS_ASSERT_TRUE(t.cFunctionCalled("platformVariantsToTry"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(getValidVariants_default_mock_variant) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
|
||||
QStringList v = impl.getValidVariants();
|
||||
LOGOS_ASSERT_FALSE(v.isEmpty());
|
||||
LOGOS_ASSERT_EQ(v[0], QStringLiteral("mock-variant"));
|
||||
}
|
||||
|
||||
LOGOS_TEST(no_cross_module_calls_by_default) {
|
||||
auto t = LogosTestContext("package_manager");
|
||||
PackageManagerImpl impl;
|
||||
t.init(&impl);
|
||||
LOGOS_ASSERT_EQ(t.moduleCallCount("capability_module", "requestModule"), 0);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Integration tests — real PackageManagerLib from ../lib (built by Nix / workspace).
|
||||
// Skipped at configure time when the library is not present.
|
||||
|
||||
#include <logos_test.h>
|
||||
#include "package_manager_impl.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
LOGOS_TEST(integration_getValidVariants_non_empty) {
|
||||
PackageManagerImpl impl;
|
||||
QStringList v = impl.getValidVariants();
|
||||
LOGOS_ASSERT_FALSE(v.isEmpty());
|
||||
for (const QString& s : v) {
|
||||
LOGOS_ASSERT_FALSE(s.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
LOGOS_TEST(integration_empty_user_modules_yields_empty_lists) {
|
||||
QTemporaryDir dir;
|
||||
LOGOS_ASSERT_TRUE(dir.isValid());
|
||||
|
||||
PackageManagerImpl impl;
|
||||
impl.setUserModulesDirectory(dir.path());
|
||||
impl.setUserUiPluginsDirectory(dir.path());
|
||||
|
||||
LOGOS_ASSERT_TRUE(impl.getInstalledModules().isEmpty());
|
||||
LOGOS_ASSERT_TRUE(impl.getInstalledUiPlugins().isEmpty());
|
||||
LOGOS_ASSERT_TRUE(impl.getInstalledPackages().isEmpty());
|
||||
}
|
||||
|
||||
LOGOS_TEST(integration_embedded_directory_scan_empty) {
|
||||
QTemporaryDir emb;
|
||||
LOGOS_ASSERT_TRUE(emb.isValid());
|
||||
|
||||
PackageManagerImpl impl;
|
||||
impl.addEmbeddedModulesDirectory(emb.path());
|
||||
|
||||
// No packages under an empty embedded dir
|
||||
LOGOS_ASSERT_TRUE(impl.getInstalledModules().isEmpty());
|
||||
}
|
||||
Reference in New Issue
Block a user