Add unit tests for logic state machines reusal
as it will work in the real FWpull/83/head
parent
ccefe32ba1
commit
e0ea47595f
|
|
@ -21,12 +21,11 @@ using Catch::Matchers::Equals;
|
|||
|
||||
#include "../helpers/helpers.ipp"
|
||||
|
||||
void CutSlot(uint8_t cutSlot) {
|
||||
void CutSlot(logic::CutFilament &cf, uint8_t cutSlot) {
|
||||
|
||||
ForceReinitAllAutomata();
|
||||
|
||||
logic::CutFilament cf;
|
||||
REQUIRE(VerifyState(cf, false, mi::Idler::IdleSlotIndex(), 0, false, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK));
|
||||
REQUIRE(VerifyEnvironmentState(false, mi::Idler::IdleSlotIndex(), 0, false, ml::off, ml::off));
|
||||
|
||||
EnsureActiveSlotIndex(cutSlot);
|
||||
|
||||
|
|
@ -87,12 +86,30 @@ void CutSlot(uint8_t cutSlot) {
|
|||
|
||||
TEST_CASE("cut_filament::cut0", "[cut_filament]") {
|
||||
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
|
||||
CutSlot(cutSlot);
|
||||
logic::CutFilament cf;
|
||||
CutSlot(cf, cutSlot);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("cut_filament::invalid_slot", "[cut_filament]") {
|
||||
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
|
||||
InvalidSlot<logic::CutFilament>(config::toolCount, cutSlot);
|
||||
for (uint8_t activeSlot = 0; activeSlot < config::toolCount; ++activeSlot) {
|
||||
logic::CutFilament cf;
|
||||
InvalidSlot<logic::CutFilament>(cf, activeSlot, config::toolCount);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("cut_filament::state_machine_reusal", "[cut_filament]") {
|
||||
logic::CutFilament cf;
|
||||
for (uint8_t activeSlot = 0; activeSlot < config::toolCount; ++activeSlot) {
|
||||
InvalidSlot<logic::CutFilament>(cf, activeSlot, config::toolCount);
|
||||
}
|
||||
|
||||
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
|
||||
CutSlot(cf, cutSlot);
|
||||
}
|
||||
|
||||
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
|
||||
CutSlot(cf, cutSlot);
|
||||
InvalidSlot<logic::CutFilament>(cf, cutSlot, config::toolCount);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,12 +70,8 @@ TEST_CASE("eject_filament::eject0", "[eject_filament][.]") {
|
|||
}
|
||||
|
||||
TEST_CASE("eject_filament::invalid_slot", "[eject_filament]") {
|
||||
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
|
||||
InvalidSlot<logic::EjectFilament>(config::toolCount, cutSlot);
|
||||
for (uint8_t activeSlot = 0; activeSlot < config::toolCount; ++activeSlot) {
|
||||
logic::EjectFilament ef;
|
||||
InvalidSlot<logic::EjectFilament>(ef, activeSlot, config::toolCount);
|
||||
}
|
||||
}
|
||||
|
||||
// comments:
|
||||
// The tricky part of the whole state machine are the edge cases - filament not loaded, stall guards etc.
|
||||
// ... all the external influence we can get on the real HW
|
||||
// But the good news is we can simulate them all in the unit test and thus ensure proper handling
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
// LED checked at selector's index
|
||||
template<typename SM>
|
||||
bool VerifyState(SM &uf, bool filamentLoaded, uint8_t idlerSlotIndex, uint8_t selectorSlotIndex,
|
||||
bool findaPressed, ml::Mode greenLEDMode, ml::Mode redLEDMode, ErrorCode err, ProgressCode topLevelProgress) {
|
||||
bool VerifyEnvironmentState(bool filamentLoaded, uint8_t idlerSlotIndex, uint8_t selectorSlotIndex,
|
||||
bool findaPressed, ml::Mode greenLEDMode, ml::Mode redLEDMode) {
|
||||
CHECKED_ELSE(mg::globals.FilamentLoaded() == filamentLoaded) { return false; }
|
||||
CHECKED_ELSE(mm::axes[mm::Idler].pos == mi::Idler::SlotPosition(idlerSlotIndex).v) { return false; }
|
||||
CHECKED_ELSE(mi::idler.Engaged() == (idlerSlotIndex < config::toolCount)) { return false; }
|
||||
|
|
@ -19,8 +17,19 @@ bool VerifyState(SM &uf, bool filamentLoaded, uint8_t idlerSlotIndex, uint8_t se
|
|||
CHECKED_ELSE(ml::leds.Mode(selectorSlotIndex, ml::green) == greenLEDMode) { return false; }
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CHECKED_ELSE(uf.Error() == err) { return false; }
|
||||
// LED checked at selector's index
|
||||
template<typename SM>
|
||||
bool VerifyState(SM &uf, bool filamentLoaded, uint8_t idlerSlotIndex, uint8_t selectorSlotIndex,
|
||||
bool findaPressed, ml::Mode greenLEDMode, ml::Mode redLEDMode, ErrorCode err, ProgressCode topLevelProgress) {
|
||||
|
||||
VerifyEnvironmentState(filamentLoaded, idlerSlotIndex, selectorSlotIndex, findaPressed, greenLEDMode, redLEDMode);
|
||||
|
||||
CHECKED_ELSE(uf.Error() == err) {
|
||||
return false;
|
||||
}
|
||||
CHECKED_ELSE(uf.TopLevelState() == topLevelProgress) { return false; }
|
||||
return true;
|
||||
}
|
||||
|
|
@ -52,12 +61,13 @@ bool VerifyState2(SM &uf, bool filamentLoaded, uint8_t idlerSlotIndex, uint8_t s
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename SM>
|
||||
void InvalidSlot(uint8_t invSlot, uint8_t activeSlot){
|
||||
void InvalidSlot(SM &logicSM, uint8_t activeSlot, uint8_t invSlot){
|
||||
ForceReinitAllAutomata();
|
||||
|
||||
SM logicSM;
|
||||
REQUIRE(VerifyState(logicSM, false, mi::Idler::IdleSlotIndex(), 0, false, ml::off, ml::off, ErrorCode::OK, ProgressCode::OK));
|
||||
REQUIRE(VerifyEnvironmentState(false, mi::Idler::IdleSlotIndex(), 0, false, ml::off, ml::off));
|
||||
|
||||
EnsureActiveSlotIndex(activeSlot);
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,24 @@ TEST_CASE("load_filament::failed_load_to_finda_0-4_resolve_help_second_fail", "[
|
|||
}
|
||||
|
||||
TEST_CASE("load_filament::invalid_slot", "[load_filament]") {
|
||||
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
|
||||
InvalidSlot<logic::LoadFilament>(config::toolCount, cutSlot);
|
||||
for (uint8_t activeSlot = 0; activeSlot < config::toolCount; ++activeSlot) {
|
||||
logic::LoadFilament lf;
|
||||
InvalidSlot<logic::LoadFilament>(lf, activeSlot, config::toolCount);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("load_filament::state_machine_reusal", "[load_filament]") {
|
||||
logic::LoadFilament lf;
|
||||
|
||||
for (uint8_t fromSlot = 0; fromSlot < config::toolCount; ++fromSlot) {
|
||||
for (uint8_t toSlot = 0; toSlot < config::toolCount + 2; ++toSlot) {
|
||||
logic::LoadFilament lf;
|
||||
if (toSlot >= config::toolCount) {
|
||||
InvalidSlot<logic::LoadFilament>(lf, fromSlot, toSlot);
|
||||
} else {
|
||||
LoadFilamentCommonSetup(toSlot, lf);
|
||||
LoadFilamentSuccessful(toSlot, lf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,11 +21,9 @@ using Catch::Matchers::Equals;
|
|||
|
||||
#include "../helpers/helpers.ipp"
|
||||
|
||||
void ToolChange(uint8_t fromSlot, uint8_t toSlot) {
|
||||
void ToolChange(logic::ToolChange tc, uint8_t fromSlot, uint8_t toSlot) {
|
||||
ForceReinitAllAutomata();
|
||||
|
||||
logic::ToolChange tc;
|
||||
|
||||
EnsureActiveSlotIndex(fromSlot);
|
||||
|
||||
// restart the automaton
|
||||
|
|
@ -55,11 +53,9 @@ void ToolChange(uint8_t fromSlot, uint8_t toSlot) {
|
|||
REQUIRE(mg::globals.ActiveSlot() == toSlot);
|
||||
}
|
||||
|
||||
void NoToolChange(uint8_t fromSlot, uint8_t toSlot) {
|
||||
void NoToolChange(logic::ToolChange tc, uint8_t fromSlot, uint8_t toSlot) {
|
||||
ForceReinitAllAutomata();
|
||||
|
||||
logic::ToolChange tc;
|
||||
|
||||
EnsureActiveSlotIndex(fromSlot);
|
||||
|
||||
// restart the automaton
|
||||
|
|
@ -73,17 +69,35 @@ void NoToolChange(uint8_t fromSlot, uint8_t toSlot) {
|
|||
TEST_CASE("tool_change::test0", "[tool_change]") {
|
||||
for (uint8_t fromSlot = 0; fromSlot < config::toolCount; ++fromSlot) {
|
||||
for (uint8_t toSlot = 0; toSlot < config::toolCount; ++toSlot) {
|
||||
logic::ToolChange tc;
|
||||
if (fromSlot != toSlot) {
|
||||
ToolChange(fromSlot, toSlot);
|
||||
ToolChange(tc, fromSlot, toSlot);
|
||||
} else {
|
||||
NoToolChange(fromSlot, toSlot);
|
||||
NoToolChange(tc, fromSlot, toSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("tool_change::invalid_slot", "[tool_change]") {
|
||||
for (uint8_t cutSlot = 0; cutSlot < config::toolCount; ++cutSlot) {
|
||||
InvalidSlot<logic::ToolChange>(config::toolCount, cutSlot);
|
||||
for (uint8_t fromSlot = 0; fromSlot < config::toolCount; ++fromSlot) {
|
||||
logic::ToolChange tc;
|
||||
InvalidSlot<logic::ToolChange>(tc, fromSlot, config::toolCount);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("tool_change::state_machine_reusal", "[tool_change]") {
|
||||
logic::ToolChange tc;
|
||||
|
||||
for (uint8_t fromSlot = 0; fromSlot < config::toolCount; ++fromSlot) {
|
||||
for (uint8_t toSlot = 0; toSlot < config::toolCount + 2; ++toSlot) {
|
||||
if (toSlot >= config::toolCount) {
|
||||
InvalidSlot<logic::ToolChange>(tc, fromSlot, toSlot);
|
||||
} else if (fromSlot != toSlot) {
|
||||
ToolChange(tc, fromSlot, toSlot);
|
||||
} else {
|
||||
NoToolChange(tc, fromSlot, toSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue