Fix seek in linearly interpolated control lists.
[ardour.git] / libs / evoral / test / RangeTest.cpp
1 #include "RangeTest.hpp"
2 #include "evoral/Range.hpp"
3 #include <stdlib.h>
4
5 CPPUNIT_TEST_SUITE_REGISTRATION (RangeTest);
6
7 using namespace Evoral;
8
9 void
10 RangeTest::coalesceTest ()
11 {
12         RangeList<int> fred;
13         fred.add (Range<int> (2, 4));
14         fred.add (Range<int> (5, 6));
15         fred.add (Range<int> (6, 8));
16
17         RangeList<int>::List jim = fred.get ();
18
19         RangeList<int>::List::iterator i = jim.begin ();
20         CPPUNIT_ASSERT_EQUAL (2, i->from);
21         CPPUNIT_ASSERT_EQUAL (4, i->to);
22
23         ++i;
24         CPPUNIT_ASSERT_EQUAL (5, i->from);
25         CPPUNIT_ASSERT_EQUAL (8, i->to);
26 }
27
28 /* Basic subtraction of a few smaller ranges from a larger one */
29 void
30 RangeTest::subtractTest1 ()
31 {
32
33 /*         01234567890
34  * fred:   |---------|
35  * jim:      |-|  ||
36  * sheila: ||   ||  ||
37  */
38
39         Range<int> fred (0, 10);
40
41         RangeList<int> jim;
42         jim.add (Range<int> (2, 4));
43         jim.add (Range<int> (7, 8));
44
45         RangeList<int> sheila = subtract (fred, jim);
46
47         RangeList<int>::List s = sheila.get ();
48         CPPUNIT_ASSERT_EQUAL (size_t (3), s.size ());
49
50         RangeList<int>::List::iterator i = s.begin ();
51         CPPUNIT_ASSERT_EQUAL (0, i->from);
52         CPPUNIT_ASSERT_EQUAL (1, i->to);
53
54         ++i;
55         CPPUNIT_ASSERT_EQUAL (5, i->from);
56         CPPUNIT_ASSERT_EQUAL (6, i->to);
57
58         ++i;
59         CPPUNIT_ASSERT_EQUAL (9, i->from);
60         CPPUNIT_ASSERT_EQUAL (10, i->to);
61 }
62
63 /* Test subtraction of a range B from a range A, where A and B do not overlap */
64 void
65 RangeTest::subtractTest2 ()
66 {
67         Range<int> fred (0, 10);
68
69         RangeList<int> jim;
70         jim.add (Range<int> (12, 19));
71
72         RangeList<int> sheila = subtract (fred, jim);
73
74         RangeList<int>::List s = sheila.get ();
75         CPPUNIT_ASSERT_EQUAL (size_t (1), s.size ());
76
77         RangeList<int>::List::iterator i = s.begin ();
78         CPPUNIT_ASSERT_EQUAL (0, i->from);
79         CPPUNIT_ASSERT_EQUAL (10, i->to);
80 }
81
82 /* Test subtraction of B from A, where B entirely overlaps A */
83 void
84 RangeTest::subtractTest3 ()
85 {
86         Range<int> fred (0, 10);
87
88         RangeList<int> jim;
89         jim.add (Range<int> (0, 12));
90
91         RangeList<int> sheila = subtract (fred, jim);
92
93         RangeList<int>::List s = sheila.get ();
94         CPPUNIT_ASSERT_EQUAL (size_t (0), s.size ());
95 }
96
97 /* A bit like subtractTest1, except some of the ranges
98    we are subtracting overlap.
99 */
100 void
101 RangeTest::subtractTest4 ()
102 {
103 /*         01234567890
104  * fred:   |---------|
105  * jim:      |-|  ||
106  *                 ||
107  * sheila: ||   ||   |
108  */
109
110         Range<int> fred (0, 10);
111
112         RangeList<int> jim;
113         jim.add (Range<int> (2, 4));
114         jim.add (Range<int> (7, 8));
115         jim.add (Range<int> (8, 9));
116
117         RangeList<int> sheila = subtract (fred, jim);
118
119         RangeList<int>::List s = sheila.get ();
120         CPPUNIT_ASSERT_EQUAL (size_t (3), s.size ());
121
122         RangeList<int>::List::iterator i = s.begin ();
123         CPPUNIT_ASSERT_EQUAL (0, i->from);
124         CPPUNIT_ASSERT_EQUAL (1, i->to);
125
126         ++i;
127         CPPUNIT_ASSERT_EQUAL (5, i->from);
128         CPPUNIT_ASSERT_EQUAL (6, i->to);
129
130         ++i;
131         CPPUNIT_ASSERT_EQUAL (10, i->from);
132         CPPUNIT_ASSERT_EQUAL (10, i->to);
133 }
134
135 /* A bit like subtractTest1, except some of the ranges
136    we are subtracting overlap the start / end of the
137    initial range.
138 */
139 void
140 RangeTest::subtractTest5 ()
141 {
142 /*         01234567890123
143  * fred:    |----------|
144  * jim:    |---| || |------...
145  * sheila:i     |  |
146  */
147
148         Range<int> fred (1, 12);
149
150         RangeList<int> jim;
151         jim.add (Range<int> (0, 4));
152         jim.add (Range<int> (6, 7));
153         jim.add (Range<int> (9, 42));
154
155         RangeList<int> sheila = subtract (fred, jim);
156
157         RangeList<int>::List s = sheila.get ();
158         CPPUNIT_ASSERT_EQUAL (size_t (2), s.size ());
159
160         RangeList<int>::List::iterator i = s.begin ();
161         CPPUNIT_ASSERT_EQUAL (5, i->from);
162         CPPUNIT_ASSERT_EQUAL (5, i->to);
163
164         ++i;
165         CPPUNIT_ASSERT_EQUAL (8, i->from);
166         CPPUNIT_ASSERT_EQUAL (8, i->to);
167 }
168
169 /* Test coverage() with all possible types of overlap.
170  */
171
172 void
173 RangeTest::coverageTest ()
174 {
175
176         // b starts before a
177         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 1, 1), Evoral::OverlapNone);
178         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 1, 2), Evoral::OverlapNone);
179         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 1, 3), Evoral::OverlapStart);
180         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 1, 5), Evoral::OverlapStart);
181         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 1, 7), Evoral::OverlapExternal);
182         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 1, 9), Evoral::OverlapExternal);
183
184         // b starts at a
185         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 3, 3), Evoral::OverlapStart);
186         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 3, 5), Evoral::OverlapStart);
187         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 3, 7), Evoral::OverlapExternal);
188         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 3, 9), Evoral::OverlapExternal);
189
190         // b starts inside a
191         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 4, 4), Evoral::OverlapInternal);
192         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 4, 6), Evoral::OverlapInternal);
193         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 4, 7), Evoral::OverlapEnd);
194         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 4, 8), Evoral::OverlapEnd);
195
196         // b starts at end of a
197         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 7, 7), Evoral::OverlapEnd);
198         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 7, 9), Evoral::OverlapEnd);
199
200         // b starts after end of a
201         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 8, 8), Evoral::OverlapNone);
202         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 8, 9), Evoral::OverlapNone);
203
204         // zero-length range a
205         CPPUNIT_ASSERT_EQUAL (coverage(3, 3, 2, 4), Evoral::OverlapExternal);
206         CPPUNIT_ASSERT_EQUAL (coverage(3, 3, 1, 2), Evoral::OverlapNone);
207         CPPUNIT_ASSERT_EQUAL (coverage(3, 3, 3, 3), Evoral::OverlapExternal);
208         CPPUNIT_ASSERT_EQUAL (coverage(3, 3, 8, 9), Evoral::OverlapNone);
209
210         // negative length range a
211         // XXX these are debatable - should we just consider start & end to be
212         // swapped if end < start?
213         CPPUNIT_ASSERT_EQUAL (coverage(4, 3, 1, 2), Evoral::OverlapNone);
214         CPPUNIT_ASSERT_EQUAL (coverage(4, 3, 2, 3), Evoral::OverlapNone);
215         CPPUNIT_ASSERT_EQUAL (coverage(4, 3, 2, 4), Evoral::OverlapNone);
216         CPPUNIT_ASSERT_EQUAL (coverage(4, 3, 3, 3), Evoral::OverlapNone);
217         CPPUNIT_ASSERT_EQUAL (coverage(4, 3, 8, 9), Evoral::OverlapNone);
218
219         // negative length range b
220         // b starts before a
221         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 1, 0), Evoral::OverlapNone);
222         // b starts at a
223         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 3, 2), Evoral::OverlapNone);
224         // b starts inside a
225         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 4, 3), Evoral::OverlapNone);
226         // b starts at end of a
227         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 7, 5), Evoral::OverlapNone);
228         // b starts after end of a
229         CPPUNIT_ASSERT_EQUAL (coverage(3, 7, 8, 7), Evoral::OverlapNone);
230
231 }