1/*
2 * Copyright (c) 2013, Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include <WebCore/TimeRanges.h>
33
34using namespace WebCore;
35
36namespace TestWebKitAPI {
37
38static std::string ToString(const TimeRanges& ranges)
39{
40 std::stringstream ss;
41 ss << "{";
42 for (unsigned i = 0; i < ranges.length(); ++i)
43 ss << " [" << ranges.start(i).releaseReturnValue() << "," << ranges.end(i).releaseReturnValue() << ")";
44 ss << " }";
45
46 return ss.str();
47}
48
49#define ASSERT_RANGE(expected, range) EXPECT_EQ(expected, ToString(*range))
50
51TEST(TimeRanges, Empty)
52{
53 ASSERT_RANGE("{ }", TimeRanges::create().ptr());
54}
55
56TEST(TimeRanges, SingleRange)
57{
58 ASSERT_RANGE("{ [1,2) }", TimeRanges::create(1, 2).ptr());
59}
60
61TEST(TimeRanges, AddOrder)
62{
63 RefPtr<TimeRanges> rangeA = TimeRanges::create();
64 RefPtr<TimeRanges> rangeB = TimeRanges::create();
65
66 rangeA->add(0, 2);
67 rangeA->add(3, 4);
68 rangeA->add(5, 100);
69
70 std::string expected = "{ [0,2) [3,4) [5,100) }";
71 ASSERT_RANGE(expected, rangeA);
72
73 // Add the values in rangeA to rangeB in reverse order.
74 for (int i = rangeA->length() - 1; i >= 0; --i)
75 rangeB->add(rangeA->start(i).releaseReturnValue(), rangeA->end(i).releaseReturnValue());
76
77 ASSERT_RANGE(expected, rangeB);
78}
79
80TEST(TimeRanges, OverlappingAdds)
81{
82 RefPtr<TimeRanges> ranges = TimeRanges::create();
83
84 ranges->add(0, 2);
85 ranges->add(10, 11);
86 ASSERT_RANGE("{ [0,2) [10,11) }", ranges);
87
88 ranges->add(0, 2);
89 ASSERT_RANGE("{ [0,2) [10,11) }", ranges);
90
91 ranges->add(2, 3);
92 ASSERT_RANGE("{ [0,3) [10,11) }", ranges);
93
94 ranges->add(2, 6);
95 ASSERT_RANGE("{ [0,6) [10,11) }", ranges);
96
97 ranges->add(9, 10);
98 ASSERT_RANGE("{ [0,6) [9,11) }", ranges);
99
100 ranges->add(8, 10);
101 ASSERT_RANGE("{ [0,6) [8,11) }", ranges);
102
103 ranges->add(-1, 7);
104 ASSERT_RANGE("{ [-1,7) [8,11) }", ranges);
105
106 ranges->add(6, 9);
107 ASSERT_RANGE("{ [-1,11) }", ranges);
108}
109
110TEST(TimeRanges, IntersectWith_Self)
111{
112 RefPtr<TimeRanges> ranges = TimeRanges::create(0, 2);
113
114 ASSERT_RANGE("{ [0,2) }", ranges);
115
116 ranges->intersectWith(*ranges.get());
117
118 ASSERT_RANGE("{ [0,2) }", ranges);
119}
120
121TEST(TimeRanges, IntersectWith_IdenticalRange)
122{
123 RefPtr<TimeRanges> rangesA = TimeRanges::create(0, 2);
124 RefPtr<TimeRanges> rangesB = rangesA->copy();
125
126 ASSERT_RANGE("{ [0,2) }", rangesA);
127 ASSERT_RANGE("{ [0,2) }", rangesB);
128
129 rangesA->intersectWith(*rangesB.get());
130
131 ASSERT_RANGE("{ [0,2) }", rangesA);
132 ASSERT_RANGE("{ [0,2) }", rangesB);
133}
134
135TEST(TimeRanges, IntersectWith_Empty)
136{
137 RefPtr<TimeRanges> rangesA = TimeRanges::create(0, 2);
138 RefPtr<TimeRanges> rangesB = TimeRanges::create();
139
140 ASSERT_RANGE("{ [0,2) }", rangesA);
141 ASSERT_RANGE("{ }", rangesB);
142
143 rangesA->intersectWith(*rangesB.get());
144
145 ASSERT_RANGE("{ }", rangesA);
146 ASSERT_RANGE("{ }", rangesB);
147}
148
149TEST(TimeRanges, IntersectWith_DisjointRanges1)
150{
151
152 RefPtr<TimeRanges> rangesA = TimeRanges::create();
153 RefPtr<TimeRanges> rangesB = TimeRanges::create();
154
155 rangesA->add(0, 1);
156 rangesA->add(4, 5);
157
158 rangesB->add(2, 3);
159 rangesB->add(6, 7);
160
161 ASSERT_RANGE("{ [0,1) [4,5) }", rangesA);
162 ASSERT_RANGE("{ [2,3) [6,7) }", rangesB);
163
164 rangesA->intersectWith(*rangesB.get());
165
166 ASSERT_RANGE("{ }", rangesA);
167 ASSERT_RANGE("{ [2,3) [6,7) }", rangesB);
168}
169
170TEST(TimeRanges, IntersectWith_DisjointRanges2)
171{
172 RefPtr<TimeRanges> rangesA = TimeRanges::create();
173 RefPtr<TimeRanges> rangesB = TimeRanges::create();
174
175 rangesA->add(0, 1);
176 rangesA->add(4, 5);
177
178 rangesB->add(1, 4);
179 rangesB->add(5, 7);
180
181 ASSERT_RANGE("{ [0,1) [4,5) }", rangesA);
182 ASSERT_RANGE("{ [1,4) [5,7) }", rangesB);
183
184 rangesA->intersectWith(*rangesB.get());
185
186 ASSERT_RANGE("{ }", rangesA);
187 ASSERT_RANGE("{ [1,4) [5,7) }", rangesB);
188}
189
190TEST(TimeRanges, IntersectWith_CompleteOverlap1)
191{
192 RefPtr<TimeRanges> rangesA = TimeRanges::create();
193 RefPtr<TimeRanges> rangesB = TimeRanges::create();
194
195 rangesA->add(1, 3);
196 rangesA->add(4, 5);
197 rangesA->add(6, 9);
198
199 rangesB->add(0, 10);
200
201 ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
202 ASSERT_RANGE("{ [0,10) }", rangesB);
203
204 rangesA->intersectWith(*rangesB.get());
205
206 ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
207 ASSERT_RANGE("{ [0,10) }", rangesB);
208}
209
210TEST(TimeRanges, IntersectWith_CompleteOverlap2)
211{
212 RefPtr<TimeRanges> rangesA = TimeRanges::create();
213 RefPtr<TimeRanges> rangesB = TimeRanges::create();
214
215 rangesA->add(1, 3);
216 rangesA->add(4, 5);
217 rangesA->add(6, 9);
218
219 rangesB->add(1, 9);
220
221 ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
222 ASSERT_RANGE("{ [1,9) }", rangesB);
223
224 rangesA->intersectWith(*rangesB.get());
225
226 ASSERT_RANGE("{ [1,3) [4,5) [6,9) }", rangesA);
227 ASSERT_RANGE("{ [1,9) }", rangesB);
228}
229
230TEST(TimeRanges, IntersectWith_Gaps1)
231{
232 RefPtr<TimeRanges> rangesA = TimeRanges::create();
233 RefPtr<TimeRanges> rangesB = TimeRanges::create();
234
235 rangesA->add(0, 2);
236 rangesA->add(4, 6);
237
238 rangesB->add(1, 5);
239
240 ASSERT_RANGE("{ [0,2) [4,6) }", rangesA);
241 ASSERT_RANGE("{ [1,5) }", rangesB);
242
243 rangesA->intersectWith(*rangesB.get());
244
245 ASSERT_RANGE("{ [1,2) [4,5) }", rangesA);
246 ASSERT_RANGE("{ [1,5) }", rangesB);
247}
248
249TEST(TimeRanges, IntersectWith_Gaps2)
250{
251 RefPtr<TimeRanges> rangesA = TimeRanges::create();
252 RefPtr<TimeRanges> rangesB = TimeRanges::create();
253
254 rangesA->add(0, 2);
255 rangesA->add(4, 6);
256 rangesA->add(8, 10);
257
258 rangesB->add(1, 9);
259
260 ASSERT_RANGE("{ [0,2) [4,6) [8,10) }", rangesA);
261 ASSERT_RANGE("{ [1,9) }", rangesB);
262
263 rangesA->intersectWith(*rangesB.get());
264
265 ASSERT_RANGE("{ [1,2) [4,6) [8,9) }", rangesA);
266 ASSERT_RANGE("{ [1,9) }", rangesB);
267}
268
269TEST(TimeRanges, IntersectWith_Gaps3)
270{
271 RefPtr<TimeRanges> rangesA = TimeRanges::create();
272 RefPtr<TimeRanges> rangesB = TimeRanges::create();
273
274 rangesA->add(0, 2);
275 rangesA->add(4, 7);
276 rangesA->add(8, 10);
277
278 rangesB->add(1, 5);
279 rangesB->add(6, 9);
280
281 ASSERT_RANGE("{ [0,2) [4,7) [8,10) }", rangesA);
282 ASSERT_RANGE("{ [1,5) [6,9) }", rangesB);
283
284 rangesA->intersectWith(*rangesB.get());
285
286 ASSERT_RANGE("{ [1,2) [4,5) [6,7) [8,9) }", rangesA);
287 ASSERT_RANGE("{ [1,5) [6,9) }", rangesB);
288}
289
290}
291
292