public void CtorTests()
        {
            var obj = new RangeDayOfMonthMatcher(null, null);

            Assert.IsNotNull(obj, "Any day");
            Assert.IsNull(obj.Left);
            Assert.IsNull(obj.Right);

            obj = new RangeDayOfMonthMatcher(1, null);
            Assert.IsNotNull(obj);
            Assert.AreEqual(1, obj.Left.Value);
            Assert.IsNull(obj.Right);

            obj = new RangeDayOfMonthMatcher(null, 31);
            Assert.IsNotNull(obj);
            Assert.IsNull(obj.Left);
            Assert.AreEqual(31, obj.Right.Value);

            obj = new RangeDayOfMonthMatcher(1, 1);
            Assert.IsNotNull(obj, "Exact day");
            Assert.AreEqual(1, obj.Left.Value);
            Assert.AreEqual(1, obj.Right.Value);

            obj = new RangeDayOfMonthMatcher(1, 31);
            Assert.IsNotNull(obj, "Finite range");
            Assert.AreEqual(1, obj.Left.Value);
            Assert.AreEqual(31, obj.Right.Value);

            Assert.ThrowsException <ArgumentOutOfRangeException>(() => new RangeDayOfMonthMatcher(0, null));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => new RangeDayOfMonthMatcher(null, 0));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => new RangeDayOfMonthMatcher(32, null));
            Assert.ThrowsException <ArgumentOutOfRangeException>(() => new RangeDayOfMonthMatcher(null, 32));
        }
 public void TryParseTests()
 {
     // Testing object factory
     Assert.IsTrue(RangeDayOfMonthMatcher.TryParse("1..4", out var obj));
     Assert.IsNotNull(obj);
     Assert.AreEqual(1, obj.Left);
     Assert.AreEqual(4, obj.Right);
     Assert.IsTrue(RangeDayOfMonthMatcher.TryParse("*", out obj));
     Assert.IsNotNull(obj);
     Assert.AreEqual(1, obj.Left);
     Assert.AreEqual(31, obj.Right);
 }
        public void MatchTests()
        {
            var d1 = new DateTime(2000, 1, 1);
            var d2 = new DateTime(2000, 1, 2);
            var d3 = new DateTime(2000, 1, 3);
            var d4 = new DateTime(2000, 1, 4);
            var d5 = new DateTime(2000, 1, 5);

            var obj = new RangeDayOfMonthMatcher(null, null);

            Assert.IsTrue(obj.Match(d1));
            Assert.IsTrue(obj.Match(d2));
            Assert.IsTrue(obj.Match(d3));
            Assert.IsTrue(obj.Match(d4));
            Assert.IsTrue(obj.Match(d5));

            obj = new RangeDayOfMonthMatcher(2, null);
            Assert.IsFalse(obj.Match(d1));
            Assert.IsTrue(obj.Match(d2));
            Assert.IsTrue(obj.Match(d3));
            Assert.IsTrue(obj.Match(d4));
            Assert.IsTrue(obj.Match(d5));

            obj = new RangeDayOfMonthMatcher(null, 2);
            Assert.IsTrue(obj.Match(d1));
            Assert.IsTrue(obj.Match(d2));
            Assert.IsFalse(obj.Match(d3));
            Assert.IsFalse(obj.Match(d4));
            Assert.IsFalse(obj.Match(d5));

            obj = new RangeDayOfMonthMatcher(2, 2);
            Assert.IsFalse(obj.Match(d1));
            Assert.IsTrue(obj.Match(d2));
            Assert.IsFalse(obj.Match(d3));
            Assert.IsFalse(obj.Match(d4));
            Assert.IsFalse(obj.Match(d5));

            obj = new RangeDayOfMonthMatcher(2, 4);
            Assert.IsFalse(obj.Match(d1));
            Assert.IsTrue(obj.Match(d2));
            Assert.IsTrue(obj.Match(d3));
            Assert.IsTrue(obj.Match(d4));
            Assert.IsFalse(obj.Match(d5));
        }
        public void OpenRangeCheckTests()
        {
            var obj = new RangeDayOfMonthMatcher(null, null);

            Assert.IsTrue(obj.IsLeftOpenRange);
            Assert.IsTrue(obj.IsRightOpenRange);
            Assert.IsTrue(obj.IsOpenRange);
            Assert.IsTrue(obj.IsLeftRightOpenRange);
            Assert.IsFalse(obj.IsClosedRange);
            Assert.IsFalse(obj.IsOneDay);

            obj = new RangeDayOfMonthMatcher(1, null);
            Assert.IsFalse(obj.IsLeftOpenRange);
            Assert.IsTrue(obj.IsRightOpenRange);
            Assert.IsTrue(obj.IsOpenRange);
            Assert.IsFalse(obj.IsLeftRightOpenRange);
            Assert.IsFalse(obj.IsClosedRange);
            Assert.IsFalse(obj.IsOneDay);

            obj = new RangeDayOfMonthMatcher(null, 31);
            Assert.IsTrue(obj.IsLeftOpenRange);
            Assert.IsFalse(obj.IsRightOpenRange);
            Assert.IsTrue(obj.IsOpenRange);
            Assert.IsFalse(obj.IsLeftRightOpenRange);
            Assert.IsFalse(obj.IsClosedRange);
            Assert.IsFalse(obj.IsOneDay);

            obj = new RangeDayOfMonthMatcher(11, 11);
            Assert.IsFalse(obj.IsLeftOpenRange);
            Assert.IsFalse(obj.IsRightOpenRange);
            Assert.IsFalse(obj.IsOpenRange);
            Assert.IsFalse(obj.IsLeftRightOpenRange);
            Assert.IsTrue(obj.IsClosedRange);
            Assert.IsTrue(obj.IsOneDay);

            obj = new RangeDayOfMonthMatcher(1, 31);
            Assert.IsFalse(obj.IsLeftOpenRange);
            Assert.IsFalse(obj.IsRightOpenRange);
            Assert.IsFalse(obj.IsOpenRange);
            Assert.IsFalse(obj.IsLeftRightOpenRange);
            Assert.IsTrue(obj.IsClosedRange);
            Assert.IsFalse(obj.IsOneDay);
        }
        /// <summary>
        ///     Parse a day of month match expression.
        ///     <example>
        ///         Valid expression are:
        ///         * => Every month
        ///         11 => Only the day 11
        ///         ..11 => Every day from 1 to 11
        ///         2.. => Every day from 2 to 31
        ///         2..11 => Every day between 2 and 11
        ///         1..7/2 => Starting from day 1 every 2 days until the 7th
        ///         3../2 => Starting from day 3 every 2 days till the end of the month
        ///         1..7%2 => Every day which reminder modulo 2 is zero between the 1st and 7th
        ///         2..%3 => Starting from the 2nd every day which reminder modulo 3 is zero
        ///     </example>
        /// </summary>
        public override bool TryParse(string value, out IDayOfMonthMatcher dayOfMonthMatcher)
        {
            if (RangeDayOfMonthMatcher.TryParse(value, out var rangeDayOfMonthMatcher))
            {
                dayOfMonthMatcher = rangeDayOfMonthMatcher;
                return(true);
            }

            if (ModuloDayOfMonthMatcher.TryParse(value, out var moduloDayOfMonthMatcher))
            {
                dayOfMonthMatcher = moduloDayOfMonthMatcher;
                return(true);
            }

            if (PeriodicDayOfMonthMatcher.TryParse(value, out var periodicDayOfMonthMatcher))
            {
                dayOfMonthMatcher = periodicDayOfMonthMatcher;
                return(true);
            }

            dayOfMonthMatcher = default;
            return(false);
        }