Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/xpcom/tests/gtest/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 7 kB image not shown  

Quelle  TestObserverService.cpp   Sprache: 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 "nsISupports.h"
#include "nsIObserverService.h"
#include "nsIObserver.h"
#include "nsISimpleEnumerator.h"
#include "nsComponentManagerUtils.h"

#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsWeakReference.h"

#include "mozilla/gtest/MozAssertions.h"
#include "mozilla/RefPtr.h"

#include "gtest/gtest.h"

static void testResult(nsresult rv) {
  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), mObservations(0) {}
  NS_DECL_ISUPPORTS
  NS_DECL_NSIOBSERVER

  nsString mName;
  int mObservations;
  static int sTotalObservations;

  nsString mExpectedData;

 private:
  ~TestObserver() = default;
};

NS_IMPL_ISUPPORTS(TestObserver, nsIObserver, nsISupportsWeakReference)

int TestObserver::sTotalObservations;

NS_IMETHODIMP
TestObserver::Observe(nsISupports* aSubject, const char* aTopic,
                      const char16_t* someData) {
  mObservations++;
  sTotalObservations++;

  if (!mExpectedData.IsEmpty()) {
    EXPECT_TRUE(mExpectedData.Equals(someData));
  }

  return NS_OK;
}

static nsISupports* ToSupports(TestObserver* aObs) {
  return static_cast<nsIObserver*>(aObs);
}

static void TestExpectedCount(nsIObserverService* svc, const char* topic,
                              size_t expected) {
  nsCOMPtr<nsISimpleEnumerator> e;
  nsresult rv = svc->EnumerateObservers(topic, getter_AddRefs(e));
  testResult(rv);
  EXPECT_TRUE(e);

  bool hasMore = false;
  rv = e->HasMoreElements(&hasMore);
  testResult(rv);

  if (expected == 0) {
    EXPECT_FALSE(hasMore);
    return;
  }

  size_t count = 0;
  while (hasMore) {
    count++;

    // Grab the element.
    nsCOMPtr<nsISupports> supports;
    e->GetNext(getter_AddRefs(supports));
    ASSERT_TRUE(supports);

    // Move on.
    rv = e->HasMoreElements(&hasMore);
    testResult(rv);
  }

  EXPECT_EQ(count, expected);
}

TEST(ObserverService, Creation)
{
  nsresult rv;
  nsCOMPtr<nsIObserverService> svc =
      do_CreateInstance("@mozilla.org/observer-service;1", &rv);

  ASSERT_EQ(rv, NS_OK);
  ASSERT_TRUE(svc);
}

TEST(ObserverService, AddObserver)
{
  nsCOMPtr<nsIObserverService> svc =
      do_CreateInstance("@mozilla.org/observer-service;1");

  // Add a strong ref.
  RefPtr<TestObserver> a = new TestObserver(u"A"_ns);
  nsresult rv = svc->AddObserver(a, "Foo"false);
  testResult(rv);

  // Add a few weak ref.
  RefPtr<TestObserver> b = new TestObserver(u"B"_ns);
  rv = svc->AddObserver(b, "Bar"true);
  testResult(rv);
}

TEST(ObserverService, RemoveObserver)
{
  nsCOMPtr<nsIObserverService> svc =
      do_CreateInstance("@mozilla.org/observer-service;1");

  RefPtr<TestObserver> a = new TestObserver(u"A"_ns);
  RefPtr<TestObserver> b = new TestObserver(u"B"_ns);
  RefPtr<TestObserver> c = new TestObserver(u"C"_ns);

  svc->AddObserver(a, "Foo"false);
  svc->AddObserver(b, "Foo"true);

  // Remove from non-existent topic.
  nsresult rv = svc->RemoveObserver(a, "Bar");
  ASSERT_NS_FAILED(rv);

  // Remove a.
  testResult(svc->RemoveObserver(a, "Foo"));

  // Remove b.
  testResult(svc->RemoveObserver(b, "Foo"));

  // Attempt to remove c.
  rv = svc->RemoveObserver(c, "Foo");
  ASSERT_NS_FAILED(rv);
}

TEST(ObserverService, EnumerateEmpty)
{
  nsCOMPtr<nsIObserverService> svc =
      do_CreateInstance("@mozilla.org/observer-service;1");

  // Try with no observers.
  TestExpectedCount(svc, "A", 0);

  // Now add an observer and enumerate an unobserved topic.
  RefPtr<TestObserver> a = new TestObserver(u"A"_ns);
  testResult(svc->AddObserver(a, "Foo"false));

  TestExpectedCount(svc, "A", 0);
}

