summaryrefslogtreecommitdiff
path: root/platform/ios/test
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios/test')
-rw-r--r--platform/ios/test/MGLMapViewContentInsetTests.m177
-rw-r--r--platform/ios/test/MGLMapViewGestureRecognizerTests.mm280
-rw-r--r--platform/ios/test/MGLMapViewPitchTests.m4
-rw-r--r--platform/ios/test/MGLMockGestureRecognizers.h19
-rw-r--r--platform/ios/test/MGLMockGestureRecognizers.m44
5 files changed, 524 insertions, 0 deletions
diff --git a/platform/ios/test/MGLMapViewContentInsetTests.m b/platform/ios/test/MGLMapViewContentInsetTests.m
new file mode 100644
index 0000000000..185baf4a05
--- /dev/null
+++ b/platform/ios/test/MGLMapViewContentInsetTests.m
@@ -0,0 +1,177 @@
+#import <Mapbox/Mapbox.h>
+#import <XCTest/XCTest.h>
+
+@interface MGLMapViewContentInsetTests : XCTestCase <MGLMapViewDelegate>
+
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) UIWindow *window;
+@property (nonatomic) UIViewController *viewController;
+@property (nonatomic) XCTestExpectation *styleLoadingExpectation;
+@property (assign) CGRect screenBounds;
+
+@end
+
+@implementation MGLMapViewContentInsetTests
+
+- (void)setUp {
+ [super setUp];
+
+ [MGLAccountManager setAccessToken:@"pk.feedcafedeadbeefbadebede"];
+ NSURL *styleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"];
+ self.screenBounds = UIScreen.mainScreen.bounds;
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.screenBounds styleURL:styleURL];
+ self.mapView.zoomLevel = 16;
+ self.mapView.delegate = self;
+
+ self.viewController = [[UIViewController alloc] init];
+ self.viewController.view = [[UIView alloc] initWithFrame:self.screenBounds];
+ [self.viewController.view addSubview:self.mapView];
+ self.window = [[UIWindow alloc] initWithFrame:self.screenBounds];
+ [self.window addSubview:self.viewController.view];
+ [self.window makeKeyAndVisible];
+
+ if (!self.mapView.style) {
+ _styleLoadingExpectation = [self expectationWithDescription:@"Map view should finish loading style."];
+ [self waitForExpectationsWithTimeout:10 handler:nil];
+ }
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ XCTAssertNotNil(mapView.style);
+ XCTAssertEqual(mapView.style, style);
+
+ [_styleLoadingExpectation fulfill];
+}
+
+- (void)tearDown {
+ self.mapView = nil;
+ [MGLAccountManager setAccessToken:nil];
+ [super tearDown];
+}
+
+- (void)testContentInsetCenter {
+ CLLocationCoordinate2D center = CLLocationCoordinate2DMake(1.0, 5.0);
+ self.mapView.centerCoordinate = center;
+ XCTAssertEqualWithAccuracy(self.mapView.centerCoordinate.latitude, center.latitude, 0.01);
+ XCTAssertEqualWithAccuracy(self.mapView.centerCoordinate.longitude, center.longitude, 0.01);
+
+ CGPoint centerPoint = [self.mapView convertCoordinate:center toPointToView:self.mapView];
+
+ XCTAssertEqualWithAccuracy(centerPoint.x, self.screenBounds.size.width/2, 0.01);
+ XCTAssertEqualWithAccuracy(centerPoint.y, self.screenBounds.size.height/2, 0.01);
+
+ // shifting contentInset should keep the same centerCoordinate but shift the screen
+ // center point accordingly
+ UIEdgeInsets contentInset = UIEdgeInsetsMake(50.0, 10.0, 10.0, 30.0);
+ self.mapView.contentInset = contentInset;
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+ XCTAssertEqualWithAccuracy(self.mapView.centerCoordinate.latitude, center.latitude, 0.01);
+ XCTAssertEqualWithAccuracy(self.mapView.centerCoordinate.longitude, center.longitude, 0.01);
+ CGPoint shiftedPoint = [self.mapView convertCoordinate:center toPointToView:self.mapView];
+ CGPoint expectedShiftedPoint = CGPointMake((self.screenBounds.size.width/2) + ((contentInset.left - contentInset.right) / 2 ),
+ (self.screenBounds.size.height/2) + ((contentInset.top - contentInset.bottom) / 2));
+ XCTAssertEqualWithAccuracy(shiftedPoint.x, expectedShiftedPoint.x, 0.01);
+ XCTAssertEqualWithAccuracy(shiftedPoint.y, expectedShiftedPoint.y, 0.01);
+
+
+}
+
+- (void)testContentInsetOrnaments {
+ CGFloat margin = 8;
+ self.mapView.contentInset = UIEdgeInsetsZero;
+ UIView *scaleBar = self.mapView.scaleBar;
+ CGPoint expectedScaleBarOrigin = CGPointMake(margin, margin);
+ XCTAssertTrue(CGPointEqualToPoint(scaleBar.frame.origin, expectedScaleBarOrigin));
+
+ UIView *compassView = self.mapView.compassView;
+ CGFloat x = self.screenBounds.size.width - compassView.bounds.size.width - margin;
+ CGPoint expectedCompassOrigin = CGPointMake(x, margin);
+ XCTAssertTrue(CGPointEqualToPoint(compassView.frame.origin, expectedCompassOrigin));
+
+ UIView *logoView = self.mapView.logoView;
+ CGFloat y = self.screenBounds.size.height - logoView.bounds.size.height - margin;
+ CGPoint expectedLogoOrigin = CGPointMake(margin, y);
+ XCTAssertTrue(CGPointEqualToPoint(logoView.frame.origin, expectedLogoOrigin));
+
+ UIView *attributionView = self.mapView.attributionButton;
+ x = self.screenBounds.size.width - attributionView.bounds.size.width - margin;
+ y = self.screenBounds.size.height - attributionView.bounds.size.height - margin;
+ CGPoint expectedAttributionOrigin = CGPointMake(x, y);
+ XCTAssertTrue(CGPointEqualToPoint(attributionView.frame.origin, expectedAttributionOrigin));
+
+ UIEdgeInsets insets = UIEdgeInsetsMake(15, 10, 20, 5);
+ self.viewController.automaticallyAdjustsScrollViewInsets = NO;
+ self.mapView.contentInset = insets;
+
+ [self.mapView setNeedsLayout];
+ [self.mapView layoutIfNeeded];
+
+ expectedScaleBarOrigin = CGPointMake(insets.left + self.mapView.scaleBarMargins.x, insets.top + self.mapView.scaleBarMargins.y);
+ XCTAssertTrue(CGPointEqualToPoint(scaleBar.frame.origin, expectedScaleBarOrigin));
+
+ x = self.screenBounds.size.width - compassView.bounds.size.width - insets.right - self.mapView.compassViewMargins.x;
+ expectedCompassOrigin = CGPointMake(x, insets.top + self.mapView.compassViewMargins.y);
+ XCTAssertTrue(CGPointEqualToPoint(compassView.frame.origin, expectedCompassOrigin));
+
+ y = self.screenBounds.size.height - logoView.bounds.size.height - insets.bottom - self.mapView.logoViewMargins.y;
+ expectedLogoOrigin = CGPointMake(insets.left + self.mapView.logoViewMargins.x, y);
+ XCTAssertTrue(CGPointEqualToPoint(logoView.frame.origin, expectedLogoOrigin));
+
+ x = self.screenBounds.size.width - attributionView.bounds.size.width - insets.right - self.mapView.attributionButtonMargins.x;
+ y = self.screenBounds.size.height - attributionView.bounds.size.height - insets.bottom - self.mapView.attributionButtonMargins.y;
+ expectedAttributionOrigin = CGPointMake(x, y);
+ XCTAssertTrue(CGPointEqualToPoint(attributionView.frame.origin, expectedAttributionOrigin));
+
+ // tests that passing negative values result in a 0 inset value
+ insets = UIEdgeInsetsMake(-100, -100, -100, -100);
+ self.mapView.contentInset = insets;
+
+ [self.mapView setNeedsLayout];
+ [self.mapView layoutIfNeeded];
+
+ expectedScaleBarOrigin = CGPointMake(margin, margin);
+ XCTAssertTrue(CGPointEqualToPoint(scaleBar.frame.origin, expectedScaleBarOrigin));
+
+ x = self.screenBounds.size.width - compassView.bounds.size.width - margin;
+ expectedCompassOrigin = CGPointMake(x, margin);
+ XCTAssertTrue(CGPointEqualToPoint(compassView.frame.origin, expectedCompassOrigin));
+
+ y = self.screenBounds.size.height - logoView.bounds.size.height - margin;
+ expectedLogoOrigin = CGPointMake(margin, y);
+ XCTAssertTrue(CGPointEqualToPoint(logoView.frame.origin, expectedLogoOrigin));
+
+ x = self.screenBounds.size.width - attributionView.bounds.size.width - margin;
+ y = self.screenBounds.size.height - attributionView.bounds.size.height - margin;
+ expectedAttributionOrigin = CGPointMake(x, y);
+ XCTAssertTrue(CGPointEqualToPoint(attributionView.frame.origin, expectedAttributionOrigin));
+
+ self.mapView.automaticallyAdjustsContentInset = YES;
+ insets = UIEdgeInsetsMake(100, 100, 100, 100);
+ self.mapView.contentInset = insets;
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, insets));
+
+ [self.mapView setNeedsLayout];
+ [self.mapView layoutIfNeeded];
+
+ // when automaticallyAdjustsContentInset = YES the content insets should be overwriten
+ XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, insets));
+
+ expectedScaleBarOrigin = CGPointMake(margin, margin);
+ XCTAssertTrue(CGPointEqualToPoint(scaleBar.frame.origin, expectedScaleBarOrigin));
+
+ x = self.screenBounds.size.width - compassView.bounds.size.width - margin;
+ expectedCompassOrigin = CGPointMake(x, margin);
+ XCTAssertTrue(CGPointEqualToPoint(compassView.frame.origin, expectedCompassOrigin));
+
+ y = self.screenBounds.size.height - logoView.bounds.size.height - margin;
+ expectedLogoOrigin = CGPointMake(margin, y);
+ XCTAssertTrue(CGPointEqualToPoint(logoView.frame.origin, expectedLogoOrigin));
+
+ x = self.screenBounds.size.width - attributionView.bounds.size.width - margin;
+ y = self.screenBounds.size.height - attributionView.bounds.size.height - margin;
+ expectedAttributionOrigin = CGPointMake(x, y);
+ XCTAssertTrue(CGPointEqualToPoint(attributionView.frame.origin, expectedAttributionOrigin));
+
+}
+
+@end
diff --git a/platform/ios/test/MGLMapViewGestureRecognizerTests.mm b/platform/ios/test/MGLMapViewGestureRecognizerTests.mm
new file mode 100644
index 0000000000..58fbf2d03b
--- /dev/null
+++ b/platform/ios/test/MGLMapViewGestureRecognizerTests.mm
@@ -0,0 +1,280 @@
+#import <Mapbox/Mapbox.h>
+#import <XCTest/XCTest.h>
+
+#import "../../darwin/src/MGLGeometry_Private.h"
+#import "MGLMockGestureRecognizers.h"
+
+#include <mbgl/map/map.hpp>
+#include <mbgl/map/camera.hpp>
+
+@interface MGLMapView (MGLMapViewGestureRecognizerTests)
+
+- (mbgl::Map &)mbglMap;
+
+- (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch;
+- (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate;
+- (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap;
+- (void)handleTwoFingerTapGesture:(UITapGestureRecognizer *)twoFingerTap;
+- (void)handleQuickZoomGesture:(UILongPressGestureRecognizer *)quickZoom;
+- (void)handleTwoFingerDragGesture:(UIPanGestureRecognizer *)twoFingerDrag;
+
+@end
+
+@interface MGLMapViewGestureRecognizerTests : XCTestCase <MGLMapViewDelegate>
+
+@property (nonatomic) MGLMapView *mapView;
+@property (nonatomic) UIWindow *window;
+@property (nonatomic) UIViewController *viewController;
+@property (nonatomic) XCTestExpectation *styleLoadingExpectation;
+@property (nonatomic) XCTestExpectation *twoFingerExpectation;
+@property (nonatomic) XCTestExpectation *quickZoomExpectation;
+@property (nonatomic) XCTestExpectation *doubleTapExpectation;
+@property (nonatomic) XCTestExpectation *twoFingerDragExpectation;
+@property (assign) CGRect screenBounds;
+
+@end
+
+@implementation MGLMapViewGestureRecognizerTests
+
+- (void)setUp {
+ [super setUp];
+
+ [MGLAccountManager setAccessToken:@"pk.feedcafedeadbeefbadebede"];
+ NSURL *styleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"];
+ self.screenBounds = UIScreen.mainScreen.bounds;
+ self.mapView = [[MGLMapView alloc] initWithFrame:self.screenBounds styleURL:styleURL];
+ self.mapView.zoomLevel = 16;
+ self.mapView.delegate = self;
+
+ self.viewController = [[UIViewController alloc] init];
+ self.viewController.view = [[UIView alloc] initWithFrame:self.screenBounds];
+ [self.viewController.view addSubview:self.mapView];
+ self.window = [[UIWindow alloc] initWithFrame:self.screenBounds];
+ [self.window addSubview:self.viewController.view];
+ [self.window makeKeyAndVisible];
+
+ if (!self.mapView.style) {
+ _styleLoadingExpectation = [self expectationWithDescription:@"Map view should finish loading style."];
+ [self waitForExpectationsWithTimeout:10 handler:nil];
+ }
+}
+
+- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
+ XCTAssertNotNil(mapView.style);
+ XCTAssertEqual(mapView.style, style);
+
+ [_styleLoadingExpectation fulfill];
+}
+
+- (void)testHandlePinchGestureContentInset {
+ UIEdgeInsets contentInset = UIEdgeInsetsZero;
+ self.mapView.contentInset = contentInset;
+ mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.mapView.contentInset);
+ auto cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"MGLMapView's contentInset property should match camera's padding.");
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ contentInset = UIEdgeInsetsMake(20, 20, 20, 20);
+ [self.mapView setCamera:self.mapView.camera withDuration:0.1 animationTimingFunction:nil edgePadding:contentInset completionHandler:nil];
+ XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ UIPinchGestureRecognizerMock *pinchGesture = [[UIPinchGestureRecognizerMock alloc] initWithTarget:nil action:nil];
+ pinchGesture.state = UIGestureRecognizerStateBegan;
+ pinchGesture.scale = 1.0;
+ [self.mapView handlePinchGesture:pinchGesture];
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ pinchGesture.state = UIGestureRecognizerStateChanged;
+ [self.mapView handlePinchGesture:pinchGesture];
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+
+ pinchGesture.state = UIGestureRecognizerStateEnded;
+ [self.mapView handlePinchGesture:pinchGesture];
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+
+}
+
+- (void)testHandleRotateGestureContentInset {
+ UIEdgeInsets contentInset = UIEdgeInsetsZero;
+ self.mapView.contentInset = contentInset;
+ mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.mapView.contentInset);
+ auto cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"MGLMapView's contentInset property should match camera's padding.");
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ contentInset = UIEdgeInsetsMake(20, 20, 20, 20);
+ [self.mapView setCamera:self.mapView.camera withDuration:0.1 animationTimingFunction:nil edgePadding:contentInset completionHandler:nil];
+ XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ UIRotationGestureRecognizerMock *rotateGesture = [[UIRotationGestureRecognizerMock alloc] initWithTarget:nil action:nil];
+ rotateGesture.state = UIGestureRecognizerStateBegan;
+ rotateGesture.rotation = 1;
+ [self.mapView handleRotateGesture:rotateGesture];
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ rotateGesture.state = UIGestureRecognizerStateChanged;
+ [self.mapView handleRotateGesture:rotateGesture];
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+
+ rotateGesture.state = UIGestureRecognizerStateEnded;
+ [self.mapView handleRotateGesture:rotateGesture];
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+
+}
+
+- (void)testHandleDoubleTapGestureContentInset {
+ UIEdgeInsets contentInset = UIEdgeInsetsMake(1, 1, 1, 1);
+ self.mapView.contentInset = contentInset;
+ mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.mapView.contentInset);
+ auto cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"MGLMapView's contentInset property should match camera's padding.");
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ contentInset = UIEdgeInsetsMake(20, 20, 20, 20);
+ [self.mapView setCamera:self.mapView.camera withDuration:0.1 animationTimingFunction:nil edgePadding:contentInset completionHandler:nil];
+ XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ UITapGestureRecognizerMock *doubleTapGesture = [[UITapGestureRecognizerMock alloc] initWithTarget:nil action:nil];
+ doubleTapGesture.mockTappedView = self.mapView;
+ doubleTapGesture.mockTappedPoint = CGPointMake(1.0, 1.0);
+
+ [self.mapView handleDoubleTapGesture:doubleTapGesture];
+ _doubleTapExpectation = [self expectationWithDescription:@"Double tap gesture animation."];
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ [self->_doubleTapExpectation fulfill];
+ });
+ [self waitForExpectationsWithTimeout:10 handler:nil];
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+
+}
+
+- (void)testHandleTwoFingerTapGesture {
+ UIEdgeInsets contentInset = UIEdgeInsetsZero;
+ self.mapView.contentInset = contentInset;
+ mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.mapView.contentInset);
+ auto cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"MGLMapView's contentInset property should match camera's padding.");
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ contentInset = UIEdgeInsetsMake(20, 20, 20, 20);
+ [self.mapView setCamera:self.mapView.camera withDuration:0.1 animationTimingFunction:nil edgePadding:contentInset completionHandler:nil];
+ XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ UITapGestureRecognizerMock *twoFingerTap = [[UITapGestureRecognizerMock alloc] initWithTarget:nil action:nil];
+ twoFingerTap.mockTappedView = self.mapView;
+ twoFingerTap.mockTappedPoint = CGPointMake(1.0, 1.0);
+
+ [self.mapView handleTwoFingerTapGesture:twoFingerTap];
+ _twoFingerExpectation = [self expectationWithDescription:@"Two Finger tap gesture animation."];
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ [self->_twoFingerExpectation fulfill];
+ });
+ [self waitForExpectationsWithTimeout:10 handler:nil];
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+}
+
+- (void)testHandleQuickZoomGesture {
+ UIEdgeInsets contentInset = UIEdgeInsetsZero;
+ self.mapView.contentInset = contentInset;
+ mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.mapView.contentInset);
+ auto cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"MGLMapView's contentInset property should match camera's padding.");
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ contentInset = UIEdgeInsetsMake(20, 20, 20, 20);
+ [self.mapView setCamera:self.mapView.camera withDuration:0.1 animationTimingFunction:nil edgePadding:contentInset completionHandler:nil];
+ XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ UILongPressGestureRecognizerMock *quickZoom = [[UILongPressGestureRecognizerMock alloc] initWithTarget:nil action:nil];
+ quickZoom.state = UIGestureRecognizerStateBegan;
+ [self.mapView handleQuickZoomGesture:quickZoom];
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ quickZoom.state = UIGestureRecognizerStateChanged;
+ quickZoom.mockTappedPoint = CGPointMake(self.mapView.frame.size.width / 2, self.mapView.frame.size.height / 2);
+ [self.mapView handleQuickZoomGesture:quickZoom];
+ _quickZoomExpectation = [self expectationWithDescription:@"Quick zoom gesture animation."];
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ [self->_quickZoomExpectation fulfill];
+ });
+ [self waitForExpectationsWithTimeout:10 handler:nil];
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+
+ quickZoom.state = UIGestureRecognizerStateEnded;
+ [self.mapView handleQuickZoomGesture:quickZoom];
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+}
+
+- (void)testHandleTwoFingerDragGesture {
+ UIEdgeInsets contentInset = UIEdgeInsetsZero;
+ self.mapView.contentInset = contentInset;
+ mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.mapView.contentInset);
+ auto cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"MGLMapView's contentInset property should match camera's padding.");
+ XCTAssertTrue(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ contentInset = UIEdgeInsetsMake(20, 20, 20, 20);
+ [self.mapView setCamera:self.mapView.camera withDuration:0.1 animationTimingFunction:nil edgePadding:contentInset completionHandler:nil];
+ XCTAssertFalse(UIEdgeInsetsEqualToEdgeInsets(self.mapView.contentInset, contentInset));
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ UIPanGestureRecognizerMock *twoFingerDrag = [[UIPanGestureRecognizerMock alloc] initWithTarget:nil action:nil];
+ twoFingerDrag.state = UIGestureRecognizerStateBegan;
+ twoFingerDrag.firstFingerPoint = CGPointMake(self.mapView.frame.size.width / 3, self.mapView.frame.size.height/2);
+ twoFingerDrag.secondFingerPoint = CGPointMake((self.mapView.frame.size.width / 2), self.mapView.frame.size.height/2);
+ twoFingerDrag.numberOfTouches = 2;
+ [self.mapView handleTwoFingerDragGesture:twoFingerDrag];
+ XCTAssertNotEqual(padding, cameraPadding);
+
+ twoFingerDrag.state = UIGestureRecognizerStateChanged;
+ twoFingerDrag.firstFingerPoint = CGPointMake(self.mapView.frame.size.width / 3, (self.mapView.frame.size.height/2)-10);
+ twoFingerDrag.secondFingerPoint = CGPointMake((self.mapView.frame.size.width / 2), (self.mapView.frame.size.height/2)-10);
+ [self.mapView handleTwoFingerDragGesture:twoFingerDrag];
+ _twoFingerDragExpectation = [self expectationWithDescription:@"Quick zoom gesture animation."];
+
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ [self->_twoFingerDragExpectation fulfill];
+ });
+ [self waitForExpectationsWithTimeout:10 handler:nil];
+
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+
+ twoFingerDrag.state = UIGestureRecognizerStateEnded;
+ [self.mapView handleTwoFingerDragGesture:twoFingerDrag];
+ cameraPadding = self.mapView.mbglMap.getCameraOptions().padding;
+ XCTAssertEqual(padding, cameraPadding, @"When a gesture recognizer is performed contentInsets and camera padding should match.");
+}
+
+@end
diff --git a/platform/ios/test/MGLMapViewPitchTests.m b/platform/ios/test/MGLMapViewPitchTests.m
index 3e9311dbd4..fa657eb994 100644
--- a/platform/ios/test/MGLMapViewPitchTests.m
+++ b/platform/ios/test/MGLMapViewPitchTests.m
@@ -2,6 +2,7 @@
#import <XCTest/XCTest.h>
@interface MockUIPanGestureRecognizer : UIPanGestureRecognizer
+@property(nonatomic, readwrite) UIGestureRecognizerState state;
@property NSUInteger mbx_numberOfFingersForGesture;
@property CGPoint mbx_middlePoint;
@property CGPoint mbx_westPoint;
@@ -9,6 +10,9 @@
@end
@implementation MockUIPanGestureRecognizer
+
+@synthesize state;
+
- (instancetype)initWithTarget:(id)target action:(SEL)action {
if (self = [super initWithTarget:target action:action]) {
self.mbx_numberOfFingersForGesture = 2;
diff --git a/platform/ios/test/MGLMockGestureRecognizers.h b/platform/ios/test/MGLMockGestureRecognizers.h
index aa5fbec494..29889e39f4 100644
--- a/platform/ios/test/MGLMockGestureRecognizers.h
+++ b/platform/ios/test/MGLMockGestureRecognizers.h
@@ -4,7 +4,26 @@
@interface UIPinchGestureRecognizerMock : UIPinchGestureRecognizer
@property (nonatomic, readwrite) CGFloat velocity;
@property (nonatomic) CGPoint locationInViewOverride;
+@property(nonatomic, readwrite) UIGestureRecognizerState state;
@end
@interface UIRotationGestureRecognizerMock : UIRotationGestureRecognizer
+@property(nonatomic, readwrite) UIGestureRecognizerState state;
+@end
+
+@interface UITapGestureRecognizerMock : UITapGestureRecognizer
+@property (strong, nonatomic) UIView *mockTappedView;
+@property (assign) CGPoint mockTappedPoint;
+@end
+
+@interface UILongPressGestureRecognizerMock : UILongPressGestureRecognizer
+@property(nonatomic, readwrite) UIGestureRecognizerState state;
+@property (assign) CGPoint mockTappedPoint;
+@end
+
+@interface UIPanGestureRecognizerMock : UIPanGestureRecognizer
+@property(nonatomic, readwrite) UIGestureRecognizerState state;
+@property (assign) CGPoint firstFingerPoint;
+@property (assign) CGPoint secondFingerPoint;
+@property(nonatomic, readwrite) NSUInteger numberOfTouches;
@end
diff --git a/platform/ios/test/MGLMockGestureRecognizers.m b/platform/ios/test/MGLMockGestureRecognizers.m
index 89df6750a9..c818805174 100644
--- a/platform/ios/test/MGLMockGestureRecognizers.m
+++ b/platform/ios/test/MGLMockGestureRecognizers.m
@@ -1,11 +1,55 @@
#import "MGLMockGestureRecognizers.h"
+#import "objc/runtime.h"
@implementation UIPinchGestureRecognizerMock
@synthesize velocity;
+@synthesize state;
- (CGPoint)locationInView:(nullable UIView *)view { return self.locationInViewOverride; }
@end
@implementation UIRotationGestureRecognizerMock
- (CGPoint)locationInView:(nullable UIView*)view { return view.center; }
+@synthesize state;
+@end
+
+@implementation UITapGestureRecognizerMock
+
++ (void)load {
+ method_exchangeImplementations(class_getInstanceMethod(self, @selector(state)),
+ class_getInstanceMethod(self, @selector(mockState)));
+}
+
+- (UIGestureRecognizerState)mockState {
+ return UIGestureRecognizerStateRecognized;
+}
+
+- (UIView *)view {
+ return self.mockTappedView;
+}
+
+- (CGPoint)locationInView:(UIView *)view {
+ return self.mockTappedPoint;
+}
+
+@end
+
+@implementation UILongPressGestureRecognizerMock
+@synthesize state;
+
+- (CGPoint)locationInView:(UIView *)view {
+ return self.mockTappedPoint;
+}
+@end
+
+@implementation UIPanGestureRecognizerMock
+@synthesize state;
+@synthesize numberOfTouches;
+
+- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView *)view {
+ if (touchIndex) {
+ return self.secondFingerPoint;
+ }
+ return self.firstFingerPoint;
+}
@end