// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/RecurrenceRuleMatcher.java
// public static <T> Matcher<T> are(Matcher<T> matcher)
// {
//     Description description = new StringDescription();
//     matcher.describeTo(description);
//     return describedAs(String.format("are %s", description.toString()), is(matcher));
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/RecurrenceRuleMatcher.java
// public static Function<DateTime, Matcher<RecurrenceRule>> instances(Matcher<DateTime> dtMatchers)
// {
//     return dateTime -> InstancesMatcher.instances(dateTime, dtMatchers);
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/RecurrenceRuleMatcher.java
// public static Function<DateTime, Matcher<RecurrenceRule>> startingWith(String... dates)
// {
//     return startingWith(new Seq<>(dates));
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/RecurrenceRuleMatcher.java
// public static Matcher<RecurrenceRule> validRule(DateTime start, Iterable<Function<DateTime, Matcher<RecurrenceRule>>> matcherFunctions)
// {
//     return new AllOf<>(new Joined<>(new Seq<>(increasing(start)), new Mapped<>(f -> f.value(start), matcherFunctions)));
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/datetime/DayOfMonthMatcher.java
// public static Matcher<DateTime> onDayOfMonth(Matcher<Integer> dayMatcher)
// {
//     return new DayOfMonthMatcher(dayMatcher);
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/datetime/DayOfYearMatcher.java
// public static Matcher<DateTime> onDayOfYear(Matcher<Integer> dayMatcher)
// {
//     return new DayOfYearMatcher(dayMatcher);
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/datetime/MonthMatcher.java
// public static Matcher<DateTime> inMonth(Matcher<Integer> monthMatcher)
// {
//     return new MonthMatcher(monthMatcher);
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/datetime/WeekOfYearMatcher.java
// public static Matcher<DateTime> inWeekOfYear(Matcher<Integer> weekOfYearMatcher)
// {
//     return new WeekOfYearMatcher(weekOfYearMatcher);
// }


