walk sequence of range boundaries values for source and filter ranges

add lower level logic for walking the boundary markers of sets
but distinguish between a source range and a filter range when
looking at the start and end boundary behavior
This commit is contained in:
2026-01-11 16:20:03 -06:00
parent 211efb5d16
commit 98a9fd43fe
3 changed files with 261 additions and 3 deletions

View File

@@ -128,3 +128,212 @@
(int-range-inclusive 5 5)
(int-range-inclusive 13 17)
(int-range-inclusive 5 5)])))))
(deftest walk-range-boundaries-test
(testing "only filter-ranges"
(is (= #{}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :filter-range
:value 1
:prev-value 0
:next-value 2
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :filter-range
:value 4
:prev-value 3
:next-value 5
:type :int-range-inclusive}]))))
(testing "only source-ranges"
(is (= #{(int-range-inclusive 1 5)}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :source-range
:value 1
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 5
:type :int-range-inclusive}])))
(is (= #{(int-range-inclusive 1 5)
(int-range-inclusive 11 15)}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :source-range
:value 1
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 5
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :source-range
:value 11
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 15
:type :int-range-inclusive}]))))
(testing "filter-ranges before source-ranges"
(is (= #{(int-range-inclusive 11 15)}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :filter-range
:value 1
:prev-value 0
:next-value 2
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :filter-range
:prev-value 4
:value 5
:next-value 6
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :source-range
:value 11
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 15
:type :int-range-inclusive}]))))
(testing "filter-ranges after source-ranges"
(is (= #{(int-range-inclusive 1 5)}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :source-range
:value 1
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 5
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :filter-range
:prev-value 10
:value 11
:next-value 12
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :filter-range
:prev-value 14
:value 15
:next-value 16
:type :int-range-inclusive}]))))
(testing "single filter-range between source-range"
(is (= #{(int-range-inclusive 1 5)
(int-range-inclusive 11 20)}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :source-range
:value 1
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :filter-range
:prev-value 5
:value 6
:next-value 7
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :filter-range
:prev-value 10
:value 10
:next-value 11
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 20
:type :int-range-inclusive}]))))
(testing "multiple filter-ranges between source-range"
(is (= #{(int-range-inclusive 1 5)
(int-range-inclusive 11 12)
(int-range-inclusive 20 20)}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :source-range
:value 1
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :filter-range
:prev-value 5
:value 6
:next-value 7
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :filter-range
:prev-value 10
:value 10
:next-value 11
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :filter-range
:prev-value 12
:value 13
:next-value 14
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :filter-range
:prev-value 18
:value 19
:next-value 20
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 20
:type :int-range-inclusive}]))))
(testing "source range between filter-range"
(is (= #{}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :filter-range
:prev-value 1
:value 1
:next-value 2
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :source-range
:value 6
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 10
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :source-range
:value 13
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 19
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :filter-range
:prev-value 19
:value 20
:next-value 21
:type :int-range-inclusive}]))))
(testing "filter range overlaps source ranges"
(is (= #{(int-range-inclusive 1 4)
(int-range-inclusive 11 13)}
(range/walk-range-boundaries [{:boundary-type :start
:range-source-type :source-range
:value 1
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :filter-range
:prev-value 4
:value 5
:next-value 6
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 6
:type :int-range-inclusive}
{:boundary-type :start
:range-source-type :source-range
:value 8
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :filter-range
:prev-value 9
:value 10
:next-value 11
:type :int-range-inclusive}
{:boundary-type :end
:range-source-type :source-range
:value 13
:type :int-range-inclusive}])))))