def test_forward_non_recurrent_random(unit, overlap):
    """`forward()` method of non-recurrent time intervals with and without
    overlapping `start` date."""
    correction = BASE[unit]

    max_ = add_delta(MAX, -1 * N, unit)

    unit_maximum = delta(MIN, max_, unit)

    interval = Interval(*sorted(randuniq(2, correction, unit_maximum)))

    if overlap:
        start = add_delta(
            MIN,
            rnd.randrange(
                int(interval.start), int(interval.stop)
            ) - correction,
            unit
        )
    else:
        start = add_delta(MIN,
                          int(interval.start) - correction,
                          unit)

    stop = add_delta(MIN, int(interval.stop) - correction + 1, unit)
    expected = [Interval(start, stop)]

    timeinterval = TimeInterval(interval, unit, None)
    actual = list(islice(timeinterval.forward(start), None, N))

    assert actual == expected
def test_forward_corner_cases(interval, unit, recurrence, start, expected):
    """Corner cases for `forward()` method."""
    timeinterval = TimeInterval(interval=interval, unit=unit,
                                recurrence=recurrence)
    actual = list(islice((e for e in timeinterval.forward(start)),
                         len(expected)))

    assert actual == expected
def test_forward_recurrent_random(unit, recurrence, overlap):
    """`forward()` method of recurrent time intervals with and without
    overlapping `start` date."""
    correction = BASE[unit]

    max_ = add_delta(MAX, -1 * N, recurrence)

    unit_maximum = delta(MIN, add_delta(MIN, 1, recurrence), unit)

    interval = Interval(*sorted(randuniq(2, correction, unit_maximum)))

    expected = []

    initial = start = floor(
        add_delta(MIN, rnd.randrange(delta(MIN, max_, unit)), unit),
        recurrence
    )

    if overlap:
        initial = start = add_delta(
            initial,
            rnd.randrange(
                int(interval.start), int(interval.stop)
            ) - correction,
            unit
        )

    for i in range(N):
        recurrence_start = floor(start, recurrence)
        first = floor(add_delta(recurrence_start,
                                interval.start - correction,
                                unit), unit)
        second = add_delta(floor(add_delta(recurrence_start,
                                 interval.stop - correction,
                                 unit),
                            unit), 1, unit)
        assert first < second
        assert start < second
        if start > first:
            first = start

        expected.append(Interval(first, second))
        start = floor(add_delta(recurrence_start, 1, recurrence), recurrence)

    timeinterval = TimeInterval(interval, unit, recurrence)
    actual = list(islice(timeinterval.forward(initial), None, N))

    assert actual == expected