-module(logic_recurrence_tests). -include_lib("eunit/include/eunit.hrl"). logic_recurrence_test_() -> [ {"Parse RRULE test", fun test_parse_rrule/0}, {"Validate RRULE test", fun test_validate_rrule/0}, {"Generate daily occurrences test", fun test_daily_occurrences/0}, {"Generate weekly occurrences test", fun test_weekly_occurrences/0}, {"Generate monthly occurrences test", fun test_monthly_occurrences/0}, {"Generate with count limit test", fun test_count_limit/0}, {"Generate with until limit test", fun test_until_limit/0} ]. test_parse_rrule() -> RRule = #{ <<"freq">> => <<"WEEKLY">>, <<"interval">> => 2, <<"until">> => <<"2026-12-31T00:00:00Z">>, <<"byday">> => [<<"MO">>, <<"WE">>, <<"FR">>] }, {ok, Parsed} = logic_recurrence:parse_rrule(RRule), ?assertEqual(<<"WEEKLY">>, maps:get(freq, Parsed)), ?assertEqual(2, maps:get(interval, Parsed)), ?assertEqual(<<"2026-12-31T00:00:00Z">>, maps:get(until, Parsed)), ?assertEqual([<<"MO">>, <<"WE">>, <<"FR">>], maps:get(byday, Parsed)). test_validate_rrule() -> ValidRule = #{ freq => <<"DAILY">>, interval => 1 }, ?assert(logic_recurrence:validate_rrule(ValidRule)), InvalidFreq = #{ freq => <<"YEARLY">>, interval => 1 }, ?assertNot(logic_recurrence:validate_rrule(InvalidFreq)), InvalidInterval = #{ freq => <<"DAILY">>, interval => 0 }, ?assertNot(logic_recurrence:validate_rrule(InvalidInterval)). test_daily_occurrences() -> StartTime = {{2026, 4, 20}, {10, 0, 0}}, RRule = #{ freq => <<"DAILY">>, interval => 1 }, RangeEnd = {{2026, 4, 25}, {10, 0, 0}}, Occurrences = logic_recurrence:generate_occurrences(StartTime, RRule, RangeEnd), ?assertEqual(6, length(Occurrences)), ?assertEqual({{2026, 4, 20}, {10, 0, 0}}, lists:nth(1, Occurrences)), ?assertEqual({{2026, 4, 25}, {10, 0, 0}}, lists:nth(6, Occurrences)). test_weekly_occurrences() -> StartTime = {{2026, 4, 20}, {10, 0, 0}}, % Monday RRule = #{ freq => <<"WEEKLY">>, interval => 1 }, RangeEnd = {{2026, 5, 11}, {10, 0, 0}}, Occurrences = logic_recurrence:generate_occurrences(StartTime, RRule, RangeEnd), ?assertEqual(4, length(Occurrences)), ?assertEqual({{2026, 4, 20}, {10, 0, 0}}, lists:nth(1, Occurrences)), ?assertEqual({{2026, 5, 11}, {10, 0, 0}}, lists:nth(4, Occurrences)). test_monthly_occurrences() -> StartTime = {{2026, 4, 20}, {10, 0, 0}}, RRule = #{ freq => <<"MONTHLY">>, interval => 1 }, RangeEnd = {{2026, 7, 20}, {10, 0, 0}}, Occurrences = logic_recurrence:generate_occurrences(StartTime, RRule, RangeEnd), ?assertEqual(4, length(Occurrences)), ?assertEqual({{2026, 4, 20}, {10, 0, 0}}, lists:nth(1, Occurrences)), ?assertEqual({{2026, 7, 20}, {10, 0, 0}}, lists:nth(4, Occurrences)). test_count_limit() -> StartTime = {{2026, 4, 20}, {10, 0, 0}}, RRule = #{ freq => <<"DAILY">>, interval => 1, count => 3 }, RangeEnd = {{2026, 12, 31}, {10, 0, 0}}, Occurrences = logic_recurrence:generate_occurrences(StartTime, RRule, RangeEnd), ?assertEqual(3, length(Occurrences)). test_until_limit() -> StartTime = {{2026, 4, 20}, {10, 0, 0}}, RRule = #{ freq => <<"DAILY">>, interval => 1, until => <<"2026-04-22T10:00:00Z">> }, RangeEnd = {{2026, 12, 31}, {10, 0, 0}}, Occurrences = logic_recurrence:generate_occurrences(StartTime, RRule, RangeEnd), % 20, 21, 22 апреля = 3 дня ?assertEqual(3, length(Occurrences)).