Bug 1314556 - Convert TestAudioEventTimeline.cpp to a gtest. r=padenot.
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 03 Nov 2016 13:39:26 +1100
changeset 347511 ce032e762e19150e79ef3e7938c86ae39a40af43
parent 347510 f8334efe84730204eab8e6f4411d75990232f4fc
child 347512 daeb765e4bf6fa3a16f6382f3a6e33b3282a3948
push id10298
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:33:03 +0000
treeherdermozilla-aurora@7e29173b1641 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs1314556
milestone52.0a1
Bug 1314556 - Convert TestAudioEventTimeline.cpp to a gtest. r=padenot. This required moving template function ValidateEvent into the .h file to avoid linking problems in xul-gtest.
dom/media/webaudio/AudioEventTimeline.cpp
dom/media/webaudio/AudioEventTimeline.h
dom/media/webaudio/compiledtest/TestAudioEventTimeline.cpp
dom/media/webaudio/compiledtest/moz.build
dom/media/webaudio/gtest/TestAudioEventTimeline.cpp
dom/media/webaudio/gtest/moz.build
dom/media/webaudio/moz.build
testing/cppunittest.ini
--- a/dom/media/webaudio/AudioEventTimeline.cpp
+++ b/dom/media/webaudio/AudioEventTimeline.cpp
@@ -46,108 +46,16 @@ static float ExtractValueFromCurve(doubl
   } else {
     return aCurve[current];
   }
 }
 
 namespace mozilla {
 namespace dom {
 
-template <class ErrorResult> bool
-AudioEventTimeline::ValidateEvent(AudioTimelineEvent& aEvent,
-                                  ErrorResult& aRv)
-{
-  MOZ_ASSERT(NS_IsMainThread());
-
-  auto TimeOf = [](const AudioTimelineEvent& aEvent) -> double {
-    return aEvent.template Time<double>();
-  };
-
-  // Validate the event itself
-  if (!WebAudioUtils::IsTimeValid(TimeOf(aEvent)) ||
-      !WebAudioUtils::IsTimeValid(aEvent.mTimeConstant)) {
-    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return false;
-  }
-
-  if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
-    if (!aEvent.mCurve || !aEvent.mCurveLength) {
-      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-      return false;
-    }
-    for (uint32_t i = 0; i < aEvent.mCurveLength; ++i) {
-      if (!IsValid(aEvent.mCurve[i])) {
-        aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-        return false;
-      }
-    }
-  }
-
-  bool timeAndValueValid = IsValid(aEvent.mValue) &&
-                           IsValid(aEvent.mDuration);
-  if (!timeAndValueValid) {
-    aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-    return false;
-  }
-
-  // Make sure that non-curve events don't fall within the duration of a
-  // curve event.
-  for (unsigned i = 0; i < mEvents.Length(); ++i) {
-    if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve &&
-        !(aEvent.mType == AudioTimelineEvent::SetValueCurve &&
-          TimeOf(aEvent) == TimeOf(mEvents[i])) &&
-        TimeOf(mEvents[i]) <= TimeOf(aEvent) &&
-        TimeOf(mEvents[i]) + mEvents[i].mDuration >= TimeOf(aEvent)) {
-      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-      return false;
-    }
-  }
-
-  // Make sure that curve events don't fall in a range which includes other
-  // events.
-  if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
-    for (unsigned i = 0; i < mEvents.Length(); ++i) {
-      // In case we have two curve at the same time
-      if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve &&
-          TimeOf(mEvents[i]) == TimeOf(aEvent)) {
-        continue;
-      }
-      if (TimeOf(mEvents[i]) > TimeOf(aEvent) &&
-          TimeOf(mEvents[i]) < TimeOf(aEvent) + aEvent.mDuration) {
-        aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-        return false;
-      }
-    }
-  }
-
-  // Make sure that invalid values are not used for exponential curves
-  if (aEvent.mType == AudioTimelineEvent::ExponentialRamp) {
-    if (aEvent.mValue <= 0.f) {
-      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-      return false;
-    }
-    const AudioTimelineEvent* previousEvent = GetPreviousEvent(TimeOf(aEvent));
-    if (previousEvent) {
-      if (previousEvent->mValue <= 0.f) {
-        aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-        return false;
-      }
-    } else {
-      if (mValue <= 0.f) {
-        aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
-        return false;
-      }
-    }
-  }
-  return true;
-}
-template bool
-AudioEventTimeline::ValidateEvent(AudioTimelineEvent& aEvent,
-                                  ErrorResult& aRv);
-
 // This method computes the AudioParam value at a given time based on the event timeline
 template<class TimeType> void
 AudioEventTimeline::GetValuesAtTimeHelper(TimeType aTime, float* aBuffer,
                                           const size_t aSize)
 {
   MOZ_ASSERT(aBuffer);
   MOZ_ASSERT(aSize);
 
--- a/dom/media/webaudio/AudioEventTimeline.h
+++ b/dom/media/webaudio/AudioEventTimeline.h
@@ -166,18 +166,102 @@ class AudioEventTimeline
 public:
   explicit AudioEventTimeline(float aDefaultValue)
     : mValue(aDefaultValue),
       mComputedValue(aDefaultValue),
       mLastComputedValue(aDefaultValue)
   { }
 
   template <class ErrorResult>
-  bool ValidateEvent(AudioTimelineEvent& aEvent,
-                     ErrorResult& aRv);
+  bool ValidateEvent(AudioTimelineEvent& aEvent, ErrorResult& aRv)
+  {
+    MOZ_ASSERT(NS_IsMainThread());
+
+    auto TimeOf = [](const AudioTimelineEvent& aEvent) -> double {
+      return aEvent.template Time<double>();
+    };
+
+    // Validate the event itself
+    if (!WebAudioUtils::IsTimeValid(TimeOf(aEvent)) ||
+        !WebAudioUtils::IsTimeValid(aEvent.mTimeConstant)) {
+      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+      return false;
+    }
+
+    if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
+      if (!aEvent.mCurve || !aEvent.mCurveLength) {
+        aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+        return false;
+      }
+      for (uint32_t i = 0; i < aEvent.mCurveLength; ++i) {
+        if (!IsValid(aEvent.mCurve[i])) {
+          aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+          return false;
+        }
+      }
+    }
+
+    bool timeAndValueValid = IsValid(aEvent.mValue) &&
+                             IsValid(aEvent.mDuration);
+    if (!timeAndValueValid) {
+      aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+      return false;
+    }
+
+    // Make sure that non-curve events don't fall within the duration of a
+    // curve event.
+    for (unsigned i = 0; i < mEvents.Length(); ++i) {
+      if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve &&
+          !(aEvent.mType == AudioTimelineEvent::SetValueCurve &&
+            TimeOf(aEvent) == TimeOf(mEvents[i])) &&
+          TimeOf(mEvents[i]) <= TimeOf(aEvent) &&
+          TimeOf(mEvents[i]) + mEvents[i].mDuration >= TimeOf(aEvent)) {
+        aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+        return false;
+      }
+    }
+
+    // Make sure that curve events don't fall in a range which includes other
+    // events.
+    if (aEvent.mType == AudioTimelineEvent::SetValueCurve) {
+      for (unsigned i = 0; i < mEvents.Length(); ++i) {
+        // In case we have two curve at the same time
+        if (mEvents[i].mType == AudioTimelineEvent::SetValueCurve &&
+            TimeOf(mEvents[i]) == TimeOf(aEvent)) {
+          continue;
+        }
+        if (TimeOf(mEvents[i]) > TimeOf(aEvent) &&
+            TimeOf(mEvents[i]) < TimeOf(aEvent) + aEvent.mDuration) {
+          aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+          return false;
+        }
+      }
+    }
+
+    // Make sure that invalid values are not used for exponential curves
+    if (aEvent.mType == AudioTimelineEvent::ExponentialRamp) {
+      if (aEvent.mValue <= 0.f) {
+        aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+        return false;
+      }
+      const AudioTimelineEvent* previousEvent = GetPreviousEvent(TimeOf(aEvent));
+      if (previousEvent) {
+        if (previousEvent->mValue <= 0.f) {
+          aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+          return false;
+        }
+      } else {
+        if (mValue <= 0.f) {
+          aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
+          return false;
+        }
+      }
+    }
+    return true;
+  }
 
   template<typename TimeType>
   void InsertEvent(const AudioTimelineEvent& aEvent)
   {
     for (unsigned i = 0; i < mEvents.Length(); ++i) {
       if (aEvent.template Time<TimeType>() == mEvents[i].template Time<TimeType>()) {
         if (aEvent.mType == mEvents[i].mType) {
           // If times and types are equal, replace the event
rename from dom/media/webaudio/compiledtest/TestAudioEventTimeline.cpp
rename to dom/media/webaudio/gtest/TestAudioEventTimeline.cpp
--- a/dom/media/webaudio/compiledtest/TestAudioEventTimeline.cpp
+++ b/dom/media/webaudio/gtest/TestAudioEventTimeline.cpp
@@ -1,18 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim:set ts=2 sw=2 sts=2 et cindent: */
 /* 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 "AudioEventTimeline.cpp"
-#include "TestHarness.h"
+#include "AudioEventTimeline.h"
 #include <sstream>
 #include <limits>
+#include "gtest/gtest.h"
 
 // Mock the MediaStream class
 namespace mozilla {
 class MediaStream
 {
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaStream)
 private:
   ~MediaStream() {
@@ -22,21 +22,20 @@ private:
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using std::numeric_limits;
 
 // Some simple testing primitives
 void ok(bool val, const char* msg)
 {
-  if (val) {
-    passed(msg);
-  } else {
-    fail(msg);
+  if (!val) {
+    fprintf(stderr, "failure: %s", msg);
   }
+  ASSERT_TRUE(val);
 }
 
 namespace std {
 
 template <class T>
 basic_ostream<T, char_traits<T> >&
 operator<<(basic_ostream<T, char_traits<T> >& os, nsresult rv)
 {
@@ -45,28 +44,28 @@ operator<<(basic_ostream<T, char_traits<
 }
 
 } // namespace std
 
 template <class T, class U>
 void is(const T& a, const U& b, const char* msg)
 {
   std::stringstream ss;
-  ss << msg << ", Got: " << a << ", expected: " << b;
+  ss << msg << ", Got: " << a << ", expected: " << b << std::endl;
   ok(a == b, ss.str().c_str());
 }
 
 template <>
 void is(const float& a, const float& b, const char* msg)
 {
   // stupidly high, since we mostly care about the correctness of the algorithm
   const float kEpsilon = 0.00001f;
 
   std::stringstream ss;
-  ss << msg << ", Got: " << a << ", expected: " << b;
+  ss << msg << ", Got: " << a << ", expected: " << b << std::endl;
   ok(fabsf(a - b) < kEpsilon, ss.str().c_str());
 }
 
 class ErrorResultMock
 {
 public:
   ErrorResultMock()
     : mRv(NS_OK)
@@ -89,17 +88,17 @@ public:
   }
 
 private:
   nsresult mRv;
 };
 
 typedef AudioEventTimeline Timeline;
 
-void TestSpecExample()
+TEST(AudioEventTimeline, SpecExample)
 {
   // First, run the basic tests
   Timeline timeline(10.0f);
   is(timeline.Value(), 10.0f, "Correct default value returned");
 
   ErrorResultMock rv;
 
   float curve[] = { -1.0f, 0.0f, 1.0f };
@@ -145,17 +144,17 @@ void TestSpecExample()
   is(timeline.GetValueAtTime(0.6), 0.75f, "Correct value");
   is(timeline.GetValueAtTime(0.65), (0.75f * powf(0.05f / 0.75f, 0.5f)), "Correct value");
   is(timeline.GetValueAtTime(0.7), -1.0f, "Correct value");
   is(timeline.GetValueAtTime(0.8), 0.0f, "Correct value");
   is(timeline.GetValueAtTime(0.9), 1.0f, "Correct value");
   is(timeline.GetValueAtTime(1.0), 1.0f, "Correct value");
 }
 
-void TestInvalidEvents()
+TEST(AudioEventTimeline, InvalidEvents)
 {
   static_assert(numeric_limits<float>::has_quiet_NaN, "Platform must have a quiet NaN");
   const float NaN = numeric_limits<float>::quiet_NaN();
   const float Infinity = numeric_limits<float>::infinity();
   Timeline timeline(10.0f);
 
   float curve[] = { -1.0f, 0.0f, 1.0f };
   float badCurve1[] = { -1.0f, NaN, 1.0f };
@@ -213,17 +212,17 @@ void TestInvalidEvents()
   timeline.SetValueCurveAtTime(curve, ArrayLength(curve), 1.0, NaN, rv);
   is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
   timeline.SetValueCurveAtTime(curve, ArrayLength(curve), 1.0, Infinity, rv);
   is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
   timeline.SetValueCurveAtTime(curve, ArrayLength(curve), 1.0, -Infinity, rv);
   is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
 }
 
-void TestEventReplacement()
+TEST(AudioEventTimeline, EventReplacement)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   is(timeline.GetEventCount(), 0u, "No events yet");
   timeline.SetValueAtTime(10.0f, 0.1, rv);
   is(timeline.GetEventCount(), 1u, "One event scheduled now");
@@ -232,17 +231,17 @@ void TestEventReplacement()
   is(timeline.GetEventCount(), 1u, "Event should be replaced");
   is(timeline.GetValueAtTime(0.1), 20.0f, "The first event should be overwritten");
   timeline.LinearRampToValueAtTime(30.0f, 0.1, rv);
   is(rv, NS_OK, "Event scheduling should be successful");
   is(timeline.GetEventCount(), 2u, "Different event type should be appended");
   is(timeline.GetValueAtTime(0.1), 30.0f, "The first event should be overwritten");
 }
 
-void TestEventRemoval()
+TEST(AudioEventTimeline, EventRemoval)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetValueAtTime(10.0f, 0.1, rv);
   timeline.SetValueAtTime(15.0f, 0.15, rv);
   timeline.SetValueAtTime(20.0f, 0.2, rv);
@@ -253,77 +252,77 @@ void TestEventRemoval()
   timeline.CancelScheduledValues(0.3);
   is(timeline.GetEventCount(), 3u, "Should successfully delete one event");
   timeline.CancelScheduledValues(0.12);
   is(timeline.GetEventCount(), 1u, "Should successfully delete two events");
   timeline.CancelAllEvents();
   ok(timeline.HasSimpleValue(), "No event should remain scheduled");
 }
 
-void TestBeforeFirstEventSetValue()
+TEST(AudioEventTimeline, BeforeFirstEventSetValue)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetValueAtTime(20.0f, 1.0, rv);
   is(timeline.GetValueAtTime(0.5), 10.0f, "Retrun the default value before the first event");
 }
 
-void TestBeforeFirstEventSetTarget()
+TEST(AudioEventTimeline, BeforeFirstEventSetTarget)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv);
   is(timeline.GetValueAtTime(0.5), 10.0f, "Retrun the default value before the first event");
 }
 
-void TestBeforeFirstEventLinearRamp()
+TEST(AudioEventTimeline, BeforeFirstEventLinearRamp)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.LinearRampToValueAtTime(20.0f, 1.0, rv);
   is(timeline.GetValueAtTime(0.5), 10.0f, "Retrun the default value before the first event");
 }
 
-void TestBeforeFirstEventExponentialRamp()
+TEST(AudioEventTimeline, BeforeFirstEventExponentialRamp)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.ExponentialRampToValueAtTime(20.0f, 1.0, rv);
   is(timeline.GetValueAtTime(0.5), 10.0f, "Retrun the default value before the first event");
 }
 
-void TestAfterLastValueEvent()
+TEST(AudioEventTimeline, AfterLastValueEvent)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetValueAtTime(20.0f, 1.0, rv);
   is(timeline.GetValueAtTime(1.5), 20.0f, "Return the last value after the last SetValue event");
 }
 
-void TestAfterLastTargetValueEvent()
+TEST(AudioEventTimeline, AfterLastTargetValueEvent)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv);
   is(timeline.GetValueAtTime(10.), (20.f + (10.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after the last SetTarget event based on the curve");
 }
 
-void TestAfterLastTargetValueEventWithValueSet()
+TEST(AudioEventTimeline, AfterLastTargetValueEventWithValueSet)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetValue(50.f);
   timeline.SetTargetAtTime(20.0f, 1.0, 5.0, rv);
 
@@ -333,85 +332,85 @@ void TestAfterLastTargetValueEventWithVa
   // previous times.
   for (double i = 0.0; i < 9.99; i+=0.01) {
     timeline.GetValueAtTime(i);
   }
 
   is(timeline.GetValueAtTime(10.), (20.f + (50.f - 20.f) * expf(-9.0f / 5.0f)), "Return the value after SetValue and the last SetTarget event based on the curve");
 }
 
-void TestValue()
+TEST(AudioEventTimeline, Value)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   is(timeline.Value(), 10.0f, "value should initially match the default value");
   timeline.SetValue(20.0f);
   is(timeline.Value(), 20.0f, "Should be able to set the value");
   timeline.SetValueAtTime(20.0f, 1.0, rv);
   // TODO: The following check needs to change when we compute the value based on the current time of the context
   is(timeline.Value(), 20.0f, "TODO...");
   timeline.SetValue(30.0f);
   is(timeline.Value(), 20.0f, "Should not be able to set the value");
 }
 
-void TestLinearRampAtZero()
+TEST(AudioEventTimeline, LinearRampAtZero)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.LinearRampToValueAtTime(20.0f, 0.0, rv);
   is(timeline.GetValueAtTime(0.0), 20.0f, "Should get the correct value when t0 == t1 == 0");
 }
 
-void TestExponentialRampAtZero()
+TEST(AudioEventTimeline, ExponentialRampAtZero)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.ExponentialRampToValueAtTime(20.0f, 0.0, rv);
   is(timeline.GetValueAtTime(0.0), 20.0f, "Should get the correct value when t0 == t1 == 0");
 }
 
-void TestLinearRampAtSameTime()
+TEST(AudioEventTimeline, LinearRampAtSameTime)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetValueAtTime(5.0f, 1.0, rv);
   timeline.LinearRampToValueAtTime(20.0f, 1.0, rv);
   is(timeline.GetValueAtTime(1.0), 20.0f, "Should get the correct value when t0 == t1");
 }
 
-void TestExponentialRampAtSameTime()
+TEST(AudioEventTimeline, ExponentialRampAtSameTime)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetValueAtTime(5.0f, 1.0, rv);
   timeline.ExponentialRampToValueAtTime(20.0f, 1.0, rv);
   is(timeline.GetValueAtTime(1.0), 20.0f, "Should get the correct value when t0 == t1");
 }
 
-void TestSetTargetZeroTimeConstant()
+TEST(AudioEventTimeline, SetTargetZeroTimeConstant)
 {
   Timeline timeline(10.0f);
 
   ErrorResultMock rv;
 
   timeline.SetTargetAtTime(20.0f, 1.0, 0.0, rv);
   is(timeline.GetValueAtTime(1.0), 20.0f, "Should get the correct value when t0 == t1");
 }
 
-void TestExponentialInvalidPreviousZeroValue()
+TEST(AudioEventTimeline, ExponentialInvalidPreviousZeroValue)
 {
   Timeline timeline(0.f);
 
   ErrorResultMock rv;
 
   timeline.ExponentialRampToValueAtTime(1.f, 1.0, rv);
   is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
   timeline.SetValue(1.f);
@@ -427,51 +426,20 @@ void TestExponentialInvalidPreviousZeroV
   is(rv, NS_ERROR_DOM_SYNTAX_ERR, "Correct error code returned");
   timeline.CancelScheduledValues(0.0);
   is(timeline.GetEventCount(), 0u, "Should have no events scheduled");
   rv = NS_OK;
   timeline.ExponentialRampToValueAtTime(1.f, 1.0, rv);
   is(rv, NS_OK, "Should succeed this time");
 }
 
-void
-TestSettingValueCurveTwice()
+TEST(AudioEventTimeline, SettingValueCurveTwice)
 {
   Timeline timeline(0.f);
   float curve[] = { -1.0f, 0.0f, 1.0f };
 
   ErrorResultMock rv;
 
   timeline.SetValueCurveAtTime(curve, ArrayLength(curve), 0.0f, 0.3f, rv);
   timeline.SetValueCurveAtTime(curve, ArrayLength(curve), 0.0f, 0.3f, rv);
   is(rv, NS_OK, "SetValueCurveAtTime succeeded");
 }
 
-int main()
-{
-  ScopedXPCOM xpcom("TestAudioEventTimeline");
-  if (xpcom.failed()) {
-    return 1;
-  }
-
-  TestSpecExample();
-  TestInvalidEvents();
-  TestEventReplacement();
-  TestEventRemoval();
-  TestBeforeFirstEventSetValue();
-  TestBeforeFirstEventSetTarget();
-  TestBeforeFirstEventLinearRamp();
-  TestBeforeFirstEventExponentialRamp();
-  TestAfterLastValueEvent();
-  TestAfterLastTargetValueEvent();
-  TestAfterLastTargetValueEventWithValueSet();
-  TestValue();
-  TestLinearRampAtZero();
-  TestExponentialRampAtZero();
-  TestLinearRampAtSameTime();
-  TestExponentialRampAtSameTime();
-  TestSetTargetZeroTimeConstant();
-  TestExponentialInvalidPreviousZeroValue();
-  TestSettingValueCurveTwice();
-
-  return gFailCount > 0;
-}
-
rename from dom/media/webaudio/compiledtest/moz.build
rename to dom/media/webaudio/gtest/moz.build
--- a/dom/media/webaudio/compiledtest/moz.build
+++ b/dom/media/webaudio/gtest/moz.build
@@ -1,13 +1,15 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
-GeckoCppUnitTests([
-    'TestAudioEventTimeline',
-])
+UNIFIED_SOURCES += [
+    'TestAudioEventTimeline.cpp',
+]
 
 LOCAL_INCLUDES += [
     '..',
 ]
+
+FINAL_LIBRARY = 'xul-gtest'
--- a/dom/media/webaudio/moz.build
+++ b/dom/media/webaudio/moz.build
@@ -4,17 +4,17 @@
 # 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/.
 
 with Files('*'):
     BUG_COMPONENT = ('Core', 'Web Audio')
 
 DIRS += ['blink']
 
-TEST_DIRS += ['compiledtest']
+TEST_DIRS += ['gtest']
 
 MOCHITEST_MANIFESTS += [
     'test/blink/mochitest.ini',
     'test/mochitest.ini',
 ]
 
 BROWSER_CHROME_MANIFESTS += [
     'test/browser.ini',
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -1,17 +1,16 @@
 [ShowAlignments]
 [ShowSSEConfig]
 [TestAppShellSteadyState]
 [TestArray]
 [TestArrayUtils]
 [TestAtomics]
 [TestAudioBuffers]
 skip-if = os == 'b2g'  # Bug 1062937
-[TestAudioEventTimeline]
 [TestAudioMixer]
 [TestAutoPtr]
 [TestAutoRef]
 [TestBinarySearch]
 [TestBind]
 [TestBloomFilter]
 [TestCOM]
 skip-if = os != 'win'