mirror of
https://github.com/PerMalmberg/libcron.git
synced 2025-04-22 08:23:04 -05:00
More tests, seems to be working. Still needs to handle non-existent dates.
This commit is contained in:
parent
74800b0d5e
commit
f7442f6972
6
.idea/runConfigurations/All.xml
generated
Normal file
6
.idea/runConfigurations/All.xml
generated
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="All" type="CMakeCatchTestRunConfigurationType" factoryName="Catch Test" singleton="true" PASS_PARENT_ENVS_2="true" PROJECT_NAME="Project" TARGET_NAME="cron_test" CONFIG_NAME="Debug" RUN_TARGET_PROJECT_NAME="Project" RUN_TARGET_NAME="cron_test" TEST_MODE="SUITE_TEST">
|
||||||
|
<envs />
|
||||||
|
<method />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.9)
|
cmake_minimum_required(VERSION 3.6)
|
||||||
|
|
||||||
add_subdirectory(libcron)
|
add_subdirectory(libcron)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 3.9)
|
cmake_minimum_required(VERSION 3.6)
|
||||||
project(libcron)
|
project(libcron)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
@ -9,9 +9,12 @@ namespace libcron
|
|||||||
std::chrono::system_clock::time_point
|
std::chrono::system_clock::time_point
|
||||||
CronSchedule::calculate_from(const std::chrono::system_clock::time_point& from)
|
CronSchedule::calculate_from(const std::chrono::system_clock::time_point& from)
|
||||||
{
|
{
|
||||||
auto curr = from;
|
//auto time_part = from - date::floor<days>(from);
|
||||||
|
auto curr = from;// - time_part;
|
||||||
|
//auto dt = to_calendar_time(curr);
|
||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
|
|
||||||
while (!done)
|
while (!done)
|
||||||
{
|
{
|
||||||
year_month_day ymd = date::floor<days>(curr);
|
year_month_day ymd = date::floor<days>(curr);
|
||||||
@ -19,23 +22,24 @@ namespace libcron
|
|||||||
// Add months until one of the allowed days are found, or stay at the current one.
|
// Add months until one of the allowed days are found, or stay at the current one.
|
||||||
if (data.get_months().find(static_cast<Months>(unsigned(ymd.month()))) == data.get_months().end())
|
if (data.get_months().find(static_cast<Months>(unsigned(ymd.month()))) == data.get_months().end())
|
||||||
{
|
{
|
||||||
curr += months{1};
|
auto next_month = ymd + months{1};
|
||||||
ymd = date::floor<days>(curr);
|
sys_days s = next_month.year() / next_month.month() / 1;
|
||||||
|
curr = s;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If all days are allowed, then the 'day of week' takes precedence, which also means that
|
// 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.
|
// 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))
|
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.
|
// 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<DayOfMonth>(unsigned(ymd.day()))) ==
|
if (data.get_day_of_month().find(static_cast<DayOfMonth>(unsigned(ymd.day()))) ==
|
||||||
data.get_day_of_month().end())
|
data.get_day_of_month().end())
|
||||||
{
|
{
|
||||||
|
sys_days s = ymd;
|
||||||
|
curr = s;
|
||||||
curr += days{1};
|
curr += days{1};
|
||||||
ymd = date::floor<days>(curr);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -45,30 +49,27 @@ namespace libcron
|
|||||||
if (data.get_day_of_week().find(static_cast<DayOfWeek>(unsigned(ymw.weekday()))) ==
|
if (data.get_day_of_week().find(static_cast<DayOfWeek>(unsigned(ymw.weekday()))) ==
|
||||||
data.get_day_of_week().end())
|
data.get_day_of_week().end())
|
||||||
{
|
{
|
||||||
|
sys_days s = ymd;
|
||||||
|
curr = s;
|
||||||
curr += days{1};
|
curr += days{1};
|
||||||
ymw = date::floor<days>(curr);
|
|
||||||
continue;
|
continue;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add hours until the current hour is one of the allowed
|
//curr += time_part;
|
||||||
auto date_time = to_calendar_time(curr);
|
auto date_time = to_calendar_time(curr);
|
||||||
if (data.get_hours().find(static_cast<Hours>(date_time.hour)) == data.get_hours().end())
|
if (data.get_hours().find(static_cast<Hours>(date_time.hour)) == data.get_hours().end())
|
||||||
{
|
{
|
||||||
curr += hours{1};
|
curr += hours{1};
|
||||||
continue;
|
curr -= minutes{date_time.min};
|
||||||
|
curr -= seconds{date_time.sec};
|
||||||
}
|
}
|
||||||
else if (data.get_minutes().find(static_cast<Minutes >(date_time.min)) == data.get_minutes().end())
|
else if (data.get_minutes().find(static_cast<Minutes >(date_time.min)) == data.get_minutes().end())
|
||||||
{
|
{
|
||||||
curr += minutes{1};
|
curr += minutes{1};
|
||||||
continue;
|
curr -= seconds{date_time.sec};
|
||||||
}
|
}
|
||||||
else if (data.get_seconds().find(static_cast<Seconds>(date_time.sec)) == data.get_seconds().end())
|
else if (data.get_seconds().find(static_cast<Seconds>(date_time.sec)) == data.get_seconds().end())
|
||||||
{
|
|
||||||
curr += seconds{1};
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if( curr <= from )
|
|
||||||
{
|
{
|
||||||
curr += seconds{1};
|
curr += seconds{1};
|
||||||
}
|
}
|
||||||
@ -78,7 +79,6 @@ namespace libcron
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return curr;
|
return curr;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,6 +13,6 @@ include_directories(
|
|||||||
add_executable(
|
add_executable(
|
||||||
${PROJECT_NAME}
|
${PROJECT_NAME}
|
||||||
test.cpp
|
test.cpp
|
||||||
)
|
CronScheduleTest.cpp)
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME} libcron)
|
target_link_libraries(${PROJECT_NAME} libcron)
|
66
test/CronScheduleTest.cpp
Normal file
66
test/CronScheduleTest.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include <catch.hpp>
|
||||||
|
#include <chrono>
|
||||||
|
#include <date.h>
|
||||||
|
#include <libcron/Cron.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
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)));
|
||||||
|
}
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user