From f7442f697211952c1f0b9203189e41835dda5bcc Mon Sep 17 00:00:00 2001 From: Per Malmberg Date: Fri, 9 Mar 2018 23:51:13 +0100 Subject: [PATCH] More tests, seems to be working. Still needs to handle non-existent dates. --- .idea/runConfigurations/All.xml | 6 +++ CMakeLists.txt | 2 +- libcron/CMakeLists.txt | 2 +- libcron/CronSchedule.cpp | 46 +++++++++++------------ test/CMakeLists.txt | 2 +- test/CronScheduleTest.cpp | 66 +++++++++++++++++++++++++++++++++ test/test.cpp | 50 ------------------------- 7 files changed, 98 insertions(+), 76 deletions(-) create mode 100644 .idea/runConfigurations/All.xml create mode 100644 test/CronScheduleTest.cpp diff --git a/.idea/runConfigurations/All.xml b/.idea/runConfigurations/All.xml new file mode 100644 index 0000000..19c75ae --- /dev/null +++ b/.idea/runConfigurations/All.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index a6b181a..d0bb848 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.6) add_subdirectory(libcron) add_subdirectory(test) diff --git a/libcron/CMakeLists.txt b/libcron/CMakeLists.txt index 9fdd111..66ac343 100644 --- a/libcron/CMakeLists.txt +++ b/libcron/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.6) project(libcron) set(CMAKE_CXX_STANDARD 14) diff --git a/libcron/CronSchedule.cpp b/libcron/CronSchedule.cpp index a4ec362..a91f1b1 100644 --- a/libcron/CronSchedule.cpp +++ b/libcron/CronSchedule.cpp @@ -9,9 +9,12 @@ namespace libcron std::chrono::system_clock::time_point CronSchedule::calculate_from(const std::chrono::system_clock::time_point& from) { - auto curr = from; + //auto time_part = from - date::floor(from); + auto curr = from;// - time_part; + //auto dt = to_calendar_time(curr); bool done = false; + while (!done) { year_month_day ymd = date::floor(curr); @@ -19,23 +22,24 @@ namespace libcron // Add months until one of the allowed days are found, or stay at the current one. if (data.get_months().find(static_cast(unsigned(ymd.month()))) == data.get_months().end()) { - curr += months{1}; - ymd = date::floor(curr); + auto next_month = ymd + months{1}; + sys_days s = next_month.year() / next_month.month() / 1; + curr = s; continue; } - - // If all days are allowed, then the 'day of week' takes precedence, which also means that - // day of week only is ignored when specific days of months are specified. - if (data.get_day_of_month().size() != CronData::value_of(DayOfMonth::Last)) + // If all days are allowed, then the 'day of week' takes precedence, which also means that + // day of week only is ignored when specific days of months are specified. + else if (data.get_day_of_month().size() != CronData::value_of(DayOfMonth::Last)) { // Add days until one of the allowed days are found, or stay at the current one. - if(data.get_day_of_month().find(static_cast(unsigned(ymd.day()))) == - data.get_day_of_month().end()) + if (data.get_day_of_month().find(static_cast(unsigned(ymd.day()))) == + data.get_day_of_month().end()) { + sys_days s = ymd; + curr = s; curr += days{1}; - ymd = date::floor(curr); continue; - }; + } } else { @@ -43,32 +47,29 @@ namespace libcron year_month_weekday ymw = date::floor(curr); if (data.get_day_of_week().find(static_cast(unsigned(ymw.weekday()))) == - data.get_day_of_week().end()) + data.get_day_of_week().end()) { + sys_days s = ymd; + curr = s; curr += days{1}; - ymw = date::floor(curr); continue; - }; + } } - // Add hours until the current hour is one of the allowed + //curr += time_part; auto date_time = to_calendar_time(curr); if (data.get_hours().find(static_cast(date_time.hour)) == data.get_hours().end()) { curr += hours{1}; - continue; + curr -= minutes{date_time.min}; + curr -= seconds{date_time.sec}; } else if (data.get_minutes().find(static_cast(date_time.min)) == data.get_minutes().end()) { curr += minutes{1}; - continue; + curr -= seconds{date_time.sec}; } else if (data.get_seconds().find(static_cast(date_time.sec)) == data.get_seconds().end()) - { - curr += seconds{1}; - continue; - } - else if( curr <= from ) { curr += seconds{1}; } @@ -78,7 +79,6 @@ namespace libcron } } - return curr; } } \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index dda57bf..65387b1 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,6 +13,6 @@ include_directories( add_executable( ${PROJECT_NAME} test.cpp -) + CronScheduleTest.cpp) target_link_libraries(${PROJECT_NAME} libcron) \ No newline at end of file diff --git a/test/CronScheduleTest.cpp b/test/CronScheduleTest.cpp new file mode 100644 index 0000000..091f6c8 --- /dev/null +++ b/test/CronScheduleTest.cpp @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +using namespace libcron; +using namespace date; +using namespace std::chrono; + +system_clock::time_point DT(year_month_day ymd, hours h = hours{0}, minutes m = minutes{0}, seconds s = seconds{0}) +{ + sys_days t = ymd; + auto sum = t + h + m + s; + return sum; +} + +bool test(const std::string& schedule, system_clock::time_point from, system_clock::time_point expected_next) +{ + auto c = CronData::create(schedule); + bool res = c.is_valid(); + if (res) + { + CronSchedule sched(c); + auto run_time = sched.calculate_from(from); + res &= expected_next == run_time; + + if (!res) + { + std::cout + << "From: " << from << "\n" + << "Expected: " << expected_next << "\n" + << "Calculated: " << run_time; + + } + } + + return res; +} + + +SCENARIO("Calculating next runtime") +{ + REQUIRE(test("0 0 * * * *", DT(2010_y / 1 / 1), DT(2010_y / 1 / 1, hours{0}))); + REQUIRE(test("0 0 * * * *", DT(2010_y / 1 / 1, hours{0}, minutes{0}, seconds{1}), DT(2010_y / 1 / 1, hours{1}))); + REQUIRE(test("0 0 * * * *", DT(2010_y / 1 / 1, hours{5}), DT(2010_y / 1 / 1, hours{5}))); + REQUIRE(test("0 0 * * * *", DT(2010_y / 1 / 1, hours{5}, minutes{1}), DT(2010_y / 1 / 1, hours{6}))); + REQUIRE(test("0 0 * * * *", DT(2017_y / 12 / 31, hours{23}, minutes{59}, seconds{58}), DT(2018_y / 1 / 1, hours{0}))); + REQUIRE(test("0 0 10 * * *", DT(2017_y / 12 / 31, hours{9}, minutes{59}, seconds{58}), DT(2017_y / 12 / 31, hours{10}))); + REQUIRE(test("0 0 10 * * *", DT(2017_y / 12 / 31, hours{23}, minutes{59}, seconds{58}), DT(2018_y / 1 / 1, hours{10}))); + REQUIRE(test("0 0 10 * FEB *", DT(2017_y / 12 / 31, hours{23}, minutes{59}, seconds{58}), DT(2018_y / 2 / 1, hours{10}))); + REQUIRE(test("0 0 10 25 FEB *", DT(2017_y / 12 / 31, hours{23}, minutes{59}, seconds{58}), DT(2018_y / 2 / 25, hours{10}))); + REQUIRE(test("0 0 10 * FEB 1", DT(2017_y / 12 / 31, hours{23}, minutes{59}, seconds{58}), DT(year_month_day{2018_y/2/mon[1]}, hours{10}))); + REQUIRE(test("0 0 10 * FEB 6", DT(2017_y / 12 / 31, hours{23}, minutes{59}, seconds{58}), DT(year_month_day{2018_y/2/sat[1]}, hours{10}))); + REQUIRE(test("* * * 10-12 NOV *", DT(2018_y / 11 / 11, hours{10}, minutes{11}, seconds{12}), DT(year_month_day{2018_y/11/11}, hours{10}, minutes{11}, seconds{12}))); +} + +SCENARIO("Leap year") +{ + REQUIRE(test("0 0 * 29 FEB *", DT(2018_y / 1 / 1), DT(2020_y / 2 / 29))); +} + +SCENARIO("Date that does not exist") +{ + //REQUIRE_FALSE(test("0 0 * 30 FEB *", DT(2018_y / 1 / 1), DT(2020_y / 2 / 29))); +} \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp index d9129e6..53cd06c 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -227,53 +227,3 @@ SCENARIO("Using step syntax") } } -SCENARIO("Calculating next runtime") -{ - GIVEN("An item schedule for the top of every hour") - { - auto c = CronData::create("0 0 * * * *"); - REQUIRE(c.is_valid()); - CronSchedule sched(c); - - WHEN("Start time is midnight") - { - sys_days midnight = 2010_y/1/1; - std::chrono::system_clock::time_point run_time = sched.calculate_from(midnight); - - THEN("Next runtime is 01:00 of the same date") - { - auto t = CronSchedule::to_calendar_time(run_time); - REQUIRE(t.year == 2010); - REQUIRE(t.month == 1); - REQUIRE(t.day == 1); - REQUIRE(t.hour == 1); - REQUIRE(t.min == 0); - REQUIRE(t.sec == 0); - } - } - AND_WHEN("Start time 05:00:00") - { - sys_days midnight = 2010_y/1/1; - system_clock::time_point five = midnight; - five += hours{5}; - - auto t2 = CronSchedule::to_calendar_time(five); - - std::chrono::system_clock::time_point run_time = sched.calculate_from(five); - - THEN("Next runtime is 06:00 of the same date") - { - auto t = CronSchedule::to_calendar_time(run_time); - REQUIRE(t.year == 2010); - REQUIRE(t.month == 1); - REQUIRE(t.day == 1); - REQUIRE(t.hour == 6); - REQUIRE(t.min == 0); - REQUIRE(t.sec == 0); - } - } - - - - } -} \ No newline at end of file