/** * @file spitRepoTest.cpp * @author Gustice * @brief */ #include "doctest/doctest.h" #include #include #include #include "spit_processor.hpp" using namespace spit; using namespace std; static queue cbEvents; class ClientMock { public: void onServerEvent(SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) { } void onConnectionStatus(string serverID, string serverComputerName, string serverName, int serverStepTime, SProcessor::Connection connectionStatus, SProcessor::Connection oldConnectionStatus) { } void onProjectUpdate(SProcessor::ProjUpdate state, string projectId) { } void onSpitType(SProcessor::ObjectEvent event, bool isRemote, const SType &sType) { cbEvents.push(fmt::format("{}: {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sType.GroupName.get())); } void onSpitObject(SProcessor::ObjectEvent event, bool isRemote, const SType &sType, const SObject &sObject) { cbEvents.push(fmt::format("{}: {} {} {} {} {}", (int)event, isRemote, sType.getID(), sType.Name.get(), sObject.Name.get(), sObject.getID())); } void onPlay(string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) { } void onPlaySpitType(string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) { } void onPlayRemoteObjectStatus(const SType &sType, const SObject &sObject, uint64_t p_FrameInsideObject, int value) { } bool onCheckSpitTypeVeto(bool knownType, bool createdByClient) { cbEvents.push(fmt::format("veto check {}/{}", knownType, createdByClient)); return true; } bool onCheckSpitObjectVeto(bool knownType) { return true; } }; class SpitClientFix { protected: std::vector messages; ClientMock client; SProcessor::Callbacks callbacks{ .onServerEvent = [&](SProcessor::ServerEvent event, const SadDetectedServer &detectedServer) { client.onServerEvent(event, detectedServer); }, .onConnectionStatus = [&](string serverID, string serverComputerName, string serverName, int serverStepTime, SProcessor::Connection connectionStatus, SProcessor::Connection oldConnectionStatus) { client.onConnectionStatus(serverID, serverComputerName, serverName, serverStepTime, connectionStatus, oldConnectionStatus); }, .onProjectUpdate = [&](SProcessor::ProjUpdate state, string projectId) { client.onProjectUpdate(state, projectId); }, .onSpitType = [&](SProcessor::ObjectEvent event, bool isRemote, const SType &t) { client.onSpitType(event, isRemote, t); }, .onSpitObject = [&](SProcessor::ObjectEvent event, bool isRemote, const SType &t, const SObject &o) { client.onSpitObject(event, isRemote, t, o); }, .onPlay = [&](string playerID, string playerName, char playerType, bool playerIsRunning, uint64_t timeFrames) { client.onPlay(playerID, playerName, playerType, playerIsRunning, timeFrames); }, .onPlaySpitType = [&](string playerID, string spitTypeID, bool playerIsRunning, bool started, bool ended, double value) { client.onPlaySpitType(playerID, spitTypeID, playerIsRunning, started, ended, value); }, .onPlayRemoteObjectStatus = [&](const SType &t, const SObject &o, uint64_t p_FrameInsideObject, int value) { client.onPlayRemoteObjectStatus(t, o, p_FrameInsideObject, value); }, .onCheckSpitTypeVeto = [&](bool knownType, bool createdByClient) { return client.onCheckSpitTypeVeto(knownType, createdByClient); }, .onCheckSpitObjectVeto = [&](bool knownType) { return client.onCheckSpitObjectVeto(knownType); }}; SProcessor::InternalCallbacks intCallbacks{ .delay = [&](int ms) { return; }, .sendMessage = [&](Message::OPPart &msg) { return 0; }, .parseMessage = [&](Message &msg) { // auto o = fmt::format("msg-{}", msg.getHeader()->getMessageNumber()); // messages.push_back(o); }, }; SProcessor sut{"sut", "sutProj", "dev", "##GUID##", callbacks, intCallbacks}; }; TEST_CASE_FIXTURE(SpitClientFix, "Spit types") { { Message::ReportType t; t.setConfirmed(false); t.setID("type1Id#Rem"); t.setFixed(true); t.setServerRemote(true); t.setServerProjectIndepended(true); t.setGroupName("sGroup"); t.setName("type1Name"); t.setDelay(100); t.setDuration(200); sut.checkParseMessageData(sut.createMessage(t)); } CHECK_MESSAGE(cbEvents.front() == "0: true type1Id#Rem type1Name sGroup", cbEvents.front()); cbEvents.pop(); { Message::ReportType t; t.setConfirmed(false); t.setID("type2Id#Rem"); t.setFixed(true); t.setServerRemote(true); t.setServerProjectIndepended(true); t.setGroupName("sGroup"); t.setName("type2Name"); t.setDelay(100); t.setDuration(200); sut.checkParseMessageData(sut.createMessage(t)); } CHECK_MESSAGE(cbEvents.front() == "0: true type2Id#Rem type2Name sGroup", cbEvents.front()); cbEvents.pop(); { Message::ReportType t; t.setConfirmed(false); t.setID("type1Id#Rem"); t.setFixed(true); t.setServerRemote(true); t.setServerProjectIndepended(true); t.setGroupName("sGroup"); t.setName("type1Name"); t.setDelay(200); t.setDuration(300); sut.checkParseMessageData(sut.createMessage(t)); } CHECK_MESSAGE(cbEvents.front() == "1: true type1Id#Rem type1Name sGroup", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); // Local Objects { Message::ReportType t; t.setConfirmed(false); t.setID("type1Id#Loc"); t.setFixed(true); t.setServerRemote(false); t.setServerProjectIndepended(true); t.setGroupName("sGroup"); t.setName("type1Name"); t.setDelay(100); t.setDuration(200); sut.checkParseMessageData(sut.createMessage(t)); } CHECK_MESSAGE(cbEvents.front() == "veto check false/false", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: false type1Id#Loc type1Name sGroup", cbEvents.front()); cbEvents.pop(); { Message::ReportType t; t.setConfirmed(false); t.setID("type2Id#Loc"); t.setFixed(true); t.setServerRemote(false); t.setServerProjectIndepended(true); t.setGroupName("sGroup"); t.setName("type2Name"); t.setDelay(100); t.setDuration(200); sut.checkParseMessageData(sut.createMessage(t)); } CHECK_MESSAGE(cbEvents.front() == "veto check false/false", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: false type2Id#Loc type2Name sGroup", cbEvents.front()); cbEvents.pop(); { Message::ReportType t; t.setConfirmed(false); t.setID("type1Id#Loc"); t.setFixed(true); t.setServerRemote(false); t.setServerProjectIndepended(true); t.setGroupName("sGroup"); t.setName("type1Name"); t.setDelay(200); t.setDuration(300); sut.checkParseMessageData(sut.createMessage(t)); } CHECK_MESSAGE(cbEvents.front() == "1: false type1Id#Loc type1Name sGroup", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); } TEST_CASE_FIXTURE(SpitClientFix, "Message Counter") { Message::ReportType t1; t1.setID("type#1"); t1.setServerRemote(true); auto m1 = sut.createMessage(t1); Message::ReportType t2; t2.setID("type#2"); t2.setServerRemote(true); auto m2 = sut.createMessage(t2); Message::ReportType t3; t3.setID("type#3"); t3.setServerRemote(true); auto m3 = sut.createMessage(t3); Message::ReportType t4; t4.setID("type#4"); t4.setServerRemote(true); auto m4 = sut.createMessage(t4); Message::ReportType t5; t5.setID("type#5"); t5.setServerRemote(true); auto m5 = sut.createMessage(t5); Message::ReportType t6; t6.setID("type#6"); t6.setServerRemote(true); auto m6 = sut.createMessage(t6); CHECK(cbEvents.empty()); SUBCASE("Normal order") { REQUIRE(cbEvents.size() == 0); sut.checkParseMessageData(m1); CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m2); CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m3); CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m4); CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); } CHECK(cbEvents.empty()); SUBCASE("overtakes one") { REQUIRE(cbEvents.size() == 0); sut.checkParseMessageData(m1); CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m3); CHECK(cbEvents.empty()); sut.checkParseMessageData(m2); CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m4); CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); } CHECK(cbEvents.empty()); SUBCASE("overtakes two") { REQUIRE(cbEvents.size() == 0); sut.checkParseMessageData(m1); CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m4); CHECK(cbEvents.empty()); sut.checkParseMessageData(m2); CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m3); CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m5); CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); } CHECK(cbEvents.empty()); SUBCASE("many overtakes") { REQUIRE(cbEvents.size() == 0); sut.checkParseMessageData(m1); CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m5); CHECK(cbEvents.empty()); sut.checkParseMessageData(m6); CHECK(cbEvents.empty()); sut.checkParseMessageData(m4); CHECK(cbEvents.empty()); sut.checkParseMessageData(m3); CHECK(cbEvents.empty()); sut.checkParseMessageData(m2); CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#6 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); } CHECK(cbEvents.empty()); SUBCASE("reverse order") { REQUIRE(cbEvents.size() == 0); sut.checkParseMessageData(m1); CHECK_MESSAGE(cbEvents.front() == "0: true type#1 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); sut.checkParseMessageData(m6); CHECK(cbEvents.empty()); sut.checkParseMessageData(m5); CHECK(cbEvents.empty()); sut.checkParseMessageData(m4); CHECK(cbEvents.empty()); sut.checkParseMessageData(m3); CHECK(cbEvents.empty()); sut.checkParseMessageData(m2); CHECK_MESSAGE(cbEvents.front() == "0: true type#2 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#3 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#4 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#5 ", cbEvents.front()); cbEvents.pop(); CHECK_MESSAGE(cbEvents.front() == "0: true type#6 ", cbEvents.front()); cbEvents.pop(); CHECK(cbEvents.empty()); } }