/// <summary>
        ///     Parse a year match expression.
        ///     <example>
        ///         Valid expression are:
        ///         * => Every year
        ///         2020 => Exactly that year
        ///         ..2030 => Every year until 2030 comprised
        ///         2020.. => Every year starting from 2020
        ///         2020..2030 => Every year between 2020 and 2030
        ///         */Leap => Every leap year
        ///         2020..2030/Leap => Every leap year between 2020 and 2030
        ///         */NotLeap => Every non leap year
        ///         2020..2030/2 => Starting from 2020 every 2 years until 2030
        ///         2020../2 => Starting from 2020 every 2 years
        ///         2020../NotLeap => Starting from 2020 every NonLeap year
        ///         2020..2030%2 => Every year which reminder modulo 2 is zero between 2020 and 2030
        ///         2020..%3 => Starting from 2020 every year which reminder modulo 3 is zero
        ///     </example>
        /// </summary>
        public override bool TryParse(string value, out IYearMatcher yearMatcher)
        {
            if (RangeYearMatcher.TryParse(value, out var rangeYearMatcher))
            {
                yearMatcher = rangeYearMatcher;
                return(true);
            }

            if (PeriodicYearMatcher.TryParse(value, out var periodYearMatcher))
            {
                yearMatcher = periodYearMatcher;
                return(true);
            }

            if (ModuloYearMatcher.TryParse(value, out var moduloYearMatcher))
            {
                yearMatcher = moduloYearMatcher;
                return(true);
            }

            if (LeapYearMatcher.TryParse(value, out var leapYearMatcher))
            {
                yearMatcher = leapYearMatcher;
                return(true);
            }

            if (NotLeapYearMatcher.TryParse(value, out var notLeapYearMatcher))
            {
                yearMatcher = notLeapYearMatcher;
                return(true);
            }

            yearMatcher = default;
            return(false);
        }
        public void CtorTests()
        {
            var obj = new PeriodicYearMatcher(2000, null, 2);

            Assert.AreEqual(2, obj.Period);

            Assert.ThrowsException <ArgumentException>(() => new PeriodicYearMatcher(2000, 2000, 2),
                                                       "Single year range invalid");
            Assert.ThrowsException <ArgumentException>(() => new PeriodicYearMatcher(2000, 3000, 1),
                                                       "Invalid period");
        }
 public void TryParseTests()
 {
     // Testing object factory
     Assert.IsTrue(PeriodicYearMatcher.TryParse("1..4/2", out var obj));
     Assert.IsNotNull(obj);
     Assert.AreEqual(1, obj.Left);
     Assert.AreEqual(4, obj.Right);
     Assert.AreEqual(2, obj.Period);
     Assert.IsTrue(PeriodicYearMatcher.TryParse("1../3", out obj));
     Assert.IsNotNull(obj);
     Assert.AreEqual(1, obj.Left);
     Assert.IsNull(obj.Right);
     Assert.AreEqual(3, obj.Period);
 }
        public void MatchTests()
        {
            var dt2000 = new DateTime(2000, 1, 1);
            var dt2001 = new DateTime(2001, 1, 1);
            var dt2002 = new DateTime(2002, 1, 1);
            var dt2003 = new DateTime(2003, 1, 1);

            var obj = new PeriodicYearMatcher(2000, null, 2);

            Assert.IsTrue(obj.Match(dt2000));
            Assert.IsFalse(obj.Match(dt2001));
            Assert.IsTrue(obj.Match(dt2002));
            Assert.IsFalse(obj.Match(dt2003));
            obj = new PeriodicYearMatcher(2001, null, 2);
            Assert.IsFalse(obj.Match(dt2000));
            Assert.IsTrue(obj.Match(dt2001));
            Assert.IsFalse(obj.Match(dt2002));
            Assert.IsTrue(obj.Match(dt2003));
            obj = new PeriodicYearMatcher(2002, null, 2);
            Assert.IsFalse(obj.Match(dt2000));
            Assert.IsFalse(obj.Match(dt2001));
            Assert.IsTrue(obj.Match(dt2002));
            Assert.IsFalse(obj.Match(dt2003));
        }