diff --git a/Tests/cpptick.cpp b/Tests/cpptick.cpp index ddc0570..97666f3 100644 --- a/Tests/cpptick.cpp +++ b/Tests/cpptick.cpp @@ -134,24 +134,137 @@ TEST_CASE("Timer will be invoked.", "[cpptick]") SECTION("Timer will be invoked after 100 milliseconds.") { timer.start(); - auto current = TestHal::getMillis(); scheduler.tick(); CHECK(callback_count == 0); + SECTION("Timer won't be executed prematurely.") + { + std::this_thread::sleep_for(80ms); + scheduler.tick(); + CHECK(callback_count == 0); + } + + SECTION("Time will be executed after period elapsed.") + { + std::this_thread::sleep_for(110ms); + scheduler.tick(); + CHECK(callback_count == 1); + + SECTION("Single shot timer isn't executed again.") + { + CHECK(callback_count == 1); + + std::this_thread::sleep_for(110ms); + scheduler.tick(); + CHECK(callback_count == 1); + } + } + } + + SECTION("An unstarted timer does not run.") + { + scheduler.tick(); + CHECK(callback_count == 0); + std::this_thread::sleep_for(110ms); + scheduler.tick(); + CHECK(callback_count == 0); + } + + delete f; +} + +TEST_CASE("Periodic timers will be invoked repeatedly.", "[cpptick]") +{ + cpptick::Scheduler scheduler; + + cpptick::Slot slot(&scheduler); + auto* f = slot.connect(callbackByOne); + + callback_count = 0; + REQUIRE(callback_count == 0); + + cpptick::Timer timer(&scheduler, 100, false); + timer.setSlot(slot); + + SECTION("Timer will be invoked after 100 milliseconds.") + { + timer.start(); scheduler.tick(); - CHECK(callback_count == 1); + CHECK(callback_count == 0); - SECTION("Single shot timer isn't executed again.") + SECTION("Timer won't be executed prematurely.") { + std::this_thread::sleep_for(80ms); + scheduler.tick(); + CHECK(callback_count == 0); + } + + SECTION("Time will be executed after period elapsed.") + { + std::this_thread::sleep_for(110ms); + scheduler.tick(); CHECK(callback_count == 1); - std::this_thread::sleep_for(110ms); - CHECK(callback_count == 1); + SECTION("Periodic timer is executed again.") + { + CHECK(callback_count == 1); + + std::this_thread::sleep_for(110ms); + scheduler.tick(); + CHECK(callback_count == 2); + } } } delete f; } + +TEST_CASE("Sequential timers operate appropriately.", "[cpptick]") +{ + cpptick::Scheduler scheduler; + + cpptick::Slot slot_a(&scheduler); + auto* f = slot_a.connect(callbackByOne); + + cpptick::Timer timer_a(&scheduler, 100, false); + timer_a.setSlot(slot_a); + + auto callback_by_two = []() -> void + { + callback_count += 2; + }; + cpptick::Slot slot_b(&scheduler); + auto* ff = slot_b.connect(callback_by_two); + + cpptick::Timer timer_b(&scheduler, 50, true); + timer_b.setSlot(slot_b); + + callback_count = 0; + REQUIRE(callback_count == 0); + + timer_a.start(); + timer_b.start(); + + SECTION("Shorter timer is called first.", "[cpptick]") + { + std::this_thread::sleep_for(60ms); + scheduler.tick(); + CHECK(callback_count == 2); + + scheduler.tick(); + CHECK(callback_count == 2); + + SECTION("Longer timer is executed afterwards.", "[cpptick]") + { + std::this_thread::sleep_for(50ms); + scheduler.tick(); + CHECK(callback_count == 3); + } + } + + delete f; + delete ff; +}