Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/media/gtest/TestIntervalSet.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "gtest/gtest.h"
7
#include "mozilla/dom/TimeRanges.h"
8
#include "TimeUnits.h"
9
#include "Intervals.h"
10
#include <algorithm>
11
#include <vector>
12
13
using namespace mozilla;
14
15
typedef media::Interval<uint8_t> ByteInterval;
16
typedef media::Interval<int> IntInterval;
17
typedef media::IntervalSet<int> IntIntervals;
18
19
ByteInterval CreateByteInterval(int32_t aStart, int32_t aEnd)
20
0
{
21
0
  ByteInterval test(aStart, aEnd);
22
0
  return test;
23
0
}
24
25
media::IntervalSet<uint8_t> CreateByteIntervalSet(int32_t aStart, int32_t aEnd)
26
0
{
27
0
  media::IntervalSet<uint8_t> test;
28
0
  test += ByteInterval(aStart, aEnd);
29
0
  return test;
30
0
}
31
32
TEST(IntervalSet, Constructors)
33
0
{
34
0
  const int32_t start = 1;
35
0
  const int32_t end = 2;
36
0
  const int32_t fuzz = 0;
37
0
38
0
  // Compiler exercise.
39
0
  ByteInterval test1(start, end);
40
0
  ByteInterval test2(test1);
41
0
  ByteInterval test3(start, end, fuzz);
42
0
  ByteInterval test4(test3);
43
0
  ByteInterval test5 = CreateByteInterval(start, end);
44
0
45
0
  media::IntervalSet<uint8_t> blah1(test1);
46
0
  media::IntervalSet<uint8_t> blah2 = blah1;
47
0
  media::IntervalSet<uint8_t> blah3 = blah1 + test1;
48
0
  media::IntervalSet<uint8_t> blah4 = test1 + blah1;
49
0
  media::IntervalSet<uint8_t> blah5 = CreateByteIntervalSet(start, end);
50
0
  (void)test1; (void)test2; (void)test3; (void)test4; (void)test5;
51
0
  (void)blah1; (void)blah2; (void)blah3; (void)blah4; (void)blah5;
52
0
}
53
54
media::TimeInterval CreateTimeInterval(int32_t aStart, int32_t aEnd)
55
0
{
56
0
  // Copy constructor test
57
0
  media::TimeUnit start = media::TimeUnit::FromMicroseconds(aStart);
58
0
  media::TimeUnit end;
59
0
  // operator=  test
60
0
  end = media::TimeUnit::FromMicroseconds(aEnd);
61
0
  media::TimeInterval ti(start, end);
62
0
  return ti;
63
0
}
64
65
media::TimeIntervals CreateTimeIntervals(int32_t aStart, int32_t aEnd)
66
0
{
67
0
  media::TimeIntervals test;
68
0
  test += CreateTimeInterval(aStart, aEnd);
69
0
  return test;
70
0
}
71
72
TEST(IntervalSet, TimeIntervalsConstructors)
73
0
{
74
0
  const auto start = media::TimeUnit::FromMicroseconds(1);
75
0
  const auto end = media::TimeUnit::FromMicroseconds(2);
76
0
  const media::TimeUnit fuzz;
77
0
78
0
  // Compiler exercise.
79
0
  media::TimeInterval test1(start, end);
80
0
  media::TimeInterval test2(test1);
81
0
  media::TimeInterval test3(start, end, fuzz);
82
0
  media::TimeInterval test4(test3);
83
0
  media::TimeInterval test5 =
84
0
    CreateTimeInterval(start.ToMicroseconds(), end.ToMicroseconds());
85
0
86
0
  media::TimeIntervals blah1(test1);
87
0
  media::TimeIntervals blah2(blah1);
88
0
  media::TimeIntervals blah3 = blah1 + test1;
89
0
  media::TimeIntervals blah4 = test1 + blah1;
90
0
  media::TimeIntervals blah5 =
91
0
    CreateTimeIntervals(start.ToMicroseconds(), end.ToMicroseconds());
92
0
  (void)test1; (void)test2; (void)test3; (void)test4; (void)test5;
93
0
  (void)blah1; (void)blah2; (void)blah3; (void)blah4; (void)blah5;
94
0
95
0
  media::TimeIntervals i0{media::TimeInterval(media::TimeUnit::FromSeconds(0),
96
0
                                              media::TimeUnit::FromSeconds(0))};
97
0
  EXPECT_EQ(0u, i0.Length()); // Constructing with an empty time interval.
98
0
}
99
100
TEST(IntervalSet, Length)
101
0
{
102
0
  IntInterval i(15, 25);
103
0
  EXPECT_EQ(10, i.Length());
104
0
}
105
106
TEST(IntervalSet, Intersects)
107
0
{
108
0
  EXPECT_TRUE(IntInterval(1,5).Intersects(IntInterval(3,4)));
109
0
  EXPECT_TRUE(IntInterval(1,5).Intersects(IntInterval(3,7)));
110
0
  EXPECT_TRUE(IntInterval(1,5).Intersects(IntInterval(-1,3)));
111
0
  EXPECT_TRUE(IntInterval(1,5).Intersects(IntInterval(-1,7)));
112
0
  EXPECT_FALSE(IntInterval(1,5).Intersects(IntInterval(6,7)));
113
0
  EXPECT_FALSE(IntInterval(1,5).Intersects(IntInterval(-1,0)));
114
0
  // End boundary is exclusive of the interval.
115
0
  EXPECT_FALSE(IntInterval(1,5).Intersects(IntInterval(5,7)));
116
0
  EXPECT_FALSE(IntInterval(1,5).Intersects(IntInterval(0,1)));
117
0
  // Empty identical interval do not intersect.
118
0
  EXPECT_FALSE(IntInterval(1,1).Intersects(IntInterval(1,1)));
119
0
  // Empty interval do not intersect.
120
0
  EXPECT_FALSE(IntInterval(1,1).Intersects(IntInterval(2,2)));
121
0
}
122
123
TEST(IntervalSet, Intersection)
124
0
{
125
0
  IntInterval i0(10, 20);
126
0
  IntInterval i1(15, 25);
127
0
  IntInterval i = i0.Intersection(i1);
128
0
  EXPECT_EQ(15, i.mStart);
129
0
  EXPECT_EQ(20, i.mEnd);
130
0
  IntInterval j0(10, 20);
131
0
  IntInterval j1(20, 25);
132
0
  IntInterval j = j0.Intersection(j1);
133
0
  EXPECT_TRUE(j.IsEmpty());
134
0
  IntInterval k0(2, 2);
135
0
  IntInterval k1(2, 2);
136
0
  IntInterval k = k0.Intersection(k1);
137
0
  EXPECT_TRUE(k.IsEmpty());
138
0
}
139
140
TEST(IntervalSet, Equals)
141
0
{
142
0
  IntInterval i0(10, 20);
143
0
  IntInterval i1(10, 20);
144
0
  EXPECT_EQ(i0, i1);
145
0
146
0
  IntInterval i2(5, 20);
147
0
  EXPECT_NE(i0, i2);
148
0
149
0
  IntInterval i3(10, 15);
150
0
  EXPECT_NE(i0, i2);
151
0
}
152
153
TEST(IntervalSet, IntersectionIntervalSet)
154
0
{
155
0
  IntIntervals i0;
156
0
  i0 += IntInterval(5, 10);
157
0
  i0 += IntInterval(20, 25);
158
0
  i0 += IntInterval(40, 60);
159
0
160
0
  IntIntervals i1;
161
0
  i1.Add(IntInterval(7, 15));
162
0
  i1.Add(IntInterval(16, 27));
163
0
  i1.Add(IntInterval(45, 50));
164
0
  i1.Add(IntInterval(53, 57));
165
0
166
0
  IntIntervals i = media::Intersection(i0, i1);
167
0
168
0
  EXPECT_EQ(4u, i.Length());
169
0
170
0
  EXPECT_EQ(7, i[0].mStart);
171
0
  EXPECT_EQ(10, i[0].mEnd);
172
0
173
0
  EXPECT_EQ(20, i[1].mStart);
174
0
  EXPECT_EQ(25, i[1].mEnd);
175
0
176
0
  EXPECT_EQ(45, i[2].mStart);
177
0
  EXPECT_EQ(50, i[2].mEnd);
178
0
179
0
  EXPECT_EQ(53, i[3].mStart);
180
0
  EXPECT_EQ(57, i[3].mEnd);
181
0
}
182
183
template<typename T>
184
static void Compare(const media::IntervalSet<T>& aI1,
185
                    const media::IntervalSet<T>& aI2)
