1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#import <Mapbox/Mapbox.h>
#pragma clang diagnostic ignored "-Wgnu-statement-expression"
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
#import <XCTest/XCTest.h>
@interface MGLOfflineStorageTests : XCTestCase
@end
@implementation MGLOfflineStorageTests
- (void)testSharedObject {
XCTAssertEqual([MGLOfflineStorage sharedOfflineStorage], [MGLOfflineStorage sharedOfflineStorage], @"There should only be one shared offline storage object.");
}
// This test needs to come first so it can test the initial loading of packs.
- (void)testAAALoadPacks {
XCTestExpectation *kvoExpectation = [self keyValueObservingExpectationForObject:[MGLOfflineStorage sharedOfflineStorage] keyPath:@"packs" handler:^BOOL(id _Nonnull observedObject, NSDictionary * _Nonnull change) {
NSKeyValueChange changeKind = [change[NSKeyValueChangeKindKey] unsignedIntegerValue];
return changeKind = NSKeyValueChangeSetting;
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
XCTAssertNotNil([MGLOfflineStorage sharedOfflineStorage].packs, @"Shared offline storage object should have a non-nil collection of packs by this point.");
}
- (void)testAddPack {
NSUInteger countOfPacks = [MGLOfflineStorage sharedOfflineStorage].packs.count;
NSURL *styleURL = [MGLStyle lightStyleURL];
/// Somewhere near Grape Grove, Ohio, United States.
MGLCoordinateBounds bounds = {
{ 39.70358155855172, -83.69506472545841 },
{ 39.703818870225376, -83.69420641857361 },
};
double zoomLevel = 20;
MGLTilePyramidOfflineRegion *region = [[MGLTilePyramidOfflineRegion alloc] initWithStyleURL:styleURL bounds:bounds fromZoomLevel:zoomLevel toZoomLevel:zoomLevel];
NSString *nameKey = @"Name";
NSString *name = @"🍇 Grape Grove";
NSData *context = [NSKeyedArchiver archivedDataWithRootObject:@{
nameKey: name,
}];
__block MGLOfflinePack *pack;
[self keyValueObservingExpectationForObject:[MGLOfflineStorage sharedOfflineStorage] keyPath:@"packs" handler:^BOOL(id _Nonnull observedObject, NSDictionary * _Nonnull change) {
NSKeyValueChange changeKind = [change[NSKeyValueChangeKindKey] unsignedIntegerValue];
NSIndexSet *indices = change[NSKeyValueChangeIndexesKey];
return changeKind == NSKeyValueChangeInsertion && indices.count == 1;
}];
XCTestExpectation *additionCompletionHandlerExpectation = [self expectationWithDescription:@"add pack completion handler"];
[[MGLOfflineStorage sharedOfflineStorage] addPackForRegion:region withContext:context completionHandler:^(MGLOfflinePack * _Nullable completionHandlerPack, NSError * _Nullable error) {
XCTAssertNotNil(completionHandlerPack, @"Added pack should exist.");
XCTAssertEqual(completionHandlerPack.state, MGLOfflinePackStateUnknown, @"Pack should initially have unknown state.");
pack = completionHandlerPack;
[additionCompletionHandlerExpectation fulfill];
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
XCTAssertEqual([MGLOfflineStorage sharedOfflineStorage].packs.count, countOfPacks + 1, @"Added pack should have been added to the canonical collection of packs owned by the shared offline storage object. This assertion can fail if this test is run before -testAAALoadPacks.");
XCTAssertEqual(pack, [MGLOfflineStorage sharedOfflineStorage].packs.lastObject, @"Pack should be appended to end of packs array.");
XCTAssertEqualObjects(pack.region, region, @"Added pack’s region has changed.");
NSDictionary *userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:pack.context];
XCTAssert([userInfo isKindOfClass:[NSDictionary class]], @"Context of offline pack isn’t a dictionary.");
XCTAssert([userInfo[nameKey] isKindOfClass:[NSString class]], @"Name of offline pack isn’t a string.");
XCTAssertEqualObjects(userInfo[nameKey], name, @"Name of offline pack has changed.");
XCTAssertEqual(pack.state, MGLOfflinePackStateUnknown, @"Pack should initially have unknown state.");
[self keyValueObservingExpectationForObject:pack keyPath:@"state" handler:^BOOL(id _Nonnull observedObject, NSDictionary * _Nonnull change) {
NSKeyValueChange changeKind = [change[NSKeyValueChangeKindKey] unsignedIntegerValue];
MGLOfflinePackState state = [change[NSKeyValueChangeNewKey] integerValue];
return changeKind == NSKeyValueChangeSetting && state == MGLOfflinePackStateInactive;
}];
[self expectationForNotification:MGLOfflinePackProgressChangedNotification object:pack handler:^BOOL(NSNotification * _Nonnull notification) {
MGLOfflinePack *notificationPack = notification.object;
XCTAssert([notificationPack isKindOfClass:[MGLOfflinePack class]], @"Object of notification should be an MGLOfflinePack.");
return notificationPack == pack && pack.state == MGLOfflinePackStateInactive;
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
}
- (void)testRemovePack {
NSUInteger countOfPacks = [MGLOfflineStorage sharedOfflineStorage].packs.count;
MGLOfflinePack *pack = [MGLOfflineStorage sharedOfflineStorage].packs.lastObject;
XCTAssertNotNil(pack, @"Added pack should still exist.");
XCTestExpectation *kvoExpectation = [self keyValueObservingExpectationForObject:[MGLOfflineStorage sharedOfflineStorage] keyPath:@"packs" handler:^BOOL(id _Nonnull observedObject, NSDictionary * _Nonnull change) {
NSKeyValueChange changeKind = [change[NSKeyValueChangeKindKey] unsignedIntegerValue];
NSIndexSet *indices = change[NSKeyValueChangeIndexesKey];
return changeKind = NSKeyValueChangeRemoval && indices.count == 1;
}];
XCTestExpectation *completionHandlerExpectation = [self expectationWithDescription:@"remove pack completion handler"];
[[MGLOfflineStorage sharedOfflineStorage] removePack:pack withCompletionHandler:^(NSError * _Nullable error) {
XCTAssertEqual(pack.state, MGLOfflinePackStateInvalid, @"Removed pack should be invalid in the completion handler.");
[completionHandlerExpectation fulfill];
}];
[self waitForExpectationsWithTimeout:1 handler:nil];
XCTAssertEqual(pack.state, MGLOfflinePackStateInvalid, @"Removed pack should have been invalidated synchronously.");
XCTAssertEqual([MGLOfflineStorage sharedOfflineStorage].packs.count, countOfPacks - 1, @"Removed pack should have been removed from the canonical collection of packs owned by the shared offline storage object. This assertion can fail if this test is run before -testAAALoadPacks or -testAddPack.");
}
@end
|