Index: services/media/common/test/timeline_rate_test.cc |
diff --git a/services/media/common/test/timeline_rate_test.cc b/services/media/common/test/timeline_rate_test.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d7080a062bce144b3efee5de6ee2927c5553cbef |
--- /dev/null |
+++ b/services/media/common/test/timeline_rate_test.cc |
@@ -0,0 +1,186 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include <limits> |
+ |
+#include "mojo/services/media/common/cpp/timeline_rate.h" |
+#include "services/media/common/test/test_base.h" |
+ |
+namespace mojo { |
+namespace media { |
+namespace { |
+ |
+class TimelineRateTest : public TestBase { |
+ static uint32_t gcd(uint32_t a, uint32_t b) { |
+ while (b != 0) { |
+ uint32_t t = a; |
+ a = b; |
+ b = t % b; |
+ } |
+ return a; |
+ } |
+ |
+ public: |
+ // Verifies TimelineRate::Reduce and the constructor, ensuring that the ratio |
+ // subject_delta * common_factor / reference_delta * common_factor is reduced |
+ // to subject_delta / reference_delta. subject_delta and reference_delta need |
+ // to be relatively prime for this to work. |
+ void VerifyReduce(uint32_t subject_delta, |
+ uint32_t reference_delta, |
+ uint32_t common_factor) { |
+ // Make sure subject_delta and reference_delta are relatively prime. |
+ EXPECT_EQ(1u, gcd(subject_delta, reference_delta)); |
+ |
+ uint32_t test_subject_delta = subject_delta * common_factor; |
+ uint32_t test_reference_delta = reference_delta * common_factor; |
+ |
+ // Make sure the constructor reduces. |
+ TimelineRate rate(test_subject_delta, test_reference_delta); |
+ EXPECT_EQ(subject_delta, rate.subject_delta()); |
+ EXPECT_EQ(reference_delta, rate.reference_delta()); |
+ |
+ // Test the static method. |
+ TimelineRate::Reduce(&test_subject_delta, &test_reference_delta); |
+ EXPECT_EQ(subject_delta, test_subject_delta); |
+ EXPECT_EQ(reference_delta, test_reference_delta); |
+ } |
+ |
+ // Verifies the TimelineRate::Scale methods by scaling value by subject_delta |
+ // / |
+ // reference_delta and verifying the result. |
+ void VerifyScale(int64_t value, |
+ uint32_t subject_delta, |
+ uint32_t reference_delta, |
+ int64_t result) { |
+ // Test the instance method. |
+ EXPECT_EQ(result, |
+ TimelineRate(subject_delta, reference_delta).Scale(value)); |
+ |
+ // Test the static method. |
+ EXPECT_EQ(result, |
+ TimelineRate::Scale(value, subject_delta, reference_delta)); |
+ |
+ // Test the operators. |
+ EXPECT_EQ(result, value * TimelineRate(subject_delta, reference_delta)); |
+ EXPECT_EQ(result, TimelineRate(subject_delta, reference_delta) * value); |
+ if (subject_delta != 0) { |
+ EXPECT_EQ(result, value / TimelineRate(reference_delta, subject_delta)); |
+ } |
+ } |
+ |
+ // Verifies the TimelineRate::Product methods by multiplying the given a and b |
+ // rates and checking the result against the expected rate. |
+ void VerifyProduct(uint32_t a_subject_delta, |
+ uint32_t a_reference_delta, |
+ uint32_t b_subject_delta, |
+ uint32_t b_reference_delta, |
+ uint32_t expected_subject_delta, |
+ uint32_t expected_reference_delta, |
+ bool exact) { |
+ // Test the first static method. |
+ uint32_t actual_subject_delta; |
+ uint32_t actual_reference_delta; |
+ TimelineRate::Product(a_subject_delta, a_reference_delta, b_subject_delta, |
+ b_reference_delta, &actual_subject_delta, |
+ &actual_reference_delta, exact); |
+ EXPECT_EQ(expected_subject_delta, actual_subject_delta); |
+ EXPECT_EQ(expected_reference_delta, actual_reference_delta); |
+ |
+ // Test the second static method. |
+ EXPECT_EQ(TimelineRate(expected_subject_delta, expected_reference_delta), |
+ TimelineRate::Product( |
+ TimelineRate(a_subject_delta, a_reference_delta), |
+ TimelineRate(b_subject_delta, b_reference_delta), exact)); |
+ |
+ // Test the operator |
+ if (exact) { |
+ EXPECT_EQ(TimelineRate(expected_subject_delta, expected_reference_delta), |
+ TimelineRate(a_subject_delta, a_reference_delta) * |
+ TimelineRate(b_subject_delta, b_reference_delta)); |
+ } |
+ } |
+ |
+ // Verifies the TimelineRaten::Inverse method using the given rate. |
+ void VerifyInverse(uint32_t subject_delta, uint32_t reference_delta) { |
+ TimelineRate rate(subject_delta, reference_delta); |
+ TimelineRate inverse(rate.Inverse()); |
+ EXPECT_EQ(rate.reference_delta(), inverse.subject_delta()); |
+ EXPECT_EQ(rate.subject_delta(), inverse.reference_delta()); |
+ } |
+}; |
+ |
+// Tests TimelineRate::Reduce and that the TimelineRate constructor reduces. |
+TEST_F(TimelineRateTest, Reduce) { |
+ VerifyReduce(0, 1, 1); |
+ VerifyReduce(1, 1, 1); |
+ VerifyReduce(1234, 1, 1); |
+ VerifyReduce(1, 1234, 14); |
+ VerifyReduce(1, 1, 1234); |
+ VerifyReduce(10, 1, 1234); |
+ VerifyReduce(1, 10, 1234); |
+ VerifyReduce(49, 81, 1); |
+ VerifyReduce(49, 81, 10); |
+ VerifyReduce(49, 81, 100); |
+ VerifyReduce(1, 8, 65536); |
+ VerifyReduce(8, 1, 65536); |
+} |
+ |
+// Tests TimelineRate::Scale, static, instance and operator versions. |
+TEST_F(TimelineRateTest, Scale) { |
+ const int64_t int64_min = std::numeric_limits<int64_t>::min(); |
+ VerifyScale(0, 0, 1, 0); |
+ VerifyScale(1, 0, 1, 0); |
+ VerifyScale(0, 1, 1, 0); |
+ VerifyScale(1, 1, 1, 1); |
+ VerifyScale(1, 2, 1, 2); |
+ VerifyScale(1, 1, 2, 0); |
+ VerifyScale(-1, 1, 2, -1); |
+ VerifyScale(1000, 1, 2, 500); |
+ VerifyScale(1001, 1, 2, 500); |
+ VerifyScale(-1000, 1, 2, -500); |
+ VerifyScale(-1001, 1, 2, -501); |
+ VerifyScale(1000, 2, 1, 2000); |
+ VerifyScale(1001, 2, 1, 2002); |
+ VerifyScale(-1000, 2, 1, -2000); |
+ VerifyScale(-1001, 2, 1, -2002); |
+ VerifyScale(1ll << 32, 1, 1, 1ll << 32); |
+ VerifyScale(1ll << 32, 1, 2, 1ll << 31); |
+ VerifyScale(1ll << 32, 2, 1, 1ll << 33); |
+ VerifyScale(1234ll << 30, 1, 1, 1234ll << 30); |
+ VerifyScale(1234ll << 30, 1, 2, 1234ll << 29); |
+ VerifyScale(1234ll << 30, 2, 1, 1234ll << 31); |
+ VerifyScale(1234ll << 30, 1 << 31, 1, TimelineRate::kOverflow); |
+ VerifyScale(1234ll << 30, 1ll << 31, (1ll << 31) - 2, |
+ (1234ll << 30) + 1234ll); |
+ VerifyScale(int64_min, 1, 1, int64_min); |
+ VerifyScale(int64_min, 1, 2, int64_min / 2); |
+ VerifyScale(int64_min / 2, 2, 1, int64_min); |
+ VerifyScale(int64_min, 1000001, 1000000, TimelineRate::kOverflow); |
+} |
+ |
+// Tests TimelineRate::Product, static and operator versions. |
+TEST_F(TimelineRateTest, Product) { |
+ VerifyProduct(0, 1, 0, 1, 0, 1, true); |
+ VerifyProduct(1, 1, 1, 1, 1, 1, true); |
+ VerifyProduct(10, 1, 1, 10, 1, 1, true); |
+ VerifyProduct(4321, 1234, 617, 4321, 1, 2, true); |
+ VerifyProduct(1234, 4321, 4321, 617, 2, 1, true); |
+ VerifyProduct(1ll << 31, (1ll << 31) - 1, (1ll << 31) - 1, 1ll << 31, 1, 1, |
+ true); |
+ VerifyProduct(1ll << 31, (1ll << 31) - 1, (1ll << 31) - 2, 1ll << 31, |
+ 0x7ffffffe, 0x7fffffff, false); |
+} |
+ |
+// Tests TimelineRate::Inverse. |
+TEST_F(TimelineRateTest, Inverse) { |
+ VerifyInverse(1, 1); |
+ VerifyInverse(2, 1); |
+ VerifyInverse(1, 2); |
+ VerifyInverse(1000000, 1234); |
+ VerifyInverse(1234, 1000000); |
+} |
+ |
+} // namespace |
+} // namespace media |
+} // namespace mojo |