186
0
{
187
0
  EXPECT_EQ(aI1.Length(), aI2.Length());
188
0
  if (aI1.Length() != aI2.Length()) {
189
0
    return;
190
0
  }
191
0
  for (uint32_t i = 0; i < aI1.Length(); i++) {
192
0
    EXPECT_EQ(aI1[i].mStart, aI2[i].mStart);
193
0
    EXPECT_EQ(aI1[i].mEnd, aI2[i].mEnd);
194
0
  }
195
0
}
196
197
static void GeneratePermutations(const IntIntervals& aI1,
198
                                 const IntIntervals& aI2)
199
0
{
200
0
  IntIntervals i_ref = media::Intersection(aI1, aI2);
201
0
  // Test all permutations possible
202
0
  std::vector<uint32_t> comb1;
203
0
  for (uint32_t i = 0; i < aI1.Length(); i++) {
204
0
    comb1.push_back(i);
205
0
  }
206
0
  std::vector<uint32_t> comb2;
207
0
  for (uint32_t i = 0; i < aI2.Length(); i++) {
208
0
    comb2.push_back(i);
209
0
  }
210
0
211
0
  do {
212
0
    do {
213
0
      // Create intervals according to new indexes.
214
0
      IntIntervals i_0;
215
0
      for (uint32_t i = 0; i < comb1.size(); i++) {
216
0
        i_0 += aI1[comb1[i]];
217
0
      }
218
0
      // Test that intervals are always normalized.
219
0
      Compare(aI1, i_0);
220
0
      IntIntervals i_1;
221
0
      for (uint32_t i = 0; i < comb2.size(); i++) {
222
0
        i_1 += aI2[comb2[i]];
223
0
      }
224
0
      Compare(aI2, i_1);
225
0
      // Check intersections yield the same result.
226
0
      Compare(i_0.Intersection(i_1), i_ref);
227
0
    } while (std::next_permutation(comb2.begin(), comb2.end()));
228
0
  } while (std::next_permutation(comb1.begin(), comb1.end()));
229
0
}
230
231
TEST(IntervalSet, IntersectionNormalizedIntervalSet)
232
0
{
233
0
  IntIntervals i0;
234
0
  i0 += IntInterval(5, 10);
235
0
  i0 += IntInterval(20, 25);
236
0
  i0 += IntInterval(40, 60);
237
0
238
0
  IntIntervals i1;
239
0
  i1.Add(IntInterval(7, 15));
240
0
  i1.Add(IntInterval(16, 27));
241
0
  i1.Add(IntInterval(45, 50));
242
0
  i1.Add(IntInterval(53, 57));
243
0
244
0
  GeneratePermutations(i0, i1);
245
0
}
246
247
TEST(IntervalSet, IntersectionUnorderedNonNormalizedIntervalSet)
248
0
{
249
0
  IntIntervals i0;
250
0
  i0 += IntInterval(5, 10);
251
0
  i0 += IntInterval(8, 25);
252
0
  i0 += IntInterval(24, 60);
253
0
254
0
  IntIntervals i1;
255
0
  i1.Add(IntInterval(7, 15));
256
0
  i1.Add(IntInterval(10, 27));
257
0
  i1.Add(IntInterval(45, 50));
258
0
  i1.Add(IntInterval(53, 57));
259
0
260
0
  GeneratePermutations(i0, i1);
261
0
}
262
263
TEST(IntervalSet, IntersectionNonNormalizedInterval)
264
0
{
265
0
  IntIntervals i0;
266
0
  i0 += IntInterval(5, 10);
267
0
  i0 += IntInterval(8, 25);
268
0
  i0 += IntInterval(30, 60);
269
0
270
0
  media::Interval<int> i1(9, 15);
271
0
  i0.Intersection(i1);
272
0
  EXPECT_EQ(1u, i0.Length());
273
0
  EXPECT_EQ(i0[0].mStart, i1.mStart);
274
0
  EXPECT_EQ(i0[0].mEnd, i1.mEnd);
275
0
}
276
277
TEST(IntervalSet, IntersectionUnorderedNonNormalizedInterval)
278
0
{
279
0
  IntIntervals i0;
280
0
  i0 += IntInterval(1, 3);
281
0
  i0 += IntInterval(1, 10);
282
0
  i0 += IntInterval(9, 12);
283
0
  i0 += IntInterval(12, 15);
284
0
  i0 += IntInterval(8, 25);
285
0
  i0 += IntInterval(30, 60);
286
0
  i0 += IntInterval(5, 10);
287
0
  i0 += IntInterval(30, 60);
288
0
289
0
  media::Interval<int> i1(9, 15);
290
0
  i0.Intersection(i1);
291
0
  EXPECT_EQ(1u, i0.Length());
292
0
  EXPECT_EQ(i0[0].mStart, i1.mStart);
293
0
  EXPECT_EQ(i0[0].mEnd, i1.mEnd);
294
0
}
295
296
static IntIntervals Duplicate(const IntIntervals& aValue)
297
0
{
298
0
  IntIntervals value(aValue);
299
0
  return value;
300
0
}
301
302
TEST(IntervalSet, Normalize)
303
0
{
304
0
  IntIntervals i;
305
0
  // Test IntervalSet<T> + Interval<T> operator.
306
0
  i = i + IntInterval(20, 30);
307
0
  // Test Internal<T> + IntervalSet<T> operator.
308
0
  i = IntInterval(2, 7) + i;
309
0
  // Test Interval<T> + IntervalSet<T> operator
310
0
  i = IntInterval(1, 8) + i;
311
0
  IntIntervals interval;
312
0
  interval += IntInterval(5, 10);
313
0
  // Test += with rval move.
314
0
  i += Duplicate(interval);
315
0
  // Test = with move and add with move.
316
0
  i = Duplicate(interval) + i;
317
0
318
0
  EXPECT_EQ(2u, i.Length());
319
0
320
0
  EXPECT_EQ(1, i[0].mStart);
321
0
  EXPECT_EQ(10, i[0].mEnd);
322
0
323
0
  EXPECT_EQ(20, i[1].mStart);
324
0
  EXPECT_EQ(30, i[1].mEnd);
325
0
326
0
  media::TimeIntervals ti;
327
0
  ti += media::TimeInterval(media::TimeUnit::FromSeconds(0.0),
328
0
                            media::TimeUnit::FromSeconds(3.203333));
329
0
  ti += media::TimeInterval(media::TimeUnit::FromSeconds(3.203366),
330
0
                            media::TimeUnit::FromSeconds(10.010065));
331
0
  EXPECT_EQ(2u, ti.Length());
332
0
  ti += media::TimeInterval(ti.Start(0), ti.End(0), media::TimeUnit::FromMicroseconds(35000));
333
0
  EXPECT_EQ(1u, ti.Length());
334
0
}
335
336
TEST(IntervalSet, ContainValue)
337
0
{
338
0
  IntIntervals i0;
339
0
  i0 += IntInterval(0, 10);
340
0
  i0 += IntInterval(15, 20);
341
0
  i0 += IntInterval(30, 50);
342
0
  EXPECT_TRUE(i0.Contains(0)); // start is inclusive.
343
0
  EXPECT_TRUE(i0.Contains(17));
344
0
  EXPECT_FALSE(i0.Contains(20)); // end boundary is exclusive.
345
0
  EXPECT_FALSE(i0.Contains(25));
346
0
}
347
348
TEST(IntervalSet, ContainValueWithFuzz)
349
0
{
350
0
  IntIntervals i0;
351
0
  i0 += IntInterval(0, 10);
352
0
  i0 += IntInterval(15, 20, 1);
353
0
  i0 += IntInterval(30, 50);
354
0
  EXPECT_TRUE(i0.Contains(0)); // start is inclusive.
355
0
  EXPECT_TRUE(i0.Contains(17));
356
0
  EXPECT_TRUE(i0.Contains(20)); // end boundary is exclusive but we have a fuzz of 1.
357
0
  EXPECT_FALSE(i0.Contains(25));
358
0
}
359
360
TEST(IntervalSet, ContainInterval)
361
0
{
362
0
  IntIntervals i0;
363
0
  i0 += IntInterval(0, 10);
364
0
  i0 += IntInterval(15, 20);
365
0
  i0 += IntInterval(30, 50);
366
0
  EXPECT_TRUE(i0.Contains(IntInterval(2, 8)));
367
0
  EXPECT_TRUE(i0.Contains(IntInterval(31, 50)));
368
0
  EXPECT_TRUE(i0.Contains(IntInterval(0, 10)));
369
0
  EXPECT_FALSE(i0.Contains(IntInterval(0, 11)));
370
0
  EXPECT_TRUE(i0.Contains(IntInterval(0, 5)));
371
0
  EXPECT_FALSE(i0.Contains(IntInterval(8, 15)));
372
0
  EXPECT_FALSE(i0.Contains(IntInterval(15, 30)));
373
0
  EXPECT_FALSE(i0.Contains(IntInterval(30, 55)));
374
0
}
375
376
TEST(IntervalSet, ContainIntervalWithFuzz)
377
0
{
378
0
  IntIntervals i0;
379
0
  i0 += IntInterval(0, 10);
380
0
  i0 += IntInterval(15, 20);
381
0
  i0 += IntInterval(30, 50);
382
0
  EXPECT_TRUE(i0.Contains(IntInterval(2, 8)));
383
0
  EXPECT_TRUE(i0.Contains(IntInterval(31, 50)));
384
0
  EXPECT_TRUE(i0.Contains(IntInterval(0, 11, 1)));
385
0
  EXPECT_TRUE(i0.Contains(IntInterval(0, 5)));
386
0
  EXPECT_FALSE(i0.Contains(IntInterval(8, 15)));
387
0
  EXPECT_FALSE(i0.Contains(IntInterval(15, 21)));
388
0
  EXPECT_FALSE(i0.Contains(IntInterval(15, 30)));
389
0
  EXPECT_FALSE(i0.Contains(IntInterval(30, 55)));
390
0
391
0
  IntIntervals i1;
392
0
  i1 += IntInterval(0, 10, 1);
393
0
  i1 += IntInterval(15, 20, 1);
394
0
  i1 += IntInterval(30, 50, 1);
395
0
  EXPECT_TRUE(i1.Contains(IntInterval(2, 8)));
396
0
  EXPECT_TRUE(i1.Contains(IntInterval(29, 51)));
397
0
  EXPECT_TRUE(i1.Contains(IntInterval(0, 11, 1)));
398
0
  EXPECT_TRUE(i1.Contains(IntInterval(15, 21)));
399
0
}
400
401
TEST(IntervalSet, Span)
402
0
{
403
0
  IntInterval i0(0,10);
404
0
  IntInterval i1(20,30);
405
0
  IntInterval i{i0.Span(i1)};
406
0
407
0
  EXPECT_EQ(i.mStart, 0);
408
0
  EXPECT_EQ(i.mEnd, 30);
409
0
}
410
411
TEST(IntervalSet, Union)
412
0
{
413
0
  IntIntervals i0;
414
0
  i0 += IntInterval(5, 10);
415
0
  i0 += IntInterval(20, 25);
416
0
  i0 += IntInterval(40, 60);
417
0
418
0
  IntIntervals i1;
419
0
  i1.Add(IntInterval(7, 15));
420
0
  i1.Add(IntInterval(16, 27));
421
0
  i1.Add(IntInterval(45, 50));
422
0
  i1.Add(IntInterval(53, 57));
423
0
424
0
  IntIntervals i = media::Union(i0, i1);
425
0
426
0
  EXPECT_EQ(3u, i.Length());
427
0
428
0
  EXPECT_EQ(5, i[0].mStart);
429
0
  EXPECT_EQ(15, i[0].mEnd);
430
0
431
0
  EXPECT_EQ(16, i[1].mStart);
432
0
  EXPECT_EQ(27, i[1].mEnd);
433
0
434
0
  EXPECT_EQ(40, i[2].mStart);
435
0
  EXPECT_EQ(60, i[2].mEnd);
436
0
}
437
438
TEST(IntervalSet, UnionNotOrdered)
439
0
{
440
0
  IntIntervals i0;
441
0
  i0 += IntInterval(20, 25);
442
0
  i0 += IntInterval(40, 60);
443
0
  i0 += IntInterval(5, 10);
444
0
445
0
  IntIntervals i1;
446
0
  i1.Add(IntInterval(16, 27));
447
0
  i1.Add(IntInterval(7, 15));
448
0
  i1.Add(IntInterval(53, 57));
449
0
  i1.Add(IntInterval(45, 50));
450
0
451
0
  IntIntervals i = media::Union(i0, i1);
452
0
453
0
  EXPECT_EQ(3u, i.Length());
454
0
455
0
  EXPECT_EQ(5, i[0].mStart);
456
0
  EXPECT_EQ(15, i[0].mEnd);
457
0
458
0
  EXPECT_EQ(16, i[1].mStart);
459
0
  EXPECT_EQ(27, i[1].mEnd);
460
0
461
0
  EXPECT_EQ(40, i[2].mStart);
462
0
  EXPECT_EQ(60, i[2].mEnd);
463
0
}
464
465
TEST(IntervalSet, NormalizeFuzz)
466
0
{
467
0
  IntIntervals i0;
468
0
  i0 += IntInterval(11, 25, 0);
469
0
  i0 += IntInterval(5, 10, 1);
470
0
  i0 += IntInterval(40, 60, 1);
471
0
472
0
  EXPECT_EQ(2u, i0.Length());
473
0
474
0
  EXPECT_EQ(5, i0[0].mStart);
475
0
  EXPECT_EQ(25, i0[0].mEnd);
476
0
477
0
  EXPECT_EQ(40, i0[1].mStart);
478
0
  EXPECT_EQ(60, i0[1].mEnd);
479
0
}
480
481
TEST(IntervalSet, UnionFuzz)
482
0
{
483
0
  IntIntervals i0;
484
0
  i0 += IntInterval(5, 10, 1);
485
0
  i0 += IntInterval(11, 25, 0);
486
0
  i0 += IntInterval(40, 60, 1);
487
0
  EXPECT_EQ(2u, i0.Length());
488
0
  EXPECT_EQ(5, i0[0].mStart);
489
0
  EXPECT_EQ(25, i0[0].mEnd);
490
0
  EXPECT_EQ(40, i0[1].mStart);
491
0
  EXPECT_EQ(60, i0[1].mEnd);
492
0
493
0
  IntIntervals i1;
494
0
  i1.Add(IntInterval(7, 15, 1));
495
0
  i1.Add(IntInterval(16, 27, 1));
496
0
  i1.Add(IntInterval(45, 50, 1));
497
0
  i1.Add(IntInterval(53, 57, 1));
498
0
  EXPECT_EQ(3u, i1.Length());
499
0
  EXPECT_EQ(7, i1[0].mStart);
500
0
  EXPECT_EQ(27, i1[0].mEnd);
501
0
  EXPECT_EQ(45, i1[1].mStart);
502
0
  EXPECT_EQ(50, i1[1].mEnd);
503
0
  EXPECT_EQ(53, i1[2].mStart);
504
0
  EXPECT_EQ(57, i1[2].mEnd);
505
0
506
0
  IntIntervals i = media::Union(i0, i1);
507
0
508
0
  EXPECT_EQ(2u, i.Length());
509
0
510
0
  EXPECT_EQ(5, i[0].mStart);
511
0
  EXPECT_EQ(27, i[0].mEnd);
512
0
513
0
  EXPECT_EQ(40, i[1].mStart);
514
0
  EXPECT_EQ(60, i[1].mEnd);
515
0
}
516
517
TEST(IntervalSet, Contiguous)
518
0
{
519
0
  EXPECT_FALSE(IntInterval(5, 10).Contiguous(IntInterval(11, 25)));
520
0
  EXPECT_TRUE(IntInterval(5, 10).Contiguous(IntInterval(10, 25)));
521
0
  EXPECT_TRUE(IntInterval(5, 10, 1).Contiguous(IntInterval(11, 25)));
522
0
  EXPECT_TRUE(IntInterval(5, 10).Contiguous(IntInterval(11, 25, 1)));
523
0
}
524
525
TEST(IntervalSet, TimeRangesSeconds)
526
0
{
527
0
  media::TimeIntervals i0;
528
0
  i0 += media::TimeInterval(media::TimeUnit::FromSeconds(20), media::TimeUnit::FromSeconds(25));
529
0
  i0 += media::TimeInterval(media::TimeUnit::FromSeconds(40), media::TimeUnit::FromSeconds(60));
530
0
  i0 += media::TimeInterval(media::TimeUnit::FromSeconds(5), media::TimeUnit::FromSeconds(10));
531
0
532
0
  media::TimeIntervals i1;
533
0
  i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(16), media::TimeUnit::FromSeconds(27)));
