/*! * \file deque.cpp * \brief * Unit tests for edeque * * \copyright Copyright (C) 2020 Christos Choutouridis * *
License
* The MIT License (MIT) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. *
* */ #include #include #include namespace Tedeque { using namespace tbx; int global_flag =0; // Callable mocks void vfun(void) { ++global_flag; } struct vfoo { void operator() (void) { ++global_flag; } }; TEST (Tedeque, construct) { using Edeque = edeque; struct T { int a,b; }; int local{}; Edeque e1(Edeque::size_match::GE, 3, [](){ ++global_flag; }); Edeque e2(Edeque::size_match::GE, 3, [&](){ ++local; }); Edeque e3(Edeque::size_match::EQ, 7, vfun); edeque e4(edeque::size_match::EQ, 2, vfoo{}); edeque q1; edeque q2(edeque::size_match::DISABLED, 0, nullptr); EXPECT_EQ (8UL, e1.capacity()); EXPECT_EQ (8UL, e2.capacity()); EXPECT_EQ (8UL, e3.capacity()); EXPECT_EQ (8UL, e4.capacity()); EXPECT_EQ (8UL, q1.capacity()); EXPECT_EQ (8UL, q2.capacity()); } TEST (Tedeque, base_class) { using Edeque = edeque; Edeque e1(Edeque::size_match::GE, 3, [](){ ++global_flag; }); // Access of base class functionality EXPECT_EQ (8UL, e1.capacity()); EXPECT_EQ (0UL, e1.size()); EXPECT_EQ (true, e1.empty()); EXPECT_EQ (false, e1.full()); e1.push_back(7); EXPECT_EQ (7, e1.front()); EXPECT_EQ (7, e1.back()); EXPECT_EQ (7, e1.pop_front()); e1.push_front(42); EXPECT_EQ (42, e1.front()); EXPECT_EQ (42, e1.back()); EXPECT_EQ (42, e1.pop_back()); e1.push_back(1); e1.push_back(2); e1.push_back(3); int check_it=1; for (auto it = e1.begin() ; it != e1.end() ; ++it) EXPECT_EQ(*it, check_it++); EXPECT_EQ(4, check_it); // run through all } TEST (Tedeque, set_clear_check_trigger) { using Edeque = edeque; bool flag{}; Edeque e1(Edeque::size_match::GE, 1, [&](){ flag = true; }); flag = false; e1.clear_trigger(); EXPECT_EQ (false, flag); e1.push_back(1); // 1, no-trigger cleared EXPECT_EQ (false, flag); flag = false; e1.clear(); e1.clear_trigger(); EXPECT_EQ (false, flag); // no spurious triggers e1.push_back(1); // 1 e1.push_back(2); // 2 e1.set_trigger(Edeque::size_match::GE, 1, [&](){ flag = true; }); EXPECT_EQ (false, flag); // no spurious triggers e1.check_trigger(); // manual trigger EXPECT_EQ (true, flag); flag = false; e1.check_trigger(); // manual trigger attempt EXPECT_EQ (false, flag); // [SIZE triggers are auto clear] Edeque e2(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; }); flag = false; e2.clear_trigger(); EXPECT_EQ (false, flag); e2.push_back(42); // push 42, no-trigger cleared EXPECT_EQ (false, flag); e2.set_trigger(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; }); EXPECT_EQ (false, flag); // no spurious triggers e2.push_back(42); // push 42, trigger EXPECT_EQ (true, flag); flag = false; e2.push_back(42); // push 42, re-trigger [DATA re-triggers] EXPECT_EQ (true, flag); } TEST (Tedeque, size_triggers) { using Edeque = edeque; bool flag{}; // size_match::GE (size()>= 2) Edeque ee(Edeque::size_match::GE, 2, [&](){ flag = true; }); flag = false; ee.clear(); ee.push_back(1); // 1 EXPECT_EQ (false, flag); ee.push_back(2); // 2, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(3); // 3, no-trigger cleared EXPECT_EQ (false, flag); // size_match::GT (size()> 1) flag = false; ee.clear(); ee.set_trigger(Edeque::size_match::GT, 1, [&](){ flag = true; }); ee.push_back(1); // 1 EXPECT_EQ (false, flag); ee.push_back(2); // 2, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(3); // 3, no-trigger cleared EXPECT_EQ (false, flag); // size_match::LE (size()<= 1) flag = false; ee.clear(); ee.push_back(1); // 1 ee.push_back(2); // 2 ee.push_back(3); // 3 ee.set_trigger(Edeque::size_match::LE, 1, [&](){ flag = true; }); ee.pop_front(); // 2 EXPECT_EQ (false, flag); ee.pop_front(); // 1, trigger EXPECT_EQ (true, flag); flag = false; ee.pop_front(); // 0, no-trigger cleared EXPECT_EQ (false, flag); // size_match::LT (size()< 2) flag = false; ee.clear(); ee.push_back(1); // 1 ee.push_back(2); // 2 ee.push_back(3); // 3 ee.set_trigger(Edeque::size_match::LT, 2, [&](){ flag = true; }); ee.pop_front(); // 2 EXPECT_EQ (false, flag); ee.pop_front(); // 1, trigger EXPECT_EQ (true, flag); flag = false; ee.pop_front(); // 0, no-trigger cleared EXPECT_EQ (false, flag); // size_match::EQ (size()== 2) flag = false; ee.clear(); ee.set_trigger(Edeque::size_match::EQ, 2, [&](){ flag = true; }); ee.push_back(1); // 1 EXPECT_EQ (false, flag); ee.push_back(2); // 2, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(3); // 3 ee.pop_front(); // 2, no-trigger cleared EXPECT_EQ (false, flag); // size_match::NE (size()!= 0) flag = false; ee.clear(); ee.set_trigger(Edeque::size_match::NE, 0, [&](){ flag = true; }); EXPECT_EQ (false, flag); ee.push_back(1); // 1, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(2); // 2, no-trigger EXPECT_EQ (false, flag); } TEST (Tedeque, data_triggers) { using Edeque = edeque; bool flag{}; // data_match::MATCH_PUSH (item == 42) Edeque ee(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; }); flag = false; ee.push_back(7); // 7 EXPECT_EQ (false, flag); ee.push_back(42); // push:42, trigger EXPECT_EQ (true, flag); flag = false; ee.pop_back(); // pop:42, no-trigger EXPECT_EQ (false, flag); ee.push_back(42); // push:42, re-trigger EXPECT_EQ (true, flag); // data_match::MATCH_POP (item == 42) flag = false; ee.clear_trigger(); ee.set_trigger(Edeque::data_match::MATCH_POP, 42, [&](){ flag = true; }); ee.push_back(7); // 7 EXPECT_EQ (false, flag); ee.push_back(42); // push:42, no-trigger EXPECT_EQ (false, flag); ee.pop_back(); // pop:42, trigger EXPECT_EQ (true, flag); // data_match::MISMATCH_PUSH (item != 42) flag = false; ee.clear(); ee.clear_trigger(); ee.push_back(7); // 7 ee.set_trigger(Edeque::data_match::MISMATCH_PUSH, 42, [&](){ flag = true; }); EXPECT_EQ (false, flag); // no spurious triggers ee.push_back(42); // 42, no-trigger EXPECT_EQ (false, flag); ee.push_back(0); // 0, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(1); // 1, re-trigger EXPECT_EQ (true, flag); // data_match::MISMATCH_POP (item != 42) flag = false; ee.clear(); ee.clear_trigger(); ee.push_back(7); // ->7 ee.pop_back(); // <-7 ee.set_trigger(Edeque::data_match::MISMATCH_POP, 42, [&](){ flag = true; }); EXPECT_EQ (false, flag); // no spurious triggers ee.push_back(42); // ->42, no-trigger EXPECT_EQ (false, flag); ee.push_back(0); // ->0, no-trigger EXPECT_EQ (false, flag); ee.pop_back(); // pop:0, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(0); ee.pop_back(); // pop:0, re-trigger EXPECT_EQ (true, flag); } // atomic TEST (Tedeque, construct_atomic) { using Edeque = edeque; struct T { int a,b; }; int local{}; Edeque e1(Edeque::size_match::GE, 3, [](){ ++global_flag; }); Edeque e2(Edeque::size_match::GE, 3, [&](){ ++local; }); Edeque e3(Edeque::size_match::EQ, 7, vfun); edeque e4(edeque::size_match::EQ, 2, vfoo{}); edeque q1; edeque q2(edeque::size_match::DISABLED, 0, nullptr); EXPECT_EQ (8UL, e1.capacity()); EXPECT_EQ (8UL, e2.capacity()); EXPECT_EQ (8UL, e3.capacity()); EXPECT_EQ (8UL, e4.capacity()); EXPECT_EQ (8UL, q1.capacity()); EXPECT_EQ (8UL, q2.capacity()); } TEST (Tedeque, base_class_atomic) { using Edeque = edeque; Edeque e1(Edeque::size_match::GE, 3, [](){ ++global_flag; }); // Access of base class functionality EXPECT_EQ (8UL, e1.capacity()); EXPECT_EQ (0UL, e1.size()); EXPECT_EQ (true, e1.empty()); EXPECT_EQ (false, e1.full()); e1.push_back(7); EXPECT_EQ (7, e1.front()); EXPECT_EQ (7, e1.back()); EXPECT_EQ (7, e1.pop_front()); e1.push_front(42); EXPECT_EQ (42, e1.front()); EXPECT_EQ (42, e1.back()); EXPECT_EQ (42, e1.pop_back()); e1.push_back(1); e1.push_back(2); e1.push_back(3); int check_it=1; for (auto it = e1.begin() ; it != e1.end() ; ++it) EXPECT_EQ(*it, check_it++); EXPECT_EQ(4, check_it); // run through all } TEST (Tedeque, set_clear_check_trigger_atomic) { using Edeque = edeque; bool flag{}; Edeque e1(Edeque::size_match::GE, 1, [&](){ flag = true; }); flag = false; e1.clear_trigger(); EXPECT_EQ (false, flag); e1.push_back(1); // 1, no-trigger cleared EXPECT_EQ (false, flag); flag = false; e1.clear(); e1.clear_trigger(); EXPECT_EQ (false, flag); // no spurious triggers e1.push_back(1); // 1 e1.push_back(2); // 2 e1.set_trigger(Edeque::size_match::GE, 1, [&](){ flag = true; }); EXPECT_EQ (false, flag); // no spurious triggers e1.check_trigger(); // manual trigger EXPECT_EQ (true, flag); flag = false; e1.check_trigger(); // manual trigger attempt EXPECT_EQ (false, flag); // [SIZE triggers are auto clear] Edeque e2(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; }); flag = false; e2.clear_trigger(); EXPECT_EQ (false, flag); e2.push_back(42); // push 42, no-trigger cleared EXPECT_EQ (false, flag); e2.set_trigger(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; }); EXPECT_EQ (false, flag); // no spurious triggers e2.push_back(42); // push 42, trigger EXPECT_EQ (true, flag); flag = false; e2.push_back(42); // push 42, re-trigger [DATA re-triggers] EXPECT_EQ (true, flag); } TEST (Tedeque, size_triggers_atomic) { using Edeque = edeque; bool flag{}; // size_match::GE (size()>= 2) Edeque ee(Edeque::size_match::GE, 2, [&](){ flag = true; }); flag = false; ee.clear(); ee.push_back(1); // 1 EXPECT_EQ (false, flag); ee.push_back(2); // 2, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(3); // 3, no-trigger cleared EXPECT_EQ (false, flag); // size_match::GT (size()> 1) flag = false; ee.clear(); ee.set_trigger(Edeque::size_match::GT, 1, [&](){ flag = true; }); ee.push_back(1); // 1 EXPECT_EQ (false, flag); ee.push_back(2); // 2, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(3); // 3, no-trigger cleared EXPECT_EQ (false, flag); // size_match::LE (size()<= 1) flag = false; ee.clear(); ee.push_back(1); // 1 ee.push_back(2); // 2 ee.push_back(3); // 3 ee.set_trigger(Edeque::size_match::LE, 1, [&](){ flag = true; }); ee.pop_front(); // 2 EXPECT_EQ (false, flag); ee.pop_front(); // 1, trigger EXPECT_EQ (true, flag); flag = false; ee.pop_front(); // 0, no-trigger cleared EXPECT_EQ (false, flag); // size_match::LT (size()< 2) flag = false; ee.clear(); ee.push_back(1); // 1 ee.push_back(2); // 2 ee.push_back(3); // 3 ee.set_trigger(Edeque::size_match::LT, 2, [&](){ flag = true; }); ee.pop_front(); // 2 EXPECT_EQ (false, flag); ee.pop_front(); // 1, trigger EXPECT_EQ (true, flag); flag = false; ee.pop_front(); // 0, no-trigger cleared EXPECT_EQ (false, flag); // size_match::EQ (size()== 2) flag = false; ee.clear(); ee.set_trigger(Edeque::size_match::EQ, 2, [&](){ flag = true; }); ee.push_back(1); // 1 EXPECT_EQ (false, flag); ee.push_back(2); // 2, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(3); // 3 ee.pop_front(); // 2, no-trigger cleared EXPECT_EQ (false, flag); // size_match::NE (size()!= 0) flag = false; ee.clear(); ee.set_trigger(Edeque::size_match::NE, 0, [&](){ flag = true; }); EXPECT_EQ (false, flag); ee.push_back(1); // 1, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(2); // 2, no-trigger EXPECT_EQ (false, flag); } TEST (Tedeque, data_triggers_atomic) { using Edeque = edeque; bool flag{}; // data_match::MATCH_PUSH (item == 42) Edeque ee(Edeque::data_match::MATCH_PUSH, 42, [&](){ flag = true; }); flag = false; ee.push_back(7); // 7 EXPECT_EQ (false, flag); ee.push_back(42); // push:42, trigger EXPECT_EQ (true, flag); flag = false; ee.pop_back(); // pop:42, no-trigger EXPECT_EQ (false, flag); ee.push_back(42); // push:42, re-trigger EXPECT_EQ (true, flag); // data_match::MATCH_POP (item == 42) flag = false; ee.clear_trigger(); ee.set_trigger(Edeque::data_match::MATCH_POP, 42, [&](){ flag = true; }); ee.push_back(7); // 7 EXPECT_EQ (false, flag); ee.push_back(42); // push:42, no-trigger EXPECT_EQ (false, flag); ee.pop_back(); // pop:42, trigger EXPECT_EQ (true, flag); // data_match::MISMATCH_PUSH (item != 42) flag = false; ee.clear(); ee.clear_trigger(); ee.push_back(7); // 7 ee.set_trigger(Edeque::data_match::MISMATCH_PUSH, 42, [&](){ flag = true; }); EXPECT_EQ (false, flag); // no spurious triggers ee.push_back(42); // 42, no-trigger EXPECT_EQ (false, flag); ee.push_back(0); // 0, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(1); // 1, re-trigger EXPECT_EQ (true, flag); // data_match::MISMATCH_POP (item != 42) flag = false; ee.clear(); ee.clear_trigger(); ee.push_back(7); // ->7 ee.pop_back(); // <-7 ee.set_trigger(Edeque::data_match::MISMATCH_POP, 42, [&](){ flag = true; }); EXPECT_EQ (false, flag); // no spurious triggers ee.push_back(42); // ->42, no-trigger EXPECT_EQ (false, flag); ee.push_back(0); // ->0, no-trigger EXPECT_EQ (false, flag); ee.pop_back(); // pop:0, trigger EXPECT_EQ (true, flag); flag = false; ee.push_back(0); ee.pop_back(); // pop:0, re-trigger EXPECT_EQ (true, flag); } }