Bug 1313479 - Part 1: Convert TestObserverService to a gtest. r=froydnj
authorEric Rahm <erahm@mozilla.com>
Fri, 04 Nov 2016 16:23:58 -0700
changeset 321082 921433b91312e220341c858581e852c843d89d21
parent 321081 fd302c72543de9f896f35fa87d9b2d07f49a4f1f
child 321083 a3b30fb7d3e6a4f97889180b6348d7771bd05891
push id83521
push usererahm@mozilla.com
push dateFri, 04 Nov 2016 23:24:08 +0000
treeherdermozilla-inbound@a3b30fb7d3e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfroydnj
bugs1313479
milestone52.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 1313479 - Part 1: Convert TestObserverService to a gtest. r=froydnj This is a straightforward conversion to a gtest. The test itself is updated to use RefPtr/nsCOMPtr where appropriate to avoid memory leaks. MozReview-Commit-ID: JyHF3iTaoOg
testing/cppunittest.ini
xpcom/tests/TestObserverService.cpp
xpcom/tests/gtest/TestObserverService.cpp
xpcom/tests/gtest/moz.build
xpcom/tests/moz.build
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -42,17 +42,16 @@ skip-if = os != 'win'
 [TestMacroArgs]
 [TestMacroForEach]
 [TestMathAlgorithms]
 [TestMaybe]
 [TestNativeXMLHttpRequest]
 skip-if = os == 'b2g' || os == 'android'  #Bug 919642
 [TestNtPathToDosPath]
 skip-if = os != 'win'
-[TestObserverService]
 [TestPLDHash]
 skip-if = os == 'b2g'  #Bug 1038197
 [TestPair]
 [TestPlainTextSerializer]
 skip-if = os == 'b2g' || os == 'android'  #Bug 919599
 [TestPoisonArea]
 skip-if = os == 'android' # Bug 1147630
 [TestRefPtr]
rename from xpcom/tests/TestObserverService.cpp
rename to xpcom/tests/gtest/TestObserverService.cpp
--- a/xpcom/tests/TestObserverService.cpp
+++ b/xpcom/tests/gtest/TestObserverService.cpp
@@ -3,150 +3,128 @@
  * 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 "nsISupports.h"
 #include "nsIComponentManager.h"
 #include "nsIObserverService.h"
 #include "nsIObserver.h"
 #include "nsISimpleEnumerator.h"
-#include "nsStringGlue.h"
+#include "nsComponentManagerUtils.h"
+
+#include "nsCOMPtr.h"
 #include "nsWeakReference.h"
-#include "nsComponentManagerUtils.h"
-#include "mozilla/Attributes.h"
 
-#include <stdio.h>
+#include "mozilla/RefPtr.h"
 
