implement Milestone 18: inter-app MessageBus with intent system
This commit is contained in:
@@ -31,6 +31,7 @@ add_library(mosis-sandbox STATIC
|
||||
../src/main/cpp/sandbox/sensor_interface.cpp
|
||||
../src/main/cpp/sandbox/bluetooth_interface.cpp
|
||||
../src/main/cpp/sandbox/contacts_interface.cpp
|
||||
../src/main/cpp/sandbox/message_bus.cpp
|
||||
)
|
||||
target_include_directories(mosis-sandbox PUBLIC
|
||||
../src/main/cpp/sandbox
|
||||
|
||||
@@ -21,11 +21,16 @@
|
||||
#include "sensor_interface.h"
|
||||
#include "bluetooth_interface.h"
|
||||
#include "contacts_interface.h"
|
||||
#include "message_bus.h"
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <cstdlib>
|
||||
#ifdef _WIN32
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
// Get path to scripts directory
|
||||
std::string GetScriptsDir() {
|
||||
@@ -3075,11 +3080,181 @@ bool Test_ContactsLuaIntegration(std::string& error_msg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// MILESTONE 18: MESSAGE BUS TESTS
|
||||
//=============================================================================
|
||||
|
||||
bool Test_MessageBusSendToReceiver(std::string& error_msg) {
|
||||
mosis::MessageBus bus;
|
||||
|
||||
bool received = false;
|
||||
mosis::Intent receivedIntent;
|
||||
|
||||
// Register receiver
|
||||
bus.RegisterReceiver("receiver.app", {"share", {}}, [&](const mosis::Intent& i) {
|
||||
received = true;
|
||||
receivedIntent = i;
|
||||
});
|
||||
|
||||
// Send intent
|
||||
mosis::Intent intent{"share", "text/plain", "Hello", "sender.app"};
|
||||
std::string err;
|
||||
auto result = bus.Send("sender.app", "receiver.app", intent, err);
|
||||
|
||||
EXPECT_TRUE(result == mosis::MessageError::None);
|
||||
EXPECT_TRUE(received);
|
||||
EXPECT_TRUE(receivedIntent.action == "share");
|
||||
EXPECT_TRUE(receivedIntent.data == "Hello");
|
||||
EXPECT_TRUE(receivedIntent.from_app == "sender.app");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_MessageBusBlockUnregistered(std::string& error_msg) {
|
||||
mosis::MessageBus bus;
|
||||
|
||||
// No receivers registered
|
||||
mosis::Intent intent{"share", "text/plain", "Hello", "sender.app"};
|
||||
std::string err;
|
||||
auto result = bus.Send("sender.app", "receiver.app", intent, err);
|
||||
|
||||
EXPECT_TRUE(result == mosis::MessageError::ReceiverNotFound);
|
||||
EXPECT_TRUE(err.find("not found") != std::string::npos ||
|
||||
err.find("no receiver") != std::string::npos);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_MessageBusBroadcast(std::string& error_msg) {
|
||||
mosis::MessageBus bus;
|
||||
|
||||
int receiveCount = 0;
|
||||
|
||||
// Register multiple receivers for same action
|
||||
bus.RegisterReceiver("app1", {"share", {}}, [&](const mosis::Intent&) { receiveCount++; });
|
||||
bus.RegisterReceiver("app2", {"share", {}}, [&](const mosis::Intent&) { receiveCount++; });
|
||||
bus.RegisterReceiver("app3", {"other", {}}, [&](const mosis::Intent&) { receiveCount++; });
|
||||
|
||||
// Broadcast share intent
|
||||
mosis::Intent intent{"share", "text/plain", "Hello", "sender.app"};
|
||||
std::string err;
|
||||
auto result = bus.Broadcast("sender.app", intent, err);
|
||||
|
||||
EXPECT_TRUE(result == mosis::MessageError::None);
|
||||
EXPECT_TRUE(receiveCount == 2); // Only app1 and app2
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_MessageBusMimeFilter(std::string& error_msg) {
|
||||
mosis::MessageBus bus;
|
||||
|
||||
bool imageReceived = false;
|
||||
bool textReceived = false;
|
||||
|
||||
// Register with MIME filter
|
||||
bus.RegisterReceiver("image.viewer", {"view", {"image/png", "image/jpeg"}},
|
||||
[&](const mosis::Intent&) { imageReceived = true; });
|
||||
bus.RegisterReceiver("text.viewer", {"view", {"text/plain"}},
|
||||
[&](const mosis::Intent&) { textReceived = true; });
|
||||
|
||||
// Send image intent
|
||||
mosis::Intent imgIntent{"view", "image/png", "data", "sender"};
|
||||
std::string err;
|
||||
bus.Broadcast("sender", imgIntent, err);
|
||||
|
||||
EXPECT_TRUE(imageReceived);
|
||||
EXPECT_TRUE(!textReceived);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_MessageBusDataLimit(std::string& error_msg) {
|
||||
mosis::MessageBus bus;
|
||||
|
||||
bus.RegisterReceiver("receiver", {"share", {}}, [](const mosis::Intent&) {});
|
||||
|
||||
// Create oversized data (> 1MB)
|
||||
std::string largeData(2 * 1024 * 1024, 'x');
|
||||
|
||||
mosis::Intent intent{"share", "text/plain", largeData, "sender"};
|
||||
std::string err;
|
||||
auto result = bus.Send("sender", "receiver", intent, err);
|
||||
|
||||
EXPECT_TRUE(result == mosis::MessageError::DataTooLarge);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_MessageBusBlockedApp(std::string& error_msg) {
|
||||
mosis::MessageBus bus;
|
||||
|
||||
bus.RegisterReceiver("receiver", {"share", {}}, [](const mosis::Intent&) {});
|
||||
bus.BlockApp("bad.app");
|
||||
|
||||
mosis::Intent intent{"share", "text/plain", "Hello", "bad.app"};
|
||||
std::string err;
|
||||
auto result = bus.Send("bad.app", "receiver", intent, err);
|
||||
|
||||
EXPECT_TRUE(result == mosis::MessageError::SenderBlocked);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Test_MessageBusLuaIntegration(std::string& error_msg) {
|
||||
SandboxContext ctx = TestContext();
|
||||
LuaSandbox sandbox(ctx);
|
||||
|
||||
mosis::MessageBus bus;
|
||||
mosis::RegisterIntentsAPI(sandbox.GetState(), &bus, "test.app");
|
||||
|
||||
std::string script = R"lua(
|
||||
-- Test that intents global exists
|
||||
if not intents then
|
||||
error("intents global not found")
|
||||
end
|
||||
if not intents.on then
|
||||
error("intents.on not found")
|
||||
end
|
||||
if not intents.send then
|
||||
error("intents.send not found")
|
||||
end
|
||||
if not intents.broadcast then
|
||||
error("intents.broadcast not found")
|
||||
end
|
||||
if not intents.hasReceiver then
|
||||
error("intents.hasReceiver not found")
|
||||
end
|
||||
if not intents.getReceivers then
|
||||
error("intents.getReceivers not found")
|
||||
end
|
||||
if not intents.unregisterAll then
|
||||
error("intents.unregisterAll not found")
|
||||
end
|
||||
)lua";
|
||||
|
||||
bool ok = sandbox.LoadString(script, "intents_test");
|
||||
if (!ok) {
|
||||
error_msg = "Lua test failed: " + sandbox.GetLastError();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// MAIN
|
||||
//=============================================================================
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef _WIN32
|
||||
// Disable VC runtime abort dialog - write to console instead
|
||||
_set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
|
||||
_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
|
||||
_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
|
||||
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
|
||||
#endif
|
||||
|
||||
std::string filter;
|
||||
std::string output_file = "test_results.json";
|
||||
|
||||
@@ -3276,6 +3451,15 @@ int main(int argc, char* argv[]) {
|
||||
harness.AddTest("ContactsDeleteNotFound", Test_ContactsDeleteNotFound);
|
||||
harness.AddTest("ContactsLuaIntegration", Test_ContactsLuaIntegration);
|
||||
|
||||
// Milestone 18: Message Bus
|
||||
harness.AddTest("MessageBusSendToReceiver", Test_MessageBusSendToReceiver);
|
||||
harness.AddTest("MessageBusBlockUnregistered", Test_MessageBusBlockUnregistered);
|
||||
harness.AddTest("MessageBusBroadcast", Test_MessageBusBroadcast);
|
||||
harness.AddTest("MessageBusMimeFilter", Test_MessageBusMimeFilter);
|
||||
harness.AddTest("MessageBusDataLimit", Test_MessageBusDataLimit);
|
||||
harness.AddTest("MessageBusBlockedApp", Test_MessageBusBlockedApp);
|
||||
harness.AddTest("MessageBusLuaIntegration", Test_MessageBusLuaIntegration);
|
||||
|
||||
// Run tests
|
||||
auto results = harness.Run(filter);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user