Bug 1204872 - Add gtest for AccessibleCaretManager. r=roc
authorTing-Yu Lin <tlin@mozilla.com>
Sat, 19 Sep 2015 01:05:19 +0800
changeset 295902 0a3148919d902c36e92633cf3784d6aa5909335e
parent 295901 51c8dca62df70a3d9de67bc4be6e3d10b2e8cc11
child 295903 c9dbc1119342145b08883bb85566a270a3081b48
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1204872, 1169974
milestone43.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 1204872 - Add gtest for AccessibleCaretManager. r=roc Add basic gtest to ensure AccessibleCaret and AccessibleCaretManager are both testable. More tests to come. Allow -Winconsistent-missing-override warning in gtest since MOCK_METHOD does not have 'override' keyword. See bug 1169974.
layout/base/gtest/TestAccessibleCaretManager.cpp
layout/base/gtest/moz.build
new file mode 100644
--- /dev/null
+++ b/layout/base/gtest/TestAccessibleCaretManager.cpp
@@ -0,0 +1,208 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "gmock/gmock.h"
+
+#include <string>
+
+#include "AccessibleCaret.h"
+#include "AccessibleCaretManager.h"
+
+using ::testing::DefaultValue;
+using ::testing::Eq;
+using ::testing::InSequence;
+using ::testing::MockFunction;
+using ::testing::Return;
+using ::testing::_;
+
+// -----------------------------------------------------------------------------
+// This file tests CaretStateChanged events and the appearance of the two
+// AccessibleCarets manipulated by AccessibleCaretManager.
+
+namespace mozilla
+{
+using dom::CaretChangedReason;
+
+class AccessibleCaretManagerTester : public ::testing::Test
+{
+public:
+  class MockAccessibleCaret : public AccessibleCaret
+  {
+  public:
+    MockAccessibleCaret() : AccessibleCaret(nullptr) {}
+
+    virtual void SetAppearance(Appearance aAppearance) override
+    {
+      // A simplified version without touching CaretElement().
+      mAppearance = aAppearance;
+    }
+
+    virtual void SetSelectionBarEnabled(bool aEnabled) override
+    {
+      // A simplified version without touching CaretElement().
+      mSelectionBarEnabled = aEnabled;
+    }
+
+    MOCK_METHOD2(SetPosition,
+                 PositionChangedResult(nsIFrame* aFrame, int32_t aOffset));
+
+  }; // class MockAccessibleCaret
+
+  class MockAccessibleCaretManager : public AccessibleCaretManager
+  {
+  public:
+    using CaretMode = AccessibleCaretManager::CaretMode;
+    using AccessibleCaretManager::UpdateCarets;
+
+    MockAccessibleCaretManager()
+      : AccessibleCaretManager(nullptr)
+    {
+      mFirstCaret = MakeUnique<MockAccessibleCaret>();
+      mSecondCaret = MakeUnique<MockAccessibleCaret>();
+    }
+
+    CaretMode LastUpdateCaretMode() const
+    {
+      return mLastUpdateCaretMode;
+    }
+
+    MockAccessibleCaret& FirstCaret()
+    {
+      return static_cast<MockAccessibleCaret&>(*mFirstCaret);
+    }
+
+    MockAccessibleCaret& SecondCaret()
+    {
+      return static_cast<MockAccessibleCaret&>(*mSecondCaret);
+    }
+
+    virtual bool CompareTreePosition(nsIFrame* aStartFrame,
+                                     nsIFrame* aEndFrame) const override
+    {
+      return true;
+    }
+
+    virtual bool IsCaretDisplayableInCursorMode(
+      nsIFrame** aOutFrame = nullptr, int32_t* aOutOffset = nullptr) const override
+    {
+      return true;
+    }
+
+    virtual void UpdateCaretsForTilt() override {}
+
+    MOCK_CONST_METHOD0(GetCaretMode, CaretMode());
+    MOCK_CONST_METHOD1(DispatchCaretStateChangedEvent,
+                       void(CaretChangedReason aReason));
+    MOCK_CONST_METHOD1(HasNonEmptyTextContent, bool(nsINode* aNode));
+
+  }; // class MockAccessibleCaretManager
+
+  using Appearance = AccessibleCaret::Appearance;
+  using PositionChangedResult = AccessibleCaret::PositionChangedResult;
+  using CaretMode = MockAccessibleCaretManager::CaretMode;
+
+  AccessibleCaretManagerTester()
+  {
+    DefaultValue<CaretMode>::Set(CaretMode::None);
+    DefaultValue<PositionChangedResult>::Set(PositionChangedResult::NotChanged);
+
+    EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
+      .WillRepeatedly(Return(PositionChangedResult::Changed));
+
+    EXPECT_CALL(mManager.SecondCaret(), SetPosition(_, _))
+      .WillRepeatedly(Return(PositionChangedResult::Changed));
+  }
+
+  void CheckStates(CaretMode aCaretMode,
+                   Appearance aFirstCaretAppearance,
+                   Appearance aSecondCaretAppearance)
+  {
+    EXPECT_EQ(mManager.LastUpdateCaretMode(), aCaretMode);
+    EXPECT_EQ(mManager.FirstCaret().GetAppearance(), aFirstCaretAppearance);
+    EXPECT_EQ(mManager.SecondCaret().GetAppearance(), aSecondCaretAppearance);
+  }
+
+  // Member variables
+  MockAccessibleCaretManager mManager;
+
+}; // class AccessibleCaretManagerTester
+
+TEST_F(AccessibleCaretManagerTester, TestUpdatesInSelectionMode)
+{
+  EXPECT_CALL(mManager, GetCaretMode())
+    .WillRepeatedly(Return(CaretMode::Selection));
+
+  EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
+                CaretChangedReason::Updateposition)).Times(3);
+
+  mManager.UpdateCarets();
+  CheckStates(CaretMode::Selection, Appearance::Normal, Appearance::Normal);
+
+  mManager.OnReflow();
+  CheckStates(CaretMode::Selection, Appearance::Normal, Appearance::Normal);
+
+  mManager.OnScrollPositionChanged();
+  CheckStates(CaretMode::Selection, Appearance::Normal, Appearance::Normal);
+}
+
+TEST_F(AccessibleCaretManagerTester, TestUpdatesInCursorModeOnNonEmptyContent)
+{
+  EXPECT_CALL(mManager, GetCaretMode())
+    .WillRepeatedly(Return(CaretMode::Cursor));
+
+  EXPECT_CALL(mManager, HasNonEmptyTextContent(_))
+    .WillRepeatedly(Return(true));
+
+  MockFunction<void(std::string aCheckPointName)> check;
+  {
+    InSequence dummy;
+
+    EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
+                  CaretChangedReason::Updateposition)).Times(1);
+    EXPECT_CALL(check, Call("mouse down"));
+
+    EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
+                  CaretChangedReason::Updateposition)).Times(1);
+    EXPECT_CALL(check, Call("reflow"));
+
+    EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
+                  CaretChangedReason::Visibilitychange)).Times(1);
+    EXPECT_CALL(check, Call("blur"));
+
+    EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
+                  CaretChangedReason::Updateposition)).Times(1);
+    EXPECT_CALL(check, Call("mouse up"));
+
+    EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
+                  CaretChangedReason::Updateposition)).Times(1);
+  }
+
+  // Simulate a single tap on a non-empty input.
+  mManager.OnSelectionChanged(nullptr, nullptr,
+                              nsISelectionListener::DRAG_REASON |
+                              nsISelectionListener::MOUSEDOWN_REASON);
+  CheckStates(CaretMode::Cursor, Appearance::Normal, Appearance::None);
+  check.Call("mouse down");
+
+  mManager.OnReflow();
+  CheckStates(CaretMode::Cursor, Appearance::Normal, Appearance::None);
+  check.Call("reflow");
+
+  mManager.OnBlur();
+  CheckStates(CaretMode::Cursor, Appearance::None, Appearance::None);
+  check.Call("blur");
+
+  mManager.OnSelectionChanged(nullptr, nullptr,
+                              nsISelectionListener::MOUSEUP_REASON);
+  CheckStates(CaretMode::Cursor, Appearance::Normal, Appearance::None);
+  check.Call("mouse up");
+
+  mManager.OnScrollPositionChanged();
+  CheckStates(CaretMode::Cursor, Appearance::Normal, Appearance::None);
+}
+
+} // namespace mozilla
--- a/layout/base/gtest/moz.build
+++ b/layout/base/gtest/moz.build
@@ -1,23 +1,30 @@
 # -*- Mode: python; c-basic-offset: 4; 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/.
 
 UNIFIED_SOURCES += [
-    'TestAccessibleCaretEventHub.cpp'
+    'TestAccessibleCaretEventHub.cpp',
+    'TestAccessibleCaretManager.cpp',
 ]
 
+# XXX: Allow -Winconsistent-missing-override for TestAccessibleCaretManager.cpp
+# that stub virtual methods have 'override' keyword while mocked methods by
+# MOCK_METHOD macro does not. (See 1169974)
+ALLOW_COMPILER_WARNINGS = True
+
 include('/ipc/chromium/chromium-config.mozbuild')
 
 LOCAL_INCLUDES += [
     '/docshell/base',
-    '/layout/base'
+    '/layout/base',
+    '/layout/style',
 ]
 
 if CONFIG['GNU_CXX']:
     CXXFLAGS += ['-Wshadow']
 
 # Workaround bug 1142396. Suppress the warning from gmock library for clang.
 if CONFIG['CLANG_CXX']:
     CXXFLAGS += ['-Wno-null-dereference']