-static nsIObserverService *anObserverService = nullptr;
+#include "gtest/gtest.h"
 
 static void testResult( nsresult rv ) {
-  if ( NS_SUCCEEDED( rv ) ) {
-    printf("...ok\n");
-  } else {
-    printf("...failed, rv=0x%x\n", (int)rv);
-  }
-  return;
-}
-
-void printString(nsString &str) {
-  printf("%s", NS_ConvertUTF16toUTF8(str).get());
+  EXPECT_TRUE(NS_SUCCEEDED(rv)) << "0x" << std::hex << (int)rv;
 }
 
 class TestObserver final : public nsIObserver,
   public nsSupportsWeakReference
 {
 public:
   explicit TestObserver( const nsAString &name )
-    : mName( name ) {
+    : mName( name )
+    , mObservations( 0 ) {
     }
   NS_DECL_ISUPPORTS
-    NS_DECL_NSIOBSERVER
+  NS_DECL_NSIOBSERVER
 
-    nsString mName;
+  nsString mName;
+  int mObservations;
 
 private:
   ~TestObserver() {}
 };
 
 NS_IMPL_ISUPPORTS( TestObserver, nsIObserver, nsISupportsWeakReference )
 
 NS_IMETHODIMP
 TestObserver::Observe(nsISupports *aSubject,
     const char *aTopic,
     const char16_t *someData ) {
-  nsCString topic( aTopic );
-  nsString data( someData );
-  /*
-     The annoying double-cast below is to work around an annoying bug in
-     the compiler currently used on wensleydale.  This is a test.
-  */
-  printString(mName);
-  printf(" has observed something: subject@%p", (void*)aSubject);
-  printf(" name=");
-  printString(reinterpret_cast<TestObserver*>(reinterpret_cast<void*>(aSubject))->mName);
-  printf(" aTopic=%s", topic.get());
-  printf(" someData=");
-  printString(data);
-  printf("\n");
+  mObservations++;
   return NS_OK;
 }
 
-int main(int argc, char *argv[])
+static nsISupports* ToSupports(TestObserver* aObs)
+{
+  return static_cast<nsIObserver*>(aObs);
+}
+
+TEST(ObserverService, Tests)
 {
   nsCString topicA; topicA.Assign( "topic-A" );
   nsCString topicB; topicB.Assign( "topic-B" );
   nsresult rv;
 
-  nsresult res = CallCreateInstance("@mozilla.org/observer-service;1", &anObserverService);
+  nsCOMPtr<nsIObserverService> anObserverService =
+    do_CreateInstance("@mozilla.org/observer-service;1", &rv);
+
+  ASSERT_EQ(rv, NS_OK);
+  ASSERT_TRUE(anObserverService);
 
-  if (res == NS_OK) {
+  RefPtr<TestObserver> aObserver = new TestObserver(NS_LITERAL_STRING("Observer-A"));
+  RefPtr<TestObserver> bObserver = new TestObserver(NS_LITERAL_STRING("Observer-B"));
+
+  rv = anObserverService->AddObserver(aObserver, topicA.get(), false);
+  testResult(rv);
 
-    nsIObserver *aObserver = new TestObserver(NS_LITERAL_STRING("Observer-A"));
-    aObserver->AddRef();
-    nsIObserver *bObserver = new TestObserver(NS_LITERAL_STRING("Observer-B"));
-    bObserver->AddRef();
+  rv = anObserverService->AddObserver(bObserver, topicA.get(), false);
+  testResult(rv);
+
+  rv = anObserverService->AddObserver(bObserver, topicB.get(), false);
+  testResult(rv);
 
-    printf("Adding Observer-A as observer of topic-A...\n");
-    rv = anObserverService->AddObserver(aObserver, topicA.get(), false);
-    testResult(rv);
-
-    printf("Adding Observer-B as observer of topic-A...\n");
-    rv = anObserverService->AddObserver(bObserver, topicA.get(), false);
-    testResult(rv);
+  rv = anObserverService->NotifyObservers(ToSupports(aObserver),
+      topicA.get(),
+      u"Testing Notify(observer-A, topic-A)" );
+  testResult(rv);
+  ASSERT_EQ(aObserver->mObservations, 1);
+  ASSERT_EQ(bObserver->mObservations, 1);
 
-    printf("Adding Observer-B as observer of topic-B...\n");
-    rv = anObserverService->AddObserver(bObserver, topicB.get(), false);
-    testResult(rv);
+  rv = anObserverService->NotifyObservers(ToSupports(bObserver),
+      topicB.get(),
+      u"Testing Notify(observer-B, topic-B)" );
+  testResult(rv);
+  ASSERT_EQ(aObserver->mObservations, 1);
+  ASSERT_EQ(bObserver->mObservations, 2);
 
-    printf("Testing Notify(observer-A, topic-A)...\n");
-    rv = anObserverService->NotifyObservers( aObserver,
-        topicA.get(),
-        u"Testing Notify(observer-A, topic-A)" );
-    testResult(rv);
+  nsCOMPtr<nsISimpleEnumerator> e;
+  rv = anObserverService->EnumerateObservers(topicA.get(), getter_AddRefs(e));
+  testResult(rv);
+  ASSERT_TRUE(e);
 
-    printf("Testing Notify(observer-B, topic-B)...\n");
-    rv = anObserverService->NotifyObservers( bObserver,
-        topicB.get(),
-        u"Testing Notify(observer-B, topic-B)" );
-    testResult(rv);
+  bool loop = true;
+  int count = 0;
+  while( NS_SUCCEEDED(e->HasMoreElements(&loop)) && loop)
+  {
+    count++;
 
-    printf("Testing EnumerateObserverList (for topic-A)...\n");
-    nsCOMPtr<nsISimpleEnumerator> e;
-    rv = anObserverService->EnumerateObservers(topicA.get(), getter_AddRefs(e));
+    nsCOMPtr<nsISupports> supports;
+    e->GetNext(getter_AddRefs(supports));
+    ASSERT_TRUE(supports);
 
+    nsCOMPtr<nsIObserver> observer = do_QueryInterface(supports);
+    ASSERT_TRUE(observer);
+
+    rv = observer->Observe( observer,
+        topicA.get(),
+        u"during enumeration" );
     testResult(rv);
+  }
 
-    printf("Enumerating observers of topic-A...\n");
-    if ( e ) {
-      nsCOMPtr<nsIObserver> observer;
-      bool loop = true;
-      while( NS_SUCCEEDED(e->HasMoreElements(&loop)) && loop)
-      {
-        nsCOMPtr<nsISupports> supports;
-        e->GetNext(getter_AddRefs(supports));
-        observer = do_QueryInterface(supports);
-        printf("Calling observe on enumerated observer ");
-        printString(reinterpret_cast<TestObserver*>
-            (reinterpret_cast<void*>(observer.get()))->mName);
-        printf("...\n");
-        rv = observer->Observe( observer,
-            topicA.get(),
-            u"during enumeration" );
-        testResult(rv);
-      }
-    }
-    printf("...done enumerating observers of topic-A\n");
+  ASSERT_EQ(count, 2);
+  ASSERT_EQ(aObserver->mObservations, 2);
+  ASSERT_EQ(bObserver->mObservations, 3);
 
-    printf("Removing Observer-A...\n");
-    rv = anObserverService->RemoveObserver(aObserver, topicA.get());
-    testResult(rv);
-
+  rv = anObserverService->RemoveObserver(aObserver, topicA.get());
+  testResult(rv);
 
-    printf("Removing Observer-B (topic-A)...\n");
-    rv = anObserverService->RemoveObserver(bObserver, topicB.get());
-    testResult(rv);
-    printf("Removing Observer-B (topic-B)...\n");
-    rv = anObserverService->RemoveObserver(bObserver, topicA.get());
-    testResult(rv);
-
-  }
-  return 0;
+  rv = anObserverService->RemoveObserver(bObserver, topicB.get());
+  testResult(rv);
+  rv = anObserverService->RemoveObserver(bObserver, topicA.get());
+  testResult(rv);
 }
--- a/xpcom/tests/gtest/moz.build
+++ b/xpcom/tests/gtest/moz.build
@@ -15,16 +15,17 @@ UNIFIED_SOURCES += [
     'TestCRT.cpp',
     'TestEncoding.cpp',
     'TestEscapeURL.cpp',
     'TestExpirationTracker.cpp',
     'TestFile.cpp',
     'TestID.cpp',
     'TestNSPRLogModulesParser.cpp',
     'TestObserverArray.cpp',
+    'TestObserverService.cpp',
     'TestPipes.cpp',
     'TestPLDHash.cpp',
     'TestPriorityQueue.cpp',
     'TestSlicedInputStream.cpp',
     'TestSnappyStreams.cpp',
     'TestStateWatching.cpp',
     'TestStorageStream.cpp',
     'TestStrings.cpp',
--- a/xpcom/tests/moz.build
+++ b/xpcom/tests/moz.build
@@ -41,17 +41,16 @@ if CONFIG['OS_TARGET'] == 'WINNT':
 if CONFIG['WRAP_STL_INCLUDES'] and not CONFIG['CLANG_CL']:
     GeckoSimplePrograms([
         'TestSTLWrappers',
     ])
 
 XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
 
 GeckoCppUnitTests([
-    'TestObserverService',
     'TestStringAPI',
     'TestTArray',
     'TestTextFormatter',
     'TestThreadUtils',
     'TestTimers'
 ])
 
 if CONFIG['MOZ_MEMORY']: