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
114
115
116
117
118
119
120
121
122
|
#import <XCTest/XCTest.h>
#import "MGLTestingSupport.h"
@interface MGLMapRegionChangeEventsTests : XCTestCase
@property (nonatomic) XCUIApplication *app;
@end
@implementation MGLMapRegionChangeEventsTests
- (void)setUp {
[super setUp];
// In UI tests it is usually best to stop immediately when a failure occurs.
self.continueAfterFailure = NO;
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
self.app = [[XCUIApplication alloc] init];
self.app.launchArguments = [self.app.launchArguments arrayByAddingObject:@"useFastAnimations"];
[self.app launch];
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testMapViewRegionChangeEvents {
__block XCUIElement *mapViewElement;
__block NSMutableArray *regionEvents = [NSMutableArray array];
[XCTContext runActivityNamed:@"Wait for initial render" block:^(id<XCTActivity> _Nonnull activity) {
XCUIElementQuery *allQuery = [self.app descendantsMatchingType:XCUIElementTypeAny];
mapViewElement = [allQuery elementMatchingType:XCUIElementTypeAny identifier:MGLTestingSupportMapViewID];
XCTDarwinNotificationExpectation *expectation = [[XCTDarwinNotificationExpectation alloc] initWithNotificationName:MGLTestingSupportNotificationMapViewRendered];
[self waitForExpectations:@[expectation] timeout:15.0];
}];
[XCTContext runActivityNamed:@"Perform guestures" block:^(id<XCTActivity> _Nonnull activity) {
XCTDarwinNotificationExpectation *willChangeExpectation = [[XCTDarwinNotificationExpectation alloc] initWithNotificationName:MGLTestingSupportNotificationMapViewRegionWillChange];
willChangeExpectation.handler = ^BOOL{
// Expect the RegionWillChange event occoured 2 times
[regionEvents addObject:MGLTestingSupportNotificationMapViewRegionWillChange];
NSArray *events = [regionEvents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF = %@",
MGLTestingSupportNotificationMapViewRegionWillChange]];
return events.count == 2;
};
XCTDarwinNotificationExpectation *isChangingExpectation = [[XCTDarwinNotificationExpectation alloc] initWithNotificationName:MGLTestingSupportNotificationMapViewRegionIsChanging];
isChangingExpectation.handler = ^BOOL{
[regionEvents addObject:MGLTestingSupportNotificationMapViewRegionIsChanging];
NSArray *events = [regionEvents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF = %@",
MGLTestingSupportNotificationMapViewRegionIsChanging]];
// Expect the RegionIsChanging event occoured > 2 times
return events.count >= 2;
};
XCTDarwinNotificationExpectation *didChangeExpectation = [[XCTDarwinNotificationExpectation alloc] initWithNotificationName:MGLTestingSupportNotificationMapViewRegionDidChanged];
didChangeExpectation.handler = ^BOOL{
[regionEvents addObject:MGLTestingSupportNotificationMapViewRegionDidChanged];
NSArray *events = [regionEvents filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF = %@",
MGLTestingSupportNotificationMapViewRegionDidChanged]];
// Expect the RegionDidChanged event occoured 2 times
return events.count == 2;
};
[mapViewElement swipeUp];
// TODO: Seems the swipe down guesture performed after previous guesture finished,
// Tried to find a method which could interrupt previous guesture and start an new guesture
[mapViewElement swipeDown];
[self waitForExpectations:@[willChangeExpectation,
isChangingExpectation,
didChangeExpectation]
timeout:10];
}];
/*
Verify the events occured as the following order.
-mapView:regionWillChangeAnimated:
-mapViewIsChangingAnimated: many times
-mapView:regionDidChangeAnimated:
-mapView:regionWillChangeAnimated:
-mapViewIsChangingAnimated: many times
-mapView:regionDidChangeAnimated:
*/
NSIndexSet *willChangePoints = [regionEvents indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
return [obj isEqualToString:MGLTestingSupportNotificationMapViewRegionWillChange];
}];
NSIndexSet *didChangedPoints = [regionEvents indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
return [obj isEqualToString:MGLTestingSupportNotificationMapViewRegionDidChanged];
}];
[XCTContext runActivityNamed:@"Verify events triggered by swipe up" block:^(id<XCTActivity> _Nonnull activity) {
[self verifyOrderWithEvents:[regionEvents subarrayWithRange:NSMakeRange(willChangePoints.firstIndex,
didChangedPoints.firstIndex - willChangePoints.firstIndex + 1)]];
}];
[XCTContext runActivityNamed:@"Verify events triggered by swipe down" block:^(id<XCTActivity> _Nonnull activity) {
[self verifyOrderWithEvents:[regionEvents subarrayWithRange:NSMakeRange(willChangePoints.lastIndex,
didChangedPoints.lastIndex - willChangePoints.lastIndex + 1)]];
}];
}
- (void)verifyOrderWithEvents:(NSArray *)events {
// All the evets's count should >= 3
XCTAssertGreaterThanOrEqual(events.count, 3);
// The RegionWillChange event should occoured at first
XCTAssertEqual(events.firstObject, MGLTestingSupportNotificationMapViewRegionWillChange);
// All the RegionIsChanging event occoured in the process
for (NSInteger i = 1; i < events.count - 2; i ++) {
XCTAssertEqual(events[i], MGLTestingSupportNotificationMapViewRegionIsChanging);
}
// The RegionDidChanged event should occoured at end
XCTAssertEqual(events.lastObject, MGLTestingSupportNotificationMapViewRegionDidChanged);
}
@end
|