forked from facebook/componentkit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCKComponentDelegateAttributeTests.mm
157 lines (114 loc) · 4.9 KB
/
CKComponentDelegateAttributeTests.mm
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <XCTest/XCTest.h>
#import <ComponentKit/CKComponent+UIView.h>
#import <ComponentKit/CKComponent.h>
#import <ComponentKit/CKComponentDelegateAttribute.h>
#import <ComponentKit/CKComponentLayout.h>
#import <ComponentKit/CKComponentSubclass.h>
#import <ComponentKit/CKComponentInternal.h>
#import <ComponentKit/CKCompositeComponent.h>
@interface CKDetectScrollComponent : CKCompositeComponent <UIScrollViewDelegate>
@property (nonatomic, assign) BOOL receivedScroll;
@end
@interface CKComponentGestureActionsTests : XCTestCase
@end
@interface CKComponentDelegateAttributeTests : XCTestCase
@end
@implementation CKComponentDelegateAttributeTests
- (void)testApplicationApplies
{
CKComponentViewAttributeValue attr = CKComponentDelegateAttribute(@selector(setDelegate:), {
@selector(scrollViewDidScroll:)
});
UIScrollView *scrollView = [[UIScrollView alloc] init];
attr.first.applicator(scrollView, attr.second);
XCTAssertNotNil(scrollView.delegate, @"Expected delegate to be set");
attr.first.unapplicator(scrollView, attr.second);
XCTAssertNil(scrollView.delegate, @"Expected delegate to be unset");
}
static UIScrollView *findScrollView(UIView *v)
{
if ([v isKindOfClass:[UIScrollView class]]) {
return (UIScrollView *)v;
} else {
for (UIView *sub in v.subviews) {
return findScrollView(sub);
}
}
return nil;
};
- (void)testProxiedEventsProxy
{
CKDetectScrollComponent *hierarchy =
[CKDetectScrollComponent
newWithComponent:[CKComponent
newWithView:{[UIScrollView class],
{CKComponentDelegateAttribute(@selector(setDelegate:), {
@selector(scrollViewDidScroll:),
})}}
size:{}]];
CKComponentLayout layout = [hierarchy layoutThatFits:{} parentSize:{NAN, NAN}];
UIView *container = [UIView new];
NSSet *mounted = CKMountComponentLayout(layout, container, nil, nil);
XCTAssertFalse(hierarchy.receivedScroll, @"Should not have triggered yet");
UIScrollView *scroll = findScrollView(container);
scroll.contentOffset = CGPointMake(0, 100);
XCTAssertTrue(hierarchy.receivedScroll, @"Should have recived scroll event");
// Temporary hack because there's not a good way to unmount components. An assert fires otherwise.
// TODO: CKComponentUnmount(mounted);
[mounted makeObjectsPerformSelector:@selector(unmount)];
CKDetectScrollComponent *noScrollHierarchy =
[CKDetectScrollComponent
newWithComponent:[CKComponent
newWithView:{[UIScrollView class],
{CKComponentDelegateAttribute(@selector(setDelegate:), {})}}
size:{}]];
layout = [noScrollHierarchy layoutThatFits:{} parentSize:{NAN, NAN}];
CKMountComponentLayout(layout, container, nil, nil);
XCTAssertFalse(noScrollHierarchy.receivedScroll, @"Should not have triggered yet");
hierarchy.receivedScroll = NO;
scroll.contentOffset = CGPointMake(0, 100);
XCTAssertFalse(noScrollHierarchy.receivedScroll, @"Should not have triggered because we don't want scroll events.");
XCTAssertFalse(hierarchy.receivedScroll, @"Should not have triggered on old hierarchy either.");
}
- (void)testProxiedEventsProxyThrowsAssertionButDoesNotCrashWhenUnmounted
{
CKDetectScrollComponent *hierarchy =
[CKDetectScrollComponent
newWithComponent:[CKComponent
newWithView:{[UIScrollView class],
{CKComponentDelegateAttribute(@selector(setDelegate:), {
@selector(scrollViewDidScroll:),
})}}
size:{}]];
CKComponentLayout layout = [hierarchy layoutThatFits:{} parentSize:{NAN, NAN}];
UIView *container = [UIView new];
NSSet *mounted = CKMountComponentLayout(layout, container, nil, nil);
XCTAssertFalse(hierarchy.receivedScroll, @"Should not have triggered yet");
UIScrollView *scroll = findScrollView(container);
CKUnmountComponents(mounted);
@try {
// We have an assertion that may throw an exception depending on build flags. We don't want to assert that it throws
// but we do want to make sure we don't crash, so we catch it and ignore the results.
scroll.contentOffset = CGPointMake(0, 100);
} @catch (NSException *exception) { }
XCTAssertFalse(hierarchy.receivedScroll, @"Should not have recived scroll event");
// Un-set the delegate since deallocation will trigger a scroll event, which will throw the same assertion as we are
// catching above.
scroll.delegate = nil;
}
@end
@implementation CKDetectScrollComponent
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
_receivedScroll = YES;
}
@end