534
0
  i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(7), media::TimeUnit::FromSeconds(15)));
535
0
  i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(53), media::TimeUnit::FromSeconds(57)));
536
0
  i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(45), media::TimeUnit::FromSeconds(50)));
537
0
538
0
  media::TimeIntervals i(i0 + i1);
539
0
  RefPtr<dom::TimeRanges> tr = new dom::TimeRanges(i);
540
0
  EXPECT_EQ(tr->Length(), i.Length());
541
0
  for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
542
0
    ErrorResult rv;
543
0
    EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds());
544
0
    EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds());
545
0
    EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
546
0
    EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
547
0
  }
548
0
}
549
550
static void CheckTimeRanges(dom::TimeRanges* aTr, const media::TimeIntervals& aTi)
551
0
{
552
0
  RefPtr<dom::TimeRanges> tr = new dom::TimeRanges;
553
0
  tr->Union(aTr, 0); // This will normalize the time range.
554
0
  EXPECT_EQ(tr->Length(), aTi.Length());
555
0
  for (dom::TimeRanges::index_type i = 0; i < tr->Length(); i++) {
556
0
    ErrorResult rv;
557
0
    EXPECT_EQ(tr->Start(i, rv), aTi[i].mStart.ToSeconds());
558
0
    EXPECT_EQ(tr->Start(i, rv), aTi.Start(i).ToSeconds());
559
0
    EXPECT_EQ(tr->End(i, rv), aTi[i].mEnd.ToSeconds());
560
0
    EXPECT_EQ(tr->End(i, rv), aTi.End(i).ToSeconds());
561
0
  }
562
0
}
563
564
TEST(IntervalSet, TimeRangesConversion)
565
0
{
566
0
  RefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
567
0
  tr->Add(20, 25);
568
0
  tr->Add(40, 60);
569
0
  tr->Add(5, 10);
570
0
  tr->Add(16, 27);
571
0
  tr->Add(53, 57);
572
0
  tr->Add(45, 50);
573
0
574
0
  // explicit copy constructor and ToTimeIntervals.
575
0
  media::TimeIntervals i1(tr->ToTimeIntervals());
576
0
  CheckTimeRanges(tr, i1);
577
0
578
0
  // ctor(const TimeIntervals&)
579
0
  RefPtr<dom::TimeRanges> tr2 = new dom::TimeRanges(tr->ToTimeIntervals());
580
0
  CheckTimeRanges(tr2, i1);
581
0
}
582
583
TEST(IntervalSet, TimeRangesMicroseconds)
584
0
{
585
0
  media::TimeIntervals i0;
586
0
587
0
  i0 += media::TimeInterval(media::TimeUnit::FromMicroseconds(20), media::TimeUnit::FromMicroseconds(25));
588
0
  i0 += media::TimeInterval(media::TimeUnit::FromMicroseconds(40), media::TimeUnit::FromMicroseconds(60));
589
0
  i0 += media::TimeInterval(media::TimeUnit::FromMicroseconds(5), media::TimeUnit::FromMicroseconds(10));
590
0
591
0
  media::TimeIntervals i1;
592
0
  i1.Add(media::TimeInterval(media::TimeUnit::FromMicroseconds(16), media::TimeUnit::FromMicroseconds(27)));
593
0
  i1.Add(media::TimeInterval(media::TimeUnit::FromMicroseconds(7), media::TimeUnit::FromMicroseconds(15)));
594
0
  i1.Add(media::TimeInterval(media::TimeUnit::FromMicroseconds(53), media::TimeUnit::FromMicroseconds(57)));
595
0
  i1.Add(media::TimeInterval(media::TimeUnit::FromMicroseconds(45), media::TimeUnit::FromMicroseconds(50)));
596
0
597
0
  media::TimeIntervals i(i0 + i1);
598
0
  RefPtr<dom::TimeRanges> tr = new dom::TimeRanges(i);
599
0
  EXPECT_EQ(tr->Length(), i.Length());
600
0
  for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
601
0
    ErrorResult rv;
602
0
    EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds());
