summaryrefslogtreecommitdiff
path: root/platform/ios/Integration Tests/Snapshotter Tests/MGLMapSnapshotterTest.m
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios/Integration Tests/Snapshotter Tests/MGLMapSnapshotterTest.m')
-rw-r--r--platform/ios/Integration Tests/Snapshotter Tests/MGLMapSnapshotterTest.m537
1 files changed, 0 insertions, 537 deletions
diff --git a/platform/ios/Integration Tests/Snapshotter Tests/MGLMapSnapshotterTest.m b/platform/ios/Integration Tests/Snapshotter Tests/MGLMapSnapshotterTest.m
deleted file mode 100644
index 9ef2054dff..0000000000
--- a/platform/ios/Integration Tests/Snapshotter Tests/MGLMapSnapshotterTest.m
+++ /dev/null
@@ -1,537 +0,0 @@
-#import "MGLMapViewIntegrationTest.h"
-#import "MGLMapSnapshotter_Private.h"
-
-@interface MGLMapSnapshotter ()
-@property (nonatomic) BOOL cancelled;
-@end
-
-
-@interface MGLMapSnapshotterTest : MGLMapViewIntegrationTest
-@end
-
-// Convenience func to create snapshotter
-MGLMapSnapshotter* snapshotterWithCoordinates(CLLocationCoordinate2D coordinates, CGSize size) {
- // Create snapshot options
- MGLMapCamera* mapCamera = [[MGLMapCamera alloc] init];
- mapCamera.pitch = 20;
- mapCamera.centerCoordinate = coordinates;
- MGLMapSnapshotOptions* options = [[MGLMapSnapshotOptions alloc] initWithStyleURL:[MGLStyle satelliteStreetsStyleURL]
- camera:mapCamera
- size:size];
- options.zoomLevel = 10;
-
- // Create and start the snapshotter
- MGLMapSnapshotter* snapshotter = [[MGLMapSnapshotter alloc] initWithOptions:options];
- return snapshotter;
-}
-
-MGLMapSnapshotter* snapshotterWithBounds(MGLCoordinateBounds bounds, CGSize size) {
-
- MGLMapCamera* mapCamera = [[MGLMapCamera alloc] init];
- MGLMapSnapshotOptions* options = [[MGLMapSnapshotOptions alloc] initWithStyleURL:[MGLStyle satelliteStreetsStyleURL]
- camera:mapCamera
- size:size];
- options.coordinateBounds = bounds;
-
- // Create and start the snapshotter
- MGLMapSnapshotter* snapshotter = [[MGLMapSnapshotter alloc] initWithOptions:options];
- return snapshotter;
-}
-
-
-
-@implementation MGLMapSnapshotterTest
-
-- (void)testMultipleSnapshotsWithASingleSnapshotter🔒 {
- CGSize size = self.mapView.bounds.size;
-
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshots"];
- expectation.expectedFulfillmentCount = 2;
- expectation.assertForOverFulfill = YES;
-
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
- XCTAssertNotNil(snapshotter);
-
- [snapshotter startWithCompletionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- [expectation fulfill];
- }];
-
- @try {
- [snapshotter startWithCompletionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- XCTFail(@"Should not be called - but should it?");
- }];
- XCTFail(@"Should not be called");
- }
- @catch (NSException *exception) {
- XCTAssert(exception.name == NSInternalInconsistencyException);
- [expectation fulfill];
- }
-
- [self waitForExpectations:@[expectation] timeout:10.0];
-}
-
-- (void)testDeallocatingSnapshotterDuringSnapshot🔒 {
- // See also https://github.com/mapbox/mapbox-gl-native/issues/12336
-
- NSTimeInterval timeout = 10.0;
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshot"];
- CGSize size = self.mapView.bounds.size;
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- // Test triggering to main queue
- dispatch_queue_t backgroundQueue = dispatch_get_main_queue();
-// dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
-
- __weak __typeof__(self) weakself = self;
-
- dispatch_async(backgroundQueue, ^{
-
- dispatch_group_t dg = dispatch_group_create();
- dispatch_group_enter(dg);
-
- dispatch_async(dispatch_get_main_queue(), ^{
- MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
- __weak MGLMapSnapshotter *weakSnapshotter = snapshotter;
-
- [snapshotter startWithCompletionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- // We expect this completion block to be called with an error
- __typeof__(self) strongself = weakself;
-
- MGLTestAssertNil(strongself, snapshot);
- MGLTestAssert(strongself,
- ([error.domain isEqualToString:MGLErrorDomain] && error.code == MGLErrorCodeSnapshotFailed),
- @"Should have errored");
- MGLTestAssertNil(strongself, weakSnapshotter, @"Snapshotter should have been deallocated");
-
- dispatch_group_leave(dg);
- }];
- });
-
- dispatch_group_notify(dg, dispatch_get_main_queue(), ^{
- [expectation fulfill];
- });
- });
-
- [self waitForExpectations:@[expectation] timeout:timeout];
-}
-
-- (void)testSnapshotterUsingNestedDispatchQueues🔒 {
- // This is the opposite pair to the above test `testDeallocatingSnapshotterDuringSnapshot`
- // The only significant difference is that the snapshotter is a `__block` variable, so
- // its lifetime should continue until it's set to nil in the completion block.
- // See also https://github.com/mapbox/mapbox-gl-native/issues/12336
-
- NSTimeInterval timeout = 10.0;
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshot"];
- CGSize size = self.mapView.bounds.size;
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- // Test triggering to main queue
- dispatch_queue_t backgroundQueue = dispatch_get_main_queue();
- // dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
-
- __weak __typeof__(self) weakself = self;
-
- dispatch_async(backgroundQueue, ^{
-
- dispatch_group_t dg = dispatch_group_create();
- dispatch_group_enter(dg);
-
- dispatch_async(dispatch_get_main_queue(), ^{
-
- __block MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
-
- [snapshotter startWithCompletionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- // We expect this completion block to be called with an error
- __typeof__(self) strongself = weakself;
- MGLTestAssertNotNil(strongself, snapshot);
- MGLTestAssertNil(strongself, error, @"Snapshotter should have completed");
- dispatch_group_leave(dg);
- snapshotter = nil;
- }];
- });
-
- dispatch_group_notify(dg, dispatch_get_main_queue(), ^{
- [expectation fulfill];
- });
- });
-
- [self waitForExpectations:@[expectation] timeout:timeout];
-}
-
-- (void)testCancellingSnapshot🔒 {
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshots"];
- expectation.assertForOverFulfill = YES;
- expectation.expectedFulfillmentCount = 1;
-
- CGSize size = self.mapView.bounds.size;
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
-
- __weak __typeof__(self) weakself = self;
-
- [snapshotter startWithCompletionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- // We expect this completion block to be called with an error
- __typeof__(self) strongself = weakself;
-
- MGLTestAssertNil(strongself, snapshot);
- MGLTestAssert(strongself,
- ([error.domain isEqualToString:MGLErrorDomain] && error.code == MGLErrorCodeSnapshotFailed),
- @"Should have been cancelled");
- MGLTestAssert(strongself, snapshotter.cancelled, @"Should have been cancelled");
- [expectation fulfill];
- }];
-
- [snapshotter cancel];
-
- [self waitForExpectations:@[expectation] timeout:5.0];
-}
-
-- (void)testAllocatingSnapshotOnBackgroundQueue🔒 {
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshots"];
-
- CGSize size = self.mapView.bounds.size;
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, QOS_MIN_RELATIVE_PRIORITY);
- dispatch_queue_t backgroundQueue = dispatch_queue_create(__PRETTY_FUNCTION__, attr);
-
- dispatch_async(backgroundQueue, ^{
-
- // Create the snapshotter - DO NOT START.
- MGLMapSnapshotter* snapshotter = snapshotterWithCoordinates(coord, size);
-
- dispatch_group_t group = dispatch_group_create();
- dispatch_group_enter(group);
-
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
- dispatch_group_leave(group);
- });
-
- dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
-
- snapshotter = nil;
-
- dispatch_sync(dispatch_get_main_queue(), ^{
- [expectation fulfill];
- });
- });
-
- [self waitForExpectations:@[expectation] timeout:2.0];
-}
-
-- (void)testSnapshotterFromBackgroundQueueShouldFail🔒 {
- CGSize size = self.mapView.bounds.size;
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshots"];
- expectation.expectedFulfillmentCount = 1;
- expectation.assertForOverFulfill = YES;
-
- __weak __typeof__(self) weakself = self;
-
- dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, QOS_MIN_RELATIVE_PRIORITY); // also for concurrent
- dispatch_queue_t backgroundQueue = dispatch_queue_create(__PRETTY_FUNCTION__, attr);
-
- // Use dispatch_group to keep the backgroundQueue block around (and
- // so also the MGLMapSnapshotter
- dispatch_group_t group = dispatch_group_create();
- dispatch_group_enter(group);
-
- dispatch_async(backgroundQueue, ^{
-
- MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
- XCTAssertNotNil(snapshotter);
-
- MGLMapSnapshotCompletionHandler completion = ^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- // The completion block should not be called
- MGLTestFail(weakself);
- dispatch_group_leave(group);
- };
-
- @try {
- [snapshotter startWithCompletionHandler:completion];
- MGLTestFail(weakself, @"startWithCompletionHandler: should raise an exception");
- }
- @catch (NSException *exception) {
- MGLTestAssert(weakself, exception.name == NSInvalidArgumentException);
- dispatch_group_leave(group);
- }
-
- // Wait for the snapshot to complete
- dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
-
- snapshotter = nil;
-
- dispatch_sync(dispatch_get_main_queue(), ^{
- [expectation fulfill];
- });
- });
-
- [self waitForExpectations:@[expectation] timeout:60.0];
-}
-
-- (void)testMultipleSnapshotters🔒🙁 {
- NSUInteger numSnapshots = 8;
- CGSize size = self.mapView.bounds.size;
-
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshots"];
- expectation.expectedFulfillmentCount = numSnapshots;
- expectation.assertForOverFulfill = YES;
-
- __weak __typeof__(self) weakself = self;
-
- for (size_t run = 0; run < numSnapshots; run++) {
-
- float ratio = (float)run/(float)numSnapshots;
- float lon = (ratio*120.0) + ((1.0-ratio)*54.0);
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(57.0, lon);
-
- __block MGLMapSnapshotter *snapshotter;
-
- // Allocate from an autorelease pool here, to avoid having
- // snapshotter retained for longer than we'd like to test.
- @autoreleasepool {
- snapshotter = snapshotterWithCoordinates(coord, size);
- XCTAssertNotNil(snapshotter);
- }
-
- [snapshotter startWithCompletionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
-
- // This should be the main queue
- __typeof__(self) strongself = weakself;
-
- MGLTestAssertNotNil(strongself, strongself);
-
- MGLTestAssertNotNil(strongself, snapshot);
- MGLTestAssertNotNil(strongself, snapshot.image);
- MGLTestAssertNil(strongself, error, @"Snapshot should not error with: %@", error);
-
- // Change this to XCTAttachmentLifetimeKeepAlways to be able to look at the snapshots after running
- XCTAttachment *attachment = [XCTAttachment attachmentWithImage:snapshot.image];
- attachment.lifetime = XCTAttachmentLifetimeDeleteOnSuccess;
- [strongself addAttachment:attachment];
-
- // Dealloc the snapshotter (by having this line in the block, we
- // also retained the snapshotter. Setting to nil should release, as
- // this block should be the only thing retaining it (since it was
- // allocated from the above autorelease pool)
- snapshotter = nil;
-
- [expectation fulfill];
- }];
- } // end for loop
-
- [self waitForExpectations:@[expectation] timeout:60.0];
-}
-
-- (void)testSnapshotPointConversion🔒 {
- CGSize size = self.mapView.bounds.size;
-
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshot"];
- expectation.expectedFulfillmentCount = 1;
- expectation.assertForOverFulfill = YES;
-
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
- XCTAssertNotNil(snapshotter);
-
- __weak __typeof__(self) weakself = self;
-
- [snapshotter startWithCompletionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
-
- __typeof__(self) myself = weakself;
-
- MGLTestAssertNotNil(myself, snapshot);
-
- CGPoint point = [snapshot pointForCoordinate:coord];
-
- CGFloat epsilon = 0.000001;
-
- MGLTestAssertEqualWithAccuracy(myself, point.x, size.width/2.0, epsilon);
- MGLTestAssertEqualWithAccuracy(myself, point.y, size.height/2.0, epsilon);
-
- CLLocationCoordinate2D coord2 = [snapshot coordinateForPoint:point];
-
- MGLTestAssertEqualWithAccuracy(myself, coord.latitude, coord2.latitude, epsilon);
- MGLTestAssertEqualWithAccuracy(myself, coord.longitude, coord2.longitude, epsilon);
-
- [expectation fulfill];
- }];
-
- [self waitForExpectations:@[expectation] timeout:10.0];
-}
-
-- (void)testSnapshotPointConversionCoordinateOrdering🔒 {
- CGSize size = self.mapView.bounds.size;
-
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshot"];
- expectation.expectedFulfillmentCount = 1;
- expectation.assertForOverFulfill = YES;
-
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
- XCTAssertNotNil(snapshotter);
-
- __weak __typeof__(self) weakself = self;
-
- [snapshotter startWithCompletionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
-
- __typeof__(self) myself = weakself;
-
- CGFloat epsilon = 0.000001;
-
- MGLTestAssertNotNil(myself, snapshot);
-
- CLLocationCoordinate2D coordTL = [snapshot coordinateForPoint:CGPointZero];
-
- MGLTestAssert(myself, coordTL.longitude < coord.longitude);
- MGLTestAssert(myself, coordTL.latitude > coord.latitude);
-
- // And check point
- CGPoint tl = [snapshot pointForCoordinate:coordTL];
- MGLTestAssertEqualWithAccuracy(myself, tl.x, 0.0, epsilon);
- MGLTestAssertEqualWithAccuracy(myself, tl.y, 0.0, epsilon);
-
- CLLocationCoordinate2D coordBR = [snapshot coordinateForPoint:CGPointMake(size.width, size.height)];
-
- MGLTestAssert(myself, coordBR.longitude > coord.longitude);
- MGLTestAssert(myself, coordBR.latitude < coord.latitude);
-
- [expectation fulfill];
- }];
-
- [self waitForExpectations:@[expectation] timeout:10.0];
-}
-
-- (void)testSnapshotWithOverlayHandlerFailure🔒 {
- CGSize size = self.mapView.bounds.size;
-
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshot with overlay fails"];
- expectation.expectedFulfillmentCount = 2;
-
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
- XCTAssertNotNil(snapshotter);
-
- [snapshotter startWithOverlayHandler:^(MGLMapSnapshotOverlay *snapshotOverlay) {
- XCTAssertNotNil(snapshotOverlay);
-
- UIGraphicsEndImageContext();
- [expectation fulfill];
- } completionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- XCTAssertNil(snapshot);
- XCTAssertNotNil(error);
- XCTAssertEqualObjects(error.domain, MGLErrorDomain);
- XCTAssertEqual(error.code, MGLErrorCodeSnapshotFailed);
- XCTAssertEqualObjects(error.localizedDescription, @"Failed to generate composited snapshot.");
-
- [expectation fulfill];
- }];
-
- [self waitForExpectations:@[expectation] timeout:10.0];
-}
-
-- (void)testSnapshotWithOverlayHandlerSuccess🔒 {
- CGSize size = self.mapView.bounds.size;
- CGRect snapshotRect = CGRectMake(0, 0, size.width, size.height);
-
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshot with overlay succeeds"];
- expectation.expectedFulfillmentCount = 2;
-
- CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(30.0, 30.0);
-
- MGLMapSnapshotter *snapshotter = snapshotterWithCoordinates(coord, size);
- XCTAssertNotNil(snapshotter);
-
- CGFloat scale = snapshotter.options.scale;
-
- [snapshotter startWithOverlayHandler:^(MGLMapSnapshotOverlay *snapshotOverlay) {
- XCTAssertNotNil(snapshotOverlay);
-
- CGFloat width = CGBitmapContextGetWidth(snapshotOverlay.context);
- CGFloat height = CGBitmapContextGetHeight(snapshotOverlay.context);
-
- CGRect contextRect = CGContextConvertRectToDeviceSpace(snapshotOverlay.context, CGRectMake(0, 0, 1, 0));
- CGFloat scaleFromContext = contextRect.size.width;
- XCTAssertEqual(scale, scaleFromContext);
- XCTAssertEqual(width, size.width*scale);
- XCTAssertEqual(height, size.height*scale);
-
- CGContextSetFillColorWithColor(snapshotOverlay.context, [UIColor.greenColor CGColor]);
- CGContextSetAlpha(snapshotOverlay.context, 0.2);
- CGContextAddRect(snapshotOverlay.context, snapshotRect);
- CGContextFillRect(snapshotOverlay.context, snapshotRect);
- [expectation fulfill];
- } completionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- XCTAssertNil(error);
- XCTAssertNotNil(snapshot);
- [expectation fulfill];
- }];
-
- [self waitForExpectations:@[expectation] timeout:10.0];
-}
-
-- (void)testSnapshotCoordinatesWithOverlayHandler🔒 {
- CGSize size = self.mapView.bounds.size;
-
- XCTestExpectation *expectation = [self expectationWithDescription:@"snapshot with overlay succeeds"];
- expectation.expectedFulfillmentCount = 2;
-
- CLLocationCoordinate2D london = { .latitude = 51.5074, .longitude = -0.1278 };
- CLLocationCoordinate2D paris = { .latitude = 48.8566, .longitude = 2.3522 };
-
- MGLCoordinateBounds bounds = {
- .ne = london,
- .sw = paris
- };
-
- MGLMapSnapshotter *snapshotter = snapshotterWithBounds(bounds, size);
- XCTAssertNotNil(snapshotter);
-
- void (^testCoordinates)(id<MGLMapSnapshotProtocol>) = ^(id<MGLMapSnapshotProtocol> snapshot){
- XCTAssertNotNil(snapshot);
-
- CGPoint londonPoint = [snapshot pointForCoordinate:london];
- CGPoint parisPoint = [snapshot pointForCoordinate:paris];
-
- XCTAssertEqualWithAccuracy(londonPoint.x, 0, 0.1);
- XCTAssertEqualWithAccuracy(parisPoint.x, size.width, 0.1);
-
- // Vertically, London and Paris are inset (due to the size vs coordinate bounds)
- XCTAssert(parisPoint.y > londonPoint.y);
- XCTAssert(londonPoint.y > 0.0);
- XCTAssert(parisPoint.y < size.height);
-
- CLLocationCoordinate2D london2 = [snapshot coordinateForPoint:londonPoint];
- CLLocationCoordinate2D paris2 = [snapshot coordinateForPoint:parisPoint];
-
- XCTAssertEqualWithAccuracy(london.latitude, london2.latitude, 0.0000001);
- XCTAssertEqualWithAccuracy(london.longitude, london2.longitude, 0.0000001);
- XCTAssertEqualWithAccuracy(paris.latitude, paris2.latitude, 0.0000001);
- XCTAssertEqualWithAccuracy(paris.longitude, paris2.longitude, 0.0000001);
- };
-
- [snapshotter startWithOverlayHandler:^(MGLMapSnapshotOverlay *snapshotOverlay) {
- XCTAssert([snapshotOverlay conformsToProtocol:@protocol(MGLMapSnapshotProtocol)]);
- testCoordinates((id<MGLMapSnapshotProtocol>)snapshotOverlay);
-
- [expectation fulfill];
- } completionHandler:^(MGLMapSnapshot * _Nullable snapshot, NSError * _Nullable error) {
- XCTAssert([snapshot conformsToProtocol:@protocol(MGLMapSnapshotProtocol)]);
- testCoordinates((id<MGLMapSnapshotProtocol>)snapshot);
-
- [expectation fulfill];
- }];
-
- [self waitForExpectations:@[expectation] timeout:10.0];
-}
-
-
-@end