Bug 1271483 - p16. gtest for list-string functions - r=cpearce
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 26 May 2016 19:24:35 +1000
changeset 302301 da005aa1d83c4a32c2ff1d211d359581013352ed
parent 302300 575198d83ce778cd2dad9e7ce6978b6f58937738
child 302302 08e186081db2275a88437b51e925b92f13f572dc
push id30356
push usercbook@mozilla.com
push dateWed, 22 Jun 2016 11:45:58 +0000
treeherdermozilla-central@4e17dca08962 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1271483
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1271483 - p16. gtest for list-string functions - r=cpearce Moved templated code to VideoUtils.h, so it can more easily be reused, and tested. MozReview-Commit-ID: 3vOvaj5VVhm
dom/media/DecoderDoctorDiagnostics.cpp
dom/media/VideoUtils.h
dom/media/gtest/TestVideoUtils.cpp
dom/media/gtest/moz.build
--- a/dom/media/DecoderDoctorDiagnostics.cpp
+++ b/dom/media/DecoderDoctorDiagnostics.cpp
@@ -12,16 +12,17 @@
 #include "nsContentUtils.h"
 #include "nsGkAtoms.h"
 #include "nsIDocument.h"
 #include "nsIObserverService.h"
 #include "nsIScriptError.h"
 #include "nsITimer.h"
 #include "nsIWeakReference.h"
 #include "nsPluginHost.h"
+#include "VideoUtils.h"
 
 static mozilla::LazyLogModule sDecoderDoctorLog("DecoderDoctor");
 #define DD_LOG(level, arg, ...) MOZ_LOG(sDecoderDoctorLog, level, (arg, ##__VA_ARGS__))
 #define DD_DEBUG(arg, ...) DD_LOG(mozilla::LogLevel::Debug, arg, ##__VA_ARGS__)
 #define DD_INFO(arg, ...) DD_LOG(mozilla::LogLevel::Info, arg, ##__VA_ARGS__)
 #define DD_WARN(arg, ...) DD_LOG(mozilla::LogLevel::Warning, arg, ##__VA_ARGS__)
 
 namespace mozilla {
@@ -237,129 +238,16 @@ DecoderDoctorDocumentWatcher::EnsureTime
     if (NS_WARN_IF(NS_FAILED(
           mTimer->InitWithCallback(
             this, sAnalysisPeriod_ms, nsITimer::TYPE_ONE_SHOT)))) {
       mTimer = nullptr;
     }
   }
 }
 