603
0
    EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds());
604
0
    EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
605
0
    EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
606
0
  }
607
0
608
0
  tr->Normalize();
609
0
  EXPECT_EQ(tr->Length(), i.Length());
610
0
  for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
611
0
    ErrorResult rv;
612
0
    EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds());
613
0
    EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds());
614
0
    EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
615
0
    EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
616
0
  }
617
0
618
0
  // Check infinity values aren't lost in the conversion.
619
0
  tr = new dom::TimeRanges();
620
0
  tr->Add(0, 30);
621
0
  tr->Add(50, std::numeric_limits<double>::infinity());
622
0
  media::TimeIntervals i_oo = tr->ToTimeIntervals();
623
0
  RefPtr<dom::TimeRanges> tr2 = new dom::TimeRanges(i_oo);
624
0
  EXPECT_EQ(tr->Length(), tr2->Length());
625
0
  for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
626
0
    ErrorResult rv;
627
0
    EXPECT_EQ(tr->Start(index, rv), tr2->Start(index, rv));
628
0
    EXPECT_EQ(tr->End(index, rv), tr2->End(index, rv));
629
0
  }
630
0
}
631
632
template<typename T>
633
class Foo
634
{
635
public:
636
  Foo()
637
    : mArg1(1)
638
    , mArg2(2)
639
    , mArg3(3)
640
0
  {}
641
642
  Foo(T a1, T a2, T a3)
643
    : mArg1(a1)
644
    , mArg2(a2)
645
    , mArg3(a3)
646
0
  {}
647
648
  Foo<T> operator+ (const Foo<T>& aOther) const
649
0
  {
650
0
    Foo<T> blah;
651
0
    blah.mArg1 += aOther.mArg1;
652
0
    blah.mArg2 += aOther.mArg2;
653
0
    blah.mArg3 += aOther.mArg3;
654
0
    return blah;
655
0
  }
656
  Foo<T> operator- (const Foo<T>& aOther) const
657
0
  {
658
0
    Foo<T> blah;
659
0
    blah.mArg1 -= aOther.mArg1;
660
0
    blah.mArg2 -= aOther.mArg2;
661
0
    blah.mArg3 -= aOther.mArg3;
662
0
    return blah;
663
0
  }
664
  bool operator< (const Foo<T>& aOther) const
665
0
  {
666
0
    return mArg1 < aOther.mArg1;
667
0
  }
668
  bool operator== (const Foo<T>& aOther) const
669
0
  {
670
0
    return mArg1 == aOther.mArg1;
671
0
  }
672
  bool operator<= (const Foo<T>& aOther) const
673
0
  {
674
0
    return mArg1 <= aOther.mArg1;
675
0
  }
676
677
private:
678
  int32_t mArg1;
679
  int32_t mArg2;
680
  int32_t mArg3;
681
};
682
683
TEST(IntervalSet, FooIntervalSet)
684
0
{
685
0
  media::Interval<Foo<int>> i(Foo<int>(), Foo<int>(4,5,6));
686
0
  media::IntervalSet<Foo<int>> is;
687
0
  is += i;
688
0
  is += i;
689
0
  is.Add(i);
690
0
  is = is + i;
691
0
  is = i + is;
692
0
  EXPECT_EQ(1u, is.Length());
693
0
  EXPECT_EQ(Foo<int>(), is[0].mStart);
694
0
  EXPECT_EQ(Foo<int>(4,5,6), is[0].mEnd);
695
0
}
696
697
TEST(IntervalSet, StaticAssert)
698
0
{
699
0
  media::Interval<int> i;
700
0
701
0
  static_assert(mozilla::IsSame<nsTArray_CopyChooser<IntIntervals>::Type, nsTArray_CopyWithConstructors<IntIntervals>>::value, "Must use copy constructor");
702
0
  static_assert(mozilla::IsSame<nsTArray_CopyChooser<media::TimeIntervals>::Type, nsTArray_CopyWithConstructors<media::TimeIntervals>>::value, "Must use copy constructor");
703
0
}
704
705
TEST(IntervalSet, Substraction)
706
0
{
707
0
  IntIntervals i0;
708
0
  i0 += IntInterval(5, 10);
709
0
  i0 += IntInterval(20, 25);
710
0
  i0 += IntInterval(40, 60);
711
0
712
0
  IntInterval i1(8, 15);
713
0
  i0 -= i1;
714
0
715
0
  EXPECT_EQ(3u, i0.Length());
716
0
  EXPECT_EQ(5, i0[0].mStart);
717
0
  EXPECT_EQ(8, i0[0].mEnd);
718
0
  EXPECT_EQ(20, i0[1].mStart);
719
0
  EXPECT_EQ(25, i0[1].mEnd);
720
0
  EXPECT_EQ(40, i0[2].mStart);
721
0
  EXPECT_EQ(60, i0[2].mEnd);
722
0
723
0
  i0 = IntIntervals();
724
0
  i0 += IntInterval(5, 10);
725
0
  i0 += IntInterval(20, 25);
726
0
  i0 += IntInterval(40, 60);
727
0
  i1 = IntInterval(0, 60);
728
0
  i0 -= i1;
729
0
  EXPECT_EQ(0u, i0.Length());
730
0
731
0
  i0 = IntIntervals();
732
0
  i0 += IntInterval(5, 10);
733
0
  i0 += IntInterval(20, 25);
734
0
  i0 += IntInterval(40, 60);
735
0
  i1 = IntInterval(0, 45);
736
0
  i0 -= i1;
737
0
  EXPECT_EQ(1u, i0.Length());
738
0
  EXPECT_EQ(45, i0[0].mStart);
739
0
  EXPECT_EQ(60, i0[0].mEnd);
740
0
741
0
  i0 = IntIntervals();
742
0
  i0 += IntInterval(5, 10);
743
0
  i0 += IntInterval(20, 25);
744
0
  i0 += IntInterval(40, 60);
745
0
  i1 = IntInterval(8, 45);
746
0
  i0 -= i1;
747
0
  EXPECT_EQ(2u, i0.Length());
748
0
  EXPECT_EQ(5, i0[0].mStart);
749
0
  EXPECT_EQ(8, i0[0].mEnd);
750
0
  EXPECT_EQ(45, i0[1].mStart);
751
0
  EXPECT_EQ(60, i0[1].mEnd);
752
0
753
0
  i0 = IntIntervals();
754
0
  i0 += IntInterval(5, 10);
755
0
  i0 += IntInterval(20, 25);
756
0
  i0 += IntInterval(40, 60);
757
0
  i1 = IntInterval(8, 70);
758
0
  i0 -= i1;
759
0
  EXPECT_EQ(1u, i0.Length());
760
0
  EXPECT_EQ(5, i0[0].mStart);
761
0
  EXPECT_EQ(8, i0[0].mEnd);
762
0
763
0
  i0 = IntIntervals();
764
0
  i0 += IntInterval(0, 10);
765
0
  IntIntervals i2;
766
0
  i2 += IntInterval(4, 6);
767
0
  i0 -= i2;
768
0
  EXPECT_EQ(2u, i0.Length());
769
0
  EXPECT_EQ(0, i0[0].mStart);
770
0
  EXPECT_EQ(4, i0[0].mEnd);
771
0
  EXPECT_EQ(6, i0[1].mStart);
772
0
  EXPECT_EQ(10, i0[1].mEnd);
773
0
774
0
  i0 = IntIntervals();
775
0
  i0 += IntInterval(0, 1);
776
0
  i0 += IntInterval(3, 10);
777
0
  EXPECT_EQ(2u, i0.Length());
778
0
  // This fuzz should collapse i0 into [0,10).
779
0
  i0.SetFuzz(1);
780
0
  EXPECT_EQ(1u, i0.Length());
781
0
  EXPECT_EQ(1, i0[0].mFuzz);
782
0
  i2 = IntInterval(4, 6);
783
0
  i0 -= i2;
784
0
  EXPECT_EQ(2u, i0.Length());
785
0
  EXPECT_EQ(0, i0[0].mStart);
786
0
  EXPECT_EQ(4, i0[0].mEnd);
787
0
  EXPECT_EQ(6, i0[1].mStart);
788
0
  EXPECT_EQ(10, i0[1].mEnd);
789
0
  EXPECT_EQ(1, i0[0].mFuzz);
790
0
  EXPECT_EQ(1, i0[1].mFuzz);
791
0
792
0
  i0 = IntIntervals();
793
0
  i0 += IntInterval(0, 10);
794
0
  // [4,6) with fuzz 1 used to fail because the complementary interval set
795
0
  // [0,4)+[6,10) would collapse into [0,10).
796
0
  i2 = IntInterval(4, 6);
797
0
  i2.SetFuzz(1);
798
0
  i0 -= i2;
799
0
  EXPECT_EQ(2u, i0.Length());
800
0
  EXPECT_EQ(0, i0[0].mStart);
801
0
  EXPECT_EQ(4, i0[0].mEnd);
802
0
  EXPECT_EQ(6, i0[1].mStart);
803
0
  EXPECT_EQ(10, i0[1].mEnd);
804
0
}