summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wray <jason@mapbox.com>2019-07-12 17:24:02 -0700
committerJason Wray <jason@mapbox.com>2019-07-15 13:31:02 -0700
commit6d4ef2177c4a5fb4dcb869bc560145285a28c434 (patch)
treeeb531e3efa1a9914c20480c5830d03b0277e7b29
parent28b1e72ba147f6968f538b436a691cb2dc65b203 (diff)
downloadqtlocation-mapboxgl-upstream/friedbunny-adds-pinch-gesture-tests-and-such.tar.gz
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj4
-rw-r--r--platform/ios/test/MGLMapViewZoomTests.m140
2 files changed, 144 insertions, 0 deletions
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index 7daffb1179..10c18a41eb 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -392,6 +392,7 @@
9680274022653B84006BA4A1 /* MBXSKUToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 9680273E22653B84006BA4A1 /* MBXSKUToken.h */; };
9680276422655696006BA4A1 /* libmbxaccounts.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9680274122653C3E006BA4A1 /* libmbxaccounts.a */; };
96802766226556C5006BA4A1 /* libmbxaccounts.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9680274122653C3E006BA4A1 /* libmbxaccounts.a */; };
+ 9686D1BD22D9357700194EA0 /* MGLMapViewZoomTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9686D1BC22D9357700194EA0 /* MGLMapViewZoomTests.m */; };
968F36B51E4D128D003A5522 /* MGLDistanceFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 3557F7AE1E1D27D300CCA5E6 /* MGLDistanceFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
96E027231E57C76E004B8E66 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 96E027251E57C76E004B8E66 /* Localizable.strings */; };
96E516DC2000547000A02306 /* MGLPolyline_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 9654C1251FFC1AB900DB6A19 /* MGLPolyline_Private.h */; };
@@ -1130,6 +1131,7 @@
967C864A210A9D3C004DF794 /* UIDevice+MGLAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIDevice+MGLAdditions.m"; sourceTree = "<group>"; };
9680273E22653B84006BA4A1 /* MBXSKUToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MBXSKUToken.h; path = "../vendor/mapbox-accounts-ios/MBXSKUToken.h"; sourceTree = "<group>"; };
9680274122653C3E006BA4A1 /* libmbxaccounts.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libmbxaccounts.a; path = "vendor/mapbox-accounts-ios/libmbxaccounts.a"; sourceTree = SOURCE_ROOT; };
+ 9686D1BC22D9357700194EA0 /* MGLMapViewZoomTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLMapViewZoomTests.m; sourceTree = "<group>"; };
968F36B41E4D0FC6003A5522 /* ja */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
96E027241E57C76E004B8E66 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
96E027271E57C77A004B8E66 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -2055,6 +2057,7 @@
96381C0122C6F3950053497D /* MGLMapViewPitchTests.m */,
9658C154204761FC00D8A674 /* MGLMapViewScaleBarTests.m */,
076171C22139C70900668A35 /* MGLMapViewTests.m */,
+ 9686D1BC22D9357700194EA0 /* MGLMapViewZoomTests.m */,
1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */,
96036A0520059BBA00510F3D /* MGLNSOrthographyAdditionsTests.m */,
DAE7DEC11E245455007505A6 /* MGLNSStringAdditionsTests.m */,
@@ -3270,6 +3273,7 @@
3575798B1D502B0C000B822E /* MGLBackgroundStyleLayerTests.mm in Sources */,
9658C155204761FC00D8A674 /* MGLMapViewScaleBarTests.m in Sources */,
409D0A0D1ED614CE00C95D0C /* MGLAnnotationViewIntegrationTests.swift in Sources */,
+ 9686D1BD22D9357700194EA0 /* MGLMapViewZoomTests.m in Sources */,
DA2E88621CC0382C00F24E7B /* MGLOfflinePackTests.m in Sources */,
55E2AD131E5B125400E8C587 /* MGLOfflineStorageTests.mm in Sources */,
07D8C6FF1F67562C00381808 /* MGLComputedShapeSourceTests.m in Sources */,
diff --git a/platform/ios/test/MGLMapViewZoomTests.m b/platform/ios/test/MGLMapViewZoomTests.m
new file mode 100644
index 0000000000..bd617857fd
--- /dev/null
+++ b/platform/ios/test/MGLMapViewZoomTests.m
@@ -0,0 +1,140 @@
+#import <Mapbox/Mapbox.h>
+#import <XCTest/XCTest.h>
+
+@interface MGLMapView (MGLMapViewZoomTests)
+- (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch;
+@end
+
+@interface UIPinchGestureRecognizerMock : UIPinchGestureRecognizer
+@property (nonatomic) CGPoint locationInViewOverride;
+@end
+
+@implementation UIPinchGestureRecognizerMock
+- (CGPoint)locationInView:(nullable UIView *)view { return self.locationInViewOverride; }
+@end
+
+@interface MGLMapViewZoomTests : XCTestCase
+@property (nonatomic) MGLMapView *mapView;
+@end
+
+@implementation MGLMapViewZoomTests
+
+- (void)setUp {
+ [super setUp];
+
+ [MGLAccountManager setAccessToken:@"pk.feedcafedeadbeefbadebede"];
+ NSURL *styleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"];
+ self.mapView = [[MGLMapView alloc] initWithFrame:UIScreen.mainScreen.bounds styleURL:styleURL];
+}
+
+- (void)tearDown {
+ self.mapView = nil;
+ [MGLAccountManager setAccessToken:nil];
+ [super tearDown];
+}
+
+- (void)testZoom {
+ CLLocationCoordinate2D originalCenterCoordinate = self.mapView.centerCoordinate;
+
+ for (NSNumber *zoom in @[@1, @5, @10, @15, @22]) {
+ self.mapView.zoomLevel = [zoom doubleValue];
+ XCTAssertEqual(self.mapView.zoomLevel, [zoom doubleValue], @"Map zoom should match z%@.", zoom);
+
+ XCTAssertEqualWithAccuracy(originalCenterCoordinate.latitude, self.mapView.centerCoordinate.latitude, 0.0000001, "@Map center coordinate latitude should remain constant during zoom to z%@.", zoom);
+ XCTAssertEqualWithAccuracy(originalCenterCoordinate.longitude, self.mapView.centerCoordinate.longitude, 0.0000001, @"Map center coordinate longitude should remain constant during zoom to z%@.", zoom);
+ }
+}
+
+- (void)testZoomEnabled {
+ UIPinchGestureRecognizerMock *gesture = [[UIPinchGestureRecognizerMock alloc] initWithTarget:nil action:nil];
+ gesture.state = UIGestureRecognizerStateBegan;
+ gesture.scale = 10.f;
+ [self.mapView handlePinchGesture:gesture];
+ gesture.state = UIGestureRecognizerStateChanged;
+
+ // Disabled
+ {
+ self.mapView.zoomEnabled = NO;
+ XCTAssertEqual(self.mapView.allowsZooming, NO);
+
+ [self.mapView handlePinchGesture:gesture];
+ XCTAssertNotEqual(self.mapView.zoomLevel, log2(gesture.scale), @"Gestural zoom should not work when zoom is disabled.");
+
+ self.mapView.zoomLevel = 15.f;
+ XCTAssertEqualWithAccuracy(self.mapView.zoomLevel, 15, 0.001, @"Programmatic zoom is allowed when zoomEnabled = NO.");
+ }
+
+ // Enabled
+ {
+ // No need to reset the map zoom or gesture scale, since gesture scale hasn't been applied yet and the map zoom will be overriden when the gesture is handled.
+ self.mapView.zoomEnabled = YES;
+ XCTAssertEqual(self.mapView.allowsZooming, YES);
+
+ [self.mapView handlePinchGesture:gesture];
+ XCTAssertEqualWithAccuracy(self.mapView.zoomLevel, log2(gesture.scale), 0.001, @"Gestural zoom should work when zoom is enabled.");
+ }
+}
+
+- (void)testPinchGesture {
+ CLLocationCoordinate2D originalCenterCoordinate = self.mapView.centerCoordinate;
+
+ UIPinchGestureRecognizerMock *gesture = [[UIPinchGestureRecognizerMock alloc] initWithTarget:self.mapView action:nil];
+ gesture.state = UIGestureRecognizerStateBegan;
+ gesture.scale = 0;
+ gesture.locationInViewOverride = self.mapView.center;
+ [self.mapView handlePinchGesture:gesture];
+ XCTAssertEqual(self.mapView.zoomLevel, 0);
+
+ for (NSNumber *zoom in @[@1, @5, @10, @15, @22]) {
+ gesture.state = UIGestureRecognizerStateChanged;
+ gesture.scale = MGLScaleFromZoomLevel([zoom doubleValue]);
+ [self.mapView handlePinchGesture:gesture];
+ XCTAssertEqual(self.mapView.zoomLevel, [zoom doubleValue], @"Map zoom should match gesture to z%@.", zoom);
+
+ // Given a hypothetical zoom into the exact center of the map, the center coordinate should remain the same.
+ XCTAssertEqualWithAccuracy(originalCenterCoordinate.latitude, self.mapView.centerCoordinate.latitude, 0.0000001, "@Map center coordinate latitude should remain constant during zoom to z%@.", zoom);
+ XCTAssertEqualWithAccuracy(originalCenterCoordinate.longitude, self.mapView.centerCoordinate.longitude, 0.0000001, @"Map center coordinate longitude should remain constant during zoom to z%@.", zoom);
+ }
+}
+
+// Regression test for: https://github.com/mapbox/mapbox-gl-native/issues/14977
+- (void)testPinchGestureOffCenter {
+ self.mapView.zoomLevel = 15;
+
+ // Set up pinch gesture at z15 with an origin of 0,0.
+ UIPinchGestureRecognizerMock *gesture = [[UIPinchGestureRecognizerMock alloc] initWithTarget:self.mapView action:nil];
+ gesture.state = UIGestureRecognizerStateBegan;
+ gesture.scale = 0;
+ gesture.locationInViewOverride = CGPointMake(0, 0);
+ [self.mapView handlePinchGesture:gesture];
+ XCTAssertEqual(self.mapView.zoomLevel, 15);
+
+ // Set a map rotation so that we can later check if un-rotating happens around the correct center point.
+ self.mapView.direction = 45;
+
+ // Zoom to z18 at the off-center origin.
+ gesture.state = UIGestureRecognizerStateChanged;
+ gesture.scale = MGLScaleFromZoomLevel(3);
+ [self.mapView handlePinchGesture:gesture];
+ XCTAssertEqual(self.mapView.zoomLevel, 18, @"Map zoom should match original zoom plus gesture zoom.");
+
+ // Check that the center coordinate remains the same when direction is reset to north.
+ CLLocationCoordinate2D centerCoordinateBeforeReset = self.mapView.centerCoordinate;
+ CLLocationCoordinate2D manuallyDerivedCenterCoordinate = [self.mapView convertPoint:self.mapView.center toCoordinateFromView:nil];
+ XCTAssertEqualWithAccuracy(centerCoordinateBeforeReset.latitude, manuallyDerivedCenterCoordinate.latitude, 0.0000001, "@Map center latitude should be equal to manually derived latitude.");
+ XCTAssertEqualWithAccuracy(centerCoordinateBeforeReset.longitude, manuallyDerivedCenterCoordinate.longitude, 0.0000001, @"Map center longitude should be equal to manually derived longitude.");
+
+ self.mapView.direction = 0;
+ XCTAssertEqualWithAccuracy(centerCoordinateBeforeReset.latitude, self.mapView.centerCoordinate.latitude, 0.0000001, "@Map center coordinate latitude should remain constant after resetting to north.");
+ XCTAssertEqualWithAccuracy(centerCoordinateBeforeReset.longitude, self.mapView.centerCoordinate.longitude, 0.0000001, @"Map center coordinate longitude should remain constant after resetting to north.");
+}
+
+NS_INLINE CGFloat MGLScaleFromZoomLevel(double zoom) {
+ return pow(2, zoom);
+}
+
+__unused NS_INLINE double MGLZoomLevelFromScale(CGFloat scale) {
+ return log2(scale);
+}
+
+@end