зеркало из https://github.com/mozilla/gecko-dev.git
822 строки
22 KiB
C++
822 строки
22 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "gtest/gtest.h"
|
|
#include "mozilla/dom/TimeRanges.h"
|
|
#include "TimeUnits.h"
|
|
#include "Intervals.h"
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
using namespace mozilla;
|
|
|
|
typedef media::Interval<uint8_t> ByteInterval;
|
|
typedef media::Interval<int> IntInterval;
|
|
typedef media::IntervalSet<int> IntIntervals;
|
|
|
|
ByteInterval CreateByteInterval(int32_t aStart, int32_t aEnd)
|
|
{
|
|
ByteInterval test(aStart, aEnd);
|
|
return test;
|
|
}
|
|
|
|
media::IntervalSet<uint8_t> CreateByteIntervalSet(int32_t aStart, int32_t aEnd)
|
|
{
|
|
media::IntervalSet<uint8_t> test;
|
|
test += ByteInterval(aStart, aEnd);
|
|
return test;
|
|
}
|
|
|
|
TEST(IntervalSet, Constructors)
|
|
{
|
|
const int32_t start = 1;
|
|
const int32_t end = 2;
|
|
const int32_t fuzz = 0;
|
|
|
|
// Compiler exercise.
|
|
ByteInterval test1(start, end);
|
|
ByteInterval test2(test1);
|
|
ByteInterval test3(start, end, fuzz);
|
|
ByteInterval test4(test3);
|
|
ByteInterval test5 = CreateByteInterval(start, end);
|
|
|
|
media::IntervalSet<uint8_t> blah1(test1);
|
|
media::IntervalSet<uint8_t> blah2 = blah1;
|
|
media::IntervalSet<uint8_t> blah3 = blah1 + test1;
|
|
media::IntervalSet<uint8_t> blah4 = test1 + blah1;
|
|
media::IntervalSet<uint8_t> blah5 = CreateByteIntervalSet(start, end);
|
|
(void)test1; (void)test2; (void)test3; (void)test4; (void)test5;
|
|
(void)blah1; (void)blah2; (void)blah3; (void)blah4; (void)blah5;
|
|
}
|
|
|
|
media::TimeInterval CreateTimeInterval(int32_t aStart, int32_t aEnd)
|
|
{
|
|
// Copy constructor test
|
|
media::Microseconds startus(aStart);
|
|
media::TimeUnit start(startus);
|
|
media::TimeUnit end;
|
|
// operator= test
|
|
end = media::Microseconds(aEnd);
|
|
media::TimeInterval ti(start, end);
|
|
return ti;
|
|
}
|
|
|
|
media::TimeIntervals CreateTimeIntervals(int32_t aStart, int32_t aEnd)
|
|
{
|
|
media::TimeIntervals test;
|
|
test += CreateTimeInterval(aStart, aEnd);
|
|
return test;
|
|
}
|
|
|
|
TEST(IntervalSet, TimeIntervalsConstructors)
|
|
{
|
|
const media::Microseconds start(1);
|
|
const media::Microseconds end(2);
|
|
const media::Microseconds fuzz;
|
|
|
|
// Compiler exercise.
|
|
media::TimeInterval test1(start, end);
|
|
media::TimeInterval test2(test1);
|
|
media::TimeInterval test3(start, end, fuzz);
|
|
media::TimeInterval test4(test3);
|
|
media::TimeInterval test5 = CreateTimeInterval(start.mValue, end.mValue);
|
|
|
|
media::TimeIntervals blah1(test1);
|
|
media::TimeIntervals blah2(blah1);
|
|
media::TimeIntervals blah3 = blah1 + test1;
|
|
media::TimeIntervals blah4 = test1 + blah1;
|
|
media::TimeIntervals blah5 = CreateTimeIntervals(start.mValue, end.mValue);
|
|
(void)test1; (void)test2; (void)test3; (void)test4; (void)test5;
|
|
(void)blah1; (void)blah2; (void)blah3; (void)blah4; (void)blah5;
|
|
|
|
media::TimeIntervals i0{media::TimeInterval(media::TimeUnit::FromSeconds(0),
|
|
media::TimeUnit::FromSeconds(0))};
|
|
EXPECT_EQ(0u, i0.Length()); // Constructing with an empty time interval.
|
|
}
|
|
|
|
TEST(IntervalSet, Length)
|
|
{
|
|
IntInterval i(15, 25);
|
|
EXPECT_EQ(10, i.Length());
|
|
}
|
|
|
|
TEST(IntervalSet, Intersects)
|
|
{
|
|
EXPECT_TRUE(IntInterval(1,5).Intersects(IntInterval(3,4)));
|
|
EXPECT_TRUE(IntInterval(1,5).Intersects(IntInterval(3,7)));
|
|
EXPECT_TRUE(IntInterval(1,5).Intersects(IntInterval(-1,3)));
|
|
EXPECT_TRUE(IntInterval(1,5).Intersects(IntInterval(-1,7)));
|
|
EXPECT_FALSE(IntInterval(1,5).Intersects(IntInterval(6,7)));
|
|
EXPECT_FALSE(IntInterval(1,5).Intersects(IntInterval(-1,0)));
|
|
// End boundary is exclusive of the interval.
|
|
EXPECT_FALSE(IntInterval(1,5).Intersects(IntInterval(5,7)));
|
|
EXPECT_FALSE(IntInterval(1,5).Intersects(IntInterval(0,1)));
|
|
// Empty identical interval do not intersect.
|
|
EXPECT_FALSE(IntInterval(1,1).Intersects(IntInterval(1,1)));
|
|
// Empty interval do not intersect.
|
|
EXPECT_FALSE(IntInterval(1,1).Intersects(IntInterval(2,2)));
|
|
}
|
|
|
|
TEST(IntervalSet, Intersection)
|
|
{
|
|
IntInterval i0(10, 20);
|
|
IntInterval i1(15, 25);
|
|
IntInterval i = i0.Intersection(i1);
|
|
EXPECT_EQ(15, i.mStart);
|
|
EXPECT_EQ(20, i.mEnd);
|
|
IntInterval j0(10, 20);
|
|
IntInterval j1(20, 25);
|
|
IntInterval j = j0.Intersection(j1);
|
|
EXPECT_TRUE(j.IsEmpty());
|
|
IntInterval k0(2, 2);
|
|
IntInterval k1(2, 2);
|
|
IntInterval k = k0.Intersection(k1);
|
|
EXPECT_TRUE(k.IsEmpty());
|
|
}
|
|
|
|
TEST(IntervalSet, Equals)
|
|
{
|
|
IntInterval i0(10, 20);
|
|
IntInterval i1(10, 20);
|
|
EXPECT_EQ(i0, i1);
|
|
|
|
IntInterval i2(5, 20);
|
|
EXPECT_NE(i0, i2);
|
|
|
|
IntInterval i3(10, 15);
|
|
EXPECT_NE(i0, i2);
|
|
}
|
|
|
|
TEST(IntervalSet, IntersectionIntervalSet)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
|
|
IntIntervals i1;
|
|
i1.Add(IntInterval(7, 15));
|
|
i1.Add(IntInterval(16, 27));
|
|
i1.Add(IntInterval(45, 50));
|
|
i1.Add(IntInterval(53, 57));
|
|
|
|
IntIntervals i = media::Intersection(i0, i1);
|
|
|
|
EXPECT_EQ(4u, i.Length());
|
|
|
|
EXPECT_EQ(7, i[0].mStart);
|
|
EXPECT_EQ(10, i[0].mEnd);
|
|
|
|
EXPECT_EQ(20, i[1].mStart);
|
|
EXPECT_EQ(25, i[1].mEnd);
|
|
|
|
EXPECT_EQ(45, i[2].mStart);
|
|
EXPECT_EQ(50, i[2].mEnd);
|
|
|
|
EXPECT_EQ(53, i[3].mStart);
|
|
EXPECT_EQ(57, i[3].mEnd);
|
|
}
|
|
|
|
template<typename T>
|
|
static void Compare(const media::IntervalSet<T>& aI1,
|
|
const media::IntervalSet<T>& aI2)
|
|
{
|
|
EXPECT_EQ(aI1.Length(), aI2.Length());
|
|
if (aI1.Length() != aI2.Length()) {
|
|
return;
|
|
}
|
|
for (uint32_t i = 0; i < aI1.Length(); i++) {
|
|
EXPECT_EQ(aI1[i].mStart, aI2[i].mStart);
|
|
EXPECT_EQ(aI1[i].mEnd, aI2[i].mEnd);
|
|
}
|
|
}
|
|
|
|
static void GeneratePermutations(IntIntervals aI1,
|
|
IntIntervals aI2)
|
|
{
|
|
IntIntervals i_ref = media::Intersection(aI1, aI2);
|
|
// Test all permutations possible
|
|
std::vector<uint32_t> comb1;
|
|
for (uint32_t i = 0; i < aI1.Length(); i++) {
|
|
comb1.push_back(i);
|
|
}
|
|
std::vector<uint32_t> comb2;
|
|
for (uint32_t i = 0; i < aI2.Length(); i++) {
|
|
comb2.push_back(i);
|
|
}
|
|
|
|
do {
|
|
do {
|
|
// Create intervals according to new indexes.
|
|
IntIntervals i_0;
|
|
for (uint32_t i = 0; i < comb1.size(); i++) {
|
|
i_0 += aI1[comb1[i]];
|
|
}
|
|
// Test that intervals are always normalized.
|
|
Compare(aI1, i_0);
|
|
IntIntervals i_1;
|
|
for (uint32_t i = 0; i < comb2.size(); i++) {
|
|
i_1 += aI2[comb2[i]];
|
|
}
|
|
Compare(aI2, i_1);
|
|
// Check intersections yield the same result.
|
|
Compare(i_0.Intersection(i_1), i_ref);
|
|
} while (std::next_permutation(comb2.begin(), comb2.end()));
|
|
} while (std::next_permutation(comb1.begin(), comb1.end()));
|
|
}
|
|
|
|
TEST(IntervalSet, IntersectionNormalizedIntervalSet)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
|
|
IntIntervals i1;
|
|
i1.Add(IntInterval(7, 15));
|
|
i1.Add(IntInterval(16, 27));
|
|
i1.Add(IntInterval(45, 50));
|
|
i1.Add(IntInterval(53, 57));
|
|
|
|
GeneratePermutations(i0, i1);
|
|
}
|
|
|
|
TEST(IntervalSet, IntersectionUnorderedNonNormalizedIntervalSet)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(8, 25);
|
|
i0 += IntInterval(24, 60);
|
|
|
|
IntIntervals i1;
|
|
i1.Add(IntInterval(7, 15));
|
|
i1.Add(IntInterval(10, 27));
|
|
i1.Add(IntInterval(45, 50));
|
|
i1.Add(IntInterval(53, 57));
|
|
|
|
GeneratePermutations(i0, i1);
|
|
}
|
|
|
|
TEST(IntervalSet, IntersectionNonNormalizedInterval)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(8, 25);
|
|
i0 += IntInterval(30, 60);
|
|
|
|
media::Interval<int> i1(9, 15);
|
|
i0.Intersection(i1);
|
|
EXPECT_EQ(1u, i0.Length());
|
|
EXPECT_EQ(i0[0].mStart, i1.mStart);
|
|
EXPECT_EQ(i0[0].mEnd, i1.mEnd);
|
|
}
|
|
|
|
TEST(IntervalSet, IntersectionUnorderedNonNormalizedInterval)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(1, 3);
|
|
i0 += IntInterval(1, 10);
|
|
i0 += IntInterval(9, 12);
|
|
i0 += IntInterval(12, 15);
|
|
i0 += IntInterval(8, 25);
|
|
i0 += IntInterval(30, 60);
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(30, 60);
|
|
|
|
media::Interval<int> i1(9, 15);
|
|
i0.Intersection(i1);
|
|
EXPECT_EQ(1u, i0.Length());
|
|
EXPECT_EQ(i0[0].mStart, i1.mStart);
|
|
EXPECT_EQ(i0[0].mEnd, i1.mEnd);
|
|
}
|
|
|
|
static IntIntervals Duplicate(const IntIntervals& aValue)
|
|
{
|
|
IntIntervals value(aValue);
|
|
return value;
|
|
}
|
|
|
|
TEST(IntervalSet, Normalize)
|
|
{
|
|
IntIntervals i;
|
|
// Test IntervalSet<T> + Interval<T> operator.
|
|
i = i + IntInterval(20, 30);
|
|
// Test Internal<T> + IntervalSet<T> operator.
|
|
i = IntInterval(2, 7) + i;
|
|
// Test Interval<T> + IntervalSet<T> operator
|
|
i = IntInterval(1, 8) + i;
|
|
IntIntervals interval;
|
|
interval += IntInterval(5, 10);
|
|
// Test += with rval move.
|
|
i += Duplicate(interval);
|
|
// Test = with move and add with move.
|
|
i = Duplicate(interval) + i;
|
|
|
|
EXPECT_EQ(2u, i.Length());
|
|
|
|
EXPECT_EQ(1, i[0].mStart);
|
|
EXPECT_EQ(10, i[0].mEnd);
|
|
|
|
EXPECT_EQ(20, i[1].mStart);
|
|
EXPECT_EQ(30, i[1].mEnd);
|
|
|
|
media::TimeIntervals ti;
|
|
ti += media::TimeInterval(media::TimeUnit::FromSeconds(0.0),
|
|
media::TimeUnit::FromSeconds(3.203333));
|
|
ti += media::TimeInterval(media::TimeUnit::FromSeconds(3.203366),
|
|
media::TimeUnit::FromSeconds(10.010065));
|
|
EXPECT_EQ(2u, ti.Length());
|
|
ti += media::TimeInterval(ti.Start(0), ti.End(0), media::TimeUnit::FromMicroseconds(35000));
|
|
EXPECT_EQ(1u, ti.Length());
|
|
}
|
|
|
|
TEST(IntervalSet, ContainValue)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(0, 10);
|
|
i0 += IntInterval(15, 20);
|
|
i0 += IntInterval(30, 50);
|
|
EXPECT_TRUE(i0.Contains(0)); // start is inclusive.
|
|
EXPECT_TRUE(i0.Contains(17));
|
|
EXPECT_FALSE(i0.Contains(20)); // end boundary is exclusive.
|
|
EXPECT_FALSE(i0.Contains(25));
|
|
}
|
|
|
|
TEST(IntervalSet, ContainValueWithFuzz)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(0, 10);
|
|
i0 += IntInterval(15, 20, 1);
|
|
i0 += IntInterval(30, 50);
|
|
EXPECT_TRUE(i0.Contains(0)); // start is inclusive.
|
|
EXPECT_TRUE(i0.Contains(17));
|
|
EXPECT_TRUE(i0.Contains(20)); // end boundary is exclusive but we have a fuzz of 1.
|
|
EXPECT_FALSE(i0.Contains(25));
|
|
}
|
|
|
|
TEST(IntervalSet, ContainInterval)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(0, 10);
|
|
i0 += IntInterval(15, 20);
|
|
i0 += IntInterval(30, 50);
|
|
EXPECT_TRUE(i0.Contains(IntInterval(2, 8)));
|
|
EXPECT_TRUE(i0.Contains(IntInterval(31, 50)));
|
|
EXPECT_TRUE(i0.Contains(IntInterval(0, 10)));
|
|
EXPECT_FALSE(i0.Contains(IntInterval(0, 11)));
|
|
EXPECT_TRUE(i0.Contains(IntInterval(0, 5)));
|
|
EXPECT_FALSE(i0.Contains(IntInterval(8, 15)));
|
|
EXPECT_FALSE(i0.Contains(IntInterval(15, 30)));
|
|
EXPECT_FALSE(i0.Contains(IntInterval(30, 55)));
|
|
}
|
|
|
|
TEST(IntervalSet, ContainIntervalWithFuzz)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(0, 10);
|
|
i0 += IntInterval(15, 20);
|
|
i0 += IntInterval(30, 50);
|
|
EXPECT_TRUE(i0.Contains(IntInterval(2, 8)));
|
|
EXPECT_TRUE(i0.Contains(IntInterval(31, 50)));
|
|
EXPECT_TRUE(i0.Contains(IntInterval(0, 11, 1)));
|
|
EXPECT_TRUE(i0.Contains(IntInterval(0, 5)));
|
|
EXPECT_FALSE(i0.Contains(IntInterval(8, 15)));
|
|
EXPECT_FALSE(i0.Contains(IntInterval(15, 21)));
|
|
EXPECT_FALSE(i0.Contains(IntInterval(15, 30)));
|
|
EXPECT_FALSE(i0.Contains(IntInterval(30, 55)));
|
|
|
|
IntIntervals i1;
|
|
i1 += IntInterval(0, 10, 1);
|
|
i1 += IntInterval(15, 20, 1);
|
|
i1 += IntInterval(30, 50, 1);
|
|
EXPECT_TRUE(i1.Contains(IntInterval(2, 8)));
|
|
EXPECT_TRUE(i1.Contains(IntInterval(29, 51)));
|
|
EXPECT_TRUE(i1.Contains(IntInterval(0, 11, 1)));
|
|
EXPECT_TRUE(i1.Contains(IntInterval(15, 21)));
|
|
}
|
|
|
|
TEST(IntervalSet, Span)
|
|
{
|
|
IntInterval i0(0,10);
|
|
IntInterval i1(20,30);
|
|
IntInterval i{i0.Span(i1)};
|
|
|
|
EXPECT_EQ(i.mStart, 0);
|
|
EXPECT_EQ(i.mEnd, 30);
|
|
}
|
|
|
|
TEST(IntervalSet, Union)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
|
|
IntIntervals i1;
|
|
i1.Add(IntInterval(7, 15));
|
|
i1.Add(IntInterval(16, 27));
|
|
i1.Add(IntInterval(45, 50));
|
|
i1.Add(IntInterval(53, 57));
|
|
|
|
IntIntervals i = media::Union(i0, i1);
|
|
|
|
EXPECT_EQ(3u, i.Length());
|
|
|
|
EXPECT_EQ(5, i[0].mStart);
|
|
EXPECT_EQ(15, i[0].mEnd);
|
|
|
|
EXPECT_EQ(16, i[1].mStart);
|
|
EXPECT_EQ(27, i[1].mEnd);
|
|
|
|
EXPECT_EQ(40, i[2].mStart);
|
|
EXPECT_EQ(60, i[2].mEnd);
|
|
}
|
|
|
|
TEST(IntervalSet, UnionNotOrdered)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
i0 += IntInterval(5, 10);
|
|
|
|
IntIntervals i1;
|
|
i1.Add(IntInterval(16, 27));
|
|
i1.Add(IntInterval(7, 15));
|
|
i1.Add(IntInterval(53, 57));
|
|
i1.Add(IntInterval(45, 50));
|
|
|
|
IntIntervals i = media::Union(i0, i1);
|
|
|
|
EXPECT_EQ(3u, i.Length());
|
|
|
|
EXPECT_EQ(5, i[0].mStart);
|
|
EXPECT_EQ(15, i[0].mEnd);
|
|
|
|
EXPECT_EQ(16, i[1].mStart);
|
|
EXPECT_EQ(27, i[1].mEnd);
|
|
|
|
EXPECT_EQ(40, i[2].mStart);
|
|
EXPECT_EQ(60, i[2].mEnd);
|
|
}
|
|
|
|
TEST(IntervalSet, NormalizeFuzz)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(11, 25, 0);
|
|
i0 += IntInterval(5, 10, 1);
|
|
i0 += IntInterval(40, 60, 1);
|
|
|
|
EXPECT_EQ(2u, i0.Length());
|
|
|
|
EXPECT_EQ(5, i0[0].mStart);
|
|
EXPECT_EQ(25, i0[0].mEnd);
|
|
|
|
EXPECT_EQ(40, i0[1].mStart);
|
|
EXPECT_EQ(60, i0[1].mEnd);
|
|
}
|
|
|
|
TEST(IntervalSet, UnionFuzz)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(5, 10, 1);
|
|
i0 += IntInterval(11, 25, 0);
|
|
i0 += IntInterval(40, 60, 1);
|
|
EXPECT_EQ(2u, i0.Length());
|
|
EXPECT_EQ(5, i0[0].mStart);
|
|
EXPECT_EQ(25, i0[0].mEnd);
|
|
EXPECT_EQ(40, i0[1].mStart);
|
|
EXPECT_EQ(60, i0[1].mEnd);
|
|
|
|
IntIntervals i1;
|
|
i1.Add(IntInterval(7, 15, 1));
|
|
i1.Add(IntInterval(16, 27, 1));
|
|
i1.Add(IntInterval(45, 50, 1));
|
|
i1.Add(IntInterval(53, 57, 1));
|
|
EXPECT_EQ(3u, i1.Length());
|
|
EXPECT_EQ(7, i1[0].mStart);
|
|
EXPECT_EQ(27, i1[0].mEnd);
|
|
EXPECT_EQ(45, i1[1].mStart);
|
|
EXPECT_EQ(50, i1[1].mEnd);
|
|
EXPECT_EQ(53, i1[2].mStart);
|
|
EXPECT_EQ(57, i1[2].mEnd);
|
|
|
|
IntIntervals i = media::Union(i0, i1);
|
|
|
|
EXPECT_EQ(2u, i.Length());
|
|
|
|
EXPECT_EQ(5, i[0].mStart);
|
|
EXPECT_EQ(27, i[0].mEnd);
|
|
|
|
EXPECT_EQ(40, i[1].mStart);
|
|
EXPECT_EQ(60, i[1].mEnd);
|
|
}
|
|
|
|
TEST(IntervalSet, Contiguous)
|
|
{
|
|
EXPECT_FALSE(IntInterval(5, 10).Contiguous(IntInterval(11, 25)));
|
|
EXPECT_TRUE(IntInterval(5, 10).Contiguous(IntInterval(10, 25)));
|
|
EXPECT_TRUE(IntInterval(5, 10, 1).Contiguous(IntInterval(11, 25)));
|
|
EXPECT_TRUE(IntInterval(5, 10).Contiguous(IntInterval(11, 25, 1)));
|
|
}
|
|
|
|
TEST(IntervalSet, TimeRangesSeconds)
|
|
{
|
|
media::TimeIntervals i0;
|
|
i0 += media::TimeInterval(media::TimeUnit::FromSeconds(20), media::TimeUnit::FromSeconds(25));
|
|
i0 += media::TimeInterval(media::TimeUnit::FromSeconds(40), media::TimeUnit::FromSeconds(60));
|
|
i0 += media::TimeInterval(media::TimeUnit::FromSeconds(5), media::TimeUnit::FromSeconds(10));
|
|
|
|
media::TimeIntervals i1;
|
|
i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(16), media::TimeUnit::FromSeconds(27)));
|
|
i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(7), media::TimeUnit::FromSeconds(15)));
|
|
i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(53), media::TimeUnit::FromSeconds(57)));
|
|
i1.Add(media::TimeInterval(media::TimeUnit::FromSeconds(45), media::TimeUnit::FromSeconds(50)));
|
|
|
|
media::TimeIntervals i(i0 + i1);
|
|
nsRefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
|
|
i.ToTimeRanges(tr);
|
|
EXPECT_EQ(tr->Length(), i.Length());
|
|
for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
|
|
ErrorResult rv;
|
|
EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds());
|
|
EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds());
|
|
EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
|
|
EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
|
|
}
|
|
}
|
|
|
|
static void CheckTimeRanges(dom::TimeRanges* aTr, const media::TimeIntervals& aTi)
|
|
{
|
|
nsRefPtr<dom::TimeRanges> tr = new dom::TimeRanges;
|
|
tr->Union(aTr, 0); // This will normalize the time range.
|
|
EXPECT_EQ(tr->Length(), aTi.Length());
|
|
for (dom::TimeRanges::index_type i = 0; i < tr->Length(); i++) {
|
|
ErrorResult rv;
|
|
EXPECT_EQ(tr->Start(i, rv), aTi[i].mStart.ToSeconds());
|
|
EXPECT_EQ(tr->Start(i, rv), aTi.Start(i).ToSeconds());
|
|
EXPECT_EQ(tr->End(i, rv), aTi[i].mEnd.ToSeconds());
|
|
EXPECT_EQ(tr->End(i, rv), aTi.End(i).ToSeconds());
|
|
}
|
|
}
|
|
|
|
TEST(IntervalSet, TimeRangesConversion)
|
|
{
|
|
nsRefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
|
|
tr->Add(20, 25);
|
|
tr->Add(40, 60);
|
|
tr->Add(5, 10);
|
|
tr->Add(16, 27);
|
|
tr->Add(53, 57);
|
|
tr->Add(45, 50);
|
|
|
|
// explicit copy constructor
|
|
media::TimeIntervals i1(tr);
|
|
CheckTimeRanges(tr, i1);
|
|
|
|
// static FromTimeRanges
|
|
media::TimeIntervals i2 = media::TimeIntervals::FromTimeRanges(tr);
|
|
CheckTimeRanges(tr, i2);
|
|
|
|
media::TimeIntervals i3;
|
|
// operator=(TimeRanges*)
|
|
i3 = tr;
|
|
CheckTimeRanges(tr, i3);
|
|
|
|
// operator= test
|
|
i1 = tr.get();
|
|
CheckTimeRanges(tr, i1);
|
|
}
|
|
|
|
TEST(IntervalSet, TimeRangesMicroseconds)
|
|
{
|
|
media::TimeIntervals i0;
|
|
|
|
// Test media::Microseconds and TimeUnit interchangeability (compilation only)
|
|
media::TimeUnit time1{media::Microseconds(5)};
|
|
media::Microseconds microseconds(5);
|
|
media::TimeUnit time2 = media::TimeUnit(microseconds);
|
|
EXPECT_EQ(time1, time2);
|
|
|
|
i0 += media::TimeInterval(media::Microseconds(20), media::Microseconds(25));
|
|
i0 += media::TimeInterval(media::Microseconds(40), media::Microseconds(60));
|
|
i0 += media::TimeInterval(media::Microseconds(5), media::Microseconds(10));
|
|
|
|
media::TimeIntervals i1;
|
|
i1.Add(media::TimeInterval(media::Microseconds(16), media::Microseconds(27)));
|
|
i1.Add(media::TimeInterval(media::Microseconds(7), media::Microseconds(15)));
|
|
i1.Add(media::TimeInterval(media::Microseconds(53), media::Microseconds(57)));
|
|
i1.Add(media::TimeInterval(media::Microseconds(45), media::Microseconds(50)));
|
|
|
|
media::TimeIntervals i(i0 + i1);
|
|
nsRefPtr<dom::TimeRanges> tr = new dom::TimeRanges();
|
|
i.ToTimeRanges(tr);
|
|
EXPECT_EQ(tr->Length(), i.Length());
|
|
for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
|
|
ErrorResult rv;
|
|
EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds());
|
|
EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds());
|
|
EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
|
|
EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
|
|
}
|
|
|
|
tr->Normalize();
|
|
EXPECT_EQ(tr->Length(), i.Length());
|
|
for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
|
|
ErrorResult rv;
|
|
EXPECT_EQ(tr->Start(index, rv), i[index].mStart.ToSeconds());
|
|
EXPECT_EQ(tr->Start(index, rv), i.Start(index).ToSeconds());
|
|
EXPECT_EQ(tr->End(index, rv), i[index].mEnd.ToSeconds());
|
|
EXPECT_EQ(tr->End(index, rv), i.End(index).ToSeconds());
|
|
}
|
|
|
|
// Check infinity values aren't lost in the conversion.
|
|
tr = new dom::TimeRanges();
|
|
tr->Add(0, 30);
|
|
tr->Add(50, std::numeric_limits<double>::infinity());
|
|
media::TimeIntervals i_oo{media::TimeIntervals::FromTimeRanges(tr)};
|
|
nsRefPtr<dom::TimeRanges> tr2 = new dom::TimeRanges();
|
|
i_oo.ToTimeRanges(tr2);
|
|
EXPECT_EQ(tr->Length(), tr2->Length());
|
|
for (dom::TimeRanges::index_type index = 0; index < tr->Length(); index++) {
|
|
ErrorResult rv;
|
|
EXPECT_EQ(tr->Start(index, rv), tr2->Start(index, rv));
|
|
EXPECT_EQ(tr->End(index, rv), tr2->End(index, rv));
|
|
}
|
|
}
|
|
|
|
template<typename T>
|
|
class Foo
|
|
{
|
|
public:
|
|
Foo()
|
|
: mArg1(1)
|
|
, mArg2(2)
|
|
, mArg3(3)
|
|
{}
|
|
|
|
Foo(T a1, T a2, T a3)
|
|
: mArg1(a1)
|
|
, mArg2(a2)
|
|
, mArg3(a3)
|
|
{}
|
|
|
|
Foo<T> operator+ (const Foo<T>& aOther) const
|
|
{
|
|
Foo<T> blah;
|
|
blah.mArg1 += aOther.mArg1;
|
|
blah.mArg2 += aOther.mArg2;
|
|
blah.mArg3 += aOther.mArg3;
|
|
return blah;
|
|
}
|
|
Foo<T> operator- (const Foo<T>& aOther) const
|
|
{
|
|
Foo<T> blah;
|
|
blah.mArg1 -= aOther.mArg1;
|
|
blah.mArg2 -= aOther.mArg2;
|
|
blah.mArg3 -= aOther.mArg3;
|
|
return blah;
|
|
}
|
|
bool operator< (const Foo<T>& aOther) const
|
|
{
|
|
return mArg1 < aOther.mArg1;
|
|
}
|
|
bool operator== (const Foo<T>& aOther) const
|
|
{
|
|
return mArg1 == aOther.mArg1;
|
|
}
|
|
bool operator<= (const Foo<T>& aOther) const
|
|
{
|
|
return mArg1 <= aOther.mArg1;
|
|
}
|
|
|
|
private:
|
|
int32_t mArg1;
|
|
int32_t mArg2;
|
|
int32_t mArg3;
|
|
};
|
|
|
|
TEST(IntervalSet, FooIntervalSet)
|
|
{
|
|
media::Interval<Foo<int>> i(Foo<int>(), Foo<int>(4,5,6));
|
|
media::IntervalSet<Foo<int>> is;
|
|
is += i;
|
|
is += i;
|
|
is.Add(i);
|
|
is = is + i;
|
|
is = i + is;
|
|
EXPECT_EQ(1u, is.Length());
|
|
EXPECT_EQ(Foo<int>(), is[0].mStart);
|
|
EXPECT_EQ(Foo<int>(4,5,6), is[0].mEnd);
|
|
}
|
|
|
|
TEST(IntervalSet, StaticAssert)
|
|
{
|
|
media::Interval<int> i;
|
|
|
|
static_assert(mozilla::IsSame<nsTArray_CopyChooser<IntIntervals>::Type, nsTArray_CopyWithConstructors<IntIntervals>>::value, "Must use copy constructor");
|
|
static_assert(mozilla::IsSame<nsTArray_CopyChooser<media::TimeIntervals>::Type, nsTArray_CopyWithConstructors<media::TimeIntervals>>::value, "Must use copy constructor");
|
|
}
|
|
|
|
TEST(IntervalSet, Substraction)
|
|
{
|
|
IntIntervals i0;
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
|
|
IntInterval i1(8, 15);
|
|
i0 -= i1;
|
|
|
|
EXPECT_EQ(3u, i0.Length());
|
|
EXPECT_EQ(5, i0[0].mStart);
|
|
EXPECT_EQ(8, i0[0].mEnd);
|
|
EXPECT_EQ(20, i0[1].mStart);
|
|
EXPECT_EQ(25, i0[1].mEnd);
|
|
EXPECT_EQ(40, i0[2].mStart);
|
|
EXPECT_EQ(60, i0[2].mEnd);
|
|
|
|
i0 = IntIntervals();
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
i1 = IntInterval(0, 60);
|
|
i0 -= i1;
|
|
EXPECT_EQ(0u, i0.Length());
|
|
|
|
i0 = IntIntervals();
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
i1 = IntInterval(0, 45);
|
|
i0 -= i1;
|
|
EXPECT_EQ(1u, i0.Length());
|
|
EXPECT_EQ(45, i0[0].mStart);
|
|
EXPECT_EQ(60, i0[0].mEnd);
|
|
|
|
i0 = IntIntervals();
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
i1 = IntInterval(8, 45);
|
|
i0 -= i1;
|
|
EXPECT_EQ(2u, i0.Length());
|
|
EXPECT_EQ(5, i0[0].mStart);
|
|
EXPECT_EQ(8, i0[0].mEnd);
|
|
EXPECT_EQ(45, i0[1].mStart);
|
|
EXPECT_EQ(60, i0[1].mEnd);
|
|
|
|
i0 = IntIntervals();
|
|
i0 += IntInterval(5, 10);
|
|
i0 += IntInterval(20, 25);
|
|
i0 += IntInterval(40, 60);
|
|
i1 = IntInterval(8, 70);
|
|
i0 -= i1;
|
|
EXPECT_EQ(1u, i0.Length());
|
|
EXPECT_EQ(5, i0[0].mStart);
|
|
EXPECT_EQ(8, i0[0].mEnd);
|
|
|
|
i0 = IntIntervals();
|
|
i0 += IntInterval(0, 10);
|
|
IntIntervals i2;
|
|
i2 += IntInterval(4, 6);
|
|
i0 -= i2;
|
|
EXPECT_EQ(2u, i0.Length());
|
|
EXPECT_EQ(0, i0[0].mStart);
|
|
EXPECT_EQ(4, i0[0].mEnd);
|
|
EXPECT_EQ(6, i0[1].mStart);
|
|
EXPECT_EQ(10, i0[1].mEnd);
|
|
|
|
i0 = IntIntervals();
|
|
i0 += IntInterval(0, 1);
|
|
i0 += IntInterval(3, 10);
|
|
EXPECT_EQ(2u, i0.Length());
|
|
// This fuzz should collapse i0 into [0,10).
|
|
i0.SetFuzz(1);
|
|
EXPECT_EQ(1u, i0.Length());
|
|
EXPECT_EQ(1, i0[0].mFuzz);
|
|
i2 = IntInterval(4, 6);
|
|
i0 -= i2;
|
|
EXPECT_EQ(2u, i0.Length());
|
|
EXPECT_EQ(0, i0[0].mStart);
|
|
EXPECT_EQ(4, i0[0].mEnd);
|
|
EXPECT_EQ(6, i0[1].mStart);
|
|
EXPECT_EQ(10, i0[1].mEnd);
|
|
EXPECT_EQ(1, i0[0].mFuzz);
|
|
EXPECT_EQ(1, i0[1].mFuzz);
|
|
|
|
i0 = IntIntervals();
|
|
i0 += IntInterval(0, 10);
|
|
// [4,6) with fuzz 1 used to fail because the complementary interval set
|
|
// [0,4)+[6,10) would collapse into [0,10).
|
|
i2 = IntInterval(4, 6);
|
|
i2.SetFuzz(1);
|
|
i0 -= i2;
|
|
EXPECT_EQ(2u, i0.Length());
|
|
EXPECT_EQ(0, i0[0].mStart);
|
|
EXPECT_EQ(4, i0[0].mEnd);
|
|
EXPECT_EQ(6, i0[1].mStart);
|
|
EXPECT_EQ(10, i0[1].mEnd);
|
|
}
|