test_ops.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. """Tests for Interval-Interval operations, such as overlaps, contains, etc."""
  2. import pytest
  3. from pandas import Interval, Timedelta, Timestamp
  4. @pytest.fixture(params=[
  5. (Timedelta('0 days'), Timedelta('1 day')),
  6. (Timestamp('2018-01-01'), Timedelta('1 day')),
  7. (0, 1)], ids=lambda x: type(x[0]).__name__)
  8. def start_shift(request):
  9. """
  10. Fixture for generating intervals of types from a start value and a shift
  11. value that can be added to start to generate an endpoint
  12. """
  13. return request.param
  14. class TestOverlaps(object):
  15. def test_overlaps_self(self, start_shift, closed):
  16. start, shift = start_shift
  17. interval = Interval(start, start + shift, closed)
  18. assert interval.overlaps(interval)
  19. def test_overlaps_nested(self, start_shift, closed, other_closed):
  20. start, shift = start_shift
  21. interval1 = Interval(start, start + 3 * shift, other_closed)
  22. interval2 = Interval(start + shift, start + 2 * shift, closed)
  23. # nested intervals should always overlap
  24. assert interval1.overlaps(interval2)
  25. def test_overlaps_disjoint(self, start_shift, closed, other_closed):
  26. start, shift = start_shift
  27. interval1 = Interval(start, start + shift, other_closed)
  28. interval2 = Interval(start + 2 * shift, start + 3 * shift, closed)
  29. # disjoint intervals should never overlap
  30. assert not interval1.overlaps(interval2)
  31. def test_overlaps_endpoint(self, start_shift, closed, other_closed):
  32. start, shift = start_shift
  33. interval1 = Interval(start, start + shift, other_closed)
  34. interval2 = Interval(start + shift, start + 2 * shift, closed)
  35. # overlap if shared endpoint is closed for both (overlap at a point)
  36. result = interval1.overlaps(interval2)
  37. expected = interval1.closed_right and interval2.closed_left
  38. assert result == expected
  39. @pytest.mark.parametrize('other', [
  40. 10, True, 'foo', Timedelta('1 day'), Timestamp('2018-01-01')],
  41. ids=lambda x: type(x).__name__)
  42. def test_overlaps_invalid_type(self, other):
  43. interval = Interval(0, 1)
  44. msg = '`other` must be an Interval, got {other}'.format(
  45. other=type(other).__name__)
  46. with pytest.raises(TypeError, match=msg):
  47. interval.overlaps(other)