import org.dmfs.rfc5545.DateTime;
import org.junit.Test;
import static org.dmfs.rfc5545.hamcrest.RecurrenceRuleMatcher.are;
import static org.dmfs.rfc5545.hamcrest.RecurrenceRuleMatcher.instances;
import static org.dmfs.rfc5545.hamcrest.RecurrenceRuleMatcher.startingWith;
import static org.dmfs.rfc5545.hamcrest.RecurrenceRuleMatcher.validRule;
import static org.dmfs.rfc5545.hamcrest.datetime.DayOfMonthMatcher.onDayOfMonth;
import static org.dmfs.rfc5545.hamcrest.datetime.DayOfYearMatcher.onDayOfYear;
import static org.dmfs.rfc5545.hamcrest.datetime.MonthMatcher.inMonth;
import static org.dmfs.rfc5545.hamcrest.datetime.WeekOfYearMatcher.inWeekOfYear;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
                        startingWith("20121231", "20140101", "20150101", "20160101", "20161231", "20180101", "20190101", "20200101", "20201231"))));
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=366;SKIP=BACKWARD"),
                is(validRule(DateTime.parse("20121231"),
                        instances(are(onDayOfMonth(31), inMonth(12))),
                        startingWith("20121231", "20131231", "20141231", "20151231", "20161231", "20171231", "20181231", "20191231", "20201231"))));

        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=-366"),
                is(validRule(DateTime.parse("20120101"),
                        instances(are(onDayOfMonth(1), inMonth(1))),
                        startingWith("20120101", "20160101", "20200101"))));
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=-366;SKIP=OMIT"),
                is(validRule(DateTime.parse("20120101"),
                        instances(are(onDayOfMonth(1), inMonth(1))),
                        startingWith("20120101", "20160101", "20200101"))));
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=-366;SKIP=FORWARD"),
                is(validRule(DateTime.parse("20120101"),
                        instances(are(onDayOfMonth(1), inMonth(1), onDayOfYear(1))),
                        startingWith("20120101", "20130101", "20140101", "20150101", "20160101", "20170101", "20180101", "20190101", "20200101"))));
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=-366;SKIP=BACKWARD"),
                is(validRule(DateTime.parse("20120101"),
                        instances(are(onDayOfMonth(1, 31), inMonth(1, 12))),
                        startingWith("20120101", "20121231", "20131231", "20141231", "20160101", "20161231", "20171231", "20181231", "20200101"))));
    }


    @Test
    public void testByWeekNoSkip() throws InvalidRecurrenceRuleException
    {
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYWEEKNO=53"),
                is(validRule(DateTime.parse("20151229"),
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/RecurrenceRuleMatcher.java
// public static <T> Matcher<T> are(Matcher<T> matcher)
// {
//     Description description = new StringDescription();
//     matcher.describeTo(description);
//     return describedAs(String.format("are %s", description.toString()), is(matcher));
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/RecurrenceRuleMatcher.java
// public static Function<DateTime, Matcher<RecurrenceRule>> instances(Matcher<DateTime> dtMatchers)
// {
//     return dateTime -> InstancesMatcher.instances(dateTime, dtMatchers);
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/RecurrenceRuleMatcher.java
// public static Function<DateTime, Matcher<RecurrenceRule>> startingWith(String... dates)
// {
//     return startingWith(new Seq<>(dates));
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/RecurrenceRuleMatcher.java
// public static Matcher<RecurrenceRule> validRule(DateTime start, Iterable<Function<DateTime, Matcher<RecurrenceRule>>> matcherFunctions)
// {
//     return new AllOf<>(new Joined<>(new Seq<>(increasing(start)), new Mapped<>(f -> f.value(start), matcherFunctions)));
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/datetime/DayOfMonthMatcher.java
// public static Matcher<DateTime> onDayOfMonth(Matcher<Integer> dayMatcher)
// {
//     return new DayOfMonthMatcher(dayMatcher);
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/datetime/DayOfYearMatcher.java
// public static Matcher<DateTime> onDayOfYear(Matcher<Integer> dayMatcher)
// {
//     return new DayOfYearMatcher(dayMatcher);
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/datetime/MonthMatcher.java
// public static Matcher<DateTime> inMonth(Matcher<Integer> monthMatcher)
// {
//     return new MonthMatcher(monthMatcher);
// }
// 
// Path: lib-recur-hamcrest/src/main/java/org/dmfs/rfc5545/hamcrest/datetime/WeekOfYearMatcher.java
// public static Matcher<DateTime> inWeekOfYear(Matcher<Integer> weekOfYearMatcher)
// {
//     return new WeekOfYearMatcher(weekOfYearMatcher);
// }


// Path: src/test/java/org/dmfs/rfc5545/recur/RScaleTest.java
import org.dmfs.rfc5545.DateTime;
import org.junit.Test;
import static org.dmfs.rfc5545.hamcrest.RecurrenceRuleMatcher.are;
import static org.dmfs.rfc5545.hamcrest.RecurrenceRuleMatcher.instances;
import static org.dmfs.rfc5545.hamcrest.RecurrenceRuleMatcher.startingWith;
import static org.dmfs.rfc5545.hamcrest.RecurrenceRuleMatcher.validRule;
import static org.dmfs.rfc5545.hamcrest.datetime.DayOfMonthMatcher.onDayOfMonth;
import static org.dmfs.rfc5545.hamcrest.datetime.DayOfYearMatcher.onDayOfYear;
import static org.dmfs.rfc5545.hamcrest.datetime.MonthMatcher.inMonth;
import static org.dmfs.rfc5545.hamcrest.datetime.WeekOfYearMatcher.inWeekOfYear;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

                        startingWith("20121231", "20140101", "20150101", "20160101", "20161231", "20180101", "20190101", "20200101", "20201231"))));
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=366;SKIP=BACKWARD"),
                is(validRule(DateTime.parse("20121231"),
                        instances(are(onDayOfMonth(31), inMonth(12))),
                        startingWith("20121231", "20131231", "20141231", "20151231", "20161231", "20171231", "20181231", "20191231", "20201231"))));

        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=-366"),
                is(validRule(DateTime.parse("20120101"),
                        instances(are(onDayOfMonth(1), inMonth(1))),
                        startingWith("20120101", "20160101", "20200101"))));
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=-366;SKIP=OMIT"),
                is(validRule(DateTime.parse("20120101"),
                        instances(are(onDayOfMonth(1), inMonth(1))),
                        startingWith("20120101", "20160101", "20200101"))));
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=-366;SKIP=FORWARD"),
                is(validRule(DateTime.parse("20120101"),
                        instances(are(onDayOfMonth(1), inMonth(1), onDayOfYear(1))),
                        startingWith("20120101", "20130101", "20140101", "20150101", "20160101", "20170101", "20180101", "20190101", "20200101"))));
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYYEARDAY=-366;SKIP=BACKWARD"),
                is(validRule(DateTime.parse("20120101"),
                        instances(are(onDayOfMonth(1, 31), inMonth(1, 12))),
                        startingWith("20120101", "20121231", "20131231", "20141231", "20160101", "20161231", "20171231", "20181231", "20200101"))));
    }


    @Test
    public void testByWeekNoSkip() throws InvalidRecurrenceRuleException
    {
        assertThat(new RecurrenceRule("FREQ=YEARLY;RSCALE=GREGORIAN;BYWEEKNO=53"),
                is(validRule(DateTime.parse("20151229"),
                        instances(are(onDayOfMonth(28, 29), inMonth(12), inWeekOfYear(53))),