Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

[ios] Add MGLMapViewZoomTests and clean-up other gesture tests #15117

Merged
merged 3 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions platform/ios/ios.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -426,7 +427,7 @@
96E516FB20005A4000A02306 /* MGLUserLocationHeadingBeamLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 966FCF4A1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.h */; };
96E516FC20005A4400A02306 /* MGLUserLocationHeadingIndicator.h in Headers */ = {isa = PBXBuildFile; fileRef = 96F3F73B1F5711F1003E2D2C /* MGLUserLocationHeadingIndicator.h */; };
96E5170420005A6B00A02306 /* SMCalloutView.h in Headers */ = {isa = PBXBuildFile; fileRef = DA8848891CBB037E00AB86E3 /* SMCalloutView.h */; };
96E6145622CC135200109F14 /* MGLCompassButtonTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 96E6145522CC135200109F14 /* MGLCompassButtonTests.m */; };
96E6145622CC135200109F14 /* MGLMapViewCompassViewTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96E6145522CC135200109F14 /* MGLMapViewCompassViewTests.mm */; };
96E6145922CC169000109F14 /* MGLCompassButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 96E6145722CC169000109F14 /* MGLCompassButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
96E6145A22CC169000109F14 /* MGLCompassButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 96E6145722CC169000109F14 /* MGLCompassButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
96E6145B22CC169000109F14 /* MGLCompassButton.mm in Sources */ = {isa = PBXBuildFile; fileRef = 96E6145822CC169000109F14 /* MGLCompassButton.mm */; };
Expand Down Expand Up @@ -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>"; };
Expand All @@ -1140,7 +1142,7 @@
96E0272C1E57C7E5004B8E66 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
96E0272D1E57C7E6004B8E66 /* vi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = vi; path = vi.lproj/Localizable.strings; sourceTree = "<group>"; };
96E0272E1E57C7E7004B8E66 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = "<group>"; };
96E6145522CC135200109F14 /* MGLCompassButtonTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MGLCompassButtonTests.m; sourceTree = "<group>"; };
96E6145522CC135200109F14 /* MGLMapViewCompassViewTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLMapViewCompassViewTests.mm; sourceTree = "<group>"; };
96E6145722CC169000109F14 /* MGLCompassButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLCompassButton.h; sourceTree = "<group>"; };
96E6145822CC169000109F14 /* MGLCompassButton.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLCompassButton.mm; sourceTree = "<group>"; };
96ED34DD22374C0900E9FCA9 /* MGLMapViewDirectionTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLMapViewDirectionTests.mm; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2040,7 +2042,6 @@
DA35A2C31CCA9F8300E826B2 /* MGLClockDirectionFormatterTests.m */,
35D9DDE11DA25EEC00DAAD69 /* MGLCodingTests.mm */,
DA35A2C41CCA9F8300E826B2 /* MGLCompassDirectionFormatterTests.m */,
96E6145522CC135200109F14 /* MGLCompassButtonTests.m */,
DA35A2A91CCA058D00E826B2 /* MGLCoordinateFormatterTests.m */,
3598544C1E1D38AA00B29F84 /* MGLDistanceFormatterTests.m */,
6407D66F1E0085FD00F6A9C3 /* MGLDocumentationExampleTests.swift */,
Expand All @@ -2050,11 +2051,13 @@
DA2E885C1CC0382C00F24E7B /* MGLGeometryTests.mm */,
DA5DB1291FABF1EE001C2326 /* MGLMapAccessibilityElementTests.m */,
DA695425215B1E75002041A4 /* MGLMapCameraTests.m */,
96E6145522CC135200109F14 /* MGLMapViewCompassViewTests.mm */,
96ED34DD22374C0900E9FCA9 /* MGLMapViewDirectionTests.mm */,
16376B481FFEED010000563E /* MGLMapViewLayoutTests.m */,
96381C0122C6F3950053497D /* MGLMapViewPitchTests.m */,
9658C154204761FC00D8A674 /* MGLMapViewScaleBarTests.m */,
076171C22139C70900668A35 /* MGLMapViewTests.m */,
9686D1BC22D9357700194EA0 /* MGLMapViewZoomTests.m */,
1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */,
96036A0520059BBA00510F3D /* MGLNSOrthographyAdditionsTests.m */,
DAE7DEC11E245455007505A6 /* MGLNSStringAdditionsTests.m */,
Expand Down Expand Up @@ -3259,7 +3262,7 @@
40CFA6511D7875BB008103BD /* MGLShapeSourceTests.mm in Sources */,
DA35A2C51CCA9F8300E826B2 /* MGLClockDirectionFormatterTests.m in Sources */,
35B8E08C1D6C8B5100E768D2 /* MGLPredicateTests.mm in Sources */,
96E6145622CC135200109F14 /* MGLCompassButtonTests.m in Sources */,
96E6145622CC135200109F14 /* MGLMapViewCompassViewTests.mm in Sources */,
96036A0620059BBA00510F3D /* MGLNSOrthographyAdditionsTests.m in Sources */,
1F95931D1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm in Sources */,
DA695426215B1E76002041A4 /* MGLMapCameraTests.m in Sources */,
Expand All @@ -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 */,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
#import <Mapbox/Mapbox.h>
#import <XCTest/XCTest.h>

