Add unit test for toolbars' force touch gestures
This CL adds a unit test for the force touch gesture recognizer added
to the toolbar buttons, triggering the popup menu.
Bug: 864430
Cq-Include-Trybots: luci.chromium.try:ios-simulator-full-configs;master.tryserver.chromium.mac:ios-simulator-cronet
Change-Id: Icc2524f7e8e58bf20fb4b1381913cb82c57206a8
Reviewed-on: https://chromium-review.googlesource.com/1150142
Reviewed-by: Mark Cogan <marq@chromium.org>
Commit-Queue: Gauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#578349}
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/BUILD.gn b/ios/chrome/browser/ui/toolbar/adaptive/BUILD.gn
index 724ae32..a5e724a 100644
--- a/ios/chrome/browser/ui/toolbar/adaptive/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/adaptive/BUILD.gn
@@ -113,6 +113,24 @@
libs = [ "XCTest.framework" ]
}
+source_set("unit_tests") {
+ configs += [ "//build/config/compiler:enable_arc" ]
+ testonly = true
+ sources = [
+ "adaptive_toolbar_view_controller_unittest.mm",
+ ]
+ deps = [
+ ":adaptive_ui",
+ "//base",
+ "//base/test:test_support",
+ "//ios/chrome/browser/ui/commands",
+ "//ios/chrome/browser/ui/popup_menu/public",
+ "//ios/chrome/browser/ui/toolbar/buttons",
+ "//testing/gtest",
+ "//third_party/ocmock",
+ ]
+}
+
source_set("hooks") {
configs += [ "//build/config/compiler:enable_arc" ]
testonly = true
diff --git a/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller_unittest.mm b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller_unittest.mm
new file mode 100644
index 0000000..3305b073
--- /dev/null
+++ b/ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller_unittest.mm
@@ -0,0 +1,112 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/toolbar/adaptive/adaptive_toolbar_view_controller.h"
+
+#import <UIKit/UIGestureRecognizerSubclass.h>
+
+#include "base/run_loop.h"
+#import "base/test/ios/wait_util.h"
+#include "base/test/scoped_task_environment.h"
+#import "ios/chrome/browser/ui/commands/popup_menu_commands.h"
+#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_long_press_delegate.h"
+#import "ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view_controller.h"
+#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_button.h"
+#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_button_factory.h"
+#import "ios/chrome/browser/ui/toolbar/buttons/toolbar_constants.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+#include "third_party/ocmock/gtest_support.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+namespace {
+
+UIView* GetTabGridToolbarButton(UIView* parentView) {
+ if (parentView.accessibilityIdentifier == kToolbarStackButtonIdentifier)
+ return parentView;
+
+ for (UIView* subview in parentView.subviews) {
+ UIView* buttonSubview = GetTabGridToolbarButton(subview);
+ if (buttonSubview)
+ return buttonSubview;
+ }
+ return nil;
+}
+
+class AdaptiveToolbarViewControllerTest : public PlatformTest {
+ protected:
+ AdaptiveToolbarViewControllerTest()
+ : scopedTaskEnvironment_(
+ base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
+
+ base::test::ScopedTaskEnvironment scopedTaskEnvironment_;
+};
+
+TEST_F(AdaptiveToolbarViewControllerTest, DetectForceTouch) {
+ id dispatcher = OCMProtocolMock(@protocol(PopupMenuCommands));
+ id longPressDelegate = OCMProtocolMock(@protocol(PopupMenuLongPressDelegate));
+ ToolbarButtonFactory* factory =
+ [[ToolbarButtonFactory alloc] initWithStyle:NORMAL];
+
+ AdaptiveToolbarViewController* toolbar =
+ [[PrimaryToolbarViewController alloc] init];
+ toolbar.buttonFactory = factory;
+ toolbar.longPressDelegate = longPressDelegate;
+ toolbar.dispatcher = dispatcher;
+
+ UIView* buttonView = GetTabGridToolbarButton(toolbar.view);
+
+ ASSERT_NE(buttonView, nil);
+ ASSERT_GE(buttonView.gestureRecognizers.count, 1UL);
+
+ UIGestureRecognizer* gestureRecognizer = buttonView.gestureRecognizers[0];
+
+ id event = OCMClassMock([UIEvent class]);
+
+ id touch = OCMClassMock([UITouch class]);
+ OCMStub([touch maximumPossibleForce]).andReturn(1);
+ OCMStub([touch force]).andReturn(0.7);
+ [gestureRecognizer touchesBegan:[NSSet setWithObject:touch] withEvent:event];
+ [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event];
+
+ // Check that the dispatcher is called when the force touch is detected.
+ OCMExpect([dispatcher showTabGridButtonPopup]);
+
+ touch = OCMClassMock([UITouch class]);
+ OCMStub([touch maximumPossibleForce]).andReturn(1);
+ OCMStub([touch force]).andReturn(0.9);
+ [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event];
+
+ base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.05));
+
+ EXPECT_OCMOCK_VERIFY(dispatcher);
+
+ // Check that the longPressDelegate is notified when the gesture recognizer
+ // changes, even with lower force.
+ [[[longPressDelegate expect] ignoringNonObjectArgs]
+ longPressFocusPointChangedTo:CGPointZero];
+
+ touch = OCMClassMock([UITouch class]);
+ OCMStub([touch maximumPossibleForce]).andReturn(1);
+ OCMStub([touch force]).andReturn(0.9);
+ [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event];
+
+ base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.05));
+
+ EXPECT_OCMOCK_VERIFY(longPressDelegate);
+
+ // Change the state to Ended here, as the long press gesture recognizer isn't
+ // working on unit test (the state is cancelled).
+ gestureRecognizer.state = UIGestureRecognizerStateEnded;
+
+ base::test::ios::SpinRunLoopWithMinDelay(base::TimeDelta::FromSecondsD(0.05));
+
+ EXPECT_OCMOCK_VERIFY(longPressDelegate);
+}
+
+} // namespace
diff --git a/ios/chrome/browser/ui/util/BUILD.gn b/ios/chrome/browser/ui/util/BUILD.gn
index be0c9bf..6abd6cb 100644
--- a/ios/chrome/browser/ui/util/BUILD.gn
+++ b/ios/chrome/browser/ui/util/BUILD.gn
@@ -63,6 +63,7 @@
sources = [
"CRUILabel+AttributeUtils_unittest.mm",
"core_text_util_unittest.mm",
+ "force_touch_long_press_gesture_recognizer_unittest.mm",
"label_link_controller_unittest.mm",
"label_observer_unittest.mm",
"manual_text_framer_unittest.mm",
@@ -76,6 +77,7 @@
"//ios/third_party/material_components_ios",
"//ios/third_party/material_roboto_font_loader_ios",
"//testing/gtest",
+ "//third_party/ocmock",
"//url",
]
}
diff --git a/ios/chrome/browser/ui/util/force_touch_long_press_gesture_recognizer_unittest.mm b/ios/chrome/browser/ui/util/force_touch_long_press_gesture_recognizer_unittest.mm
new file mode 100644
index 0000000..f3909a7f
--- /dev/null
+++ b/ios/chrome/browser/ui/util/force_touch_long_press_gesture_recognizer_unittest.mm
@@ -0,0 +1,69 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/util/force_touch_long_press_gesture_recognizer.h"
+
+#import <UIKit/UIGestureRecognizerSubclass.h>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface ForceTouchLongPressGestureRecognizerReceiverForTest : NSObject
+
+@end
+
+@implementation ForceTouchLongPressGestureRecognizerReceiverForTest
+
+- (void)handleGestureRecognizer:(UIGestureRecognizer*)gesture {
+}
+
+@end
+
+namespace {
+
+using ForceTouchLongPressGestureRecognizerTest = PlatformTest;
+
+TEST_F(ForceTouchLongPressGestureRecognizerTest, DetectForceTouch) {
+ ForceTouchLongPressGestureRecognizerReceiverForTest* testReceiver =
+ [[ForceTouchLongPressGestureRecognizerReceiverForTest alloc] init];
+
+ ForceTouchLongPressGestureRecognizer* gestureRecognizer =
+ [[ForceTouchLongPressGestureRecognizer alloc]
+ initWithTarget:testReceiver
+ action:@selector(handleGestureRecognizer:)];
+ gestureRecognizer.forceThreshold = 0.6;
+
+ ASSERT_EQ(UIGestureRecognizerStatePossible, gestureRecognizer.state);
+
+ id event = OCMClassMock([UIEvent class]);
+
+ id touch = OCMClassMock([UITouch class]);
+ OCMStub([touch maximumPossibleForce]).andReturn(1);
+ OCMStub([touch force]).andReturn(0.5);
+ [gestureRecognizer touchesBegan:[NSSet setWithObject:touch] withEvent:event];
+ [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event];
+
+ EXPECT_EQ(UIGestureRecognizerStatePossible, gestureRecognizer.state);
+
+ touch = OCMClassMock([UITouch class]);
+ OCMStub([touch maximumPossibleForce]).andReturn(1);
+ OCMStub([touch force]).andReturn(0.7);
+ [gestureRecognizer touchesMoved:[NSSet setWithObject:touch] withEvent:event];
+
+ EXPECT_EQ(UIGestureRecognizerStateBegan, gestureRecognizer.state);
+
+ touch = OCMClassMock([UITouch class]);
+ OCMStub([touch maximumPossibleForce]).andReturn(1);
+ OCMStub([touch force]).andReturn(0.7);
+ [gestureRecognizer touchesEnded:[NSSet setWithObject:touch] withEvent:event];
+
+ EXPECT_EQ(UIGestureRecognizerStateCancelled, gestureRecognizer.state);
+}
+
+} // namespace
diff --git a/ios/chrome/test/BUILD.gn b/ios/chrome/test/BUILD.gn
index a4facee..12ea7a3 100644
--- a/ios/chrome/test/BUILD.gn
+++ b/ios/chrome/test/BUILD.gn
@@ -235,6 +235,7 @@
"//ios/chrome/browser/ui/table_view/cells:unit_tests",
"//ios/chrome/browser/ui/tabs:unit_tests",
"//ios/chrome/browser/ui/toolbar:unit_tests",
+ "//ios/chrome/browser/ui/toolbar/adaptive:unit_tests",
"//ios/chrome/browser/ui/toolbar/clean:unit_tests",
"//ios/chrome/browser/ui/toolbar/legacy:unit_tests",
"//ios/chrome/browser/ui/tools_menu:unit_tests",