TEST(ObserverService, Enumerate)
{
  nsCOMPtr<nsIObserverService> svc =
      do_CreateInstance("@mozilla.org/observer-service;1");

  const size_t kFooCount = 10;
  for (size_t i = 0; i < kFooCount; i++) {
    RefPtr<TestObserver> a = new TestObserver(u"A"_ns);
    testResult(svc->AddObserver(a, "Foo"false));
  }

  const size_t kBarCount = kFooCount / 2;
  for (size_t i = 0; i < kBarCount; i++) {
    RefPtr<TestObserver> a = new TestObserver(u"A"_ns);
    testResult(svc->AddObserver(a, "Bar"false));
  }

  // Enumerate "Foo".
  TestExpectedCount(svc, "Foo", kFooCount);

  // Enumerate "Bar".
  TestExpectedCount(svc, "Bar", kBarCount);
}

TEST(ObserverService, EnumerateWeakRefs)
{
  nsCOMPtr<nsIObserverService> svc =
      do_CreateInstance("@mozilla.org/observer-service;1");

  const size_t kFooCount = 10;
  for (size_t i = 0; i < kFooCount; i++) {
    RefPtr<TestObserver> a = new TestObserver(u"A"_ns);
    testResult(svc->AddObserver(a, "Foo"true));
  }

  // All refs are out of scope, expect enumeration to be empty.
  TestExpectedCount(svc, "Foo", 0);

  // Now test a mixture.
  for (size_t i = 0; i < kFooCount; i++) {
    RefPtr<TestObserver> a = new TestObserver(u"A"_ns);
    RefPtr<TestObserver> b = new TestObserver(u"B"_ns);

    // Register a as weak for "Foo".
    testResult(svc->AddObserver(a, "Foo"true));

    // Register b as strong for "Foo".
    testResult(svc->AddObserver(b, "Foo"false));
  }

  // Expect the b instances to stick around.
  TestExpectedCount(svc, "Foo", kFooCount);

  // Now add a couple weak refs, but don't go out of scope.
  RefPtr<TestObserver> a = new TestObserver(u"A"_ns);
  testResult(svc->AddObserver(a, "Foo"true));
  RefPtr<TestObserver> b = new TestObserver(u"B"_ns);
  testResult(svc->AddObserver(b, "Foo"true));

  // Expect all the observers from before and the two new ones.
  TestExpectedCount(svc, "Foo", kFooCount + 2);
}

TEST(ObserverService, TestNotify)
{
  nsCString topicA;
  topicA.Assign("topic-A");
  nsCString topicB;
  topicB.Assign("topic-B");

  nsCOMPtr<nsIObserverService> svc =
      do_CreateInstance("@mozilla.org/observer-service;1");

  RefPtr<TestObserver> aObserver = new TestObserver(u"Observer-A"_ns);
  RefPtr<TestObserver> bObserver = new TestObserver(u"Observer-B"_ns);

  // Add two observers for topicA.
  testResult(svc->AddObserver(aObserver, topicA.get(), false));
  testResult(svc->AddObserver(bObserver, topicA.get(), false));

  // Add one observer for topicB.
  testResult(svc->AddObserver(bObserver, topicB.get(), false));

  // Notify topicA.
  const char16_t* dataA = u"Testing Notify(observer-A, topic-A)";
  aObserver->mExpectedData = dataA;
  bObserver->mExpectedData = dataA;
  nsresult rv =
      svc->NotifyObservers(ToSupports(aObserver), topicA.get(), dataA);
  testResult(rv);
  ASSERT_EQ(aObserver->mObservations, 1);
  ASSERT_EQ(bObserver->mObservations, 1);

  // Notify topicB.
  const char16_t* dataB = u"Testing Notify(observer-B, topic-B)";
  bObserver->mExpectedData = dataB;
  rv = svc->NotifyObservers(ToSupports(bObserver), topicB.get(), dataB);
  testResult(rv);
  ASSERT_EQ(aObserver->mObservations, 1);
  ASSERT_EQ(bObserver->mObservations, 2);

  // Remove one of the topicA observers, make sure it's not notified.
  testResult(svc->RemoveObserver(aObserver, topicA.get()));

  // Notify topicA, only bObserver is expected to be notified.
  bObserver->mExpectedData = dataA;
  rv = svc->NotifyObservers(ToSupports(aObserver), topicA.get(), dataA);
  testResult(rv);
  ASSERT_EQ(aObserver->mObservations, 1);
  ASSERT_EQ(bObserver->mObservations, 3);

  // Remove the other topicA observer, make sure none are notified.
  testResult(svc->RemoveObserver(bObserver, topicA.get()));
  rv = svc->NotifyObservers(ToSupports(aObserver), topicA.get(), dataA);
  testResult(rv);
  ASSERT_EQ(aObserver->mObservations, 1);
  ASSERT_EQ(bObserver->mObservations, 3);
}

89%


¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.