mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-01-13 00:07:56 -05:00
* Fix of the issue that incoming call triggered handsfree ringing which didn't stop after calling side hung up. * Cleanup of several places in code, minor bluetooth <-> cellular integration refactor.
457 lines
18 KiB
C++
457 lines
18 KiB
C++
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include <catch2/catch.hpp>
|
|
#include <catch/fakeit.hpp>
|
|
#include "service-bluetooth/SettingsHolder.hpp"
|
|
#include "BluetoothStateMachine.hpp"
|
|
|
|
using namespace bluetooth;
|
|
|
|
auto InitializerMock = []() { return Result::Code::Success; };
|
|
|
|
namespace mock
|
|
{
|
|
template <typename T>
|
|
auto mock_to_shared(T *val)
|
|
{
|
|
auto t = std::shared_ptr<T>(val, [](...) {});
|
|
return t;
|
|
}
|
|
|
|
auto driver()
|
|
{
|
|
fakeit::Mock<AbstractDriver> mock;
|
|
fakeit::When(Method(mock, init)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, run)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, stop)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, scan)).AlwaysReturn(Result());
|
|
fakeit::When(Method(mock, stopScan)).AlwaysReturn();
|
|
fakeit::When(Method(mock, setVisibility)).AlwaysReturn();
|
|
fakeit::When(Method(mock, pair)).AlwaysReturn();
|
|
fakeit::When(Method(mock, unpair)).AlwaysReturn();
|
|
fakeit::When(Method(mock, registerErrorCallback)).AlwaysReturn();
|
|
fakeit::When(Method(mock, registerPowerOnCallback)).AlwaysReturn();
|
|
return mock;
|
|
};
|
|
|
|
auto handler()
|
|
{
|
|
fakeit::Mock<AbstractCommandHandler> mock;
|
|
fakeit::When(Method(mock, scan)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, stopScan)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, setVisibility)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, connect)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, disconnect)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, pair)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, unpair)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, availableDevices)).AlwaysReturn(Result::Code::Success);
|
|
return mock;
|
|
};
|
|
|
|
auto settings()
|
|
{
|
|
fakeit::Mock<bluetooth::SettingsHolder> mock;
|
|
fakeit::When(Method(mock, getValue)).AlwaysReturn({});
|
|
fakeit::When(Method(mock, setValue)).AlwaysReturn();
|
|
return mock;
|
|
}
|
|
|
|
auto devices()
|
|
{
|
|
return std::make_shared<std::vector<Devicei>>();
|
|
}
|
|
|
|
auto profile()
|
|
{
|
|
fakeit::Mock<bluetooth::BaseProfileManager> mock;
|
|
fakeit::When(Method(mock, init)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, deInit)).AlwaysReturn();
|
|
fakeit::When(Method(mock, connect)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, disconnect)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, start)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, stop)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, incomingCallStarted)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, outgoingCallStarted)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, incomingCallAnswered)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, outgoingCallAnswered)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, callTerminated)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, callMissed)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, setIncomingCallNumber)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, setSignalStrengthData)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, setOperatorNameData)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, setBatteryLevelData)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, setNetworkStatusData)).AlwaysReturn(Result::Code::Success);
|
|
fakeit::When(Method(mock, setAudioDevice)).AlwaysReturn(Result::Code::Success);
|
|
return mock;
|
|
};
|
|
|
|
struct SM
|
|
{
|
|
decltype(driver()) d = mock::driver();
|
|
decltype(handler()) h = mock::handler();
|
|
decltype(mock::settings()) s = mock::settings();
|
|
decltype(mock::profile()) p = mock::profile();
|
|
|
|
using Driver = decltype(mock_to_shared(&d.get()));
|
|
using Processor = decltype(mock_to_shared(&h.get()));
|
|
using Settings = decltype(mock_to_shared(&s.get()));
|
|
using Devices = decltype(mock::devices());
|
|
using Profile = decltype(mock_to_shared(&p.get()));
|
|
|
|
Driver drive = mock_to_shared(&d.get());
|
|
Processor processor = mock_to_shared(&h.get());
|
|
Settings sett = mock_to_shared(&s.get());
|
|
Devices devices = mock::devices();
|
|
Profile profile = mock_to_shared(&p.get());
|
|
|
|
StatefulController::Impl controller{drive, processor, InitializerMock, sett, devices, profile};
|
|
|
|
SM()
|
|
{}
|
|
|
|
explicit SM(DeviceRegistrationFunction registerDevice)
|
|
: controller{drive, processor, std::move(registerDevice), sett, devices, profile}
|
|
{}
|
|
|
|
auto &get()
|
|
{
|
|
return controller;
|
|
}
|
|
};
|
|
|
|
} // namespace mock
|
|
|
|
TEST_CASE("Given StatefulController when turn on then turned on")
|
|
{
|
|
using namespace boost::sml;
|
|
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
|
|
controller.sm.process_event(bluetooth::event::PowerOn{});
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
|
|
controller.sm.process_event(bluetooth::event::PowerOff{});
|
|
REQUIRE(controller.sm.is("Off"_s));
|
|
}
|
|
|
|
TEST_CASE("pair/unpair")
|
|
{
|
|
using namespace boost::sml;
|
|
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
auto device = Devicei{"lol"};
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::PowerOn{}));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::Pair{device}));
|
|
fakeit::Verify(Method(sm.h, pair)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::Unpair{device}));
|
|
fakeit::Verify(Method(sm.h, unpair)).Exactly(1);
|
|
}
|
|
|
|
TEST_CASE("connect/disconnect")
|
|
{
|
|
using namespace boost::sml;
|
|
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
auto device = Devicei{"lol"};
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::PowerOn{}));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::Connect{device}));
|
|
fakeit::Verify(Method(sm.h, connect)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::Disconnect{}));
|
|
fakeit::Verify(Method(sm.h, disconnect)).Exactly(1);
|
|
}
|
|
|
|
TEST_CASE("start/stop scan")
|
|
{
|
|
using namespace boost::sml;
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::PowerOn{}));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::StartScan{}));
|
|
fakeit::Verify(Method(sm.h, scan)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::StopScan{}));
|
|
fakeit::Verify(Method(sm.h, stopScan)).Exactly(1);
|
|
}
|
|
|
|
TEST_CASE("call test - incoming call")
|
|
{
|
|
using namespace boost::sml;
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::PowerOn{}));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
auto number = utils::PhoneNumber::View{};
|
|
|
|
SECTION("dropped call with no number event")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallStarted{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallTerminated{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callTerminated)).Exactly(1);
|
|
}
|
|
|
|
SECTION("answered call with no number event")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallStarted{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallAnswered{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallInProgress"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallAnswered)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallTerminated{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callTerminated)).Exactly(1);
|
|
}
|
|
|
|
SECTION("missed call with no number event")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallStarted{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallMissed{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callMissed)).Exactly(1);
|
|
}
|
|
|
|
SECTION("delayed incoming call number event")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallStarted{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallNumber{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, setIncomingCallNumber)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallTerminated{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callTerminated)).Exactly(1);
|
|
}
|
|
|
|
SECTION("dropped call")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallNumber{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(1);
|
|
fakeit::Verify(Method(sm.p, setIncomingCallNumber)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallTerminated{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callTerminated)).Exactly(1);
|
|
}
|
|
|
|
SECTION("answered call")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallNumber{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(1);
|
|
fakeit::Verify(Method(sm.p, setIncomingCallNumber)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallAnswered{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallInProgress"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallAnswered)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallTerminated{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callTerminated)).Exactly(1);
|
|
}
|
|
|
|
SECTION("missed call")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallNumber{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(1);
|
|
fakeit::Verify(Method(sm.p, setIncomingCallNumber)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallMissed{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callMissed)).Exactly(1);
|
|
}
|
|
|
|
SECTION("double missed call")
|
|
{
|
|
LOG_INFO("Double missed call");
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallNumber{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(1);
|
|
fakeit::Verify(Method(sm.p, setIncomingCallNumber)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallMissed{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callMissed)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::IncomingCallNumber{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallRinging"_s));
|
|
fakeit::Verify(Method(sm.p, incomingCallStarted)).Exactly(2);
|
|
fakeit::Verify(Method(sm.p, setIncomingCallNumber)).Exactly(2);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallMissed{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callMissed)).Exactly(2);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("call test - outgoing call")
|
|
{
|
|
using namespace boost::sml;
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::PowerOn{}));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
auto number = utils::PhoneNumber::View{};
|
|
|
|
SECTION("dropped call")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::OutgoingCallStarted{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallInitiated"_s));
|
|
fakeit::Verify(Method(sm.p, outgoingCallStarted)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallTerminated{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callTerminated)).Exactly(1);
|
|
}
|
|
|
|
SECTION("answered call")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::OutgoingCallStarted{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallInitiated"_s));
|
|
fakeit::Verify(Method(sm.p, outgoingCallStarted)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallAnswered{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallInProgress"_s));
|
|
fakeit::Verify(Method(sm.p, outgoingCallAnswered)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallTerminated{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callTerminated)).Exactly(1);
|
|
}
|
|
|
|
SECTION("miss-clicked call")
|
|
{
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::OutgoingCallStarted{number}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>("CallInitiated"_s));
|
|
fakeit::Verify(Method(sm.p, outgoingCallStarted)).Exactly(1);
|
|
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::CallTerminated{}));
|
|
REQUIRE(controller.sm.is<decltype(state<Call>)>(sml::X));
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.p, callTerminated)).Exactly(1);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("Given StatefulController when error during device registration then turned off")
|
|
{
|
|
using namespace boost::sml;
|
|
auto sm = mock::SM([]() { return bluetooth::Result::Code::SystemError; });
|
|
auto controller = sm.get();
|
|
|
|
controller.sm.process_event(bluetooth::event::PowerOn{});
|
|
REQUIRE(!controller.sm.is(state<bluetooth::On>));
|
|
}
|
|
|
|
TEST_CASE("Given StatefulController when error during driver init then turned off")
|
|
{
|
|
using namespace boost::sml;
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
|
|
fakeit::When(Method(sm.d, init)).AlwaysReturn(Result::Code::SystemError);
|
|
|
|
controller.sm.process_event(bluetooth::event::PowerOn{});
|
|
REQUIRE(!controller.sm.is(state<bluetooth::On>));
|
|
}
|
|
|
|
TEST_CASE("Given StatefulController when restart then don't init twice")
|
|
{
|
|
using namespace boost::sml;
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
|
|
controller.sm.process_event(bluetooth::event::PowerOn{});
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
fakeit::Verify(Method(sm.d, init)).Exactly(1);
|
|
controller.sm.process_event(bluetooth::event::PowerOff{});
|
|
REQUIRE(controller.sm.is("Off"_s));
|
|
fakeit::Verify(Method(sm.d, init)).Exactly(1);
|
|
fakeit::Verify(Method(sm.p, deInit)).Exactly(1);
|
|
controller.sm.process_event(bluetooth::event::PowerOn{});
|
|
fakeit::Verify(Method(sm.d, init)).Exactly(1);
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
}
|
|
|
|
TEST_CASE("Given StatefulController when turn off in off state then turned off")
|
|
{
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
// there is no Off -> Off transition so it won't be handled
|
|
REQUIRE(not controller.sm.process_event(bluetooth::event::PowerOff{}));
|
|
}
|
|
|
|
TEST_CASE("Given StatefulController when shutdown in off state then terminated")
|
|
{
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
controller.sm.process_event(bluetooth::event::ShutDown{});
|
|
REQUIRE(controller.sm.is(boost::sml::X));
|
|
}
|
|
|
|
TEST_CASE("Given StatefulController when shutdown in on state then terminated")
|
|
{
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
// there is no Off -> Off transition so it won't be handled
|
|
REQUIRE(controller.sm.process_event(bluetooth::event::PowerOn{}));
|
|
controller.sm.process_event(bluetooth::event::PowerOff{});
|
|
controller.sm.process_event(bluetooth::event::ShutDown{});
|
|
REQUIRE(controller.sm.is(boost::sml::X));
|
|
}
|
|
|
|
TEST_CASE("Given StatefulController when processing command failed then restarted and turned on")
|
|
{
|
|
using namespace boost::sml;
|
|
auto sm = mock::SM();
|
|
auto controller = sm.get();
|
|
|
|
fakeit::When(Method(sm.d, init)).AlwaysReturn(Result::Code::SystemError);
|
|
controller.sm.process_event(bluetooth::event::PowerOn{});
|
|
REQUIRE(!controller.sm.is(state<bluetooth::On>));
|
|
|
|
fakeit::When(Method(sm.d, init)).AlwaysReturn(Result::Code::Success);
|
|
controller.sm.process_event(bluetooth::event::PowerOn{});
|
|
REQUIRE(controller.sm.is(state<bluetooth::On>));
|
|
}
|