blob: 4aaf68ca0c19ad7544b54f4cf9e7caf74f792ba3 [file] [log] [blame]
//
// UIControlRACSupportSpec.m
// ReactiveCocoa
//
// Created by Justin Spahr-Summers on 2013-06-15.
// Copyright (c) 2013 GitHub, Inc. All rights reserved.
//
#import "RACTestUIButton.h"
#import "EXTKeyPathCoding.h"
#import "NSObject+RACDeallocating.h"
#import "RACChannelExamples.h"
#import "RACCompoundDisposable.h"
#import "RACDisposable.h"
#import "RACSignal.h"
#import "UIControl+RACSignalSupport.h"
#import "UISlider+RACSignalSupport.h"
SpecBegin(UIControlRACSupport)
void (^setViewValueBlock)(UISlider *, NSNumber *) = ^(UISlider *view, NSNumber *value) {
view.value = value.floatValue;
// UIControlEvents don't trigger from programmatic modification. Do it
// manually.
for (id target in view.allTargets) {
// Control events are a mask, but UIControlEventAllEvents doesn't seem to
// match anything, 0 does.
for (NSString *selectorString in [view actionsForTarget:target forControlEvent:0]) {
SEL selector = NSSelectorFromString(selectorString);
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[target methodSignatureForSelector:selector]];
invocation.selector = selector;
UIEvent *event = nil;
[invocation setArgument:&event atIndex:2];
[invocation invokeWithTarget:target];
}
}
};
itShouldBehaveLike(RACViewChannelExamples, ^{
return @{
RACViewChannelExampleCreateViewBlock: ^{
return [[UISlider alloc] init];
},
RACViewChannelExampleCreateTerminalBlock: ^(UISlider *view) {
return [view rac_newValueChannelWithNilValue:@0.0];
},
RACViewChannelExampleKeyPath: @keypath(UISlider.new, value),
RACViewChannelExampleSetViewValueBlock: setViewValueBlock
};
});
it(@"should send on the returned signal when matching actions are sent", ^{
UIControl *control = [RACTestUIButton button];
expect(control).notTo.beNil();
__block NSUInteger receivedCount = 0;
[[control
rac_signalForControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]
subscribeNext:^(UIControl *sender) {
expect(sender).to.beIdenticalTo(control);
receivedCount++;
}];
expect(receivedCount).to.equal(0);
[control sendActionsForControlEvents:UIControlEventTouchUpInside];
expect(receivedCount).to.equal(1);
// Should do nothing.
[control sendActionsForControlEvents:UIControlEventTouchDown];
expect(receivedCount).to.equal(1);
[control sendActionsForControlEvents:UIControlEventTouchUpOutside];
expect(receivedCount).to.equal(2);
});
it(@"should send completed when the control is deallocated", ^{
__block BOOL completed = NO;
__block BOOL deallocated = NO;
@autoreleasepool {
UIControl *control __attribute__((objc_precise_lifetime)) = [RACTestUIButton button];
[control.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
deallocated = YES;
}]];
[[control
rac_signalForControlEvents:UIControlEventTouchDown]
subscribeCompleted:^{
completed = YES;
}];
expect(deallocated).to.beFalsy();
expect(completed).to.beFalsy();
}
expect(deallocated).to.beTruthy();
expect(completed).to.beTruthy();
});
SpecEnd