-template <typename String>
-class StringListRange
-{
-  typedef typename String::char_type CharType;
-  typedef const CharType* Pointer;
-
-public:
-  // Iterator into range, trims items and skips empty items.
-  class Iterator
-  {
-  public:
-    bool operator!=(const Iterator& a) const
-    {
-      return mStart != a.mStart || mEnd != a.mEnd;
-    }
-    Iterator& operator++()
-    {
-      SearchItemAt(mComma + 1);
-      return *this;
-    }
-    typedef decltype(Substring(Pointer(), Pointer())) DereferencedType;
-    DereferencedType operator*()
-    {
-      return Substring(mStart, mEnd);
-    }
-  private:
-    friend class StringListRange;
-    Iterator(const CharType* aRangeStart, uint32_t aLength)
-      : mRangeEnd(aRangeStart + aLength)
-    {
-      SearchItemAt(aRangeStart);
-    }
-    void SearchItemAt(Pointer start)
-    {
-      // First, skip leading whitespace.
-      for (Pointer p = start; ; ++p) {
-        if (p >= mRangeEnd) {
-          mStart = mEnd = mComma = mRangeEnd;
-          return;
-        }
-        auto c = *p;
-        if (c == CharType(',')) {
-          // Comma -> Empty item -> Skip.
-        } else if (c != CharType(' ')) {
-          mStart = p;
-          break;
-        }
-      }
-      // Find comma, recording start of trailing space.
-      Pointer trailingWhitespace = nullptr;
-      for (Pointer p = mStart + 1; ; ++p) {
-        if (p >= mRangeEnd) {
-          mEnd = trailingWhitespace ? trailingWhitespace : p;
-          mComma = p;
-          return;
-        }
-        auto c = *p;
-        if (c == CharType(',')) {
-          mEnd = trailingWhitespace ? trailingWhitespace : p;
-          mComma = p;
-          return;
-        }
-        if (c == CharType(' ')) {
-          // Found a whitespace -> Record as trailing if not first one.
-          if (!trailingWhitespace) {
-            trailingWhitespace = p;
-          }
-        } else {
-          // Found a non-whitespace -> Reset trailing whitespace if needed.
-          if (trailingWhitespace) {
-            trailingWhitespace = nullptr;
-          }
-        }
-      }
-    }
-    const Pointer mRangeEnd;
-    Pointer mStart;
-    Pointer mEnd;
-    Pointer mComma;
-  };
-
-  explicit StringListRange(const String& aList) : mList(aList) {}
-  Iterator begin()
-  {
-    return Iterator(mList.Data(), mList.Length());
-  }
-  Iterator end()
-  {
-    return Iterator(mList.Data() + mList.Length(), 0);
-  }
-private:
-  const String& mList;
-};
-
-template <typename String>
-StringListRange<String>
-MakeStringListRange(const String& aList)
-{
-  return StringListRange<String>(aList);
-}
-
-template <typename ListString, typename ItemString>
-static bool
-StringListContains(const ListString& aList, const ItemString& aItem)
-{
-  for (const auto& listItem : MakeStringListRange(aList)) {
-    if (listItem.Equals(aItem)) {
-      return true;
-    }
-  }
-  return false;
-}
-
 static const NotificationAndReportStringId sMediaWidevineNoWMFNoSilverlight =
   { dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
     "MediaWidevineNoWMFNoSilverlight" };
 static const NotificationAndReportStringId sMediaWMFNeeded =
   { dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
     "MediaWMFNeeded" };
 static const NotificationAndReportStringId sMediaPlatformDecoderNotFound =
   { dom::DecoderDoctorNotificationType::Platform_decoder_not_found,
--- a/dom/media/VideoUtils.h
+++ b/dom/media/VideoUtils.h
@@ -329,11 +329,124 @@ bool
 IsH264ContentType(const nsAString& aContentType);
 
 bool
 IsAACContentType(const nsAString& aContentType);
 
 bool
 IsAACCodecString(const nsAString& aCodec);
 
+template <typename String>
+class StringListRange
+{
+  typedef typename String::char_type CharType;
+  typedef const CharType* Pointer;
+
+public:
+  // Iterator into range, trims items and skips empty items.
+  class Iterator
+  {
+  public:
+    bool operator!=(const Iterator& a) const
+    {
+      return mStart != a.mStart || mEnd != a.mEnd;
+    }
+    Iterator& operator++()
+    {
+      SearchItemAt(mComma + 1);
+      return *this;
+    }
+    typedef decltype(Substring(Pointer(), Pointer())) DereferencedType;
+    DereferencedType operator*()
+    {
+      return Substring(mStart, mEnd);
+    }
+  private:
+    friend class StringListRange;
+    Iterator(const CharType* aRangeStart, uint32_t aLength)
+      : mRangeEnd(aRangeStart + aLength)
+    {
+      SearchItemAt(aRangeStart);
+    }
+    void SearchItemAt(Pointer start)
+    {
+      // First, skip leading whitespace.
+      for (Pointer p = start; ; ++p) {
+        if (p >= mRangeEnd) {
+          mStart = mEnd = mComma = mRangeEnd;
+          return;
+        }
+        auto c = *p;
+        if (c == CharType(',')) {
+          // Comma -> Empty item -> Skip.
+        } else if (c != CharType(' ')) {
+          mStart = p;
+          break;
+        }
+      }
+      // Find comma, recording start of trailing space.
+      Pointer trailingWhitespace = nullptr;
+      for (Pointer p = mStart + 1; ; ++p) {
+        if (p >= mRangeEnd) {
+          mEnd = trailingWhitespace ? trailingWhitespace : p;
+          mComma = p;
+          return;
+        }
+        auto c = *p;
+        if (c == CharType(',')) {
+          mEnd = trailingWhitespace ? trailingWhitespace : p;
+          mComma = p;
+          return;
+        }
+        if (c == CharType(' ')) {
+          // Found a whitespace -> Record as trailing if not first one.
+          if (!trailingWhitespace) {
+            trailingWhitespace = p;
+          }
+        } else {
+          // Found a non-whitespace -> Reset trailing whitespace if needed.
+          if (trailingWhitespace) {
+            trailingWhitespace = nullptr;
+          }
+        }
+      }
+    }
+    const Pointer mRangeEnd;
+    Pointer mStart;
+    Pointer mEnd;
+    Pointer mComma;
+  };
+
+  explicit StringListRange(const String& aList) : mList(aList) {}
+  Iterator begin()
+  {
+    return Iterator(mList.Data(), mList.Length());
+  }
+  Iterator end()
+  {
+    return Iterator(mList.Data() + mList.Length(), 0);
+  }
+private:
+  const String& mList;
+};
+
+template <typename String>
+StringListRange<String>
+MakeStringListRange(const String& aList)
+{
+  return StringListRange<String>(aList);
+}
+
+template <typename ListString, typename ItemString>
+static bool
+StringListContains(const ListString& aList, const ItemString& aItem)
+{
+  for (const auto& listItem : MakeStringListRange(aList)) {
+    if (listItem.Equals(aItem)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 } // end namespace mozilla
 
 #endif
new file mode 100644
--- /dev/null
+++ b/dom/media/gtest/TestVideoUtils.cpp
@@ -0,0 +1,80 @@
+/* -*- 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 "nsString.h"
+#include "VideoUtils.h"
+
+using namespace mozilla;
+
+TEST(StringListRange, MakeStringListRange)
+{
+  static const struct
+  {
+    const char* mList;
+    const char* mExpected;
+  } tests[] =
+  {
+    { "", "" },
+    { " ", "" },
+    { ",", "" },
+    { " , ", "" },
+    { "a", "a|" },
+    { "  a  ", "a|" },
+    { "aa,bb", "aa|bb|" },
+    { " a a ,  b b  ", "a a|b b|" },
+    { " , ,a 1,,  ,b  2,", "a 1|b  2|" }
+  };
+
+  for (const auto& test : tests) {
+    nsCString list(test.mList);
+    nsCString out;
+    for (const auto& item : MakeStringListRange(list)) {
+      out += item;
+      out += "|";
+    }
+    EXPECT_STREQ(test.mExpected, out.Data());
+  }
+}
+
+TEST(StringListRange, StringListContains)
+{
+  static const struct
+  {
+    const char* mList;
+    const char* mItemToSearch;
+    bool mExpected;
+  } tests[] =
+  {
+    { "", "", false },
+    { "", "a", false },
+    { " ", "a", false },
+    { ",", "a", false },
+    { " , ", "", false },
+    { " , ", "a", false },
+    { "a", "a", true },
+    { "a", "b", false },
+    { "  a  ", "a", true },
+    { "aa,bb", "aa", true },
+    { "aa,bb", "bb", true },
+    { "aa,bb", "cc", false },
+    { "aa,bb", " aa ", false },
+    { " a a ,  b b  ", "a a", true },
+    { " , ,a 1,,  ,b  2,", "a 1", true },
+    { " , ,a 1,,  ,b  2,", "b  2", true },
+    { " , ,a 1,,  ,b  2,", "", false },
+    { " , ,a 1,,  ,b  2,", " ", false },
+    { " , ,a 1,,  ,b  2,", "A 1", false },
+    { " , ,A 1,,  ,b  2,", "a 1", false }
+  };
+
+  for (const auto& test : tests) {
+    nsCString list(test.mList);
+    nsCString itemToSearch(test.mItemToSearch);
+    EXPECT_EQ(test.mExpected, StringListContains(list, itemToSearch))
+      << "trying to find \"" << itemToSearch.Data()
+      << "\" in \"" << list.Data() << "\"";
+  }
+}
--- a/dom/media/gtest/moz.build
+++ b/dom/media/gtest/moz.build
@@ -15,16 +15,17 @@ UNIFIED_SOURCES += [
     'TestMediaEventSource.cpp',
     'TestMediaFormatReader.cpp',
     'TestMozPromise.cpp',
     'TestMP3Demuxer.cpp',
     'TestMP4Demuxer.cpp',
     # 'TestMP4Reader.cpp', disabled so we can turn check tests back on (bug 1175752)
     'TestTrackEncoder.cpp',
     'TestVideoSegment.cpp',
+    'TestVideoUtils.cpp',
     'TestVPXDecoding.cpp',
     'TestWebMBuffered.cpp',
 ]
 
 if CONFIG['MOZ_EME']:
     UNIFIED_SOURCES += [
         'TestEME.cpp',
     ]