#import "../../ios/src/MGLCompassButton_Private.h"
#import <mbgl/math/wrap.hpp>

@interface MGLMapView (MGLCompassButtonTests)

- (void)resetNorthAnimated:(BOOL)animated;

@end

@interface MGLCompassButtonTests : XCTestCase

@property (nonatomic) MGLMapView *mapView;

@end

@implementation MGLCompassButtonTests
Expand All @@ -34,8 +30,9 @@ - (void)tearDown {

- (void)testCompassButton {
XCTAssertNotNil(self.mapView.compassView);
XCTAssertTrue([self.mapView.compassView isKindOfClass:[MGLCompassButton class]]);
XCTAssertTrue(self.mapView.compassView.userInteractionEnabled);
XCTAssertEqual(self.mapView.compassView.gestureRecognizers.count, 1);
XCTAssertEqual(self.mapView.compassView.gestureRecognizers.count, (unsigned long)1);
XCTAssertEqual(self.mapView.compassView.accessibilityTraits, UIAccessibilityTraitButton);
XCTAssertNotNil(self.mapView.compassView.accessibilityLabel);
XCTAssertNotNil(self.mapView.compassView.accessibilityHint);
Expand Down Expand Up @@ -81,4 +78,21 @@ - (void)testVisibilityVisible {
XCTAssertEqual(self.mapView.compassView.alpha, 1, @"Compass should continue to be visible when direction is north.");
}

- (void)testCompassRotation {
self.mapView.zoomLevel = 15;

for (NSNumber *degrees in @[@-999, @-359, @-240, @-180, @-90, @-45, @0, @45, @90, @180, @240, @360, @999]) {
self.mapView.direction = [degrees doubleValue];
CGFloat wrappedDirection = mbgl::util::wrap(-self.mapView.direction, 0., 360.);
CGAffineTransform rotation = CGAffineTransformMakeRotation(MGLRadiansFromDegrees(wrappedDirection));
XCTAssertTrue(CGAffineTransformEqualToTransform(self.mapView.compassView.transform, rotation),
@"Compass transform direction %f° should equal wrapped transform direction %f° (~%.f°).", [self degreesFromAffineTransform:self.mapView.compassView.transform], [self degreesFromAffineTransform:rotation], wrappedDirection);
}
}

- (CGFloat)degreesFromAffineTransform:(CGAffineTransform)transform {
CGFloat angle = atan2f(transform.b, transform.a);
return MGLDegreesFromRadians(angle);
}

@end
99 changes: 51 additions & 48 deletions platform/ios/test/MGLMapViewDirectionTests.mm
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@

#import <mbgl/math/wrap.hpp>

static MGLMapView *mapView;

@interface MGLMapView (MGLMapViewDirectionTests)
- (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate;
- (void)resetNorthAnimated:(BOOL)animated;
@end

@interface UIRotationGestureRecognizer (MGLMapViewDirectionTests)
@property (nonatomic, readwrite) UIGestureRecognizerState state;
@interface UIRotationGestureRecognizerMock : UIRotationGestureRecognizer
@end

@implementation UIRotationGestureRecognizerMock
- (CGPoint)locationInView:(nullable UIView*)view { return view.center; }
@end

@interface MGLMapViewDirectionTests : XCTestCase
@property (nonatomic) MGLMapView *mapView;
@end

@implementation MGLMapViewDirectionTests
Expand All @@ -24,100 +26,101 @@ - (void)setUp {

[MGLAccountManager setAccessToken:@"pk.feedcafedeadbeefbadebede"];
NSURL *styleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"];
mapView = [[MGLMapView alloc] initWithFrame:CGRectMake(0, 0, 64, 64) styleURL:styleURL];
self.mapView = [[MGLMapView alloc] initWithFrame:CGRectMake(0, 0, 64, 64) styleURL:styleURL];
}

- (void)tearDown {
mapView = nil;
self.mapView = nil;
[MGLAccountManager setAccessToken:nil];
[super tearDown];
}

- (void)testDirection {
mapView.zoomLevel = 0;
mapView.direction = 30;
XCTAssertEqual(mapView.direction, 0, @"Rotation is not allowed at world-scale zoom levels.");
self.mapView.zoomLevel = 0;
self.mapView.direction = 30;
XCTAssertEqual(self.mapView.direction, 0, @"Rotation is not allowed at world-scale zoom levels.");

mapView.zoomLevel = 15;
self.mapView.zoomLevel = 15;
CLLocationCoordinate2D originalCenterCoordinate = self.mapView.centerCoordinate;

for (NSNumber *degrees in @[@-999, @-359, @-240, @-180, @-90, @-45, @0, @45, @90, @180, @240, @360, @999]) {
double inputDegrees = [degrees doubleValue];
double wrappedDegrees = mbgl::util::wrap(inputDegrees, 0., 360.);
mapView.direction = inputDegrees;
XCTAssertEqualWithAccuracy(mapView.direction, wrappedDegrees, 0.001);
self.mapView.direction = inputDegrees;
XCTAssertEqualWithAccuracy(self.mapView.direction, wrappedDegrees, 0.001);

XCTAssertEqual(originalCenterCoordinate.latitude, self.mapView.centerCoordinate.latitude, "@Map center coordinate latitude should remain constant when direction is set to %@°.", degrees);
XCTAssertEqual(originalCenterCoordinate.longitude, self.mapView.centerCoordinate.longitude, @"Map center coordinate longitude should remain constant when direction is set to %@°.", degrees);
}

[mapView resetNorthAnimated:NO];
XCTAssertEqual(mapView.direction, 0, @"Reset-to-north should set direction to 0°.");
[self.mapView resetNorthAnimated:NO];
XCTAssertEqual(self.mapView.direction, 0, @"Reset-to-north should set direction to 0°.");
XCTAssertEqual(originalCenterCoordinate.latitude, self.mapView.centerCoordinate.latitude, "@Map center coordinate latitude should remain constant when direction is reset.");
XCTAssertEqual(originalCenterCoordinate.longitude, self.mapView.centerCoordinate.longitude, @"Map center coordinate latitude should remain constant when direction is reset.");
}

- (void)testRotateEnabled {
mapView.zoomLevel = 10;
self.mapView.zoomLevel = 10;

UIRotationGestureRecognizer *gesture = [[UIRotationGestureRecognizer alloc] initWithTarget:nil action:nil];
UIRotationGestureRecognizerMock *gesture = [[UIRotationGestureRecognizerMock alloc] initWithTarget:nil action:nil];
gesture.state = UIGestureRecognizerStateBegan;
gesture.rotation = MGLRadiansFromDegrees(30);
CGFloat wrappedRotation = mbgl::util::wrap(-MGLDegreesFromRadians(gesture.rotation), 0., 360.);

// Disabled
{
mapView.rotateEnabled = NO;
XCTAssertEqual(mapView.allowsRotating, NO);
self.mapView.rotateEnabled = NO;
XCTAssertEqual(self.mapView.allowsRotating, NO);

[mapView handleRotateGesture:gesture];
XCTAssertNotEqual(mapView.direction, wrappedRotation, @"Gestural rotation should not work when rotation is disabled.");
[self.mapView handleRotateGesture:gesture];
XCTAssertNotEqual(self.mapView.direction, wrappedRotation, @"Gestural rotation should not work when rotation is disabled.");

mapView.direction = 45.f;
XCTAssertEqualWithAccuracy(mapView.direction, 45, 0.001, @"Programmatic rotation is allowed when rotateEnabled = NO.");
self.mapView.direction = 45.f;
XCTAssertEqualWithAccuracy(self.mapView.direction, 45, 0.001, @"Programmatic rotation is allowed when rotateEnabled = NO.");
}

// Enabled
{
[mapView resetNorthAnimated:NO];
mapView.rotateEnabled = YES;
XCTAssertEqual(mapView.allowsRotating, YES);
[self.mapView resetNorthAnimated:NO];
self.mapView.rotateEnabled = YES;
XCTAssertEqual(self.mapView.allowsRotating, YES);

gesture.state = UIGestureRecognizerStateChanged;
gesture.rotation = MGLRadiansFromDegrees(30);
[mapView handleRotateGesture:gesture];
XCTAssertEqualWithAccuracy(mapView.direction, wrappedRotation, 0.001, @"Gestural rotation should work when rotation is enabled.");
[self.mapView handleRotateGesture:gesture];
XCTAssertEqualWithAccuracy(self.mapView.direction, wrappedRotation, 0.001, @"Gestural rotation should work when rotation is enabled.");
}
}

- (void)testRotateGesture {
mapView.zoomLevel = 15;
- (void)testRotationGesture {
self.mapView.zoomLevel = 15;
CLLocationCoordinate2D originalCenterCoordinate = self.mapView.centerCoordinate;

UIRotationGestureRecognizer *gesture = [[UIRotationGestureRecognizer alloc] initWithTarget:nil action:nil];
UIRotationGestureRecognizerMock *gesture = [[UIRotationGestureRecognizerMock alloc] initWithTarget:self.mapView action:nil];
gesture.state = UIGestureRecognizerStateBegan;
gesture.rotation = 0;
[mapView handleRotateGesture:gesture];
XCTAssertEqual(mapView.direction, gesture.rotation);
[self.mapView addGestureRecognizer:gesture];
[self.mapView handleRotateGesture:gesture];
XCTAssertEqual(self.mapView.direction, gesture.rotation);

for (NSNumber *degrees in @[@-999, @-360, @-240, @-180, @-90, @-45, @0, @45, @90, @180, @240, @359, @999]) {
gesture.state = UIGestureRecognizerStateChanged;
gesture.rotation = MGLRadiansFromDegrees([degrees doubleValue]);
[mapView handleRotateGesture:gesture];
[self.mapView handleRotateGesture:gesture];
CGFloat wrappedRotation = mbgl::util::wrap(-MGLDegreesFromRadians(gesture.rotation), 0., 360.);
XCTAssertEqualWithAccuracy(mapView.direction, wrappedRotation, 0.001, @"Map direction should match gesture rotation for input of %@°.", degrees);
}
}
XCTAssertEqualWithAccuracy(self.mapView.direction, wrappedRotation, 0.001, @"Map direction should match gesture rotation for input of %@°.", degrees);

- (void)testCompassRotation {
mapView.zoomLevel = 15;

for (NSNumber *degrees in @[@-999, @-359, @-240, @-180, @-90, @-45, @0, @45, @90, @180, @240, @360, @999]) {
mapView.direction = [degrees doubleValue];
CGFloat wrappedDirection = mbgl::util::wrap(-mapView.direction, 0., 360.);
CGAffineTransform rotation = CGAffineTransformMakeRotation(MGLRadiansFromDegrees(wrappedDirection));
XCTAssertTrue(CGAffineTransformEqualToTransform(mapView.compassView.transform, rotation),
@"Compass transform direction %f° should equal wrapped transform direction %f° (~%.f°).", [self degreesFromAffineTransform:mapView.compassView.transform], [self degreesFromAffineTransform:rotation], wrappedDirection);
// Given a hypothetical rotation around the exact center of the map, the center coordinate should remain the same.
// See above where we override -[UIRotationGestureRecognizer locationInView:] to always return the center of the target view.
XCTAssertEqualWithAccuracy(originalCenterCoordinate.latitude, self.mapView.centerCoordinate.latitude, 0.0000001, "@Map center coordinate latitude should remain constant during rotation of %@°.", degrees);
XCTAssertEqualWithAccuracy(originalCenterCoordinate.longitude, self.mapView.centerCoordinate.longitude, 0.0000001, @"Map center coordinate longitude should remain constant during rotation of %@°.", degrees);
}
}

- (void)testResetPosition {
[mapView resetPosition];
MGLMapCamera *defaultCamera = [MGLMapCamera cameraLookingAtCenterCoordinate:CLLocationCoordinate2DMake(0, 0) altitude:mapView.camera.altitude pitch:0 heading:0];
XCTAssertTrue([mapView.camera isEqualToMapCamera:defaultCamera], @"Map camera %@ should be equal to default camera %@.", mapView.camera, defaultCamera);
[self.mapView resetPosition];
MGLMapCamera *defaultCamera = [MGLMapCamera cameraLookingAtCenterCoordinate:CLLocationCoordinate2DMake(0, 0) altitude:self.mapView.camera.altitude pitch:0 heading:0];
XCTAssertTrue([self.mapView.camera isEqualToMapCamera:defaultCamera], @"Map camera %@ should be equal to default camera %@.", self.mapView.camera, defaultCamera);
}

- (CGFloat)degreesFromAffineTransform:(CGAffineTransform)transform {
Expand Down
Loading