diff --git a/.gitmodules b/.gitmodules index a7dac25a0a..f0f5f4c35f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,7 +3,7 @@ url = https://github.com/jspahrsummers/xcconfigs.git [submodule "External/Quick"] path = External/Quick - url = https://github.com/Quick/Quick.git + url = https://github.com/github/Quick.git [submodule "External/LlamaKit"] path = External/LlamaKit url = https://github.com/ReactiveCocoa/LlamaKit.git diff --git a/External/Quick b/External/Quick index 27532db63e..04d1ef8682 160000 --- a/External/Quick +++ b/External/Quick @@ -1 +1 @@ -Subproject commit 27532db63e47f4a0250f3a80ef88f39343befdb4 +Subproject commit 04d1ef8682bfcb16e3258df87bdbb09da4a611fe diff --git a/ReactiveCocoa.xcodeproj/project.pbxproj b/ReactiveCocoa.xcodeproj/project.pbxproj index e496f2e48f..28b51b456b 100644 --- a/ReactiveCocoa.xcodeproj/project.pbxproj +++ b/ReactiveCocoa.xcodeproj/project.pbxproj @@ -7,1291 +7,1267 @@ objects = { /* Begin PBXBuildFile section */ - D011F1F319DD13F600A6F6C8 /* SignalSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D011F1F219DD13F600A6F6C8 /* SignalSpec.swift */; }; - D011F1F419DD13F600A6F6C8 /* SignalSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D011F1F219DD13F600A6F6C8 /* SignalSpec.swift */; }; - D0297D3619D67D42009986A9 /* Identity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0297D3519D67D42009986A9 /* Identity.swift */; }; - D0297D3719D67D42009986A9 /* Identity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0297D3519D67D42009986A9 /* Identity.swift */; }; - D0297D3C19D67EF5009986A9 /* LlamaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0297D3B19D67EF5009986A9 /* LlamaKit.framework */; }; - D0297D3E19D67F01009986A9 /* LlamaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0297D3D19D67F01009986A9 /* LlamaKit.framework */; }; - D02C14B1197243CB007127D4 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02C14B0197243CB007127D4 /* OptionalExtensions.swift */; }; - D02C14B2197243CB007127D4 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02C14B0197243CB007127D4 /* OptionalExtensions.swift */; }; - D036AA4B196FB7CB00B49B76 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D036AA4A196FB7CB00B49B76 /* Bag.swift */; }; - D036AA4C196FBCCD00B49B76 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D036AA4A196FB7CB00B49B76 /* Bag.swift */; }; - D047967919666BF30066B267 /* ReactiveCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = D047967819666BF30066B267 /* ReactiveCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047967F19666BF30066B267 /* ReactiveCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D047967319666BF30066B267 /* ReactiveCocoa.framework */; }; - D04796A519666CBF0066B267 /* ReactiveCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D047969A19666CBF0066B267 /* ReactiveCocoa.framework */; }; - D04797DD196670900066B267 /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479709196670900066B267 /* Action.swift */; }; - D04797DE196670900066B267 /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479709196670900066B267 /* Action.swift */; }; - D04797E1196670900066B267 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = D047970B196670900066B267 /* Atomic.swift */; }; - D04797E2196670900066B267 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = D047970B196670900066B267 /* Atomic.swift */; }; - D04797E7196670900066B267 /* Consumer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D047970E196670900066B267 /* Consumer.swift */; }; - D04797E8196670900066B267 /* Consumer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D047970E196670900066B267 /* Consumer.swift */; }; - D04797E9196670900066B267 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D047970F196670900066B267 /* Disposable.swift */; }; - D04797EA196670900066B267 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D047970F196670900066B267 /* Disposable.swift */; }; - D04797EB196670900066B267 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479710196670900066B267 /* Event.swift */; }; - D04797EC196670900066B267 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479710196670900066B267 /* Event.swift */; }; - D04797EF196670900066B267 /* NSArray+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479712196670900066B267 /* NSArray+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04797F0196670900066B267 /* NSArray+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479712196670900066B267 /* NSArray+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04797F1196670900066B267 /* NSArray+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479713196670900066B267 /* NSArray+RACSequenceAdditions.m */; }; - D04797F2196670900066B267 /* NSArray+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479713196670900066B267 /* NSArray+RACSequenceAdditions.m */; }; - D04797F3196670900066B267 /* NSControl+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479714196670900066B267 /* NSControl+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04797F5196670900066B267 /* NSControl+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479715196670900066B267 /* NSControl+RACCommandSupport.m */; }; - D04797F7196670900066B267 /* NSControl+RACTextSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479716196670900066B267 /* NSControl+RACTextSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04797F9196670900066B267 /* NSControl+RACTextSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479717196670900066B267 /* NSControl+RACTextSignalSupport.m */; }; - D04797FB196670900066B267 /* NSData+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479718196670900066B267 /* NSData+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04797FC196670900066B267 /* NSData+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479718196670900066B267 /* NSData+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04797FD196670900066B267 /* NSData+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479719196670900066B267 /* NSData+RACSupport.m */; }; - D04797FE196670900066B267 /* NSData+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479719196670900066B267 /* NSData+RACSupport.m */; }; - D04797FF196670900066B267 /* NSDictionary+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D047971A196670900066B267 /* NSDictionary+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479800196670900066B267 /* NSDictionary+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D047971A196670900066B267 /* NSDictionary+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479801196670900066B267 /* NSDictionary+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D047971B196670900066B267 /* NSDictionary+RACSequenceAdditions.m */; }; - D0479802196670900066B267 /* NSDictionary+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D047971B196670900066B267 /* NSDictionary+RACSequenceAdditions.m */; }; - D0479803196670900066B267 /* NSEnumerator+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D047971C196670900066B267 /* NSEnumerator+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479804196670900066B267 /* NSEnumerator+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D047971C196670900066B267 /* NSEnumerator+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479805196670900066B267 /* NSEnumerator+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D047971D196670900066B267 /* NSEnumerator+RACSequenceAdditions.m */; }; - D0479806196670900066B267 /* NSEnumerator+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D047971D196670900066B267 /* NSEnumerator+RACSequenceAdditions.m */; }; - D0479807196670900066B267 /* NSFileHandle+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D047971E196670900066B267 /* NSFileHandle+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479808196670900066B267 /* NSFileHandle+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D047971E196670900066B267 /* NSFileHandle+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479809196670900066B267 /* NSFileHandle+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D047971F196670900066B267 /* NSFileHandle+RACSupport.m */; }; - D047980A196670900066B267 /* NSFileHandle+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D047971F196670900066B267 /* NSFileHandle+RACSupport.m */; }; - D047980B196670900066B267 /* NSIndexSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479720196670900066B267 /* NSIndexSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047980C196670900066B267 /* NSIndexSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479720196670900066B267 /* NSIndexSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047980D196670900066B267 /* NSIndexSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479721196670900066B267 /* NSIndexSet+RACSequenceAdditions.m */; }; - D047980E196670900066B267 /* NSIndexSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479721196670900066B267 /* NSIndexSet+RACSequenceAdditions.m */; }; - D047980F196670900066B267 /* NSInvocation+RACTypeParsing.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479722196670900066B267 /* NSInvocation+RACTypeParsing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479810196670900066B267 /* NSInvocation+RACTypeParsing.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479722196670900066B267 /* NSInvocation+RACTypeParsing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479811196670900066B267 /* NSInvocation+RACTypeParsing.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479723196670900066B267 /* NSInvocation+RACTypeParsing.m */; }; - D0479812196670900066B267 /* NSInvocation+RACTypeParsing.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479723196670900066B267 /* NSInvocation+RACTypeParsing.m */; }; - D0479815196670900066B267 /* NSNotificationCenter+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479725196670900066B267 /* NSNotificationCenter+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479816196670900066B267 /* NSNotificationCenter+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479725196670900066B267 /* NSNotificationCenter+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479817196670900066B267 /* NSNotificationCenter+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479726196670900066B267 /* NSNotificationCenter+RACSupport.m */; }; - D0479818196670900066B267 /* NSNotificationCenter+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479726196670900066B267 /* NSNotificationCenter+RACSupport.m */; }; - D0479819196670900066B267 /* NSNotificationCenterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479727196670900066B267 /* NSNotificationCenterExtensions.swift */; }; - D047981A196670900066B267 /* NSNotificationCenterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479727196670900066B267 /* NSNotificationCenterExtensions.swift */; }; - D047981B196670900066B267 /* NSObject+RACAppKitBindings.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479728196670900066B267 /* NSObject+RACAppKitBindings.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047981D196670900066B267 /* NSObject+RACAppKitBindings.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479729196670900066B267 /* NSObject+RACAppKitBindings.m */; }; - D047981F196670900066B267 /* NSObject+RACDeallocating.h in Headers */ = {isa = PBXBuildFile; fileRef = D047972A196670900066B267 /* NSObject+RACDeallocating.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479820196670900066B267 /* NSObject+RACDeallocating.h in Headers */ = {isa = PBXBuildFile; fileRef = D047972A196670900066B267 /* NSObject+RACDeallocating.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479821196670900066B267 /* NSObject+RACDeallocating.m in Sources */ = {isa = PBXBuildFile; fileRef = D047972B196670900066B267 /* NSObject+RACDeallocating.m */; }; - D0479822196670900066B267 /* NSObject+RACDeallocating.m in Sources */ = {isa = PBXBuildFile; fileRef = D047972B196670900066B267 /* NSObject+RACDeallocating.m */; }; - D0479823196670900066B267 /* NSObject+RACDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = D047972C196670900066B267 /* NSObject+RACDescription.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479824196670900066B267 /* NSObject+RACDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = D047972C196670900066B267 /* NSObject+RACDescription.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479825196670900066B267 /* NSObject+RACDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = D047972D196670900066B267 /* NSObject+RACDescription.m */; }; - D0479826196670900066B267 /* NSObject+RACDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = D047972D196670900066B267 /* NSObject+RACDescription.m */; }; - D0479827196670900066B267 /* NSObject+RACKVOWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = D047972E196670900066B267 /* NSObject+RACKVOWrapper.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479828196670900066B267 /* NSObject+RACKVOWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = D047972E196670900066B267 /* NSObject+RACKVOWrapper.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479829196670900066B267 /* NSObject+RACKVOWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = D047972F196670900066B267 /* NSObject+RACKVOWrapper.m */; }; - D047982A196670900066B267 /* NSObject+RACKVOWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = D047972F196670900066B267 /* NSObject+RACKVOWrapper.m */; }; - D047982B196670900066B267 /* NSObject+RACLifting.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479730196670900066B267 /* NSObject+RACLifting.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047982C196670900066B267 /* NSObject+RACLifting.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479730196670900066B267 /* NSObject+RACLifting.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047982D196670900066B267 /* NSObject+RACLifting.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479731196670900066B267 /* NSObject+RACLifting.m */; }; - D047982E196670900066B267 /* NSObject+RACLifting.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479731196670900066B267 /* NSObject+RACLifting.m */; }; - D047982F196670900066B267 /* NSObject+RACPropertySubscribing.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479732196670900066B267 /* NSObject+RACPropertySubscribing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479830196670900066B267 /* NSObject+RACPropertySubscribing.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479732196670900066B267 /* NSObject+RACPropertySubscribing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479831196670900066B267 /* NSObject+RACPropertySubscribing.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479733196670900066B267 /* NSObject+RACPropertySubscribing.m */; }; - D0479832196670900066B267 /* NSObject+RACPropertySubscribing.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479733196670900066B267 /* NSObject+RACPropertySubscribing.m */; }; - D0479833196670900066B267 /* NSObject+RACSelectorSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479734196670900066B267 /* NSObject+RACSelectorSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479834196670900066B267 /* NSObject+RACSelectorSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479734196670900066B267 /* NSObject+RACSelectorSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479835196670900066B267 /* NSObject+RACSelectorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479735196670900066B267 /* NSObject+RACSelectorSignal.m */; }; - D0479836196670900066B267 /* NSObject+RACSelectorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479735196670900066B267 /* NSObject+RACSelectorSignal.m */; }; - D0479837196670900066B267 /* NSOrderedSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479736196670900066B267 /* NSOrderedSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479838196670900066B267 /* NSOrderedSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479736196670900066B267 /* NSOrderedSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479839196670900066B267 /* NSOrderedSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479737196670900066B267 /* NSOrderedSet+RACSequenceAdditions.m */; }; - D047983A196670900066B267 /* NSOrderedSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479737196670900066B267 /* NSOrderedSet+RACSequenceAdditions.m */; }; - D047983B196670900066B267 /* NSSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479738196670900066B267 /* NSSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047983C196670900066B267 /* NSSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479738196670900066B267 /* NSSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047983D196670900066B267 /* NSSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479739196670900066B267 /* NSSet+RACSequenceAdditions.m */; }; - D047983E196670900066B267 /* NSSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479739196670900066B267 /* NSSet+RACSequenceAdditions.m */; }; - D047983F196670900066B267 /* NSString+RACKeyPathUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = D047973A196670900066B267 /* NSString+RACKeyPathUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479840196670900066B267 /* NSString+RACKeyPathUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = D047973A196670900066B267 /* NSString+RACKeyPathUtilities.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479841196670900066B267 /* NSString+RACKeyPathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D047973B196670900066B267 /* NSString+RACKeyPathUtilities.m */; }; - D0479842196670900066B267 /* NSString+RACKeyPathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D047973B196670900066B267 /* NSString+RACKeyPathUtilities.m */; }; - D0479843196670900066B267 /* NSString+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D047973C196670900066B267 /* NSString+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479844196670900066B267 /* NSString+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D047973C196670900066B267 /* NSString+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479845196670900066B267 /* NSString+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D047973D196670900066B267 /* NSString+RACSequenceAdditions.m */; }; - D0479846196670900066B267 /* NSString+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D047973D196670900066B267 /* NSString+RACSequenceAdditions.m */; }; - D0479847196670900066B267 /* NSString+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D047973E196670900066B267 /* NSString+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479848196670900066B267 /* NSString+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D047973E196670900066B267 /* NSString+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479849196670900066B267 /* NSString+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D047973F196670900066B267 /* NSString+RACSupport.m */; }; - D047984A196670900066B267 /* NSString+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D047973F196670900066B267 /* NSString+RACSupport.m */; }; - D047984B196670900066B267 /* NSText+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479740196670900066B267 /* NSText+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047984D196670900066B267 /* NSText+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479741196670900066B267 /* NSText+RACSignalSupport.m */; }; - D047984F196670900066B267 /* NSURLConnection+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479742196670900066B267 /* NSURLConnection+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479850196670900066B267 /* NSURLConnection+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479742196670900066B267 /* NSURLConnection+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479851196670900066B267 /* NSURLConnection+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479743196670900066B267 /* NSURLConnection+RACSupport.m */; }; - D0479852196670900066B267 /* NSURLConnection+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479743196670900066B267 /* NSURLConnection+RACSupport.m */; }; - D0479853196670900066B267 /* NSURLSessionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479744196670900066B267 /* NSURLSessionExtensions.swift */; }; - D0479854196670900066B267 /* NSURLSessionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479744196670900066B267 /* NSURLSessionExtensions.swift */; }; - D0479855196670900066B267 /* NSUserDefaults+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479745196670900066B267 /* NSUserDefaults+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479856196670900066B267 /* NSUserDefaults+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479745196670900066B267 /* NSUserDefaults+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479857196670900066B267 /* NSUserDefaults+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479746196670900066B267 /* NSUserDefaults+RACSupport.m */; }; - D0479858196670900066B267 /* NSUserDefaults+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479746196670900066B267 /* NSUserDefaults+RACSupport.m */; }; - D0479859196670900066B267 /* ObjectiveCBridging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479747196670900066B267 /* ObjectiveCBridging.swift */; }; - D047985A196670900066B267 /* ObjectiveCBridging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479747196670900066B267 /* ObjectiveCBridging.swift */; }; - D047985B196670900066B267 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479748196670900066B267 /* Producer.swift */; }; - D047985C196670900066B267 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479748196670900066B267 /* Producer.swift */; }; - D047985D196670900066B267 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479749196670900066B267 /* Promise.swift */; }; - D047985E196670900066B267 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0479749196670900066B267 /* Promise.swift */; }; - D047985F196670900066B267 /* RACArraySequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D047974A196670900066B267 /* RACArraySequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479860196670900066B267 /* RACArraySequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D047974A196670900066B267 /* RACArraySequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479861196670900066B267 /* RACArraySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D047974B196670900066B267 /* RACArraySequence.m */; }; - D0479862196670900066B267 /* RACArraySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D047974B196670900066B267 /* RACArraySequence.m */; }; - D0479863196670900066B267 /* RACBacktrace.h in Headers */ = {isa = PBXBuildFile; fileRef = D047974C196670900066B267 /* RACBacktrace.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479864196670900066B267 /* RACBacktrace.h in Headers */ = {isa = PBXBuildFile; fileRef = D047974C196670900066B267 /* RACBacktrace.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479865196670900066B267 /* RACBacktrace.m in Sources */ = {isa = PBXBuildFile; fileRef = D047974D196670900066B267 /* RACBacktrace.m */; }; - D0479866196670900066B267 /* RACBacktrace.m in Sources */ = {isa = PBXBuildFile; fileRef = D047974D196670900066B267 /* RACBacktrace.m */; }; - D0479867196670900066B267 /* RACBehaviorSubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D047974E196670900066B267 /* RACBehaviorSubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479868196670900066B267 /* RACBehaviorSubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D047974E196670900066B267 /* RACBehaviorSubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479869196670900066B267 /* RACBehaviorSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D047974F196670900066B267 /* RACBehaviorSubject.m */; }; - D047986A196670900066B267 /* RACBehaviorSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D047974F196670900066B267 /* RACBehaviorSubject.m */; }; - D047986B196670900066B267 /* RACBlockTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479750196670900066B267 /* RACBlockTrampoline.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047986C196670900066B267 /* RACBlockTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479750196670900066B267 /* RACBlockTrampoline.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047986D196670900066B267 /* RACBlockTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479751196670900066B267 /* RACBlockTrampoline.m */; }; - D047986E196670900066B267 /* RACBlockTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479751196670900066B267 /* RACBlockTrampoline.m */; }; - D047986F196670900066B267 /* RACChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479752196670900066B267 /* RACChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479870196670900066B267 /* RACChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479752196670900066B267 /* RACChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479871196670900066B267 /* RACChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479753196670900066B267 /* RACChannel.m */; }; - D0479872196670900066B267 /* RACChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479753196670900066B267 /* RACChannel.m */; }; - D0479873196670900066B267 /* RACCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479754196670900066B267 /* RACCommand.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479874196670900066B267 /* RACCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479754196670900066B267 /* RACCommand.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479875196670900066B267 /* RACCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479755196670900066B267 /* RACCommand.m */; }; - D0479876196670900066B267 /* RACCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479755196670900066B267 /* RACCommand.m */; }; - D0479877196670900066B267 /* RACCompoundDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479756196670900066B267 /* RACCompoundDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479878196670900066B267 /* RACCompoundDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479756196670900066B267 /* RACCompoundDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479879196670900066B267 /* RACCompoundDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479757196670900066B267 /* RACCompoundDisposable.m */; }; - D047987A196670900066B267 /* RACCompoundDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479757196670900066B267 /* RACCompoundDisposable.m */; }; - D047987B196670900066B267 /* RACCompoundDisposableProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D0479758196670900066B267 /* RACCompoundDisposableProvider.d */; }; - D047987C196670900066B267 /* RACCompoundDisposableProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D0479758196670900066B267 /* RACCompoundDisposableProvider.d */; }; - D047987D196670900066B267 /* RACDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479759196670900066B267 /* RACDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047987E196670900066B267 /* RACDelegateProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479759196670900066B267 /* RACDelegateProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047987F196670900066B267 /* RACDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = D047975A196670900066B267 /* RACDelegateProxy.m */; }; - D0479880196670900066B267 /* RACDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = D047975A196670900066B267 /* RACDelegateProxy.m */; }; - D0479881196670900066B267 /* RACDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D047975B196670900066B267 /* RACDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479882196670900066B267 /* RACDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D047975B196670900066B267 /* RACDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479883196670900066B267 /* RACDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D047975C196670900066B267 /* RACDisposable.m */; }; - D0479884196670900066B267 /* RACDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D047975C196670900066B267 /* RACDisposable.m */; }; - D0479885196670900066B267 /* RACDynamicSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D047975D196670900066B267 /* RACDynamicSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479886196670900066B267 /* RACDynamicSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D047975D196670900066B267 /* RACDynamicSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479887196670900066B267 /* RACDynamicSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D047975E196670900066B267 /* RACDynamicSequence.m */; }; - D0479888196670900066B267 /* RACDynamicSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D047975E196670900066B267 /* RACDynamicSequence.m */; }; - D0479889196670900066B267 /* RACDynamicSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D047975F196670900066B267 /* RACDynamicSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047988A196670900066B267 /* RACDynamicSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D047975F196670900066B267 /* RACDynamicSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047988B196670900066B267 /* RACDynamicSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479760196670900066B267 /* RACDynamicSignal.m */; }; - D047988C196670900066B267 /* RACDynamicSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479760196670900066B267 /* RACDynamicSignal.m */; }; - D047988D196670900066B267 /* RACEagerSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479761196670900066B267 /* RACEagerSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047988E196670900066B267 /* RACEagerSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479761196670900066B267 /* RACEagerSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047988F196670900066B267 /* RACEagerSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479762196670900066B267 /* RACEagerSequence.m */; }; - D0479890196670900066B267 /* RACEagerSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479762196670900066B267 /* RACEagerSequence.m */; }; - D0479891196670900066B267 /* RACEmptySequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479763196670900066B267 /* RACEmptySequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479892196670900066B267 /* RACEmptySequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479763196670900066B267 /* RACEmptySequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479893196670900066B267 /* RACEmptySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479764196670900066B267 /* RACEmptySequence.m */; }; - D0479894196670900066B267 /* RACEmptySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479764196670900066B267 /* RACEmptySequence.m */; }; - D0479895196670900066B267 /* RACEmptySignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479765196670900066B267 /* RACEmptySignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479896196670900066B267 /* RACEmptySignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479765196670900066B267 /* RACEmptySignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479897196670900066B267 /* RACEmptySignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479766196670900066B267 /* RACEmptySignal.m */; }; - D0479898196670900066B267 /* RACEmptySignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479766196670900066B267 /* RACEmptySignal.m */; }; - D0479899196670900066B267 /* RACErrorSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479767196670900066B267 /* RACErrorSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047989A196670900066B267 /* RACErrorSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479767196670900066B267 /* RACErrorSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047989B196670900066B267 /* RACErrorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479768196670900066B267 /* RACErrorSignal.m */; }; - D047989C196670900066B267 /* RACErrorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479768196670900066B267 /* RACErrorSignal.m */; }; - D047989D196670900066B267 /* RACEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479769196670900066B267 /* RACEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047989E196670900066B267 /* RACEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479769196670900066B267 /* RACEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047989F196670900066B267 /* RACEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = D047976A196670900066B267 /* RACEvent.m */; }; - D04798A0196670900066B267 /* RACEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = D047976A196670900066B267 /* RACEvent.m */; }; - D04798A1196670900066B267 /* RACGroupedSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D047976B196670900066B267 /* RACGroupedSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798A2196670900066B267 /* RACGroupedSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D047976B196670900066B267 /* RACGroupedSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798A3196670900066B267 /* RACGroupedSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D047976C196670900066B267 /* RACGroupedSignal.m */; }; - D04798A4196670900066B267 /* RACGroupedSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D047976C196670900066B267 /* RACGroupedSignal.m */; }; - D04798A5196670900066B267 /* RACImmediateScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D047976D196670900066B267 /* RACImmediateScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798A6196670900066B267 /* RACImmediateScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D047976D196670900066B267 /* RACImmediateScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798A7196670900066B267 /* RACImmediateScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D047976E196670900066B267 /* RACImmediateScheduler.m */; }; - D04798A8196670900066B267 /* RACImmediateScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D047976E196670900066B267 /* RACImmediateScheduler.m */; }; - D04798A9196670900066B267 /* RACIndexSetSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D047976F196670900066B267 /* RACIndexSetSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798AA196670900066B267 /* RACIndexSetSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D047976F196670900066B267 /* RACIndexSetSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798AB196670900066B267 /* RACIndexSetSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479770196670900066B267 /* RACIndexSetSequence.m */; }; - D04798AC196670900066B267 /* RACIndexSetSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479770196670900066B267 /* RACIndexSetSequence.m */; }; - D04798AD196670900066B267 /* RACKVOChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479771196670900066B267 /* RACKVOChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798AE196670900066B267 /* RACKVOChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479771196670900066B267 /* RACKVOChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798AF196670900066B267 /* RACKVOChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479772196670900066B267 /* RACKVOChannel.m */; }; - D04798B0196670900066B267 /* RACKVOChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479772196670900066B267 /* RACKVOChannel.m */; }; - D04798B1196670900066B267 /* RACKVOTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479773196670900066B267 /* RACKVOTrampoline.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798B2196670900066B267 /* RACKVOTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479773196670900066B267 /* RACKVOTrampoline.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798B3196670900066B267 /* RACKVOTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479774196670900066B267 /* RACKVOTrampoline.m */; }; - D04798B4196670900066B267 /* RACKVOTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479774196670900066B267 /* RACKVOTrampoline.m */; }; - D04798B5196670900066B267 /* RACMulticastConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479775196670900066B267 /* RACMulticastConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798B6196670900066B267 /* RACMulticastConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479775196670900066B267 /* RACMulticastConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798B7196670900066B267 /* RACMulticastConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479776196670900066B267 /* RACMulticastConnection.m */; }; - D04798B8196670900066B267 /* RACMulticastConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479776196670900066B267 /* RACMulticastConnection.m */; }; - D04798B9196670900066B267 /* RACMulticastConnection+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479777196670900066B267 /* RACMulticastConnection+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798BA196670900066B267 /* RACMulticastConnection+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479777196670900066B267 /* RACMulticastConnection+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798BB196670900066B267 /* RACObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479778196670900066B267 /* RACObjCRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798BC196670900066B267 /* RACObjCRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479778196670900066B267 /* RACObjCRuntime.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798BD196670900066B267 /* RACObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479779196670900066B267 /* RACObjCRuntime.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - D04798BE196670900066B267 /* RACObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479779196670900066B267 /* RACObjCRuntime.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; - D04798BF196670900066B267 /* RACPassthroughSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = D047977A196670900066B267 /* RACPassthroughSubscriber.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798C0196670900066B267 /* RACPassthroughSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = D047977A196670900066B267 /* RACPassthroughSubscriber.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798C1196670900066B267 /* RACPassthroughSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D047977B196670900066B267 /* RACPassthroughSubscriber.m */; }; - D04798C2196670900066B267 /* RACPassthroughSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D047977B196670900066B267 /* RACPassthroughSubscriber.m */; }; - D04798C3196670900066B267 /* RACQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D047977C196670900066B267 /* RACQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798C4196670900066B267 /* RACQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D047977C196670900066B267 /* RACQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798C5196670900066B267 /* RACQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D047977D196670900066B267 /* RACQueueScheduler.m */; }; - D04798C6196670900066B267 /* RACQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D047977D196670900066B267 /* RACQueueScheduler.m */; }; - D04798C7196670900066B267 /* RACQueueScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = D047977E196670900066B267 /* RACQueueScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798C8196670900066B267 /* RACQueueScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = D047977E196670900066B267 /* RACQueueScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798C9196670900066B267 /* RACReplaySubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D047977F196670900066B267 /* RACReplaySubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798CA196670900066B267 /* RACReplaySubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D047977F196670900066B267 /* RACReplaySubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798CB196670900066B267 /* RACReplaySubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479780196670900066B267 /* RACReplaySubject.m */; }; - D04798CC196670900066B267 /* RACReplaySubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479780196670900066B267 /* RACReplaySubject.m */; }; - D04798CD196670900066B267 /* RACReturnSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479781196670900066B267 /* RACReturnSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798CE196670900066B267 /* RACReturnSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479781196670900066B267 /* RACReturnSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798CF196670900066B267 /* RACReturnSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479782196670900066B267 /* RACReturnSignal.m */; }; - D04798D0196670900066B267 /* RACReturnSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479782196670900066B267 /* RACReturnSignal.m */; }; - D04798D1196670900066B267 /* RACScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479783196670900066B267 /* RACScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798D2196670900066B267 /* RACScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479783196670900066B267 /* RACScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798D3196670900066B267 /* RACScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479784196670900066B267 /* RACScheduler.m */; }; - D04798D4196670900066B267 /* RACScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479784196670900066B267 /* RACScheduler.m */; }; - D04798D5196670900066B267 /* RACScheduler+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479785196670900066B267 /* RACScheduler+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798D6196670900066B267 /* RACScheduler+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479785196670900066B267 /* RACScheduler+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798D7196670900066B267 /* RACScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479786196670900066B267 /* RACScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798D8196670900066B267 /* RACScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479786196670900066B267 /* RACScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798D9196670900066B267 /* RACScopedDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479787196670900066B267 /* RACScopedDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798DA196670900066B267 /* RACScopedDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479787196670900066B267 /* RACScopedDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798DB196670900066B267 /* RACScopedDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479788196670900066B267 /* RACScopedDisposable.m */; }; - D04798DC196670900066B267 /* RACScopedDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479788196670900066B267 /* RACScopedDisposable.m */; }; - D04798DD196670900066B267 /* RACSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479789196670900066B267 /* RACSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798DE196670900066B267 /* RACSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479789196670900066B267 /* RACSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798DF196670900066B267 /* RACSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D047978A196670900066B267 /* RACSequence.m */; }; - D04798E0196670900066B267 /* RACSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D047978A196670900066B267 /* RACSequence.m */; }; - D04798E1196670900066B267 /* RACSerialDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D047978B196670900066B267 /* RACSerialDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798E2196670900066B267 /* RACSerialDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D047978B196670900066B267 /* RACSerialDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798E3196670900066B267 /* RACSerialDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D047978C196670900066B267 /* RACSerialDisposable.m */; }; - D04798E4196670900066B267 /* RACSerialDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D047978C196670900066B267 /* RACSerialDisposable.m */; }; - D04798E5196670900066B267 /* RACSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D047978D196670900066B267 /* RACSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798E6196670900066B267 /* RACSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D047978D196670900066B267 /* RACSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798E7196670900066B267 /* RACSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D047978E196670900066B267 /* RACSignal.m */; }; - D04798E8196670900066B267 /* RACSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D047978E196670900066B267 /* RACSignal.m */; }; - D04798E9196670900066B267 /* RACSignal+Operations.h in Headers */ = {isa = PBXBuildFile; fileRef = D047978F196670900066B267 /* RACSignal+Operations.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798EA196670900066B267 /* RACSignal+Operations.h in Headers */ = {isa = PBXBuildFile; fileRef = D047978F196670900066B267 /* RACSignal+Operations.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798EB196670900066B267 /* RACSignal+Operations.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479790196670900066B267 /* RACSignal+Operations.m */; }; - D04798EC196670900066B267 /* RACSignal+Operations.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479790196670900066B267 /* RACSignal+Operations.m */; }; - D04798ED196670900066B267 /* RACSignalProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D0479791196670900066B267 /* RACSignalProvider.d */; }; - D04798EE196670900066B267 /* RACSignalProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D0479791196670900066B267 /* RACSignalProvider.d */; }; - D04798EF196670900066B267 /* RACSignalSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479792196670900066B267 /* RACSignalSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798F0196670900066B267 /* RACSignalSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479792196670900066B267 /* RACSignalSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798F1196670900066B267 /* RACSignalSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479793196670900066B267 /* RACSignalSequence.m */; }; - D04798F2196670900066B267 /* RACSignalSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479793196670900066B267 /* RACSignalSequence.m */; }; - D04798F3196670900066B267 /* RACStream.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479794196670900066B267 /* RACStream.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798F4196670900066B267 /* RACStream.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479794196670900066B267 /* RACStream.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798F5196670900066B267 /* RACStream.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479795196670900066B267 /* RACStream.m */; }; - D04798F6196670900066B267 /* RACStream.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479795196670900066B267 /* RACStream.m */; }; - D04798F7196670900066B267 /* RACStream+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479796196670900066B267 /* RACStream+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798F8196670900066B267 /* RACStream+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479796196670900066B267 /* RACStream+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798F9196670900066B267 /* RACStringSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479797196670900066B267 /* RACStringSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798FA196670900066B267 /* RACStringSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479797196670900066B267 /* RACStringSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798FB196670900066B267 /* RACStringSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479798196670900066B267 /* RACStringSequence.m */; }; - D04798FC196670900066B267 /* RACStringSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479798196670900066B267 /* RACStringSequence.m */; }; - D04798FD196670900066B267 /* RACSubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479799196670900066B267 /* RACSubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798FE196670900066B267 /* RACSubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479799196670900066B267 /* RACSubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D04798FF196670900066B267 /* RACSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D047979A196670900066B267 /* RACSubject.m */; }; - D0479900196670900066B267 /* RACSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D047979A196670900066B267 /* RACSubject.m */; }; - D0479901196670900066B267 /* RACSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = D047979B196670900066B267 /* RACSubscriber.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479902196670900066B267 /* RACSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = D047979B196670900066B267 /* RACSubscriber.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479903196670900066B267 /* RACSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D047979C196670900066B267 /* RACSubscriber.m */; }; - D0479904196670900066B267 /* RACSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D047979C196670900066B267 /* RACSubscriber.m */; }; - D0479905196670900066B267 /* RACSubscriber+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D047979D196670900066B267 /* RACSubscriber+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479906196670900066B267 /* RACSubscriber+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = D047979D196670900066B267 /* RACSubscriber+Private.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479907196670900066B267 /* RACSubscriptingAssignmentTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = D047979E196670900066B267 /* RACSubscriptingAssignmentTrampoline.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479908196670900066B267 /* RACSubscriptingAssignmentTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = D047979E196670900066B267 /* RACSubscriptingAssignmentTrampoline.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479909196670900066B267 /* RACSubscriptingAssignmentTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D047979F196670900066B267 /* RACSubscriptingAssignmentTrampoline.m */; }; - D047990A196670900066B267 /* RACSubscriptingAssignmentTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D047979F196670900066B267 /* RACSubscriptingAssignmentTrampoline.m */; }; - D047990B196670900066B267 /* RACSubscriptionScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A0196670900066B267 /* RACSubscriptionScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047990C196670900066B267 /* RACSubscriptionScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A0196670900066B267 /* RACSubscriptionScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047990D196670900066B267 /* RACSubscriptionScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A1196670900066B267 /* RACSubscriptionScheduler.m */; }; - D047990E196670900066B267 /* RACSubscriptionScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A1196670900066B267 /* RACSubscriptionScheduler.m */; }; - D047990F196670900066B267 /* RACTargetQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A2196670900066B267 /* RACTargetQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479910196670900066B267 /* RACTargetQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A2196670900066B267 /* RACTargetQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479911196670900066B267 /* RACTargetQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A3196670900066B267 /* RACTargetQueueScheduler.m */; }; - D0479912196670900066B267 /* RACTargetQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A3196670900066B267 /* RACTargetQueueScheduler.m */; }; - D0479913196670900066B267 /* RACTestScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A4196670900066B267 /* RACTestScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479914196670900066B267 /* RACTestScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A4196670900066B267 /* RACTestScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479915196670900066B267 /* RACTestScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A5196670900066B267 /* RACTestScheduler.m */; }; - D0479916196670900066B267 /* RACTestScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A5196670900066B267 /* RACTestScheduler.m */; }; - D0479917196670900066B267 /* RACTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A6196670900066B267 /* RACTuple.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479918196670900066B267 /* RACTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A6196670900066B267 /* RACTuple.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479919196670900066B267 /* RACTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A7196670900066B267 /* RACTuple.m */; }; - D047991A196670900066B267 /* RACTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A7196670900066B267 /* RACTuple.m */; }; - D047991B196670900066B267 /* RACTupleSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A8196670900066B267 /* RACTupleSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047991C196670900066B267 /* RACTupleSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797A8196670900066B267 /* RACTupleSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047991D196670900066B267 /* RACTupleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A9196670900066B267 /* RACTupleSequence.m */; }; - D047991E196670900066B267 /* RACTupleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797A9196670900066B267 /* RACTupleSequence.m */; }; - D047991F196670900066B267 /* RACUnarySequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797AA196670900066B267 /* RACUnarySequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479920196670900066B267 /* RACUnarySequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797AA196670900066B267 /* RACUnarySequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479921196670900066B267 /* RACUnarySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797AB196670900066B267 /* RACUnarySequence.m */; }; - D0479922196670900066B267 /* RACUnarySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797AB196670900066B267 /* RACUnarySequence.m */; }; - D0479923196670900066B267 /* RACUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797AC196670900066B267 /* RACUnit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479924196670900066B267 /* RACUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797AC196670900066B267 /* RACUnit.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479925196670900066B267 /* RACUnit.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797AD196670900066B267 /* RACUnit.m */; }; - D0479926196670900066B267 /* RACUnit.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797AD196670900066B267 /* RACUnit.m */; }; - D0479927196670900066B267 /* RACValueTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797AE196670900066B267 /* RACValueTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479928196670900066B267 /* RACValueTransformer.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797AE196670900066B267 /* RACValueTransformer.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479929196670900066B267 /* RACValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797AF196670900066B267 /* RACValueTransformer.m */; }; - D047992A196670900066B267 /* RACValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797AF196670900066B267 /* RACValueTransformer.m */; }; - D047992B196670900066B267 /* ReactiveCocoa-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797B0196670900066B267 /* ReactiveCocoa-Bridging-Header.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047992C196670900066B267 /* ReactiveCocoa-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797B0196670900066B267 /* ReactiveCocoa-Bridging-Header.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479931196670900066B267 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04797B3196670900066B267 /* Scheduler.swift */; }; - D0479932196670900066B267 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04797B3196670900066B267 /* Scheduler.swift */; }; - D0479933196670900066B267 /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04797B4196670900066B267 /* Signal.swift */; }; - D0479934196670900066B267 /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04797B4196670900066B267 /* Signal.swift */; }; - D0479935196670900066B267 /* SignalingProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04797B5196670900066B267 /* SignalingProperty.swift */; }; - D0479936196670900066B267 /* SignalingProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04797B5196670900066B267 /* SignalingProperty.swift */; }; - D047993A196670900066B267 /* UIActionSheet+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797B7196670900066B267 /* UIActionSheet+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047993C196670900066B267 /* UIActionSheet+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797B8196670900066B267 /* UIActionSheet+RACSignalSupport.m */; }; - D047993E196670900066B267 /* UIAlertView+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797B9196670900066B267 /* UIAlertView+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479940196670900066B267 /* UIAlertView+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797BA196670900066B267 /* UIAlertView+RACSignalSupport.m */; }; - D0479942196670900066B267 /* UIBarButtonItem+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797BB196670900066B267 /* UIBarButtonItem+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479944196670900066B267 /* UIBarButtonItem+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797BC196670900066B267 /* UIBarButtonItem+RACCommandSupport.m */; }; - D0479946196670900066B267 /* UIButton+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797BD196670900066B267 /* UIButton+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479948196670900066B267 /* UIButton+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797BE196670900066B267 /* UIButton+RACCommandSupport.m */; }; - D047994A196670900066B267 /* UICollectionReusableView+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797BF196670900066B267 /* UICollectionReusableView+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047994C196670900066B267 /* UICollectionReusableView+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797C0196670900066B267 /* UICollectionReusableView+RACSignalSupport.m */; }; - D047994E196670900066B267 /* UIControl+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797C1196670900066B267 /* UIControl+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479950196670900066B267 /* UIControl+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797C2196670900066B267 /* UIControl+RACSignalSupport.m */; }; - D0479952196670900066B267 /* UIControl+RACSignalSupportPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797C3196670900066B267 /* UIControl+RACSignalSupportPrivate.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479954196670900066B267 /* UIControl+RACSignalSupportPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797C4196670900066B267 /* UIControl+RACSignalSupportPrivate.m */; }; - D0479956196670900066B267 /* UIDatePicker+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797C5196670900066B267 /* UIDatePicker+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479958196670900066B267 /* UIDatePicker+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797C6196670900066B267 /* UIDatePicker+RACSignalSupport.m */; }; - D047995A196670900066B267 /* UIGestureRecognizer+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797C7196670900066B267 /* UIGestureRecognizer+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047995C196670900066B267 /* UIGestureRecognizer+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797C8196670900066B267 /* UIGestureRecognizer+RACSignalSupport.m */; }; - D047995E196670900066B267 /* UIImagePickerController+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797C9196670900066B267 /* UIImagePickerController+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479960196670900066B267 /* UIImagePickerController+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797CA196670900066B267 /* UIImagePickerController+RACSignalSupport.m */; }; - D0479962196670900066B267 /* UIRefreshControl+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797CB196670900066B267 /* UIRefreshControl+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479964196670900066B267 /* UIRefreshControl+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797CC196670900066B267 /* UIRefreshControl+RACCommandSupport.m */; }; - D0479966196670900066B267 /* UISegmentedControl+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797CD196670900066B267 /* UISegmentedControl+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479968196670900066B267 /* UISegmentedControl+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797CE196670900066B267 /* UISegmentedControl+RACSignalSupport.m */; }; - D047996A196670900066B267 /* UISlider+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797CF196670900066B267 /* UISlider+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047996C196670900066B267 /* UISlider+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797D0196670900066B267 /* UISlider+RACSignalSupport.m */; }; - D047996E196670900066B267 /* UIStepper+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797D1196670900066B267 /* UIStepper+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479970196670900066B267 /* UIStepper+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797D2196670900066B267 /* UIStepper+RACSignalSupport.m */; }; - D0479972196670900066B267 /* UISwitch+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797D3196670900066B267 /* UISwitch+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479974196670900066B267 /* UISwitch+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797D4196670900066B267 /* UISwitch+RACSignalSupport.m */; }; - D0479976196670900066B267 /* UITableViewCell+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797D5196670900066B267 /* UITableViewCell+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479978196670900066B267 /* UITableViewCell+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797D6196670900066B267 /* UITableViewCell+RACSignalSupport.m */; }; - D047997A196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797D7196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047997C196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797D8196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.m */; }; - D047997E196670900066B267 /* UITextField+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797D9196670900066B267 /* UITextField+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479980196670900066B267 /* UITextField+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797DA196670900066B267 /* UITextField+RACSignalSupport.m */; }; - D0479982196670900066B267 /* UITextView+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D04797DB196670900066B267 /* UITextView+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479984196670900066B267 /* UITextView+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D04797DC196670900066B267 /* UITextView+RACSignalSupport.m */; }; - D0479985196670F50066B267 /* ReactiveCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = D047967819666BF30066B267 /* ReactiveCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047998B196671DF0066B267 /* EXTKeyPathCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479986196671DF0066B267 /* EXTKeyPathCoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047998C196671DF0066B267 /* EXTKeyPathCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479986196671DF0066B267 /* EXTKeyPathCoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047998D196671DF0066B267 /* EXTRuntimeExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479987196671DF0066B267 /* EXTRuntimeExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047998E196671DF0066B267 /* EXTRuntimeExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479987196671DF0066B267 /* EXTRuntimeExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047998F196671DF0066B267 /* EXTRuntimeExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479988196671DF0066B267 /* EXTRuntimeExtensions.m */; }; - D0479990196671DF0066B267 /* EXTRuntimeExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D0479988196671DF0066B267 /* EXTRuntimeExtensions.m */; }; - D0479991196671DF0066B267 /* EXTScope.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479989196671DF0066B267 /* EXTScope.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479992196671DF0066B267 /* EXTScope.h in Headers */ = {isa = PBXBuildFile; fileRef = D0479989196671DF0066B267 /* EXTScope.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479993196671DF0066B267 /* metamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = D047998A196671DF0066B267 /* metamacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D0479994196671DF0066B267 /* metamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = D047998A196671DF0066B267 /* metamacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D047999F196678F20066B267 /* ObjectiveCBridgingSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D047999E196678F20066B267 /* ObjectiveCBridgingSpec.swift */; }; - D04799A0196678F20066B267 /* ObjectiveCBridgingSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D047999E196678F20066B267 /* ObjectiveCBridgingSpec.swift */; }; - D095745E197344E3002D44C1 /* DisposableSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D095745D197344E3002D44C1 /* DisposableSpec.swift */; }; - D095745F197344E3002D44C1 /* DisposableSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D095745D197344E3002D44C1 /* DisposableSpec.swift */; }; - D09574611973506C002D44C1 /* SchedulerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09574601973506C002D44C1 /* SchedulerSpec.swift */; }; - D09574621973506C002D44C1 /* SchedulerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09574601973506C002D44C1 /* SchedulerSpec.swift */; }; - D09C6CBC198F4931008E129B /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D09C6CBB198F4931008E129B /* Quick.framework */; }; - D09C6CBD198F4934008E129B /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D09C6CBB198F4931008E129B /* Quick.framework */; }; - D0AFFF1A19CF2EF70078D030 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AFFF1919CF2EF70078D030 /* Nimble.framework */; }; - D0AFFF1C19CF2EFC0078D030 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0AFFF1B19CF2EFC0078D030 /* Nimble.framework */; }; - D0E3CF551973AFC7004FD181 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E3CF541973AFC7004FD181 /* Errors.swift */; }; - D0E3CF561973AFC7004FD181 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0E3CF541973AFC7004FD181 /* Errors.swift */; }; + D01B7B6219EDD8FE00D26E01 /* Nimble.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D05E662419EDD82000904ACA /* Nimble.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + D01B7B6319EDD8FE00D26E01 /* Quick.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D037672B19EDA75D00A782A9 /* Quick.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + D01B7B6419EDD94B00D26E01 /* ReactiveCocoa.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = D047260C19E49F82006002AA /* ReactiveCocoa.framework */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + D03764E819EDA41200A782A9 /* NSArray+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037642A19EDA41200A782A9 /* NSArray+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764E919EDA41200A782A9 /* NSArray+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037642A19EDA41200A782A9 /* NSArray+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764EA19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037642B19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m */; }; + D03764EB19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037642B19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m */; }; + D03764EC19EDA41200A782A9 /* NSControl+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037642C19EDA41200A782A9 /* NSControl+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764EE19EDA41200A782A9 /* NSControl+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037642D19EDA41200A782A9 /* NSControl+RACCommandSupport.m */; }; + D03764F019EDA41200A782A9 /* NSControl+RACTextSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037642E19EDA41200A782A9 /* NSControl+RACTextSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764F219EDA41200A782A9 /* NSControl+RACTextSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037642F19EDA41200A782A9 /* NSControl+RACTextSignalSupport.m */; }; + D03764F419EDA41200A782A9 /* NSData+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643019EDA41200A782A9 /* NSData+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764F519EDA41200A782A9 /* NSData+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643019EDA41200A782A9 /* NSData+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764F619EDA41200A782A9 /* NSData+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643119EDA41200A782A9 /* NSData+RACSupport.m */; }; + D03764F719EDA41200A782A9 /* NSData+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643119EDA41200A782A9 /* NSData+RACSupport.m */; }; + D03764F819EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643219EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764F919EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643219EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764FA19EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643319EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.m */; }; + D03764FB19EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643319EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.m */; }; + D03764FC19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643419EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764FD19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643419EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03764FE19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643519EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m */; }; + D03764FF19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643519EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m */; }; + D037650019EDA41200A782A9 /* NSFileHandle+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643619EDA41200A782A9 /* NSFileHandle+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037650119EDA41200A782A9 /* NSFileHandle+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643619EDA41200A782A9 /* NSFileHandle+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037650219EDA41200A782A9 /* NSFileHandle+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643719EDA41200A782A9 /* NSFileHandle+RACSupport.m */; }; + D037650319EDA41200A782A9 /* NSFileHandle+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643719EDA41200A782A9 /* NSFileHandle+RACSupport.m */; }; + D037650419EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643819EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037650519EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643819EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037650619EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643919EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.m */; }; + D037650719EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643919EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.m */; }; + D037650A19EDA41200A782A9 /* NSInvocation+RACTypeParsing.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643B19EDA41200A782A9 /* NSInvocation+RACTypeParsing.m */; }; + D037650B19EDA41200A782A9 /* NSInvocation+RACTypeParsing.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643B19EDA41200A782A9 /* NSInvocation+RACTypeParsing.m */; }; + D037650C19EDA41200A782A9 /* NSNotificationCenter+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643C19EDA41200A782A9 /* NSNotificationCenter+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037650D19EDA41200A782A9 /* NSNotificationCenter+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643C19EDA41200A782A9 /* NSNotificationCenter+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037650E19EDA41200A782A9 /* NSNotificationCenter+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643D19EDA41200A782A9 /* NSNotificationCenter+RACSupport.m */; }; + D037650F19EDA41200A782A9 /* NSNotificationCenter+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643D19EDA41200A782A9 /* NSNotificationCenter+RACSupport.m */; }; + D037651019EDA41200A782A9 /* NSObject+RACAppKitBindings.h in Headers */ = {isa = PBXBuildFile; fileRef = D037643E19EDA41200A782A9 /* NSObject+RACAppKitBindings.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037651219EDA41200A782A9 /* NSObject+RACAppKitBindings.m in Sources */ = {isa = PBXBuildFile; fileRef = D037643F19EDA41200A782A9 /* NSObject+RACAppKitBindings.m */; }; + D037651419EDA41200A782A9 /* NSObject+RACDeallocating.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644019EDA41200A782A9 /* NSObject+RACDeallocating.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037651519EDA41200A782A9 /* NSObject+RACDeallocating.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644019EDA41200A782A9 /* NSObject+RACDeallocating.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037651619EDA41200A782A9 /* NSObject+RACDeallocating.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644119EDA41200A782A9 /* NSObject+RACDeallocating.m */; }; + D037651719EDA41200A782A9 /* NSObject+RACDeallocating.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644119EDA41200A782A9 /* NSObject+RACDeallocating.m */; }; + D037651A19EDA41200A782A9 /* NSObject+RACDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644319EDA41200A782A9 /* NSObject+RACDescription.m */; }; + D037651B19EDA41200A782A9 /* NSObject+RACDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644319EDA41200A782A9 /* NSObject+RACDescription.m */; }; + D037651E19EDA41200A782A9 /* NSObject+RACKVOWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644519EDA41200A782A9 /* NSObject+RACKVOWrapper.m */; }; + D037651F19EDA41200A782A9 /* NSObject+RACKVOWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644519EDA41200A782A9 /* NSObject+RACKVOWrapper.m */; }; + D037652019EDA41200A782A9 /* NSObject+RACLifting.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644619EDA41200A782A9 /* NSObject+RACLifting.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037652119EDA41200A782A9 /* NSObject+RACLifting.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644619EDA41200A782A9 /* NSObject+RACLifting.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037652219EDA41200A782A9 /* NSObject+RACLifting.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644719EDA41200A782A9 /* NSObject+RACLifting.m */; }; + D037652319EDA41200A782A9 /* NSObject+RACLifting.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644719EDA41200A782A9 /* NSObject+RACLifting.m */; }; + D037652419EDA41200A782A9 /* NSObject+RACPropertySubscribing.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644819EDA41200A782A9 /* NSObject+RACPropertySubscribing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037652519EDA41200A782A9 /* NSObject+RACPropertySubscribing.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644819EDA41200A782A9 /* NSObject+RACPropertySubscribing.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037652619EDA41200A782A9 /* NSObject+RACPropertySubscribing.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644919EDA41200A782A9 /* NSObject+RACPropertySubscribing.m */; }; + D037652719EDA41200A782A9 /* NSObject+RACPropertySubscribing.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644919EDA41200A782A9 /* NSObject+RACPropertySubscribing.m */; }; + D037652819EDA41200A782A9 /* NSObject+RACSelectorSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644A19EDA41200A782A9 /* NSObject+RACSelectorSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037652919EDA41200A782A9 /* NSObject+RACSelectorSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644A19EDA41200A782A9 /* NSObject+RACSelectorSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037652A19EDA41200A782A9 /* NSObject+RACSelectorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644B19EDA41200A782A9 /* NSObject+RACSelectorSignal.m */; }; + D037652B19EDA41200A782A9 /* NSObject+RACSelectorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644B19EDA41200A782A9 /* NSObject+RACSelectorSignal.m */; }; + D037652C19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644C19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037652D19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644C19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037652E19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644D19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.m */; }; + D037652F19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644D19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.m */; }; + D037653019EDA41200A782A9 /* NSSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644E19EDA41200A782A9 /* NSSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037653119EDA41200A782A9 /* NSSet+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037644E19EDA41200A782A9 /* NSSet+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037653219EDA41200A782A9 /* NSSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644F19EDA41200A782A9 /* NSSet+RACSequenceAdditions.m */; }; + D037653319EDA41200A782A9 /* NSSet+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037644F19EDA41200A782A9 /* NSSet+RACSequenceAdditions.m */; }; + D037653619EDA41200A782A9 /* NSString+RACKeyPathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645119EDA41200A782A9 /* NSString+RACKeyPathUtilities.m */; }; + D037653719EDA41200A782A9 /* NSString+RACKeyPathUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645119EDA41200A782A9 /* NSString+RACKeyPathUtilities.m */; }; + D037653819EDA41200A782A9 /* NSString+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645219EDA41200A782A9 /* NSString+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037653919EDA41200A782A9 /* NSString+RACSequenceAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645219EDA41200A782A9 /* NSString+RACSequenceAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037653A19EDA41200A782A9 /* NSString+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645319EDA41200A782A9 /* NSString+RACSequenceAdditions.m */; }; + D037653B19EDA41200A782A9 /* NSString+RACSequenceAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645319EDA41200A782A9 /* NSString+RACSequenceAdditions.m */; }; + D037653C19EDA41200A782A9 /* NSString+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645419EDA41200A782A9 /* NSString+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037653D19EDA41200A782A9 /* NSString+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645419EDA41200A782A9 /* NSString+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037653E19EDA41200A782A9 /* NSString+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645519EDA41200A782A9 /* NSString+RACSupport.m */; }; + D037653F19EDA41200A782A9 /* NSString+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645519EDA41200A782A9 /* NSString+RACSupport.m */; }; + D037654019EDA41200A782A9 /* NSText+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645619EDA41200A782A9 /* NSText+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037654219EDA41200A782A9 /* NSText+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645719EDA41200A782A9 /* NSText+RACSignalSupport.m */; }; + D037654419EDA41200A782A9 /* NSURLConnection+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645819EDA41200A782A9 /* NSURLConnection+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037654519EDA41200A782A9 /* NSURLConnection+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645819EDA41200A782A9 /* NSURLConnection+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037654619EDA41200A782A9 /* NSURLConnection+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645919EDA41200A782A9 /* NSURLConnection+RACSupport.m */; }; + D037654719EDA41200A782A9 /* NSURLConnection+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645919EDA41200A782A9 /* NSURLConnection+RACSupport.m */; }; + D037654819EDA41200A782A9 /* NSUserDefaults+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645A19EDA41200A782A9 /* NSUserDefaults+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037654919EDA41200A782A9 /* NSUserDefaults+RACSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645A19EDA41200A782A9 /* NSUserDefaults+RACSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037654A19EDA41200A782A9 /* NSUserDefaults+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645B19EDA41200A782A9 /* NSUserDefaults+RACSupport.m */; }; + D037654B19EDA41200A782A9 /* NSUserDefaults+RACSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645B19EDA41200A782A9 /* NSUserDefaults+RACSupport.m */; }; + D037654E19EDA41200A782A9 /* RACArraySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645D19EDA41200A782A9 /* RACArraySequence.m */; }; + D037654F19EDA41200A782A9 /* RACArraySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645D19EDA41200A782A9 /* RACArraySequence.m */; }; + D037655019EDA41200A782A9 /* RACBacktrace.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645E19EDA41200A782A9 /* RACBacktrace.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037655119EDA41200A782A9 /* RACBacktrace.h in Headers */ = {isa = PBXBuildFile; fileRef = D037645E19EDA41200A782A9 /* RACBacktrace.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037655219EDA41200A782A9 /* RACBacktrace.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645F19EDA41200A782A9 /* RACBacktrace.m */; }; + D037655319EDA41200A782A9 /* RACBacktrace.m in Sources */ = {isa = PBXBuildFile; fileRef = D037645F19EDA41200A782A9 /* RACBacktrace.m */; }; + D037655619EDA41200A782A9 /* RACBehaviorSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646119EDA41200A782A9 /* RACBehaviorSubject.m */; }; + D037655719EDA41200A782A9 /* RACBehaviorSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646119EDA41200A782A9 /* RACBehaviorSubject.m */; }; + D037655A19EDA41200A782A9 /* RACBlockTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646319EDA41200A782A9 /* RACBlockTrampoline.m */; }; + D037655B19EDA41200A782A9 /* RACBlockTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646319EDA41200A782A9 /* RACBlockTrampoline.m */; }; + D037655C19EDA41200A782A9 /* RACChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646419EDA41200A782A9 /* RACChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037655D19EDA41200A782A9 /* RACChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646419EDA41200A782A9 /* RACChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037655E19EDA41200A782A9 /* RACChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646519EDA41200A782A9 /* RACChannel.m */; }; + D037655F19EDA41200A782A9 /* RACChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646519EDA41200A782A9 /* RACChannel.m */; }; + D037656019EDA41200A782A9 /* RACCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646619EDA41200A782A9 /* RACCommand.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037656119EDA41200A782A9 /* RACCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646619EDA41200A782A9 /* RACCommand.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037656219EDA41200A782A9 /* RACCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646719EDA41200A782A9 /* RACCommand.m */; }; + D037656319EDA41200A782A9 /* RACCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646719EDA41200A782A9 /* RACCommand.m */; }; + D037656419EDA41200A782A9 /* RACCompoundDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646819EDA41200A782A9 /* RACCompoundDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037656519EDA41200A782A9 /* RACCompoundDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646819EDA41200A782A9 /* RACCompoundDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037656619EDA41200A782A9 /* RACCompoundDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646919EDA41200A782A9 /* RACCompoundDisposable.m */; }; + D037656719EDA41200A782A9 /* RACCompoundDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646919EDA41200A782A9 /* RACCompoundDisposable.m */; }; + D037656819EDA41200A782A9 /* RACCompoundDisposableProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D037646A19EDA41200A782A9 /* RACCompoundDisposableProvider.d */; }; + D037656919EDA41200A782A9 /* RACCompoundDisposableProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D037646A19EDA41200A782A9 /* RACCompoundDisposableProvider.d */; }; + D037656C19EDA41200A782A9 /* RACDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646C19EDA41200A782A9 /* RACDelegateProxy.m */; }; + D037656D19EDA41200A782A9 /* RACDelegateProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646C19EDA41200A782A9 /* RACDelegateProxy.m */; }; + D037656E19EDA41200A782A9 /* RACDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646D19EDA41200A782A9 /* RACDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037656F19EDA41200A782A9 /* RACDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646D19EDA41200A782A9 /* RACDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037657019EDA41200A782A9 /* RACDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646E19EDA41200A782A9 /* RACDisposable.m */; }; + D037657119EDA41200A782A9 /* RACDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D037646E19EDA41200A782A9 /* RACDisposable.m */; }; + D037657419EDA41200A782A9 /* RACDynamicSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647019EDA41200A782A9 /* RACDynamicSequence.m */; }; + D037657519EDA41200A782A9 /* RACDynamicSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647019EDA41200A782A9 /* RACDynamicSequence.m */; }; + D037657819EDA41200A782A9 /* RACDynamicSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647219EDA41200A782A9 /* RACDynamicSignal.m */; }; + D037657919EDA41200A782A9 /* RACDynamicSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647219EDA41200A782A9 /* RACDynamicSignal.m */; }; + D037657C19EDA41200A782A9 /* RACEagerSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647419EDA41200A782A9 /* RACEagerSequence.m */; }; + D037657D19EDA41200A782A9 /* RACEagerSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647419EDA41200A782A9 /* RACEagerSequence.m */; }; + D037658019EDA41200A782A9 /* RACEmptySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647619EDA41200A782A9 /* RACEmptySequence.m */; }; + D037658119EDA41200A782A9 /* RACEmptySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647619EDA41200A782A9 /* RACEmptySequence.m */; }; + D037658419EDA41200A782A9 /* RACEmptySignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647819EDA41200A782A9 /* RACEmptySignal.m */; }; + D037658519EDA41200A782A9 /* RACEmptySignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647819EDA41200A782A9 /* RACEmptySignal.m */; }; + D037658819EDA41200A782A9 /* RACErrorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647A19EDA41200A782A9 /* RACErrorSignal.m */; }; + D037658919EDA41200A782A9 /* RACErrorSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647A19EDA41200A782A9 /* RACErrorSignal.m */; }; + D037658A19EDA41200A782A9 /* RACEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = D037647B19EDA41200A782A9 /* RACEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037658B19EDA41200A782A9 /* RACEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = D037647B19EDA41200A782A9 /* RACEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037658C19EDA41200A782A9 /* RACEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647C19EDA41200A782A9 /* RACEvent.m */; }; + D037658D19EDA41200A782A9 /* RACEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647C19EDA41200A782A9 /* RACEvent.m */; }; + D037658E19EDA41200A782A9 /* RACGroupedSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D037647D19EDA41200A782A9 /* RACGroupedSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037658F19EDA41200A782A9 /* RACGroupedSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D037647D19EDA41200A782A9 /* RACGroupedSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037659019EDA41200A782A9 /* RACGroupedSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647E19EDA41200A782A9 /* RACGroupedSignal.m */; }; + D037659119EDA41200A782A9 /* RACGroupedSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037647E19EDA41200A782A9 /* RACGroupedSignal.m */; }; + D037659419EDA41200A782A9 /* RACImmediateScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648019EDA41200A782A9 /* RACImmediateScheduler.m */; }; + D037659519EDA41200A782A9 /* RACImmediateScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648019EDA41200A782A9 /* RACImmediateScheduler.m */; }; + D037659819EDA41200A782A9 /* RACIndexSetSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648219EDA41200A782A9 /* RACIndexSetSequence.m */; }; + D037659919EDA41200A782A9 /* RACIndexSetSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648219EDA41200A782A9 /* RACIndexSetSequence.m */; }; + D037659A19EDA41200A782A9 /* RACKVOChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D037648319EDA41200A782A9 /* RACKVOChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037659B19EDA41200A782A9 /* RACKVOChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = D037648319EDA41200A782A9 /* RACKVOChannel.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037659C19EDA41200A782A9 /* RACKVOChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648419EDA41200A782A9 /* RACKVOChannel.m */; }; + D037659D19EDA41200A782A9 /* RACKVOChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648419EDA41200A782A9 /* RACKVOChannel.m */; }; + D03765A019EDA41200A782A9 /* RACKVOTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648619EDA41200A782A9 /* RACKVOTrampoline.m */; }; + D03765A119EDA41200A782A9 /* RACKVOTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648619EDA41200A782A9 /* RACKVOTrampoline.m */; }; + D03765A219EDA41200A782A9 /* RACMulticastConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = D037648719EDA41200A782A9 /* RACMulticastConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765A319EDA41200A782A9 /* RACMulticastConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = D037648719EDA41200A782A9 /* RACMulticastConnection.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765A419EDA41200A782A9 /* RACMulticastConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648819EDA41200A782A9 /* RACMulticastConnection.m */; }; + D03765A519EDA41200A782A9 /* RACMulticastConnection.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648819EDA41200A782A9 /* RACMulticastConnection.m */; }; + D03765AA19EDA41200A782A9 /* RACObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648B19EDA41200A782A9 /* RACObjCRuntime.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + D03765AB19EDA41200A782A9 /* RACObjCRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648B19EDA41200A782A9 /* RACObjCRuntime.m */; settings = {COMPILER_FLAGS = "-fno-objc-arc"; }; }; + D03765AE19EDA41200A782A9 /* RACPassthroughSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648D19EDA41200A782A9 /* RACPassthroughSubscriber.m */; }; + D03765AF19EDA41200A782A9 /* RACPassthroughSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648D19EDA41200A782A9 /* RACPassthroughSubscriber.m */; }; + D03765B019EDA41200A782A9 /* RACQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D037648E19EDA41200A782A9 /* RACQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765B119EDA41200A782A9 /* RACQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D037648E19EDA41200A782A9 /* RACQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765B219EDA41200A782A9 /* RACQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648F19EDA41200A782A9 /* RACQueueScheduler.m */; }; + D03765B319EDA41200A782A9 /* RACQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D037648F19EDA41200A782A9 /* RACQueueScheduler.m */; }; + D03765B419EDA41200A782A9 /* RACQueueScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649019EDA41200A782A9 /* RACQueueScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765B519EDA41200A782A9 /* RACQueueScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649019EDA41200A782A9 /* RACQueueScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765B619EDA41200A782A9 /* RACReplaySubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649119EDA41200A782A9 /* RACReplaySubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765B719EDA41200A782A9 /* RACReplaySubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649119EDA41200A782A9 /* RACReplaySubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765B819EDA41200A782A9 /* RACReplaySubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649219EDA41200A782A9 /* RACReplaySubject.m */; }; + D03765B919EDA41200A782A9 /* RACReplaySubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649219EDA41200A782A9 /* RACReplaySubject.m */; }; + D03765BC19EDA41200A782A9 /* RACReturnSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649419EDA41200A782A9 /* RACReturnSignal.m */; }; + D03765BD19EDA41200A782A9 /* RACReturnSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649419EDA41200A782A9 /* RACReturnSignal.m */; }; + D03765BE19EDA41200A782A9 /* RACScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649519EDA41200A782A9 /* RACScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765BF19EDA41200A782A9 /* RACScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649519EDA41200A782A9 /* RACScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765C019EDA41200A782A9 /* RACScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649619EDA41200A782A9 /* RACScheduler.m */; }; + D03765C119EDA41200A782A9 /* RACScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649619EDA41200A782A9 /* RACScheduler.m */; }; + D03765C419EDA41200A782A9 /* RACScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649819EDA41200A782A9 /* RACScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765C519EDA41200A782A9 /* RACScheduler+Subclass.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649819EDA41200A782A9 /* RACScheduler+Subclass.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765C619EDA41200A782A9 /* RACScopedDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649919EDA41200A782A9 /* RACScopedDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765C719EDA41200A782A9 /* RACScopedDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649919EDA41200A782A9 /* RACScopedDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765C819EDA41200A782A9 /* RACScopedDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649A19EDA41200A782A9 /* RACScopedDisposable.m */; }; + D03765C919EDA41200A782A9 /* RACScopedDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649A19EDA41200A782A9 /* RACScopedDisposable.m */; }; + D03765CA19EDA41200A782A9 /* RACSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649B19EDA41200A782A9 /* RACSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765CB19EDA41200A782A9 /* RACSequence.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649B19EDA41200A782A9 /* RACSequence.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765CC19EDA41200A782A9 /* RACSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649C19EDA41200A782A9 /* RACSequence.m */; }; + D03765CD19EDA41200A782A9 /* RACSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649C19EDA41200A782A9 /* RACSequence.m */; }; + D03765CE19EDA41200A782A9 /* RACSerialDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649D19EDA41200A782A9 /* RACSerialDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765CF19EDA41200A782A9 /* RACSerialDisposable.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649D19EDA41200A782A9 /* RACSerialDisposable.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765D019EDA41200A782A9 /* RACSerialDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649E19EDA41200A782A9 /* RACSerialDisposable.m */; }; + D03765D119EDA41200A782A9 /* RACSerialDisposable.m in Sources */ = {isa = PBXBuildFile; fileRef = D037649E19EDA41200A782A9 /* RACSerialDisposable.m */; }; + D03765D219EDA41200A782A9 /* RACSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649F19EDA41200A782A9 /* RACSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765D319EDA41200A782A9 /* RACSignal.h in Headers */ = {isa = PBXBuildFile; fileRef = D037649F19EDA41200A782A9 /* RACSignal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765D419EDA41200A782A9 /* RACSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764A019EDA41200A782A9 /* RACSignal.m */; }; + D03765D519EDA41200A782A9 /* RACSignal.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764A019EDA41200A782A9 /* RACSignal.m */; }; + D03765D619EDA41200A782A9 /* RACSignal+Operations.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764A119EDA41200A782A9 /* RACSignal+Operations.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765D719EDA41200A782A9 /* RACSignal+Operations.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764A119EDA41200A782A9 /* RACSignal+Operations.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765D819EDA41200A782A9 /* RACSignal+Operations.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764A219EDA41200A782A9 /* RACSignal+Operations.m */; }; + D03765D919EDA41200A782A9 /* RACSignal+Operations.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764A219EDA41200A782A9 /* RACSignal+Operations.m */; }; + D03765DA19EDA41200A782A9 /* RACSignalProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D03764A319EDA41200A782A9 /* RACSignalProvider.d */; }; + D03765DB19EDA41200A782A9 /* RACSignalProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = D03764A319EDA41200A782A9 /* RACSignalProvider.d */; }; + D03765DE19EDA41200A782A9 /* RACSignalSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764A519EDA41200A782A9 /* RACSignalSequence.m */; }; + D03765DF19EDA41200A782A9 /* RACSignalSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764A519EDA41200A782A9 /* RACSignalSequence.m */; }; + D03765E019EDA41200A782A9 /* RACStream.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764A619EDA41200A782A9 /* RACStream.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765E119EDA41200A782A9 /* RACStream.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764A619EDA41200A782A9 /* RACStream.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765E219EDA41200A782A9 /* RACStream.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764A719EDA41200A782A9 /* RACStream.m */; }; + D03765E319EDA41200A782A9 /* RACStream.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764A719EDA41200A782A9 /* RACStream.m */; }; + D03765E819EDA41200A782A9 /* RACStringSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764AA19EDA41200A782A9 /* RACStringSequence.m */; }; + D03765E919EDA41200A782A9 /* RACStringSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764AA19EDA41200A782A9 /* RACStringSequence.m */; }; + D03765EA19EDA41200A782A9 /* RACSubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764AB19EDA41200A782A9 /* RACSubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765EB19EDA41200A782A9 /* RACSubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764AB19EDA41200A782A9 /* RACSubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765EC19EDA41200A782A9 /* RACSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764AC19EDA41200A782A9 /* RACSubject.m */; }; + D03765ED19EDA41200A782A9 /* RACSubject.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764AC19EDA41200A782A9 /* RACSubject.m */; }; + D03765EE19EDA41200A782A9 /* RACSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764AD19EDA41200A782A9 /* RACSubscriber.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765EF19EDA41200A782A9 /* RACSubscriber.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764AD19EDA41200A782A9 /* RACSubscriber.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765F019EDA41200A782A9 /* RACSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764AE19EDA41200A782A9 /* RACSubscriber.m */; }; + D03765F119EDA41200A782A9 /* RACSubscriber.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764AE19EDA41200A782A9 /* RACSubscriber.m */; }; + D03765F419EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764B019EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765F519EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764B019EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765F619EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B119EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.m */; }; + D03765F719EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B119EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.m */; }; + D03765FA19EDA41200A782A9 /* RACSubscriptionScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B319EDA41200A782A9 /* RACSubscriptionScheduler.m */; }; + D03765FB19EDA41200A782A9 /* RACSubscriptionScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B319EDA41200A782A9 /* RACSubscriptionScheduler.m */; }; + D03765FC19EDA41200A782A9 /* RACTargetQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764B419EDA41200A782A9 /* RACTargetQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765FD19EDA41200A782A9 /* RACTargetQueueScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764B419EDA41200A782A9 /* RACTargetQueueScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03765FE19EDA41200A782A9 /* RACTargetQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B519EDA41200A782A9 /* RACTargetQueueScheduler.m */; }; + D03765FF19EDA41200A782A9 /* RACTargetQueueScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B519EDA41200A782A9 /* RACTargetQueueScheduler.m */; }; + D037660019EDA41200A782A9 /* RACTestScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764B619EDA41200A782A9 /* RACTestScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037660119EDA41200A782A9 /* RACTestScheduler.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764B619EDA41200A782A9 /* RACTestScheduler.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037660219EDA41200A782A9 /* RACTestScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B719EDA41200A782A9 /* RACTestScheduler.m */; }; + D037660319EDA41200A782A9 /* RACTestScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B719EDA41200A782A9 /* RACTestScheduler.m */; }; + D037660419EDA41200A782A9 /* RACTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764B819EDA41200A782A9 /* RACTuple.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037660519EDA41200A782A9 /* RACTuple.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764B819EDA41200A782A9 /* RACTuple.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037660619EDA41200A782A9 /* RACTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B919EDA41200A782A9 /* RACTuple.m */; }; + D037660719EDA41200A782A9 /* RACTuple.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764B919EDA41200A782A9 /* RACTuple.m */; }; + D037660A19EDA41200A782A9 /* RACTupleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764BB19EDA41200A782A9 /* RACTupleSequence.m */; }; + D037660B19EDA41200A782A9 /* RACTupleSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764BB19EDA41200A782A9 /* RACTupleSequence.m */; }; + D037660E19EDA41200A782A9 /* RACUnarySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764BD19EDA41200A782A9 /* RACUnarySequence.m */; }; + D037660F19EDA41200A782A9 /* RACUnarySequence.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764BD19EDA41200A782A9 /* RACUnarySequence.m */; }; + D037661019EDA41200A782A9 /* RACUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764BE19EDA41200A782A9 /* RACUnit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037661119EDA41200A782A9 /* RACUnit.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764BE19EDA41200A782A9 /* RACUnit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037661219EDA41200A782A9 /* RACUnit.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764BF19EDA41200A782A9 /* RACUnit.m */; }; + D037661319EDA41200A782A9 /* RACUnit.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764BF19EDA41200A782A9 /* RACUnit.m */; }; + D037661619EDA41200A782A9 /* RACValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764C119EDA41200A782A9 /* RACValueTransformer.m */; }; + D037661719EDA41200A782A9 /* RACValueTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764C119EDA41200A782A9 /* RACValueTransformer.m */; }; + D037661919EDA41200A782A9 /* UIActionSheet+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764C219EDA41200A782A9 /* UIActionSheet+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037661B19EDA41200A782A9 /* UIActionSheet+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764C319EDA41200A782A9 /* UIActionSheet+RACSignalSupport.m */; }; + D037661D19EDA41200A782A9 /* UIAlertView+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764C419EDA41200A782A9 /* UIAlertView+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037661F19EDA41200A782A9 /* UIAlertView+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764C519EDA41200A782A9 /* UIAlertView+RACSignalSupport.m */; }; + D037662119EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764C619EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037662319EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764C719EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.m */; }; + D037662519EDA41200A782A9 /* UIButton+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764C819EDA41200A782A9 /* UIButton+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037662719EDA41200A782A9 /* UIButton+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764C919EDA41200A782A9 /* UIButton+RACCommandSupport.m */; }; + D037662919EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764CA19EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037662B19EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764CB19EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.m */; }; + D037662D19EDA41200A782A9 /* UIControl+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764CC19EDA41200A782A9 /* UIControl+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037662F19EDA41200A782A9 /* UIControl+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764CD19EDA41200A782A9 /* UIControl+RACSignalSupport.m */; }; + D037663319EDA41200A782A9 /* UIControl+RACSignalSupportPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764CF19EDA41200A782A9 /* UIControl+RACSignalSupportPrivate.m */; }; + D037663519EDA41200A782A9 /* UIDatePicker+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764D019EDA41200A782A9 /* UIDatePicker+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037663719EDA41200A782A9 /* UIDatePicker+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764D119EDA41200A782A9 /* UIDatePicker+RACSignalSupport.m */; }; + D037663919EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764D219EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037663B19EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764D319EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.m */; }; + D037663D19EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764D419EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037663F19EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764D519EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.m */; }; + D037664119EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764D619EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037664319EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764D719EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.m */; }; + D037664519EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764D819EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037664719EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764D919EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.m */; }; + D037664919EDA41200A782A9 /* UISlider+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764DA19EDA41200A782A9 /* UISlider+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037664B19EDA41200A782A9 /* UISlider+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764DB19EDA41200A782A9 /* UISlider+RACSignalSupport.m */; }; + D037664D19EDA41200A782A9 /* UIStepper+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764DC19EDA41200A782A9 /* UIStepper+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037664F19EDA41200A782A9 /* UIStepper+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764DD19EDA41200A782A9 /* UIStepper+RACSignalSupport.m */; }; + D037665119EDA41200A782A9 /* UISwitch+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764DE19EDA41200A782A9 /* UISwitch+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037665319EDA41200A782A9 /* UISwitch+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764DF19EDA41200A782A9 /* UISwitch+RACSignalSupport.m */; }; + D037665519EDA41200A782A9 /* UITableViewCell+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764E019EDA41200A782A9 /* UITableViewCell+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037665719EDA41200A782A9 /* UITableViewCell+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764E119EDA41200A782A9 /* UITableViewCell+RACSignalSupport.m */; }; + D037665919EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764E219EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037665B19EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764E319EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.m */; }; + D037665D19EDA41200A782A9 /* UITextField+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764E419EDA41200A782A9 /* UITextField+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037665F19EDA41200A782A9 /* UITextField+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764E519EDA41200A782A9 /* UITextField+RACSignalSupport.m */; }; + D037666119EDA41200A782A9 /* UITextView+RACSignalSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = D03764E619EDA41200A782A9 /* UITextView+RACSignalSupport.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037666319EDA41200A782A9 /* UITextView+RACSignalSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = D03764E719EDA41200A782A9 /* UITextView+RACSignalSupport.m */; }; + D037666419EDA43C00A782A9 /* ReactiveCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = D04725EF19E49ED7006002AA /* ReactiveCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037666B19EDA57100A782A9 /* EXTKeyPathCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = D037666619EDA57100A782A9 /* EXTKeyPathCoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037666C19EDA57100A782A9 /* EXTKeyPathCoding.h in Headers */ = {isa = PBXBuildFile; fileRef = D037666619EDA57100A782A9 /* EXTKeyPathCoding.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037666F19EDA57100A782A9 /* EXTRuntimeExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037666819EDA57100A782A9 /* EXTRuntimeExtensions.m */; }; + D037667019EDA57100A782A9 /* EXTRuntimeExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = D037666819EDA57100A782A9 /* EXTRuntimeExtensions.m */; }; + D037667119EDA57100A782A9 /* EXTScope.h in Headers */ = {isa = PBXBuildFile; fileRef = D037666919EDA57100A782A9 /* EXTScope.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037667219EDA57100A782A9 /* EXTScope.h in Headers */ = {isa = PBXBuildFile; fileRef = D037666919EDA57100A782A9 /* EXTScope.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037667319EDA57100A782A9 /* metamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = D037666A19EDA57100A782A9 /* metamacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037667419EDA57100A782A9 /* metamacros.h in Headers */ = {isa = PBXBuildFile; fileRef = D037666A19EDA57100A782A9 /* metamacros.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D03766B919EDA60000A782A9 /* NSControllerRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667619EDA60000A782A9 /* NSControllerRACSupportSpec.m */; }; + D03766BD19EDA60000A782A9 /* NSEnumeratorRACSequenceAdditionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667819EDA60000A782A9 /* NSEnumeratorRACSequenceAdditionsSpec.m */; }; + D03766BE19EDA60000A782A9 /* NSEnumeratorRACSequenceAdditionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667819EDA60000A782A9 /* NSEnumeratorRACSequenceAdditionsSpec.m */; }; + D03766BF19EDA60000A782A9 /* NSNotificationCenterRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667919EDA60000A782A9 /* NSNotificationCenterRACSupportSpec.m */; }; + D03766C019EDA60000A782A9 /* NSNotificationCenterRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667919EDA60000A782A9 /* NSNotificationCenterRACSupportSpec.m */; }; + D03766C119EDA60000A782A9 /* NSObjectRACAppKitBindingsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667A19EDA60000A782A9 /* NSObjectRACAppKitBindingsSpec.m */; }; + D03766C319EDA60000A782A9 /* NSObjectRACDeallocatingSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667B19EDA60000A782A9 /* NSObjectRACDeallocatingSpec.m */; }; + D03766C419EDA60000A782A9 /* NSObjectRACDeallocatingSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667B19EDA60000A782A9 /* NSObjectRACDeallocatingSpec.m */; }; + D03766C519EDA60000A782A9 /* NSObjectRACLiftingSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667C19EDA60000A782A9 /* NSObjectRACLiftingSpec.m */; }; + D03766C619EDA60000A782A9 /* NSObjectRACLiftingSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667C19EDA60000A782A9 /* NSObjectRACLiftingSpec.m */; }; + D03766C719EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667E19EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.m */; }; + D03766C819EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667E19EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.m */; }; + D03766C919EDA60000A782A9 /* NSObjectRACPropertySubscribingSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667F19EDA60000A782A9 /* NSObjectRACPropertySubscribingSpec.m */; }; + D03766CA19EDA60000A782A9 /* NSObjectRACPropertySubscribingSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037667F19EDA60000A782A9 /* NSObjectRACPropertySubscribingSpec.m */; }; + D03766CB19EDA60000A782A9 /* NSObjectRACSelectorSignalSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668019EDA60000A782A9 /* NSObjectRACSelectorSignalSpec.m */; }; + D03766CC19EDA60000A782A9 /* NSObjectRACSelectorSignalSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668019EDA60000A782A9 /* NSObjectRACSelectorSignalSpec.m */; }; + D03766CD19EDA60000A782A9 /* NSStringRACKeyPathUtilitiesSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668119EDA60000A782A9 /* NSStringRACKeyPathUtilitiesSpec.m */; }; + D03766CE19EDA60000A782A9 /* NSStringRACKeyPathUtilitiesSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668119EDA60000A782A9 /* NSStringRACKeyPathUtilitiesSpec.m */; }; + D03766D119EDA60000A782A9 /* NSURLConnectionRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668319EDA60000A782A9 /* NSURLConnectionRACSupportSpec.m */; }; + D03766D219EDA60000A782A9 /* NSURLConnectionRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668319EDA60000A782A9 /* NSURLConnectionRACSupportSpec.m */; }; + D03766D319EDA60000A782A9 /* NSUserDefaultsRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668419EDA60000A782A9 /* NSUserDefaultsRACSupportSpec.m */; }; + D03766D419EDA60000A782A9 /* NSUserDefaultsRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668419EDA60000A782A9 /* NSUserDefaultsRACSupportSpec.m */; }; + D03766D519EDA60000A782A9 /* RACBacktraceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668519EDA60000A782A9 /* RACBacktraceSpec.m */; }; + D03766D619EDA60000A782A9 /* RACBacktraceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668519EDA60000A782A9 /* RACBacktraceSpec.m */; }; + D03766D719EDA60000A782A9 /* RACBlockTrampolineSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668619EDA60000A782A9 /* RACBlockTrampolineSpec.m */; }; + D03766D819EDA60000A782A9 /* RACBlockTrampolineSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668619EDA60000A782A9 /* RACBlockTrampolineSpec.m */; }; + D03766D919EDA60000A782A9 /* RACChannelExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668819EDA60000A782A9 /* RACChannelExamples.m */; }; + D03766DA19EDA60000A782A9 /* RACChannelExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668819EDA60000A782A9 /* RACChannelExamples.m */; }; + D03766DB19EDA60000A782A9 /* RACChannelSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668919EDA60000A782A9 /* RACChannelSpec.m */; }; + D03766DC19EDA60000A782A9 /* RACChannelSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668919EDA60000A782A9 /* RACChannelSpec.m */; }; + D03766DD19EDA60000A782A9 /* RACCommandSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668A19EDA60000A782A9 /* RACCommandSpec.m */; }; + D03766DE19EDA60000A782A9 /* RACCommandSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668A19EDA60000A782A9 /* RACCommandSpec.m */; }; + D03766DF19EDA60000A782A9 /* RACCompoundDisposableSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668B19EDA60000A782A9 /* RACCompoundDisposableSpec.m */; }; + D03766E019EDA60000A782A9 /* RACCompoundDisposableSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668B19EDA60000A782A9 /* RACCompoundDisposableSpec.m */; }; + D03766E119EDA60000A782A9 /* RACControlCommandExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668D19EDA60000A782A9 /* RACControlCommandExamples.m */; }; + D03766E219EDA60000A782A9 /* RACControlCommandExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668D19EDA60000A782A9 /* RACControlCommandExamples.m */; }; + D03766E319EDA60000A782A9 /* RACDelegateProxySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668E19EDA60000A782A9 /* RACDelegateProxySpec.m */; }; + D03766E419EDA60000A782A9 /* RACDelegateProxySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668E19EDA60000A782A9 /* RACDelegateProxySpec.m */; }; + D03766E519EDA60000A782A9 /* RACDisposableSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668F19EDA60000A782A9 /* RACDisposableSpec.m */; }; + D03766E619EDA60000A782A9 /* RACDisposableSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037668F19EDA60000A782A9 /* RACDisposableSpec.m */; }; + D03766E719EDA60000A782A9 /* RACEventSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669019EDA60000A782A9 /* RACEventSpec.m */; }; + D03766E819EDA60000A782A9 /* RACEventSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669019EDA60000A782A9 /* RACEventSpec.m */; }; + D03766E919EDA60000A782A9 /* RACKVOChannelSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669119EDA60000A782A9 /* RACKVOChannelSpec.m */; }; + D03766EA19EDA60000A782A9 /* RACKVOChannelSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669119EDA60000A782A9 /* RACKVOChannelSpec.m */; }; + D03766EB19EDA60000A782A9 /* RACKVOWrapperSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669219EDA60000A782A9 /* RACKVOWrapperSpec.m */; }; + D03766EC19EDA60000A782A9 /* RACKVOWrapperSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669219EDA60000A782A9 /* RACKVOWrapperSpec.m */; }; + D03766ED19EDA60000A782A9 /* RACMulticastConnectionSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669319EDA60000A782A9 /* RACMulticastConnectionSpec.m */; }; + D03766EE19EDA60000A782A9 /* RACMulticastConnectionSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669319EDA60000A782A9 /* RACMulticastConnectionSpec.m */; }; + D03766EF19EDA60000A782A9 /* RACPropertySignalExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669519EDA60000A782A9 /* RACPropertySignalExamples.m */; }; + D03766F019EDA60000A782A9 /* RACPropertySignalExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669519EDA60000A782A9 /* RACPropertySignalExamples.m */; }; + D03766F119EDA60000A782A9 /* RACSchedulerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669619EDA60000A782A9 /* RACSchedulerSpec.m */; }; + D03766F219EDA60000A782A9 /* RACSchedulerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669619EDA60000A782A9 /* RACSchedulerSpec.m */; }; + D03766F319EDA60000A782A9 /* RACSequenceAdditionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669719EDA60000A782A9 /* RACSequenceAdditionsSpec.m */; }; + D03766F419EDA60000A782A9 /* RACSequenceAdditionsSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669719EDA60000A782A9 /* RACSequenceAdditionsSpec.m */; }; + D03766F519EDA60000A782A9 /* RACSequenceExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669919EDA60000A782A9 /* RACSequenceExamples.m */; }; + D03766F619EDA60000A782A9 /* RACSequenceExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669919EDA60000A782A9 /* RACSequenceExamples.m */; }; + D03766F719EDA60000A782A9 /* RACSequenceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669A19EDA60000A782A9 /* RACSequenceSpec.m */; }; + D03766F819EDA60000A782A9 /* RACSequenceSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669A19EDA60000A782A9 /* RACSequenceSpec.m */; }; + D03766F919EDA60000A782A9 /* RACSerialDisposableSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669B19EDA60000A782A9 /* RACSerialDisposableSpec.m */; }; + D03766FA19EDA60000A782A9 /* RACSerialDisposableSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669B19EDA60000A782A9 /* RACSerialDisposableSpec.m */; }; + D03766FB19EDA60000A782A9 /* RACSignalSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669C19EDA60000A782A9 /* RACSignalSpec.m */; }; + D03766FC19EDA60000A782A9 /* RACSignalSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D037669C19EDA60000A782A9 /* RACSignalSpec.m */; }; + D03766FF19EDA60000A782A9 /* RACStreamExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A019EDA60000A782A9 /* RACStreamExamples.m */; }; + D037670019EDA60000A782A9 /* RACStreamExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A019EDA60000A782A9 /* RACStreamExamples.m */; }; + D037670119EDA60000A782A9 /* RACSubclassObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A219EDA60000A782A9 /* RACSubclassObject.m */; }; + D037670219EDA60000A782A9 /* RACSubclassObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A219EDA60000A782A9 /* RACSubclassObject.m */; }; + D037670319EDA60000A782A9 /* RACSubjectSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A319EDA60000A782A9 /* RACSubjectSpec.m */; }; + D037670419EDA60000A782A9 /* RACSubjectSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A319EDA60000A782A9 /* RACSubjectSpec.m */; }; + D037670519EDA60000A782A9 /* RACSubscriberExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A519EDA60000A782A9 /* RACSubscriberExamples.m */; }; + D037670619EDA60000A782A9 /* RACSubscriberExamples.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A519EDA60000A782A9 /* RACSubscriberExamples.m */; }; + D037670719EDA60000A782A9 /* RACSubscriberSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A619EDA60000A782A9 /* RACSubscriberSpec.m */; }; + D037670819EDA60000A782A9 /* RACSubscriberSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A619EDA60000A782A9 /* RACSubscriberSpec.m */; }; + D037670919EDA60000A782A9 /* RACSubscriptingAssignmentTrampolineSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A719EDA60000A782A9 /* RACSubscriptingAssignmentTrampolineSpec.m */; }; + D037670A19EDA60000A782A9 /* RACSubscriptingAssignmentTrampolineSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A719EDA60000A782A9 /* RACSubscriptingAssignmentTrampolineSpec.m */; }; + D037670B19EDA60000A782A9 /* RACTargetQueueSchedulerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A819EDA60000A782A9 /* RACTargetQueueSchedulerSpec.m */; }; + D037670C19EDA60000A782A9 /* RACTargetQueueSchedulerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766A819EDA60000A782A9 /* RACTargetQueueSchedulerSpec.m */; }; + D037670D19EDA60000A782A9 /* RACTestExampleScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766AA19EDA60000A782A9 /* RACTestExampleScheduler.m */; }; + D037670E19EDA60000A782A9 /* RACTestExampleScheduler.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766AA19EDA60000A782A9 /* RACTestExampleScheduler.m */; }; + D037670F19EDA60000A782A9 /* RACTestObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766AC19EDA60000A782A9 /* RACTestObject.m */; }; + D037671019EDA60000A782A9 /* RACTestObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766AC19EDA60000A782A9 /* RACTestObject.m */; }; + D037671119EDA60000A782A9 /* RACTestSchedulerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766AD19EDA60000A782A9 /* RACTestSchedulerSpec.m */; }; + D037671219EDA60000A782A9 /* RACTestSchedulerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766AD19EDA60000A782A9 /* RACTestSchedulerSpec.m */; }; + D037671419EDA60000A782A9 /* RACTestUIButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766AF19EDA60000A782A9 /* RACTestUIButton.m */; }; + D037671519EDA60000A782A9 /* RACTupleSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766B019EDA60000A782A9 /* RACTupleSpec.m */; }; + D037671619EDA60000A782A9 /* RACTupleSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766B019EDA60000A782A9 /* RACTupleSpec.m */; }; + D037671719EDA60000A782A9 /* test-data.json in Resources */ = {isa = PBXBuildFile; fileRef = D03766B119EDA60000A782A9 /* test-data.json */; }; + D037671819EDA60000A782A9 /* test-data.json in Resources */ = {isa = PBXBuildFile; fileRef = D03766B119EDA60000A782A9 /* test-data.json */; }; + D037671A19EDA60000A782A9 /* UIActionSheetRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766B219EDA60000A782A9 /* UIActionSheetRACSupportSpec.m */; }; + D037671C19EDA60000A782A9 /* UIAlertViewRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766B319EDA60000A782A9 /* UIAlertViewRACSupportSpec.m */; }; + D037671E19EDA60000A782A9 /* UIBarButtonItemRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766B419EDA60000A782A9 /* UIBarButtonItemRACSupportSpec.m */; }; + D037672019EDA60000A782A9 /* UIButtonRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766B519EDA60000A782A9 /* UIButtonRACSupportSpec.m */; }; + D037672419EDA60000A782A9 /* UIImagePickerControllerRACSupportSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = D03766B719EDA60000A782A9 /* UIImagePickerControllerRACSupportSpec.m */; }; + D037672719EDA63400A782A9 /* RACBehaviorSubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646019EDA41200A782A9 /* RACBehaviorSubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037672819EDA63500A782A9 /* RACBehaviorSubject.h in Headers */ = {isa = PBXBuildFile; fileRef = D037646019EDA41200A782A9 /* RACBehaviorSubject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D037672D19EDA75D00A782A9 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D037672B19EDA75D00A782A9 /* Quick.framework */; }; + D037672F19EDA78B00A782A9 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D037672B19EDA75D00A782A9 /* Quick.framework */; }; + D037673919EDCA0E00A782A9 /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D037673819EDCA0E00A782A9 /* SwiftSpec.swift */; }; + D037673A19EDCA0E00A782A9 /* SwiftSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D037673819EDCA0E00A782A9 /* SwiftSpec.swift */; }; + D04725F019E49ED7006002AA /* ReactiveCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = D04725EF19E49ED7006002AA /* ReactiveCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D04725F619E49ED7006002AA /* ReactiveCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D04725EA19E49ED7006002AA /* ReactiveCocoa.framework */; }; + D047261719E49F82006002AA /* ReactiveCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D047260C19E49F82006002AA /* ReactiveCocoa.framework */; }; + D05E662519EDD82000904ACA /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D05E662419EDD82000904ACA /* Nimble.framework */; }; + D05E662619EDD83000904ACA /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D05E662419EDD82000904ACA /* Nimble.framework */; }; + D0C312CB19EF2A5800984962 /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BA19EF2A5800984962 /* Action.swift */; }; + D0C312CC19EF2A5800984962 /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BA19EF2A5800984962 /* Action.swift */; }; + D0C312CD19EF2A5800984962 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BB19EF2A5800984962 /* Atomic.swift */; }; + D0C312CE19EF2A5800984962 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BB19EF2A5800984962 /* Atomic.swift */; }; + D0C312CF19EF2A5800984962 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BC19EF2A5800984962 /* Bag.swift */; }; + D0C312D019EF2A5800984962 /* Bag.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BC19EF2A5800984962 /* Bag.swift */; }; + D0C312D119EF2A5800984962 /* Consumer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BD19EF2A5800984962 /* Consumer.swift */; }; + D0C312D219EF2A5800984962 /* Consumer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BD19EF2A5800984962 /* Consumer.swift */; }; + D0C312D319EF2A5800984962 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BE19EF2A5800984962 /* Disposable.swift */; }; + D0C312D419EF2A5800984962 /* Disposable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BE19EF2A5800984962 /* Disposable.swift */; }; + D0C312D519EF2A5800984962 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BF19EF2A5800984962 /* Errors.swift */; }; + D0C312D619EF2A5800984962 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312BF19EF2A5800984962 /* Errors.swift */; }; + D0C312D719EF2A5800984962 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C019EF2A5800984962 /* Event.swift */; }; + D0C312D819EF2A5800984962 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C019EF2A5800984962 /* Event.swift */; }; + D0C312D919EF2A5800984962 /* Identity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C119EF2A5800984962 /* Identity.swift */; }; + D0C312DA19EF2A5800984962 /* Identity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C119EF2A5800984962 /* Identity.swift */; }; + D0C312DB19EF2A5800984962 /* NSNotificationCenterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C219EF2A5800984962 /* NSNotificationCenterExtensions.swift */; }; + D0C312DC19EF2A5800984962 /* NSNotificationCenterExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C219EF2A5800984962 /* NSNotificationCenterExtensions.swift */; }; + D0C312DD19EF2A5800984962 /* NSURLSessionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C319EF2A5800984962 /* NSURLSessionExtensions.swift */; }; + D0C312DE19EF2A5800984962 /* NSURLSessionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C319EF2A5800984962 /* NSURLSessionExtensions.swift */; }; + D0C312DF19EF2A5800984962 /* ObjectiveCBridging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C419EF2A5800984962 /* ObjectiveCBridging.swift */; }; + D0C312E019EF2A5800984962 /* ObjectiveCBridging.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C419EF2A5800984962 /* ObjectiveCBridging.swift */; }; + D0C312E119EF2A5800984962 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C519EF2A5800984962 /* OptionalExtensions.swift */; }; + D0C312E219EF2A5800984962 /* OptionalExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C519EF2A5800984962 /* OptionalExtensions.swift */; }; + D0C312E319EF2A5800984962 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C619EF2A5800984962 /* Producer.swift */; }; + D0C312E419EF2A5800984962 /* Producer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C619EF2A5800984962 /* Producer.swift */; }; + D0C312E519EF2A5800984962 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C719EF2A5800984962 /* Promise.swift */; }; + D0C312E619EF2A5800984962 /* Promise.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C719EF2A5800984962 /* Promise.swift */; }; + D0C312E719EF2A5800984962 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C819EF2A5800984962 /* Scheduler.swift */; }; + D0C312E819EF2A5800984962 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C819EF2A5800984962 /* Scheduler.swift */; }; + D0C312E919EF2A5800984962 /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C919EF2A5800984962 /* Signal.swift */; }; + D0C312EA19EF2A5800984962 /* Signal.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312C919EF2A5800984962 /* Signal.swift */; }; + D0C312EB19EF2A5800984962 /* SignalingProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312CA19EF2A5800984962 /* SignalingProperty.swift */; }; + D0C312EC19EF2A5800984962 /* SignalingProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312CA19EF2A5800984962 /* SignalingProperty.swift */; }; + D0C3130619EF2ACC00984962 /* LlamaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C3130519EF2ACC00984962 /* LlamaKit.framework */; }; + D0C3130819EF2AD900984962 /* LlamaKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0C3130719EF2AD900984962 /* LlamaKit.framework */; }; + D0C3130C19EF2B1F00984962 /* DisposableSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312F019EF2A7700984962 /* DisposableSpec.swift */; }; + D0C3130D19EF2B1F00984962 /* ObjectiveCBridgingSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312F119EF2A7700984962 /* ObjectiveCBridgingSpec.swift */; }; + D0C3130E19EF2B1F00984962 /* SchedulerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312F219EF2A7700984962 /* SchedulerSpec.swift */; }; + D0C3130F19EF2B1F00984962 /* SignalSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312F319EF2A7700984962 /* SignalSpec.swift */; }; + D0C3131219EF2B2000984962 /* DisposableSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312F019EF2A7700984962 /* DisposableSpec.swift */; }; + D0C3131319EF2B2000984962 /* ObjectiveCBridgingSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312F119EF2A7700984962 /* ObjectiveCBridgingSpec.swift */; }; + D0C3131419EF2B2000984962 /* SchedulerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312F219EF2A7700984962 /* SchedulerSpec.swift */; }; + D0C3131519EF2B2000984962 /* SignalSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0C312F319EF2A7700984962 /* SignalSpec.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - D047968019666BF30066B267 /* PBXContainerItemProxy */ = { + D04725F719E49ED7006002AA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; + containerPortal = D04725E119E49ED7006002AA /* Project object */; proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; + remoteGlobalIDString = D04725E919E49ED7006002AA; remoteInfo = ReactiveCocoa; }; - D047968F19666CA70066B267 /* PBXContainerItemProxy */ = { + D047261819E49F82006002AA /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; + containerPortal = D04725E119E49ED7006002AA /* Project object */; proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D047969119666CA70066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D047969319666CAD0066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04796A619666CBF0066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796B319666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796B519666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796B719666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796B919666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796BB19666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796BD19666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796BF19666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796C119666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; + remoteGlobalIDString = D047260B19E49F82006002AA; remoteInfo = ReactiveCocoa; }; - D04796C319666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796C519666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796C719666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796C919666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796CB19666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796CD19666CC00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = ReactiveCocoa; - }; - D04796CF19666CCB0066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = "ReactiveCocoa-iOS"; - }; - D04796D119666CD00066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04796D319666CD20066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04796ED19666D6C0066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04796EF19666DB60066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = "ReactiveCocoa-iOS"; - }; - D04796F719666F1D0066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04796F919666F1F0066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = "ReactiveCocoa-iOS"; - }; - D04799A119667AF80066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04799A319667CAD0066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04799A519667E580066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04799A719667E5D0066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = "ReactiveCocoa-iOS"; - }; - D04799A919667E620066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047967219666BF30066B267; - remoteInfo = "ReactiveCocoa-Mac"; - }; - D04799AB19667E740066B267 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D047966A19666BF30066B267 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D047969919666CBF0066B267; - remoteInfo = "ReactiveCocoa-iOS"; - }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + D01B7B6119EDD8F600D26E01 /* Copy Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + D01B7B6219EDD8FE00D26E01 /* Nimble.framework in Copy Frameworks */, + D01B7B6319EDD8FE00D26E01 /* Quick.framework in Copy Frameworks */, + D01B7B6419EDD94B00D26E01 /* ReactiveCocoa.framework in Copy Frameworks */, + ); + name = "Copy Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ - D011F1F219DD13F600A6F6C8 /* SignalSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalSpec.swift; sourceTree = ""; }; - D0297D3519D67D42009986A9 /* Identity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Identity.swift; sourceTree = ""; }; - D0297D3B19D67EF5009986A9 /* LlamaKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LlamaKit.framework; path = "../External/LlamaKit/build/Debug-iphoneos/LlamaKit.framework"; sourceTree = ""; }; - D0297D3D19D67F01009986A9 /* LlamaKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LlamaKit.framework; path = ../External/LlamaKit/build/Debug/LlamaKit.framework; sourceTree = ""; }; - D02C14B0197243CB007127D4 /* OptionalExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensions.swift; sourceTree = ""; }; - D036AA4A196FB7CB00B49B76 /* Bag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bag.swift; sourceTree = ""; }; - D047967319666BF30066B267 /* ReactiveCocoa.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactiveCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D047967719666BF30066B267 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D047967819666BF30066B267 /* ReactiveCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReactiveCocoa.h; sourceTree = ""; }; - D047967E19666BF30066B267 /* ReactiveCocoa-MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ReactiveCocoa-MacTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - D047968419666BF30066B267 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D047969A19666CBF0066B267 /* ReactiveCocoa.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactiveCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D04796A419666CBF0066B267 /* ReactiveCocoa-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ReactiveCocoa-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - D04796D719666CE40066B267 /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; - D04796D919666CE40066B267 /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - D04796DA19666CE40066B267 /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = ""; }; - D04796DB19666CE40066B267 /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - D04796DC19666CE40066B267 /* Test.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Test.xcconfig; sourceTree = ""; }; - D04796DE19666CE40066B267 /* Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Application.xcconfig; sourceTree = ""; }; - D04796DF19666CE40066B267 /* Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Framework.xcconfig; sourceTree = ""; }; - D04796E019666CE40066B267 /* StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = StaticLibrary.xcconfig; sourceTree = ""; }; - D04796E219666CE40066B267 /* iOS-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Application.xcconfig"; sourceTree = ""; }; - D04796E319666CE40066B267 /* iOS-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Base.xcconfig"; sourceTree = ""; }; - D04796E419666CE40066B267 /* iOS-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Framework.xcconfig"; sourceTree = ""; }; - D04796E519666CE40066B267 /* iOS-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-StaticLibrary.xcconfig"; sourceTree = ""; }; - D04796E719666CE40066B267 /* Mac-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Application.xcconfig"; sourceTree = ""; }; - D04796E819666CE40066B267 /* Mac-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Base.xcconfig"; sourceTree = ""; }; - D04796E919666CE40066B267 /* Mac-DynamicLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-DynamicLibrary.xcconfig"; sourceTree = ""; }; - D04796EA19666CE40066B267 /* Mac-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Framework.xcconfig"; sourceTree = ""; }; - D04796EB19666CE40066B267 /* Mac-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-StaticLibrary.xcconfig"; sourceTree = ""; }; - D04796EC19666CE40066B267 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - D0479709196670900066B267 /* Action.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = ""; }; - D047970B196670900066B267 /* Atomic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = ""; }; - D047970E196670900066B267 /* Consumer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Consumer.swift; sourceTree = ""; }; - D047970F196670900066B267 /* Disposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Disposable.swift; sourceTree = ""; }; - D0479710196670900066B267 /* Event.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = ""; }; - D0479712196670900066B267 /* NSArray+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+RACSequenceAdditions.h"; sourceTree = ""; }; - D0479713196670900066B267 /* NSArray+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+RACSequenceAdditions.m"; sourceTree = ""; }; - D0479714196670900066B267 /* NSControl+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSControl+RACCommandSupport.h"; sourceTree = ""; }; - D0479715196670900066B267 /* NSControl+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSControl+RACCommandSupport.m"; sourceTree = ""; }; - D0479716196670900066B267 /* NSControl+RACTextSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSControl+RACTextSignalSupport.h"; sourceTree = ""; }; - D0479717196670900066B267 /* NSControl+RACTextSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSControl+RACTextSignalSupport.m"; sourceTree = ""; }; - D0479718196670900066B267 /* NSData+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+RACSupport.h"; sourceTree = ""; }; - D0479719196670900066B267 /* NSData+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+RACSupport.m"; sourceTree = ""; }; - D047971A196670900066B267 /* NSDictionary+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+RACSequenceAdditions.h"; sourceTree = ""; }; - D047971B196670900066B267 /* NSDictionary+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+RACSequenceAdditions.m"; sourceTree = ""; }; - D047971C196670900066B267 /* NSEnumerator+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEnumerator+RACSequenceAdditions.h"; sourceTree = ""; }; - D047971D196670900066B267 /* NSEnumerator+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEnumerator+RACSequenceAdditions.m"; sourceTree = ""; }; - D047971E196670900066B267 /* NSFileHandle+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileHandle+RACSupport.h"; sourceTree = ""; }; - D047971F196670900066B267 /* NSFileHandle+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileHandle+RACSupport.m"; sourceTree = ""; }; - D0479720196670900066B267 /* NSIndexSet+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+RACSequenceAdditions.h"; sourceTree = ""; }; - D0479721196670900066B267 /* NSIndexSet+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexSet+RACSequenceAdditions.m"; sourceTree = ""; }; - D0479722196670900066B267 /* NSInvocation+RACTypeParsing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSInvocation+RACTypeParsing.h"; sourceTree = ""; }; - D0479723196670900066B267 /* NSInvocation+RACTypeParsing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSInvocation+RACTypeParsing.m"; sourceTree = ""; }; - D0479725196670900066B267 /* NSNotificationCenter+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+RACSupport.h"; sourceTree = ""; }; - D0479726196670900066B267 /* NSNotificationCenter+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNotificationCenter+RACSupport.m"; sourceTree = ""; }; - D0479727196670900066B267 /* NSNotificationCenterExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSNotificationCenterExtensions.swift; sourceTree = ""; }; - D0479728196670900066B267 /* NSObject+RACAppKitBindings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACAppKitBindings.h"; sourceTree = ""; }; - D0479729196670900066B267 /* NSObject+RACAppKitBindings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACAppKitBindings.m"; sourceTree = ""; }; - D047972A196670900066B267 /* NSObject+RACDeallocating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACDeallocating.h"; sourceTree = ""; }; - D047972B196670900066B267 /* NSObject+RACDeallocating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACDeallocating.m"; sourceTree = ""; }; - D047972C196670900066B267 /* NSObject+RACDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACDescription.h"; sourceTree = ""; }; - D047972D196670900066B267 /* NSObject+RACDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACDescription.m"; sourceTree = ""; }; - D047972E196670900066B267 /* NSObject+RACKVOWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACKVOWrapper.h"; sourceTree = ""; }; - D047972F196670900066B267 /* NSObject+RACKVOWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACKVOWrapper.m"; sourceTree = ""; }; - D0479730196670900066B267 /* NSObject+RACLifting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACLifting.h"; sourceTree = ""; }; - D0479731196670900066B267 /* NSObject+RACLifting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACLifting.m"; sourceTree = ""; }; - D0479732196670900066B267 /* NSObject+RACPropertySubscribing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACPropertySubscribing.h"; sourceTree = ""; }; - D0479733196670900066B267 /* NSObject+RACPropertySubscribing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACPropertySubscribing.m"; sourceTree = ""; }; - D0479734196670900066B267 /* NSObject+RACSelectorSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACSelectorSignal.h"; sourceTree = ""; }; - D0479735196670900066B267 /* NSObject+RACSelectorSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACSelectorSignal.m"; sourceTree = ""; }; - D0479736196670900066B267 /* NSOrderedSet+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSOrderedSet+RACSequenceAdditions.h"; sourceTree = ""; }; - D0479737196670900066B267 /* NSOrderedSet+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSOrderedSet+RACSequenceAdditions.m"; sourceTree = ""; }; - D0479738196670900066B267 /* NSSet+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSSet+RACSequenceAdditions.h"; sourceTree = ""; }; - D0479739196670900066B267 /* NSSet+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSSet+RACSequenceAdditions.m"; sourceTree = ""; }; - D047973A196670900066B267 /* NSString+RACKeyPathUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RACKeyPathUtilities.h"; sourceTree = ""; }; - D047973B196670900066B267 /* NSString+RACKeyPathUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RACKeyPathUtilities.m"; sourceTree = ""; }; - D047973C196670900066B267 /* NSString+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RACSequenceAdditions.h"; sourceTree = ""; }; - D047973D196670900066B267 /* NSString+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RACSequenceAdditions.m"; sourceTree = ""; }; - D047973E196670900066B267 /* NSString+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RACSupport.h"; sourceTree = ""; }; - D047973F196670900066B267 /* NSString+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RACSupport.m"; sourceTree = ""; }; - D0479740196670900066B267 /* NSText+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSText+RACSignalSupport.h"; sourceTree = ""; }; - D0479741196670900066B267 /* NSText+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSText+RACSignalSupport.m"; sourceTree = ""; }; - D0479742196670900066B267 /* NSURLConnection+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLConnection+RACSupport.h"; sourceTree = ""; }; - D0479743196670900066B267 /* NSURLConnection+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLConnection+RACSupport.m"; sourceTree = ""; }; - D0479744196670900066B267 /* NSURLSessionExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSURLSessionExtensions.swift; sourceTree = ""; }; - D0479745196670900066B267 /* NSUserDefaults+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSUserDefaults+RACSupport.h"; sourceTree = ""; }; - D0479746196670900066B267 /* NSUserDefaults+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSUserDefaults+RACSupport.m"; sourceTree = ""; }; - D0479747196670900066B267 /* ObjectiveCBridging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectiveCBridging.swift; sourceTree = ""; }; - D0479748196670900066B267 /* Producer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Producer.swift; sourceTree = ""; }; - D0479749196670900066B267 /* Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = ""; }; - D047974A196670900066B267 /* RACArraySequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACArraySequence.h; sourceTree = ""; }; - D047974B196670900066B267 /* RACArraySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACArraySequence.m; sourceTree = ""; }; - D047974C196670900066B267 /* RACBacktrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACBacktrace.h; sourceTree = ""; }; - D047974D196670900066B267 /* RACBacktrace.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACBacktrace.m; sourceTree = ""; }; - D047974E196670900066B267 /* RACBehaviorSubject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACBehaviorSubject.h; sourceTree = ""; }; - D047974F196670900066B267 /* RACBehaviorSubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACBehaviorSubject.m; sourceTree = ""; }; - D0479750196670900066B267 /* RACBlockTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACBlockTrampoline.h; sourceTree = ""; }; - D0479751196670900066B267 /* RACBlockTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACBlockTrampoline.m; sourceTree = ""; }; - D0479752196670900066B267 /* RACChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACChannel.h; sourceTree = ""; }; - D0479753196670900066B267 /* RACChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACChannel.m; sourceTree = ""; }; - D0479754196670900066B267 /* RACCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACCommand.h; sourceTree = ""; }; - D0479755196670900066B267 /* RACCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACCommand.m; sourceTree = ""; }; - D0479756196670900066B267 /* RACCompoundDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACCompoundDisposable.h; sourceTree = ""; }; - D0479757196670900066B267 /* RACCompoundDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACCompoundDisposable.m; sourceTree = ""; }; - D0479758196670900066B267 /* RACCompoundDisposableProvider.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = RACCompoundDisposableProvider.d; sourceTree = ""; }; - D0479759196670900066B267 /* RACDelegateProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACDelegateProxy.h; sourceTree = ""; }; - D047975A196670900066B267 /* RACDelegateProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDelegateProxy.m; sourceTree = ""; }; - D047975B196670900066B267 /* RACDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACDisposable.h; sourceTree = ""; }; - D047975C196670900066B267 /* RACDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDisposable.m; sourceTree = ""; }; - D047975D196670900066B267 /* RACDynamicSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACDynamicSequence.h; sourceTree = ""; }; - D047975E196670900066B267 /* RACDynamicSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDynamicSequence.m; sourceTree = ""; }; - D047975F196670900066B267 /* RACDynamicSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACDynamicSignal.h; sourceTree = ""; }; - D0479760196670900066B267 /* RACDynamicSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDynamicSignal.m; sourceTree = ""; }; - D0479761196670900066B267 /* RACEagerSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACEagerSequence.h; sourceTree = ""; }; - D0479762196670900066B267 /* RACEagerSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEagerSequence.m; sourceTree = ""; }; - D0479763196670900066B267 /* RACEmptySequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACEmptySequence.h; sourceTree = ""; }; - D0479764196670900066B267 /* RACEmptySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEmptySequence.m; sourceTree = ""; }; - D0479765196670900066B267 /* RACEmptySignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACEmptySignal.h; sourceTree = ""; }; - D0479766196670900066B267 /* RACEmptySignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEmptySignal.m; sourceTree = ""; }; - D0479767196670900066B267 /* RACErrorSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACErrorSignal.h; sourceTree = ""; }; - D0479768196670900066B267 /* RACErrorSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACErrorSignal.m; sourceTree = ""; }; - D0479769196670900066B267 /* RACEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACEvent.h; sourceTree = ""; }; - D047976A196670900066B267 /* RACEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEvent.m; sourceTree = ""; }; - D047976B196670900066B267 /* RACGroupedSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACGroupedSignal.h; sourceTree = ""; }; - D047976C196670900066B267 /* RACGroupedSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACGroupedSignal.m; sourceTree = ""; }; - D047976D196670900066B267 /* RACImmediateScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACImmediateScheduler.h; sourceTree = ""; }; - D047976E196670900066B267 /* RACImmediateScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACImmediateScheduler.m; sourceTree = ""; }; - D047976F196670900066B267 /* RACIndexSetSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACIndexSetSequence.h; sourceTree = ""; }; - D0479770196670900066B267 /* RACIndexSetSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACIndexSetSequence.m; sourceTree = ""; }; - D0479771196670900066B267 /* RACKVOChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACKVOChannel.h; sourceTree = ""; }; - D0479772196670900066B267 /* RACKVOChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACKVOChannel.m; sourceTree = ""; }; - D0479773196670900066B267 /* RACKVOTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACKVOTrampoline.h; sourceTree = ""; }; - D0479774196670900066B267 /* RACKVOTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACKVOTrampoline.m; sourceTree = ""; }; - D0479775196670900066B267 /* RACMulticastConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACMulticastConnection.h; sourceTree = ""; }; - D0479776196670900066B267 /* RACMulticastConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACMulticastConnection.m; sourceTree = ""; }; - D0479777196670900066B267 /* RACMulticastConnection+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACMulticastConnection+Private.h"; sourceTree = ""; }; - D0479778196670900066B267 /* RACObjCRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACObjCRuntime.h; sourceTree = ""; }; - D0479779196670900066B267 /* RACObjCRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACObjCRuntime.m; sourceTree = ""; }; - D047977A196670900066B267 /* RACPassthroughSubscriber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACPassthroughSubscriber.h; sourceTree = ""; }; - D047977B196670900066B267 /* RACPassthroughSubscriber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACPassthroughSubscriber.m; sourceTree = ""; }; - D047977C196670900066B267 /* RACQueueScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACQueueScheduler.h; sourceTree = ""; }; - D047977D196670900066B267 /* RACQueueScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACQueueScheduler.m; sourceTree = ""; }; - D047977E196670900066B267 /* RACQueueScheduler+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACQueueScheduler+Subclass.h"; sourceTree = ""; }; - D047977F196670900066B267 /* RACReplaySubject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACReplaySubject.h; sourceTree = ""; }; - D0479780196670900066B267 /* RACReplaySubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACReplaySubject.m; sourceTree = ""; }; - D0479781196670900066B267 /* RACReturnSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACReturnSignal.h; sourceTree = ""; }; - D0479782196670900066B267 /* RACReturnSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACReturnSignal.m; sourceTree = ""; }; - D0479783196670900066B267 /* RACScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACScheduler.h; sourceTree = ""; }; - D0479784196670900066B267 /* RACScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACScheduler.m; sourceTree = ""; }; - D0479785196670900066B267 /* RACScheduler+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACScheduler+Private.h"; sourceTree = ""; }; - D0479786196670900066B267 /* RACScheduler+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACScheduler+Subclass.h"; sourceTree = ""; }; - D0479787196670900066B267 /* RACScopedDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACScopedDisposable.h; sourceTree = ""; }; - D0479788196670900066B267 /* RACScopedDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACScopedDisposable.m; sourceTree = ""; }; - D0479789196670900066B267 /* RACSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSequence.h; sourceTree = ""; }; - D047978A196670900066B267 /* RACSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSequence.m; sourceTree = ""; }; - D047978B196670900066B267 /* RACSerialDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSerialDisposable.h; sourceTree = ""; }; - D047978C196670900066B267 /* RACSerialDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSerialDisposable.m; sourceTree = ""; }; - D047978D196670900066B267 /* RACSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSignal.h; sourceTree = ""; }; - D047978E196670900066B267 /* RACSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSignal.m; sourceTree = ""; }; - D047978F196670900066B267 /* RACSignal+Operations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACSignal+Operations.h"; sourceTree = ""; }; - D0479790196670900066B267 /* RACSignal+Operations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RACSignal+Operations.m"; sourceTree = ""; }; - D0479791196670900066B267 /* RACSignalProvider.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = RACSignalProvider.d; sourceTree = ""; }; - D0479792196670900066B267 /* RACSignalSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSignalSequence.h; sourceTree = ""; }; - D0479793196670900066B267 /* RACSignalSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSignalSequence.m; sourceTree = ""; }; - D0479794196670900066B267 /* RACStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACStream.h; sourceTree = ""; }; - D0479795196670900066B267 /* RACStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACStream.m; sourceTree = ""; }; - D0479796196670900066B267 /* RACStream+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACStream+Private.h"; sourceTree = ""; }; - D0479797196670900066B267 /* RACStringSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACStringSequence.h; sourceTree = ""; }; - D0479798196670900066B267 /* RACStringSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACStringSequence.m; sourceTree = ""; }; - D0479799196670900066B267 /* RACSubject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubject.h; sourceTree = ""; }; - D047979A196670900066B267 /* RACSubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubject.m; sourceTree = ""; }; - D047979B196670900066B267 /* RACSubscriber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubscriber.h; sourceTree = ""; }; - D047979C196670900066B267 /* RACSubscriber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriber.m; sourceTree = ""; }; - D047979D196670900066B267 /* RACSubscriber+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACSubscriber+Private.h"; sourceTree = ""; }; - D047979E196670900066B267 /* RACSubscriptingAssignmentTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubscriptingAssignmentTrampoline.h; sourceTree = ""; }; - D047979F196670900066B267 /* RACSubscriptingAssignmentTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriptingAssignmentTrampoline.m; sourceTree = ""; }; - D04797A0196670900066B267 /* RACSubscriptionScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubscriptionScheduler.h; sourceTree = ""; }; - D04797A1196670900066B267 /* RACSubscriptionScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriptionScheduler.m; sourceTree = ""; }; - D04797A2196670900066B267 /* RACTargetQueueScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTargetQueueScheduler.h; sourceTree = ""; }; - D04797A3196670900066B267 /* RACTargetQueueScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTargetQueueScheduler.m; sourceTree = ""; }; - D04797A4196670900066B267 /* RACTestScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTestScheduler.h; sourceTree = ""; }; - D04797A5196670900066B267 /* RACTestScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTestScheduler.m; sourceTree = ""; }; - D04797A6196670900066B267 /* RACTuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTuple.h; sourceTree = ""; }; - D04797A7196670900066B267 /* RACTuple.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTuple.m; sourceTree = ""; }; - D04797A8196670900066B267 /* RACTupleSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTupleSequence.h; sourceTree = ""; }; - D04797A9196670900066B267 /* RACTupleSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTupleSequence.m; sourceTree = ""; }; - D04797AA196670900066B267 /* RACUnarySequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACUnarySequence.h; sourceTree = ""; }; - D04797AB196670900066B267 /* RACUnarySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACUnarySequence.m; sourceTree = ""; }; - D04797AC196670900066B267 /* RACUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACUnit.h; sourceTree = ""; }; - D04797AD196670900066B267 /* RACUnit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACUnit.m; sourceTree = ""; }; - D04797AE196670900066B267 /* RACValueTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACValueTransformer.h; sourceTree = ""; }; - D04797AF196670900066B267 /* RACValueTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACValueTransformer.m; sourceTree = ""; }; - D04797B0196670900066B267 /* ReactiveCocoa-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ReactiveCocoa-Bridging-Header.h"; sourceTree = ""; }; - D04797B3196670900066B267 /* Scheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scheduler.swift; sourceTree = ""; }; - D04797B4196670900066B267 /* Signal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal.swift; sourceTree = ""; }; - D04797B5196670900066B267 /* SignalingProperty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalingProperty.swift; sourceTree = ""; }; - D04797B7196670900066B267 /* UIActionSheet+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIActionSheet+RACSignalSupport.h"; sourceTree = ""; }; - D04797B8196670900066B267 /* UIActionSheet+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIActionSheet+RACSignalSupport.m"; sourceTree = ""; }; - D04797B9196670900066B267 /* UIAlertView+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+RACSignalSupport.h"; sourceTree = ""; }; - D04797BA196670900066B267 /* UIAlertView+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+RACSignalSupport.m"; sourceTree = ""; }; - D04797BB196670900066B267 /* UIBarButtonItem+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+RACCommandSupport.h"; sourceTree = ""; }; - D04797BC196670900066B267 /* UIBarButtonItem+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+RACCommandSupport.m"; sourceTree = ""; }; - D04797BD196670900066B267 /* UIButton+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+RACCommandSupport.h"; sourceTree = ""; }; - D04797BE196670900066B267 /* UIButton+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+RACCommandSupport.m"; sourceTree = ""; }; - D04797BF196670900066B267 /* UICollectionReusableView+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionReusableView+RACSignalSupport.h"; sourceTree = ""; }; - D04797C0196670900066B267 /* UICollectionReusableView+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionReusableView+RACSignalSupport.m"; sourceTree = ""; }; - D04797C1196670900066B267 /* UIControl+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIControl+RACSignalSupport.h"; sourceTree = ""; }; - D04797C2196670900066B267 /* UIControl+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIControl+RACSignalSupport.m"; sourceTree = ""; }; - D04797C3196670900066B267 /* UIControl+RACSignalSupportPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIControl+RACSignalSupportPrivate.h"; sourceTree = ""; }; - D04797C4196670900066B267 /* UIControl+RACSignalSupportPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIControl+RACSignalSupportPrivate.m"; sourceTree = ""; }; - D04797C5196670900066B267 /* UIDatePicker+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIDatePicker+RACSignalSupport.h"; sourceTree = ""; }; - D04797C6196670900066B267 /* UIDatePicker+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIDatePicker+RACSignalSupport.m"; sourceTree = ""; }; - D04797C7196670900066B267 /* UIGestureRecognizer+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIGestureRecognizer+RACSignalSupport.h"; sourceTree = ""; }; - D04797C8196670900066B267 /* UIGestureRecognizer+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIGestureRecognizer+RACSignalSupport.m"; sourceTree = ""; }; - D04797C9196670900066B267 /* UIImagePickerController+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImagePickerController+RACSignalSupport.h"; sourceTree = ""; }; - D04797CA196670900066B267 /* UIImagePickerController+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImagePickerController+RACSignalSupport.m"; sourceTree = ""; }; - D04797CB196670900066B267 /* UIRefreshControl+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIRefreshControl+RACCommandSupport.h"; sourceTree = ""; }; - D04797CC196670900066B267 /* UIRefreshControl+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIRefreshControl+RACCommandSupport.m"; sourceTree = ""; }; - D04797CD196670900066B267 /* UISegmentedControl+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UISegmentedControl+RACSignalSupport.h"; sourceTree = ""; }; - D04797CE196670900066B267 /* UISegmentedControl+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UISegmentedControl+RACSignalSupport.m"; sourceTree = ""; }; - D04797CF196670900066B267 /* UISlider+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UISlider+RACSignalSupport.h"; sourceTree = ""; }; - D04797D0196670900066B267 /* UISlider+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UISlider+RACSignalSupport.m"; sourceTree = ""; }; - D04797D1196670900066B267 /* UIStepper+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIStepper+RACSignalSupport.h"; sourceTree = ""; }; - D04797D2196670900066B267 /* UIStepper+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIStepper+RACSignalSupport.m"; sourceTree = ""; }; - D04797D3196670900066B267 /* UISwitch+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UISwitch+RACSignalSupport.h"; sourceTree = ""; }; - D04797D4196670900066B267 /* UISwitch+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UISwitch+RACSignalSupport.m"; sourceTree = ""; }; - D04797D5196670900066B267 /* UITableViewCell+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableViewCell+RACSignalSupport.h"; sourceTree = ""; }; - D04797D6196670900066B267 /* UITableViewCell+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableViewCell+RACSignalSupport.m"; sourceTree = ""; }; - D04797D7196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableViewHeaderFooterView+RACSignalSupport.h"; sourceTree = ""; }; - D04797D8196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableViewHeaderFooterView+RACSignalSupport.m"; sourceTree = ""; }; - D04797D9196670900066B267 /* UITextField+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+RACSignalSupport.h"; sourceTree = ""; }; - D04797DA196670900066B267 /* UITextField+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+RACSignalSupport.m"; sourceTree = ""; }; - D04797DB196670900066B267 /* UITextView+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextView+RACSignalSupport.h"; sourceTree = ""; }; - D04797DC196670900066B267 /* UITextView+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextView+RACSignalSupport.m"; sourceTree = ""; }; - D0479986196671DF0066B267 /* EXTKeyPathCoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTKeyPathCoding.h; sourceTree = ""; }; - D0479987196671DF0066B267 /* EXTRuntimeExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTRuntimeExtensions.h; sourceTree = ""; }; - D0479988196671DF0066B267 /* EXTRuntimeExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EXTRuntimeExtensions.m; sourceTree = ""; }; - D0479989196671DF0066B267 /* EXTScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTScope.h; sourceTree = ""; }; - D047998A196671DF0066B267 /* metamacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = metamacros.h; sourceTree = ""; }; - D0479995196673730066B267 /* ReactiveCocoa-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ReactiveCocoa-Prefix.pch"; sourceTree = ""; }; - D047999E196678F20066B267 /* ObjectiveCBridgingSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectiveCBridgingSpec.swift; sourceTree = ""; }; - D095745719733F74002D44C1 /* AtomicSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicSpec.swift; sourceTree = ""; }; - D095745A197341C2002D44C1 /* BagSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BagSpec.swift; sourceTree = ""; }; - D095745D197344E3002D44C1 /* DisposableSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisposableSpec.swift; sourceTree = ""; }; - D09574601973506C002D44C1 /* SchedulerSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchedulerSpec.swift; sourceTree = ""; }; - D09C6CBB198F4931008E129B /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Quick.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - D0AFFF1919CF2EF70078D030 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = ../External/Quick/Externals/Nimble/build/Debug/Nimble.framework; sourceTree = ""; }; - D0AFFF1B19CF2EFC0078D030 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = "../External/Quick/Externals/Nimble/build/Debug-iphoneos/Nimble.framework"; sourceTree = ""; }; - D0E3CF541973AFC7004FD181 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; + D037642A19EDA41200A782A9 /* NSArray+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+RACSequenceAdditions.h"; sourceTree = ""; }; + D037642B19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+RACSequenceAdditions.m"; sourceTree = ""; }; + D037642C19EDA41200A782A9 /* NSControl+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSControl+RACCommandSupport.h"; sourceTree = ""; }; + D037642D19EDA41200A782A9 /* NSControl+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSControl+RACCommandSupport.m"; sourceTree = ""; }; + D037642E19EDA41200A782A9 /* NSControl+RACTextSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSControl+RACTextSignalSupport.h"; sourceTree = ""; }; + D037642F19EDA41200A782A9 /* NSControl+RACTextSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSControl+RACTextSignalSupport.m"; sourceTree = ""; }; + D037643019EDA41200A782A9 /* NSData+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+RACSupport.h"; sourceTree = ""; }; + D037643119EDA41200A782A9 /* NSData+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSData+RACSupport.m"; sourceTree = ""; }; + D037643219EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+RACSequenceAdditions.h"; sourceTree = ""; }; + D037643319EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+RACSequenceAdditions.m"; sourceTree = ""; }; + D037643419EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEnumerator+RACSequenceAdditions.h"; sourceTree = ""; }; + D037643519EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEnumerator+RACSequenceAdditions.m"; sourceTree = ""; }; + D037643619EDA41200A782A9 /* NSFileHandle+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileHandle+RACSupport.h"; sourceTree = ""; }; + D037643719EDA41200A782A9 /* NSFileHandle+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileHandle+RACSupport.m"; sourceTree = ""; }; + D037643819EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSIndexSet+RACSequenceAdditions.h"; sourceTree = ""; }; + D037643919EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSIndexSet+RACSequenceAdditions.m"; sourceTree = ""; }; + D037643A19EDA41200A782A9 /* NSInvocation+RACTypeParsing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSInvocation+RACTypeParsing.h"; sourceTree = ""; }; + D037643B19EDA41200A782A9 /* NSInvocation+RACTypeParsing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSInvocation+RACTypeParsing.m"; sourceTree = ""; }; + D037643C19EDA41200A782A9 /* NSNotificationCenter+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+RACSupport.h"; sourceTree = ""; }; + D037643D19EDA41200A782A9 /* NSNotificationCenter+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNotificationCenter+RACSupport.m"; sourceTree = ""; }; + D037643E19EDA41200A782A9 /* NSObject+RACAppKitBindings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACAppKitBindings.h"; sourceTree = ""; }; + D037643F19EDA41200A782A9 /* NSObject+RACAppKitBindings.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACAppKitBindings.m"; sourceTree = ""; }; + D037644019EDA41200A782A9 /* NSObject+RACDeallocating.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACDeallocating.h"; sourceTree = ""; }; + D037644119EDA41200A782A9 /* NSObject+RACDeallocating.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACDeallocating.m"; sourceTree = ""; }; + D037644219EDA41200A782A9 /* NSObject+RACDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACDescription.h"; sourceTree = ""; }; + D037644319EDA41200A782A9 /* NSObject+RACDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACDescription.m"; sourceTree = ""; }; + D037644419EDA41200A782A9 /* NSObject+RACKVOWrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACKVOWrapper.h"; sourceTree = ""; }; + D037644519EDA41200A782A9 /* NSObject+RACKVOWrapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACKVOWrapper.m"; sourceTree = ""; }; + D037644619EDA41200A782A9 /* NSObject+RACLifting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACLifting.h"; sourceTree = ""; }; + D037644719EDA41200A782A9 /* NSObject+RACLifting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACLifting.m"; sourceTree = ""; }; + D037644819EDA41200A782A9 /* NSObject+RACPropertySubscribing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACPropertySubscribing.h"; sourceTree = ""; }; + D037644919EDA41200A782A9 /* NSObject+RACPropertySubscribing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACPropertySubscribing.m"; sourceTree = ""; }; + D037644A19EDA41200A782A9 /* NSObject+RACSelectorSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+RACSelectorSignal.h"; sourceTree = ""; }; + D037644B19EDA41200A782A9 /* NSObject+RACSelectorSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+RACSelectorSignal.m"; sourceTree = ""; }; + D037644C19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSOrderedSet+RACSequenceAdditions.h"; sourceTree = ""; }; + D037644D19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSOrderedSet+RACSequenceAdditions.m"; sourceTree = ""; }; + D037644E19EDA41200A782A9 /* NSSet+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSSet+RACSequenceAdditions.h"; sourceTree = ""; }; + D037644F19EDA41200A782A9 /* NSSet+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSSet+RACSequenceAdditions.m"; sourceTree = ""; }; + D037645019EDA41200A782A9 /* NSString+RACKeyPathUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RACKeyPathUtilities.h"; sourceTree = ""; }; + D037645119EDA41200A782A9 /* NSString+RACKeyPathUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RACKeyPathUtilities.m"; sourceTree = ""; }; + D037645219EDA41200A782A9 /* NSString+RACSequenceAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RACSequenceAdditions.h"; sourceTree = ""; }; + D037645319EDA41200A782A9 /* NSString+RACSequenceAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RACSequenceAdditions.m"; sourceTree = ""; }; + D037645419EDA41200A782A9 /* NSString+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+RACSupport.h"; sourceTree = ""; }; + D037645519EDA41200A782A9 /* NSString+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+RACSupport.m"; sourceTree = ""; }; + D037645619EDA41200A782A9 /* NSText+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSText+RACSignalSupport.h"; sourceTree = ""; }; + D037645719EDA41200A782A9 /* NSText+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSText+RACSignalSupport.m"; sourceTree = ""; }; + D037645819EDA41200A782A9 /* NSURLConnection+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLConnection+RACSupport.h"; sourceTree = ""; }; + D037645919EDA41200A782A9 /* NSURLConnection+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLConnection+RACSupport.m"; sourceTree = ""; }; + D037645A19EDA41200A782A9 /* NSUserDefaults+RACSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSUserDefaults+RACSupport.h"; sourceTree = ""; }; + D037645B19EDA41200A782A9 /* NSUserDefaults+RACSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSUserDefaults+RACSupport.m"; sourceTree = ""; }; + D037645C19EDA41200A782A9 /* RACArraySequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACArraySequence.h; sourceTree = ""; }; + D037645D19EDA41200A782A9 /* RACArraySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACArraySequence.m; sourceTree = ""; }; + D037645E19EDA41200A782A9 /* RACBacktrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACBacktrace.h; sourceTree = ""; }; + D037645F19EDA41200A782A9 /* RACBacktrace.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACBacktrace.m; sourceTree = ""; }; + D037646019EDA41200A782A9 /* RACBehaviorSubject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACBehaviorSubject.h; sourceTree = ""; }; + D037646119EDA41200A782A9 /* RACBehaviorSubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACBehaviorSubject.m; sourceTree = ""; }; + D037646219EDA41200A782A9 /* RACBlockTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACBlockTrampoline.h; sourceTree = ""; }; + D037646319EDA41200A782A9 /* RACBlockTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACBlockTrampoline.m; sourceTree = ""; }; + D037646419EDA41200A782A9 /* RACChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACChannel.h; sourceTree = ""; }; + D037646519EDA41200A782A9 /* RACChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACChannel.m; sourceTree = ""; }; + D037646619EDA41200A782A9 /* RACCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACCommand.h; sourceTree = ""; }; + D037646719EDA41200A782A9 /* RACCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACCommand.m; sourceTree = ""; }; + D037646819EDA41200A782A9 /* RACCompoundDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACCompoundDisposable.h; sourceTree = ""; }; + D037646919EDA41200A782A9 /* RACCompoundDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACCompoundDisposable.m; sourceTree = ""; }; + D037646A19EDA41200A782A9 /* RACCompoundDisposableProvider.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = RACCompoundDisposableProvider.d; sourceTree = ""; }; + D037646B19EDA41200A782A9 /* RACDelegateProxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACDelegateProxy.h; sourceTree = ""; }; + D037646C19EDA41200A782A9 /* RACDelegateProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDelegateProxy.m; sourceTree = ""; }; + D037646D19EDA41200A782A9 /* RACDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACDisposable.h; sourceTree = ""; }; + D037646E19EDA41200A782A9 /* RACDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDisposable.m; sourceTree = ""; }; + D037646F19EDA41200A782A9 /* RACDynamicSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACDynamicSequence.h; sourceTree = ""; }; + D037647019EDA41200A782A9 /* RACDynamicSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDynamicSequence.m; sourceTree = ""; }; + D037647119EDA41200A782A9 /* RACDynamicSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACDynamicSignal.h; sourceTree = ""; }; + D037647219EDA41200A782A9 /* RACDynamicSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDynamicSignal.m; sourceTree = ""; }; + D037647319EDA41200A782A9 /* RACEagerSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACEagerSequence.h; sourceTree = ""; }; + D037647419EDA41200A782A9 /* RACEagerSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEagerSequence.m; sourceTree = ""; }; + D037647519EDA41200A782A9 /* RACEmptySequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACEmptySequence.h; sourceTree = ""; }; + D037647619EDA41200A782A9 /* RACEmptySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEmptySequence.m; sourceTree = ""; }; + D037647719EDA41200A782A9 /* RACEmptySignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACEmptySignal.h; sourceTree = ""; }; + D037647819EDA41200A782A9 /* RACEmptySignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEmptySignal.m; sourceTree = ""; }; + D037647919EDA41200A782A9 /* RACErrorSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACErrorSignal.h; sourceTree = ""; }; + D037647A19EDA41200A782A9 /* RACErrorSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACErrorSignal.m; sourceTree = ""; }; + D037647B19EDA41200A782A9 /* RACEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACEvent.h; sourceTree = ""; }; + D037647C19EDA41200A782A9 /* RACEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEvent.m; sourceTree = ""; }; + D037647D19EDA41200A782A9 /* RACGroupedSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACGroupedSignal.h; sourceTree = ""; }; + D037647E19EDA41200A782A9 /* RACGroupedSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACGroupedSignal.m; sourceTree = ""; }; + D037647F19EDA41200A782A9 /* RACImmediateScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACImmediateScheduler.h; sourceTree = ""; }; + D037648019EDA41200A782A9 /* RACImmediateScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACImmediateScheduler.m; sourceTree = ""; }; + D037648119EDA41200A782A9 /* RACIndexSetSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACIndexSetSequence.h; sourceTree = ""; }; + D037648219EDA41200A782A9 /* RACIndexSetSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACIndexSetSequence.m; sourceTree = ""; }; + D037648319EDA41200A782A9 /* RACKVOChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACKVOChannel.h; sourceTree = ""; }; + D037648419EDA41200A782A9 /* RACKVOChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACKVOChannel.m; sourceTree = ""; }; + D037648519EDA41200A782A9 /* RACKVOTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACKVOTrampoline.h; sourceTree = ""; }; + D037648619EDA41200A782A9 /* RACKVOTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACKVOTrampoline.m; sourceTree = ""; }; + D037648719EDA41200A782A9 /* RACMulticastConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACMulticastConnection.h; sourceTree = ""; }; + D037648819EDA41200A782A9 /* RACMulticastConnection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACMulticastConnection.m; sourceTree = ""; }; + D037648919EDA41200A782A9 /* RACMulticastConnection+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACMulticastConnection+Private.h"; sourceTree = ""; }; + D037648A19EDA41200A782A9 /* RACObjCRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACObjCRuntime.h; sourceTree = ""; }; + D037648B19EDA41200A782A9 /* RACObjCRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACObjCRuntime.m; sourceTree = ""; }; + D037648C19EDA41200A782A9 /* RACPassthroughSubscriber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACPassthroughSubscriber.h; sourceTree = ""; }; + D037648D19EDA41200A782A9 /* RACPassthroughSubscriber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACPassthroughSubscriber.m; sourceTree = ""; }; + D037648E19EDA41200A782A9 /* RACQueueScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACQueueScheduler.h; sourceTree = ""; }; + D037648F19EDA41200A782A9 /* RACQueueScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACQueueScheduler.m; sourceTree = ""; }; + D037649019EDA41200A782A9 /* RACQueueScheduler+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACQueueScheduler+Subclass.h"; sourceTree = ""; }; + D037649119EDA41200A782A9 /* RACReplaySubject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACReplaySubject.h; sourceTree = ""; }; + D037649219EDA41200A782A9 /* RACReplaySubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACReplaySubject.m; sourceTree = ""; }; + D037649319EDA41200A782A9 /* RACReturnSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACReturnSignal.h; sourceTree = ""; }; + D037649419EDA41200A782A9 /* RACReturnSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACReturnSignal.m; sourceTree = ""; }; + D037649519EDA41200A782A9 /* RACScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACScheduler.h; sourceTree = ""; }; + D037649619EDA41200A782A9 /* RACScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACScheduler.m; sourceTree = ""; }; + D037649719EDA41200A782A9 /* RACScheduler+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACScheduler+Private.h"; sourceTree = ""; }; + D037649819EDA41200A782A9 /* RACScheduler+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACScheduler+Subclass.h"; sourceTree = ""; }; + D037649919EDA41200A782A9 /* RACScopedDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACScopedDisposable.h; sourceTree = ""; }; + D037649A19EDA41200A782A9 /* RACScopedDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACScopedDisposable.m; sourceTree = ""; }; + D037649B19EDA41200A782A9 /* RACSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSequence.h; sourceTree = ""; }; + D037649C19EDA41200A782A9 /* RACSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSequence.m; sourceTree = ""; }; + D037649D19EDA41200A782A9 /* RACSerialDisposable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSerialDisposable.h; sourceTree = ""; }; + D037649E19EDA41200A782A9 /* RACSerialDisposable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSerialDisposable.m; sourceTree = ""; }; + D037649F19EDA41200A782A9 /* RACSignal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSignal.h; sourceTree = ""; }; + D03764A019EDA41200A782A9 /* RACSignal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSignal.m; sourceTree = ""; }; + D03764A119EDA41200A782A9 /* RACSignal+Operations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACSignal+Operations.h"; sourceTree = ""; }; + D03764A219EDA41200A782A9 /* RACSignal+Operations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RACSignal+Operations.m"; sourceTree = ""; }; + D03764A319EDA41200A782A9 /* RACSignalProvider.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = RACSignalProvider.d; sourceTree = ""; }; + D03764A419EDA41200A782A9 /* RACSignalSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSignalSequence.h; sourceTree = ""; }; + D03764A519EDA41200A782A9 /* RACSignalSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSignalSequence.m; sourceTree = ""; }; + D03764A619EDA41200A782A9 /* RACStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACStream.h; sourceTree = ""; }; + D03764A719EDA41200A782A9 /* RACStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACStream.m; sourceTree = ""; }; + D03764A819EDA41200A782A9 /* RACStream+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACStream+Private.h"; sourceTree = ""; }; + D03764A919EDA41200A782A9 /* RACStringSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACStringSequence.h; sourceTree = ""; }; + D03764AA19EDA41200A782A9 /* RACStringSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACStringSequence.m; sourceTree = ""; }; + D03764AB19EDA41200A782A9 /* RACSubject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubject.h; sourceTree = ""; }; + D03764AC19EDA41200A782A9 /* RACSubject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubject.m; sourceTree = ""; }; + D03764AD19EDA41200A782A9 /* RACSubscriber.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubscriber.h; sourceTree = ""; }; + D03764AE19EDA41200A782A9 /* RACSubscriber.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriber.m; sourceTree = ""; }; + D03764AF19EDA41200A782A9 /* RACSubscriber+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RACSubscriber+Private.h"; sourceTree = ""; }; + D03764B019EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubscriptingAssignmentTrampoline.h; sourceTree = ""; }; + D03764B119EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriptingAssignmentTrampoline.m; sourceTree = ""; }; + D03764B219EDA41200A782A9 /* RACSubscriptionScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubscriptionScheduler.h; sourceTree = ""; }; + D03764B319EDA41200A782A9 /* RACSubscriptionScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriptionScheduler.m; sourceTree = ""; }; + D03764B419EDA41200A782A9 /* RACTargetQueueScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTargetQueueScheduler.h; sourceTree = ""; }; + D03764B519EDA41200A782A9 /* RACTargetQueueScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTargetQueueScheduler.m; sourceTree = ""; }; + D03764B619EDA41200A782A9 /* RACTestScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTestScheduler.h; sourceTree = ""; }; + D03764B719EDA41200A782A9 /* RACTestScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTestScheduler.m; sourceTree = ""; }; + D03764B819EDA41200A782A9 /* RACTuple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTuple.h; sourceTree = ""; }; + D03764B919EDA41200A782A9 /* RACTuple.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTuple.m; sourceTree = ""; }; + D03764BA19EDA41200A782A9 /* RACTupleSequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTupleSequence.h; sourceTree = ""; }; + D03764BB19EDA41200A782A9 /* RACTupleSequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTupleSequence.m; sourceTree = ""; }; + D03764BC19EDA41200A782A9 /* RACUnarySequence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACUnarySequence.h; sourceTree = ""; }; + D03764BD19EDA41200A782A9 /* RACUnarySequence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACUnarySequence.m; sourceTree = ""; }; + D03764BE19EDA41200A782A9 /* RACUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACUnit.h; sourceTree = ""; }; + D03764BF19EDA41200A782A9 /* RACUnit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACUnit.m; sourceTree = ""; }; + D03764C019EDA41200A782A9 /* RACValueTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACValueTransformer.h; sourceTree = ""; }; + D03764C119EDA41200A782A9 /* RACValueTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACValueTransformer.m; sourceTree = ""; }; + D03764C219EDA41200A782A9 /* UIActionSheet+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIActionSheet+RACSignalSupport.h"; sourceTree = ""; }; + D03764C319EDA41200A782A9 /* UIActionSheet+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIActionSheet+RACSignalSupport.m"; sourceTree = ""; }; + D03764C419EDA41200A782A9 /* UIAlertView+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+RACSignalSupport.h"; sourceTree = ""; }; + D03764C519EDA41200A782A9 /* UIAlertView+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+RACSignalSupport.m"; sourceTree = ""; }; + D03764C619EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+RACCommandSupport.h"; sourceTree = ""; }; + D03764C719EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+RACCommandSupport.m"; sourceTree = ""; }; + D03764C819EDA41200A782A9 /* UIButton+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIButton+RACCommandSupport.h"; sourceTree = ""; }; + D03764C919EDA41200A782A9 /* UIButton+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIButton+RACCommandSupport.m"; sourceTree = ""; }; + D03764CA19EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UICollectionReusableView+RACSignalSupport.h"; sourceTree = ""; }; + D03764CB19EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UICollectionReusableView+RACSignalSupport.m"; sourceTree = ""; }; + D03764CC19EDA41200A782A9 /* UIControl+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIControl+RACSignalSupport.h"; sourceTree = ""; }; + D03764CD19EDA41200A782A9 /* UIControl+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIControl+RACSignalSupport.m"; sourceTree = ""; }; + D03764CE19EDA41200A782A9 /* UIControl+RACSignalSupportPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIControl+RACSignalSupportPrivate.h"; sourceTree = ""; }; + D03764CF19EDA41200A782A9 /* UIControl+RACSignalSupportPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIControl+RACSignalSupportPrivate.m"; sourceTree = ""; }; + D03764D019EDA41200A782A9 /* UIDatePicker+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIDatePicker+RACSignalSupport.h"; sourceTree = ""; }; + D03764D119EDA41200A782A9 /* UIDatePicker+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIDatePicker+RACSignalSupport.m"; sourceTree = ""; }; + D03764D219EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIGestureRecognizer+RACSignalSupport.h"; sourceTree = ""; }; + D03764D319EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIGestureRecognizer+RACSignalSupport.m"; sourceTree = ""; }; + D03764D419EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImagePickerController+RACSignalSupport.h"; sourceTree = ""; }; + D03764D519EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImagePickerController+RACSignalSupport.m"; sourceTree = ""; }; + D03764D619EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIRefreshControl+RACCommandSupport.h"; sourceTree = ""; }; + D03764D719EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIRefreshControl+RACCommandSupport.m"; sourceTree = ""; }; + D03764D819EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UISegmentedControl+RACSignalSupport.h"; sourceTree = ""; }; + D03764D919EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UISegmentedControl+RACSignalSupport.m"; sourceTree = ""; }; + D03764DA19EDA41200A782A9 /* UISlider+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UISlider+RACSignalSupport.h"; sourceTree = ""; }; + D03764DB19EDA41200A782A9 /* UISlider+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UISlider+RACSignalSupport.m"; sourceTree = ""; }; + D03764DC19EDA41200A782A9 /* UIStepper+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIStepper+RACSignalSupport.h"; sourceTree = ""; }; + D03764DD19EDA41200A782A9 /* UIStepper+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIStepper+RACSignalSupport.m"; sourceTree = ""; }; + D03764DE19EDA41200A782A9 /* UISwitch+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UISwitch+RACSignalSupport.h"; sourceTree = ""; }; + D03764DF19EDA41200A782A9 /* UISwitch+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UISwitch+RACSignalSupport.m"; sourceTree = ""; }; + D03764E019EDA41200A782A9 /* UITableViewCell+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableViewCell+RACSignalSupport.h"; sourceTree = ""; }; + D03764E119EDA41200A782A9 /* UITableViewCell+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableViewCell+RACSignalSupport.m"; sourceTree = ""; }; + D03764E219EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITableViewHeaderFooterView+RACSignalSupport.h"; sourceTree = ""; }; + D03764E319EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITableViewHeaderFooterView+RACSignalSupport.m"; sourceTree = ""; }; + D03764E419EDA41200A782A9 /* UITextField+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+RACSignalSupport.h"; sourceTree = ""; }; + D03764E519EDA41200A782A9 /* UITextField+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+RACSignalSupport.m"; sourceTree = ""; }; + D03764E619EDA41200A782A9 /* UITextView+RACSignalSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextView+RACSignalSupport.h"; sourceTree = ""; }; + D03764E719EDA41200A782A9 /* UITextView+RACSignalSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextView+RACSignalSupport.m"; sourceTree = ""; }; + D037666619EDA57100A782A9 /* EXTKeyPathCoding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTKeyPathCoding.h; sourceTree = ""; }; + D037666719EDA57100A782A9 /* EXTRuntimeExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTRuntimeExtensions.h; sourceTree = ""; }; + D037666819EDA57100A782A9 /* EXTRuntimeExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EXTRuntimeExtensions.m; sourceTree = ""; }; + D037666919EDA57100A782A9 /* EXTScope.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EXTScope.h; sourceTree = ""; }; + D037666A19EDA57100A782A9 /* metamacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = metamacros.h; sourceTree = ""; }; + D037667619EDA60000A782A9 /* NSControllerRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSControllerRACSupportSpec.m; sourceTree = ""; }; + D037667819EDA60000A782A9 /* NSEnumeratorRACSequenceAdditionsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSEnumeratorRACSequenceAdditionsSpec.m; sourceTree = ""; }; + D037667919EDA60000A782A9 /* NSNotificationCenterRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSNotificationCenterRACSupportSpec.m; sourceTree = ""; }; + D037667A19EDA60000A782A9 /* NSObjectRACAppKitBindingsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObjectRACAppKitBindingsSpec.m; sourceTree = ""; }; + D037667B19EDA60000A782A9 /* NSObjectRACDeallocatingSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObjectRACDeallocatingSpec.m; sourceTree = ""; }; + D037667C19EDA60000A782A9 /* NSObjectRACLiftingSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObjectRACLiftingSpec.m; sourceTree = ""; }; + D037667D19EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSObjectRACPropertySubscribingExamples.h; sourceTree = ""; }; + D037667E19EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObjectRACPropertySubscribingExamples.m; sourceTree = ""; }; + D037667F19EDA60000A782A9 /* NSObjectRACPropertySubscribingSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObjectRACPropertySubscribingSpec.m; sourceTree = ""; }; + D037668019EDA60000A782A9 /* NSObjectRACSelectorSignalSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObjectRACSelectorSignalSpec.m; sourceTree = ""; }; + D037668119EDA60000A782A9 /* NSStringRACKeyPathUtilitiesSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSStringRACKeyPathUtilitiesSpec.m; sourceTree = ""; }; + D037668319EDA60000A782A9 /* NSURLConnectionRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSURLConnectionRACSupportSpec.m; sourceTree = ""; }; + D037668419EDA60000A782A9 /* NSUserDefaultsRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSUserDefaultsRACSupportSpec.m; sourceTree = ""; }; + D037668519EDA60000A782A9 /* RACBacktraceSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACBacktraceSpec.m; sourceTree = ""; }; + D037668619EDA60000A782A9 /* RACBlockTrampolineSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACBlockTrampolineSpec.m; sourceTree = ""; }; + D037668719EDA60000A782A9 /* RACChannelExamples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACChannelExamples.h; sourceTree = ""; }; + D037668819EDA60000A782A9 /* RACChannelExamples.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACChannelExamples.m; sourceTree = ""; }; + D037668919EDA60000A782A9 /* RACChannelSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACChannelSpec.m; sourceTree = ""; }; + D037668A19EDA60000A782A9 /* RACCommandSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACCommandSpec.m; sourceTree = ""; }; + D037668B19EDA60000A782A9 /* RACCompoundDisposableSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACCompoundDisposableSpec.m; sourceTree = ""; }; + D037668C19EDA60000A782A9 /* RACControlCommandExamples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACControlCommandExamples.h; sourceTree = ""; }; + D037668D19EDA60000A782A9 /* RACControlCommandExamples.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACControlCommandExamples.m; sourceTree = ""; }; + D037668E19EDA60000A782A9 /* RACDelegateProxySpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDelegateProxySpec.m; sourceTree = ""; }; + D037668F19EDA60000A782A9 /* RACDisposableSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACDisposableSpec.m; sourceTree = ""; }; + D037669019EDA60000A782A9 /* RACEventSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACEventSpec.m; sourceTree = ""; }; + D037669119EDA60000A782A9 /* RACKVOChannelSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACKVOChannelSpec.m; sourceTree = ""; }; + D037669219EDA60000A782A9 /* RACKVOWrapperSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACKVOWrapperSpec.m; sourceTree = ""; }; + D037669319EDA60000A782A9 /* RACMulticastConnectionSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACMulticastConnectionSpec.m; sourceTree = ""; }; + D037669419EDA60000A782A9 /* RACPropertySignalExamples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACPropertySignalExamples.h; sourceTree = ""; }; + D037669519EDA60000A782A9 /* RACPropertySignalExamples.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACPropertySignalExamples.m; sourceTree = ""; }; + D037669619EDA60000A782A9 /* RACSchedulerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSchedulerSpec.m; sourceTree = ""; }; + D037669719EDA60000A782A9 /* RACSequenceAdditionsSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSequenceAdditionsSpec.m; sourceTree = ""; }; + D037669819EDA60000A782A9 /* RACSequenceExamples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSequenceExamples.h; sourceTree = ""; }; + D037669919EDA60000A782A9 /* RACSequenceExamples.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSequenceExamples.m; sourceTree = ""; }; + D037669A19EDA60000A782A9 /* RACSequenceSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSequenceSpec.m; sourceTree = ""; }; + D037669B19EDA60000A782A9 /* RACSerialDisposableSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSerialDisposableSpec.m; sourceTree = ""; }; + D037669C19EDA60000A782A9 /* RACSignalSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSignalSpec.m; sourceTree = ""; }; + D037669F19EDA60000A782A9 /* RACStreamExamples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACStreamExamples.h; sourceTree = ""; }; + D03766A019EDA60000A782A9 /* RACStreamExamples.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACStreamExamples.m; sourceTree = ""; }; + D03766A119EDA60000A782A9 /* RACSubclassObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubclassObject.h; sourceTree = ""; }; + D03766A219EDA60000A782A9 /* RACSubclassObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubclassObject.m; sourceTree = ""; }; + D03766A319EDA60000A782A9 /* RACSubjectSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubjectSpec.m; sourceTree = ""; }; + D03766A419EDA60000A782A9 /* RACSubscriberExamples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACSubscriberExamples.h; sourceTree = ""; }; + D03766A519EDA60000A782A9 /* RACSubscriberExamples.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriberExamples.m; sourceTree = ""; }; + D03766A619EDA60000A782A9 /* RACSubscriberSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriberSpec.m; sourceTree = ""; }; + D03766A719EDA60000A782A9 /* RACSubscriptingAssignmentTrampolineSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACSubscriptingAssignmentTrampolineSpec.m; sourceTree = ""; }; + D03766A819EDA60000A782A9 /* RACTargetQueueSchedulerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTargetQueueSchedulerSpec.m; sourceTree = ""; }; + D03766A919EDA60000A782A9 /* RACTestExampleScheduler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTestExampleScheduler.h; sourceTree = ""; }; + D03766AA19EDA60000A782A9 /* RACTestExampleScheduler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTestExampleScheduler.m; sourceTree = ""; }; + D03766AB19EDA60000A782A9 /* RACTestObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTestObject.h; sourceTree = ""; }; + D03766AC19EDA60000A782A9 /* RACTestObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTestObject.m; sourceTree = ""; }; + D03766AD19EDA60000A782A9 /* RACTestSchedulerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTestSchedulerSpec.m; sourceTree = ""; }; + D03766AE19EDA60000A782A9 /* RACTestUIButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RACTestUIButton.h; sourceTree = ""; }; + D03766AF19EDA60000A782A9 /* RACTestUIButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTestUIButton.m; sourceTree = ""; }; + D03766B019EDA60000A782A9 /* RACTupleSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RACTupleSpec.m; sourceTree = ""; }; + D03766B119EDA60000A782A9 /* test-data.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = "test-data.json"; sourceTree = ""; }; + D03766B219EDA60000A782A9 /* UIActionSheetRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIActionSheetRACSupportSpec.m; sourceTree = ""; }; + D03766B319EDA60000A782A9 /* UIAlertViewRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIAlertViewRACSupportSpec.m; sourceTree = ""; }; + D03766B419EDA60000A782A9 /* UIBarButtonItemRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIBarButtonItemRACSupportSpec.m; sourceTree = ""; }; + D03766B519EDA60000A782A9 /* UIButtonRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIButtonRACSupportSpec.m; sourceTree = ""; }; + D03766B719EDA60000A782A9 /* UIImagePickerControllerRACSupportSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIImagePickerControllerRACSupportSpec.m; sourceTree = ""; }; + D037672B19EDA75D00A782A9 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Quick.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D037673819EDCA0E00A782A9 /* SwiftSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSpec.swift; sourceTree = ""; }; + D04725EA19E49ED7006002AA /* ReactiveCocoa.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactiveCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D04725EE19E49ED7006002AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D04725EF19E49ED7006002AA /* ReactiveCocoa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReactiveCocoa.h; sourceTree = ""; }; + D04725F519E49ED7006002AA /* ReactiveCocoa-MacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ReactiveCocoa-MacTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + D04725FB19E49ED7006002AA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + D047260C19E49F82006002AA /* ReactiveCocoa.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ReactiveCocoa.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D047261619E49F82006002AA /* ReactiveCocoa-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ReactiveCocoa-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + D047262719E49FE8006002AA /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; + D047262919E49FE8006002AA /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; + D047262A19E49FE8006002AA /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = ""; }; + D047262B19E49FE8006002AA /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + D047262C19E49FE8006002AA /* Test.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Test.xcconfig; sourceTree = ""; }; + D047262E19E49FE8006002AA /* Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Application.xcconfig; sourceTree = ""; }; + D047262F19E49FE8006002AA /* Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Framework.xcconfig; sourceTree = ""; }; + D047263019E49FE8006002AA /* StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = StaticLibrary.xcconfig; sourceTree = ""; }; + D047263219E49FE8006002AA /* iOS-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Application.xcconfig"; sourceTree = ""; }; + D047263319E49FE8006002AA /* iOS-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Base.xcconfig"; sourceTree = ""; }; + D047263419E49FE8006002AA /* iOS-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-Framework.xcconfig"; sourceTree = ""; }; + D047263519E49FE8006002AA /* iOS-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "iOS-StaticLibrary.xcconfig"; sourceTree = ""; }; + D047263719E49FE8006002AA /* Mac-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Application.xcconfig"; sourceTree = ""; }; + D047263819E49FE8006002AA /* Mac-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Base.xcconfig"; sourceTree = ""; }; + D047263919E49FE8006002AA /* Mac-DynamicLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-DynamicLibrary.xcconfig"; sourceTree = ""; }; + D047263A19E49FE8006002AA /* Mac-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-Framework.xcconfig"; sourceTree = ""; }; + D047263B19E49FE8006002AA /* Mac-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-StaticLibrary.xcconfig"; sourceTree = ""; }; + D047263C19E49FE8006002AA /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + D05E662419EDD82000904ACA /* Nimble.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D0C312BA19EF2A5800984962 /* Action.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = ""; }; + D0C312BB19EF2A5800984962 /* Atomic.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = ""; }; + D0C312BC19EF2A5800984962 /* Bag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Bag.swift; sourceTree = ""; }; + D0C312BD19EF2A5800984962 /* Consumer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Consumer.swift; sourceTree = ""; }; + D0C312BE19EF2A5800984962 /* Disposable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Disposable.swift; sourceTree = ""; }; + D0C312BF19EF2A5800984962 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; + D0C312C019EF2A5800984962 /* Event.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = ""; }; + D0C312C119EF2A5800984962 /* Identity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Identity.swift; sourceTree = ""; }; + D0C312C219EF2A5800984962 /* NSNotificationCenterExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSNotificationCenterExtensions.swift; sourceTree = ""; }; + D0C312C319EF2A5800984962 /* NSURLSessionExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSURLSessionExtensions.swift; sourceTree = ""; }; + D0C312C419EF2A5800984962 /* ObjectiveCBridging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectiveCBridging.swift; sourceTree = ""; }; + D0C312C519EF2A5800984962 /* OptionalExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalExtensions.swift; sourceTree = ""; }; + D0C312C619EF2A5800984962 /* Producer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Producer.swift; sourceTree = ""; }; + D0C312C719EF2A5800984962 /* Promise.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Promise.swift; sourceTree = ""; }; + D0C312C819EF2A5800984962 /* Scheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Scheduler.swift; sourceTree = ""; }; + D0C312C919EF2A5800984962 /* Signal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Signal.swift; sourceTree = ""; }; + D0C312CA19EF2A5800984962 /* SignalingProperty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalingProperty.swift; sourceTree = ""; }; + D0C312EE19EF2A7700984962 /* AtomicSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AtomicSpec.swift; sourceTree = ""; }; + D0C312EF19EF2A7700984962 /* BagSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BagSpec.swift; sourceTree = ""; }; + D0C312F019EF2A7700984962 /* DisposableSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DisposableSpec.swift; sourceTree = ""; }; + D0C312F119EF2A7700984962 /* ObjectiveCBridgingSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectiveCBridgingSpec.swift; sourceTree = ""; }; + D0C312F219EF2A7700984962 /* SchedulerSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchedulerSpec.swift; sourceTree = ""; }; + D0C312F319EF2A7700984962 /* SignalSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SignalSpec.swift; sourceTree = ""; }; + D0C312F419EF2A7700984962 /* SwiftSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftSpec.swift; sourceTree = ""; }; + D0C3130519EF2ACC00984962 /* LlamaKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LlamaKit.framework; path = "../External/LlamaKit/build/Debug-iphoneos/LlamaKit.framework"; sourceTree = ""; }; + D0C3130719EF2AD900984962 /* LlamaKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LlamaKit.framework; path = ../External/LlamaKit/build/Debug/LlamaKit.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - D047966F19666BF30066B267 /* Frameworks */ = { + D04725E619E49ED7006002AA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D0297D3E19D67F01009986A9 /* LlamaKit.framework in Frameworks */, + D0C3130819EF2AD900984962 /* LlamaKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - D047967B19666BF30066B267 /* Frameworks */ = { + D04725F219E49ED7006002AA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D0AFFF1A19CF2EF70078D030 /* Nimble.framework in Frameworks */, - D09C6CBD198F4934008E129B /* Quick.framework in Frameworks */, - D047967F19666BF30066B267 /* ReactiveCocoa.framework in Frameworks */, + D05E662519EDD82000904ACA /* Nimble.framework in Frameworks */, + D037672D19EDA75D00A782A9 /* Quick.framework in Frameworks */, + D04725F619E49ED7006002AA /* ReactiveCocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - D047969619666CBF0066B267 /* Frameworks */ = { + D047260819E49F82006002AA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D0297D3C19D67EF5009986A9 /* LlamaKit.framework in Frameworks */, + D0C3130619EF2ACC00984962 /* LlamaKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - D04796A119666CBF0066B267 /* Frameworks */ = { + D047261319E49F82006002AA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D0AFFF1C19CF2EFC0078D030 /* Nimble.framework in Frameworks */, - D09C6CBC198F4931008E129B /* Quick.framework in Frameworks */, - D04796A519666CBF0066B267 /* ReactiveCocoa.framework in Frameworks */, + D05E662619EDD83000904ACA /* Nimble.framework in Frameworks */, + D037672F19EDA78B00A782A9 /* Quick.framework in Frameworks */, + D047261719E49F82006002AA /* ReactiveCocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - D047966919666BF30066B267 = { + D037642919EDA3B600A782A9 /* Objective-C */ = { + isa = PBXGroup; + children = ( + D037642A19EDA41200A782A9 /* NSArray+RACSequenceAdditions.h */, + D037642B19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m */, + D037642C19EDA41200A782A9 /* NSControl+RACCommandSupport.h */, + D037642D19EDA41200A782A9 /* NSControl+RACCommandSupport.m */, + D037642E19EDA41200A782A9 /* NSControl+RACTextSignalSupport.h */, + D037642F19EDA41200A782A9 /* NSControl+RACTextSignalSupport.m */, + D037643019EDA41200A782A9 /* NSData+RACSupport.h */, + D037643119EDA41200A782A9 /* NSData+RACSupport.m */, + D037643219EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.h */, + D037643319EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.m */, + D037643419EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.h */, + D037643519EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m */, + D037643619EDA41200A782A9 /* NSFileHandle+RACSupport.h */, + D037643719EDA41200A782A9 /* NSFileHandle+RACSupport.m */, + D037643819EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.h */, + D037643919EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.m */, + D037643A19EDA41200A782A9 /* NSInvocation+RACTypeParsing.h */, + D037643B19EDA41200A782A9 /* NSInvocation+RACTypeParsing.m */, + D037643C19EDA41200A782A9 /* NSNotificationCenter+RACSupport.h */, + D037643D19EDA41200A782A9 /* NSNotificationCenter+RACSupport.m */, + D037643E19EDA41200A782A9 /* NSObject+RACAppKitBindings.h */, + D037643F19EDA41200A782A9 /* NSObject+RACAppKitBindings.m */, + D037644019EDA41200A782A9 /* NSObject+RACDeallocating.h */, + D037644119EDA41200A782A9 /* NSObject+RACDeallocating.m */, + D037644219EDA41200A782A9 /* NSObject+RACDescription.h */, + D037644319EDA41200A782A9 /* NSObject+RACDescription.m */, + D037644419EDA41200A782A9 /* NSObject+RACKVOWrapper.h */, + D037644519EDA41200A782A9 /* NSObject+RACKVOWrapper.m */, + D037644619EDA41200A782A9 /* NSObject+RACLifting.h */, + D037644719EDA41200A782A9 /* NSObject+RACLifting.m */, + D037644819EDA41200A782A9 /* NSObject+RACPropertySubscribing.h */, + D037644919EDA41200A782A9 /* NSObject+RACPropertySubscribing.m */, + D037644A19EDA41200A782A9 /* NSObject+RACSelectorSignal.h */, + D037644B19EDA41200A782A9 /* NSObject+RACSelectorSignal.m */, + D037644C19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.h */, + D037644D19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.m */, + D037644E19EDA41200A782A9 /* NSSet+RACSequenceAdditions.h */, + D037644F19EDA41200A782A9 /* NSSet+RACSequenceAdditions.m */, + D037645019EDA41200A782A9 /* NSString+RACKeyPathUtilities.h */, + D037645119EDA41200A782A9 /* NSString+RACKeyPathUtilities.m */, + D037645219EDA41200A782A9 /* NSString+RACSequenceAdditions.h */, + D037645319EDA41200A782A9 /* NSString+RACSequenceAdditions.m */, + D037645419EDA41200A782A9 /* NSString+RACSupport.h */, + D037645519EDA41200A782A9 /* NSString+RACSupport.m */, + D037645619EDA41200A782A9 /* NSText+RACSignalSupport.h */, + D037645719EDA41200A782A9 /* NSText+RACSignalSupport.m */, + D037645819EDA41200A782A9 /* NSURLConnection+RACSupport.h */, + D037645919EDA41200A782A9 /* NSURLConnection+RACSupport.m */, + D037645A19EDA41200A782A9 /* NSUserDefaults+RACSupport.h */, + D037645B19EDA41200A782A9 /* NSUserDefaults+RACSupport.m */, + D037645C19EDA41200A782A9 /* RACArraySequence.h */, + D037645D19EDA41200A782A9 /* RACArraySequence.m */, + D037645E19EDA41200A782A9 /* RACBacktrace.h */, + D037645F19EDA41200A782A9 /* RACBacktrace.m */, + D037646019EDA41200A782A9 /* RACBehaviorSubject.h */, + D037646119EDA41200A782A9 /* RACBehaviorSubject.m */, + D037646219EDA41200A782A9 /* RACBlockTrampoline.h */, + D037646319EDA41200A782A9 /* RACBlockTrampoline.m */, + D037646419EDA41200A782A9 /* RACChannel.h */, + D037646519EDA41200A782A9 /* RACChannel.m */, + D037646619EDA41200A782A9 /* RACCommand.h */, + D037646719EDA41200A782A9 /* RACCommand.m */, + D037646819EDA41200A782A9 /* RACCompoundDisposable.h */, + D037646919EDA41200A782A9 /* RACCompoundDisposable.m */, + D037646A19EDA41200A782A9 /* RACCompoundDisposableProvider.d */, + D037646B19EDA41200A782A9 /* RACDelegateProxy.h */, + D037646C19EDA41200A782A9 /* RACDelegateProxy.m */, + D037646D19EDA41200A782A9 /* RACDisposable.h */, + D037646E19EDA41200A782A9 /* RACDisposable.m */, + D037646F19EDA41200A782A9 /* RACDynamicSequence.h */, + D037647019EDA41200A782A9 /* RACDynamicSequence.m */, + D037647119EDA41200A782A9 /* RACDynamicSignal.h */, + D037647219EDA41200A782A9 /* RACDynamicSignal.m */, + D037647319EDA41200A782A9 /* RACEagerSequence.h */, + D037647419EDA41200A782A9 /* RACEagerSequence.m */, + D037647519EDA41200A782A9 /* RACEmptySequence.h */, + D037647619EDA41200A782A9 /* RACEmptySequence.m */, + D037647719EDA41200A782A9 /* RACEmptySignal.h */, + D037647819EDA41200A782A9 /* RACEmptySignal.m */, + D037647919EDA41200A782A9 /* RACErrorSignal.h */, + D037647A19EDA41200A782A9 /* RACErrorSignal.m */, + D037647B19EDA41200A782A9 /* RACEvent.h */, + D037647C19EDA41200A782A9 /* RACEvent.m */, + D037647D19EDA41200A782A9 /* RACGroupedSignal.h */, + D037647E19EDA41200A782A9 /* RACGroupedSignal.m */, + D037647F19EDA41200A782A9 /* RACImmediateScheduler.h */, + D037648019EDA41200A782A9 /* RACImmediateScheduler.m */, + D037648119EDA41200A782A9 /* RACIndexSetSequence.h */, + D037648219EDA41200A782A9 /* RACIndexSetSequence.m */, + D037648319EDA41200A782A9 /* RACKVOChannel.h */, + D037648419EDA41200A782A9 /* RACKVOChannel.m */, + D037648519EDA41200A782A9 /* RACKVOTrampoline.h */, + D037648619EDA41200A782A9 /* RACKVOTrampoline.m */, + D037648719EDA41200A782A9 /* RACMulticastConnection.h */, + D037648819EDA41200A782A9 /* RACMulticastConnection.m */, + D037648919EDA41200A782A9 /* RACMulticastConnection+Private.h */, + D037648A19EDA41200A782A9 /* RACObjCRuntime.h */, + D037648B19EDA41200A782A9 /* RACObjCRuntime.m */, + D037648C19EDA41200A782A9 /* RACPassthroughSubscriber.h */, + D037648D19EDA41200A782A9 /* RACPassthroughSubscriber.m */, + D037648E19EDA41200A782A9 /* RACQueueScheduler.h */, + D037648F19EDA41200A782A9 /* RACQueueScheduler.m */, + D037649019EDA41200A782A9 /* RACQueueScheduler+Subclass.h */, + D037649119EDA41200A782A9 /* RACReplaySubject.h */, + D037649219EDA41200A782A9 /* RACReplaySubject.m */, + D037649319EDA41200A782A9 /* RACReturnSignal.h */, + D037649419EDA41200A782A9 /* RACReturnSignal.m */, + D037649519EDA41200A782A9 /* RACScheduler.h */, + D037649619EDA41200A782A9 /* RACScheduler.m */, + D037649719EDA41200A782A9 /* RACScheduler+Private.h */, + D037649819EDA41200A782A9 /* RACScheduler+Subclass.h */, + D037649919EDA41200A782A9 /* RACScopedDisposable.h */, + D037649A19EDA41200A782A9 /* RACScopedDisposable.m */, + D037649B19EDA41200A782A9 /* RACSequence.h */, + D037649C19EDA41200A782A9 /* RACSequence.m */, + D037649D19EDA41200A782A9 /* RACSerialDisposable.h */, + D037649E19EDA41200A782A9 /* RACSerialDisposable.m */, + D037649F19EDA41200A782A9 /* RACSignal.h */, + D03764A019EDA41200A782A9 /* RACSignal.m */, + D03764A119EDA41200A782A9 /* RACSignal+Operations.h */, + D03764A219EDA41200A782A9 /* RACSignal+Operations.m */, + D03764A319EDA41200A782A9 /* RACSignalProvider.d */, + D03764A419EDA41200A782A9 /* RACSignalSequence.h */, + D03764A519EDA41200A782A9 /* RACSignalSequence.m */, + D03764A619EDA41200A782A9 /* RACStream.h */, + D03764A719EDA41200A782A9 /* RACStream.m */, + D03764A819EDA41200A782A9 /* RACStream+Private.h */, + D03764A919EDA41200A782A9 /* RACStringSequence.h */, + D03764AA19EDA41200A782A9 /* RACStringSequence.m */, + D03764AB19EDA41200A782A9 /* RACSubject.h */, + D03764AC19EDA41200A782A9 /* RACSubject.m */, + D03764AD19EDA41200A782A9 /* RACSubscriber.h */, + D03764AE19EDA41200A782A9 /* RACSubscriber.m */, + D03764AF19EDA41200A782A9 /* RACSubscriber+Private.h */, + D03764B019EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.h */, + D03764B119EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.m */, + D03764B219EDA41200A782A9 /* RACSubscriptionScheduler.h */, + D03764B319EDA41200A782A9 /* RACSubscriptionScheduler.m */, + D03764B419EDA41200A782A9 /* RACTargetQueueScheduler.h */, + D03764B519EDA41200A782A9 /* RACTargetQueueScheduler.m */, + D03764B619EDA41200A782A9 /* RACTestScheduler.h */, + D03764B719EDA41200A782A9 /* RACTestScheduler.m */, + D03764B819EDA41200A782A9 /* RACTuple.h */, + D03764B919EDA41200A782A9 /* RACTuple.m */, + D03764BA19EDA41200A782A9 /* RACTupleSequence.h */, + D03764BB19EDA41200A782A9 /* RACTupleSequence.m */, + D03764BC19EDA41200A782A9 /* RACUnarySequence.h */, + D03764BD19EDA41200A782A9 /* RACUnarySequence.m */, + D03764BE19EDA41200A782A9 /* RACUnit.h */, + D03764BF19EDA41200A782A9 /* RACUnit.m */, + D03764C019EDA41200A782A9 /* RACValueTransformer.h */, + D03764C119EDA41200A782A9 /* RACValueTransformer.m */, + D03764C219EDA41200A782A9 /* UIActionSheet+RACSignalSupport.h */, + D03764C319EDA41200A782A9 /* UIActionSheet+RACSignalSupport.m */, + D03764C419EDA41200A782A9 /* UIAlertView+RACSignalSupport.h */, + D03764C519EDA41200A782A9 /* UIAlertView+RACSignalSupport.m */, + D03764C619EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.h */, + D03764C719EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.m */, + D03764C819EDA41200A782A9 /* UIButton+RACCommandSupport.h */, + D03764C919EDA41200A782A9 /* UIButton+RACCommandSupport.m */, + D03764CA19EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.h */, + D03764CB19EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.m */, + D03764CC19EDA41200A782A9 /* UIControl+RACSignalSupport.h */, + D03764CD19EDA41200A782A9 /* UIControl+RACSignalSupport.m */, + D03764CE19EDA41200A782A9 /* UIControl+RACSignalSupportPrivate.h */, + D03764CF19EDA41200A782A9 /* UIControl+RACSignalSupportPrivate.m */, + D03764D019EDA41200A782A9 /* UIDatePicker+RACSignalSupport.h */, + D03764D119EDA41200A782A9 /* UIDatePicker+RACSignalSupport.m */, + D03764D219EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.h */, + D03764D319EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.m */, + D03764D419EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.h */, + D03764D519EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.m */, + D03764D619EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.h */, + D03764D719EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.m */, + D03764D819EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.h */, + D03764D919EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.m */, + D03764DA19EDA41200A782A9 /* UISlider+RACSignalSupport.h */, + D03764DB19EDA41200A782A9 /* UISlider+RACSignalSupport.m */, + D03764DC19EDA41200A782A9 /* UIStepper+RACSignalSupport.h */, + D03764DD19EDA41200A782A9 /* UIStepper+RACSignalSupport.m */, + D03764DE19EDA41200A782A9 /* UISwitch+RACSignalSupport.h */, + D03764DF19EDA41200A782A9 /* UISwitch+RACSignalSupport.m */, + D03764E019EDA41200A782A9 /* UITableViewCell+RACSignalSupport.h */, + D03764E119EDA41200A782A9 /* UITableViewCell+RACSignalSupport.m */, + D03764E219EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.h */, + D03764E319EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.m */, + D03764E419EDA41200A782A9 /* UITextField+RACSignalSupport.h */, + D03764E519EDA41200A782A9 /* UITextField+RACSignalSupport.m */, + D03764E619EDA41200A782A9 /* UITextView+RACSignalSupport.h */, + D03764E719EDA41200A782A9 /* UITextView+RACSignalSupport.m */, + ); + name = "Objective-C"; + sourceTree = ""; + }; + D037666519EDA57100A782A9 /* extobjc */ = { isa = PBXGroup; children = ( - D047967519666BF30066B267 /* ReactiveCocoa */, - D047968219666BF30066B267 /* ReactiveCocoaTests */, - D04796D519666CE40066B267 /* Configuration */, - D047967419666BF30066B267 /* Products */, + D037666619EDA57100A782A9 /* EXTKeyPathCoding.h */, + D037666719EDA57100A782A9 /* EXTRuntimeExtensions.h */, + D037666819EDA57100A782A9 /* EXTRuntimeExtensions.m */, + D037666919EDA57100A782A9 /* EXTScope.h */, + D037666A19EDA57100A782A9 /* metamacros.h */, ); + path = extobjc; sourceTree = ""; }; - D047967419666BF30066B267 /* Products */ = { + D037667519EDA5D900A782A9 /* Objective-C */ = { isa = PBXGroup; children = ( - D047967319666BF30066B267 /* ReactiveCocoa.framework */, - D047967E19666BF30066B267 /* ReactiveCocoa-MacTests.xctest */, - D047969A19666CBF0066B267 /* ReactiveCocoa.framework */, - D04796A419666CBF0066B267 /* ReactiveCocoa-iOSTests.xctest */, + D037667619EDA60000A782A9 /* NSControllerRACSupportSpec.m */, + D037667819EDA60000A782A9 /* NSEnumeratorRACSequenceAdditionsSpec.m */, + D037667919EDA60000A782A9 /* NSNotificationCenterRACSupportSpec.m */, + D037667A19EDA60000A782A9 /* NSObjectRACAppKitBindingsSpec.m */, + D037667B19EDA60000A782A9 /* NSObjectRACDeallocatingSpec.m */, + D037667C19EDA60000A782A9 /* NSObjectRACLiftingSpec.m */, + D037667D19EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.h */, + D037667E19EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.m */, + D037667F19EDA60000A782A9 /* NSObjectRACPropertySubscribingSpec.m */, + D037668019EDA60000A782A9 /* NSObjectRACSelectorSignalSpec.m */, + D037668119EDA60000A782A9 /* NSStringRACKeyPathUtilitiesSpec.m */, + D037668319EDA60000A782A9 /* NSURLConnectionRACSupportSpec.m */, + D037668419EDA60000A782A9 /* NSUserDefaultsRACSupportSpec.m */, + D037668519EDA60000A782A9 /* RACBacktraceSpec.m */, + D037668619EDA60000A782A9 /* RACBlockTrampolineSpec.m */, + D037668719EDA60000A782A9 /* RACChannelExamples.h */, + D037668819EDA60000A782A9 /* RACChannelExamples.m */, + D037668919EDA60000A782A9 /* RACChannelSpec.m */, + D037668A19EDA60000A782A9 /* RACCommandSpec.m */, + D037668B19EDA60000A782A9 /* RACCompoundDisposableSpec.m */, + D037668C19EDA60000A782A9 /* RACControlCommandExamples.h */, + D037668D19EDA60000A782A9 /* RACControlCommandExamples.m */, + D037668E19EDA60000A782A9 /* RACDelegateProxySpec.m */, + D037668F19EDA60000A782A9 /* RACDisposableSpec.m */, + D037669019EDA60000A782A9 /* RACEventSpec.m */, + D037669119EDA60000A782A9 /* RACKVOChannelSpec.m */, + D037669219EDA60000A782A9 /* RACKVOWrapperSpec.m */, + D037669319EDA60000A782A9 /* RACMulticastConnectionSpec.m */, + D037669419EDA60000A782A9 /* RACPropertySignalExamples.h */, + D037669519EDA60000A782A9 /* RACPropertySignalExamples.m */, + D037669619EDA60000A782A9 /* RACSchedulerSpec.m */, + D037669719EDA60000A782A9 /* RACSequenceAdditionsSpec.m */, + D037669819EDA60000A782A9 /* RACSequenceExamples.h */, + D037669919EDA60000A782A9 /* RACSequenceExamples.m */, + D037669A19EDA60000A782A9 /* RACSequenceSpec.m */, + D037669B19EDA60000A782A9 /* RACSerialDisposableSpec.m */, + D037669C19EDA60000A782A9 /* RACSignalSpec.m */, + D037669F19EDA60000A782A9 /* RACStreamExamples.h */, + D03766A019EDA60000A782A9 /* RACStreamExamples.m */, + D03766A119EDA60000A782A9 /* RACSubclassObject.h */, + D03766A219EDA60000A782A9 /* RACSubclassObject.m */, + D03766A319EDA60000A782A9 /* RACSubjectSpec.m */, + D03766A419EDA60000A782A9 /* RACSubscriberExamples.h */, + D03766A519EDA60000A782A9 /* RACSubscriberExamples.m */, + D03766A619EDA60000A782A9 /* RACSubscriberSpec.m */, + D03766A719EDA60000A782A9 /* RACSubscriptingAssignmentTrampolineSpec.m */, + D03766A819EDA60000A782A9 /* RACTargetQueueSchedulerSpec.m */, + D03766B019EDA60000A782A9 /* RACTupleSpec.m */, + D03766B219EDA60000A782A9 /* UIActionSheetRACSupportSpec.m */, + D03766B319EDA60000A782A9 /* UIAlertViewRACSupportSpec.m */, + D03766B419EDA60000A782A9 /* UIBarButtonItemRACSupportSpec.m */, + D03766B519EDA60000A782A9 /* UIButtonRACSupportSpec.m */, + D03766B719EDA60000A782A9 /* UIImagePickerControllerRACSupportSpec.m */, + D037673819EDCA0E00A782A9 /* SwiftSpec.swift */, + ); + name = "Objective-C"; + sourceTree = ""; + }; + D04725E019E49ED7006002AA = { + isa = PBXGroup; + children = ( + D04725EC19E49ED7006002AA /* ReactiveCocoa */, + D04725F919E49ED7006002AA /* ReactiveCocoaTests */, + D047262519E49FE8006002AA /* Configuration */, + D04725EB19E49ED7006002AA /* Products */, + ); + sourceTree = ""; + }; + D04725EB19E49ED7006002AA /* Products */ = { + isa = PBXGroup; + children = ( + D04725EA19E49ED7006002AA /* ReactiveCocoa.framework */, + D04725F519E49ED7006002AA /* ReactiveCocoa-MacTests.xctest */, + D047260C19E49F82006002AA /* ReactiveCocoa.framework */, + D047261619E49F82006002AA /* ReactiveCocoa-iOSTests.xctest */, ); name = Products; sourceTree = ""; }; - D047967519666BF30066B267 /* ReactiveCocoa */ = { + D04725EC19E49ED7006002AA /* ReactiveCocoa */ = { isa = PBXGroup; children = ( - D047967819666BF30066B267 /* ReactiveCocoa.h */, - D0479705196670630066B267 /* Swift */, - D0479706196670680066B267 /* Objective-C */, - D047967619666BF30066B267 /* Supporting Files */, + D04725EF19E49ED7006002AA /* ReactiveCocoa.h */, + D0C312B919EF2A3000984962 /* Swift */, + D037642919EDA3B600A782A9 /* Objective-C */, + D04725ED19E49ED7006002AA /* Supporting Files */, ); path = ReactiveCocoa; sourceTree = ""; }; - D047967619666BF30066B267 /* Supporting Files */ = { + D04725ED19E49ED7006002AA /* Supporting Files */ = { isa = PBXGroup; children = ( - D0297D3D19D67F01009986A9 /* LlamaKit.framework */, - D0297D3B19D67EF5009986A9 /* LlamaKit.framework */, - D04797B0196670900066B267 /* ReactiveCocoa-Bridging-Header.h */, - D0479995196673730066B267 /* ReactiveCocoa-Prefix.pch */, - D047967719666BF30066B267 /* Info.plist */, + D037666519EDA57100A782A9 /* extobjc */, + D0C3130719EF2AD900984962 /* LlamaKit.framework */, + D0C3130519EF2ACC00984962 /* LlamaKit.framework */, + D04725EE19E49ED7006002AA /* Info.plist */, ); name = "Supporting Files"; sourceTree = ""; }; - D047968219666BF30066B267 /* ReactiveCocoaTests */ = { + D04725F919E49ED7006002AA /* ReactiveCocoaTests */ = { isa = PBXGroup; children = ( - D04797071966706F0066B267 /* Swift */, - D047968319666BF30066B267 /* Supporting Files */, + D0C312ED19EF2A6F00984962 /* Swift */, + D037667519EDA5D900A782A9 /* Objective-C */, + D04725FA19E49ED7006002AA /* Supporting Files */, ); path = ReactiveCocoaTests; sourceTree = ""; }; - D047968319666BF30066B267 /* Supporting Files */ = { + D04725FA19E49ED7006002AA /* Supporting Files */ = { isa = PBXGroup; children = ( - D0AFFF1B19CF2EFC0078D030 /* Nimble.framework */, - D0AFFF1919CF2EF70078D030 /* Nimble.framework */, - D09C6CBB198F4931008E129B /* Quick.framework */, - D047968419666BF30066B267 /* Info.plist */, + D05E662419EDD82000904ACA /* Nimble.framework */, + D037672B19EDA75D00A782A9 /* Quick.framework */, + D03766A919EDA60000A782A9 /* RACTestExampleScheduler.h */, + D03766AA19EDA60000A782A9 /* RACTestExampleScheduler.m */, + D03766AB19EDA60000A782A9 /* RACTestObject.h */, + D03766AC19EDA60000A782A9 /* RACTestObject.m */, + D03766AD19EDA60000A782A9 /* RACTestSchedulerSpec.m */, + D03766AE19EDA60000A782A9 /* RACTestUIButton.h */, + D03766AF19EDA60000A782A9 /* RACTestUIButton.m */, + D03766B119EDA60000A782A9 /* test-data.json */, + D04725FB19E49ED7006002AA /* Info.plist */, ); name = "Supporting Files"; sourceTree = ""; }; - D04796D519666CE40066B267 /* Configuration */ = { + D047262519E49FE8006002AA /* Configuration */ = { isa = PBXGroup; children = ( - D04796D619666CE40066B267 /* Base */, - D04796E119666CE40066B267 /* iOS */, - D04796E619666CE40066B267 /* Mac OS X */, - D04796EC19666CE40066B267 /* README.md */, + D047262619E49FE8006002AA /* Base */, + D047263119E49FE8006002AA /* iOS */, + D047263619E49FE8006002AA /* Mac OS X */, + D047263C19E49FE8006002AA /* README.md */, ); name = Configuration; path = External/xcconfigs; sourceTree = ""; }; - D04796D619666CE40066B267 /* Base */ = { + D047262619E49FE8006002AA /* Base */ = { isa = PBXGroup; children = ( - D04796D719666CE40066B267 /* Common.xcconfig */, - D04796D819666CE40066B267 /* Configurations */, - D04796DD19666CE40066B267 /* Targets */, + D047262719E49FE8006002AA /* Common.xcconfig */, + D047262819E49FE8006002AA /* Configurations */, + D047262D19E49FE8006002AA /* Targets */, ); path = Base; sourceTree = ""; }; - D04796D819666CE40066B267 /* Configurations */ = { + D047262819E49FE8006002AA /* Configurations */ = { isa = PBXGroup; children = ( - D04796D919666CE40066B267 /* Debug.xcconfig */, - D04796DA19666CE40066B267 /* Profile.xcconfig */, - D04796DB19666CE40066B267 /* Release.xcconfig */, - D04796DC19666CE40066B267 /* Test.xcconfig */, + D047262919E49FE8006002AA /* Debug.xcconfig */, + D047262A19E49FE8006002AA /* Profile.xcconfig */, + D047262B19E49FE8006002AA /* Release.xcconfig */, + D047262C19E49FE8006002AA /* Test.xcconfig */, ); path = Configurations; sourceTree = ""; }; - D04796DD19666CE40066B267 /* Targets */ = { + D047262D19E49FE8006002AA /* Targets */ = { isa = PBXGroup; children = ( - D04796DE19666CE40066B267 /* Application.xcconfig */, - D04796DF19666CE40066B267 /* Framework.xcconfig */, - D04796E019666CE40066B267 /* StaticLibrary.xcconfig */, + D047262E19E49FE8006002AA /* Application.xcconfig */, + D047262F19E49FE8006002AA /* Framework.xcconfig */, + D047263019E49FE8006002AA /* StaticLibrary.xcconfig */, ); path = Targets; sourceTree = ""; }; - D04796E119666CE40066B267 /* iOS */ = { + D047263119E49FE8006002AA /* iOS */ = { isa = PBXGroup; children = ( - D04796E219666CE40066B267 /* iOS-Application.xcconfig */, - D04796E319666CE40066B267 /* iOS-Base.xcconfig */, - D04796E419666CE40066B267 /* iOS-Framework.xcconfig */, - D04796E519666CE40066B267 /* iOS-StaticLibrary.xcconfig */, + D047263219E49FE8006002AA /* iOS-Application.xcconfig */, + D047263319E49FE8006002AA /* iOS-Base.xcconfig */, + D047263419E49FE8006002AA /* iOS-Framework.xcconfig */, + D047263519E49FE8006002AA /* iOS-StaticLibrary.xcconfig */, ); path = iOS; sourceTree = ""; }; - D04796E619666CE40066B267 /* Mac OS X */ = { + D047263619E49FE8006002AA /* Mac OS X */ = { isa = PBXGroup; children = ( - D04796E719666CE40066B267 /* Mac-Application.xcconfig */, - D04796E819666CE40066B267 /* Mac-Base.xcconfig */, - D04796E919666CE40066B267 /* Mac-DynamicLibrary.xcconfig */, - D04796EA19666CE40066B267 /* Mac-Framework.xcconfig */, - D04796EB19666CE40066B267 /* Mac-StaticLibrary.xcconfig */, + D047263719E49FE8006002AA /* Mac-Application.xcconfig */, + D047263819E49FE8006002AA /* Mac-Base.xcconfig */, + D047263919E49FE8006002AA /* Mac-DynamicLibrary.xcconfig */, + D047263A19E49FE8006002AA /* Mac-Framework.xcconfig */, + D047263B19E49FE8006002AA /* Mac-StaticLibrary.xcconfig */, ); path = "Mac OS X"; sourceTree = ""; }; - D0479705196670630066B267 /* Swift */ = { + D0C312B919EF2A3000984962 /* Swift */ = { isa = PBXGroup; children = ( - D0479709196670900066B267 /* Action.swift */, - D047970B196670900066B267 /* Atomic.swift */, - D036AA4A196FB7CB00B49B76 /* Bag.swift */, - D047970E196670900066B267 /* Consumer.swift */, - D047970F196670900066B267 /* Disposable.swift */, - D0E3CF541973AFC7004FD181 /* Errors.swift */, - D0479710196670900066B267 /* Event.swift */, - D0297D3519D67D42009986A9 /* Identity.swift */, - D0479727196670900066B267 /* NSNotificationCenterExtensions.swift */, - D0479744196670900066B267 /* NSURLSessionExtensions.swift */, - D0479747196670900066B267 /* ObjectiveCBridging.swift */, - D02C14B0197243CB007127D4 /* OptionalExtensions.swift */, - D0479748196670900066B267 /* Producer.swift */, - D0479749196670900066B267 /* Promise.swift */, - D04797B3196670900066B267 /* Scheduler.swift */, - D04797B4196670900066B267 /* Signal.swift */, - D04797B5196670900066B267 /* SignalingProperty.swift */, + D0C312BA19EF2A5800984962 /* Action.swift */, + D0C312BB19EF2A5800984962 /* Atomic.swift */, + D0C312BC19EF2A5800984962 /* Bag.swift */, + D0C312BD19EF2A5800984962 /* Consumer.swift */, + D0C312BE19EF2A5800984962 /* Disposable.swift */, + D0C312BF19EF2A5800984962 /* Errors.swift */, + D0C312C019EF2A5800984962 /* Event.swift */, + D0C312C119EF2A5800984962 /* Identity.swift */, + D0C312C219EF2A5800984962 /* NSNotificationCenterExtensions.swift */, + D0C312C319EF2A5800984962 /* NSURLSessionExtensions.swift */, + D0C312C419EF2A5800984962 /* ObjectiveCBridging.swift */, + D0C312C519EF2A5800984962 /* OptionalExtensions.swift */, + D0C312C619EF2A5800984962 /* Producer.swift */, + D0C312C719EF2A5800984962 /* Promise.swift */, + D0C312C819EF2A5800984962 /* Scheduler.swift */, + D0C312C919EF2A5800984962 /* Signal.swift */, + D0C312CA19EF2A5800984962 /* SignalingProperty.swift */, ); name = Swift; sourceTree = ""; }; - D0479706196670680066B267 /* Objective-C */ = { + D0C312ED19EF2A6F00984962 /* Swift */ = { isa = PBXGroup; children = ( - D0479986196671DF0066B267 /* EXTKeyPathCoding.h */, - D0479987196671DF0066B267 /* EXTRuntimeExtensions.h */, - D0479988196671DF0066B267 /* EXTRuntimeExtensions.m */, - D0479989196671DF0066B267 /* EXTScope.h */, - D047998A196671DF0066B267 /* metamacros.h */, - D0479712196670900066B267 /* NSArray+RACSequenceAdditions.h */, - D0479713196670900066B267 /* NSArray+RACSequenceAdditions.m */, - D0479714196670900066B267 /* NSControl+RACCommandSupport.h */, - D0479715196670900066B267 /* NSControl+RACCommandSupport.m */, - D0479716196670900066B267 /* NSControl+RACTextSignalSupport.h */, - D0479717196670900066B267 /* NSControl+RACTextSignalSupport.m */, - D0479718196670900066B267 /* NSData+RACSupport.h */, - D0479719196670900066B267 /* NSData+RACSupport.m */, - D047971A196670900066B267 /* NSDictionary+RACSequenceAdditions.h */, - D047971B196670900066B267 /* NSDictionary+RACSequenceAdditions.m */, - D047971C196670900066B267 /* NSEnumerator+RACSequenceAdditions.h */, - D047971D196670900066B267 /* NSEnumerator+RACSequenceAdditions.m */, - D047971E196670900066B267 /* NSFileHandle+RACSupport.h */, - D047971F196670900066B267 /* NSFileHandle+RACSupport.m */, - D0479720196670900066B267 /* NSIndexSet+RACSequenceAdditions.h */, - D0479721196670900066B267 /* NSIndexSet+RACSequenceAdditions.m */, - D0479722196670900066B267 /* NSInvocation+RACTypeParsing.h */, - D0479723196670900066B267 /* NSInvocation+RACTypeParsing.m */, - D0479725196670900066B267 /* NSNotificationCenter+RACSupport.h */, - D0479726196670900066B267 /* NSNotificationCenter+RACSupport.m */, - D0479728196670900066B267 /* NSObject+RACAppKitBindings.h */, - D0479729196670900066B267 /* NSObject+RACAppKitBindings.m */, - D047972A196670900066B267 /* NSObject+RACDeallocating.h */, - D047972B196670900066B267 /* NSObject+RACDeallocating.m */, - D047972C196670900066B267 /* NSObject+RACDescription.h */, - D047972D196670900066B267 /* NSObject+RACDescription.m */, - D047972E196670900066B267 /* NSObject+RACKVOWrapper.h */, - D047972F196670900066B267 /* NSObject+RACKVOWrapper.m */, - D0479730196670900066B267 /* NSObject+RACLifting.h */, - D0479731196670900066B267 /* NSObject+RACLifting.m */, - D0479732196670900066B267 /* NSObject+RACPropertySubscribing.h */, - D0479733196670900066B267 /* NSObject+RACPropertySubscribing.m */, - D0479734196670900066B267 /* NSObject+RACSelectorSignal.h */, - D0479735196670900066B267 /* NSObject+RACSelectorSignal.m */, - D0479736196670900066B267 /* NSOrderedSet+RACSequenceAdditions.h */, - D0479737196670900066B267 /* NSOrderedSet+RACSequenceAdditions.m */, - D0479738196670900066B267 /* NSSet+RACSequenceAdditions.h */, - D0479739196670900066B267 /* NSSet+RACSequenceAdditions.m */, - D047973A196670900066B267 /* NSString+RACKeyPathUtilities.h */, - D047973B196670900066B267 /* NSString+RACKeyPathUtilities.m */, - D047973C196670900066B267 /* NSString+RACSequenceAdditions.h */, - D047973D196670900066B267 /* NSString+RACSequenceAdditions.m */, - D047973E196670900066B267 /* NSString+RACSupport.h */, - D047973F196670900066B267 /* NSString+RACSupport.m */, - D0479740196670900066B267 /* NSText+RACSignalSupport.h */, - D0479741196670900066B267 /* NSText+RACSignalSupport.m */, - D0479742196670900066B267 /* NSURLConnection+RACSupport.h */, - D0479743196670900066B267 /* NSURLConnection+RACSupport.m */, - D0479745196670900066B267 /* NSUserDefaults+RACSupport.h */, - D0479746196670900066B267 /* NSUserDefaults+RACSupport.m */, - D047974A196670900066B267 /* RACArraySequence.h */, - D047974B196670900066B267 /* RACArraySequence.m */, - D047974C196670900066B267 /* RACBacktrace.h */, - D047974D196670900066B267 /* RACBacktrace.m */, - D047974E196670900066B267 /* RACBehaviorSubject.h */, - D047974F196670900066B267 /* RACBehaviorSubject.m */, - D0479750196670900066B267 /* RACBlockTrampoline.h */, - D0479751196670900066B267 /* RACBlockTrampoline.m */, - D0479752196670900066B267 /* RACChannel.h */, - D0479753196670900066B267 /* RACChannel.m */, - D0479754196670900066B267 /* RACCommand.h */, - D0479755196670900066B267 /* RACCommand.m */, - D0479756196670900066B267 /* RACCompoundDisposable.h */, - D0479757196670900066B267 /* RACCompoundDisposable.m */, - D0479758196670900066B267 /* RACCompoundDisposableProvider.d */, - D0479759196670900066B267 /* RACDelegateProxy.h */, - D047975A196670900066B267 /* RACDelegateProxy.m */, - D047975B196670900066B267 /* RACDisposable.h */, - D047975C196670900066B267 /* RACDisposable.m */, - D047975D196670900066B267 /* RACDynamicSequence.h */, - D047975E196670900066B267 /* RACDynamicSequence.m */, - D047975F196670900066B267 /* RACDynamicSignal.h */, - D0479760196670900066B267 /* RACDynamicSignal.m */, - D0479761196670900066B267 /* RACEagerSequence.h */, - D0479762196670900066B267 /* RACEagerSequence.m */, - D0479763196670900066B267 /* RACEmptySequence.h */, - D0479764196670900066B267 /* RACEmptySequence.m */, - D0479765196670900066B267 /* RACEmptySignal.h */, - D0479766196670900066B267 /* RACEmptySignal.m */, - D0479767196670900066B267 /* RACErrorSignal.h */, - D0479768196670900066B267 /* RACErrorSignal.m */, - D0479769196670900066B267 /* RACEvent.h */, - D047976A196670900066B267 /* RACEvent.m */, - D047976B196670900066B267 /* RACGroupedSignal.h */, - D047976C196670900066B267 /* RACGroupedSignal.m */, - D047976D196670900066B267 /* RACImmediateScheduler.h */, - D047976E196670900066B267 /* RACImmediateScheduler.m */, - D047976F196670900066B267 /* RACIndexSetSequence.h */, - D0479770196670900066B267 /* RACIndexSetSequence.m */, - D0479771196670900066B267 /* RACKVOChannel.h */, - D0479772196670900066B267 /* RACKVOChannel.m */, - D0479773196670900066B267 /* RACKVOTrampoline.h */, - D0479774196670900066B267 /* RACKVOTrampoline.m */, - D0479775196670900066B267 /* RACMulticastConnection.h */, - D0479776196670900066B267 /* RACMulticastConnection.m */, - D0479777196670900066B267 /* RACMulticastConnection+Private.h */, - D0479778196670900066B267 /* RACObjCRuntime.h */, - D0479779196670900066B267 /* RACObjCRuntime.m */, - D047977A196670900066B267 /* RACPassthroughSubscriber.h */, - D047977B196670900066B267 /* RACPassthroughSubscriber.m */, - D047977C196670900066B267 /* RACQueueScheduler.h */, - D047977D196670900066B267 /* RACQueueScheduler.m */, - D047977E196670900066B267 /* RACQueueScheduler+Subclass.h */, - D047977F196670900066B267 /* RACReplaySubject.h */, - D0479780196670900066B267 /* RACReplaySubject.m */, - D0479781196670900066B267 /* RACReturnSignal.h */, - D0479782196670900066B267 /* RACReturnSignal.m */, - D0479783196670900066B267 /* RACScheduler.h */, - D0479784196670900066B267 /* RACScheduler.m */, - D0479785196670900066B267 /* RACScheduler+Private.h */, - D0479786196670900066B267 /* RACScheduler+Subclass.h */, - D0479787196670900066B267 /* RACScopedDisposable.h */, - D0479788196670900066B267 /* RACScopedDisposable.m */, - D0479789196670900066B267 /* RACSequence.h */, - D047978A196670900066B267 /* RACSequence.m */, - D047978B196670900066B267 /* RACSerialDisposable.h */, - D047978C196670900066B267 /* RACSerialDisposable.m */, - D047978D196670900066B267 /* RACSignal.h */, - D047978E196670900066B267 /* RACSignal.m */, - D047978F196670900066B267 /* RACSignal+Operations.h */, - D0479790196670900066B267 /* RACSignal+Operations.m */, - D0479791196670900066B267 /* RACSignalProvider.d */, - D0479792196670900066B267 /* RACSignalSequence.h */, - D0479793196670900066B267 /* RACSignalSequence.m */, - D0479794196670900066B267 /* RACStream.h */, - D0479795196670900066B267 /* RACStream.m */, - D0479796196670900066B267 /* RACStream+Private.h */, - D0479797196670900066B267 /* RACStringSequence.h */, - D0479798196670900066B267 /* RACStringSequence.m */, - D0479799196670900066B267 /* RACSubject.h */, - D047979A196670900066B267 /* RACSubject.m */, - D047979B196670900066B267 /* RACSubscriber.h */, - D047979C196670900066B267 /* RACSubscriber.m */, - D047979D196670900066B267 /* RACSubscriber+Private.h */, - D047979E196670900066B267 /* RACSubscriptingAssignmentTrampoline.h */, - D047979F196670900066B267 /* RACSubscriptingAssignmentTrampoline.m */, - D04797A0196670900066B267 /* RACSubscriptionScheduler.h */, - D04797A1196670900066B267 /* RACSubscriptionScheduler.m */, - D04797A2196670900066B267 /* RACTargetQueueScheduler.h */, - D04797A3196670900066B267 /* RACTargetQueueScheduler.m */, - D04797A4196670900066B267 /* RACTestScheduler.h */, - D04797A5196670900066B267 /* RACTestScheduler.m */, - D04797A6196670900066B267 /* RACTuple.h */, - D04797A7196670900066B267 /* RACTuple.m */, - D04797A8196670900066B267 /* RACTupleSequence.h */, - D04797A9196670900066B267 /* RACTupleSequence.m */, - D04797AA196670900066B267 /* RACUnarySequence.h */, - D04797AB196670900066B267 /* RACUnarySequence.m */, - D04797AC196670900066B267 /* RACUnit.h */, - D04797AD196670900066B267 /* RACUnit.m */, - D04797AE196670900066B267 /* RACValueTransformer.h */, - D04797AF196670900066B267 /* RACValueTransformer.m */, - D04797B7196670900066B267 /* UIActionSheet+RACSignalSupport.h */, - D04797B8196670900066B267 /* UIActionSheet+RACSignalSupport.m */, - D04797B9196670900066B267 /* UIAlertView+RACSignalSupport.h */, - D04797BA196670900066B267 /* UIAlertView+RACSignalSupport.m */, - D04797BB196670900066B267 /* UIBarButtonItem+RACCommandSupport.h */, - D04797BC196670900066B267 /* UIBarButtonItem+RACCommandSupport.m */, - D04797BD196670900066B267 /* UIButton+RACCommandSupport.h */, - D04797BE196670900066B267 /* UIButton+RACCommandSupport.m */, - D04797BF196670900066B267 /* UICollectionReusableView+RACSignalSupport.h */, - D04797C0196670900066B267 /* UICollectionReusableView+RACSignalSupport.m */, - D04797C1196670900066B267 /* UIControl+RACSignalSupport.h */, - D04797C2196670900066B267 /* UIControl+RACSignalSupport.m */, - D04797C3196670900066B267 /* UIControl+RACSignalSupportPrivate.h */, - D04797C4196670900066B267 /* UIControl+RACSignalSupportPrivate.m */, - D04797C5196670900066B267 /* UIDatePicker+RACSignalSupport.h */, - D04797C6196670900066B267 /* UIDatePicker+RACSignalSupport.m */, - D04797C7196670900066B267 /* UIGestureRecognizer+RACSignalSupport.h */, - D04797C8196670900066B267 /* UIGestureRecognizer+RACSignalSupport.m */, - D04797C9196670900066B267 /* UIImagePickerController+RACSignalSupport.h */, - D04797CA196670900066B267 /* UIImagePickerController+RACSignalSupport.m */, - D04797CB196670900066B267 /* UIRefreshControl+RACCommandSupport.h */, - D04797CC196670900066B267 /* UIRefreshControl+RACCommandSupport.m */, - D04797CD196670900066B267 /* UISegmentedControl+RACSignalSupport.h */, - D04797CE196670900066B267 /* UISegmentedControl+RACSignalSupport.m */, - D04797CF196670900066B267 /* UISlider+RACSignalSupport.h */, - D04797D0196670900066B267 /* UISlider+RACSignalSupport.m */, - D04797D1196670900066B267 /* UIStepper+RACSignalSupport.h */, - D04797D2196670900066B267 /* UIStepper+RACSignalSupport.m */, - D04797D3196670900066B267 /* UISwitch+RACSignalSupport.h */, - D04797D4196670900066B267 /* UISwitch+RACSignalSupport.m */, - D04797D5196670900066B267 /* UITableViewCell+RACSignalSupport.h */, - D04797D6196670900066B267 /* UITableViewCell+RACSignalSupport.m */, - D04797D7196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.h */, - D04797D8196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.m */, - D04797D9196670900066B267 /* UITextField+RACSignalSupport.h */, - D04797DA196670900066B267 /* UITextField+RACSignalSupport.m */, - D04797DB196670900066B267 /* UITextView+RACSignalSupport.h */, - D04797DC196670900066B267 /* UITextView+RACSignalSupport.m */, - ); - name = "Objective-C"; - sourceTree = ""; - }; - D04797071966706F0066B267 /* Swift */ = { - isa = PBXGroup; - children = ( - D095745719733F74002D44C1 /* AtomicSpec.swift */, - D095745A197341C2002D44C1 /* BagSpec.swift */, - D095745D197344E3002D44C1 /* DisposableSpec.swift */, - D047999E196678F20066B267 /* ObjectiveCBridgingSpec.swift */, - D09574601973506C002D44C1 /* SchedulerSpec.swift */, - D011F1F219DD13F600A6F6C8 /* SignalSpec.swift */, + D0C312EE19EF2A7700984962 /* AtomicSpec.swift */, + D0C312EF19EF2A7700984962 /* BagSpec.swift */, + D0C312F019EF2A7700984962 /* DisposableSpec.swift */, + D0C312F119EF2A7700984962 /* ObjectiveCBridgingSpec.swift */, + D0C312F219EF2A7700984962 /* SchedulerSpec.swift */, + D0C312F319EF2A7700984962 /* SignalSpec.swift */, + D0C312F419EF2A7700984962 /* SwiftSpec.swift */, ); name = Swift; sourceTree = ""; @@ -1299,214 +1275,151 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - D047967019666BF30066B267 /* Headers */ = { + D04725E719E49ED7006002AA /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - D047991F196670900066B267 /* RACUnarySequence.h in Headers */, - D047967919666BF30066B267 /* ReactiveCocoa.h in Headers */, - D047982B196670900066B267 /* NSObject+RACLifting.h in Headers */, - D0479993196671DF0066B267 /* metamacros.h in Headers */, - D047986B196670900066B267 /* RACBlockTrampoline.h in Headers */, - D04798B1196670900066B267 /* RACKVOTrampoline.h in Headers */, - D04798BB196670900066B267 /* RACObjCRuntime.h in Headers */, - D04798A9196670900066B267 /* RACIndexSetSequence.h in Headers */, - D04797F3196670900066B267 /* NSControl+RACCommandSupport.h in Headers */, - D0479891196670900066B267 /* RACEmptySequence.h in Headers */, - D047986F196670900066B267 /* RACChannel.h in Headers */, - D0479901196670900066B267 /* RACSubscriber.h in Headers */, - D04798E5196670900066B267 /* RACSignal.h in Headers */, - D047980B196670900066B267 /* NSIndexSet+RACSequenceAdditions.h in Headers */, - D04798AD196670900066B267 /* RACKVOChannel.h in Headers */, - D047981F196670900066B267 /* NSObject+RACDeallocating.h in Headers */, - D0479815196670900066B267 /* NSNotificationCenter+RACSupport.h in Headers */, - D0479863196670900066B267 /* RACBacktrace.h in Headers */, - D04798CD196670900066B267 /* RACReturnSignal.h in Headers */, - D0479907196670900066B267 /* RACSubscriptingAssignmentTrampoline.h in Headers */, - D04798D7196670900066B267 /* RACScheduler+Subclass.h in Headers */, - D0479881196670900066B267 /* RACDisposable.h in Headers */, - D04798C3196670900066B267 /* RACQueueScheduler.h in Headers */, - D047982F196670900066B267 /* NSObject+RACPropertySubscribing.h in Headers */, - D0479991196671DF0066B267 /* EXTScope.h in Headers */, - D0479807196670900066B267 /* NSFileHandle+RACSupport.h in Headers */, - D047998D196671DF0066B267 /* EXTRuntimeExtensions.h in Headers */, - D047983B196670900066B267 /* NSSet+RACSequenceAdditions.h in Headers */, - D04798EF196670900066B267 /* RACSignalSequence.h in Headers */, - D04798F7196670900066B267 /* RACStream+Private.h in Headers */, - D047984B196670900066B267 /* NSText+RACSignalSupport.h in Headers */, - D047983F196670900066B267 /* NSString+RACKeyPathUtilities.h in Headers */, - D04798F3196670900066B267 /* RACStream.h in Headers */, - D047990F196670900066B267 /* RACTargetQueueScheduler.h in Headers */, - D04798C7196670900066B267 /* RACQueueScheduler+Subclass.h in Headers */, - D0479823196670900066B267 /* NSObject+RACDescription.h in Headers */, - D0479923196670900066B267 /* RACUnit.h in Headers */, - D0479877196670900066B267 /* RACCompoundDisposable.h in Headers */, - D04797FB196670900066B267 /* NSData+RACSupport.h in Headers */, - D047980F196670900066B267 /* NSInvocation+RACTypeParsing.h in Headers */, - D0479803196670900066B267 /* NSEnumerator+RACSequenceAdditions.h in Headers */, - D047992B196670900066B267 /* ReactiveCocoa-Bridging-Header.h in Headers */, - D0479899196670900066B267 /* RACErrorSignal.h in Headers */, - D04798DD196670900066B267 /* RACSequence.h in Headers */, - D0479847196670900066B267 /* NSString+RACSupport.h in Headers */, - D04798E1196670900066B267 /* RACSerialDisposable.h in Headers */, - D04798E9196670900066B267 /* RACSignal+Operations.h in Headers */, - D04798C9196670900066B267 /* RACReplaySubject.h in Headers */, - D04798BF196670900066B267 /* RACPassthroughSubscriber.h in Headers */, - D04798B5196670900066B267 /* RACMulticastConnection.h in Headers */, - D0479827196670900066B267 /* NSObject+RACKVOWrapper.h in Headers */, - D047991B196670900066B267 /* RACTupleSequence.h in Headers */, - D047985F196670900066B267 /* RACArraySequence.h in Headers */, - D0479867196670900066B267 /* RACBehaviorSubject.h in Headers */, - D0479895196670900066B267 /* RACEmptySignal.h in Headers */, - D04798B9196670900066B267 /* RACMulticastConnection+Private.h in Headers */, - D04798A1196670900066B267 /* RACGroupedSignal.h in Headers */, - D0479855196670900066B267 /* NSUserDefaults+RACSupport.h in Headers */, - D04798A5196670900066B267 /* RACImmediateScheduler.h in Headers */, - D04798D1196670900066B267 /* RACScheduler.h in Headers */, - D0479873196670900066B267 /* RACCommand.h in Headers */, - D0479917196670900066B267 /* RACTuple.h in Headers */, - D04798D9196670900066B267 /* RACScopedDisposable.h in Headers */, - D047998B196671DF0066B267 /* EXTKeyPathCoding.h in Headers */, - D0479913196670900066B267 /* RACTestScheduler.h in Headers */, - D0479889196670900066B267 /* RACDynamicSignal.h in Headers */, - D0479837196670900066B267 /* NSOrderedSet+RACSequenceAdditions.h in Headers */, - D04797F7196670900066B267 /* NSControl+RACTextSignalSupport.h in Headers */, - D047987D196670900066B267 /* RACDelegateProxy.h in Headers */, - D047990B196670900066B267 /* RACSubscriptionScheduler.h in Headers */, - D04798FD196670900066B267 /* RACSubject.h in Headers */, - D0479833196670900066B267 /* NSObject+RACSelectorSignal.h in Headers */, - D0479885196670900066B267 /* RACDynamicSequence.h in Headers */, - D047984F196670900066B267 /* NSURLConnection+RACSupport.h in Headers */, - D04797EF196670900066B267 /* NSArray+RACSequenceAdditions.h in Headers */, - D0479927196670900066B267 /* RACValueTransformer.h in Headers */, - D04798D5196670900066B267 /* RACScheduler+Private.h in Headers */, - D0479905196670900066B267 /* RACSubscriber+Private.h in Headers */, - D04798F9196670900066B267 /* RACStringSequence.h in Headers */, - D047981B196670900066B267 /* NSObject+RACAppKitBindings.h in Headers */, - D047989D196670900066B267 /* RACEvent.h in Headers */, - D047988D196670900066B267 /* RACEagerSequence.h in Headers */, - D0479843196670900066B267 /* NSString+RACSequenceAdditions.h in Headers */, - D04797FF196670900066B267 /* NSDictionary+RACSequenceAdditions.h in Headers */, + D04725F019E49ED7006002AA /* ReactiveCocoa.h in Headers */, + D037652019EDA41200A782A9 /* NSObject+RACLifting.h in Headers */, + D03764EC19EDA41200A782A9 /* NSControl+RACCommandSupport.h in Headers */, + D037655C19EDA41200A782A9 /* RACChannel.h in Headers */, + D03765EE19EDA41200A782A9 /* RACSubscriber.h in Headers */, + D03765D219EDA41200A782A9 /* RACSignal.h in Headers */, + D037650419EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.h in Headers */, + D037659A19EDA41200A782A9 /* RACKVOChannel.h in Headers */, + D037651419EDA41200A782A9 /* NSObject+RACDeallocating.h in Headers */, + D037650C19EDA41200A782A9 /* NSNotificationCenter+RACSupport.h in Headers */, + D037667319EDA57100A782A9 /* metamacros.h in Headers */, + D037655019EDA41200A782A9 /* RACBacktrace.h in Headers */, + D037666B19EDA57100A782A9 /* EXTKeyPathCoding.h in Headers */, + D03765F419EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.h in Headers */, + D03765C419EDA41200A782A9 /* RACScheduler+Subclass.h in Headers */, + D037656E19EDA41200A782A9 /* RACDisposable.h in Headers */, + D03765B019EDA41200A782A9 /* RACQueueScheduler.h in Headers */, + D037652419EDA41200A782A9 /* NSObject+RACPropertySubscribing.h in Headers */, + D037650019EDA41200A782A9 /* NSFileHandle+RACSupport.h in Headers */, + D037653019EDA41200A782A9 /* NSSet+RACSequenceAdditions.h in Headers */, + D037654019EDA41200A782A9 /* NSText+RACSignalSupport.h in Headers */, + D03765E019EDA41200A782A9 /* RACStream.h in Headers */, + D03765FC19EDA41200A782A9 /* RACTargetQueueScheduler.h in Headers */, + D03765B419EDA41200A782A9 /* RACQueueScheduler+Subclass.h in Headers */, + D037661019EDA41200A782A9 /* RACUnit.h in Headers */, + D037656419EDA41200A782A9 /* RACCompoundDisposable.h in Headers */, + D03764F419EDA41200A782A9 /* NSData+RACSupport.h in Headers */, + D03764FC19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.h in Headers */, + D03765CA19EDA41200A782A9 /* RACSequence.h in Headers */, + D037672719EDA63400A782A9 /* RACBehaviorSubject.h in Headers */, + D037653C19EDA41200A782A9 /* NSString+RACSupport.h in Headers */, + D03765CE19EDA41200A782A9 /* RACSerialDisposable.h in Headers */, + D03765D619EDA41200A782A9 /* RACSignal+Operations.h in Headers */, + D03765B619EDA41200A782A9 /* RACReplaySubject.h in Headers */, + D03765A219EDA41200A782A9 /* RACMulticastConnection.h in Headers */, + D037658E19EDA41200A782A9 /* RACGroupedSignal.h in Headers */, + D037654819EDA41200A782A9 /* NSUserDefaults+RACSupport.h in Headers */, + D03765BE19EDA41200A782A9 /* RACScheduler.h in Headers */, + D037656019EDA41200A782A9 /* RACCommand.h in Headers */, + D037660419EDA41200A782A9 /* RACTuple.h in Headers */, + D03765C619EDA41200A782A9 /* RACScopedDisposable.h in Headers */, + D037660019EDA41200A782A9 /* RACTestScheduler.h in Headers */, + D037652C19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.h in Headers */, + D03764F019EDA41200A782A9 /* NSControl+RACTextSignalSupport.h in Headers */, + D03765EA19EDA41200A782A9 /* RACSubject.h in Headers */, + D037652819EDA41200A782A9 /* NSObject+RACSelectorSignal.h in Headers */, + D037654419EDA41200A782A9 /* NSURLConnection+RACSupport.h in Headers */, + D03764E819EDA41200A782A9 /* NSArray+RACSequenceAdditions.h in Headers */, + D037651019EDA41200A782A9 /* NSObject+RACAppKitBindings.h in Headers */, + D037658A19EDA41200A782A9 /* RACEvent.h in Headers */, + D037667119EDA57100A782A9 /* EXTScope.h in Headers */, + D037653819EDA41200A782A9 /* NSString+RACSequenceAdditions.h in Headers */, + D03764F819EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - D047969719666CBF0066B267 /* Headers */ = { + D047260919E49F82006002AA /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - D04798BA196670900066B267 /* RACMulticastConnection+Private.h in Headers */, - D0479906196670900066B267 /* RACSubscriber+Private.h in Headers */, - D0479966196670900066B267 /* UISegmentedControl+RACSignalSupport.h in Headers */, - D0479830196670900066B267 /* NSObject+RACPropertySubscribing.h in Headers */, - D047994E196670900066B267 /* UIControl+RACSignalSupport.h in Headers */, - D04798C4196670900066B267 /* RACQueueScheduler.h in Headers */, - D047995A196670900066B267 /* UIGestureRecognizer+RACSignalSupport.h in Headers */, - D04798AA196670900066B267 /* RACIndexSetSequence.h in Headers */, - D0479920196670900066B267 /* RACUnarySequence.h in Headers */, - D0479886196670900066B267 /* RACDynamicSequence.h in Headers */, - D0479914196670900066B267 /* RACTestScheduler.h in Headers */, - D047994A196670900066B267 /* UICollectionReusableView+RACSignalSupport.h in Headers */, - D0479956196670900066B267 /* UIDatePicker+RACSignalSupport.h in Headers */, - D0479952196670900066B267 /* UIControl+RACSignalSupportPrivate.h in Headers */, - D0479994196671DF0066B267 /* metamacros.h in Headers */, - D04798B6196670900066B267 /* RACMulticastConnection.h in Headers */, - D04798D6196670900066B267 /* RACScheduler+Private.h in Headers */, - D047993E196670900066B267 /* UIAlertView+RACSignalSupport.h in Headers */, - D047990C196670900066B267 /* RACSubscriptionScheduler.h in Headers */, - D04798CA196670900066B267 /* RACReplaySubject.h in Headers */, - D0479882196670900066B267 /* RACDisposable.h in Headers */, - D0479850196670900066B267 /* NSURLConnection+RACSupport.h in Headers */, - D0479816196670900066B267 /* NSNotificationCenter+RACSupport.h in Headers */, - D0479808196670900066B267 /* NSFileHandle+RACSupport.h in Headers */, - D047988A196670900066B267 /* RACDynamicSignal.h in Headers */, - D0479824196670900066B267 /* NSObject+RACDescription.h in Headers */, - D047992C196670900066B267 /* ReactiveCocoa-Bridging-Header.h in Headers */, - D04798AE196670900066B267 /* RACKVOChannel.h in Headers */, - D0479868196670900066B267 /* RACBehaviorSubject.h in Headers */, - D0479942196670900066B267 /* UIBarButtonItem+RACCommandSupport.h in Headers */, - D0479838196670900066B267 /* NSOrderedSet+RACSequenceAdditions.h in Headers */, - D047996E196670900066B267 /* UIStepper+RACSignalSupport.h in Headers */, - D0479800196670900066B267 /* NSDictionary+RACSequenceAdditions.h in Headers */, - D047988E196670900066B267 /* RACEagerSequence.h in Headers */, - D0479804196670900066B267 /* NSEnumerator+RACSequenceAdditions.h in Headers */, - D047982C196670900066B267 /* NSObject+RACLifting.h in Headers */, - D0479992196671DF0066B267 /* EXTScope.h in Headers */, - D0479810196670900066B267 /* NSInvocation+RACTypeParsing.h in Headers */, - D0479878196670900066B267 /* RACCompoundDisposable.h in Headers */, - D0479848196670900066B267 /* NSString+RACSupport.h in Headers */, - D0479918196670900066B267 /* RACTuple.h in Headers */, - D04798C0196670900066B267 /* RACPassthroughSubscriber.h in Headers */, - D047986C196670900066B267 /* RACBlockTrampoline.h in Headers */, - D04797FC196670900066B267 /* NSData+RACSupport.h in Headers */, - D0479844196670900066B267 /* NSString+RACSequenceAdditions.h in Headers */, - D0479820196670900066B267 /* NSObject+RACDeallocating.h in Headers */, - D04798A2196670900066B267 /* RACGroupedSignal.h in Headers */, - D047997A196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.h in Headers */, - D04798B2196670900066B267 /* RACKVOTrampoline.h in Headers */, - D04798D8196670900066B267 /* RACScheduler+Subclass.h in Headers */, - D04798F4196670900066B267 /* RACStream.h in Headers */, - D04798EA196670900066B267 /* RACSignal+Operations.h in Headers */, - D0479828196670900066B267 /* NSObject+RACKVOWrapper.h in Headers */, - D0479864196670900066B267 /* RACBacktrace.h in Headers */, - D04798CE196670900066B267 /* RACReturnSignal.h in Headers */, - D047993A196670900066B267 /* UIActionSheet+RACSignalSupport.h in Headers */, - D0479985196670F50066B267 /* ReactiveCocoa.h in Headers */, - D0479962196670900066B267 /* UIRefreshControl+RACCommandSupport.h in Headers */, - D0479972196670900066B267 /* UISwitch+RACSignalSupport.h in Headers */, - D0479896196670900066B267 /* RACEmptySignal.h in Headers */, - D047991C196670900066B267 /* RACTupleSequence.h in Headers */, - D04798D2196670900066B267 /* RACScheduler.h in Headers */, - D04797F0196670900066B267 /* NSArray+RACSequenceAdditions.h in Headers */, - D04798A6196670900066B267 /* RACImmediateScheduler.h in Headers */, - D0479856196670900066B267 /* NSUserDefaults+RACSupport.h in Headers */, - D0479892196670900066B267 /* RACEmptySequence.h in Headers */, - D047983C196670900066B267 /* NSSet+RACSequenceAdditions.h in Headers */, - D04798DE196670900066B267 /* RACSequence.h in Headers */, - D047989E196670900066B267 /* RACEvent.h in Headers */, - D047998C196671DF0066B267 /* EXTKeyPathCoding.h in Headers */, - D04798E2196670900066B267 /* RACSerialDisposable.h in Headers */, - D047980C196670900066B267 /* NSIndexSet+RACSequenceAdditions.h in Headers */, - D0479982196670900066B267 /* UITextView+RACSignalSupport.h in Headers */, - D047996A196670900066B267 /* UISlider+RACSignalSupport.h in Headers */, - D047998E196671DF0066B267 /* EXTRuntimeExtensions.h in Headers */, - D0479870196670900066B267 /* RACChannel.h in Headers */, - D047995E196670900066B267 /* UIImagePickerController+RACSignalSupport.h in Headers */, - D0479976196670900066B267 /* UITableViewCell+RACSignalSupport.h in Headers */, - D04798C8196670900066B267 /* RACQueueScheduler+Subclass.h in Headers */, - D0479928196670900066B267 /* RACValueTransformer.h in Headers */, - D04798F0196670900066B267 /* RACSignalSequence.h in Headers */, - D04798FA196670900066B267 /* RACStringSequence.h in Headers */, - D047987E196670900066B267 /* RACDelegateProxy.h in Headers */, - D0479834196670900066B267 /* NSObject+RACSelectorSignal.h in Headers */, - D04798E6196670900066B267 /* RACSignal.h in Headers */, - D0479908196670900066B267 /* RACSubscriptingAssignmentTrampoline.h in Headers */, - D047989A196670900066B267 /* RACErrorSignal.h in Headers */, - D047997E196670900066B267 /* UITextField+RACSignalSupport.h in Headers */, - D04798DA196670900066B267 /* RACScopedDisposable.h in Headers */, - D0479924196670900066B267 /* RACUnit.h in Headers */, - D0479910196670900066B267 /* RACTargetQueueScheduler.h in Headers */, - D0479860196670900066B267 /* RACArraySequence.h in Headers */, - D0479840196670900066B267 /* NSString+RACKeyPathUtilities.h in Headers */, - D04798FE196670900066B267 /* RACSubject.h in Headers */, - D0479874196670900066B267 /* RACCommand.h in Headers */, - D04798F8196670900066B267 /* RACStream+Private.h in Headers */, - D0479946196670900066B267 /* UIButton+RACCommandSupport.h in Headers */, - D04798BC196670900066B267 /* RACObjCRuntime.h in Headers */, - D0479902196670900066B267 /* RACSubscriber.h in Headers */, + D037664519EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.h in Headers */, + D037666419EDA43C00A782A9 /* ReactiveCocoa.h in Headers */, + D037652519EDA41200A782A9 /* NSObject+RACPropertySubscribing.h in Headers */, + D03765B119EDA41200A782A9 /* RACQueueScheduler.h in Headers */, + D037662519EDA41200A782A9 /* UIButton+RACCommandSupport.h in Headers */, + D037672819EDA63500A782A9 /* RACBehaviorSubject.h in Headers */, + D037660119EDA41200A782A9 /* RACTestScheduler.h in Headers */, + D03765A319EDA41200A782A9 /* RACMulticastConnection.h in Headers */, + D03765B719EDA41200A782A9 /* RACReplaySubject.h in Headers */, + D037663D19EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.h in Headers */, + D037656F19EDA41200A782A9 /* RACDisposable.h in Headers */, + D037654519EDA41200A782A9 /* NSURLConnection+RACSupport.h in Headers */, + D037661D19EDA41200A782A9 /* UIAlertView+RACSignalSupport.h in Headers */, + D037650D19EDA41200A782A9 /* NSNotificationCenter+RACSupport.h in Headers */, + D037650119EDA41200A782A9 /* NSFileHandle+RACSupport.h in Headers */, + D037666119EDA41200A782A9 /* UITextView+RACSignalSupport.h in Headers */, + D037659B19EDA41200A782A9 /* RACKVOChannel.h in Headers */, + D037652D19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.h in Headers */, + D03764F919EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.h in Headers */, + D037667219EDA57100A782A9 /* EXTScope.h in Headers */, + D037663519EDA41200A782A9 /* UIDatePicker+RACSignalSupport.h in Headers */, + D037667419EDA57100A782A9 /* metamacros.h in Headers */, + D03764FD19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.h in Headers */, + D037652119EDA41200A782A9 /* NSObject+RACLifting.h in Headers */, + D037665919EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.h in Headers */, + D037656519EDA41200A782A9 /* RACCompoundDisposable.h in Headers */, + D037653D19EDA41200A782A9 /* NSString+RACSupport.h in Headers */, + D037662919EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.h in Headers */, + D037660519EDA41200A782A9 /* RACTuple.h in Headers */, + D037665519EDA41200A782A9 /* UITableViewCell+RACSignalSupport.h in Headers */, + D03764F519EDA41200A782A9 /* NSData+RACSupport.h in Headers */, + D037653919EDA41200A782A9 /* NSString+RACSequenceAdditions.h in Headers */, + D037651519EDA41200A782A9 /* NSObject+RACDeallocating.h in Headers */, + D037658F19EDA41200A782A9 /* RACGroupedSignal.h in Headers */, + D03765C519EDA41200A782A9 /* RACScheduler+Subclass.h in Headers */, + D03765E119EDA41200A782A9 /* RACStream.h in Headers */, + D03765D719EDA41200A782A9 /* RACSignal+Operations.h in Headers */, + D037655119EDA41200A782A9 /* RACBacktrace.h in Headers */, + D037665D19EDA41200A782A9 /* UITextField+RACSignalSupport.h in Headers */, + D037664919EDA41200A782A9 /* UISlider+RACSignalSupport.h in Headers */, + D03765BF19EDA41200A782A9 /* RACScheduler.h in Headers */, + D03764E919EDA41200A782A9 /* NSArray+RACSequenceAdditions.h in Headers */, + D037654919EDA41200A782A9 /* NSUserDefaults+RACSupport.h in Headers */, + D037663919EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.h in Headers */, + D037653119EDA41200A782A9 /* NSSet+RACSequenceAdditions.h in Headers */, + D03765CB19EDA41200A782A9 /* RACSequence.h in Headers */, + D037662D19EDA41200A782A9 /* UIControl+RACSignalSupport.h in Headers */, + D037666C19EDA57100A782A9 /* EXTKeyPathCoding.h in Headers */, + D037658B19EDA41200A782A9 /* RACEvent.h in Headers */, + D03765CF19EDA41200A782A9 /* RACSerialDisposable.h in Headers */, + D037650519EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.h in Headers */, + D037655D19EDA41200A782A9 /* RACChannel.h in Headers */, + D03765B519EDA41200A782A9 /* RACQueueScheduler+Subclass.h in Headers */, + D037665119EDA41200A782A9 /* UISwitch+RACSignalSupport.h in Headers */, + D037664119EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.h in Headers */, + D037652919EDA41200A782A9 /* NSObject+RACSelectorSignal.h in Headers */, + D03765D319EDA41200A782A9 /* RACSignal.h in Headers */, + D03765F519EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.h in Headers */, + D03765C719EDA41200A782A9 /* RACScopedDisposable.h in Headers */, + D037661119EDA41200A782A9 /* RACUnit.h in Headers */, + D03765FD19EDA41200A782A9 /* RACTargetQueueScheduler.h in Headers */, + D037661919EDA41200A782A9 /* UIActionSheet+RACSignalSupport.h in Headers */, + D037664D19EDA41200A782A9 /* UIStepper+RACSignalSupport.h in Headers */, + D037662119EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.h in Headers */, + D03765EB19EDA41200A782A9 /* RACSubject.h in Headers */, + D037656119EDA41200A782A9 /* RACCommand.h in Headers */, + D03765EF19EDA41200A782A9 /* RACSubscriber.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - D047967219666BF30066B267 /* ReactiveCocoa-Mac */ = { + D04725E919E49ED7006002AA /* ReactiveCocoa-Mac */ = { isa = PBXNativeTarget; - buildConfigurationList = D047968919666BF30066B267 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-Mac" */; + buildConfigurationList = D047260019E49ED7006002AA /* Build configuration list for PBXNativeTarget "ReactiveCocoa-Mac" */; buildPhases = ( - D047966E19666BF30066B267 /* Sources */, - D047966F19666BF30066B267 /* Frameworks */, - D047967019666BF30066B267 /* Headers */, - D047967119666BF30066B267 /* Resources */, + D04725E519E49ED7006002AA /* Sources */, + D04725E619E49ED7006002AA /* Frameworks */, + D04725E719E49ED7006002AA /* Headers */, + D04725E819E49ED7006002AA /* Resources */, ); buildRules = ( ); @@ -1514,46 +1427,35 @@ ); name = "ReactiveCocoa-Mac"; productName = ReactiveCocoa; - productReference = D047967319666BF30066B267 /* ReactiveCocoa.framework */; + productReference = D04725EA19E49ED7006002AA /* ReactiveCocoa.framework */; productType = "com.apple.product-type.framework"; }; - D047967D19666BF30066B267 /* ReactiveCocoa-MacTests */ = { + D04725F419E49ED7006002AA /* ReactiveCocoa-MacTests */ = { isa = PBXNativeTarget; - buildConfigurationList = D047968C19666BF30066B267 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-MacTests" */; + buildConfigurationList = D047260319E49ED7006002AA /* Build configuration list for PBXNativeTarget "ReactiveCocoa-MacTests" */; buildPhases = ( - D047967A19666BF30066B267 /* Sources */, - D047967B19666BF30066B267 /* Frameworks */, - D047967C19666BF30066B267 /* Resources */, + D04725F119E49ED7006002AA /* Sources */, + D04725F219E49ED7006002AA /* Frameworks */, + D04725F319E49ED7006002AA /* Resources */, ); buildRules = ( ); dependencies = ( - D047968119666BF30066B267 /* PBXTargetDependency */, - D047969019666CA70066B267 /* PBXTargetDependency */, - D047969219666CA70066B267 /* PBXTargetDependency */, - D047969419666CAD0066B267 /* PBXTargetDependency */, - D04796D219666CD00066B267 /* PBXTargetDependency */, - D04796D419666CD20066B267 /* PBXTargetDependency */, - D04796EE19666D6C0066B267 /* PBXTargetDependency */, - D04796F819666F1D0066B267 /* PBXTargetDependency */, - D04799A219667AF80066B267 /* PBXTargetDependency */, - D04799A419667CAD0066B267 /* PBXTargetDependency */, - D04799A619667E580066B267 /* PBXTargetDependency */, - D04799AA19667E620066B267 /* PBXTargetDependency */, + D04725F819E49ED7006002AA /* PBXTargetDependency */, ); name = "ReactiveCocoa-MacTests"; productName = ReactiveCocoaTests; - productReference = D047967E19666BF30066B267 /* ReactiveCocoa-MacTests.xctest */; + productReference = D04725F519E49ED7006002AA /* ReactiveCocoa-MacTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - D047969919666CBF0066B267 /* ReactiveCocoa-iOS */ = { + D047260B19E49F82006002AA /* ReactiveCocoa-iOS */ = { isa = PBXNativeTarget; - buildConfigurationList = D04796AD19666CBF0066B267 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-iOS" */; + buildConfigurationList = D047261F19E49F82006002AA /* Build configuration list for PBXNativeTarget "ReactiveCocoa-iOS" */; buildPhases = ( - D047969519666CBF0066B267 /* Sources */, - D047969619666CBF0066B267 /* Frameworks */, - D047969719666CBF0066B267 /* Headers */, - D047969819666CBF0066B267 /* Resources */, + D047260719E49F82006002AA /* Sources */, + D047260819E49F82006002AA /* Frameworks */, + D047260919E49F82006002AA /* Headers */, + D047260A19E49F82006002AA /* Resources */, ); buildRules = ( ); @@ -1561,532 +1463,453 @@ ); name = "ReactiveCocoa-iOS"; productName = ReactiveCocoa; - productReference = D047969A19666CBF0066B267 /* ReactiveCocoa.framework */; + productReference = D047260C19E49F82006002AA /* ReactiveCocoa.framework */; productType = "com.apple.product-type.framework"; }; - D04796A319666CBF0066B267 /* ReactiveCocoa-iOSTests */ = { + D047261519E49F82006002AA /* ReactiveCocoa-iOSTests */ = { isa = PBXNativeTarget; - buildConfigurationList = D04796B019666CBF0066B267 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-iOSTests" */; + buildConfigurationList = D047262219E49F82006002AA /* Build configuration list for PBXNativeTarget "ReactiveCocoa-iOSTests" */; buildPhases = ( - D04796A019666CBF0066B267 /* Sources */, - D04796A119666CBF0066B267 /* Frameworks */, - D04796A219666CBF0066B267 /* Resources */, + D047261219E49F82006002AA /* Sources */, + D047261319E49F82006002AA /* Frameworks */, + D047261419E49F82006002AA /* Resources */, + D01B7B6119EDD8F600D26E01 /* Copy Frameworks */, ); buildRules = ( ); dependencies = ( - D04796A719666CBF0066B267 /* PBXTargetDependency */, - D04796B419666CC00066B267 /* PBXTargetDependency */, - D04796B619666CC00066B267 /* PBXTargetDependency */, - D04796B819666CC00066B267 /* PBXTargetDependency */, - D04796BA19666CC00066B267 /* PBXTargetDependency */, - D04796BC19666CC00066B267 /* PBXTargetDependency */, - D04796BE19666CC00066B267 /* PBXTargetDependency */, - D04796C019666CC00066B267 /* PBXTargetDependency */, - D04796C219666CC00066B267 /* PBXTargetDependency */, - D04796C419666CC00066B267 /* PBXTargetDependency */, - D04796C619666CC00066B267 /* PBXTargetDependency */, - D04796C819666CC00066B267 /* PBXTargetDependency */, - D04796CA19666CC00066B267 /* PBXTargetDependency */, - D04796CC19666CC00066B267 /* PBXTargetDependency */, - D04796CE19666CC00066B267 /* PBXTargetDependency */, - D04796D019666CCB0066B267 /* PBXTargetDependency */, - D04796F019666DB60066B267 /* PBXTargetDependency */, - D04796FA19666F1F0066B267 /* PBXTargetDependency */, - D04799A819667E5D0066B267 /* PBXTargetDependency */, - D04799AC19667E740066B267 /* PBXTargetDependency */, + D047261919E49F82006002AA /* PBXTargetDependency */, ); name = "ReactiveCocoa-iOSTests"; productName = ReactiveCocoaTests; - productReference = D04796A419666CBF0066B267 /* ReactiveCocoa-iOSTests.xctest */; + productReference = D047261619E49F82006002AA /* ReactiveCocoa-iOSTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ - D047966A19666BF30066B267 /* Project object */ = { + D04725E119E49ED7006002AA /* Project object */ = { isa = PBXProject; attributes = { LastUpgradeCheck = 0610; ORGANIZATIONNAME = GitHub; TargetAttributes = { - D047967219666BF30066B267 = { - CreatedOnToolsVersion = 6.0; + D04725E919E49ED7006002AA = { + CreatedOnToolsVersion = 6.1; }; - D047967D19666BF30066B267 = { - CreatedOnToolsVersion = 6.0; - TestTargetID = D047967219666BF30066B267; + D04725F419E49ED7006002AA = { + CreatedOnToolsVersion = 6.1; }; - D047969919666CBF0066B267 = { - CreatedOnToolsVersion = 6.0; + D047260B19E49F82006002AA = { + CreatedOnToolsVersion = 6.1; }; - D04796A319666CBF0066B267 = { - CreatedOnToolsVersion = 6.0; - TestTargetID = D047969919666CBF0066B267; + D047261519E49F82006002AA = { + CreatedOnToolsVersion = 6.1; }; }; }; - buildConfigurationList = D047966D19666BF30066B267 /* Build configuration list for PBXProject "ReactiveCocoa" */; + buildConfigurationList = D04725E419E49ED7006002AA /* Build configuration list for PBXProject "ReactiveCocoa" */; compatibilityVersion = "Xcode 3.2"; developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( en, ); - mainGroup = D047966919666BF30066B267; - productRefGroup = D047967419666BF30066B267 /* Products */; + mainGroup = D04725E019E49ED7006002AA; + productRefGroup = D04725EB19E49ED7006002AA /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - D047967219666BF30066B267 /* ReactiveCocoa-Mac */, - D047967D19666BF30066B267 /* ReactiveCocoa-MacTests */, - D047969919666CBF0066B267 /* ReactiveCocoa-iOS */, - D04796A319666CBF0066B267 /* ReactiveCocoa-iOSTests */, + D04725E919E49ED7006002AA /* ReactiveCocoa-Mac */, + D04725F419E49ED7006002AA /* ReactiveCocoa-MacTests */, + D047260B19E49F82006002AA /* ReactiveCocoa-iOS */, + D047261519E49F82006002AA /* ReactiveCocoa-iOSTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - D047967119666BF30066B267 /* Resources */ = { + D04725E819E49ED7006002AA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - D047967C19666BF30066B267 /* Resources */ = { + D04725F319E49ED7006002AA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + D037671719EDA60000A782A9 /* test-data.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - D047969819666CBF0066B267 /* Resources */ = { + D047260A19E49F82006002AA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - D04796A219666CBF0066B267 /* Resources */ = { + D047261419E49F82006002AA /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + D037671819EDA60000A782A9 /* test-data.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - D047966E19666BF30066B267 /* Sources */ = { + D04725E519E49ED7006002AA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D036AA4B196FB7CB00B49B76 /* Bag.swift in Sources */, - D04798AF196670900066B267 /* RACKVOChannel.m in Sources */, - D0479897196670900066B267 /* RACEmptySignal.m in Sources */, - D04798DB196670900066B267 /* RACScopedDisposable.m in Sources */, - D0479801196670900066B267 /* NSDictionary+RACSequenceAdditions.m in Sources */, - D0479903196670900066B267 /* RACSubscriber.m in Sources */, - D04798BD196670900066B267 /* RACObjCRuntime.m in Sources */, - D04798A7196670900066B267 /* RACImmediateScheduler.m in Sources */, - D04798AB196670900066B267 /* RACIndexSetSequence.m in Sources */, - D0479831196670900066B267 /* NSObject+RACPropertySubscribing.m in Sources */, - D0479879196670900066B267 /* RACCompoundDisposable.m in Sources */, - D04797EB196670900066B267 /* Event.swift in Sources */, - D0479883196670900066B267 /* RACDisposable.m in Sources */, - D047989F196670900066B267 /* RACEvent.m in Sources */, - D0479911196670900066B267 /* RACTargetQueueScheduler.m in Sources */, - D047986D196670900066B267 /* RACBlockTrampoline.m in Sources */, - D04798DF196670900066B267 /* RACSequence.m in Sources */, - D04797DD196670900066B267 /* Action.swift in Sources */, - D04797F9196670900066B267 /* NSControl+RACTextSignalSupport.m in Sources */, - D04798CB196670900066B267 /* RACReplaySubject.m in Sources */, - D047988B196670900066B267 /* RACDynamicSignal.m in Sources */, - D0479893196670900066B267 /* RACEmptySequence.m in Sources */, - D047988F196670900066B267 /* RACEagerSequence.m in Sources */, - D0479935196670900066B267 /* SignalingProperty.swift in Sources */, - D0E3CF551973AFC7004FD181 /* Errors.swift in Sources */, - D047985D196670900066B267 /* Promise.swift in Sources */, - D0479805196670900066B267 /* NSEnumerator+RACSequenceAdditions.m in Sources */, - D0479925196670900066B267 /* RACUnit.m in Sources */, - D047984D196670900066B267 /* NSText+RACSignalSupport.m in Sources */, - D0479909196670900066B267 /* RACSubscriptingAssignmentTrampoline.m in Sources */, - D047989B196670900066B267 /* RACErrorSignal.m in Sources */, - D04797F5196670900066B267 /* NSControl+RACCommandSupport.m in Sources */, - D0479811196670900066B267 /* NSInvocation+RACTypeParsing.m in Sources */, - D04798FB196670900066B267 /* RACStringSequence.m in Sources */, - D0479825196670900066B267 /* NSObject+RACDescription.m in Sources */, - D04798C5196670900066B267 /* RACQueueScheduler.m in Sources */, - D0479875196670900066B267 /* RACCommand.m in Sources */, - D04798F1196670900066B267 /* RACSignalSequence.m in Sources */, - D0479845196670900066B267 /* NSString+RACSequenceAdditions.m in Sources */, - D04798B3196670900066B267 /* RACKVOTrampoline.m in Sources */, - D0479821196670900066B267 /* NSObject+RACDeallocating.m in Sources */, - D047985B196670900066B267 /* Producer.swift in Sources */, - D0479921196670900066B267 /* RACUnarySequence.m in Sources */, - D0479853196670900066B267 /* NSURLSessionExtensions.swift in Sources */, - D047987F196670900066B267 /* RACDelegateProxy.m in Sources */, - D04798CF196670900066B267 /* RACReturnSignal.m in Sources */, - D04798B7196670900066B267 /* RACMulticastConnection.m in Sources */, - D0479819196670900066B267 /* NSNotificationCenterExtensions.swift in Sources */, - D0479871196670900066B267 /* RACChannel.m in Sources */, - D0479849196670900066B267 /* NSString+RACSupport.m in Sources */, - D0479841196670900066B267 /* NSString+RACKeyPathUtilities.m in Sources */, - D04798E3196670900066B267 /* RACSerialDisposable.m in Sources */, - D04798D3196670900066B267 /* RACScheduler.m in Sources */, - D0479887196670900066B267 /* RACDynamicSequence.m in Sources */, - D04798F5196670900066B267 /* RACStream.m in Sources */, - D04797E7196670900066B267 /* Consumer.swift in Sources */, - D04797F1196670900066B267 /* NSArray+RACSequenceAdditions.m in Sources */, - D047982D196670900066B267 /* NSObject+RACLifting.m in Sources */, - D04798E7196670900066B267 /* RACSignal.m in Sources */, - D047980D196670900066B267 /* NSIndexSet+RACSequenceAdditions.m in Sources */, - D04798FF196670900066B267 /* RACSubject.m in Sources */, - D047990D196670900066B267 /* RACSubscriptionScheduler.m in Sources */, - D0479929196670900066B267 /* RACValueTransformer.m in Sources */, - D0479835196670900066B267 /* NSObject+RACSelectorSignal.m in Sources */, - D04797FD196670900066B267 /* NSData+RACSupport.m in Sources */, - D04797E1196670900066B267 /* Atomic.swift in Sources */, - D04797E9196670900066B267 /* Disposable.swift in Sources */, - D0297D3619D67D42009986A9 /* Identity.swift in Sources */, - D047983D196670900066B267 /* NSSet+RACSequenceAdditions.m in Sources */, - D0479915196670900066B267 /* RACTestScheduler.m in Sources */, - D0479865196670900066B267 /* RACBacktrace.m in Sources */, - D0479829196670900066B267 /* NSObject+RACKVOWrapper.m in Sources */, - D0479839196670900066B267 /* NSOrderedSet+RACSequenceAdditions.m in Sources */, - D0479869196670900066B267 /* RACBehaviorSubject.m in Sources */, - D04798ED196670900066B267 /* RACSignalProvider.d in Sources */, - D0479861196670900066B267 /* RACArraySequence.m in Sources */, - D0479933196670900066B267 /* Signal.swift in Sources */, - D0479851196670900066B267 /* NSURLConnection+RACSupport.m in Sources */, - D0479931196670900066B267 /* Scheduler.swift in Sources */, - D0479857196670900066B267 /* NSUserDefaults+RACSupport.m in Sources */, - D0479859196670900066B267 /* ObjectiveCBridging.swift in Sources */, - D02C14B1197243CB007127D4 /* OptionalExtensions.swift in Sources */, - D0479817196670900066B267 /* NSNotificationCenter+RACSupport.m in Sources */, - D04798A3196670900066B267 /* RACGroupedSignal.m in Sources */, - D047991D196670900066B267 /* RACTupleSequence.m in Sources */, - D047998F196671DF0066B267 /* EXTRuntimeExtensions.m in Sources */, - D04798EB196670900066B267 /* RACSignal+Operations.m in Sources */, - D047981D196670900066B267 /* NSObject+RACAppKitBindings.m in Sources */, - D047987B196670900066B267 /* RACCompoundDisposableProvider.d in Sources */, - D0479809196670900066B267 /* NSFileHandle+RACSupport.m in Sources */, - D04798C1196670900066B267 /* RACPassthroughSubscriber.m in Sources */, - D0479919196670900066B267 /* RACTuple.m in Sources */, + D037654219EDA41200A782A9 /* NSText+RACSignalSupport.m in Sources */, + D0C312CB19EF2A5800984962 /* Action.swift in Sources */, + D037659C19EDA41200A782A9 /* RACKVOChannel.m in Sources */, + D0C312D919EF2A5800984962 /* Identity.swift in Sources */, + D03765C819EDA41200A782A9 /* RACScopedDisposable.m in Sources */, + D03764FE19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m in Sources */, + D03764EA19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m in Sources */, + D0C312E119EF2A5800984962 /* OptionalExtensions.swift in Sources */, + D03765C019EDA41200A782A9 /* RACScheduler.m in Sources */, + D0C312D519EF2A5800984962 /* Errors.swift in Sources */, + D037659819EDA41200A782A9 /* RACIndexSetSequence.m in Sources */, + D03765D819EDA41200A782A9 /* RACSignal+Operations.m in Sources */, + D03764F219EDA41200A782A9 /* NSControl+RACTextSignalSupport.m in Sources */, + D037650219EDA41200A782A9 /* NSFileHandle+RACSupport.m in Sources */, + D03765E219EDA41200A782A9 /* RACStream.m in Sources */, + D037655619EDA41200A782A9 /* RACBehaviorSubject.m in Sources */, + D037660219EDA41200A782A9 /* RACTestScheduler.m in Sources */, + D03765B819EDA41200A782A9 /* RACReplaySubject.m in Sources */, + D03765EC19EDA41200A782A9 /* RACSubject.m in Sources */, + D03765D019EDA41200A782A9 /* RACSerialDisposable.m in Sources */, + D0C312DD19EF2A5800984962 /* NSURLSessionExtensions.swift in Sources */, + D0C312D319EF2A5800984962 /* Disposable.swift in Sources */, + D037666F19EDA57100A782A9 /* EXTRuntimeExtensions.m in Sources */, + D037653E19EDA41200A782A9 /* NSString+RACSupport.m in Sources */, + D037653619EDA41200A782A9 /* NSString+RACKeyPathUtilities.m in Sources */, + D03764FA19EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.m in Sources */, + D037656819EDA41200A782A9 /* RACCompoundDisposableProvider.d in Sources */, + D037653A19EDA41200A782A9 /* NSString+RACSequenceAdditions.m in Sources */, + D0C312D119EF2A5800984962 /* Consumer.swift in Sources */, + D03765E819EDA41200A782A9 /* RACStringSequence.m in Sources */, + D03764EE19EDA41200A782A9 /* NSControl+RACCommandSupport.m in Sources */, + D037660A19EDA41200A782A9 /* RACTupleSequence.m in Sources */, + D03765D419EDA41200A782A9 /* RACSignal.m in Sources */, + D037651A19EDA41200A782A9 /* NSObject+RACDescription.m in Sources */, + D03765A419EDA41200A782A9 /* RACMulticastConnection.m in Sources */, + D037654E19EDA41200A782A9 /* RACArraySequence.m in Sources */, + D037652219EDA41200A782A9 /* NSObject+RACLifting.m in Sources */, + D037650619EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.m in Sources */, + D037650E19EDA41200A782A9 /* NSNotificationCenter+RACSupport.m in Sources */, + D03765FA19EDA41200A782A9 /* RACSubscriptionScheduler.m in Sources */, + D0C312CF19EF2A5800984962 /* Bag.swift in Sources */, + D037658019EDA41200A782A9 /* RACEmptySequence.m in Sources */, + D03765AA19EDA41200A782A9 /* RACObjCRuntime.m in Sources */, + D037654A19EDA41200A782A9 /* NSUserDefaults+RACSupport.m in Sources */, + D037660E19EDA41200A782A9 /* RACUnarySequence.m in Sources */, + D03765FE19EDA41200A782A9 /* RACTargetQueueScheduler.m in Sources */, + D03765DE19EDA41200A782A9 /* RACSignalSequence.m in Sources */, + D037656C19EDA41200A782A9 /* RACDelegateProxy.m in Sources */, + D037657419EDA41200A782A9 /* RACDynamicSequence.m in Sources */, + D037657019EDA41200A782A9 /* RACDisposable.m in Sources */, + D03765DA19EDA41200A782A9 /* RACSignalProvider.d in Sources */, + D037653219EDA41200A782A9 /* NSSet+RACSequenceAdditions.m in Sources */, + D037651219EDA41200A782A9 /* NSObject+RACAppKitBindings.m in Sources */, + D037656619EDA41200A782A9 /* RACCompoundDisposable.m in Sources */, + D0C312DB19EF2A5800984962 /* NSNotificationCenterExtensions.swift in Sources */, + D037655A19EDA41200A782A9 /* RACBlockTrampoline.m in Sources */, + D0C312DF19EF2A5800984962 /* ObjectiveCBridging.swift in Sources */, + D037659019EDA41200A782A9 /* RACGroupedSignal.m in Sources */, + D037655E19EDA41200A782A9 /* RACChannel.m in Sources */, + D037657C19EDA41200A782A9 /* RACEagerSequence.m in Sources */, + D037657819EDA41200A782A9 /* RACDynamicSignal.m in Sources */, + D037659419EDA41200A782A9 /* RACImmediateScheduler.m in Sources */, + D037651619EDA41200A782A9 /* NSObject+RACDeallocating.m in Sources */, + D0C312E719EF2A5800984962 /* Scheduler.swift in Sources */, + D0C312CD19EF2A5800984962 /* Atomic.swift in Sources */, + D037658419EDA41200A782A9 /* RACEmptySignal.m in Sources */, + D0C312E519EF2A5800984962 /* Promise.swift in Sources */, + D037654619EDA41200A782A9 /* NSURLConnection+RACSupport.m in Sources */, + D03765F019EDA41200A782A9 /* RACSubscriber.m in Sources */, + D03764F619EDA41200A782A9 /* NSData+RACSupport.m in Sources */, + D037656219EDA41200A782A9 /* RACCommand.m in Sources */, + D0C312E919EF2A5800984962 /* Signal.swift in Sources */, + D0C312E319EF2A5800984962 /* Producer.swift in Sources */, + D037658819EDA41200A782A9 /* RACErrorSignal.m in Sources */, + D03765F619EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.m in Sources */, + D0C312EB19EF2A5800984962 /* SignalingProperty.swift in Sources */, + D037661219EDA41200A782A9 /* RACUnit.m in Sources */, + D03765A019EDA41200A782A9 /* RACKVOTrampoline.m in Sources */, + D037650A19EDA41200A782A9 /* NSInvocation+RACTypeParsing.m in Sources */, + D037660619EDA41200A782A9 /* RACTuple.m in Sources */, + D0C312D719EF2A5800984962 /* Event.swift in Sources */, + D037651E19EDA41200A782A9 /* NSObject+RACKVOWrapper.m in Sources */, + D037661619EDA41200A782A9 /* RACValueTransformer.m in Sources */, + D03765CC19EDA41200A782A9 /* RACSequence.m in Sources */, + D037652E19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.m in Sources */, + D037652619EDA41200A782A9 /* NSObject+RACPropertySubscribing.m in Sources */, + D037658C19EDA41200A782A9 /* RACEvent.m in Sources */, + D03765B219EDA41200A782A9 /* RACQueueScheduler.m in Sources */, + D037655219EDA41200A782A9 /* RACBacktrace.m in Sources */, + D037652A19EDA41200A782A9 /* NSObject+RACSelectorSignal.m in Sources */, + D03765AE19EDA41200A782A9 /* RACPassthroughSubscriber.m in Sources */, + D03765BC19EDA41200A782A9 /* RACReturnSignal.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - D047967A19666BF30066B267 /* Sources */ = { + D04725F119E49ED7006002AA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D011F1F319DD13F600A6F6C8 /* SignalSpec.swift in Sources */, - D095745E197344E3002D44C1 /* DisposableSpec.swift in Sources */, - D09574611973506C002D44C1 /* SchedulerSpec.swift in Sources */, - D047999F196678F20066B267 /* ObjectiveCBridgingSpec.swift in Sources */, + D03766C719EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.m in Sources */, + D03766E319EDA60000A782A9 /* RACDelegateProxySpec.m in Sources */, + D03766F919EDA60000A782A9 /* RACSerialDisposableSpec.m in Sources */, + D037670B19EDA60000A782A9 /* RACTargetQueueSchedulerSpec.m in Sources */, + D03766DD19EDA60000A782A9 /* RACCommandSpec.m in Sources */, + D0C3130E19EF2B1F00984962 /* SchedulerSpec.swift in Sources */, + D037670919EDA60000A782A9 /* RACSubscriptingAssignmentTrampolineSpec.m in Sources */, + D03766EB19EDA60000A782A9 /* RACKVOWrapperSpec.m in Sources */, + D03766E719EDA60000A782A9 /* RACEventSpec.m in Sources */, + D03766F719EDA60000A782A9 /* RACSequenceSpec.m in Sources */, + D03766C919EDA60000A782A9 /* NSObjectRACPropertySubscribingSpec.m in Sources */, + D03766C319EDA60000A782A9 /* NSObjectRACDeallocatingSpec.m in Sources */, + D03766BD19EDA60000A782A9 /* NSEnumeratorRACSequenceAdditionsSpec.m in Sources */, + D037670119EDA60000A782A9 /* RACSubclassObject.m in Sources */, + D03766CD19EDA60000A782A9 /* NSStringRACKeyPathUtilitiesSpec.m in Sources */, + D037671519EDA60000A782A9 /* RACTupleSpec.m in Sources */, + D03766C519EDA60000A782A9 /* NSObjectRACLiftingSpec.m in Sources */, + D03766D119EDA60000A782A9 /* NSURLConnectionRACSupportSpec.m in Sources */, + D03766F319EDA60000A782A9 /* RACSequenceAdditionsSpec.m in Sources */, + D037670D19EDA60000A782A9 /* RACTestExampleScheduler.m in Sources */, + D03766ED19EDA60000A782A9 /* RACMulticastConnectionSpec.m in Sources */, + D0C3130F19EF2B1F00984962 /* SignalSpec.swift in Sources */, + D03766E919EDA60000A782A9 /* RACKVOChannelSpec.m in Sources */, + D03766FB19EDA60000A782A9 /* RACSignalSpec.m in Sources */, + D037670719EDA60000A782A9 /* RACSubscriberSpec.m in Sources */, + D03766EF19EDA60000A782A9 /* RACPropertySignalExamples.m in Sources */, + D03766D519EDA60000A782A9 /* RACBacktraceSpec.m in Sources */, + D037670519EDA60000A782A9 /* RACSubscriberExamples.m in Sources */, + D0C3130C19EF2B1F00984962 /* DisposableSpec.swift in Sources */, + D03766D719EDA60000A782A9 /* RACBlockTrampolineSpec.m in Sources */, + D03766FF19EDA60000A782A9 /* RACStreamExamples.m in Sources */, + D03766CB19EDA60000A782A9 /* NSObjectRACSelectorSignalSpec.m in Sources */, + D037673919EDCA0E00A782A9 /* SwiftSpec.swift in Sources */, + D03766E119EDA60000A782A9 /* RACControlCommandExamples.m in Sources */, + D03766BF19EDA60000A782A9 /* NSNotificationCenterRACSupportSpec.m in Sources */, + D037670319EDA60000A782A9 /* RACSubjectSpec.m in Sources */, + D03766F119EDA60000A782A9 /* RACSchedulerSpec.m in Sources */, + D03766DF19EDA60000A782A9 /* RACCompoundDisposableSpec.m in Sources */, + D03766E519EDA60000A782A9 /* RACDisposableSpec.m in Sources */, + D0C3130D19EF2B1F00984962 /* ObjectiveCBridgingSpec.swift in Sources */, + D03766D319EDA60000A782A9 /* NSUserDefaultsRACSupportSpec.m in Sources */, + D037671119EDA60000A782A9 /* RACTestSchedulerSpec.m in Sources */, + D03766C119EDA60000A782A9 /* NSObjectRACAppKitBindingsSpec.m in Sources */, + D03766DB19EDA60000A782A9 /* RACChannelSpec.m in Sources */, + D03766D919EDA60000A782A9 /* RACChannelExamples.m in Sources */, + D03766F519EDA60000A782A9 /* RACSequenceExamples.m in Sources */, + D03766B919EDA60000A782A9 /* NSControllerRACSupportSpec.m in Sources */, + D037670F19EDA60000A782A9 /* RACTestObject.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - D047969519666CBF0066B267 /* Sources */ = { + D047260719E49F82006002AA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D0479984196670900066B267 /* UITextView+RACSignalSupport.m in Sources */, - D04798B0196670900066B267 /* RACKVOChannel.m in Sources */, - D0479898196670900066B267 /* RACEmptySignal.m in Sources */, - D0479950196670900066B267 /* UIControl+RACSignalSupport.m in Sources */, - D0479954196670900066B267 /* UIControl+RACSignalSupportPrivate.m in Sources */, - D0479960196670900066B267 /* UIImagePickerController+RACSignalSupport.m in Sources */, - D047996C196670900066B267 /* UISlider+RACSignalSupport.m in Sources */, - D04798DC196670900066B267 /* RACScopedDisposable.m in Sources */, - D0479802196670900066B267 /* NSDictionary+RACSequenceAdditions.m in Sources */, - D0479904196670900066B267 /* RACSubscriber.m in Sources */, - D04798BE196670900066B267 /* RACObjCRuntime.m in Sources */, - D0479940196670900066B267 /* UIAlertView+RACSignalSupport.m in Sources */, - D04798A8196670900066B267 /* RACImmediateScheduler.m in Sources */, - D0479970196670900066B267 /* UIStepper+RACSignalSupport.m in Sources */, - D04798AC196670900066B267 /* RACIndexSetSequence.m in Sources */, - D0479832196670900066B267 /* NSObject+RACPropertySubscribing.m in Sources */, - D047987A196670900066B267 /* RACCompoundDisposable.m in Sources */, - D04797EC196670900066B267 /* Event.swift in Sources */, - D0479884196670900066B267 /* RACDisposable.m in Sources */, - D04798A0196670900066B267 /* RACEvent.m in Sources */, - D0479912196670900066B267 /* RACTargetQueueScheduler.m in Sources */, - D047986E196670900066B267 /* RACBlockTrampoline.m in Sources */, - D04798E0196670900066B267 /* RACSequence.m in Sources */, - D0479990196671DF0066B267 /* EXTRuntimeExtensions.m in Sources */, - D04797DE196670900066B267 /* Action.swift in Sources */, - D047997C196670900066B267 /* UITableViewHeaderFooterView+RACSignalSupport.m in Sources */, - D04798CC196670900066B267 /* RACReplaySubject.m in Sources */, - D0479958196670900066B267 /* UIDatePicker+RACSignalSupport.m in Sources */, - D047988C196670900066B267 /* RACDynamicSignal.m in Sources */, - D0479894196670900066B267 /* RACEmptySequence.m in Sources */, - D0479890196670900066B267 /* RACEagerSequence.m in Sources */, - D0479936196670900066B267 /* SignalingProperty.swift in Sources */, - D047985E196670900066B267 /* Promise.swift in Sources */, - D0479806196670900066B267 /* NSEnumerator+RACSequenceAdditions.m in Sources */, - D047994C196670900066B267 /* UICollectionReusableView+RACSignalSupport.m in Sources */, - D0479926196670900066B267 /* RACUnit.m in Sources */, - D047990A196670900066B267 /* RACSubscriptingAssignmentTrampoline.m in Sources */, - D047989C196670900066B267 /* RACErrorSignal.m in Sources */, - D0479812196670900066B267 /* NSInvocation+RACTypeParsing.m in Sources */, - D04798FC196670900066B267 /* RACStringSequence.m in Sources */, - D0479826196670900066B267 /* NSObject+RACDescription.m in Sources */, - D0479968196670900066B267 /* UISegmentedControl+RACSignalSupport.m in Sources */, - D04798C6196670900066B267 /* RACQueueScheduler.m in Sources */, - D047995C196670900066B267 /* UIGestureRecognizer+RACSignalSupport.m in Sources */, - D0479876196670900066B267 /* RACCommand.m in Sources */, - D04798F2196670900066B267 /* RACSignalSequence.m in Sources */, - D0479948196670900066B267 /* UIButton+RACCommandSupport.m in Sources */, - D0479846196670900066B267 /* NSString+RACSequenceAdditions.m in Sources */, - D04798B4196670900066B267 /* RACKVOTrampoline.m in Sources */, - D0479822196670900066B267 /* NSObject+RACDeallocating.m in Sources */, - D047985C196670900066B267 /* Producer.swift in Sources */, - D0479922196670900066B267 /* RACUnarySequence.m in Sources */, - D0479854196670900066B267 /* NSURLSessionExtensions.swift in Sources */, - D0479880196670900066B267 /* RACDelegateProxy.m in Sources */, - D04798D0196670900066B267 /* RACReturnSignal.m in Sources */, - D0479980196670900066B267 /* UITextField+RACSignalSupport.m in Sources */, - D04798B8196670900066B267 /* RACMulticastConnection.m in Sources */, - D047981A196670900066B267 /* NSNotificationCenterExtensions.swift in Sources */, - D0479872196670900066B267 /* RACChannel.m in Sources */, - D047984A196670900066B267 /* NSString+RACSupport.m in Sources */, - D0479842196670900066B267 /* NSString+RACKeyPathUtilities.m in Sources */, - D047993C196670900066B267 /* UIActionSheet+RACSignalSupport.m in Sources */, - D0479964196670900066B267 /* UIRefreshControl+RACCommandSupport.m in Sources */, - D04798E4196670900066B267 /* RACSerialDisposable.m in Sources */, - D0297D3719D67D42009986A9 /* Identity.swift in Sources */, - D04798D4196670900066B267 /* RACScheduler.m in Sources */, - D0479888196670900066B267 /* RACDynamicSequence.m in Sources */, - D04798F6196670900066B267 /* RACStream.m in Sources */, - D04797E8196670900066B267 /* Consumer.swift in Sources */, - D04797F2196670900066B267 /* NSArray+RACSequenceAdditions.m in Sources */, - D047982E196670900066B267 /* NSObject+RACLifting.m in Sources */, - D04798E8196670900066B267 /* RACSignal.m in Sources */, - D047980E196670900066B267 /* NSIndexSet+RACSequenceAdditions.m in Sources */, - D0479978196670900066B267 /* UITableViewCell+RACSignalSupport.m in Sources */, - D0479900196670900066B267 /* RACSubject.m in Sources */, - D047990E196670900066B267 /* RACSubscriptionScheduler.m in Sources */, - D047992A196670900066B267 /* RACValueTransformer.m in Sources */, - D02C14B2197243CB007127D4 /* OptionalExtensions.swift in Sources */, - D0479836196670900066B267 /* NSObject+RACSelectorSignal.m in Sources */, - D04797FE196670900066B267 /* NSData+RACSupport.m in Sources */, - D04797E2196670900066B267 /* Atomic.swift in Sources */, - D04797EA196670900066B267 /* Disposable.swift in Sources */, - D047983E196670900066B267 /* NSSet+RACSequenceAdditions.m in Sources */, - D0479916196670900066B267 /* RACTestScheduler.m in Sources */, - D0479866196670900066B267 /* RACBacktrace.m in Sources */, - D047982A196670900066B267 /* NSObject+RACKVOWrapper.m in Sources */, - D047983A196670900066B267 /* NSOrderedSet+RACSequenceAdditions.m in Sources */, - D047986A196670900066B267 /* RACBehaviorSubject.m in Sources */, - D04798EE196670900066B267 /* RACSignalProvider.d in Sources */, - D0479862196670900066B267 /* RACArraySequence.m in Sources */, - D0479934196670900066B267 /* Signal.swift in Sources */, - D0479852196670900066B267 /* NSURLConnection+RACSupport.m in Sources */, - D0479932196670900066B267 /* Scheduler.swift in Sources */, - D0479858196670900066B267 /* NSUserDefaults+RACSupport.m in Sources */, - D047985A196670900066B267 /* ObjectiveCBridging.swift in Sources */, - D0479818196670900066B267 /* NSNotificationCenter+RACSupport.m in Sources */, - D04798A4196670900066B267 /* RACGroupedSignal.m in Sources */, - D047991E196670900066B267 /* RACTupleSequence.m in Sources */, - D04798EC196670900066B267 /* RACSignal+Operations.m in Sources */, - D0479944196670900066B267 /* UIBarButtonItem+RACCommandSupport.m in Sources */, - D047987C196670900066B267 /* RACCompoundDisposableProvider.d in Sources */, - D0479974196670900066B267 /* UISwitch+RACSignalSupport.m in Sources */, - D047980A196670900066B267 /* NSFileHandle+RACSupport.m in Sources */, - D0E3CF561973AFC7004FD181 /* Errors.swift in Sources */, - D04798C2196670900066B267 /* RACPassthroughSubscriber.m in Sources */, - D036AA4C196FBCCD00B49B76 /* Bag.swift in Sources */, - D047991A196670900066B267 /* RACTuple.m in Sources */, + D037659D19EDA41200A782A9 /* RACKVOChannel.m in Sources */, + D037666319EDA41200A782A9 /* UITextView+RACSignalSupport.m in Sources */, + D037662F19EDA41200A782A9 /* UIControl+RACSignalSupport.m in Sources */, + D03765C919EDA41200A782A9 /* RACScopedDisposable.m in Sources */, + D0C312D619EF2A5800984962 /* Errors.swift in Sources */, + D03764FF19EDA41200A782A9 /* NSEnumerator+RACSequenceAdditions.m in Sources */, + D037664719EDA41200A782A9 /* UISegmentedControl+RACSignalSupport.m in Sources */, + D0C312E619EF2A5800984962 /* Promise.swift in Sources */, + D0C312E219EF2A5800984962 /* OptionalExtensions.swift in Sources */, + D0C312EC19EF2A5800984962 /* SignalingProperty.swift in Sources */, + D03764EB19EDA41200A782A9 /* NSArray+RACSequenceAdditions.m in Sources */, + D0C312D419EF2A5800984962 /* Disposable.swift in Sources */, + D03765C119EDA41200A782A9 /* RACScheduler.m in Sources */, + D037662B19EDA41200A782A9 /* UICollectionReusableView+RACSignalSupport.m in Sources */, + D037659919EDA41200A782A9 /* RACIndexSetSequence.m in Sources */, + D03765D919EDA41200A782A9 /* RACSignal+Operations.m in Sources */, + D0C312EA19EF2A5800984962 /* Signal.swift in Sources */, + D037661B19EDA41200A782A9 /* UIActionSheet+RACSignalSupport.m in Sources */, + D0C312E419EF2A5800984962 /* Producer.swift in Sources */, + D037650319EDA41200A782A9 /* NSFileHandle+RACSupport.m in Sources */, + D03765E319EDA41200A782A9 /* RACStream.m in Sources */, + D037655719EDA41200A782A9 /* RACBehaviorSubject.m in Sources */, + D037663B19EDA41200A782A9 /* UIGestureRecognizer+RACSignalSupport.m in Sources */, + D037660319EDA41200A782A9 /* RACTestScheduler.m in Sources */, + D03765B919EDA41200A782A9 /* RACReplaySubject.m in Sources */, + D03765ED19EDA41200A782A9 /* RACSubject.m in Sources */, + D037664F19EDA41200A782A9 /* UIStepper+RACSignalSupport.m in Sources */, + D03765D119EDA41200A782A9 /* RACSerialDisposable.m in Sources */, + D037663F19EDA41200A782A9 /* UIImagePickerController+RACSignalSupport.m in Sources */, + D037653F19EDA41200A782A9 /* NSString+RACSupport.m in Sources */, + D037653719EDA41200A782A9 /* NSString+RACKeyPathUtilities.m in Sources */, + D03764FB19EDA41200A782A9 /* NSDictionary+RACSequenceAdditions.m in Sources */, + D0C312DA19EF2A5800984962 /* Identity.swift in Sources */, + D037656919EDA41200A782A9 /* RACCompoundDisposableProvider.d in Sources */, + D037653B19EDA41200A782A9 /* NSString+RACSequenceAdditions.m in Sources */, + D037661F19EDA41200A782A9 /* UIAlertView+RACSignalSupport.m in Sources */, + D03765E919EDA41200A782A9 /* RACStringSequence.m in Sources */, + D037660B19EDA41200A782A9 /* RACTupleSequence.m in Sources */, + D03765D519EDA41200A782A9 /* RACSignal.m in Sources */, + D037663319EDA41200A782A9 /* UIControl+RACSignalSupportPrivate.m in Sources */, + D037664319EDA41200A782A9 /* UIRefreshControl+RACCommandSupport.m in Sources */, + D037651B19EDA41200A782A9 /* NSObject+RACDescription.m in Sources */, + D03765A519EDA41200A782A9 /* RACMulticastConnection.m in Sources */, + D037654F19EDA41200A782A9 /* RACArraySequence.m in Sources */, + D0C312DE19EF2A5800984962 /* NSURLSessionExtensions.swift in Sources */, + D037652319EDA41200A782A9 /* NSObject+RACLifting.m in Sources */, + D037650719EDA41200A782A9 /* NSIndexSet+RACSequenceAdditions.m in Sources */, + D037665F19EDA41200A782A9 /* UITextField+RACSignalSupport.m in Sources */, + D037650F19EDA41200A782A9 /* NSNotificationCenter+RACSupport.m in Sources */, + D03765FB19EDA41200A782A9 /* RACSubscriptionScheduler.m in Sources */, + D037658119EDA41200A782A9 /* RACEmptySequence.m in Sources */, + D03765AB19EDA41200A782A9 /* RACObjCRuntime.m in Sources */, + D0C312E019EF2A5800984962 /* ObjectiveCBridging.swift in Sources */, + D037654B19EDA41200A782A9 /* NSUserDefaults+RACSupport.m in Sources */, + D037660F19EDA41200A782A9 /* RACUnarySequence.m in Sources */, + D03765FF19EDA41200A782A9 /* RACTargetQueueScheduler.m in Sources */, + D03765DF19EDA41200A782A9 /* RACSignalSequence.m in Sources */, + D037656D19EDA41200A782A9 /* RACDelegateProxy.m in Sources */, + D037657519EDA41200A782A9 /* RACDynamicSequence.m in Sources */, + D037657119EDA41200A782A9 /* RACDisposable.m in Sources */, + D03765DB19EDA41200A782A9 /* RACSignalProvider.d in Sources */, + D037653319EDA41200A782A9 /* NSSet+RACSequenceAdditions.m in Sources */, + D037665319EDA41200A782A9 /* UISwitch+RACSignalSupport.m in Sources */, + D0C312CC19EF2A5800984962 /* Action.swift in Sources */, + D0C312D819EF2A5800984962 /* Event.swift in Sources */, + D037664B19EDA41200A782A9 /* UISlider+RACSignalSupport.m in Sources */, + D037656719EDA41200A782A9 /* RACCompoundDisposable.m in Sources */, + D037655B19EDA41200A782A9 /* RACBlockTrampoline.m in Sources */, + D037659119EDA41200A782A9 /* RACGroupedSignal.m in Sources */, + D037655F19EDA41200A782A9 /* RACChannel.m in Sources */, + D037657D19EDA41200A782A9 /* RACEagerSequence.m in Sources */, + D037657919EDA41200A782A9 /* RACDynamicSignal.m in Sources */, + D037659519EDA41200A782A9 /* RACImmediateScheduler.m in Sources */, + D037651719EDA41200A782A9 /* NSObject+RACDeallocating.m in Sources */, + D037658519EDA41200A782A9 /* RACEmptySignal.m in Sources */, + D037663719EDA41200A782A9 /* UIDatePicker+RACSignalSupport.m in Sources */, + D037654719EDA41200A782A9 /* NSURLConnection+RACSupport.m in Sources */, + D03765F119EDA41200A782A9 /* RACSubscriber.m in Sources */, + D03764F719EDA41200A782A9 /* NSData+RACSupport.m in Sources */, + D0C312CE19EF2A5800984962 /* Atomic.swift in Sources */, + D0C312E819EF2A5800984962 /* Scheduler.swift in Sources */, + D037656319EDA41200A782A9 /* RACCommand.m in Sources */, + D037658919EDA41200A782A9 /* RACErrorSignal.m in Sources */, + D03765F719EDA41200A782A9 /* RACSubscriptingAssignmentTrampoline.m in Sources */, + D037661319EDA41200A782A9 /* RACUnit.m in Sources */, + D037662319EDA41200A782A9 /* UIBarButtonItem+RACCommandSupport.m in Sources */, + D03765A119EDA41200A782A9 /* RACKVOTrampoline.m in Sources */, + D037665B19EDA41200A782A9 /* UITableViewHeaderFooterView+RACSignalSupport.m in Sources */, + D0C312D019EF2A5800984962 /* Bag.swift in Sources */, + D037650B19EDA41200A782A9 /* NSInvocation+RACTypeParsing.m in Sources */, + D037660719EDA41200A782A9 /* RACTuple.m in Sources */, + D037667019EDA57100A782A9 /* EXTRuntimeExtensions.m in Sources */, + D037651F19EDA41200A782A9 /* NSObject+RACKVOWrapper.m in Sources */, + D0C312DC19EF2A5800984962 /* NSNotificationCenterExtensions.swift in Sources */, + D037661719EDA41200A782A9 /* RACValueTransformer.m in Sources */, + D03765CD19EDA41200A782A9 /* RACSequence.m in Sources */, + D037652F19EDA41200A782A9 /* NSOrderedSet+RACSequenceAdditions.m in Sources */, + D037662719EDA41200A782A9 /* UIButton+RACCommandSupport.m in Sources */, + D037652719EDA41200A782A9 /* NSObject+RACPropertySubscribing.m in Sources */, + D037658D19EDA41200A782A9 /* RACEvent.m in Sources */, + D03765B319EDA41200A782A9 /* RACQueueScheduler.m in Sources */, + D037655319EDA41200A782A9 /* RACBacktrace.m in Sources */, + D037665719EDA41200A782A9 /* UITableViewCell+RACSignalSupport.m in Sources */, + D037652B19EDA41200A782A9 /* NSObject+RACSelectorSignal.m in Sources */, + D03765AF19EDA41200A782A9 /* RACPassthroughSubscriber.m in Sources */, + D03765BD19EDA41200A782A9 /* RACReturnSignal.m in Sources */, + D0C312D219EF2A5800984962 /* Consumer.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - D04796A019666CBF0066B267 /* Sources */ = { + D047261219E49F82006002AA /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - D011F1F419DD13F600A6F6C8 /* SignalSpec.swift in Sources */, - D095745F197344E3002D44C1 /* DisposableSpec.swift in Sources */, - D09574621973506C002D44C1 /* SchedulerSpec.swift in Sources */, - D04799A0196678F20066B267 /* ObjectiveCBridgingSpec.swift in Sources */, + D03766C819EDA60000A782A9 /* NSObjectRACPropertySubscribingExamples.m in Sources */, + D037672419EDA60000A782A9 /* UIImagePickerControllerRACSupportSpec.m in Sources */, + D03766E419EDA60000A782A9 /* RACDelegateProxySpec.m in Sources */, + D03766FA19EDA60000A782A9 /* RACSerialDisposableSpec.m in Sources */, + D037670C19EDA60000A782A9 /* RACTargetQueueSchedulerSpec.m in Sources */, + D03766DE19EDA60000A782A9 /* RACCommandSpec.m in Sources */, + D037670A19EDA60000A782A9 /* RACSubscriptingAssignmentTrampolineSpec.m in Sources */, + D03766EC19EDA60000A782A9 /* RACKVOWrapperSpec.m in Sources */, + D037673A19EDCA0E00A782A9 /* SwiftSpec.swift in Sources */, + D03766E819EDA60000A782A9 /* RACEventSpec.m in Sources */, + D03766F819EDA60000A782A9 /* RACSequenceSpec.m in Sources */, + D037671E19EDA60000A782A9 /* UIBarButtonItemRACSupportSpec.m in Sources */, + D03766CA19EDA60000A782A9 /* NSObjectRACPropertySubscribingSpec.m in Sources */, + D0C3131319EF2B2000984962 /* ObjectiveCBridgingSpec.swift in Sources */, + D03766C419EDA60000A782A9 /* NSObjectRACDeallocatingSpec.m in Sources */, + D0C3131519EF2B2000984962 /* SignalSpec.swift in Sources */, + D03766BE19EDA60000A782A9 /* NSEnumeratorRACSequenceAdditionsSpec.m in Sources */, + D037672019EDA60000A782A9 /* UIButtonRACSupportSpec.m in Sources */, + D037670219EDA60000A782A9 /* RACSubclassObject.m in Sources */, + D03766CE19EDA60000A782A9 /* NSStringRACKeyPathUtilitiesSpec.m in Sources */, + D037671619EDA60000A782A9 /* RACTupleSpec.m in Sources */, + D03766C619EDA60000A782A9 /* NSObjectRACLiftingSpec.m in Sources */, + D03766D219EDA60000A782A9 /* NSURLConnectionRACSupportSpec.m in Sources */, + D03766F419EDA60000A782A9 /* RACSequenceAdditionsSpec.m in Sources */, + D0C3131419EF2B2000984962 /* SchedulerSpec.swift in Sources */, + D037670E19EDA60000A782A9 /* RACTestExampleScheduler.m in Sources */, + D0C3131219EF2B2000984962 /* DisposableSpec.swift in Sources */, + D03766EE19EDA60000A782A9 /* RACMulticastConnectionSpec.m in Sources */, + D03766EA19EDA60000A782A9 /* RACKVOChannelSpec.m in Sources */, + D03766FC19EDA60000A782A9 /* RACSignalSpec.m in Sources */, + D037670819EDA60000A782A9 /* RACSubscriberSpec.m in Sources */, + D037671C19EDA60000A782A9 /* UIAlertViewRACSupportSpec.m in Sources */, + D03766F019EDA60000A782A9 /* RACPropertySignalExamples.m in Sources */, + D03766D619EDA60000A782A9 /* RACBacktraceSpec.m in Sources */, + D037670619EDA60000A782A9 /* RACSubscriberExamples.m in Sources */, + D03766D819EDA60000A782A9 /* RACBlockTrampolineSpec.m in Sources */, + D037670019EDA60000A782A9 /* RACStreamExamples.m in Sources */, + D03766CC19EDA60000A782A9 /* NSObjectRACSelectorSignalSpec.m in Sources */, + D03766E219EDA60000A782A9 /* RACControlCommandExamples.m in Sources */, + D03766C019EDA60000A782A9 /* NSNotificationCenterRACSupportSpec.m in Sources */, + D037670419EDA60000A782A9 /* RACSubjectSpec.m in Sources */, + D037671419EDA60000A782A9 /* RACTestUIButton.m in Sources */, + D03766F219EDA60000A782A9 /* RACSchedulerSpec.m in Sources */, + D03766E019EDA60000A782A9 /* RACCompoundDisposableSpec.m in Sources */, + D03766E619EDA60000A782A9 /* RACDisposableSpec.m in Sources */, + D03766D419EDA60000A782A9 /* NSUserDefaultsRACSupportSpec.m in Sources */, + D037671219EDA60000A782A9 /* RACTestSchedulerSpec.m in Sources */, + D03766DC19EDA60000A782A9 /* RACChannelSpec.m in Sources */, + D037671A19EDA60000A782A9 /* UIActionSheetRACSupportSpec.m in Sources */, + D03766DA19EDA60000A782A9 /* RACChannelExamples.m in Sources */, + D03766F619EDA60000A782A9 /* RACSequenceExamples.m in Sources */, + D037671019EDA60000A782A9 /* RACTestObject.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - D047968119666BF30066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D047968019666BF30066B267 /* PBXContainerItemProxy */; - }; - D047969019666CA70066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D047968F19666CA70066B267 /* PBXContainerItemProxy */; - }; - D047969219666CA70066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D047969119666CA70066B267 /* PBXContainerItemProxy */; - }; - D047969419666CAD0066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D047969319666CAD0066B267 /* PBXContainerItemProxy */; - }; - D04796A719666CBF0066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796A619666CBF0066B267 /* PBXContainerItemProxy */; - }; - D04796B419666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796B319666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796B619666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796B519666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796B819666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796B719666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796BA19666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796B919666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796BC19666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796BB19666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796BE19666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796BD19666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796C019666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796BF19666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796C219666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796C119666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796C419666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796C319666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796C619666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796C519666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796C819666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796C719666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796CA19666CC00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796C919666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796CC19666CC00066B267 /* PBXTargetDependency */ = { + D04725F819E49ED7006002AA /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796CB19666CC00066B267 /* PBXContainerItemProxy */; + target = D04725E919E49ED7006002AA /* ReactiveCocoa-Mac */; + targetProxy = D04725F719E49ED7006002AA /* PBXContainerItemProxy */; }; - D04796CE19666CC00066B267 /* PBXTargetDependency */ = { + D047261919E49F82006002AA /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796CD19666CC00066B267 /* PBXContainerItemProxy */; - }; - D04796D019666CCB0066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796CF19666CCB0066B267 /* PBXContainerItemProxy */; - }; - D04796D219666CD00066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D04796D119666CD00066B267 /* PBXContainerItemProxy */; - }; - D04796D419666CD20066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D04796D319666CD20066B267 /* PBXContainerItemProxy */; - }; - D04796EE19666D6C0066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D04796ED19666D6C0066B267 /* PBXContainerItemProxy */; - }; - D04796F019666DB60066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796EF19666DB60066B267 /* PBXContainerItemProxy */; - }; - D04796F819666F1D0066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D04796F719666F1D0066B267 /* PBXContainerItemProxy */; - }; - D04796FA19666F1F0066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04796F919666F1F0066B267 /* PBXContainerItemProxy */; - }; - D04799A219667AF80066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D04799A119667AF80066B267 /* PBXContainerItemProxy */; - }; - D04799A419667CAD0066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D04799A319667CAD0066B267 /* PBXContainerItemProxy */; - }; - D04799A619667E580066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D04799A519667E580066B267 /* PBXContainerItemProxy */; - }; - D04799A819667E5D0066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04799A719667E5D0066B267 /* PBXContainerItemProxy */; - }; - D04799AA19667E620066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047967219666BF30066B267 /* ReactiveCocoa-Mac */; - targetProxy = D04799A919667E620066B267 /* PBXContainerItemProxy */; - }; - D04799AC19667E740066B267 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D047969919666CBF0066B267 /* ReactiveCocoa-iOS */; - targetProxy = D04799AB19667E740066B267 /* PBXContainerItemProxy */; + target = D047260B19E49F82006002AA /* ReactiveCocoa-iOS */; + targetProxy = D047261819E49F82006002AA /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - D047968719666BF30066B267 /* Debug */ = { + D04725FE19E49ED7006002AA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796D919666CE40066B267 /* Debug.xcconfig */; + baseConfigurationReference = D047262919E49FE8006002AA /* Debug.xcconfig */; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; CURRENT_PROJECT_VERSION = 1; - GCC_PREFIX_HEADER = "ReactiveCocoa/ReactiveCocoa-Prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.9; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2095,14 +1918,11 @@ }; name = Debug; }; - D047968819666BF30066B267 /* Release */ = { + D04725FF19E49ED7006002AA /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796DB19666CE40066B267 /* Release.xcconfig */; + baseConfigurationReference = D047262B19E49FE8006002AA /* Release.xcconfig */; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; CURRENT_PROJECT_VERSION = 1; - GCC_PREFIX_HEADER = "ReactiveCocoa/ReactiveCocoa-Prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.9; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2111,106 +1931,119 @@ }; name = Release; }; - D047968A19666BF30066B267 /* Debug */ = { + D047260119E49ED7006002AA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796EA19666CE40066B267 /* Mac-Framework.xcconfig */; + baseConfigurationReference = D047263A19E49FE8006002AA /* Mac-Framework.xcconfig */; buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; INFOPLIST_FILE = ReactiveCocoa/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + USER_HEADER_SEARCH_PATHS = ReactiveCocoa/extobjc; }; name = Debug; }; - D047968B19666BF30066B267 /* Release */ = { + D047260219E49ED7006002AA /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796EA19666CE40066B267 /* Mac-Framework.xcconfig */; + baseConfigurationReference = D047263A19E49FE8006002AA /* Mac-Framework.xcconfig */; buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; INFOPLIST_FILE = ReactiveCocoa/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + USER_HEADER_SEARCH_PATHS = ReactiveCocoa/extobjc; }; name = Release; }; - D047968D19666BF30066B267 /* Debug */ = { + D047260419E49ED7006002AA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E719666CE40066B267 /* Mac-Application.xcconfig */; + baseConfigurationReference = D047263719E49FE8006002AA /* Mac-Application.xcconfig */; buildSettings = { - GCC_PREFIX_HEADER = "ReactiveCocoaTests/ReactiveCocoaTests-Prefix.pch"; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); INFOPLIST_FILE = ReactiveCocoaTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; - D047968E19666BF30066B267 /* Release */ = { + D047260519E49ED7006002AA /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E719666CE40066B267 /* Mac-Application.xcconfig */; + baseConfigurationReference = D047263719E49FE8006002AA /* Mac-Application.xcconfig */; buildSettings = { - GCC_PREFIX_HEADER = "ReactiveCocoaTests/ReactiveCocoaTests-Prefix.pch"; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); INFOPLIST_FILE = ReactiveCocoaTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; - D04796AE19666CBF0066B267 /* Debug */ = { + D047262019E49F82006002AA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E419666CE40066B267 /* iOS-Framework.xcconfig */; + baseConfigurationReference = D047263419E49FE8006002AA /* iOS-Framework.xcconfig */; buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; INFOPLIST_FILE = ReactiveCocoa/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + USER_HEADER_SEARCH_PATHS = ReactiveCocoa/extobjc; }; name = Debug; }; - D04796AF19666CBF0066B267 /* Release */ = { + D047262119E49F82006002AA /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E419666CE40066B267 /* iOS-Framework.xcconfig */; + baseConfigurationReference = D047263419E49FE8006002AA /* iOS-Framework.xcconfig */; buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; INFOPLIST_FILE = ReactiveCocoa/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + USER_HEADER_SEARCH_PATHS = ReactiveCocoa/extobjc; }; name = Release; }; - D04796B119666CBF0066B267 /* Debug */ = { + D047262319E49F82006002AA /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E219666CE40066B267 /* iOS-Application.xcconfig */; + baseConfigurationReference = D047263219E49FE8006002AA /* iOS-Application.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); - GCC_PREFIX_HEADER = "ReactiveCocoaTests/ReactiveCocoaTests-Prefix.pch"; INFOPLIST_FILE = ReactiveCocoaTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; - D04796B219666CBF0066B267 /* Release */ = { + D047262419E49F82006002AA /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E219666CE40066B267 /* iOS-Application.xcconfig */; + baseConfigurationReference = D047263219E49FE8006002AA /* iOS-Application.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); - GCC_PREFIX_HEADER = "ReactiveCocoaTests/ReactiveCocoaTests-Prefix.pch"; INFOPLIST_FILE = ReactiveCocoaTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; - D04796FB19666F510066B267 /* Profile */ = { + D047263D19E4A008006002AA /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796DA19666CE40066B267 /* Profile.xcconfig */; + baseConfigurationReference = D047262A19E49FE8006002AA /* Profile.xcconfig */; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; CURRENT_PROJECT_VERSION = 1; - GCC_PREFIX_HEADER = "ReactiveCocoa/ReactiveCocoa-Prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.9; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2219,60 +2052,65 @@ }; name = Profile; }; - D04796FC19666F510066B267 /* Profile */ = { + D047263E19E4A008006002AA /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796EA19666CE40066B267 /* Mac-Framework.xcconfig */; + baseConfigurationReference = D047263A19E49FE8006002AA /* Mac-Framework.xcconfig */; buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; INFOPLIST_FILE = ReactiveCocoa/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + USER_HEADER_SEARCH_PATHS = ReactiveCocoa/extobjc; }; name = Profile; }; - D04796FD19666F510066B267 /* Profile */ = { + D047263F19E4A008006002AA /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E719666CE40066B267 /* Mac-Application.xcconfig */; + baseConfigurationReference = D047263719E49FE8006002AA /* Mac-Application.xcconfig */; buildSettings = { - GCC_PREFIX_HEADER = "ReactiveCocoaTests/ReactiveCocoaTests-Prefix.pch"; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); INFOPLIST_FILE = ReactiveCocoaTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Profile; }; - D04796FE19666F510066B267 /* Profile */ = { + D047264019E4A008006002AA /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E419666CE40066B267 /* iOS-Framework.xcconfig */; + baseConfigurationReference = D047263419E49FE8006002AA /* iOS-Framework.xcconfig */; buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; INFOPLIST_FILE = ReactiveCocoa/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + USER_HEADER_SEARCH_PATHS = ReactiveCocoa/extobjc; }; name = Profile; }; - D04796FF19666F510066B267 /* Profile */ = { + D047264119E4A008006002AA /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E219666CE40066B267 /* iOS-Application.xcconfig */; + baseConfigurationReference = D047263219E49FE8006002AA /* iOS-Application.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); - GCC_PREFIX_HEADER = "ReactiveCocoaTests/ReactiveCocoaTests-Prefix.pch"; INFOPLIST_FILE = ReactiveCocoaTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Profile; }; - D047970019666F550066B267 /* Test */ = { + D047264219E4A00B006002AA /* Test */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796DC19666CE40066B267 /* Test.xcconfig */; + baseConfigurationReference = D047262C19E49FE8006002AA /* Test.xcconfig */; buildSettings = { - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; CURRENT_PROJECT_VERSION = 1; - GCC_PREFIX_HEADER = "ReactiveCocoa/ReactiveCocoa-Prefix.pch"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; MACOSX_DEPLOYMENT_TARGET = 10.9; TARGETED_DEVICE_FAMILY = "1,2"; @@ -2281,48 +2119,56 @@ }; name = Test; }; - D047970119666F550066B267 /* Test */ = { + D047264319E4A00B006002AA /* Test */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796EA19666CE40066B267 /* Mac-Framework.xcconfig */; + baseConfigurationReference = D047263A19E49FE8006002AA /* Mac-Framework.xcconfig */; buildSettings = { DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_VERSION = A; INFOPLIST_FILE = ReactiveCocoa/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + USER_HEADER_SEARCH_PATHS = ReactiveCocoa/extobjc; }; name = Test; }; - D047970219666F550066B267 /* Test */ = { + D047264419E4A00B006002AA /* Test */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E719666CE40066B267 /* Mac-Application.xcconfig */; + baseConfigurationReference = D047263719E49FE8006002AA /* Mac-Application.xcconfig */; buildSettings = { - GCC_PREFIX_HEADER = "ReactiveCocoaTests/ReactiveCocoaTests-Prefix.pch"; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); INFOPLIST_FILE = ReactiveCocoaTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Test; }; - D047970319666F550066B267 /* Test */ = { + D047264519E4A00B006002AA /* Test */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E419666CE40066B267 /* iOS-Framework.xcconfig */; + baseConfigurationReference = D047263419E49FE8006002AA /* iOS-Framework.xcconfig */; buildSettings = { - CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; INFOPLIST_FILE = ReactiveCocoa/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + USER_HEADER_SEARCH_PATHS = ReactiveCocoa/extobjc; }; name = Test; }; - D047970419666F550066B267 /* Test */ = { + D047264619E4A00B006002AA /* Test */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D04796E219666CE40066B267 /* iOS-Application.xcconfig */; + baseConfigurationReference = D047263219E49FE8006002AA /* iOS-Application.xcconfig */; buildSettings = { FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", ); - GCC_PREFIX_HEADER = "ReactiveCocoaTests/ReactiveCocoaTests-Prefix.pch"; INFOPLIST_FILE = ReactiveCocoaTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Test; @@ -2330,62 +2176,62 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - D047966D19666BF30066B267 /* Build configuration list for PBXProject "ReactiveCocoa" */ = { + D04725E419E49ED7006002AA /* Build configuration list for PBXProject "ReactiveCocoa" */ = { isa = XCConfigurationList; buildConfigurations = ( - D047968719666BF30066B267 /* Debug */, - D047970019666F550066B267 /* Test */, - D047968819666BF30066B267 /* Release */, - D04796FB19666F510066B267 /* Profile */, + D04725FE19E49ED7006002AA /* Debug */, + D047264219E4A00B006002AA /* Test */, + D04725FF19E49ED7006002AA /* Release */, + D047263D19E4A008006002AA /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D047968919666BF30066B267 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-Mac" */ = { + D047260019E49ED7006002AA /* Build configuration list for PBXNativeTarget "ReactiveCocoa-Mac" */ = { isa = XCConfigurationList; buildConfigurations = ( - D047968A19666BF30066B267 /* Debug */, - D047970119666F550066B267 /* Test */, - D047968B19666BF30066B267 /* Release */, - D04796FC19666F510066B267 /* Profile */, + D047260119E49ED7006002AA /* Debug */, + D047264319E4A00B006002AA /* Test */, + D047260219E49ED7006002AA /* Release */, + D047263E19E4A008006002AA /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D047968C19666BF30066B267 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-MacTests" */ = { + D047260319E49ED7006002AA /* Build configuration list for PBXNativeTarget "ReactiveCocoa-MacTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - D047968D19666BF30066B267 /* Debug */, - D047970219666F550066B267 /* Test */, - D047968E19666BF30066B267 /* Release */, - D04796FD19666F510066B267 /* Profile */, + D047260419E49ED7006002AA /* Debug */, + D047264419E4A00B006002AA /* Test */, + D047260519E49ED7006002AA /* Release */, + D047263F19E4A008006002AA /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D04796AD19666CBF0066B267 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-iOS" */ = { + D047261F19E49F82006002AA /* Build configuration list for PBXNativeTarget "ReactiveCocoa-iOS" */ = { isa = XCConfigurationList; buildConfigurations = ( - D04796AE19666CBF0066B267 /* Debug */, - D047970319666F550066B267 /* Test */, - D04796AF19666CBF0066B267 /* Release */, - D04796FE19666F510066B267 /* Profile */, + D047262019E49F82006002AA /* Debug */, + D047264519E4A00B006002AA /* Test */, + D047262119E49F82006002AA /* Release */, + D047264019E4A008006002AA /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D04796B019666CBF0066B267 /* Build configuration list for PBXNativeTarget "ReactiveCocoa-iOSTests" */ = { + D047262219E49F82006002AA /* Build configuration list for PBXNativeTarget "ReactiveCocoa-iOSTests" */ = { isa = XCConfigurationList; buildConfigurations = ( - D04796B119666CBF0066B267 /* Debug */, - D047970419666F550066B267 /* Test */, - D04796B219666CBF0066B267 /* Release */, - D04796FF19666F510066B267 /* Profile */, + D047262319E49F82006002AA /* Debug */, + D047264619E4A00B006002AA /* Test */, + D047262419E49F82006002AA /* Release */, + D047264119E4A008006002AA /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; - rootObject = D047966A19666BF30066B267 /* Project object */; + rootObject = D04725E119E49ED7006002AA /* Project object */; } diff --git a/ReactiveCocoa.xcodeproj/xcshareddata/xcschemes/ReactiveCocoa Mac.xcscheme b/ReactiveCocoa.xcodeproj/xcshareddata/xcschemes/ReactiveCocoa Mac.xcscheme index 2005ccd97f..aa908fa265 100644 --- a/ReactiveCocoa.xcodeproj/xcshareddata/xcschemes/ReactiveCocoa Mac.xcscheme +++ b/ReactiveCocoa.xcodeproj/xcshareddata/xcschemes/ReactiveCocoa Mac.xcscheme @@ -1,7 +1,7 @@ + version = "1.3"> @@ -14,12 +14,26 @@ buildForAnalyzing = "YES"> + + + + + + + + @@ -68,6 +90,15 @@ useCustomWorkingDirectory = "NO" buildConfiguration = "Profile" debugDocumentVersioning = "YES"> + + + + diff --git a/ReactiveCocoa.xcodeproj/xcshareddata/xcschemes/ReactiveCocoa iOS.xcscheme b/ReactiveCocoa.xcodeproj/xcshareddata/xcschemes/ReactiveCocoa iOS.xcscheme index 21648682ab..5715867435 100644 --- a/ReactiveCocoa.xcodeproj/xcshareddata/xcschemes/ReactiveCocoa iOS.xcscheme +++ b/ReactiveCocoa.xcodeproj/xcshareddata/xcschemes/ReactiveCocoa iOS.xcscheme @@ -1,7 +1,7 @@ + version = "1.3"> @@ -14,12 +14,26 @@ buildForAnalyzing = "YES"> + + + + + + + + @@ -68,6 +90,15 @@ useCustomWorkingDirectory = "NO" buildConfiguration = "Profile" debugDocumentVersioning = "YES"> + + + + diff --git a/ReactiveCocoa/Info.plist b/ReactiveCocoa/Info.plist index f06e0bd952..30d0b08169 100644 --- a/ReactiveCocoa/Info.plist +++ b/ReactiveCocoa/Info.plist @@ -5,13 +5,13 @@ CFBundleDevelopmentRegion en CFBundleExecutable - ${EXECUTABLE_NAME} + $(EXECUTABLE_NAME) CFBundleIdentifier - com.github.${PRODUCT_NAME:rfc1034identifier} + com.github.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName - ${PRODUCT_NAME} + $(PRODUCT_NAME) CFBundlePackageType FMWK CFBundleShortVersionString @@ -19,7 +19,9 @@ CFBundleSignature ???? CFBundleVersion - ${CURRENT_PROJECT_VERSION} + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2014 GitHub. All rights reserved. NSPrincipalClass diff --git a/ReactiveCocoa/NSObject+RACLifting.h b/ReactiveCocoa/NSObject+RACLifting.h index af928e6a12..bc4bca2663 100644 --- a/ReactiveCocoa/NSObject+RACLifting.h +++ b/ReactiveCocoa/NSObject+RACLifting.h @@ -6,6 +6,8 @@ // Copyright (c) 2012 GitHub, Inc. All rights reserved. // +#import + @class RACSignal; @interface NSObject (RACLifting) diff --git a/ReactiveCocoa/RACCommand.m b/ReactiveCocoa/RACCommand.m index 6108865802..c1adecec5c 100644 --- a/ReactiveCocoa/RACCommand.m +++ b/ReactiveCocoa/RACCommand.m @@ -189,7 +189,7 @@ - (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id RACSignal *moreExecutionsAllowed = [RACSignal if:RACObserve(self, allowsConcurrentExecution) then:[RACSignal return:@YES] - else:[immediateExecuting notEach]]; + else:[immediateExecuting not]]; if (enabledSignal == nil) { enabledSignal = [RACSignal return:@YES]; @@ -202,7 +202,7 @@ - (id)initWithEnabled:(RACSignal *)enabledSignal signalBlock:(RACSignal * (^)(id _immediateEnabled = [[RACSignal combineLatest:@[ enabledSignal, moreExecutionsAllowed ]] - reduceAnd]; + and]; _enabled = [[[[[self.immediateEnabled take:1] diff --git a/ReactiveCocoa/RACSignal+Operations.h b/ReactiveCocoa/RACSignal+Operations.h index b9eae4f91a..ffbcded54a 100644 --- a/ReactiveCocoa/RACSignal+Operations.h +++ b/ReactiveCocoa/RACSignal+Operations.h @@ -637,21 +637,21 @@ extern const NSInteger RACSignalErrorNoMatchingCase; /// the receiver sends anything other than NSNumbers. /// /// Returns a signal of inverted NSNumber-wrapped BOOLs. -- (RACSignal *)notEach; +- (RACSignal *)not; /// Performs a boolean AND on all of the RACTuple of NSNumbers in sent by the receiver. /// /// Asserts if the receiver sends anything other than a RACTuple of one or more NSNumbers. /// /// Returns a signal that applies AND to each NSNumber in the tuple. -- (RACSignal *)reduceAnd; +- (RACSignal *)and; /// Performs a boolean OR on all of the RACTuple of NSNumbers in sent by the receiver. /// /// Asserts if the receiver sends anything other than a RACTuple of one or more NSNumbers. /// /// Returns a signal that applies OR to each NSNumber in the tuple. -- (RACSignal *)reduceOr; +- (RACSignal *)or; /// Sends the result of calling the block with arguments as packed in each RACTuple /// sent by the receiver. diff --git a/ReactiveCocoa/RACSignal+Operations.m b/ReactiveCocoa/RACSignal+Operations.m index e86b6211e3..656004c7b5 100644 --- a/ReactiveCocoa/RACSignal+Operations.m +++ b/ReactiveCocoa/RACSignal+Operations.m @@ -1232,38 +1232,38 @@ - (RACSignal *)dematerialize { }] setNameWithFormat:@"[%@] -dematerialize", self.name]; } -- (RACSignal *)notEach { +- (RACSignal *)not { return [[self map:^(NSNumber *value) { - NSCAssert([value isKindOfClass:NSNumber.class], @"-notEach must only be used on a signal of NSNumbers. Instead, got: %@", value); + NSCAssert([value isKindOfClass:NSNumber.class], @"-not must only be used on a signal of NSNumbers. Instead, got: %@", value); return @(!value.boolValue); - }] setNameWithFormat:@"[%@] -notEach", self.name]; + }] setNameWithFormat:@"[%@] -not", self.name]; } -- (RACSignal *)reduceAnd { +- (RACSignal *)and { return [[self map:^(RACTuple *tuple) { - NSCAssert([tuple isKindOfClass:RACTuple.class], @"-reduceAnd must only be used on a signal of RACTuples of NSNumbers. Instead, received: %@", tuple); - NSCAssert(tuple.count > 0, @"-reduceAnd must only be used on a signal of RACTuples of NSNumbers, with at least 1 value in the tuple"); + NSCAssert([tuple isKindOfClass:RACTuple.class], @"-and must only be used on a signal of RACTuples of NSNumbers. Instead, received: %@", tuple); + NSCAssert(tuple.count > 0, @"-and must only be used on a signal of RACTuples of NSNumbers, with at least 1 value in the tuple"); return @([tuple.rac_sequence all:^(NSNumber *number) { - NSCAssert([number isKindOfClass:NSNumber.class], @"-reduceAnd must only be used on a signal of RACTuples of NSNumbers. Instead, tuple contains a non-NSNumber value: %@", tuple); + NSCAssert([number isKindOfClass:NSNumber.class], @"-and must only be used on a signal of RACTuples of NSNumbers. Instead, tuple contains a non-NSNumber value: %@", tuple); return number.boolValue; }]); - }] setNameWithFormat:@"[%@] -reduceAnd", self.name]; + }] setNameWithFormat:@"[%@] -and", self.name]; } -- (RACSignal *)reduceOr { +- (RACSignal *)or { return [[self map:^(RACTuple *tuple) { - NSCAssert([tuple isKindOfClass:RACTuple.class], @"-reduceOr must only be used on a signal of RACTuples of NSNumbers. Instead, received: %@", tuple); - NSCAssert(tuple.count > 0, @"-reduceOr must only be used on a signal of RACTuples of NSNumbers, with at least 1 value in the tuple"); + NSCAssert([tuple isKindOfClass:RACTuple.class], @"-or must only be used on a signal of RACTuples of NSNumbers. Instead, received: %@", tuple); + NSCAssert(tuple.count > 0, @"-or must only be used on a signal of RACTuples of NSNumbers, with at least 1 value in the tuple"); return @([tuple.rac_sequence any:^(NSNumber *number) { - NSCAssert([number isKindOfClass:NSNumber.class], @"-reduceOr must only be used on a signal of RACTuples of NSNumbers. Instead, tuple contains a non-NSNumber value: %@", tuple); + NSCAssert([number isKindOfClass:NSNumber.class], @"-or must only be used on a signal of RACTuples of NSNumbers. Instead, tuple contains a non-NSNumber value: %@", tuple); return number.boolValue; }]); - }] setNameWithFormat:@"[%@] -reduceOr", self.name]; + }] setNameWithFormat:@"[%@] -or", self.name]; } - (RACSignal *)reduceApply { diff --git a/ReactiveCocoa/ReactiveCocoa.h b/ReactiveCocoa/ReactiveCocoa.h index ff91a1ae1c..164b4a9146 100644 --- a/ReactiveCocoa/ReactiveCocoa.h +++ b/ReactiveCocoa/ReactiveCocoa.h @@ -2,8 +2,8 @@ // ReactiveCocoa.h // ReactiveCocoa // -// Created by Justin Spahr-Summers on 2014-07-03. -// Copyright (c) 2014 GitHub. All rights reserved. +// Created by Josh Abernathy on 3/5/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. // #import @@ -15,6 +15,7 @@ FOUNDATION_EXPORT double ReactiveCocoaVersionNumber; FOUNDATION_EXPORT const unsigned char ReactiveCocoaVersionString[]; #import +#import #import #import #import @@ -32,6 +33,7 @@ FOUNDATION_EXPORT const unsigned char ReactiveCocoaVersionString[]; #import #import #import +#import #import #import #import @@ -42,8 +44,10 @@ FOUNDATION_EXPORT const unsigned char ReactiveCocoaVersionString[]; #import #import #import +#import #import #import +#import #import #import #import @@ -74,6 +78,7 @@ FOUNDATION_EXPORT const unsigned char ReactiveCocoaVersionString[]; #import #import #import + #import #import #import #elif TARGET_OS_MAC diff --git a/ReactiveCocoa/EXTKeyPathCoding.h b/ReactiveCocoa/extobjc/EXTKeyPathCoding.h similarity index 100% rename from ReactiveCocoa/EXTKeyPathCoding.h rename to ReactiveCocoa/extobjc/EXTKeyPathCoding.h diff --git a/ReactiveCocoa/EXTRuntimeExtensions.h b/ReactiveCocoa/extobjc/EXTRuntimeExtensions.h similarity index 100% rename from ReactiveCocoa/EXTRuntimeExtensions.h rename to ReactiveCocoa/extobjc/EXTRuntimeExtensions.h diff --git a/ReactiveCocoa/EXTRuntimeExtensions.m b/ReactiveCocoa/extobjc/EXTRuntimeExtensions.m similarity index 99% rename from ReactiveCocoa/EXTRuntimeExtensions.m rename to ReactiveCocoa/extobjc/EXTRuntimeExtensions.m index 4d35a3ecef..159f09ca04 100644 --- a/ReactiveCocoa/EXTRuntimeExtensions.m +++ b/ReactiveCocoa/extobjc/EXTRuntimeExtensions.m @@ -8,7 +8,9 @@ // #import "EXTRuntimeExtensions.h" + #import +#import #import #import #import diff --git a/ReactiveCocoa/EXTScope.h b/ReactiveCocoa/extobjc/EXTScope.h similarity index 100% rename from ReactiveCocoa/EXTScope.h rename to ReactiveCocoa/extobjc/EXTScope.h diff --git a/ReactiveCocoa/metamacros.h b/ReactiveCocoa/extobjc/metamacros.h similarity index 100% rename from ReactiveCocoa/metamacros.h rename to ReactiveCocoa/extobjc/metamacros.h diff --git a/ReactiveCocoaTests/Info.plist b/ReactiveCocoaTests/Info.plist index 4ebde7b7b9..3768d04bb5 100644 --- a/ReactiveCocoaTests/Info.plist +++ b/ReactiveCocoaTests/Info.plist @@ -5,13 +5,13 @@ CFBundleDevelopmentRegion en CFBundleExecutable - ${EXECUTABLE_NAME} + $(EXECUTABLE_NAME) CFBundleIdentifier - com.github.${PRODUCT_NAME:rfc1034identifier} + com.github.$(PRODUCT_NAME:rfc1034identifier) CFBundleInfoDictionaryVersion 6.0 CFBundleName - ${PRODUCT_NAME} + $(PRODUCT_NAME) CFBundlePackageType BNDL CFBundleShortVersionString diff --git a/ReactiveCocoaTests/NSControllerRACSupportSpec.m b/ReactiveCocoaTests/NSControllerRACSupportSpec.m new file mode 100644 index 0000000000..97baede437 --- /dev/null +++ b/ReactiveCocoaTests/NSControllerRACSupportSpec.m @@ -0,0 +1,47 @@ +// +// NSControllerRACSupportSpec.m +// ReactiveCocoa +// +// Created by Uri Baghin on 26/10/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import +#import "RACKVOChannel.h" + +@interface RACTestController : NSController + +@property (nonatomic, strong) id object; + +@end + +@implementation RACTestController + +@end + +QuickSpecBegin(NSControllerRACSupportSpec) + +qck_it(@"RACKVOChannel should support NSController", ^{ + RACTestController *a = [[RACTestController alloc] init]; + RACTestController *b = [[RACTestController alloc] init]; + RACChannelTo(a, object) = RACChannelTo(b, object); + expect(a.object).to(beNil()); + expect(b.object).to(beNil()); + + a.object = a; + expect(a.object).to(equal(a)); + expect(b.object).to(equal(a)); + + b.object = b; + expect(a.object).to(equal(b)); + expect(b.object).to(equal(b)); + + a.object = nil; + expect(a.object).to(beNil()); + expect(b.object).to(beNil()); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSEnumeratorRACSequenceAdditionsSpec.m b/ReactiveCocoaTests/NSEnumeratorRACSequenceAdditionsSpec.m new file mode 100644 index 0000000000..04c141aaa0 --- /dev/null +++ b/ReactiveCocoaTests/NSEnumeratorRACSequenceAdditionsSpec.m @@ -0,0 +1,28 @@ +// +// NSEnumeratorRACSequenceAdditionsSpec.m +// ReactiveCocoa +// +// Created by Uri Baghin on 07/01/2013. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSequenceExamples.h" + +#import "NSEnumerator+RACSequenceAdditions.h" + +QuickSpecBegin(NSEnumeratorRACSequenceAdditionsSpec) + +qck_describe(@"-rac_sequence", ^{ + NSArray *values = @[ @0, @1, @2, @3, @4 ]; + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: values.objectEnumerator.rac_sequence, + RACSequenceExampleExpectedValues: values + }; + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSNotificationCenterRACSupportSpec.m b/ReactiveCocoaTests/NSNotificationCenterRACSupportSpec.m new file mode 100644 index 0000000000..e1ad5476a9 --- /dev/null +++ b/ReactiveCocoaTests/NSNotificationCenterRACSupportSpec.m @@ -0,0 +1,87 @@ +// +// NSNotificationCenterRACSupportSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-12-07. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "NSNotificationCenter+RACSupport.h" +#import "RACSignal.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "NSObject+RACDeallocating.h" + +static NSString * const TestNotification = @"TestNotification"; + +QuickSpecBegin(NSNotificationCenterRACSupportSpec) + +__block NSNotificationCenter *notificationCenter; + +qck_beforeEach(^{ + // The compiler gets confused and thinks you might be messaging + // NSDistributedNotificationCenter otherwise. Wtf? + notificationCenter = NSNotificationCenter.defaultCenter; +}); + +qck_it(@"should send the notification when posted by any object", ^{ + RACSignal *signal = [notificationCenter rac_addObserverForName:TestNotification object:nil]; + + __block NSUInteger count = 0; + [signal subscribeNext:^(NSNotification *notification) { + ++count; + + expect(notification).to(beAKindOf(NSNotification.class)); + expect(notification.name).to(equal(TestNotification)); + }]; + + expect(@(count)).to(equal(@0)); + + [notificationCenter postNotificationName:TestNotification object:nil]; + expect(@(count)).to(equal(@1)); + + [notificationCenter postNotificationName:TestNotification object:self]; + expect(@(count)).to(equal(@2)); +}); + +qck_it(@"should send the notification when posted by a specific object", ^{ + RACSignal *signal = [notificationCenter rac_addObserverForName:TestNotification object:self]; + + __block NSUInteger count = 0; + [signal subscribeNext:^(NSNotification *notification) { + ++count; + + expect(notification).to(beAKindOf(NSNotification.class)); + expect(notification.name).to(equal(TestNotification)); + expect(notification.object).to(beIdenticalTo(self)); + }]; + + expect(@(count)).to(equal(@0)); + + [notificationCenter postNotificationName:TestNotification object:nil]; + expect(@(count)).to(equal(@0)); + + [notificationCenter postNotificationName:TestNotification object:self]; + expect(@(count)).to(equal(@1)); +}); + +qck_it(@"shouldn't strongly capture the notification object", ^{ + RACSignal *signal __attribute__((objc_precise_lifetime, unused)); + + __block BOOL dealloced = NO; + @autoreleasepool { + NSObject *notificationObject = [[NSObject alloc] init]; + [notificationObject.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + dealloced = YES; + }]]; + + signal = [notificationCenter rac_addObserverForName:TestNotification object:notificationObject]; + } + + expect(@(dealloced)).to(beTruthy()); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSObjectRACAppKitBindingsSpec.m b/ReactiveCocoaTests/NSObjectRACAppKitBindingsSpec.m new file mode 100644 index 0000000000..2664c6e9f7 --- /dev/null +++ b/ReactiveCocoaTests/NSObjectRACAppKitBindingsSpec.m @@ -0,0 +1,39 @@ +// +// NSObjectRACAppKitBindingsSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-07-01. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACChannelExamples.h" + +#import "EXTKeyPathCoding.h" +#import "NSObject+RACAppKitBindings.h" + +QuickSpecBegin(NSObjectRACAppKitBindingsSpec) + +qck_itBehavesLike(RACViewChannelExamples, ^{ + return @{ + RACViewChannelExampleCreateViewBlock: ^{ + return [[NSSlider alloc] initWithFrame:NSZeroRect]; + }, + RACViewChannelExampleCreateTerminalBlock: ^(NSSlider *view) { + return [view rac_channelToBinding:NSValueBinding]; + }, + RACViewChannelExampleKeyPath: @keypath(NSSlider.new, objectValue), + RACViewChannelExampleSetViewValueBlock: ^(NSSlider *view, NSNumber *value) { + view.objectValue = value; + + // Bindings don't actually trigger from programmatic modification. Do it + // manually. + NSDictionary *bindingInfo = [view infoForBinding:NSValueBinding]; + [bindingInfo[NSObservedObjectKey] setValue:value forKeyPath:bindingInfo[NSObservedKeyPathKey]]; + } + }; +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSObjectRACDeallocatingSpec.m b/ReactiveCocoaTests/NSObjectRACDeallocatingSpec.m new file mode 100644 index 0000000000..5d162ac6af --- /dev/null +++ b/ReactiveCocoaTests/NSObjectRACDeallocatingSpec.m @@ -0,0 +1,198 @@ +// +// NSObject+RACDeallocating.m +// ReactiveCocoa +// +// Created by Kazuo Koga on 2013/03/15. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTestObject.h" + +#import "NSObject+RACDeallocating.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACSignal+Operations.h" +#import + +@interface RACDeallocSwizzlingTestClass : NSObject +@end + +@implementation RACDeallocSwizzlingTestClass + +- (void)dealloc { + // Provide an empty implementation just so we can swizzle it. +} + +@end + +@interface RACDeallocSwizzlingTestSubclass : RACDeallocSwizzlingTestClass +@end + +@implementation RACDeallocSwizzlingTestSubclass +@end + +QuickSpecBegin(NSObjectRACDeallocatingSpec) + +qck_describe(@"-dealloc swizzling", ^{ + SEL selector = NSSelectorFromString(@"dealloc"); + + qck_it(@"should not invoke superclass -dealloc method twice", ^{ + __block NSUInteger superclassDeallocatedCount = 0; + __block BOOL subclassDeallocated = NO; + + @autoreleasepool { + RACDeallocSwizzlingTestSubclass *object __attribute__((objc_precise_lifetime)) = [[RACDeallocSwizzlingTestSubclass alloc] init]; + + Method oldDeallocMethod = class_getInstanceMethod(RACDeallocSwizzlingTestClass.class, selector); + void (*oldDealloc)(id, SEL) = (__typeof__(oldDealloc))method_getImplementation(oldDeallocMethod); + + id newDealloc = ^(__unsafe_unretained id self) { + superclassDeallocatedCount++; + oldDealloc(self, selector); + }; + + class_replaceMethod(RACDeallocSwizzlingTestClass.class, selector, imp_implementationWithBlock(newDealloc), method_getTypeEncoding(oldDeallocMethod)); + + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + subclassDeallocated = YES; + }]]; + + expect(@(subclassDeallocated)).to(beFalsy()); + expect(@(superclassDeallocatedCount)).to(equal(@0)); + } + + expect(@(subclassDeallocated)).to(beTruthy()); + expect(@(superclassDeallocatedCount)).to(equal(@1)); + }); + + qck_it(@"should invoke superclass -dealloc method swizzled in after the subclass", ^{ + __block BOOL superclassDeallocated = NO; + __block BOOL subclassDeallocated = NO; + + @autoreleasepool { + RACDeallocSwizzlingTestSubclass *object __attribute__((objc_precise_lifetime)) = [[RACDeallocSwizzlingTestSubclass alloc] init]; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + subclassDeallocated = YES; + }]]; + + Method oldDeallocMethod = class_getInstanceMethod(RACDeallocSwizzlingTestClass.class, selector); + void (*oldDealloc)(id, SEL) = (__typeof__(oldDealloc))method_getImplementation(oldDeallocMethod); + + id newDealloc = ^(__unsafe_unretained id self) { + superclassDeallocated = YES; + oldDealloc(self, selector); + }; + + class_replaceMethod(RACDeallocSwizzlingTestClass.class, selector, imp_implementationWithBlock(newDealloc), method_getTypeEncoding(oldDeallocMethod)); + + expect(@(subclassDeallocated)).to(beFalsy()); + expect(@(superclassDeallocated)).to(beFalsy()); + } + + expect(@(subclassDeallocated)).to(beTruthy()); + expect(@(superclassDeallocated)).to(beTruthy()); + }); +}); + +qck_describe(@"-rac_deallocDisposable", ^{ + qck_it(@"should dispose of the disposable when it is dealloc'd", ^{ + __block BOOL wasDisposed = NO; + @autoreleasepool { + NSObject *object __attribute__((objc_precise_lifetime)) = [[NSObject alloc] init]; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + wasDisposed = YES; + }]]; + + expect(@(wasDisposed)).to(beFalsy()); + } + + expect(@(wasDisposed)).to(beTruthy()); + }); + + qck_it(@"should be able to use the object during disposal", ^{ + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + + @autoreleasepool { + object.objectValue = [@"foo" mutableCopy]; + } + + __unsafe_unretained RACTestObject *weakObject = object; + + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + expect(weakObject.objectValue).to(equal(@"foo")); + }]]; + } + }); +}); + +qck_describe(@"-rac_willDeallocSignal", ^{ + qck_it(@"should complete on dealloc", ^{ + __block BOOL completed = NO; + @autoreleasepool { + [[[[RACTestObject alloc] init] rac_willDeallocSignal] subscribeCompleted:^{ + completed = YES; + }]; + } + + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should not send anything", ^{ + __block BOOL valueReceived = NO; + __block BOOL completed = NO; + @autoreleasepool { + [[[[RACTestObject alloc] init] rac_willDeallocSignal] subscribeNext:^(id x) { + valueReceived = YES; + } completed:^{ + completed = YES; + }]; + } + + expect(@(valueReceived)).to(beFalsy()); + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should complete upon subscription if already deallocated", ^{ + __block BOOL deallocated = NO; + + RACSignal *signal; + + @autoreleasepool { + RACTestObject *object = [[RACTestObject alloc] init]; + + signal = [object rac_willDeallocSignal]; + [signal subscribeCompleted:^{ + deallocated = YES; + }]; + } + + expect(@(deallocated)).to(beTruthy()); + expect(@([signal waitUntilCompleted:NULL])).to(beTruthy()); + }); + + qck_it(@"should complete before the object is invalid", ^{ + __block NSString *objectValue; + + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + + @autoreleasepool { + object.objectValue = [@"foo" mutableCopy]; + } + + __unsafe_unretained RACTestObject *weakObject = object; + + [[object rac_willDeallocSignal] subscribeCompleted:^{ + objectValue = [weakObject.objectValue copy]; + }]; + } + + expect(objectValue).to(equal(@"foo")); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSObjectRACLiftingSpec.m b/ReactiveCocoaTests/NSObjectRACLiftingSpec.m new file mode 100644 index 0000000000..dd9a8c8310 --- /dev/null +++ b/ReactiveCocoaTests/NSObjectRACLiftingSpec.m @@ -0,0 +1,410 @@ +// +// NSObjectRACLifting.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 10/2/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTestObject.h" + +#import "NSObject+RACLifting.h" +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACPropertySubscribing.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACSubject.h" +#import "RACTuple.h" +#import "RACUnit.h" + +QuickSpecBegin(NSObjectRACLiftingSpec) + +qck_describe(@"-rac_liftSelector:withSignals:", ^{ + __block RACTestObject *object; + + qck_beforeEach(^{ + object = [[RACTestObject alloc] init]; + }); + + qck_it(@"should call the selector with the value of the signal", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setObjectValue:) withSignals:subject, nil]; + + expect(object.objectValue).to(beNil()); + + [subject sendNext:@1]; + expect(object.objectValue).to(equal(@1)); + + [subject sendNext:@42]; + expect(object.objectValue).to(equal(@42)); + }); +}); + +qck_describe(@"-rac_liftSelector:withSignalsFromArray:", ^{ + __block RACTestObject *object; + + qck_beforeEach(^{ + object = [[RACTestObject alloc] init]; + }); + + qck_it(@"should call the selector with the value of the signal", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setObjectValue:) withSignalsFromArray:@[ subject ]]; + + expect(object.objectValue).to(beNil()); + + [subject sendNext:@1]; + expect(object.objectValue).to(equal(@1)); + + [subject sendNext:@42]; + expect(object.objectValue).to(equal(@42)); + }); + + qck_it(@"should call the selector with the value of the signal unboxed", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setIntegerValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(object.integerValue)).to(equal(@0)); + + [subject sendNext:@1]; + expect(@(object.integerValue)).to(equal(@1)); + + [subject sendNext:@42]; + expect(@(object.integerValue)).to(equal(@42)); + }); + + qck_it(@"should work with multiple arguments", ^{ + RACSubject *objectValueSubject = [RACSubject subject]; + RACSubject *integerValueSubject = [RACSubject subject]; + [object rac_liftSelector:@selector(setObjectValue:andIntegerValue:) withSignalsFromArray:@[ objectValueSubject, integerValueSubject ]]; + + expect(@(object.hasInvokedSetObjectValueAndIntegerValue)).to(beFalsy()); + expect(object.objectValue).to(beNil()); + expect(@(object.integerValue)).to(equal(@0)); + + [objectValueSubject sendNext:@1]; + expect(@(object.hasInvokedSetObjectValueAndIntegerValue)).to(beFalsy()); + expect(object.objectValue).to(beNil()); + expect(@(object.integerValue)).to(equal(@0)); + + [integerValueSubject sendNext:@42]; + expect(@(object.hasInvokedSetObjectValueAndIntegerValue)).to(beTruthy()); + expect(object.objectValue).to(equal(@1)); + expect(@(object.integerValue)).to(equal(@42)); + }); + + qck_it(@"should work with signals that immediately start with a value", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setObjectValue:) withSignalsFromArray:@[ [subject startWith:@42] ]]; + + expect(object.objectValue).to(equal(@42)); + + [subject sendNext:@1]; + expect(object.objectValue).to(equal(@1)); + }); + + qck_it(@"should work with signals that send nil", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setObjectValue:) withSignalsFromArray:@[ subject ]]; + + [subject sendNext:nil]; + expect(object.objectValue).to(beNil()); + + [subject sendNext:RACTupleNil.tupleNil]; + expect(object.objectValue).to(beNil()); + }); + + qck_it(@"should work with integers", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setIntegerValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(object.integerValue)).to(equal(@0)); + + [subject sendNext:@1]; + expect(@(object.integerValue)).to(equal(@1)); + }); + + qck_it(@"should convert between numeric types", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setIntegerValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(object.integerValue)).to(equal(@0)); + + [subject sendNext:@1.0]; + expect(@(object.integerValue)).to(equal(@1)); + }); + + qck_it(@"should work with class objects", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setObjectValue:) withSignalsFromArray:@[ subject ]]; + + expect(object.objectValue).to(beNil()); + + [subject sendNext:self.class]; + expect(object.objectValue).to(equal(self.class)); + }); + + qck_it(@"should work for char pointer", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setCharPointerValue:) withSignalsFromArray:@[ subject ]]; + + expect([NSValue valueWithPointer:object.charPointerValue]).to(equal([NSValue valueWithPointer:NULL])); + + NSString *string = @"blah blah blah"; + [subject sendNext:string]; + expect(@(object.charPointerValue)).to(equal(string)); + }); + + qck_it(@"should work for const char pointer", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setConstCharPointerValue:) withSignalsFromArray:@[ subject ]]; + + expect([NSValue valueWithPointer:object.constCharPointerValue]).to(equal([NSValue valueWithPointer:NULL])); + + NSString *string = @"blah blah blah"; + [subject sendNext:string]; + expect(@(object.constCharPointerValue)).to(equal(string)); + }); + + qck_it(@"should work for CGRect", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setRectValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(CGRectEqualToRect(object.rectValue, CGRectZero))).to(beTruthy()); + + CGRect value = CGRectMake(10, 20, 30, 40); + [subject sendNext:[NSValue valueWithBytes:&value objCType:@encode(CGRect)]]; + expect(@(CGRectEqualToRect(object.rectValue, value))).to(beTruthy()); + }); + + qck_it(@"should work for CGSize", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setSizeValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(CGSizeEqualToSize(object.sizeValue, CGSizeZero))).to(beTruthy()); + + CGSize value = CGSizeMake(10, 20); + [subject sendNext:[NSValue valueWithBytes:&value objCType:@encode(CGSize)]]; + expect(@(CGSizeEqualToSize(object.sizeValue, value))).to(beTruthy()); + }); + + qck_it(@"should work for CGPoint", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setPointValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(CGPointEqualToPoint(object.pointValue, CGPointZero))).to(beTruthy()); + + CGPoint value = CGPointMake(10, 20); + [subject sendNext:[NSValue valueWithBytes:&value objCType:@encode(CGPoint)]]; + expect(@(CGPointEqualToPoint(object.pointValue, value))).to(beTruthy()); + }); + + qck_it(@"should work for NSRange", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setRangeValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(NSEqualRanges(object.rangeValue, NSMakeRange(0, 0)))).to(beTruthy()); + + NSRange value = NSMakeRange(10, 20); + [subject sendNext:[NSValue valueWithRange:value]]; + expect(@(NSEqualRanges(object.rangeValue, value))).to(beTruthy()); + }); + + qck_it(@"should work for _Bool", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setC99BoolValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(object.c99BoolValue)).to(beFalsy()); + + _Bool value = true; + [subject sendNext:@(value)]; + expect(@(object.c99BoolValue)).to(beTruthy()); + }); + + qck_it(@"should work for primitive pointers", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(write5ToIntPointer:) withSignalsFromArray:@[ subject ]]; + + int value = 0; + int *valuePointer = &value; + expect(@(value)).to(equal(@0)); + + [subject sendNext:[NSValue valueWithPointer:valuePointer]]; + expect(@(value)).to(equal(@5)); + }); + + qck_it(@"should work for custom structs", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setStructValue:) withSignalsFromArray:@[ subject ]]; + + expect(@(object.structValue.integerField)).to(equal(@0)); + expect(@(object.structValue.doubleField)).to(equal(@0.0)); + + RACTestStruct value = (RACTestStruct){7, 1.23}; + [subject sendNext:[NSValue valueWithBytes:&value objCType:@encode(typeof(value))]]; + expect(@(object.structValue.integerField)).to(equal(@(value.integerField))); + expect(@(object.structValue.doubleField)).to(equal(@(value.doubleField))); + }); + + qck_it(@"should send the latest value of the signal as the right argument", ^{ + RACSubject *subject = [RACSubject subject]; + [object rac_liftSelector:@selector(setObjectValue:andIntegerValue:) withSignalsFromArray:@[ [RACSignal return:@"object"], subject ]]; + [subject sendNext:@1]; + + expect(object.objectValue).to(equal(@"object")); + expect(@(object.integerValue)).to(equal(@1)); + }); + + qck_describe(@"the returned signal", ^{ + qck_it(@"should send the return value of the method invocation", ^{ + RACSubject *objectSubject = [RACSubject subject]; + RACSubject *integerSubject = [RACSubject subject]; + RACSignal *signal = [object rac_liftSelector:@selector(combineObjectValue:andIntegerValue:) withSignalsFromArray:@[ objectSubject, integerSubject ]]; + + __block NSString *result; + [signal subscribeNext:^(id x) { + result = x; + }]; + + [objectSubject sendNext:@"Magic number"]; + expect(result).to(beNil()); + + [integerSubject sendNext:@42]; + expect(result).to(equal(@"Magic number: 42")); + }); + + qck_it(@"should send RACUnit.defaultUnit for void-returning methods", ^{ + RACSubject *subject = [RACSubject subject]; + RACSignal *signal = [object rac_liftSelector:@selector(setObjectValue:) withSignalsFromArray:@[ subject ]]; + + __block id result; + [signal subscribeNext:^(id x) { + result = x; + }]; + + [subject sendNext:@1]; + + expect(result).to(equal(RACUnit.defaultUnit)); + }); + + qck_it(@"should support integer returning methods", ^{ + RACSubject *subject = [RACSubject subject]; + RACSignal *signal = [object rac_liftSelector:@selector(doubleInteger:) withSignalsFromArray:@[ subject ]]; + + __block id result; + [signal subscribeNext:^(id x) { + result = x; + }]; + + [subject sendNext:@1]; + + expect(result).to(equal(@2)); + }); + + qck_it(@"should support char * returning methods", ^{ + RACSubject *subject = [RACSubject subject]; + RACSignal *signal = [object rac_liftSelector:@selector(doubleString:) withSignalsFromArray:@[ subject ]]; + + __block id result; + [signal subscribeNext:^(id x) { + result = x; + }]; + + [subject sendNext:@"test"]; + + expect(result).to(equal(@"testtest")); + }); + + qck_it(@"should support const char * returning methods", ^{ + RACSubject *subject = [RACSubject subject]; + RACSignal *signal = [object rac_liftSelector:@selector(doubleConstString:) withSignalsFromArray:@[ subject ]]; + + __block id result; + [signal subscribeNext:^(id x) { + result = x; + }]; + + [subject sendNext:@"test"]; + + expect(result).to(equal(@"testtest")); + }); + + qck_it(@"should support struct returning methods", ^{ + RACSubject *subject = [RACSubject subject]; + RACSignal *signal = [object rac_liftSelector:@selector(doubleStruct:) withSignalsFromArray:@[ subject ]]; + + __block NSValue *boxedResult; + [signal subscribeNext:^(id x) { + boxedResult = x; + }]; + + RACTestStruct value = {4, 12.3}; + NSValue *boxedValue = [NSValue valueWithBytes:&value objCType:@encode(typeof(value))]; + [subject sendNext:boxedValue]; + + RACTestStruct result = {0, 0.0}; + [boxedResult getValue:&result]; + expect(@(result.integerField)).to(equal(@8)); + expect(@(result.doubleField)).to(equal(@24.6)); + }); + + qck_it(@"should support block arguments and returns", ^{ + RACSubject *subject = [RACSubject subject]; + RACSignal *signal = [object rac_liftSelector:@selector(wrapBlock:) withSignalsFromArray:@[ subject ]]; + + __block BOOL blockInvoked = NO; + dispatch_block_t testBlock = ^{ + blockInvoked = YES; + }; + + __block dispatch_block_t result; + [signal subscribeNext:^(id x) { + result = x; + }]; + + [subject sendNext:testBlock]; + expect(result).notTo(beNil()); + + result(); + expect(@(blockInvoked)).to(beTruthy()); + }); + + qck_it(@"should replay the last value", ^{ + RACSubject *objectSubject = [RACSubject subject]; + RACSubject *integerSubject = [RACSubject subject]; + RACSignal *signal = [object rac_liftSelector:@selector(combineObjectValue:andIntegerValue:) withSignalsFromArray:@[ objectSubject, integerSubject ]]; + + [objectSubject sendNext:@"Magic number"]; + [integerSubject sendNext:@42]; + [integerSubject sendNext:@43]; + + __block NSString *result; + [signal subscribeNext:^(id x) { + result = x; + }]; + + expect(result).to(equal(@"Magic number: 43")); + }); + }); + + qck_it(@"shouldn't strongly capture the receiver", ^{ + __block BOOL dealloced = NO; + @autoreleasepool { + RACTestObject *testObject __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + [testObject.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + dealloced = YES; + }]]; + + RACSubject *subject = [RACSubject subject]; + [testObject rac_liftSelector:@selector(setObjectValue:) withSignalsFromArray:@[ subject ]]; + [subject sendNext:@1]; + } + + expect(@(dealloced)).to(beTruthy()); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSObjectRACPropertySubscribingExamples.h b/ReactiveCocoaTests/NSObjectRACPropertySubscribingExamples.h new file mode 100644 index 0000000000..694ce597f6 --- /dev/null +++ b/ReactiveCocoaTests/NSObjectRACPropertySubscribingExamples.h @@ -0,0 +1,16 @@ +// +// NSObjectRACPropertySubscribingExamples.h +// ReactiveCocoa +// +// Created by Josh Vera on 4/10/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +// The name of the shared examples for a signal-driven observation. +extern NSString * const RACPropertySubscribingExamples; + +// The block should have the signature: +// RACSignal * (^)(RACTestObject *testObject, NSString *keyPath, id observer) +// and should observe the value of the key path on testObject with observer. The value +// for this key should not be nil. +extern NSString * const RACPropertySubscribingExamplesSetupBlock; diff --git a/ReactiveCocoaTests/NSObjectRACPropertySubscribingExamples.m b/ReactiveCocoaTests/NSObjectRACPropertySubscribingExamples.m new file mode 100644 index 0000000000..ed444a8c0c --- /dev/null +++ b/ReactiveCocoaTests/NSObjectRACPropertySubscribingExamples.m @@ -0,0 +1,223 @@ +// +// NSObjectRACPropertySubscribingExamples.m +// ReactiveCocoa +// +// Created by Josh Vera on 4/10/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTestObject.h" +#import "NSObjectRACPropertySubscribingExamples.h" + +#import "EXTScope.h" +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACPropertySubscribing.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACSignal.h" + +NSString * const RACPropertySubscribingExamples = @"RACPropertySubscribingExamples"; +NSString * const RACPropertySubscribingExamplesSetupBlock = @"RACPropertySubscribingExamplesSetupBlock"; + +QuickSharedExampleGroupsBegin(NSObjectRACPropertySubscribingExamples) + +qck_sharedExamples(RACPropertySubscribingExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block RACSignal *(^signalBlock)(RACTestObject *object, NSString *keyPath, id observer); + + qck_beforeEach(^{ + signalBlock = exampleContext()[RACPropertySubscribingExamplesSetupBlock]; + }); + + qck_it(@"should send the current value once on subscription", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + RACSignal *signal = signalBlock(object, @keypath(object, objectValue), self); + NSMutableArray *values = [NSMutableArray array]; + + object.objectValue = @0; + [signal subscribeNext:^(id x) { + [values addObject:x]; + }]; + + expect(values).to(equal((@[ @0 ]))); + }); + + qck_it(@"should send the new value when it changes", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + RACSignal *signal = signalBlock(object, @keypath(object, objectValue), self); + NSMutableArray *values = [NSMutableArray array]; + + object.objectValue = @0; + [signal subscribeNext:^(id x) { + [values addObject:x]; + }]; + + expect(values).to(equal((@[ @0 ]))); + + object.objectValue = @1; + expect(values).to(equal((@[ @0, @1 ]))); + + }); + + qck_it(@"should stop observing when disposed", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + RACSignal *signal = signalBlock(object, @keypath(object, objectValue), self); + NSMutableArray *values = [NSMutableArray array]; + + object.objectValue = @0; + RACDisposable *disposable = [signal subscribeNext:^(id x) { + [values addObject:x]; + }]; + + object.objectValue = @1; + NSArray *expected = @[ @0, @1 ]; + expect(values).to(equal(expected)); + + [disposable dispose]; + object.objectValue = @2; + expect(values).to(equal(expected)); + }); + + qck_it(@"shouldn't send any more values after the observer is gone", ^{ + __block BOOL observerDealloced = NO; + RACTestObject *object = [[RACTestObject alloc] init]; + NSMutableArray *values = [NSMutableArray array]; + @autoreleasepool { + RACTestObject *observer __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + [observer.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + observerDealloced = YES; + }]]; + + RACSignal *signal = signalBlock(object, @keypath(object, objectValue), observer); + object.objectValue = @1; + [signal subscribeNext:^(id x) { + [values addObject:x]; + }]; + } + + expect(@(observerDealloced)).to(beTruthy()); + + NSArray *expected = @[ @1 ]; + expect(values).to(equal(expected)); + + object.objectValue = @2; + expect(values).to(equal(expected)); + }); + + qck_it(@"shouldn't keep either object alive unnaturally long", ^{ + __block BOOL objectDealloced = NO; + __block BOOL scopeObjectDealloced = NO; + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + objectDealloced = YES; + }]]; + RACTestObject *scopeObject __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + [scopeObject.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + scopeObjectDealloced = YES; + }]]; + + RACSignal *signal = signalBlock(object, @keypath(object, objectValue), scopeObject); + + [signal subscribeNext:^(id _) { + + }]; + } + + expect(@(objectDealloced)).to(beTruthy()); + expect(@(scopeObjectDealloced)).to(beTruthy()); + }); + + qck_it(@"shouldn't keep the signal alive past the lifetime of the object", ^{ + __block BOOL objectDealloced = NO; + __block BOOL signalDealloced = NO; + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + objectDealloced = YES; + }]]; + + RACSignal *signal = [signalBlock(object, @keypath(object, objectValue), self) map:^(id value) { + return value; + }]; + + [signal.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + signalDealloced = YES; + }]]; + + [signal subscribeNext:^(id _) { + + }]; + } + + expect(@(signalDealloced)).toEventually(beTruthy()); + expect(@(objectDealloced)).to(beTruthy()); + }); + + qck_it(@"shouldn't crash when the value is changed on a different queue", ^{ + __block id value; + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + + RACSignal *signal = signalBlock(object, @keypath(object, objectValue), self); + + [signal subscribeNext:^(id x) { + value = x; + }]; + + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + [queue addOperationWithBlock:^{ + object.objectValue = @1; + }]; + + [queue waitUntilAllOperationsAreFinished]; + } + + expect(value).toEventually(equal(@1)); + }); + + qck_describe(@"mutating collections", ^{ + __block RACTestObject *object; + __block NSMutableOrderedSet *lastValue; + __block NSMutableOrderedSet *proxySet; + + qck_beforeEach(^{ + object = [[RACTestObject alloc] init]; + object.objectValue = [NSMutableOrderedSet orderedSetWithObject:@1]; + + NSString *keyPath = @keypath(object, objectValue); + + [signalBlock(object, keyPath, self) subscribeNext:^(NSMutableOrderedSet *x) { + lastValue = x; + }]; + + proxySet = [object mutableOrderedSetValueForKey:keyPath]; + }); + + qck_it(@"sends the newest object when inserting values into an observed object", ^{ + NSMutableOrderedSet *expected = [NSMutableOrderedSet orderedSetWithObjects: @1, @2, nil]; + + [proxySet addObject:@2]; + expect(lastValue).to(equal(expected)); + }); + + qck_it(@"sends the newest object when removing values in an observed object", ^{ + NSMutableOrderedSet *expected = [NSMutableOrderedSet orderedSet]; + + [proxySet removeAllObjects]; + expect(lastValue).to(equal(expected)); + }); + + qck_it(@"sends the newest object when replacing values in an observed object", ^{ + NSMutableOrderedSet *expected = [NSMutableOrderedSet orderedSetWithObjects: @2, nil]; + + [proxySet replaceObjectAtIndex:0 withObject:@2]; + expect(lastValue).to(equal(expected)); + }); + }); + +}); + +QuickSharedExampleGroupsEnd diff --git a/ReactiveCocoaTests/NSObjectRACPropertySubscribingSpec.m b/ReactiveCocoaTests/NSObjectRACPropertySubscribingSpec.m new file mode 100644 index 0000000000..bbd7de457e --- /dev/null +++ b/ReactiveCocoaTests/NSObjectRACPropertySubscribingSpec.m @@ -0,0 +1,158 @@ +// +// NSObjectRACPropertySubscribingSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 9/28/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "NSObjectRACPropertySubscribingExamples.h" +#import "RACTestObject.h" + +#import "NSObject+RACPropertySubscribing.h" +#import "RACDisposable.h" +#import "RACSignal.h" + +QuickSpecBegin(NSObjectRACPropertySubscribingSpec) + +qck_describe(@"-rac_valuesForKeyPath:observer:", ^{ + id (^setupBlock)(id, id, id) = ^(RACTestObject *object, NSString *keyPath, id observer) { + return [object rac_valuesForKeyPath:keyPath observer:observer]; + }; + + qck_itBehavesLike(RACPropertySubscribingExamples, ^{ + return @{ RACPropertySubscribingExamplesSetupBlock: setupBlock }; + }); + +}); + +qck_describe(@"+rac_signalWithChangesFor:keyPath:options:observer:", ^{ + qck_describe(@"KVO options argument", ^{ + __block RACTestObject *object; + __block id actual; + __block RACSignal *(^objectValueSignal)(NSKeyValueObservingOptions); + + qck_beforeEach(^{ + object = [[RACTestObject alloc] init]; + + objectValueSignal = ^(NSKeyValueObservingOptions options) { + return [[object rac_valuesAndChangesForKeyPath:@keypath(object, objectValue) options:options observer:self] reduceEach:^(id value, NSDictionary *change) { + return change; + }]; + }; + }); + + qck_it(@"sends a KVO dictionary", ^{ + [objectValueSignal(0) subscribeNext:^(NSDictionary *x) { + actual = x; + }]; + + object.objectValue = @1; + + expect(actual).to(beAKindOf(NSDictionary.class)); + }); + + qck_it(@"sends a kind key by default", ^{ + [objectValueSignal(0) subscribeNext:^(NSDictionary *x) { + actual = x[NSKeyValueChangeKindKey]; + }]; + + object.objectValue = @1; + + expect(actual).notTo(beNil()); + }); + + qck_it(@"sends the newest changes with NSKeyValueObservingOptionNew", ^{ + [objectValueSignal(NSKeyValueObservingOptionNew) subscribeNext:^(NSDictionary *x) { + actual = x[NSKeyValueChangeNewKey]; + }]; + + object.objectValue = @1; + expect(actual).to(equal(@1)); + + object.objectValue = @2; + expect(actual).to(equal(@2)); + }); + + qck_it(@"sends an additional change value with NSKeyValueObservingOptionPrior", ^{ + NSMutableArray *values = [NSMutableArray new]; + NSArray *expected = @[ @(YES), @(NO) ]; + + [objectValueSignal(NSKeyValueObservingOptionPrior) subscribeNext:^(NSDictionary *x) { + BOOL isPrior = [x[NSKeyValueChangeNotificationIsPriorKey] boolValue]; + [values addObject:@(isPrior)]; + }]; + + object.objectValue = @[ @1 ]; + + expect(values).to(equal(expected)); + }); + + qck_it(@"sends index changes when adding, inserting or removing a value from an observed object", ^{ + __block NSUInteger hasIndexesCount = 0; + + [objectValueSignal(0) subscribeNext:^(NSDictionary *x) { + if (x[NSKeyValueChangeIndexesKey] != nil) { + hasIndexesCount += 1; + } + }]; + + object.objectValue = [NSMutableOrderedSet orderedSet]; + expect(@(hasIndexesCount)).to(equal(@0)); + + NSMutableOrderedSet *objectValue = [object mutableOrderedSetValueForKey:@"objectValue"]; + + [objectValue addObject:@1]; + expect(@(hasIndexesCount)).to(equal(@1)); + + [objectValue replaceObjectAtIndex:0 withObject:@2]; + expect(@(hasIndexesCount)).to(equal(@2)); + + [objectValue removeObject:@2]; + expect(@(hasIndexesCount)).to(equal(@3)); + }); + + qck_it(@"sends the previous value with NSKeyValueObservingOptionOld", ^{ + [objectValueSignal(NSKeyValueObservingOptionOld) subscribeNext:^(NSDictionary *x) { + actual = x[NSKeyValueChangeOldKey]; + }]; + + object.objectValue = @1; + expect(actual).to(equal(NSNull.null)); + + object.objectValue = @2; + expect(actual).to(equal(@1)); + }); + + qck_it(@"sends the initial value with NSKeyValueObservingOptionInitial", ^{ + [objectValueSignal(NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew) subscribeNext:^(NSDictionary *x) { + actual = x[NSKeyValueChangeNewKey]; + }]; + + expect(actual).to(equal(NSNull.null)); + }); + }); +}); + +qck_describe(@"-rac_valuesAndChangesForKeyPath:options:observer:", ^{ + qck_it(@"should complete immediately if the receiver or observer have deallocated", ^{ + RACSignal *signal; + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + RACTestObject *observer __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + signal = [object rac_valuesAndChangesForKeyPath:@keypath(object, stringValue) options:0 observer:observer]; + } + + __block BOOL completed = NO; + [signal subscribeCompleted:^{ + completed = YES; + }]; + + expect(@(completed)).to(beTruthy()); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSObjectRACSelectorSignalSpec.m b/ReactiveCocoaTests/NSObjectRACSelectorSignalSpec.m new file mode 100644 index 0000000000..d7eaebb3fa --- /dev/null +++ b/ReactiveCocoaTests/NSObjectRACSelectorSignalSpec.m @@ -0,0 +1,501 @@ +// +// NSObjectRACSelectorSignalSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 3/18/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTestObject.h" +#import "RACSubclassObject.h" + +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACPropertySubscribing.h" +#import "NSObject+RACSelectorSignal.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACMulticastConnection.h" +#import "RACSignal+Operations.h" +#import "RACSignal.h" +#import "RACTuple.h" + +@protocol TestProtocol + +@required +- (BOOL)requiredMethod:(NSUInteger)number; +- (void)lifeIsGood:(id)sender; + +@optional +- (NSUInteger)optionalMethodWithObject:(id)object flag:(BOOL)flag; +- (id)objectValue; + +@end + +QuickSpecBegin(NSObjectRACSelectorSignalSpec) + +qck_describe(@"RACTestObject", ^{ + qck_it(@"should send the argument for each invocation", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + __block id value; + [[object rac_signalForSelector:@selector(lifeIsGood:)] subscribeNext:^(RACTuple *x) { + value = x.first; + }]; + + [object lifeIsGood:@42]; + + expect(value).to(equal(@42)); + }); + + qck_it(@"should send completed on deallocation", ^{ + __block BOOL completed = NO; + __block BOOL deallocated = NO; + + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocated = YES; + }]]; + + [[object rac_signalForSelector:@selector(lifeIsGood:)] subscribeCompleted:^{ + completed = YES; + }]; + + expect(@(deallocated)).to(beFalsy()); + expect(@(completed)).to(beFalsy()); + } + + expect(@(deallocated)).to(beTruthy()); + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should send for a zero-argument method", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + __block RACTuple *value; + [[object rac_signalForSelector:@selector(objectValue)] subscribeNext:^(RACTuple *x) { + value = x; + }]; + + [object objectValue]; + expect(value).to(equal([RACTuple tupleWithObjectsFromArray:@[]])); + }); + + qck_it(@"should send the argument for each invocation to the instance's own signal", ^{ + RACTestObject *object1 = [[RACTestObject alloc] init]; + __block id value1; + [[object1 rac_signalForSelector:@selector(lifeIsGood:)] subscribeNext:^(RACTuple *x) { + value1 = x.first; + }]; + + RACTestObject *object2 = [[RACTestObject alloc] init]; + __block id value2; + [[object2 rac_signalForSelector:@selector(lifeIsGood:)] subscribeNext:^(RACTuple *x) { + value2 = x.first; + }]; + + [object1 lifeIsGood:@42]; + [object2 lifeIsGood:@"Carpe diem"]; + + expect(value1).to(equal(@42)); + expect(value2).to(equal(@"Carpe diem")); + }); + + qck_it(@"should send multiple arguments for each invocation", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + __block id value1; + __block id value2; + [[object rac_signalForSelector:@selector(combineObjectValue:andSecondObjectValue:)] subscribeNext:^(RACTuple *x) { + value1 = x.first; + value2 = x.second; + }]; + + expect([object combineObjectValue:@42 andSecondObjectValue:@"foo"]).to(equal(@"42: foo")); + expect(value1).to(equal(@42)); + expect(value2).to(equal(@"foo")); + }); + + qck_it(@"should send arguments for invocation of non-existant methods", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + __block id key; + __block id value; + [[object rac_signalForSelector:@selector(setObject:forKey:)] subscribeNext:^(RACTuple *x) { + value = x.first; + key = x.second; + }]; + + [object performSelector:@selector(setObject:forKey:) withObject:@YES withObject:@"Winner"]; + + expect(value).to(equal(@YES)); + expect(key).to(equal(@"Winner")); + }); + + qck_it(@"should send arguments for invocation and invoke the original method on previously KVO'd receiver", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + [[RACObserve(object, objectValue) publish] connect]; + + __block id key; + __block id value; + [[object rac_signalForSelector:@selector(setObjectValue:andSecondObjectValue:)] subscribeNext:^(RACTuple *x) { + value = x.first; + key = x.second; + }]; + + [object setObjectValue:@YES andSecondObjectValue:@"Winner"]; + + expect(@(object.hasInvokedSetObjectValueAndSecondObjectValue)).to(beTruthy()); + expect(object.objectValue).to(equal(@YES)); + expect(object.secondObjectValue).to(equal(@"Winner")); + + expect(value).to(equal(@YES)); + expect(key).to(equal(@"Winner")); + }); + + qck_it(@"should send arguments for invocation and invoke the original method when receiver is subsequently KVO'd", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + __block id key; + __block id value; + [[object rac_signalForSelector:@selector(setObjectValue:andSecondObjectValue:)] subscribeNext:^(RACTuple *x) { + value = x.first; + key = x.second; + }]; + + [[RACObserve(object, objectValue) publish] connect]; + + [object setObjectValue:@YES andSecondObjectValue:@"Winner"]; + + expect(@(object.hasInvokedSetObjectValueAndSecondObjectValue)).to(beTruthy()); + expect(object.objectValue).to(equal(@YES)); + expect(object.secondObjectValue).to(equal(@"Winner")); + + expect(value).to(equal(@YES)); + expect(key).to(equal(@"Winner")); + }); + + qck_it(@"should properly implement -respondsToSelector: when called on KVO'd receiver", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + // First, setup KVO on `object`, which gives us the desired side-effect + // of `object` taking on a KVO-custom subclass. + [[RACObserve(object, objectValue) publish] connect]; + + SEL selector = NSSelectorFromString(@"anyOldSelector:"); + + // With the KVO subclass in place, call -rac_signalForSelector: to + // implement -anyOldSelector: directly on the KVO subclass. + [object rac_signalForSelector:selector]; + + expect(@([object respondsToSelector:selector])).to(beTruthy()); + }); + + qck_it(@"should properly implement -respondsToSelector: when called on signalForSelector'd receiver that has subsequently been KVO'd", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + SEL selector = NSSelectorFromString(@"anyOldSelector:"); + + // Implement -anyOldSelector: on the object first + [object rac_signalForSelector:selector]; + + expect(@([object respondsToSelector:selector])).to(beTruthy()); + + // Then KVO the object + [[RACObserve(object, objectValue) publish] connect]; + + expect(@([object respondsToSelector:selector])).to(beTruthy()); + }); + + qck_it(@"should properly implement -respondsToSelector: when called on signalForSelector'd receiver that has subsequently been KVO'd, then signalForSelector'd again", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + SEL selector = NSSelectorFromString(@"anyOldSelector:"); + + // Implement -anyOldSelector: on the object first + [object rac_signalForSelector:selector]; + + expect(@([object respondsToSelector:selector])).to(beTruthy()); + + // Then KVO the object + [[RACObserve(object, objectValue) publish] connect]; + + expect(@([object respondsToSelector:selector])).to(beTruthy()); + + SEL selector2 = NSSelectorFromString(@"anotherSelector:"); + + // Then implement -anotherSelector: on the object + [object rac_signalForSelector:selector2]; + + expect(@([object respondsToSelector:selector2])).to(beTruthy()); + }); + + qck_it(@"should call the right signal for two instances of the same class, adding signals for the same selector", ^{ + RACTestObject *object1 = [[RACTestObject alloc] init]; + RACTestObject *object2 = [[RACTestObject alloc] init]; + + SEL selector = NSSelectorFromString(@"lifeIsGood:"); + + __block id value1 = nil; + [[object1 rac_signalForSelector:selector] subscribeNext:^(RACTuple *x) { + value1 = x.first; + }]; + + __block id value2 = nil; + [[object2 rac_signalForSelector:selector] subscribeNext:^(RACTuple *x) { + value2 = x.first; + }]; + + [object1 lifeIsGood:@42]; + expect(value1).to(equal(@42)); + expect(value2).to(beNil()); + + [object2 lifeIsGood:@420]; + expect(value1).to(equal(@42)); + expect(value2).to(equal(@420)); + }); + + qck_it(@"should properly implement -respondsToSelector: for optional method from a protocol", ^{ + // Selector for the targeted optional method from a protocol. + SEL selector = @selector(optionalProtocolMethodWithObjectValue:); + + RACTestObject *object1 = [[RACTestObject alloc] init]; + + // Method implementation of the selector is added to its swizzled class. + [object1 rac_signalForSelector:selector fromProtocol:@protocol(RACTestProtocol)]; + + expect(@([object1 respondsToSelector:selector])).to(beTruthy()); + + RACTestObject *object2 = [[RACTestObject alloc] init]; + + // Call -rac_signalForSelector: to swizzle this instance's class, + // method implementations of -respondsToSelector: and + // -forwardInvocation:. + [object2 rac_signalForSelector:@selector(lifeIsGood:)]; + + // This instance should not respond to the selector because of not + // calling -rac_signalForSelector: with the selector. + expect(@([object2 respondsToSelector:selector])).to(beFalsy()); + }); + + qck_it(@"should send non-object arguments", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + __block id value; + [[object rac_signalForSelector:@selector(setIntegerValue:)] subscribeNext:^(RACTuple *x) { + value = x.first; + }]; + + object.integerValue = 42; + expect(value).to(equal(@42)); + }); + + qck_it(@"should send on signal after the original method is invoked", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + __block BOOL invokedMethodBefore = NO; + [[object rac_signalForSelector:@selector(setObjectValue:andSecondObjectValue:)] subscribeNext:^(RACTuple *x) { + invokedMethodBefore = object.hasInvokedSetObjectValueAndSecondObjectValue; + }]; + + [object setObjectValue:@YES andSecondObjectValue:@"Winner"]; + expect(@(invokedMethodBefore)).to(beTruthy()); + }); +}); + +qck_it(@"should swizzle an NSObject method", ^{ + NSObject *object = [[NSObject alloc] init]; + + __block RACTuple *value; + [[object rac_signalForSelector:@selector(description)] subscribeNext:^(RACTuple *x) { + value = x; + }]; + + expect([object description]).notTo(beNil()); + expect(value).to(equal([RACTuple tupleWithObjectsFromArray:@[]])); +}); + +qck_describe(@"a class that already overrides -forwardInvocation:", ^{ + qck_it(@"should invoke the superclass' implementation", ^{ + RACSubclassObject *object = [[RACSubclassObject alloc] init]; + + __block id value; + [[object rac_signalForSelector:@selector(lifeIsGood:)] subscribeNext:^(RACTuple *x) { + value = x.first; + }]; + + [object lifeIsGood:@42]; + expect(value).to(equal(@42)); + + expect([NSValue valueWithPointer:object.forwardedSelector]).to(equal([NSValue valueWithPointer:NULL])); + + [object performSelector:@selector(allObjects)]; + + expect(value).to(equal(@42)); + expect(NSStringFromSelector(object.forwardedSelector)).to(equal(@"allObjects")); + }); + + qck_it(@"should not infinite recurse when KVO'd after RAC swizzled", ^{ + RACSubclassObject *object = [[RACSubclassObject alloc] init]; + + __block id value; + [[object rac_signalForSelector:@selector(lifeIsGood:)] subscribeNext:^(RACTuple *x) { + value = x.first; + }]; + + [[RACObserve(object, objectValue) publish] connect]; + + [object lifeIsGood:@42]; + expect(value).to(equal(@42)); + + expect([NSValue valueWithPointer:object.forwardedSelector]).to(equal([NSValue valueWithPointer:NULL])); + [object performSelector:@selector(allObjects)]; + expect(NSStringFromSelector(object.forwardedSelector)).to(equal(@"allObjects")); + }); +}); + +qck_describe(@"two classes in the same hierarchy", ^{ + __block RACTestObject *superclassObj; + __block RACTuple *superclassTuple; + + __block RACSubclassObject *subclassObj; + __block RACTuple *subclassTuple; + + qck_beforeEach(^{ + superclassObj = [[RACTestObject alloc] init]; + expect(superclassObj).notTo(beNil()); + + subclassObj = [[RACSubclassObject alloc] init]; + expect(subclassObj).notTo(beNil()); + }); + + qck_it(@"should not collide", ^{ + [[superclassObj rac_signalForSelector:@selector(combineObjectValue:andIntegerValue:)] subscribeNext:^(RACTuple *t) { + superclassTuple = t; + }]; + + [[subclassObj rac_signalForSelector:@selector(combineObjectValue:andIntegerValue:)] subscribeNext:^(RACTuple *t) { + subclassTuple = t; + }]; + + expect([superclassObj combineObjectValue:@"foo" andIntegerValue:42]).to(equal(@"foo: 42")); + + NSArray *expectedValues = @[ @"foo", @42 ]; + expect(superclassTuple.allObjects).to(equal(expectedValues)); + + expect([subclassObj combineObjectValue:@"foo" andIntegerValue:42]).to(equal(@"fooSUBCLASS: 42")); + + expectedValues = @[ @"foo", @42 ]; + expect(subclassTuple.allObjects).to(equal(expectedValues)); + }); + + qck_it(@"should not collide when the superclass is invoked asynchronously", ^{ + [[superclassObj rac_signalForSelector:@selector(setObjectValue:andSecondObjectValue:)] subscribeNext:^(RACTuple *t) { + superclassTuple = t; + }]; + + [[subclassObj rac_signalForSelector:@selector(setObjectValue:andSecondObjectValue:)] subscribeNext:^(RACTuple *t) { + subclassTuple = t; + }]; + + [superclassObj setObjectValue:@"foo" andSecondObjectValue:@"42"]; + expect(@(superclassObj.hasInvokedSetObjectValueAndSecondObjectValue)).to(beTruthy()); + + NSArray *expectedValues = @[ @"foo", @"42" ]; + expect(superclassTuple.allObjects).to(equal(expectedValues)); + + [subclassObj setObjectValue:@"foo" andSecondObjectValue:@"42"]; + expect(@(subclassObj.hasInvokedSetObjectValueAndSecondObjectValue)).to(beFalsy()); + expect(@(subclassObj.hasInvokedSetObjectValueAndSecondObjectValue)).toEventually(beTruthy()); + + expectedValues = @[ @"foo", @"42" ]; + expect(subclassTuple.allObjects).to(equal(expectedValues)); + }); +}); + +qck_describe(@"-rac_signalForSelector:fromProtocol", ^{ + __block RACTestObject *object; + __block Protocol *protocol; + + qck_beforeEach(^{ + object = (id)[[RACTestObject alloc] init]; + expect(object).notTo(beNil()); + + protocol = @protocol(TestProtocol); + expect(protocol).notTo(beNil()); + }); + + qck_it(@"should not clobber a required method already implemented", ^{ + __block id value; + [[object rac_signalForSelector:@selector(lifeIsGood:) fromProtocol:protocol] subscribeNext:^(RACTuple *x) { + value = x.first; + }]; + + [object lifeIsGood:@42]; + expect(value).to(equal(@42)); + }); + + qck_it(@"should not clobber an optional method already implemented", ^{ + object.objectValue = @"foo"; + + __block id value; + [[object rac_signalForSelector:@selector(objectValue) fromProtocol:protocol] subscribeNext:^(RACTuple *x) { + value = x; + }]; + + expect([object objectValue]).to(equal(@"foo")); + expect(value).to(equal([RACTuple tupleWithObjectsFromArray:@[]])); + }); + + qck_it(@"should inject a required method", ^{ + __block id value; + [[object rac_signalForSelector:@selector(requiredMethod:) fromProtocol:protocol] subscribeNext:^(RACTuple *x) { + value = x.first; + }]; + + expect(@([object requiredMethod:42])).to(beFalsy()); + expect(value).to(equal(@42)); + }); + + qck_it(@"should inject an optional method", ^{ + __block id value; + [[object rac_signalForSelector:@selector(optionalMethodWithObject:flag:) fromProtocol:protocol] subscribeNext:^(RACTuple *x) { + value = x; + }]; + + expect(@([object optionalMethodWithObject:@"foo" flag:YES])).to(equal(@0)); + expect(value).to(equal(RACTuplePack(@"foo", @YES))); + }); +}); + +qck_describe(@"class reporting", ^{ + __block RACTestObject *object; + __block Class originalClass; + + qck_beforeEach(^{ + object = [[RACTestObject alloc] init]; + originalClass = object.class; + }); + + qck_it(@"should report the original class", ^{ + [object rac_signalForSelector:@selector(lifeIsGood:)]; + expect(object.class).to(beIdenticalTo(originalClass)); + }); + + qck_it(@"should report the original class when it's KVO'd after dynamically subclassing", ^{ + [object rac_signalForSelector:@selector(lifeIsGood:)]; + [[RACObserve(object, objectValue) publish] connect]; + expect(object.class).to(beIdenticalTo(originalClass)); + }); + + qck_it(@"should report the original class when it's KVO'd before dynamically subclassing", ^{ + [[RACObserve(object, objectValue) publish] connect]; + [object rac_signalForSelector:@selector(lifeIsGood:)]; + expect(object.class).to(beIdenticalTo(originalClass)); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSStringRACKeyPathUtilitiesSpec.m b/ReactiveCocoaTests/NSStringRACKeyPathUtilitiesSpec.m new file mode 100644 index 0000000000..f39497a5ed --- /dev/null +++ b/ReactiveCocoaTests/NSStringRACKeyPathUtilitiesSpec.m @@ -0,0 +1,54 @@ +// +// NSStringRACKeyPathUtilitiesSpec.m +// ReactiveCocoa +// +// Created by Uri Baghin on 05/05/2013. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "NSString+RACKeyPathUtilities.h" + +QuickSpecBegin(NSStringRACKeyPathUtilitiesSpec) + +qck_describe(@"-keyPathComponents", ^{ + qck_it(@"should return components in the key path", ^{ + expect(@"self.test.key.path".rac_keyPathComponents).to(equal((@[@"self", @"test", @"key", @"path"]))); + }); + + qck_it(@"should return nil if given an empty string", ^{ + expect(@"".rac_keyPathComponents).to(beNil()); + }); +}); + +qck_describe(@"-keyPathByDeletingLastKeyPathComponent", ^{ + qck_it(@"should return the parent key path", ^{ + expect(@"grandparent.parent.child".rac_keyPathByDeletingLastKeyPathComponent).to(equal(@"grandparent.parent")); + }); + + qck_it(@"should return nil if given an empty string", ^{ + expect(@"".rac_keyPathByDeletingLastKeyPathComponent).to(beNil()); + }); + + qck_it(@"should return nil if given a key path with only one component", ^{ + expect(@"self".rac_keyPathByDeletingLastKeyPathComponent).to(beNil()); + }); +}); + +qck_describe(@"-keyPathByDeletingFirstKeyPathComponent", ^{ + qck_it(@"should return the remaining key path", ^{ + expect(@"first.second.third".rac_keyPathByDeletingFirstKeyPathComponent).to(equal(@"second.third")); + }); + + qck_it(@"should return nil if given an empty string", ^{ + expect(@"".rac_keyPathByDeletingFirstKeyPathComponent).to(beNil()); + }); + + qck_it(@"should return nil if given a key path with only one component", ^{ + expect(@"self".rac_keyPathByDeletingFirstKeyPathComponent).to(beNil()); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSURLConnectionRACSupportSpec.m b/ReactiveCocoaTests/NSURLConnectionRACSupportSpec.m new file mode 100644 index 0000000000..68c2e0af7b --- /dev/null +++ b/ReactiveCocoaTests/NSURLConnectionRACSupportSpec.m @@ -0,0 +1,39 @@ +// +// NSURLConnectionRACSupportSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-10-01. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "NSURLConnection+RACSupport.h" +#import "RACSignal+Operations.h" +#import "RACTuple.h" + +QuickSpecBegin(NSURLConnectionRACSupportSpec) + +qck_it(@"should fetch a JSON file", ^{ + NSURL *fileURL = [[NSBundle bundleForClass:self.class] URLForResource:@"test-data" withExtension:@"json"]; + expect(fileURL).notTo(beNil()); + + NSURLRequest *request = [NSURLRequest requestWithURL:fileURL]; + + BOOL success = NO; + NSError *error = nil; + RACTuple *result = [[NSURLConnection rac_sendAsynchronousRequest:request] firstOrDefault:nil success:&success error:&error]; + expect(@(success)).to(beTruthy()); + expect(error).to(beNil()); + expect(result).to(beAKindOf(RACTuple.class)); + + NSURLResponse *response = result.first; + expect(response).to(beAKindOf(NSURLResponse.class)); + + NSData *data = result.second; + expect(data).to(beAKindOf(NSData.class)); + expect(data).to(equal([NSData dataWithContentsOfURL:fileURL])); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/NSUserDefaultsRACSupportSpec.m b/ReactiveCocoaTests/NSUserDefaultsRACSupportSpec.m new file mode 100644 index 0000000000..068474d6bf --- /dev/null +++ b/ReactiveCocoaTests/NSUserDefaultsRACSupportSpec.m @@ -0,0 +1,136 @@ +// +// NSUserDefaultsRACSupportSpec.m +// ReactiveCocoa +// +// Created by Matt Diephouse on 12/19/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "NSUserDefaults+RACSupport.h" + +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACKVOChannel.h" +#import "NSObject+RACDeallocating.h" +#import "RACSignal+Operations.h" + +static NSString * const NSUserDefaultsRACSupportSpecStringDefault = @"NSUserDefaultsRACSupportSpecStringDefault"; +static NSString * const NSUserDefaultsRACSupportSpecBoolDefault = @"NSUserDefaultsRACSupportSpecBoolDefault"; + +@interface TestObserver : NSObject + +@property (copy, atomic) NSString *string1; +@property (copy, atomic) NSString *string2; + +@property (assign, atomic) BOOL bool1; + +@end + +@implementation TestObserver + +@end + +QuickSpecBegin(NSUserDefaultsRACSupportSpec) + +__block NSUserDefaults *defaults = nil; +__block TestObserver *observer = nil; + +qck_beforeEach(^{ + defaults = NSUserDefaults.standardUserDefaults; + [defaults removeObjectForKey:NSUserDefaultsRACSupportSpecStringDefault]; + [defaults removeObjectForKey:NSUserDefaultsRACSupportSpecBoolDefault]; + + observer = [TestObserver new]; +}); + +qck_afterEach(^{ + observer = nil; +}); + +qck_it(@"should set defaults", ^{ + RACChannelTo(observer, string1) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault]; + RACChannelTo(observer, bool1, @NO) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecBoolDefault]; + + observer.string1 = @"A string"; + observer.bool1 = YES; + + expect([defaults objectForKey:NSUserDefaultsRACSupportSpecStringDefault]).toEventually(equal(@"A string")); + expect([defaults objectForKey:NSUserDefaultsRACSupportSpecBoolDefault]).toEventually(equal(@YES)); +}); + +qck_it(@"should read defaults", ^{ + RACChannelTo(observer, string1) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault]; + RACChannelTo(observer, bool1, @NO) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecBoolDefault]; + + expect(observer.string1).to(beNil()); + expect(@(observer.bool1)).to(equal(@NO)); + + [defaults setObject:@"Another string" forKey:NSUserDefaultsRACSupportSpecStringDefault]; + [defaults setBool:YES forKey:NSUserDefaultsRACSupportSpecBoolDefault]; + + expect(observer.string1).to(equal(@"Another string")); + expect(@(observer.bool1)).to(equal(@YES)); +}); + +qck_it(@"should be okay to create 2 terminals", ^{ + RACChannelTo(observer, string1) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault]; + RACChannelTo(observer, string2) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault]; + + [defaults setObject:@"String 3" forKey:NSUserDefaultsRACSupportSpecStringDefault]; + + expect(observer.string1).to(equal(@"String 3")); + expect(observer.string2).to(equal(@"String 3")); +}); + +qck_it(@"should handle removed defaults", ^{ + observer.string1 = @"Some string"; + observer.bool1 = YES; + + RACChannelTo(observer, string1) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault]; + RACChannelTo(observer, bool1, @NO) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecBoolDefault]; + + [defaults removeObjectForKey:NSUserDefaultsRACSupportSpecStringDefault]; + [defaults removeObjectForKey:NSUserDefaultsRACSupportSpecBoolDefault]; + + expect(observer.string1).to(beNil()); + expect(@(observer.bool1)).to(equal(@NO)); +}); + +qck_it(@"shouldn't resend values", ^{ + RACChannelTerminal *terminal = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault]; + + RACChannelTo(observer, string1) = terminal; + + RACSignal *sentValue = [terminal replayLast]; + observer.string1 = @"Test value"; + id value = [sentValue asynchronousFirstOrDefault:nil success:NULL error:NULL]; + expect(value).to(beNil()); +}); + +qck_it(@"should complete when the NSUserDefaults deallocates", ^{ + __block RACChannelTerminal *terminal; + __block BOOL deallocated = NO; + + @autoreleasepool { + NSUserDefaults *customDefaults __attribute__((objc_precise_lifetime)) = [NSUserDefaults new]; + [customDefaults.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocated = YES; + }]]; + + terminal = [customDefaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault]; + } + + expect(@(deallocated)).to(beTruthy()); + expect(@([terminal asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy()); +}); + +qck_it(@"should send an initial value", ^{ + [defaults setObject:@"Initial" forKey:NSUserDefaultsRACSupportSpecStringDefault]; + RACChannelTerminal *terminal = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault]; + expect([terminal asynchronousFirstOrDefault:nil success:NULL error:NULL]).to(equal(@"Initial")); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACBacktraceSpec.m b/ReactiveCocoaTests/RACBacktraceSpec.m new file mode 100644 index 0000000000..d6d453730f --- /dev/null +++ b/ReactiveCocoaTests/RACBacktraceSpec.m @@ -0,0 +1,151 @@ +// +// RACBacktraceSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-12-24. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACBacktrace.h" + +#import "NSArray+RACSequenceAdditions.h" +#import "RACReplaySubject.h" +#import "RACScheduler.h" +#import "RACSequence.h" +#import "RACSignal+Operations.h" + +#ifdef RAC_DEBUG_BACKTRACE + +static RACBacktrace *previousBacktrace; + +static void capturePreviousBacktrace(void *context) { + previousBacktrace = [RACBacktrace backtrace].previousThreadBacktrace; +} + +typedef struct { + dispatch_queue_t queue; + NSUInteger i; + __unsafe_unretained RACSubject *doneSubject; +} RACDeepRecursionContext; + +static void recurseDeeply(void *ptr) { + RACDeepRecursionContext *context = ptr; + + if (context->i++ < 10000) { + rac_dispatch_async_f(context->queue, context, recurseDeeply); + } else { + [context->doneSubject sendCompleted]; + } +} + +QuickSpecBegin(RACBacktraceSpec) + +__block dispatch_block_t block; + +qck_beforeEach(^{ + expect([RACBacktrace backtrace].previousThreadBacktrace).to(beNil()); + previousBacktrace = nil; + + block = ^{ + capturePreviousBacktrace(NULL); + }; +}); + +qck_it(@"should capture the current backtrace", ^{ + RACBacktrace *backtrace = [RACBacktrace backtrace]; + expect(backtrace).notTo(beNil()); +}); + +qck_describe(@"with a GCD queue", ^{ + __block dispatch_queue_t queue; + + qck_beforeEach(^{ + queue = dispatch_queue_create("com.github.ReactiveCocoa.RACBacktraceSpec", DISPATCH_QUEUE_SERIAL); + }); + + qck_afterEach(^{ + dispatch_barrier_sync(queue, ^{}); + dispatch_release(queue); + }); + + qck_it(@"should trace across dispatch_async", ^{ + rac_dispatch_async(queue, block); + expect(previousBacktrace).toEventuallyNot(beNil()); + }); + + qck_it(@"should trace across dispatch_async to the main thread", ^{ + rac_dispatch_async(queue, ^{ + rac_dispatch_async(dispatch_get_main_queue(), block); + }); + + expect(previousBacktrace).toEventuallyNot(beNil()); + }); + + qck_it(@"should trace across dispatch_async_f", ^{ + rac_dispatch_async_f(queue, NULL, &capturePreviousBacktrace); + expect(previousBacktrace).toEventuallyNot(beNil()); + }); + + qck_it(@"should trace across dispatch_barrier_async", ^{ + rac_dispatch_barrier_async(queue, block); + expect(previousBacktrace).toEventuallyNot(beNil()); + }); + + qck_it(@"should trace across dispatch_barrier_async_f", ^{ + rac_dispatch_barrier_async_f(queue, NULL, &capturePreviousBacktrace); + expect(previousBacktrace).toEventuallyNot(beNil()); + }); + + qck_it(@"should trace across dispatch_after", ^{ + rac_dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1), queue, block); + expect(previousBacktrace).toEventuallyNot(beNil()); + }); + + qck_it(@"should trace across dispatch_after_f", ^{ + rac_dispatch_after_f(dispatch_time(DISPATCH_TIME_NOW, 1), queue, NULL, &capturePreviousBacktrace); + expect(previousBacktrace).toEventuallyNot(beNil()); + }); + + qck_it(@"shouldn't overflow the stack when deallocating a huge backtrace list", ^{ + RACSubject *doneSubject = [RACReplaySubject subject]; + RACDeepRecursionContext context = { + .queue = queue, + .i = 0, + .doneSubject = doneSubject + }; + + rac_dispatch_async_f(queue, &context, &recurseDeeply); + [doneSubject waitUntilCompleted:NULL]; + }); +}); + +qck_it(@"should trace across a RACScheduler", ^{ + [[RACScheduler scheduler] schedule:block]; + expect(previousBacktrace).toEventuallyNot(beNil()); +}); + +qck_it(@"shouldn't go bonkers with RACScheduler", ^{ + NSMutableArray *a = [NSMutableArray array]; + for (NSUInteger i = 0; i < 5000; i++) { + [a addObject:@(i)]; + } + + [[a.rac_sequence signalWithScheduler:[RACScheduler scheduler]] subscribeCompleted:^{}]; +}); + +// Tracing across NSOperationQueue only works on OS X because it depends on +// interposing through dynamic linking +#ifndef __IPHONE_OS_VERSION_MIN_REQUIRED + qck_it(@"should trace across an NSOperationQueue", ^{ + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + [queue addOperationWithBlock:block]; + expect(previousBacktrace).toEventuallyNot(beNil()); + }); +#endif + +QuickSpecEnd + +#endif diff --git a/ReactiveCocoaTests/RACBlockTrampolineSpec.m b/ReactiveCocoaTests/RACBlockTrampolineSpec.m new file mode 100644 index 0000000000..06744ef800 --- /dev/null +++ b/ReactiveCocoaTests/RACBlockTrampolineSpec.m @@ -0,0 +1,51 @@ +// +// RACBlockTrampolineSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 10/28/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACBlockTrampoline.h" +#import "RACTuple.h" + +QuickSpecBegin(RACBlockTrampolineSpec) + +qck_it(@"should invoke the block with the given arguments", ^{ + __block NSString *stringArg; + __block NSNumber *numberArg; + id (^block)(NSString *, NSNumber *) = ^ id (NSString *string, NSNumber *number) { + stringArg = string; + numberArg = number; + return nil; + }; + + [RACBlockTrampoline invokeBlock:block withArguments:RACTuplePack(@"hi", @1)]; + expect(stringArg).to(equal(@"hi")); + expect(numberArg).to(equal(@1)); +}); + +qck_it(@"should return the result of the block invocation", ^{ + NSString * (^block)(NSString *) = ^(NSString *string) { + return string.uppercaseString; + }; + + NSString *result = [RACBlockTrampoline invokeBlock:block withArguments:RACTuplePack(@"hi")]; + expect(result).to(equal(@"HI")); +}); + +qck_it(@"should pass RACTupleNils as nil", ^{ + __block id arg; + id (^block)(id) = ^ id (id obj) { + arg = obj; + return nil; + }; + + [RACBlockTrampoline invokeBlock:block withArguments:RACTuplePack(nil)]; + expect(arg).to(beNil()); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACChannelExamples.h b/ReactiveCocoaTests/RACChannelExamples.h new file mode 100644 index 0000000000..0952fedbba --- /dev/null +++ b/ReactiveCocoaTests/RACChannelExamples.h @@ -0,0 +1,34 @@ +// +// RACChannelExamples.h +// ReactiveCocoa +// +// Created by Uri Baghin on 30/12/2012. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +// The name of the shared examples for RACChannel and its subclasses. +extern NSString * const RACChannelExamples; + +// A block of type `RACChannel * (^)(void)`, which should return a new +// RACChannel. +extern NSString * const RACChannelExampleCreateBlock; + +// The name of the shared examples for any RACChannel class that gets and sets +// a property. +extern NSString * const RACViewChannelExamples; + +// A block of type `NSObject * (^)(void)`, which should create a new test view +// and return it. +extern NSString * const RACViewChannelExampleCreateViewBlock; + +// A block of type `RACChannelTerminal * (^)(NSObject *view)`, which should +// create a new RACChannel to the given test view and return an terminal. +extern NSString * const RACViewChannelExampleCreateTerminalBlock; + +// The key path that will be read/written in RACViewChannelExamples. This +// must lead to an NSNumber or numeric primitive property. +extern NSString * const RACViewChannelExampleKeyPath; + +// A block of type `void (^)(NSObject *view, NSNumber *value)`, which should +// change the given test view's value to the given one. +extern NSString * const RACViewChannelExampleSetViewValueBlock; diff --git a/ReactiveCocoaTests/RACChannelExamples.m b/ReactiveCocoaTests/RACChannelExamples.m new file mode 100644 index 0000000000..3473ed952d --- /dev/null +++ b/ReactiveCocoaTests/RACChannelExamples.m @@ -0,0 +1,301 @@ +// +// RACChannelExamples.m +// ReactiveCocoa +// +// Created by Uri Baghin on 30/12/2012. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACChannelExamples.h" + +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACPropertySubscribing.h" +#import "RACChannel.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACSignal+Operations.h" + +NSString * const RACChannelExamples = @"RACChannelExamples"; +NSString * const RACChannelExampleCreateBlock = @"RACChannelExampleCreateBlock"; + +NSString * const RACViewChannelExamples = @"RACViewChannelExamples"; +NSString * const RACViewChannelExampleCreateViewBlock = @"RACViewChannelExampleCreateViewBlock"; +NSString * const RACViewChannelExampleCreateTerminalBlock = @"RACViewChannelExampleCreateTerminalBlock"; +NSString * const RACViewChannelExampleKeyPath = @"RACViewChannelExampleKeyPath"; +NSString * const RACViewChannelExampleSetViewValueBlock = @"RACViewChannelExampleSetViewValueBlock"; + +QuickSharedExampleGroupsBegin(RACChannelExampleGroups) + +qck_sharedExamples(RACChannelExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block RACChannel * (^getChannel)(void); + __block RACChannel *channel; + + id value1 = @"test value 1"; + id value2 = @"test value 2"; + id value3 = @"test value 3"; + NSArray *values = @[ value1, value2, value3 ]; + + qck_beforeEach(^{ + getChannel = exampleContext()[RACChannelExampleCreateBlock]; + channel = getChannel(); + }); + + qck_it(@"should not send any leadingTerminal value on subscription", ^{ + __block id receivedValue = nil; + + [channel.followingTerminal sendNext:value1]; + [channel.leadingTerminal subscribeNext:^(id x) { + receivedValue = x; + }]; + + expect(receivedValue).to(beNil()); + + [channel.followingTerminal sendNext:value2]; + expect(receivedValue).to(equal(value2)); + }); + + qck_it(@"should send the latest followingTerminal value on subscription", ^{ + __block id receivedValue = nil; + + [channel.leadingTerminal sendNext:value1]; + [[channel.followingTerminal take:1] subscribeNext:^(id x) { + receivedValue = x; + }]; + + expect(receivedValue).to(equal(value1)); + + [channel.leadingTerminal sendNext:value2]; + [[channel.followingTerminal take:1] subscribeNext:^(id x) { + receivedValue = x; + }]; + + expect(receivedValue).to(equal(value2)); + }); + + qck_it(@"should send leadingTerminal values as they change", ^{ + NSMutableArray *receivedValues = [NSMutableArray array]; + [channel.leadingTerminal subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + [channel.followingTerminal sendNext:value1]; + [channel.followingTerminal sendNext:value2]; + [channel.followingTerminal sendNext:value3]; + expect(receivedValues).to(equal(values)); + }); + + qck_it(@"should send followingTerminal values as they change", ^{ + [channel.leadingTerminal sendNext:value1]; + + NSMutableArray *receivedValues = [NSMutableArray array]; + [channel.followingTerminal subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + [channel.leadingTerminal sendNext:value2]; + [channel.leadingTerminal sendNext:value3]; + expect(receivedValues).to(equal(values)); + }); + + qck_it(@"should complete both signals when the leadingTerminal is completed", ^{ + __block BOOL completedLeft = NO; + [channel.leadingTerminal subscribeCompleted:^{ + completedLeft = YES; + }]; + + __block BOOL completedRight = NO; + [channel.followingTerminal subscribeCompleted:^{ + completedRight = YES; + }]; + + [channel.leadingTerminal sendCompleted]; + expect(@(completedLeft)).to(beTruthy()); + expect(@(completedRight)).to(beTruthy()); + }); + + qck_it(@"should complete both signals when the followingTerminal is completed", ^{ + __block BOOL completedLeft = NO; + [channel.leadingTerminal subscribeCompleted:^{ + completedLeft = YES; + }]; + + __block BOOL completedRight = NO; + [channel.followingTerminal subscribeCompleted:^{ + completedRight = YES; + }]; + + [channel.followingTerminal sendCompleted]; + expect(@(completedLeft)).to(beTruthy()); + expect(@(completedRight)).to(beTruthy()); + }); + + qck_it(@"should replay completion to new subscribers", ^{ + [channel.leadingTerminal sendCompleted]; + + __block BOOL completedLeft = NO; + [channel.leadingTerminal subscribeCompleted:^{ + completedLeft = YES; + }]; + + __block BOOL completedRight = NO; + [channel.followingTerminal subscribeCompleted:^{ + completedRight = YES; + }]; + + expect(@(completedLeft)).to(beTruthy()); + expect(@(completedRight)).to(beTruthy()); + }); +}); + +QuickSharedExampleGroupsEnd + +QuickSharedExampleGroupsBegin(RACViewChannelExampleGroups) + +qck_sharedExamples(RACViewChannelExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block NSString *keyPath; + __block NSObject * (^getView)(void); + __block RACChannelTerminal * (^getTerminal)(NSObject *); + __block void (^setViewValue)(NSObject *view, NSNumber *value); + + __block NSObject *testView; + __block RACChannelTerminal *endpoint; + + qck_beforeEach(^{ + keyPath = exampleContext()[RACViewChannelExampleKeyPath]; + getTerminal = exampleContext()[RACViewChannelExampleCreateTerminalBlock]; + getView = exampleContext()[RACViewChannelExampleCreateViewBlock]; + setViewValue = exampleContext()[RACViewChannelExampleSetViewValueBlock]; + + testView = getView(); + endpoint = getTerminal(testView); + }); + + qck_it(@"should not send changes made by the channel itself", ^{ + __block BOOL receivedNext = NO; + [endpoint subscribeNext:^(id x) { + receivedNext = YES; + }]; + + expect(@(receivedNext)).to(beFalsy()); + + [endpoint sendNext:@0.1]; + expect(@(receivedNext)).to(beFalsy()); + + [endpoint sendNext:@0.2]; + expect(@(receivedNext)).to(beFalsy()); + + [endpoint sendCompleted]; + expect(@(receivedNext)).to(beFalsy()); + }); + + qck_it(@"should not send progammatic changes made to the view", ^{ + __block BOOL receivedNext = NO; + [endpoint subscribeNext:^(id x) { + receivedNext = YES; + }]; + + expect(@(receivedNext)).to(beFalsy()); + + [testView setValue:@0.1 forKeyPath:keyPath]; + expect(@(receivedNext)).to(beFalsy()); + + [testView setValue:@0.2 forKeyPath:keyPath]; + expect(@(receivedNext)).to(beFalsy()); + }); + + qck_it(@"should not have a starting value", ^{ + __block BOOL receivedNext = NO; + [endpoint subscribeNext:^(id x) { + receivedNext = YES; + }]; + + expect(@(receivedNext)).to(beFalsy()); + }); + + qck_it(@"should send view changes", ^{ + __block NSString *received; + [endpoint subscribeNext:^(id x) { + received = x; + }]; + + setViewValue(testView, @0.1); + expect(received).to(equal(@0.1)); + + setViewValue(testView, @0.2); + expect(received).to(equal(@0.2)); + }); + + qck_it(@"should set values on the view", ^{ + [endpoint sendNext:@0.1]; + expect([testView valueForKeyPath:keyPath]).to(equal(@0.1)); + + [endpoint sendNext:@0.2]; + expect([testView valueForKeyPath:keyPath]).to(equal(@0.2)); + }); + + qck_it(@"should not echo changes back to the channel", ^{ + __block NSUInteger receivedCount = 0; + [endpoint subscribeNext:^(id _) { + receivedCount++; + }]; + + expect(@(receivedCount)).to(equal(@0)); + + [endpoint sendNext:@0.1]; + expect(@(receivedCount)).to(equal(@0)); + + setViewValue(testView, @0.2); + expect(@(receivedCount)).to(equal(@1)); + }); + + qck_it(@"should complete when the view deallocates", ^{ + __block BOOL deallocated = NO; + __block BOOL completed = NO; + + @autoreleasepool { + NSObject *view __attribute__((objc_precise_lifetime)) = getView(); + [view.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocated = YES; + }]]; + + RACChannelTerminal *terminal = getTerminal(view); + [terminal subscribeCompleted:^{ + completed = YES; + }]; + + expect(@(deallocated)).to(beFalsy()); + expect(@(completed)).to(beFalsy()); + } + + expect(@(deallocated)).to(beTruthy()); + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should deallocate after the view deallocates", ^{ + __block BOOL viewDeallocated = NO; + __block BOOL terminalDeallocated = NO; + + @autoreleasepool { + NSObject *view __attribute__((objc_precise_lifetime)) = getView(); + [view.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + viewDeallocated = YES; + }]]; + + RACChannelTerminal *terminal = getTerminal(view); + [terminal.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + terminalDeallocated = YES; + }]]; + + expect(@(viewDeallocated)).to(beFalsy()); + expect(@(terminalDeallocated)).to(beFalsy()); + } + + expect(@(viewDeallocated)).to(beTruthy()); + expect(@(terminalDeallocated)).toEventually(beTruthy()); + }); +}); + +QuickSharedExampleGroupsEnd diff --git a/ReactiveCocoaTests/RACChannelSpec.m b/ReactiveCocoaTests/RACChannelSpec.m new file mode 100644 index 0000000000..9f6cb7acc9 --- /dev/null +++ b/ReactiveCocoaTests/RACChannelSpec.m @@ -0,0 +1,76 @@ +// +// RACChannelSpec.m +// ReactiveCocoa +// +// Created by Uri Baghin on 30/12/2012. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACChannelExamples.h" + +#import "NSObject+RACDeallocating.h" +#import "RACChannel.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACSignal.h" + +QuickSpecBegin(RACChannelSpec) + +qck_describe(@"RACChannel", ^{ + qck_itBehavesLike(RACChannelExamples, ^{ + return @{ + RACChannelExampleCreateBlock: [^{ + return [[RACChannel alloc] init]; + } copy] + }; + }); + + qck_describe(@"memory management", ^{ + qck_it(@"should dealloc when its subscribers are disposed", ^{ + RACDisposable *leadingDisposable = nil; + RACDisposable *followingDisposable = nil; + + __block BOOL deallocated = NO; + + @autoreleasepool { + RACChannel *channel __attribute__((objc_precise_lifetime)) = [[RACChannel alloc] init]; + [channel.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocated = YES; + }]]; + + leadingDisposable = [channel.leadingTerminal subscribeCompleted:^{}]; + followingDisposable = [channel.followingTerminal subscribeCompleted:^{}]; + } + + [leadingDisposable dispose]; + [followingDisposable dispose]; + expect(@(deallocated)).toEventually(beTruthy()); + }); + + qck_it(@"should dealloc when its subscriptions are disposed", ^{ + RACDisposable *leadingDisposable = nil; + RACDisposable *followingDisposable = nil; + + __block BOOL deallocated = NO; + + @autoreleasepool { + RACChannel *channel __attribute__((objc_precise_lifetime)) = [[RACChannel alloc] init]; + [channel.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocated = YES; + }]]; + + leadingDisposable = [[RACSignal never] subscribe:channel.leadingTerminal]; + followingDisposable = [[RACSignal never] subscribe:channel.followingTerminal]; + } + + [leadingDisposable dispose]; + [followingDisposable dispose]; + expect(@(deallocated)).toEventually(beTruthy()); + }); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACCommandSpec.m b/ReactiveCocoaTests/RACCommandSpec.m new file mode 100644 index 0000000000..11f60427f6 --- /dev/null +++ b/ReactiveCocoaTests/RACCommandSpec.m @@ -0,0 +1,529 @@ +// +// RACCommandSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 8/31/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "NSArray+RACSequenceAdditions.h" +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACPropertySubscribing.h" +#import "RACCommand.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACEvent.h" +#import "RACScheduler.h" +#import "RACSequence.h" +#import "RACSignal+Operations.h" +#import "RACSubject.h" +#import "RACUnit.h" + +QuickSpecBegin(RACCommandSpec) + +RACSignal * (^emptySignalBlock)(id) = ^(id _) { + return [RACSignal empty]; +}; + +qck_describe(@"with a simple signal block", ^{ + __block RACCommand *command; + + qck_beforeEach(^{ + command = [[RACCommand alloc] initWithSignalBlock:^(id value) { + return [RACSignal return:value]; + }]; + + expect(command).notTo(beNil()); + expect(@(command.allowsConcurrentExecution)).to(beFalsy()); + }); + + qck_it(@"should be enabled by default", ^{ + expect([command.enabled first]).to(equal(@YES)); + }); + + qck_it(@"should not be executing by default", ^{ + expect([command.executing first]).to(equal(@NO)); + }); + + qck_it(@"should create an execution signal", ^{ + __block NSUInteger signalsReceived = 0; + __block BOOL completed = NO; + + id value = NSNull.null; + [command.executionSignals subscribeNext:^(RACSignal *signal) { + signalsReceived++; + + [signal subscribeNext:^(id x) { + expect(x).to(equal(value)); + } completed:^{ + completed = YES; + }]; + }]; + + expect(@(signalsReceived)).to(equal(@0)); + + [command execute:value]; + expect(@(signalsReceived)).toEventually(equal(@1)); + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should return the execution signal from -execute:", ^{ + __block BOOL completed = NO; + + id value = NSNull.null; + [[command + execute:value] + subscribeNext:^(id x) { + expect(x).to(equal(value)); + } completed:^{ + completed = YES; + }]; + + expect(@(completed)).toEventually(beTruthy()); + }); + + qck_it(@"should always send executionSignals on the main thread", ^{ + __block RACScheduler *receivedScheduler = nil; + [command.executionSignals subscribeNext:^(id _) { + receivedScheduler = RACScheduler.currentScheduler; + }]; + + [[RACScheduler scheduler] schedule:^{ + expect(@([[command execute:nil] waitUntilCompleted:NULL])).to(beTruthy()); + }]; + + expect(receivedScheduler).to(beNil()); + expect(receivedScheduler).toEventually(equal(RACScheduler.mainThreadScheduler)); + }); + + qck_it(@"should not send anything on 'errors' by default", ^{ + __block BOOL receivedError = NO; + [command.errors subscribeNext:^(id _) { + receivedError = YES; + }]; + + expect(@([[command execute:nil] asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy()); + expect(@(receivedError)).to(beFalsy()); + }); + + qck_it(@"should be executing while an execution signal is running", ^{ + [command.executionSignals subscribeNext:^(RACSignal *signal) { + [signal subscribeNext:^(id x) { + expect([command.executing first]).to(equal(@YES)); + }]; + }]; + + expect(@([[command execute:nil] asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy()); + expect([command.executing first]).to(equal(@NO)); + }); + + qck_it(@"should always update executing on the main thread", ^{ + __block RACScheduler *updatedScheduler = nil; + [[command.executing skip:1] subscribeNext:^(NSNumber *executing) { + if (!executing.boolValue) return; + + updatedScheduler = RACScheduler.currentScheduler; + }]; + + [[RACScheduler scheduler] schedule:^{ + expect(@([[command execute:nil] waitUntilCompleted:NULL])).to(beTruthy()); + }]; + + expect([command.executing first]).to(equal(@NO)); + expect(updatedScheduler).toEventually(equal(RACScheduler.mainThreadScheduler)); + }); + + qck_it(@"should dealloc without subscribers", ^{ + __block BOOL disposed = NO; + + @autoreleasepool { + RACCommand *command __attribute__((objc_precise_lifetime)) = [[RACCommand alloc] initWithSignalBlock:emptySignalBlock]; + [command.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + disposed = YES; + }]]; + } + + expect(@(disposed)).toEventually(beTruthy()); + }); + + qck_it(@"should complete signals on the main thread when deallocated", ^{ + __block RACScheduler *executionSignalsScheduler = nil; + __block RACScheduler *executingScheduler = nil; + __block RACScheduler *enabledScheduler = nil; + __block RACScheduler *errorsScheduler = nil; + + [[RACScheduler scheduler] schedule:^{ + @autoreleasepool { + RACCommand *command __attribute__((objc_precise_lifetime)) = [[RACCommand alloc] initWithSignalBlock:emptySignalBlock]; + + [command.executionSignals subscribeCompleted:^{ + executionSignalsScheduler = RACScheduler.currentScheduler; + }]; + + [command.executing subscribeCompleted:^{ + executingScheduler = RACScheduler.currentScheduler; + }]; + + [command.enabled subscribeCompleted:^{ + enabledScheduler = RACScheduler.currentScheduler; + }]; + + [command.errors subscribeCompleted:^{ + errorsScheduler = RACScheduler.currentScheduler; + }]; + } + }]; + + expect(executionSignalsScheduler).toEventually(equal(RACScheduler.mainThreadScheduler)); + expect(executingScheduler).toEventually(equal(RACScheduler.mainThreadScheduler)); + expect(enabledScheduler).toEventually(equal(RACScheduler.mainThreadScheduler)); + expect(errorsScheduler).toEventually(equal(RACScheduler.mainThreadScheduler)); + }); +}); + +qck_it(@"should invoke the signalBlock once per execution", ^{ + NSMutableArray *valuesReceived = [NSMutableArray array]; + RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(id x) { + [valuesReceived addObject:x]; + return [RACSignal empty]; + }]; + + expect(@([[command execute:@"foo"] asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy()); + expect(valuesReceived).to(equal((@[ @"foo" ]))); + + expect(@([[command execute:@"bar"] asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy()); + expect(valuesReceived).to(equal((@[ @"foo", @"bar" ]))); +}); + +qck_it(@"should send on executionSignals in order of execution", ^{ + RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(RACSequence *seq) { + return [seq signalWithScheduler:RACScheduler.immediateScheduler]; + }]; + + NSMutableArray *valuesReceived = [NSMutableArray array]; + [[command.executionSignals + concat] + subscribeNext:^(id x) { + [valuesReceived addObject:x]; + }]; + + RACSequence *first = @[ @"foo", @"bar" ].rac_sequence; + expect(@([[command execute:first] asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy()); + + RACSequence *second = @[ @"buzz", @"baz" ].rac_sequence; + expect(@([[command execute:second] asynchronouslyWaitUntilCompleted:NULL])).toEventually(beTruthy()); + + NSArray *expectedValues = @[ @"foo", @"bar", @"buzz", @"baz" ]; + expect(valuesReceived).to(equal(expectedValues)); +}); + +qck_it(@"should wait for all signals to complete or error before executing sends NO", ^{ + RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(RACSignal *signal) { + return signal; + }]; + + command.allowsConcurrentExecution = YES; + + RACSubject *firstSubject = [RACSubject subject]; + expect([command execute:firstSubject]).notTo(beNil()); + + RACSubject *secondSubject = [RACSubject subject]; + expect([command execute:secondSubject]).notTo(beNil()); + + expect([command.executing first]).toEventually(equal(@YES)); + + [firstSubject sendError:nil]; + expect([command.executing first]).to(equal(@YES)); + + [secondSubject sendNext:nil]; + expect([command.executing first]).to(equal(@YES)); + + [secondSubject sendCompleted]; + expect([command.executing first]).toEventually(equal(@NO)); +}); + +qck_it(@"should not deliver errors from executionSignals", ^{ + RACSubject *subject = [RACSubject subject]; + NSMutableArray *receivedEvents = [NSMutableArray array]; + + RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(id _) { + return subject; + }]; + + [[[command.executionSignals + flatten] + materialize] + subscribeNext:^(RACEvent *event) { + [receivedEvents addObject:event]; + }]; + + expect([command execute:nil]).notTo(beNil()); + expect([command.executing first]).toEventually(equal(@YES)); + + [subject sendNext:RACUnit.defaultUnit]; + + NSArray *expectedEvents = @[ [RACEvent eventWithValue:RACUnit.defaultUnit] ]; + expect(receivedEvents).toEventually(equal(expectedEvents)); + expect([command.executing first]).to(equal(@YES)); + + [subject sendNext:@"foo"]; + + expectedEvents = @[ [RACEvent eventWithValue:RACUnit.defaultUnit], [RACEvent eventWithValue:@"foo"] ]; + expect(receivedEvents).toEventually(equal(expectedEvents)); + expect([command.executing first]).to(equal(@YES)); + + NSError *error = [NSError errorWithDomain:@"" code:1 userInfo:nil]; + [subject sendError:error]; + + expect([command.executing first]).toEventually(equal(@NO)); + expect(receivedEvents).to(equal(expectedEvents)); +}); + +qck_it(@"should deliver errors from -execute:", ^{ + RACSubject *subject = [RACSubject subject]; + NSMutableArray *receivedEvents = [NSMutableArray array]; + + RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(id _) { + return subject; + }]; + + [[[command + execute:nil] + materialize] + subscribeNext:^(RACEvent *event) { + [receivedEvents addObject:event]; + }]; + + expect([command.executing first]).toEventually(equal(@YES)); + + [subject sendNext:RACUnit.defaultUnit]; + + NSArray *expectedEvents = @[ [RACEvent eventWithValue:RACUnit.defaultUnit] ]; + expect(receivedEvents).toEventually(equal(expectedEvents)); + expect([command.executing first]).to(equal(@YES)); + + [subject sendNext:@"foo"]; + + expectedEvents = @[ [RACEvent eventWithValue:RACUnit.defaultUnit], [RACEvent eventWithValue:@"foo"] ]; + expect(receivedEvents).toEventually(equal(expectedEvents)); + expect([command.executing first]).to(equal(@YES)); + + NSError *error = [NSError errorWithDomain:@"" code:1 userInfo:nil]; + [subject sendError:error]; + + expectedEvents = @[ [RACEvent eventWithValue:RACUnit.defaultUnit], [RACEvent eventWithValue:@"foo"], [RACEvent eventWithError:error] ]; + expect(receivedEvents).toEventually(equal(expectedEvents)); + expect([command.executing first]).toEventually(equal(@NO)); +}); + +qck_it(@"should deliver errors onto 'errors'", ^{ + RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(RACSignal *signal) { + return signal; + }]; + + command.allowsConcurrentExecution = YES; + + RACSubject *firstSubject = [RACSubject subject]; + expect([command execute:firstSubject]).notTo(beNil()); + + RACSubject *secondSubject = [RACSubject subject]; + expect([command execute:secondSubject]).notTo(beNil()); + + NSError *firstError = [NSError errorWithDomain:@"" code:1 userInfo:nil]; + NSError *secondError = [NSError errorWithDomain:@"" code:2 userInfo:nil]; + + // We should receive errors from our previously-started executions. + NSMutableArray *receivedErrors = [NSMutableArray array]; + [command.errors subscribeNext:^(NSError *error) { + [receivedErrors addObject:error]; + }]; + + expect([command.executing first]).toEventually(equal(@YES)); + + [firstSubject sendError:firstError]; + expect([command.executing first]).toEventually(equal(@YES)); + + NSArray *expected = @[ firstError ]; + expect(receivedErrors).toEventually(equal(expected)); + + [secondSubject sendError:secondError]; + expect([command.executing first]).toEventually(equal(@NO)); + + expected = @[ firstError, secondError ]; + expect(receivedErrors).toEventually(equal(expected)); +}); + +qck_it(@"should not deliver non-error events onto 'errors'", ^{ + RACSubject *subject = [RACSubject subject]; + RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(id _) { + return subject; + }]; + + __block BOOL receivedEvent = NO; + [command.errors subscribeNext:^(id _) { + receivedEvent = YES; + }]; + + expect([command execute:nil]).notTo(beNil()); + expect([command.executing first]).toEventually(equal(@YES)); + + [subject sendNext:RACUnit.defaultUnit]; + [subject sendCompleted]; + + expect([command.executing first]).toEventually(equal(@NO)); + expect(@(receivedEvent)).to(beFalsy()); +}); + +qck_it(@"should send errors on the main thread", ^{ + RACCommand *command = [[RACCommand alloc] initWithSignalBlock:^(RACSignal *signal) { + return signal; + }]; + + NSError *error = [NSError errorWithDomain:@"" code:1 userInfo:nil]; + + __block RACScheduler *receivedScheduler = nil; + [command.errors subscribeNext:^(NSError *e) { + expect(e).to(equal(error)); + receivedScheduler = RACScheduler.currentScheduler; + }]; + + RACSignal *errorSignal = [RACSignal error:error]; + + [[RACScheduler scheduler] schedule:^{ + [command execute:errorSignal]; + }]; + + expect(receivedScheduler).to(beNil()); + expect(receivedScheduler).toEventually(equal(RACScheduler.mainThreadScheduler)); +}); + +qck_describe(@"enabled signal", ^{ + __block RACSubject *enabledSubject; + __block RACCommand *command; + + qck_beforeEach(^{ + enabledSubject = [RACSubject subject]; + command = [[RACCommand alloc] initWithEnabled:enabledSubject signalBlock:^(id _) { + return [RACSignal return:RACUnit.defaultUnit]; + }]; + }); + + qck_it(@"should send YES by default", ^{ + expect([command.enabled first]).to(equal(@YES)); + }); + + qck_it(@"should send whatever the enabledSignal has sent most recently", ^{ + [enabledSubject sendNext:@NO]; + expect([command.enabled first]).toEventually(equal(@NO)); + + [enabledSubject sendNext:@YES]; + expect([command.enabled first]).toEventually(equal(@YES)); + + [enabledSubject sendNext:@NO]; + expect([command.enabled first]).toEventually(equal(@NO)); + }); + + qck_it(@"should sample enabledSignal synchronously at initialization time", ^{ + RACCommand *command = [[RACCommand alloc] initWithEnabled:[RACSignal return:@NO] signalBlock:^(id _) { + return [RACSignal empty]; + }]; + expect([command.enabled first]).to(equal(@NO)); + }); + + qck_it(@"should send NO while executing is YES and allowsConcurrentExecution is NO", ^{ + [[command.executionSignals flatten] subscribeNext:^(id _) { + expect([command.executing first]).to(equal(@YES)); + expect([command.enabled first]).to(equal(@NO)); + }]; + + expect([command.enabled first]).to(equal(@YES)); + expect(@([[command execute:nil] asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy()); + expect([command.enabled first]).to(equal(@YES)); + }); + + qck_it(@"should send YES while executing is YES and allowsConcurrentExecution is YES", ^{ + command.allowsConcurrentExecution = YES; + + __block BOOL outerExecuted = NO; + __block BOOL innerExecuted = NO; + + // Prevent infinite recursion by only responding to the first value. + [[[command.executionSignals + take:1] + flatten] + subscribeNext:^(id _) { + outerExecuted = YES; + + expect([command.executing first]).to(equal(@YES)); + expect([command.enabled first]).to(equal(@YES)); + + [[command execute:nil] subscribeCompleted:^{ + innerExecuted = YES; + }]; + }]; + + expect([command.enabled first]).to(equal(@YES)); + + expect([command execute:nil]).notTo(beNil()); + expect(@(outerExecuted)).toEventually(beTruthy()); + expect(@(innerExecuted)).toEventually(beTruthy()); + + expect([command.enabled first]).to(equal(@YES)); + }); + + qck_it(@"should send an error from -execute: when NO", ^{ + [enabledSubject sendNext:@NO]; + + RACSignal *signal = [command execute:nil]; + expect(signal).notTo(beNil()); + + __block BOOL success = NO; + __block NSError *error = nil; + expect([signal firstOrDefault:nil success:&success error:&error]).to(beNil()); + expect(@(success)).to(beFalsy()); + + expect(error).notTo(beNil()); + expect(error.domain).to(equal(RACCommandErrorDomain)); + expect(@(error.code)).to(equal(@(RACCommandErrorNotEnabled))); + expect(error.userInfo[RACUnderlyingCommandErrorKey]).to(beIdenticalTo(command)); + }); + + qck_it(@"should always update on the main thread", ^{ + __block RACScheduler *updatedScheduler = nil; + [[command.enabled skip:1] subscribeNext:^(id _) { + updatedScheduler = RACScheduler.currentScheduler; + }]; + + [[RACScheduler scheduler] schedule:^{ + [enabledSubject sendNext:@NO]; + }]; + + expect([command.enabled first]).to(equal(@YES)); + expect([command.enabled first]).toEventually(equal(@NO)); + expect(updatedScheduler).to(equal(RACScheduler.mainThreadScheduler)); + }); + + qck_it(@"should complete when the command is deallocated even if the input signal hasn't", ^{ + __block BOOL deallocated = NO; + __block BOOL completed = NO; + + @autoreleasepool { + RACCommand *command __attribute__((objc_precise_lifetime)) = [[RACCommand alloc] initWithEnabled:enabledSubject signalBlock:emptySignalBlock]; + [command.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocated = YES; + }]]; + + [command.enabled subscribeCompleted:^{ + completed = YES; + }]; + } + + expect(@(deallocated)).toEventually(beTruthy()); + expect(@(completed)).toEventually(beTruthy()); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACCompoundDisposableSpec.m b/ReactiveCocoaTests/RACCompoundDisposableSpec.m new file mode 100644 index 0000000000..c135018a45 --- /dev/null +++ b/ReactiveCocoaTests/RACCompoundDisposableSpec.m @@ -0,0 +1,112 @@ +// +// RACCompoundDisposableSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 11/30/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACCompoundDisposable.h" + +QuickSpecBegin(RACCompoundDisposableSpec) + +qck_it(@"should dispose of all its contained disposables", ^{ + __block BOOL d1Disposed = NO; + RACDisposable *d1 = [RACDisposable disposableWithBlock:^{ + d1Disposed = YES; + }]; + + __block BOOL d2Disposed = NO; + RACDisposable *d2 = [RACDisposable disposableWithBlock:^{ + d2Disposed = YES; + }]; + + __block BOOL d3Disposed = NO; + RACDisposable *d3 = [RACDisposable disposableWithBlock:^{ + d3Disposed = YES; + }]; + + __block BOOL d4Disposed = NO; + RACDisposable *d4 = [RACDisposable disposableWithBlock:^{ + d4Disposed = YES; + }]; + + RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposableWithDisposables:@[ d1, d2, d3 ]]; + [disposable addDisposable:d4]; + + expect(@(d1Disposed)).to(beFalsy()); + expect(@(d2Disposed)).to(beFalsy()); + expect(@(d3Disposed)).to(beFalsy()); + expect(@(d4Disposed)).to(beFalsy()); + expect(@(disposable.disposed)).to(beFalsy()); + + [disposable dispose]; + + expect(@(d1Disposed)).to(beTruthy()); + expect(@(d2Disposed)).to(beTruthy()); + expect(@(d3Disposed)).to(beTruthy()); + expect(@(d4Disposed)).to(beTruthy()); + expect(@(disposable.disposed)).to(beTruthy()); +}); + +qck_it(@"should dispose of any added disposables immediately if it's already been disposed", ^{ + RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable]; + [disposable dispose]; + + RACDisposable *d = [[RACDisposable alloc] init]; + + expect(@(d.disposed)).to(beFalsy()); + [disposable addDisposable:d]; + expect(@(d.disposed)).to(beTruthy()); +}); + +qck_it(@"should work when initialized with -init", ^{ + RACCompoundDisposable *disposable = [[RACCompoundDisposable alloc] init]; + + __block BOOL disposed = NO; + RACDisposable *d = [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + [disposable addDisposable:d]; + expect(@(disposed)).to(beFalsy()); + + [disposable dispose]; + expect(@(disposed)).to(beTruthy()); +}); + +qck_it(@"should work when initialized with +disposableWithBlock:", ^{ + __block BOOL compoundDisposed = NO; + RACCompoundDisposable *disposable = [RACCompoundDisposable disposableWithBlock:^{ + compoundDisposed = YES; + }]; + + __block BOOL disposed = NO; + RACDisposable *d = [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + [disposable addDisposable:d]; + expect(@(disposed)).to(beFalsy()); + expect(@(compoundDisposed)).to(beFalsy()); + + [disposable dispose]; + expect(@(disposed)).to(beTruthy()); + expect(@(compoundDisposed)).to(beTruthy()); +}); + +qck_it(@"should allow disposables to be removed", ^{ + RACCompoundDisposable *disposable = [[RACCompoundDisposable alloc] init]; + RACDisposable *d = [[RACDisposable alloc] init]; + + [disposable addDisposable:d]; + [disposable removeDisposable:d]; + + [disposable dispose]; + expect(@(d.disposed)).to(beFalsy()); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACControlCommandExamples.h b/ReactiveCocoaTests/RACControlCommandExamples.h new file mode 100644 index 0000000000..3fbaa34ca6 --- /dev/null +++ b/ReactiveCocoaTests/RACControlCommandExamples.h @@ -0,0 +1,18 @@ +// +// RACControlCommandExamples.h +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-08-15. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +// The name of the shared examples for any control class that has +// `rac_command` and `isEnabled` properties. +extern NSString * const RACControlCommandExamples; + +// The control to test. +extern NSString * const RACControlCommandExampleControl; + +// A block of type `void (^)(id control)` which should activate the +// `rac_command` of the `control` by manipulating the control itself. +extern NSString * const RACControlCommandExampleActivateBlock; diff --git a/ReactiveCocoaTests/RACControlCommandExamples.m b/ReactiveCocoaTests/RACControlCommandExamples.m new file mode 100644 index 0000000000..7033fc978e --- /dev/null +++ b/ReactiveCocoaTests/RACControlCommandExamples.m @@ -0,0 +1,84 @@ +// +// RACControlCommandExamples.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-08-15. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACControlCommandExamples.h" + +#import "RACCommand.h" +#import "RACSubject.h" +#import "RACUnit.h" + +NSString * const RACControlCommandExamples = @"RACControlCommandExamples"; +NSString * const RACControlCommandExampleControl = @"RACControlCommandExampleControl"; +NSString * const RACControlCommandExampleActivateBlock = @"RACControlCommandExampleActivateBlock"; + +// Methods used by the unit test that would otherwise require platform-specific +// imports. +@interface NSObject (RACControlCommandExamples) + +@property (nonatomic, strong) RACCommand *rac_command; + +- (BOOL)isEnabled; + +@end + +QuickSharedExampleGroupsBegin(RACControlCommandExampleGroups) + +qck_sharedExamples(RACControlCommandExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block id control; + __block void (^activate)(id); + + __block RACSubject *enabledSubject; + __block RACCommand *command; + + qck_beforeEach(^{ + control = exampleContext()[RACControlCommandExampleControl]; + activate = [exampleContext()[RACControlCommandExampleActivateBlock] copy]; + + enabledSubject = [RACSubject subject]; + command = [[RACCommand alloc] initWithEnabled:enabledSubject signalBlock:^(id sender) { + return [RACSignal return:sender]; + }]; + + [control setRac_command:command]; + }); + + qck_it(@"should bind the control's enabledness to the command", ^{ + expect(@([control isEnabled])).toEventually(beTruthy()); + + [enabledSubject sendNext:@NO]; + expect(@([control isEnabled])).toEventually(beFalsy()); + + [enabledSubject sendNext:@YES]; + expect(@([control isEnabled])).toEventually(beTruthy()); + }); + + qck_it(@"should execute the control's command when activated", ^{ + __block BOOL executed = NO; + [[command.executionSignals flatten] subscribeNext:^(id sender) { + expect(sender).to(equal(control)); + executed = YES; + }]; + + activate(control); + expect(@(executed)).toEventually(beTruthy()); + }); + + qck_it(@"should overwrite an existing command when setting a new one", ^{ + RACCommand *secondCommand = [[RACCommand alloc] initWithSignalBlock:^(id _) { + return [RACSignal return:RACUnit.defaultUnit]; + }]; + + [control setRac_command:secondCommand]; + expect([control rac_command]).to(beIdenticalTo(secondCommand)); + }); +}); + +QuickSharedExampleGroupsEnd diff --git a/ReactiveCocoaTests/RACDelegateProxySpec.m b/ReactiveCocoaTests/RACDelegateProxySpec.m new file mode 100644 index 0000000000..9b8d2e4c30 --- /dev/null +++ b/ReactiveCocoaTests/RACDelegateProxySpec.m @@ -0,0 +1,92 @@ +// +// RACDelegateProxySpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-06-22. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "NSObject+RACSelectorSignal.h" +#import "RACDelegateProxy.h" +#import "RACSignal.h" +#import "RACTuple.h" +#import "RACCompoundDisposable.h" +#import "NSObject+RACDeallocating.h" + +@protocol TestDelegateProtocol +- (NSUInteger)lengthOfString:(NSString *)str; +@end + +@interface TestDelegate : NSObject +@property (nonatomic, assign) BOOL lengthOfStringInvoked; +@end + +QuickSpecBegin(RACDelegateProxySpec) + +__block id proxy; +__block TestDelegate *delegate; +__block Protocol *protocol; + +qck_beforeEach(^{ + protocol = @protocol(TestDelegateProtocol); + expect(protocol).notTo(beNil()); + + proxy = [[RACDelegateProxy alloc] initWithProtocol:protocol]; + expect(proxy).notTo(beNil()); + expect([proxy rac_proxiedDelegate]).to(beNil()); + + delegate = [[TestDelegate alloc] init]; + expect(delegate).notTo(beNil()); +}); + +qck_it(@"should not respond to selectors at first", ^{ + expect(@([proxy respondsToSelector:@selector(lengthOfString:)])).to(beFalsy()); +}); + +qck_it(@"should send on a signal for a protocol method", ^{ + __block RACTuple *tuple; + [[proxy signalForSelector:@selector(lengthOfString:)] subscribeNext:^(RACTuple *t) { + tuple = t; + }]; + + expect(@([proxy respondsToSelector:@selector(lengthOfString:)])).to(beTruthy()); + expect(@([proxy lengthOfString:@"foo"])).to(equal(@0)); + expect(tuple).to(equal(RACTuplePack(@"foo"))); +}); + +qck_it(@"should forward to the proxied delegate", ^{ + [proxy setRac_proxiedDelegate:delegate]; + + expect(@([proxy respondsToSelector:@selector(lengthOfString:)])).to(beTruthy()); + expect(@([proxy lengthOfString:@"foo"])).to(equal(@3)); + expect(@(delegate.lengthOfStringInvoked)).to(beTruthy()); +}); + +qck_it(@"should not send to the delegate when signals are applied", ^{ + [proxy setRac_proxiedDelegate:delegate]; + + __block RACTuple *tuple; + [[proxy signalForSelector:@selector(lengthOfString:)] subscribeNext:^(RACTuple *t) { + tuple = t; + }]; + + expect(@([proxy respondsToSelector:@selector(lengthOfString:)])).to(beTruthy()); + expect(@([proxy lengthOfString:@"foo"])).to(equal(@0)); + + expect(tuple).to(equal(RACTuplePack(@"foo"))); + expect(@(delegate.lengthOfStringInvoked)).to(beFalsy()); +}); + +QuickSpecEnd + +@implementation TestDelegate + +- (NSUInteger)lengthOfString:(NSString *)str { + self.lengthOfStringInvoked = YES; + return str.length; +} + +@end diff --git a/ReactiveCocoaTests/RACDisposableSpec.m b/ReactiveCocoaTests/RACDisposableSpec.m new file mode 100644 index 0000000000..6d6e374c35 --- /dev/null +++ b/ReactiveCocoaTests/RACDisposableSpec.m @@ -0,0 +1,76 @@ +// +// RACDisposableSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-06-13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACDisposable.h" +#import "RACScopedDisposable.h" + +QuickSpecBegin(RACDisposableSpec) + +qck_it(@"should initialize without a block", ^{ + RACDisposable *disposable = [[RACDisposable alloc] init]; + expect(disposable).notTo(beNil()); + expect(@(disposable.disposed)).to(beFalsy()); + + [disposable dispose]; + expect(@(disposable.disposed)).to(beTruthy()); +}); + +qck_it(@"should execute a block upon disposal", ^{ + __block BOOL disposed = NO; + RACDisposable *disposable = [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + expect(disposable).notTo(beNil()); + expect(@(disposed)).to(beFalsy()); + expect(@(disposable.disposed)).to(beFalsy()); + + [disposable dispose]; + expect(@(disposed)).to(beTruthy()); + expect(@(disposable.disposed)).to(beTruthy()); +}); + +qck_it(@"should not dispose upon deallocation", ^{ + __block BOOL disposed = NO; + __weak RACDisposable *weakDisposable = nil; + + @autoreleasepool { + RACDisposable *disposable = [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + weakDisposable = disposable; + expect(weakDisposable).notTo(beNil()); + } + + expect(weakDisposable).to(beNil()); + expect(@(disposed)).to(beFalsy()); +}); + +qck_it(@"should create a scoped disposable", ^{ + __block BOOL disposed = NO; + __weak RACScopedDisposable *weakDisposable = nil; + + @autoreleasepool { + RACScopedDisposable *disposable __attribute__((objc_precise_lifetime)) = [RACScopedDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + weakDisposable = disposable; + expect(weakDisposable).notTo(beNil()); + expect(@(disposed)).to(beFalsy()); + } + + expect(weakDisposable).to(beNil()); + expect(@(disposed)).to(beTruthy()); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACEventSpec.m b/ReactiveCocoaTests/RACEventSpec.m new file mode 100644 index 0000000000..0a1d3e6a21 --- /dev/null +++ b/ReactiveCocoaTests/RACEventSpec.m @@ -0,0 +1,83 @@ +// +// RACEventSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-01-07. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACEvent.h" + +QuickSpecBegin(RACEventSpec) + +qck_it(@"should return the singleton completed event", ^{ + RACEvent *event = RACEvent.completedEvent; + expect(event).notTo(beNil()); + + expect(event).to(beIdenticalTo(RACEvent.completedEvent)); + expect([event copy]).to(beIdenticalTo(event)); + + expect(@(event.eventType)).to(equal(@(RACEventTypeCompleted))); + expect(@(event.finished)).to(beTruthy()); + expect(event.error).to(beNil()); + expect(event.value).to(beNil()); +}); + +qck_it(@"should return an error event", ^{ + NSError *error = [NSError errorWithDomain:@"foo" code:1 userInfo:nil]; + RACEvent *event = [RACEvent eventWithError:error]; + expect(event).notTo(beNil()); + + expect(event).to(equal([RACEvent eventWithError:error])); + expect([event copy]).to(equal(event)); + + expect(@(event.eventType)).to(equal(@(RACEventTypeError))); + expect(@(event.finished)).to(beTruthy()); + expect(event.error).to(equal(error)); + expect(event.value).to(beNil()); +}); + +qck_it(@"should return an error event with a nil error", ^{ + RACEvent *event = [RACEvent eventWithError:nil]; + expect(event).notTo(beNil()); + + expect(event).to(equal([RACEvent eventWithError:nil])); + expect([event copy]).to(equal(event)); + + expect(@(event.eventType)).to(equal(@(RACEventTypeError))); + expect(@(event.finished)).to(beTruthy()); + expect(event.error).to(beNil()); + expect(event.value).to(beNil()); +}); + +qck_it(@"should return a next event", ^{ + NSString *value = @"foo"; + RACEvent *event = [RACEvent eventWithValue:value]; + expect(event).notTo(beNil()); + + expect(event).to(equal([RACEvent eventWithValue:value])); + expect([event copy]).to(equal(event)); + + expect(@(event.eventType)).to(equal(@(RACEventTypeNext))); + expect(@(event.finished)).to(beFalsy()); + expect(event.error).to(beNil()); + expect(event.value).to(equal(value)); +}); + +qck_it(@"should return a next event with a nil value", ^{ + RACEvent *event = [RACEvent eventWithValue:nil]; + expect(event).notTo(beNil()); + + expect(event).to(equal([RACEvent eventWithValue:nil])); + expect([event copy]).to(equal(event)); + + expect(@(event.eventType)).to(equal(@(RACEventTypeNext))); + expect(@(event.finished)).to(beFalsy()); + expect(event.error).to(beNil()); + expect(event.value).to(beNil()); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACKVOChannelSpec.m b/ReactiveCocoaTests/RACKVOChannelSpec.m new file mode 100644 index 0000000000..70e94df285 --- /dev/null +++ b/ReactiveCocoaTests/RACKVOChannelSpec.m @@ -0,0 +1,394 @@ +// +// RACKVOChannelSpec.m +// ReactiveCocoa +// +// Created by Uri Baghin on 16/12/2012. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTestObject.h" +#import "RACChannelExamples.h" +#import "RACPropertySignalExamples.h" + +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACKVOWrapper.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACKVOChannel.h" +#import "RACSignal+Operations.h" + +QuickSpecBegin(RACKVOChannelSpec) + +qck_describe(@"RACKVOChannel", ^{ + __block RACTestObject *object; + __block RACKVOChannel *channel; + id value1 = @"test value 1"; + id value2 = @"test value 2"; + id value3 = @"test value 3"; + NSArray *values = @[ value1, value2, value3 ]; + + qck_beforeEach(^{ + object = [[RACTestObject alloc] init]; + channel = [[RACKVOChannel alloc] initWithTarget:object keyPath:@keypath(object.stringValue) nilValue:nil]; + }); + + id setupBlock = ^(RACTestObject *testObject, NSString *keyPath, id nilValue, RACSignal *signal) { + RACKVOChannel *channel = [[RACKVOChannel alloc] initWithTarget:testObject keyPath:keyPath nilValue:nilValue]; + [signal subscribe:channel.followingTerminal]; + }; + + qck_itBehavesLike(RACPropertySignalExamples, ^{ + return @{ RACPropertySignalExamplesSetupBlock: setupBlock }; + }); + + qck_itBehavesLike(RACChannelExamples, ^{ + return @{ + RACChannelExampleCreateBlock: [^{ + return [[RACKVOChannel alloc] initWithTarget:object keyPath:@keypath(object.stringValue) nilValue:nil]; + } copy] + }; + }); + + qck_it(@"should send the object's current value when subscribed to followingTerminal", ^{ + __block id receivedValue = @"received value should not be this"; + [[channel.followingTerminal take:1] subscribeNext:^(id x) { + receivedValue = x; + }]; + + expect(receivedValue).to(beNil()); + + object.stringValue = value1; + [[channel.followingTerminal take:1] subscribeNext:^(id x) { + receivedValue = x; + }]; + + expect(receivedValue).to(equal(value1)); + }); + + qck_it(@"should send the object's new value on followingTerminal when it's changed", ^{ + object.stringValue = value1; + + NSMutableArray *receivedValues = [NSMutableArray array]; + [channel.followingTerminal subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + object.stringValue = value2; + object.stringValue = value3; + expect(receivedValues).to(equal(values)); + }); + + qck_it(@"should set the object's value using values sent to the followingTerminal", ^{ + expect(object.stringValue).to(beNil()); + + [channel.followingTerminal sendNext:value1]; + expect(object.stringValue).to(equal(value1)); + + [channel.followingTerminal sendNext:value2]; + expect(object.stringValue).to(equal(value2)); + }); + + qck_it(@"should be able to subscribe to signals", ^{ + NSMutableArray *receivedValues = [NSMutableArray array]; + [object rac_observeKeyPath:@keypath(object.stringValue) options:0 observer:self block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + [receivedValues addObject:value]; + }]; + + RACSignal *signal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:value1]; + [subscriber sendNext:value2]; + [subscriber sendNext:value3]; + return nil; + }]; + + [signal subscribe:channel.followingTerminal]; + expect(receivedValues).to(equal(values)); + }); + + qck_it(@"should complete both terminals when the target deallocates", ^{ + __block BOOL leadingCompleted = NO; + __block BOOL followingCompleted = NO; + __block BOOL deallocated = NO; + + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocated = YES; + }]]; + + RACKVOChannel *channel = [[RACKVOChannel alloc] initWithTarget:object keyPath:@keypath(object.stringValue) nilValue:nil]; + [channel.leadingTerminal subscribeCompleted:^{ + leadingCompleted = YES; + }]; + + [channel.followingTerminal subscribeCompleted:^{ + followingCompleted = YES; + }]; + + expect(@(deallocated)).to(beFalsy()); + expect(@(leadingCompleted)).to(beFalsy()); + expect(@(followingCompleted)).to(beFalsy()); + } + + expect(@(deallocated)).to(beTruthy()); + expect(@(leadingCompleted)).to(beTruthy()); + expect(@(followingCompleted)).to(beTruthy()); + }); + + qck_it(@"should deallocate when the target deallocates", ^{ + __block BOOL targetDeallocated = NO; + __block BOOL channelDeallocated = NO; + + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + targetDeallocated = YES; + }]]; + + RACKVOChannel *channel = [[RACKVOChannel alloc] initWithTarget:object keyPath:@keypath(object.stringValue) nilValue:nil]; + [channel.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + channelDeallocated = YES; + }]]; + + expect(@(targetDeallocated)).to(beFalsy()); + expect(@(channelDeallocated)).to(beFalsy()); + } + + expect(@(targetDeallocated)).to(beTruthy()); + expect(@(channelDeallocated)).to(beTruthy()); + }); +}); + +qck_describe(@"RACChannelTo", ^{ + __block RACTestObject *a; + __block RACTestObject *b; + __block RACTestObject *c; + __block NSString *testName1; + __block NSString *testName2; + __block NSString *testName3; + + qck_beforeEach(^{ + a = [[RACTestObject alloc] init]; + b = [[RACTestObject alloc] init]; + c = [[RACTestObject alloc] init]; + testName1 = @"sync it!"; + testName2 = @"sync it again!"; + testName3 = @"sync it once more!"; + }); + + qck_it(@"should keep objects' properties in sync", ^{ + RACChannelTo(a, stringValue) = RACChannelTo(b, stringValue); + expect(a.stringValue).to(beNil()); + expect(b.stringValue).to(beNil()); + + a.stringValue = testName1; + expect(a.stringValue).to(equal(testName1)); + expect(b.stringValue).to(equal(testName1)); + + b.stringValue = testName2; + expect(a.stringValue).to(equal(testName2)); + expect(b.stringValue).to(equal(testName2)); + + a.stringValue = nil; + expect(a.stringValue).to(beNil()); + expect(b.stringValue).to(beNil()); + }); + + qck_it(@"should keep properties identified by keypaths in sync", ^{ + RACChannelTo(a, strongTestObjectValue.stringValue) = RACChannelTo(b, strongTestObjectValue.stringValue); + a.strongTestObjectValue = [[RACTestObject alloc] init]; + b.strongTestObjectValue = [[RACTestObject alloc] init]; + + a.strongTestObjectValue.stringValue = testName1; + expect(a.strongTestObjectValue.stringValue).to(equal(testName1)); + expect(b.strongTestObjectValue.stringValue).to(equal(testName1)); + expect(a.strongTestObjectValue).notTo(equal(b.strongTestObjectValue)); + + b.strongTestObjectValue = nil; + expect(a.strongTestObjectValue.stringValue).to(beNil()); + + c.stringValue = testName2; + b.strongTestObjectValue = c; + expect(a.strongTestObjectValue.stringValue).to(equal(testName2)); + expect(b.strongTestObjectValue.stringValue).to(equal(testName2)); + expect(a.strongTestObjectValue).notTo(equal(b.strongTestObjectValue)); + }); + + qck_it(@"should update properties identified by keypaths when the intermediate values change", ^{ + RACChannelTo(a, strongTestObjectValue.stringValue) = RACChannelTo(b, strongTestObjectValue.stringValue); + a.strongTestObjectValue = [[RACTestObject alloc] init]; + b.strongTestObjectValue = [[RACTestObject alloc] init]; + c.stringValue = testName1; + b.strongTestObjectValue = c; + + expect(a.strongTestObjectValue.stringValue).to(equal(testName1)); + expect(a.strongTestObjectValue).notTo(equal(b.strongTestObjectValue)); + }); + + qck_it(@"should update properties identified by keypaths when the channel was created when one of the two objects had an intermediate nil value", ^{ + RACChannelTo(a, strongTestObjectValue.stringValue) = RACChannelTo(b, strongTestObjectValue.stringValue); + b.strongTestObjectValue = [[RACTestObject alloc] init]; + c.stringValue = testName1; + a.strongTestObjectValue = c; + + expect(a.strongTestObjectValue.stringValue).to(equal(testName1)); + expect(b.strongTestObjectValue.stringValue).to(equal(testName1)); + expect(a.strongTestObjectValue).notTo(equal(b.strongTestObjectValue)); + }); + + qck_it(@"should take the value of the object being bound to at the start", ^{ + a.stringValue = testName1; + b.stringValue = testName2; + + RACChannelTo(a, stringValue) = RACChannelTo(b, stringValue); + expect(a.stringValue).to(equal(testName2)); + expect(b.stringValue).to(equal(testName2)); + }); + + qck_it(@"should update the value even if it's the same value the object had before it was bound", ^{ + a.stringValue = testName1; + b.stringValue = testName2; + + RACChannelTo(a, stringValue) = RACChannelTo(b, stringValue); + expect(a.stringValue).to(equal(testName2)); + expect(b.stringValue).to(equal(testName2)); + + b.stringValue = testName1; + expect(a.stringValue).to(equal(testName1)); + expect(b.stringValue).to(equal(testName1)); + }); + + qck_it(@"should bind transitively", ^{ + a.stringValue = testName1; + b.stringValue = testName2; + c.stringValue = testName3; + + RACChannelTo(a, stringValue) = RACChannelTo(b, stringValue); + RACChannelTo(b, stringValue) = RACChannelTo(c, stringValue); + expect(a.stringValue).to(equal(testName3)); + expect(b.stringValue).to(equal(testName3)); + expect(c.stringValue).to(equal(testName3)); + + c.stringValue = testName1; + expect(a.stringValue).to(equal(testName1)); + expect(b.stringValue).to(equal(testName1)); + expect(c.stringValue).to(equal(testName1)); + + b.stringValue = testName2; + expect(a.stringValue).to(equal(testName2)); + expect(b.stringValue).to(equal(testName2)); + expect(c.stringValue).to(equal(testName2)); + + a.stringValue = testName3; + expect(a.stringValue).to(equal(testName3)); + expect(b.stringValue).to(equal(testName3)); + expect(c.stringValue).to(equal(testName3)); + }); + + qck_it(@"should bind changes made by KVC on arrays", ^{ + b.arrayValue = @[]; + RACChannelTo(a, arrayValue) = RACChannelTo(b, arrayValue); + + [[b mutableArrayValueForKeyPath:@keypath(b.arrayValue)] addObject:@1]; + expect(a.arrayValue).to(equal(b.arrayValue)); + }); + + qck_it(@"should bind changes made by KVC on sets", ^{ + b.setValue = [NSSet set]; + RACChannelTo(a, setValue) = RACChannelTo(b, setValue); + + [[b mutableSetValueForKeyPath:@keypath(b.setValue)] addObject:@1]; + expect(a.setValue).to(equal(b.setValue)); + }); + + qck_it(@"should bind changes made by KVC on ordered sets", ^{ + b.orderedSetValue = [NSOrderedSet orderedSet]; + RACChannelTo(a, orderedSetValue) = RACChannelTo(b, orderedSetValue); + + [[b mutableOrderedSetValueForKeyPath:@keypath(b.orderedSetValue)] addObject:@1]; + expect(a.orderedSetValue).to(equal(b.orderedSetValue)); + }); + + qck_it(@"should handle deallocation of intermediate objects correctly even without support from KVO", ^{ + __block BOOL wasDisposed = NO; + + RACChannelTo(a, weakTestObjectValue.stringValue) = RACChannelTo(b, strongTestObjectValue.stringValue); + b.strongTestObjectValue = [[RACTestObject alloc] init]; + + @autoreleasepool { + RACTestObject *object = [[RACTestObject alloc] init]; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + wasDisposed = YES; + }]]; + + a.weakTestObjectValue = object; + object.stringValue = testName1; + + expect(@(wasDisposed)).to(beFalsy()); + expect(b.strongTestObjectValue.stringValue).to(equal(testName1)); + } + + expect(@(wasDisposed)).toEventually(beTruthy()); + expect(b.strongTestObjectValue.stringValue).to(beNil()); + }); + + qck_it(@"should stop binding when disposed", ^{ + RACChannelTerminal *aTerminal = RACChannelTo(a, stringValue); + RACChannelTerminal *bTerminal = RACChannelTo(b, stringValue); + + a.stringValue = testName1; + RACDisposable *disposable = [aTerminal subscribe:bTerminal]; + + expect(a.stringValue).to(equal(testName1)); + expect(b.stringValue).to(equal(testName1)); + + a.stringValue = testName2; + expect(a.stringValue).to(equal(testName2)); + expect(b.stringValue).to(equal(testName2)); + + [disposable dispose]; + + a.stringValue = testName3; + expect(a.stringValue).to(equal(testName3)); + expect(b.stringValue).to(equal(testName2)); + }); + + qck_it(@"should use the nilValue when sent nil", ^{ + RACChannelTerminal *terminal = RACChannelTo(a, integerValue, @5); + expect(@(a.integerValue)).to(equal(@0)); + + [terminal sendNext:@2]; + expect(@(a.integerValue)).to(equal(@2)); + + [terminal sendNext:nil]; + expect(@(a.integerValue)).to(equal(@5)); + }); + + qck_it(@"should use the nilValue when an intermediate object is nil", ^{ + __block BOOL wasDisposed = NO; + + RACChannelTo(a, weakTestObjectValue.integerValue, @5) = RACChannelTo(b, strongTestObjectValue.integerValue, @5); + b.strongTestObjectValue = [[RACTestObject alloc] init]; + + @autoreleasepool { + RACTestObject *object = [[RACTestObject alloc] init]; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + wasDisposed = YES; + }]]; + + a.weakTestObjectValue = object; + object.integerValue = 2; + + expect(@(wasDisposed)).to(beFalsy()); + expect(@(b.strongTestObjectValue.integerValue)).to(equal(@2)); + } + + expect(@(wasDisposed)).toEventually(beTruthy()); + expect(@(b.strongTestObjectValue.integerValue)).to(equal(@5)); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACKVOWrapperSpec.m b/ReactiveCocoaTests/RACKVOWrapperSpec.m new file mode 100644 index 0000000000..b60ac2a9f1 --- /dev/null +++ b/ReactiveCocoaTests/RACKVOWrapperSpec.m @@ -0,0 +1,669 @@ +// +// RACKVOWrapperSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-08-07. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "NSObject+RACKVOWrapper.h" + +#import "EXTKeyPathCoding.h" +#import "NSObject+RACDeallocating.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACKVOTrampoline.h" +#import "RACTestObject.h" + +@interface RACTestOperation : NSOperation +@end + +// The name of the examples. +static NSString * const RACKVOWrapperExamples = @"RACKVOWrapperExamples"; + +// A block that returns an object to observe in the examples. +static NSString * const RACKVOWrapperExamplesTargetBlock = @"RACKVOWrapperExamplesTargetBlock"; + +// The key path to observe in the examples. +// +// The key path must have at least one weak property in it. +static NSString * const RACKVOWrapperExamplesKeyPath = @"RACKVOWrapperExamplesKeyPath"; + +// A block that changes the value of a weak property in the observed key path. +// The block is passed the object the example is observing and the new value the +// weak property should be changed to( +static NSString * const RACKVOWrapperExamplesChangeBlock = @"RACKVOWrapperExamplesChangeBlock"; + +// A block that returns a valid value for the weak property changed by +// RACKVOWrapperExamplesChangeBlock. The value must deallocate +// normally. +static NSString * const RACKVOWrapperExamplesValueBlock = @"RACKVOWrapperExamplesValueBlock"; + +// Whether RACKVOWrapperExamplesChangeBlock changes the value +// of the last key path component in the key path directly. +static NSString * const RACKVOWrapperExamplesChangesValueDirectly = @"RACKVOWrapperExamplesChangesValueDirectly"; + +// The name of the examples. +static NSString * const RACKVOWrapperCollectionExamples = @"RACKVOWrapperCollectionExamples"; + +// A block that returns an object to observe in the examples. +static NSString * const RACKVOWrapperCollectionExamplesTargetBlock = @"RACKVOWrapperCollectionExamplesTargetBlock"; + +// The key path to observe in the examples. +// +// Must identify a property of type NSOrderedSet. +static NSString * const RACKVOWrapperCollectionExamplesKeyPath = @"RACKVOWrapperCollectionExamplesKeyPath"; + +QuickSharedExampleGroupsBegin(RACKVOWrapperExampleGroups) + +qck_sharedExamples(RACKVOWrapperExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block NSObject *target = nil; + __block NSString *keyPath = nil; + __block void (^changeBlock)(NSObject *, id) = nil; + __block id (^valueBlock)(void) = nil; + __block BOOL changesValueDirectly = NO; + + __block NSUInteger priorCallCount = 0; + __block NSUInteger posteriorCallCount = 0; + __block BOOL priorTriggeredByLastKeyPathComponent = NO; + __block BOOL posteriorTriggeredByLastKeyPathComponent = NO; + __block BOOL posteriorTriggeredByDeallocation = NO; + __block void (^callbackBlock)(id, NSDictionary *, BOOL, BOOL) = nil; + + qck_beforeEach(^{ + NSObject * (^targetBlock)(void) = exampleContext()[RACKVOWrapperExamplesTargetBlock]; + target = targetBlock(); + keyPath = exampleContext()[RACKVOWrapperExamplesKeyPath]; + changeBlock = exampleContext()[RACKVOWrapperExamplesChangeBlock]; + valueBlock = exampleContext()[RACKVOWrapperExamplesValueBlock]; + changesValueDirectly = [exampleContext()[RACKVOWrapperExamplesChangesValueDirectly] boolValue]; + + priorCallCount = 0; + posteriorCallCount = 0; + + callbackBlock = [^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + if ([change[NSKeyValueChangeNotificationIsPriorKey] boolValue]) { + priorTriggeredByLastKeyPathComponent = affectedOnlyLastComponent; + ++priorCallCount; + return; + } + posteriorTriggeredByLastKeyPathComponent = affectedOnlyLastComponent; + posteriorTriggeredByDeallocation = causedByDealloc; + ++posteriorCallCount; + } copy]; + }); + + qck_afterEach(^{ + target = nil; + keyPath = nil; + changeBlock = nil; + valueBlock = nil; + changesValueDirectly = NO; + + callbackBlock = nil; + }); + + qck_it(@"should not call the callback block on add if called without NSKeyValueObservingOptionInitial", ^{ + [target rac_observeKeyPath:keyPath options:NSKeyValueObservingOptionPrior observer:nil block:callbackBlock]; + expect(@(priorCallCount)).to(equal(@0)); + expect(@(posteriorCallCount)).to(equal(@0)); + }); + + qck_it(@"should call the callback block on add if called with NSKeyValueObservingOptionInitial", ^{ + [target rac_observeKeyPath:keyPath options:NSKeyValueObservingOptionPrior | NSKeyValueObservingOptionInitial observer:nil block:callbackBlock]; + expect(@(priorCallCount)).to(equal(@0)); + expect(@(posteriorCallCount)).to(equal(@1)); + }); + + qck_it(@"should call the callback block twice per change, once prior and once posterior", ^{ + [target rac_observeKeyPath:keyPath options:NSKeyValueObservingOptionPrior observer:nil block:callbackBlock]; + priorCallCount = 0; + posteriorCallCount = 0; + + id value1 = valueBlock(); + changeBlock(target, value1); + expect(@(priorCallCount)).to(equal(@1)); + expect(@(posteriorCallCount)).to(equal(@1)); + expect(@(priorTriggeredByLastKeyPathComponent)).to(equal(@(changesValueDirectly))); + expect(@(posteriorTriggeredByLastKeyPathComponent)).to(equal(@(changesValueDirectly))); + expect(@(posteriorTriggeredByDeallocation)).to(beFalsy()); + + id value2 = valueBlock(); + changeBlock(target, value2); + expect(@(priorCallCount)).to(equal(@2)); + expect(@(posteriorCallCount)).to(equal(@2)); + expect(@(priorTriggeredByLastKeyPathComponent)).to(equal(@(changesValueDirectly))); + expect(@(posteriorTriggeredByLastKeyPathComponent)).to(equal(@(changesValueDirectly))); + expect(@(posteriorTriggeredByDeallocation)).to(beFalsy()); + }); + + qck_it(@"should call the callback block with NSKeyValueChangeNotificationIsPriorKey set before the value is changed, and not set after the value is changed", ^{ + __block BOOL priorCalled = NO; + __block BOOL posteriorCalled = NO; + __block id priorValue = nil; + __block id posteriorValue = nil; + + id value1 = valueBlock(); + changeBlock(target, value1); + id oldValue = [target valueForKeyPath:keyPath]; + + [target rac_observeKeyPath:keyPath options:NSKeyValueObservingOptionPrior observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + if ([change[NSKeyValueChangeNotificationIsPriorKey] boolValue]) { + priorCalled = YES; + priorValue = value; + expect(@(posteriorCalled)).to(beFalsy()); + return; + } + posteriorCalled = YES; + posteriorValue = value; + expect(@(priorCalled)).to(beTruthy()); + }]; + + id value2 = valueBlock(); + changeBlock(target, value2); + id newValue = [target valueForKeyPath:keyPath]; + expect(@(priorCalled)).to(beTruthy()); + expect(priorValue).to(equal(oldValue)); + expect(@(posteriorCalled)).to(beTruthy()); + expect(posteriorValue).to(equal(newValue)); + }); + + qck_it(@"should not call the callback block after it's been disposed", ^{ + RACDisposable *disposable = [target rac_observeKeyPath:keyPath options:NSKeyValueObservingOptionPrior observer:nil block:callbackBlock]; + priorCallCount = 0; + posteriorCallCount = 0; + + [disposable dispose]; + expect(@(priorCallCount)).to(equal(@0)); + expect(@(posteriorCallCount)).to(equal(@0)); + + id value = valueBlock(); + changeBlock(target, value); + expect(@(priorCallCount)).to(equal(@0)); + expect(@(posteriorCallCount)).to(equal(@0)); + }); + + qck_it(@"should call the callback block only once with NSKeyValueChangeNotificationIsPriorKey not set when the value is deallocated", ^{ + __block BOOL valueDidDealloc = NO; + + [target rac_observeKeyPath:keyPath options:NSKeyValueObservingOptionPrior observer:nil block:callbackBlock]; + + @autoreleasepool { + NSObject *value __attribute__((objc_precise_lifetime)) = valueBlock(); + [value.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + valueDidDealloc = YES; + }]]; + + changeBlock(target, value); + priorCallCount = 0; + posteriorCallCount = 0; + } + + expect(@(valueDidDealloc)).to(beTruthy()); + expect(@(priorCallCount)).to(equal(@0)); + expect(@(posteriorCallCount)).to(equal(@1)); + expect(@(posteriorTriggeredByDeallocation)).to(beTruthy()); + }); +}); + +qck_sharedExamples(RACKVOWrapperCollectionExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block NSObject *target = nil; + __block NSString *keyPath = nil; + __block NSMutableOrderedSet *mutableKeyPathProxy = nil; + __block void (^callbackBlock)(id, NSDictionary *, BOOL, BOOL) = nil; + + __block id priorValue = nil; + __block id posteriorValue = nil; + __block NSDictionary *priorChange = nil; + __block NSDictionary *posteriorChange = nil; + + qck_beforeEach(^{ + NSObject * (^targetBlock)(void) = exampleContext()[RACKVOWrapperCollectionExamplesTargetBlock]; + target = targetBlock(); + keyPath = exampleContext()[RACKVOWrapperCollectionExamplesKeyPath]; + + callbackBlock = [^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + if ([change[NSKeyValueChangeNotificationIsPriorKey] boolValue]) { + priorValue = value; + priorChange = change; + return; + } + posteriorValue = value; + posteriorChange = change; + } copy]; + + [target setValue:[NSOrderedSet orderedSetWithObject:@0] forKeyPath:keyPath]; + [target rac_observeKeyPath:keyPath options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld | NSKeyValueObservingOptionPrior observer:nil block:callbackBlock]; + mutableKeyPathProxy = [target mutableOrderedSetValueForKeyPath:keyPath]; + }); + + qck_afterEach(^{ + target = nil; + keyPath = nil; + callbackBlock = nil; + + priorValue = nil; + priorChange = nil; + posteriorValue = nil; + posteriorChange = nil; + }); + + qck_it(@"should support inserting elements into ordered collections", ^{ + [mutableKeyPathProxy insertObject:@1 atIndex:0]; + + expect(priorValue).to(equal([NSOrderedSet orderedSetWithArray:@[ @0 ]])); + expect(posteriorValue).to(equal([NSOrderedSet orderedSetWithArray:(@[ @1, @0 ])])); + expect(priorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeInsertion))); + expect(posteriorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeInsertion))); + expect(priorChange[NSKeyValueChangeOldKey]).to(beNil()); + expect(posteriorChange[NSKeyValueChangeNewKey]).to(equal(@[ @1 ])); + expect(priorChange[NSKeyValueChangeIndexesKey]).to(equal([NSIndexSet indexSetWithIndex:0])); + expect(posteriorChange[NSKeyValueChangeIndexesKey]).to(equal([NSIndexSet indexSetWithIndex:0])); + }); + + qck_it(@"should support removing elements from ordered collections", ^{ + [mutableKeyPathProxy removeObjectAtIndex:0]; + + expect(priorValue).to(equal([NSOrderedSet orderedSetWithArray:@[ @0 ]])); + expect(posteriorValue).to(equal([NSOrderedSet orderedSetWithArray:@[]])); + expect(priorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeRemoval))); + expect(posteriorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeRemoval))); + expect(priorChange[NSKeyValueChangeOldKey]).to(equal(@[ @0 ])); + expect(posteriorChange[NSKeyValueChangeNewKey]).to(beNil()); + expect(priorChange[NSKeyValueChangeIndexesKey]).to(equal([NSIndexSet indexSetWithIndex:0])); + expect(posteriorChange[NSKeyValueChangeIndexesKey]).to(equal([NSIndexSet indexSetWithIndex:0])); + }); + + qck_it(@"should support replacing elements in ordered collections", ^{ + [mutableKeyPathProxy replaceObjectAtIndex:0 withObject:@1]; + + expect(priorValue).to(equal([NSOrderedSet orderedSetWithArray:@[ @0 ]])); + expect(posteriorValue).to(equal([NSOrderedSet orderedSetWithArray:@[ @1 ]])); + expect(priorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeReplacement))); + expect(posteriorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeReplacement))); + expect(priorChange[NSKeyValueChangeOldKey]).to(equal(@[ @0 ])); + expect(posteriorChange[NSKeyValueChangeNewKey]).to(equal(@[ @1 ])); + expect(priorChange[NSKeyValueChangeIndexesKey]).to(equal([NSIndexSet indexSetWithIndex:0])); + expect(posteriorChange[NSKeyValueChangeIndexesKey]).to(equal([NSIndexSet indexSetWithIndex:0])); + }); + + qck_it(@"should support adding elements to unordered collections", ^{ + [mutableKeyPathProxy unionOrderedSet:[NSOrderedSet orderedSetWithObject:@1]]; + + expect(priorValue).to(equal([NSOrderedSet orderedSetWithArray:@[ @0 ]])); + expect(posteriorValue).to(equal([NSOrderedSet orderedSetWithArray:(@[ @0, @1 ])])); + expect(priorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeInsertion))); + expect(posteriorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeInsertion))); + expect(priorChange[NSKeyValueChangeOldKey]).to(beNil()); + expect(posteriorChange[NSKeyValueChangeNewKey]).to(equal(@[ @1 ])); + }); + + qck_it(@"should support removing elements from unordered collections", ^{ + [mutableKeyPathProxy minusOrderedSet:[NSOrderedSet orderedSetWithObject:@0]]; + + expect(priorValue).to(equal([NSOrderedSet orderedSetWithArray:@[ @0 ]])); + expect(posteriorValue).to(equal([NSOrderedSet orderedSetWithArray:@[]])); + expect(priorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeRemoval))); + expect(posteriorChange[NSKeyValueChangeKindKey]).to(equal(@(NSKeyValueChangeRemoval))); + expect(priorChange[NSKeyValueChangeOldKey]).to(equal(@[ @0 ])); + expect(posteriorChange[NSKeyValueChangeNewKey]).to(beNil()); + }); +}); + +QuickSharedExampleGroupsEnd + +QuickSpecBegin(RACKVOWrapperSpec) + +qck_describe(@"-rac_observeKeyPath:options:observer:block:", ^{ + qck_describe(@"on simple keys", ^{ + NSObject * (^targetBlock)(void) = ^{ + return [[RACTestObject alloc] init]; + }; + + void (^changeBlock)(RACTestObject *, id) = ^(RACTestObject *target, id value) { + target.weakTestObjectValue = value; + }; + + id (^valueBlock)(void) = ^{ + return [[RACTestObject alloc] init]; + }; + + qck_itBehavesLike(RACKVOWrapperExamples, ^{ + return @{ + RACKVOWrapperExamplesTargetBlock: targetBlock, + RACKVOWrapperExamplesKeyPath: @keypath(RACTestObject.new, weakTestObjectValue), + RACKVOWrapperExamplesChangeBlock: changeBlock, + RACKVOWrapperExamplesValueBlock: valueBlock, + RACKVOWrapperExamplesChangesValueDirectly: @YES + }; + }); + + qck_itBehavesLike(RACKVOWrapperCollectionExamples, ^{ + return @{ + RACKVOWrapperCollectionExamplesTargetBlock: targetBlock, + RACKVOWrapperCollectionExamplesKeyPath: @keypath(RACTestObject.new, orderedSetValue) + }; + }); + }); + + qck_describe(@"on composite key paths'", ^{ + qck_describe(@"last key path components", ^{ + NSObject *(^targetBlock)(void) = ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + object.strongTestObjectValue = [[RACTestObject alloc] init]; + return object; + }; + + void (^changeBlock)(RACTestObject *, id) = ^(RACTestObject *target, id value) { + target.strongTestObjectValue.weakTestObjectValue = value; + }; + + id (^valueBlock)(void) = ^{ + return [[RACTestObject alloc] init]; + }; + + qck_itBehavesLike(RACKVOWrapperExamples, ^{ + return @{ + RACKVOWrapperExamplesTargetBlock: targetBlock, + RACKVOWrapperExamplesKeyPath: @keypath(RACTestObject.new, strongTestObjectValue.weakTestObjectValue), + RACKVOWrapperExamplesChangeBlock: changeBlock, + RACKVOWrapperExamplesValueBlock: valueBlock, + RACKVOWrapperExamplesChangesValueDirectly: @YES + }; + }); + + qck_itBehavesLike(RACKVOWrapperCollectionExamples, ^{ + return @{ + RACKVOWrapperCollectionExamplesTargetBlock: targetBlock, + RACKVOWrapperCollectionExamplesKeyPath: @keypath(RACTestObject.new, strongTestObjectValue.orderedSetValue) + }; + }); + }); + + qck_describe(@"intermediate key path components", ^{ + NSObject *(^targetBlock)(void) = ^{ + return [[RACTestObject alloc] init]; + }; + + void (^changeBlock)(RACTestObject *, id) = ^(RACTestObject *target, id value) { + target.weakTestObjectValue = value; + }; + + id (^valueBlock)(void) = ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + object.strongTestObjectValue = [[RACTestObject alloc] init]; + return object; + }; + + qck_itBehavesLike(RACKVOWrapperExamples, ^{ + return @{ + RACKVOWrapperExamplesTargetBlock: targetBlock, + RACKVOWrapperExamplesKeyPath: @keypath([[RACTestObject alloc] init], weakTestObjectValue.strongTestObjectValue), + RACKVOWrapperExamplesChangeBlock: changeBlock, + RACKVOWrapperExamplesValueBlock: valueBlock, + RACKVOWrapperExamplesChangesValueDirectly: @NO + }; + }); + }); + + qck_it(@"should not notice deallocation of the object returned by a dynamic final property", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + __block id lastValue = nil; + @autoreleasepool { + [object rac_observeKeyPath:@keypath(object.dynamicObjectProperty) options:NSKeyValueObservingOptionInitial observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + lastValue = value; + }]; + + expect(lastValue).to(beAKindOf(RACTestObject.class)); + } + + expect(lastValue).to(beAKindOf(RACTestObject.class)); + }); + + qck_it(@"should not notice deallocation of the object returned by a dynamic intermediate property", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + __block id lastValue = nil; + @autoreleasepool { + [object rac_observeKeyPath:@keypath(object.dynamicObjectProperty.integerValue) options:NSKeyValueObservingOptionInitial observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + lastValue = value; + }]; + + expect(lastValue).to(equal(@42)); + } + + expect(lastValue).to(equal(@42)); + }); + + qck_it(@"should not notice deallocation of the object returned by a dynamic method", ^{ + RACTestObject *object = [[RACTestObject alloc] init]; + + __block id lastValue = nil; + @autoreleasepool { + [object rac_observeKeyPath:@keypath(object.dynamicObjectMethod) options:NSKeyValueObservingOptionInitial observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + lastValue = value; + }]; + + expect(lastValue).to(beAKindOf(RACTestObject.class)); + } + + expect(lastValue).to(beAKindOf(RACTestObject.class)); + }); + }); + + qck_it(@"should not call the callback block when the value is the observer", ^{ + __block BOOL observerDisposed = NO; + __block BOOL observerDeallocationTriggeredChange = NO; + __block BOOL targetDisposed = NO; + __block BOOL targetDeallocationTriggeredChange = NO; + + @autoreleasepool { + RACTestObject *observer __attribute__((objc_precise_lifetime)) = [RACTestObject new]; + [observer.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + observerDisposed = YES; + }]]; + + RACTestObject *target __attribute__((objc_precise_lifetime)) = [RACTestObject new]; + [target.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + targetDisposed = YES; + }]]; + + observer.weakTestObjectValue = observer; + target.weakTestObjectValue = target; + + // These observations can only result in dealloc triggered callbacks. + [observer rac_observeKeyPath:@keypath(target.weakTestObjectValue) options:0 observer:observer block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + observerDeallocationTriggeredChange = YES; + }]; + + [target rac_observeKeyPath:@keypath(target.weakTestObjectValue) options:0 observer:observer block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + targetDeallocationTriggeredChange = YES; + }]; + } + + expect(@(observerDisposed)).to(beTruthy()); + expect(@(observerDeallocationTriggeredChange)).to(beFalsy()); + + expect(@(targetDisposed)).to(beTruthy()); + expect(@(targetDeallocationTriggeredChange)).to(beTruthy()); + }); + + qck_it(@"should call the callback block for deallocation of the initial value of a single-key key path", ^{ + RACTestObject *target = [RACTestObject new]; + __block BOOL objectDisposed = NO; + __block BOOL objectDeallocationTriggeredChange = NO; + + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [RACTestObject new]; + target.weakTestObjectValue = object; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + objectDisposed = YES; + }]]; + + [target rac_observeKeyPath:@keypath(target.weakTestObjectValue) options:0 observer:target block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + objectDeallocationTriggeredChange = YES; + }]; + } + + expect(@(objectDisposed)).to(beTruthy()); + expect(@(objectDeallocationTriggeredChange)).to(beTruthy()); + }); + + qck_it(@"should call the callback block for deallocation of an object conforming to protocol property", ^{ + RACTestObject *target = [RACTestObject new]; + __block BOOL objectDisposed = NO; + __block BOOL objectDeallocationTriggeredChange = NO; + + @autoreleasepool { + RACTestObject *object __attribute__((objc_precise_lifetime)) = [RACTestObject new]; + target.weakObjectWithProtocol = object; + [object.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + objectDisposed = YES; + }]]; + + [target rac_observeKeyPath:@keypath(target.weakObjectWithProtocol) options:0 observer:target block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + objectDeallocationTriggeredChange = YES; + }]; + } + + expect(@(objectDisposed)).to(beTruthy()); + expect(@(objectDeallocationTriggeredChange)).to(beTruthy()); + }); +}); + +qck_describe(@"rac_addObserver:forKeyPath:options:block:", ^{ + qck_it(@"should add and remove an observer", ^{ + NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{}]; + expect(operation).notTo(beNil()); + + __block BOOL notified = NO; + RACDisposable *disposable = [operation rac_observeKeyPath:@"isFinished" options:NSKeyValueObservingOptionNew observer:self block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + expect([change objectForKey:NSKeyValueChangeNewKey]).to(equal(@YES)); + + expect(@(notified)).to(beFalsy()); + notified = YES; + }]; + + expect(disposable).notTo(beNil()); + + [operation start]; + [operation waitUntilFinished]; + + expect(@(notified)).toEventually(beTruthy()); + }); + + qck_it(@"should accept a nil observer", ^{ + NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{}]; + RACDisposable *disposable = [operation rac_observeKeyPath:@"isFinished" options:NSKeyValueObservingOptionNew observer:nil block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {}]; + + expect(disposable).notTo(beNil()); + }); + + qck_it(@"automatically stops KVO on subclasses when the target deallocates", ^{ + void (^testKVOOnSubclass)(Class targetClass, id observer) = ^(Class targetClass, id observer) { + __weak id weakTarget = nil; + __weak id identifier = nil; + + @autoreleasepool { + // Create an observable target that we control the memory management of. + CFTypeRef target = CFBridgingRetain([[targetClass alloc] init]); + expect((__bridge id)target).notTo(beNil()); + + weakTarget = (__bridge id)target; + expect(weakTarget).notTo(beNil()); + + identifier = [(__bridge id)target rac_observeKeyPath:@"isFinished" options:0 observer:observer block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {}]; + expect(identifier).notTo(beNil()); + + CFRelease(target); + } + + expect(weakTarget).to(beNil()); + expect(identifier).to(beNil()); + }; + + qck_it(@"stops KVO on NSObject subclasses", ^{ + testKVOOnSubclass(NSOperation.class, self); + }); + + qck_it(@"stops KVO on subclasses of already-swizzled classes", ^{ + testKVOOnSubclass(RACTestOperation.class, self); + }); + + qck_it(@"stops KVO on NSObject subclasses even with a nil observer", ^{ + testKVOOnSubclass(NSOperation.class, nil); + }); + + qck_it(@"stops KVO on subclasses of already-swizzled classes even with a nil observer", ^{ + testKVOOnSubclass(RACTestOperation.class, nil); + }); + }); + + qck_it(@"should automatically stop KVO when the observer deallocates", ^{ + __weak id weakObserver = nil; + __weak id identifier = nil; + + NSOperation *operation = [[NSOperation alloc] init]; + + @autoreleasepool { + // Create an observer that we control the memory management of. + CFTypeRef observer = CFBridgingRetain([[NSOperation alloc] init]); + expect((__bridge id)observer).notTo(beNil()); + + weakObserver = (__bridge id)observer; + expect(weakObserver).notTo(beNil()); + + identifier = [operation rac_observeKeyPath:@"isFinished" options:0 observer:(__bridge id)observer block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) {}]; + expect(identifier).notTo(beNil()); + + CFRelease(observer); + } + + expect(weakObserver).to(beNil()); + }); + + qck_it(@"should stop KVO when the observer is disposed", ^{ + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + __block NSString *name = nil; + + RACDisposable *disposable = [queue rac_observeKeyPath:@"name" options:0 observer:self block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + name = queue.name; + }]; + + queue.name = @"1"; + expect(name).to(equal(@"1")); + [disposable dispose]; + queue.name = @"2"; + expect(name).to(equal(@"1")); + }); + + qck_it(@"should distinguish between observers being disposed", ^{ + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; + __block NSString *name1 = nil; + __block NSString *name2 = nil; + + RACDisposable *disposable = [queue rac_observeKeyPath:@"name" options:0 observer:self block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + name1 = queue.name; + }]; + [queue rac_observeKeyPath:@"name" options:0 observer:self block:^(id value, NSDictionary *change, BOOL causedByDealloc, BOOL affectedOnlyLastComponent) { + name2 = queue.name; + }]; + + queue.name = @"1"; + expect(name1).to(equal(@"1")); + expect(name2).to(equal(@"1")); + [disposable dispose]; + queue.name = @"2"; + expect(name1).to(equal(@"1")); + expect(name2).to(equal(@"2")); + }); +}); + +QuickSpecEnd + +@implementation RACTestOperation +@end diff --git a/ReactiveCocoaTests/RACMulticastConnectionSpec.m b/ReactiveCocoaTests/RACMulticastConnectionSpec.m new file mode 100644 index 0000000000..7a50ca2093 --- /dev/null +++ b/ReactiveCocoaTests/RACMulticastConnectionSpec.m @@ -0,0 +1,150 @@ +// +// RACMulticastConnectionSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 10/8/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACMulticastConnection.h" +#import "RACDisposable.h" +#import "RACSignal+Operations.h" +#import "RACSubscriber.h" +#import "RACReplaySubject.h" +#import "RACScheduler.h" +#import + +QuickSpecBegin(RACMulticastConnectionSpec) + +__block NSUInteger subscriptionCount = 0; +__block RACMulticastConnection *connection; + +qck_beforeEach(^{ + subscriptionCount = 0; + connection = [[RACSignal createSignal:^(id subscriber) { + subscriptionCount++; + return (RACDisposable *)nil; + }] publish]; + + expect(@(subscriptionCount)).to(equal(@0)); +}); + +qck_describe(@"-connect", ^{ + qck_it(@"should subscribe to the underlying signal", ^{ + [connection connect]; + expect(@(subscriptionCount)).to(equal(@1)); + }); + + qck_it(@"should return the same disposable for each invocation", ^{ + RACDisposable *d1 = [connection connect]; + RACDisposable *d2 = [connection connect]; + expect(d1).to(equal(d2)); + expect(@(subscriptionCount)).to(equal(@1)); + }); + + qck_it(@"shouldn't reconnect after disposal", ^{ + RACDisposable *disposable1 = [connection connect]; + expect(@(subscriptionCount)).to(equal(@1)); + + [disposable1 dispose]; + + RACDisposable *disposable2 = [connection connect]; + expect(@(subscriptionCount)).to(equal(@1)); + expect(disposable1).to(equal(disposable2)); + }); + + qck_it(@"shouldn't race when connecting", ^{ + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + + RACMulticastConnection *connection = [[RACSignal + defer:^ id { + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + return nil; + }] + publish]; + + __block RACDisposable *disposable; + [RACScheduler.scheduler schedule:^{ + disposable = [connection connect]; + dispatch_semaphore_signal(semaphore); + }]; + + expect([connection connect]).notTo(beNil()); + dispatch_semaphore_signal(semaphore); + + expect(disposable).toEventuallyNot(beNil()); + }); +}); + +qck_describe(@"-autoconnect", ^{ + __block RACSignal *autoconnectedSignal; + + qck_beforeEach(^{ + autoconnectedSignal = [connection autoconnect]; + }); + + qck_it(@"should subscribe to the multicasted signal on the first subscription", ^{ + expect(@(subscriptionCount)).to(equal(@0)); + + [autoconnectedSignal subscribeNext:^(id x) {}]; + expect(@(subscriptionCount)).to(equal(@1)); + + [autoconnectedSignal subscribeNext:^(id x) {}]; + expect(@(subscriptionCount)).to(equal(@1)); + }); + + qck_it(@"should dispose of the multicasted subscription when the signal has no subscribers", ^{ + __block BOOL disposed = NO; + __block id connectionSubscriber = nil; + RACSignal *signal = [[[RACSignal createSignal:^(id subscriber) { + // Keep the subscriber alive so it doesn't trigger disposal on dealloc + connectionSubscriber = subscriber; + subscriptionCount++; + return [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + }] publish] autoconnect]; + RACDisposable *disposable = [signal subscribeNext:^(id x) {}]; + + expect(@(disposed)).to(beFalsy()); + [disposable dispose]; + expect(@(disposed)).to(beTruthy()); + }); + + qck_it(@"shouldn't reconnect after disposal", ^{ + RACDisposable *disposable = [autoconnectedSignal subscribeNext:^(id x) {}]; + expect(@(subscriptionCount)).to(equal(@1)); + [disposable dispose]; + + disposable = [autoconnectedSignal subscribeNext:^(id x) {}]; + expect(@(subscriptionCount)).to(equal(@1)); + [disposable dispose]; + }); + + qck_it(@"should replay values after disposal when multicasted to a replay subject", ^{ + RACSubject *subject = [RACSubject subject]; + RACSignal *signal = [[subject multicast:[RACReplaySubject subject]] autoconnect]; + + NSMutableArray *results1 = [NSMutableArray array]; + RACDisposable *disposable = [signal subscribeNext:^(id x) { + [results1 addObject:x]; + }]; + + [subject sendNext:@1]; + [subject sendNext:@2]; + + expect(results1).to(equal((@[ @1, @2 ]))); + [disposable dispose]; + + NSMutableArray *results2 = [NSMutableArray array]; + [signal subscribeNext:^(id x) { + [results2 addObject:x]; + }]; + expect(results2).toEventually(equal((@[ @1, @2 ]))); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACPropertySignalExamples.h b/ReactiveCocoaTests/RACPropertySignalExamples.h new file mode 100644 index 0000000000..59a2b4305b --- /dev/null +++ b/ReactiveCocoaTests/RACPropertySignalExamples.h @@ -0,0 +1,18 @@ +// +// RACPropertySignalExamples.h +// ReactiveCocoa +// +// Created by Josh Abernathy on 9/28/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +// The name of the shared examples for a signal-driven property. +extern NSString * const RACPropertySignalExamples; + +// The block should have the signature: +// +// void (^)(RACTestObject *testObject, NSString *keyPath, id nilValue, RACSignal *signal) +// +// and should tie the value of the key path on testObject to signal. `nilValue` +// will be used when the signal sends a `nil` value. +extern NSString * const RACPropertySignalExamplesSetupBlock; diff --git a/ReactiveCocoaTests/RACPropertySignalExamples.m b/ReactiveCocoaTests/RACPropertySignalExamples.m new file mode 100644 index 0000000000..9fda17ca12 --- /dev/null +++ b/ReactiveCocoaTests/RACPropertySignalExamples.m @@ -0,0 +1,142 @@ +// +// RACPropertySignalExamples.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 9/28/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTestObject.h" + +#import "EXTKeyPathCoding.h" +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACPropertySubscribing.h" +#import "NSObject+RACSelectorSignal.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACSubject.h" + +NSString * const RACPropertySignalExamples = @"RACPropertySignalExamples"; +NSString * const RACPropertySignalExamplesSetupBlock = @"RACPropertySignalExamplesSetupBlock"; + +QuickSharedExampleGroupsBegin(RACPropertySignalExampleGroups) + +qck_sharedExamples(RACPropertySignalExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block RACTestObject *testObject = nil; + __block void (^setupBlock)(RACTestObject *, NSString *keyPath, id nilValue, RACSignal *); + + qck_beforeEach(^{ + setupBlock = exampleContext()[RACPropertySignalExamplesSetupBlock]; + testObject = [[RACTestObject alloc] init]; + }); + + qck_it(@"should set the value of the property with the latest value from the signal", ^{ + RACSubject *subject = [RACSubject subject]; + setupBlock(testObject, @keypath(testObject.objectValue), nil, subject); + expect(testObject.objectValue).to(beNil()); + + [subject sendNext:@1]; + expect(testObject.objectValue).to(equal(@1)); + + [subject sendNext:@2]; + expect(testObject.objectValue).to(equal(@2)); + + [subject sendNext:nil]; + expect(testObject.objectValue).to(beNil()); + }); + + qck_it(@"should set the given nilValue for an object property", ^{ + RACSubject *subject = [RACSubject subject]; + setupBlock(testObject, @keypath(testObject.objectValue), @"foo", subject); + expect(testObject.objectValue).to(beNil()); + + [subject sendNext:@1]; + expect(testObject.objectValue).to(equal(@1)); + + [subject sendNext:@2]; + expect(testObject.objectValue).to(equal(@2)); + + [subject sendNext:nil]; + expect(testObject.objectValue).to(equal(@"foo")); + }); + + qck_it(@"should leave the value of the property alone after the signal completes", ^{ + RACSubject *subject = [RACSubject subject]; + setupBlock(testObject, @keypath(testObject.objectValue), nil, subject); + expect(testObject.objectValue).to(beNil()); + + [subject sendNext:@1]; + expect(testObject.objectValue).to(equal(@1)); + + [subject sendCompleted]; + expect(testObject.objectValue).to(equal(@1)); + }); + + qck_it(@"should set the value of a non-object property with the latest value from the signal", ^{ + RACSubject *subject = [RACSubject subject]; + setupBlock(testObject, @keypath(testObject.integerValue), nil, subject); + expect(@(testObject.integerValue)).to(equal(@0)); + + [subject sendNext:@1]; + expect(@(testObject.integerValue)).to(equal(@1)); + + [subject sendNext:@2]; + expect(@(testObject.integerValue)).to(equal(@2)); + + [subject sendNext:@0]; + expect(@(testObject.integerValue)).to(equal(@0)); + }); + + qck_it(@"should set the given nilValue for a non-object property", ^{ + RACSubject *subject = [RACSubject subject]; + setupBlock(testObject, @keypath(testObject.integerValue), @42, subject); + expect(@(testObject.integerValue)).to(equal(@0)); + + [subject sendNext:@1]; + expect(@(testObject.integerValue)).to(equal(@1)); + + [subject sendNext:@2]; + expect(@(testObject.integerValue)).to(equal(@2)); + + [subject sendNext:nil]; + expect(@(testObject.integerValue)).to(equal(@42)); + }); + + qck_it(@"should not invoke -setNilValueForKey: with a nilValue", ^{ + RACSubject *subject = [RACSubject subject]; + setupBlock(testObject, @keypath(testObject.integerValue), @42, subject); + + __block BOOL setNilValueForKeyInvoked = NO; + [[testObject rac_signalForSelector:@selector(setNilValueForKey:)] subscribeNext:^(NSString *key) { + setNilValueForKeyInvoked = YES; + }]; + + [subject sendNext:nil]; + expect(@(testObject.integerValue)).to(equal(@42)); + expect(@(setNilValueForKeyInvoked)).to(beFalsy()); + }); + + qck_it(@"should invoke -setNilValueForKey: without a nilValue", ^{ + RACSubject *subject = [RACSubject subject]; + setupBlock(testObject, @keypath(testObject.integerValue), nil, subject); + + [subject sendNext:@1]; + expect(@(testObject.integerValue)).to(equal(@1)); + + testObject.catchSetNilValueForKey = YES; + + __block BOOL setNilValueForKeyInvoked = NO; + [[testObject rac_signalForSelector:@selector(setNilValueForKey:)] subscribeNext:^(NSString *key) { + setNilValueForKeyInvoked = YES; + }]; + + [subject sendNext:nil]; + expect(@(testObject.integerValue)).to(equal(@1)); + expect(@(setNilValueForKeyInvoked)).to(beTruthy()); + }); +}); + +QuickSharedExampleGroupsEnd diff --git a/ReactiveCocoaTests/RACSchedulerSpec.m b/ReactiveCocoaTests/RACSchedulerSpec.m new file mode 100644 index 0000000000..815b51fc79 --- /dev/null +++ b/ReactiveCocoaTests/RACSchedulerSpec.m @@ -0,0 +1,439 @@ +// +// RACSchedulerSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 11/29/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACScheduler.h" +#import "RACScheduler+Private.h" +#import "RACQueueScheduler+Subclass.h" +#import "RACDisposable.h" +#import "EXTScope.h" +#import "RACTestExampleScheduler.h" +#import + +// This shouldn't be used directly. Use the `expectCurrentSchedulers` block +// below instead. +static void expectCurrentSchedulersInner(NSArray *schedulers, NSMutableArray *currentSchedulerArray) { + if (schedulers.count > 0) { + RACScheduler *topScheduler = schedulers[0]; + [topScheduler schedule:^{ + RACScheduler *currentScheduler = RACScheduler.currentScheduler; + if (currentScheduler != nil) [currentSchedulerArray addObject:currentScheduler]; + expectCurrentSchedulersInner([schedulers subarrayWithRange:NSMakeRange(1, schedulers.count - 1)], currentSchedulerArray); + }]; + } +} + +QuickSpecBegin(RACSchedulerSpec) + +qck_it(@"should know its current scheduler", ^{ + // Recursively schedules a block in each of the given schedulers and records + // the +currentScheduler at each step. It then expects the array of + // +currentSchedulers and the expected array to be equal. + // + // schedulers - The array of schedulers to recursively schedule. + // expectedCurrentSchedulers - The array of +currentSchedulers to expect. + void (^expectCurrentSchedulers)(NSArray *, NSArray *) = ^(NSArray *schedulers, NSArray *expectedCurrentSchedulers) { + NSMutableArray *currentSchedulerArray = [NSMutableArray array]; + expectCurrentSchedulersInner(schedulers, currentSchedulerArray); + expect(currentSchedulerArray).toEventually(equal(expectedCurrentSchedulers)); + }; + + RACScheduler *backgroundScheduler = [RACScheduler scheduler]; + + expectCurrentSchedulers(@[ backgroundScheduler, RACScheduler.immediateScheduler ], @[ backgroundScheduler, backgroundScheduler ]); + expectCurrentSchedulers(@[ backgroundScheduler, RACScheduler.subscriptionScheduler ], @[ backgroundScheduler, backgroundScheduler ]); + + NSArray *mainThreadJumper = @[ RACScheduler.mainThreadScheduler, backgroundScheduler, RACScheduler.mainThreadScheduler ]; + expectCurrentSchedulers(mainThreadJumper, mainThreadJumper); + + NSArray *backgroundJumper = @[ backgroundScheduler, RACScheduler.mainThreadScheduler, backgroundScheduler ]; + expectCurrentSchedulers(backgroundJumper, backgroundJumper); +}); + +qck_describe(@"+mainThreadScheduler", ^{ + qck_it(@"should cancel scheduled blocks when disposed", ^{ + __block BOOL firstBlockRan = NO; + __block BOOL secondBlockRan = NO; + + RACDisposable *disposable = [RACScheduler.mainThreadScheduler schedule:^{ + firstBlockRan = YES; + }]; + + expect(disposable).notTo(beNil()); + + [RACScheduler.mainThreadScheduler schedule:^{ + secondBlockRan = YES; + }]; + + [disposable dispose]; + + expect(@(secondBlockRan)).to(beFalsy()); + expect(@(secondBlockRan)).toEventually(beTruthy()); + expect(@(firstBlockRan)).to(beFalsy()); + }); + + qck_it(@"should schedule future blocks", ^{ + __block BOOL done = NO; + + [RACScheduler.mainThreadScheduler after:[NSDate date] schedule:^{ + done = YES; + }]; + + expect(@(done)).to(beFalsy()); + expect(@(done)).toEventually(beTruthy()); + }); + + qck_it(@"should cancel future blocks when disposed", ^{ + __block BOOL firstBlockRan = NO; + __block BOOL secondBlockRan = NO; + + RACDisposable *disposable = [RACScheduler.mainThreadScheduler after:[NSDate date] schedule:^{ + firstBlockRan = YES; + }]; + + expect(disposable).notTo(beNil()); + + [RACScheduler.mainThreadScheduler after:[NSDate date] schedule:^{ + secondBlockRan = YES; + }]; + + [disposable dispose]; + + expect(@(secondBlockRan)).to(beFalsy()); + expect(@(secondBlockRan)).toEventually(beTruthy()); + expect(@(firstBlockRan)).to(beFalsy()); + }); + + qck_it(@"should schedule recurring blocks", ^{ + __block NSUInteger count = 0; + + RACDisposable *disposable = [RACScheduler.mainThreadScheduler after:[NSDate date] repeatingEvery:0.05 withLeeway:0 schedule:^{ + count++; + }]; + + expect(@(count)).to(equal(@0)); + expect(@(count)).toEventually(beGreaterThanOrEqualTo(@1)); + expect(@(count)).toEventually(beGreaterThanOrEqualTo(@2)); + expect(@(count)).toEventually(beGreaterThanOrEqualTo(@3)); + + [disposable dispose]; + [NSRunLoop.mainRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + + expect(@(count)).to(beGreaterThanOrEqualTo(@3)); + }); +}); + +qck_describe(@"+scheduler", ^{ + __block RACScheduler *scheduler; + __block NSDate * (^futureDate)(void); + + qck_beforeEach(^{ + scheduler = [RACScheduler scheduler]; + + futureDate = ^{ + return [NSDate dateWithTimeIntervalSinceNow:0.01]; + }; + }); + + qck_it(@"should cancel scheduled blocks when disposed", ^{ + __block BOOL firstBlockRan = NO; + __block BOOL secondBlockRan = NO; + + // Start off on the scheduler so the enqueued blocks won't run until we + // return. + [scheduler schedule:^{ + RACDisposable *disposable = [scheduler schedule:^{ + firstBlockRan = YES; + }]; + + expect(disposable).notTo(beNil()); + + [scheduler schedule:^{ + secondBlockRan = YES; + }]; + + [disposable dispose]; + }]; + + expect(@(secondBlockRan)).toEventually(beTruthy()); + expect(@(firstBlockRan)).to(beFalsy()); + }); + + qck_it(@"should schedule future blocks", ^{ + __block BOOL done = NO; + + [scheduler after:futureDate() schedule:^{ + done = YES; + }]; + + expect(@(done)).to(beFalsy()); + expect(@(done)).toEventually(beTruthy()); + }); + + qck_it(@"should cancel future blocks when disposed", ^{ + __block BOOL firstBlockRan = NO; + __block BOOL secondBlockRan = NO; + + NSDate *date = futureDate(); + RACDisposable *disposable = [scheduler after:date schedule:^{ + firstBlockRan = YES; + }]; + + expect(disposable).notTo(beNil()); + [disposable dispose]; + + [scheduler after:date schedule:^{ + secondBlockRan = YES; + }]; + + expect(@(secondBlockRan)).to(beFalsy()); + expect(@(secondBlockRan)).toEventually(beTruthy()); + expect(@(firstBlockRan)).to(beFalsy()); + }); + + qck_it(@"should schedule recurring blocks", ^{ + __block NSUInteger count = 0; + + RACDisposable *disposable = [scheduler after:[NSDate date] repeatingEvery:0.05 withLeeway:0 schedule:^{ + count++; + }]; + + expect(@(count)).to(beGreaterThanOrEqualTo(@0)); + expect(@(count)).toEventually(beGreaterThanOrEqualTo(@1)); + expect(@(count)).toEventually(beGreaterThanOrEqualTo(@2)); + expect(@(count)).toEventually(beGreaterThanOrEqualTo(@3)); + + [disposable dispose]; + [NSThread sleepForTimeInterval:0.1]; + + expect(@(count)).to(beGreaterThanOrEqualTo(@3)); + }); +}); + +qck_describe(@"+subscriptionScheduler", ^{ + qck_describe(@"setting +currentScheduler", ^{ + __block RACScheduler *currentScheduler; + + qck_beforeEach(^{ + currentScheduler = nil; + }); + + qck_it(@"should be the +mainThreadScheduler when scheduled from the main queue", ^{ + dispatch_async(dispatch_get_main_queue(), ^{ + [RACScheduler.subscriptionScheduler schedule:^{ + currentScheduler = RACScheduler.currentScheduler; + }]; + }); + + expect(currentScheduler).toEventually(equal(RACScheduler.mainThreadScheduler)); + }); + + qck_it(@"should be a +scheduler when scheduled from an unknown queue", ^{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [RACScheduler.subscriptionScheduler schedule:^{ + currentScheduler = RACScheduler.currentScheduler; + }]; + }); + + expect(currentScheduler).toEventuallyNot(beNil()); + expect(currentScheduler).notTo(equal(RACScheduler.mainThreadScheduler)); + }); + + qck_it(@"should equal the background scheduler from which the block was scheduled", ^{ + RACScheduler *backgroundScheduler = [RACScheduler scheduler]; + [backgroundScheduler schedule:^{ + [RACScheduler.subscriptionScheduler schedule:^{ + currentScheduler = RACScheduler.currentScheduler; + }]; + }]; + + expect(currentScheduler).toEventually(equal(backgroundScheduler)); + }); + }); + + qck_it(@"should execute scheduled blocks immediately if it's in a scheduler already", ^{ + __block BOOL done = NO; + __block BOOL executedImmediately = NO; + + [[RACScheduler scheduler] schedule:^{ + [RACScheduler.subscriptionScheduler schedule:^{ + executedImmediately = YES; + }]; + + done = YES; + }]; + + expect(@(done)).toEventually(beTruthy()); + expect(@(executedImmediately)).to(beTruthy()); + }); +}); + +qck_describe(@"+immediateScheduler", ^{ + qck_it(@"should immediately execute scheduled blocks", ^{ + __block BOOL executed = NO; + RACDisposable *disposable = [RACScheduler.immediateScheduler schedule:^{ + executed = YES; + }]; + + expect(disposable).to(beNil()); + expect(@(executed)).to(beTruthy()); + }); + + qck_it(@"should block for future scheduled blocks", ^{ + __block BOOL executed = NO; + RACDisposable *disposable = [RACScheduler.immediateScheduler after:[NSDate dateWithTimeIntervalSinceNow:0.01] schedule:^{ + executed = YES; + }]; + + expect(@(executed)).to(beTruthy()); + expect(disposable).to(beNil()); + }); +}); + +qck_describe(@"-scheduleRecursiveBlock:", ^{ + qck_describe(@"with a synchronous scheduler", ^{ + qck_it(@"should behave like a normal block when it doesn't invoke itself", ^{ + __block BOOL executed = NO; + [RACScheduler.immediateScheduler scheduleRecursiveBlock:^(void (^recurse)(void)) { + expect(@(executed)).to(beFalsy()); + executed = YES; + }]; + + expect(@(executed)).to(beTruthy()); + }); + + qck_it(@"should reschedule itself after the caller completes", ^{ + __block NSUInteger count = 0; + [RACScheduler.immediateScheduler scheduleRecursiveBlock:^(void (^recurse)(void)) { + NSUInteger thisCount = ++count; + if (thisCount < 3) { + recurse(); + + // The block shouldn't have been invoked again yet, only + // scheduled. + expect(@(count)).to(equal(@(thisCount))); + } + }]; + + expect(@(count)).to(equal(@3)); + }); + + qck_it(@"should unroll deep recursion", ^{ + static const NSUInteger depth = 100000; + __block NSUInteger scheduleCount = 0; + [RACScheduler.immediateScheduler scheduleRecursiveBlock:^(void (^recurse)(void)) { + scheduleCount++; + + if (scheduleCount < depth) recurse(); + }]; + + expect(@(scheduleCount)).to(equal(@(depth))); + }); + }); + + qck_describe(@"with an asynchronous scheduler", ^{ + qck_it(@"should behave like a normal block when it doesn't invoke itself", ^{ + __block BOOL executed = NO; + [RACScheduler.mainThreadScheduler scheduleRecursiveBlock:^(void (^recurse)(void)) { + expect(@(executed)).to(beFalsy()); + executed = YES; + }]; + + expect(@(executed)).toEventually(beTruthy()); + }); + + qck_it(@"should reschedule itself after the caller completes", ^{ + __block NSUInteger count = 0; + [RACScheduler.mainThreadScheduler scheduleRecursiveBlock:^(void (^recurse)(void)) { + NSUInteger thisCount = ++count; + if (thisCount < 3) { + recurse(); + + // The block shouldn't have been invoked again yet, only + // scheduled. + expect(@(count)).to(equal(@(thisCount))); + } + }]; + + expect(@(count)).toEventually(equal(@3)); + }); + + qck_it(@"should reschedule when invoked asynchronously", ^{ + __block NSUInteger count = 0; + + RACScheduler *asynchronousScheduler = [RACScheduler scheduler]; + [RACScheduler.mainThreadScheduler scheduleRecursiveBlock:^(void (^recurse)(void)) { + [asynchronousScheduler after:[NSDate dateWithTimeIntervalSinceNow:0.01] schedule:^{ + NSUInteger thisCount = ++count; + if (thisCount < 3) { + recurse(); + + // The block shouldn't have been invoked again yet, only + // scheduled. + expect(@(count)).to(equal(@(thisCount))); + } + }]; + }]; + + expect(@(count)).toEventually(equal(@3)); + }); + + qck_it(@"shouldn't reschedule itself when disposed", ^{ + __block NSUInteger count = 0; + __block RACDisposable *disposable = [RACScheduler.mainThreadScheduler scheduleRecursiveBlock:^(void (^recurse)(void)) { + ++count; + + expect(disposable).notTo(beNil()); + [disposable dispose]; + + recurse(); + }]; + + expect(@(count)).toEventually(equal(@1)); + }); + }); +}); + +qck_describe(@"subclassing", ^{ + __block RACTestExampleScheduler *scheduler; + + qck_beforeEach(^{ + scheduler = [[RACTestExampleScheduler alloc] initWithQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)]; + }); + + qck_it(@"should invoke blocks scheduled with -schedule:", ^{ + __block BOOL invoked = NO; + [scheduler schedule:^{ + invoked = YES; + }]; + + expect(@(invoked)).toEventually(beTruthy()); + }); + + qck_it(@"should invoke blocks scheduled with -after:schedule:", ^{ + __block BOOL invoked = NO; + [scheduler after:[NSDate dateWithTimeIntervalSinceNow:0.01] schedule:^{ + invoked = YES; + }]; + + expect(@(invoked)).toEventually(beTruthy()); + }); + + qck_it(@"should set a valid current scheduler", ^{ + __block RACScheduler *currentScheduler; + [scheduler schedule:^{ + currentScheduler = RACScheduler.currentScheduler; + }]; + + expect(currentScheduler).toEventually(equal(scheduler)); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACSequenceAdditionsSpec.m b/ReactiveCocoaTests/RACSequenceAdditionsSpec.m new file mode 100644 index 0000000000..e7c0e9e76c --- /dev/null +++ b/ReactiveCocoaTests/RACSequenceAdditionsSpec.m @@ -0,0 +1,359 @@ +// +// RACSequenceAdditionsSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-01. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSequenceExamples.h" + +#import "NSArray+RACSequenceAdditions.h" +#import "NSDictionary+RACSequenceAdditions.h" +#import "NSOrderedSet+RACSequenceAdditions.h" +#import "NSSet+RACSequenceAdditions.h" +#import "NSString+RACSequenceAdditions.h" +#import "NSIndexSet+RACSequenceAdditions.h" +#import "RACSequence.h" +#import "RACTuple.h" + +QuickSpecBegin(RACSequenceAdditionsSpec) + +__block NSArray *numbers; + +qck_beforeEach(^{ + NSMutableArray *mutableNumbers = [NSMutableArray array]; + for (NSUInteger i = 0; i < 100; i++) { + [mutableNumbers addObject:@(i)]; + } + + numbers = [mutableNumbers copy]; +}); + +qck_describe(@"NSArray sequences", ^{ + __block NSMutableArray *values; + __block RACSequence *sequence; + + qck_beforeEach(^{ + values = [numbers mutableCopy]; + sequence = values.rac_sequence; + expect(sequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: values + }; + }); + + qck_describe(@"should be immutable", ^{ + __block NSArray *unchangedValues; + + qck_beforeEach(^{ + unchangedValues = [values copy]; + [values addObject:@6]; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: unchangedValues + }; + }); + }); + + qck_it(@"should fast enumerate after zipping", ^{ + // This certain list of values causes issues, for some reason. + NSArray *values = @[ @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0, @0 ]; + RACSequence *zippedSequence = [RACSequence zip:@[ values.rac_sequence, values.rac_sequence ] reduce:^(id obj1, id obj2) { + return obj1; + }]; + + NSMutableArray *collectedValues = [NSMutableArray array]; + for (id value in zippedSequence) { + [collectedValues addObject:value]; + } + + expect(collectedValues).to(equal(values)); + }); +}); + +qck_describe(@"NSDictionary sequences", ^{ + __block NSMutableDictionary *dict; + + __block NSMutableArray *tuples; + __block RACSequence *tupleSequence; + + __block NSArray *keys; + __block RACSequence *keySequence; + + __block NSArray *values; + __block RACSequence *valueSequence; + + qck_beforeEach(^{ + dict = [@{ + @"foo": @"bar", + @"baz": @"buzz", + @5: NSNull.null + } mutableCopy]; + + tuples = [NSMutableArray array]; + for (id key in dict) { + RACTuple *tuple = [RACTuple tupleWithObjects:key, dict[key], nil]; + [tuples addObject:tuple]; + } + + tupleSequence = dict.rac_sequence; + expect(tupleSequence).notTo(beNil()); + + keys = [dict.allKeys copy]; + keySequence = dict.rac_keySequence; + expect(keySequence).notTo(beNil()); + + values = [dict.allValues copy]; + valueSequence = dict.rac_valueSequence; + expect(valueSequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: tupleSequence, + RACSequenceExampleExpectedValues: tuples + }; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: keySequence, + RACSequenceExampleExpectedValues: keys + }; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: valueSequence, + RACSequenceExampleExpectedValues: values + }; + }); + + qck_describe(@"should be immutable", ^{ + qck_beforeEach(^{ + dict[@"foo"] = @"rab"; + dict[@6] = @7; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: tupleSequence, + RACSequenceExampleExpectedValues: tuples + }; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: keySequence, + RACSequenceExampleExpectedValues: keys + }; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: valueSequence, + RACSequenceExampleExpectedValues: values + }; + }); + }); +}); + +qck_describe(@"NSOrderedSet sequences", ^{ + __block NSMutableOrderedSet *values; + __block RACSequence *sequence; + + qck_beforeEach(^{ + values = [NSMutableOrderedSet orderedSetWithArray:numbers]; + sequence = values.rac_sequence; + expect(sequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: values.array + }; + }); + + qck_describe(@"should be immutable", ^{ + __block NSArray *unchangedValues; + + qck_beforeEach(^{ + unchangedValues = [values.array copy]; + [values addObject:@6]; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: unchangedValues + }; + }); + }); +}); + +qck_describe(@"NSSet sequences", ^{ + __block NSMutableSet *values; + __block RACSequence *sequence; + + qck_beforeEach(^{ + values = [NSMutableSet setWithArray:numbers]; + sequence = values.rac_sequence; + expect(sequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: values.allObjects + }; + }); + + qck_describe(@"should be immutable", ^{ + __block NSArray *unchangedValues; + + qck_beforeEach(^{ + unchangedValues = [values.allObjects copy]; + [values addObject:@6]; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: unchangedValues + }; + }); + }); +}); + +qck_describe(@"NSString sequences", ^{ + __block NSMutableString *string; + __block NSArray *values; + __block RACSequence *sequence; + + qck_beforeEach(^{ + string = [@"foobar" mutableCopy]; + values = @[ @"f", @"o", @"o", @"b", @"a", @"r" ]; + sequence = string.rac_sequence; + expect(sequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: values + }; + }); + + qck_describe(@"should be immutable", ^{ + qck_beforeEach(^{ + [string appendString:@"buzz"]; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: values + }; + }); + }); + + qck_it(@"should work with composed characters", ^{ + NSString *string = @"\u2665\uFE0F\u2666\uFE0F"; + NSArray *expectedSequence = @[ @"\u2665\uFE0F", @"\u2666\uFE0F" ]; + expect(string.rac_sequence.array).to(equal(expectedSequence)); + }); +}); + +qck_describe(@"RACTuple sequences", ^{ + __block RACTuple *tuple; + __block RACSequence *sequence; + + qck_beforeEach(^{ + tuple = RACTuplePack(@"foo", nil, @"bar", NSNull.null, RACTupleNil.tupleNil); + + sequence = tuple.rac_sequence; + expect(sequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: @[ @"foo", NSNull.null, @"bar", NSNull.null, NSNull.null ] + }; + }); +}); + +qck_describe(@"NSIndexSet sequences", ^{ + __block NSMutableIndexSet *values; + __block RACSequence *sequence; + + NSArray * (^valuesFromIndexSet)(NSIndexSet *indexSet) = ^NSArray *(NSIndexSet *indexSet) { + NSMutableArray *arr = [NSMutableArray array]; + [indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) { + [arr addObject:@(idx)]; + }]; + + return [arr copy]; + }; + + qck_beforeEach(^{ + values = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 10)]; + sequence = values.rac_sequence; + expect(sequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: valuesFromIndexSet(values) + }; + }); + + qck_describe(@"should be immutable", ^{ + __block NSArray *unchangedValues; + + qck_beforeEach(^{ + unchangedValues = valuesFromIndexSet(values); + [values addIndex:20]; + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: unchangedValues + }; + }); + }); + + qck_describe(@"should not fire if empty", ^{ + __block NSIndexSet *emptyIndexSet; + __block RACSequence *emptySequence; + + qck_beforeEach(^{ + emptyIndexSet = [NSIndexSet indexSet]; + emptySequence = emptyIndexSet.rac_sequence; + expect(emptySequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: emptySequence, + RACSequenceExampleExpectedValues: valuesFromIndexSet(emptyIndexSet) + }; + }); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACSequenceExamples.h b/ReactiveCocoaTests/RACSequenceExamples.h new file mode 100644 index 0000000000..922b056e74 --- /dev/null +++ b/ReactiveCocoaTests/RACSequenceExamples.h @@ -0,0 +1,16 @@ +// +// RACSequenceExamples.h +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-01. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +// The name of the shared examples for RACSequence instances. +extern NSString * const RACSequenceExamples; + +// RACSequence * +extern NSString * const RACSequenceExampleSequence; + +// NSArray * +extern NSString * const RACSequenceExampleExpectedValues; diff --git a/ReactiveCocoaTests/RACSequenceExamples.m b/ReactiveCocoaTests/RACSequenceExamples.m new file mode 100644 index 0000000000..55e29d827e --- /dev/null +++ b/ReactiveCocoaTests/RACSequenceExamples.m @@ -0,0 +1,128 @@ +// +// RACSequenceExamples.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-01. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSequenceExamples.h" + +#import "RACScheduler.h" +#import "RACSequence.h" +#import "RACSignal+Operations.h" + +NSString * const RACSequenceExamples = @"RACSequenceExamples"; +NSString * const RACSequenceExampleSequence = @"RACSequenceExampleSequence"; +NSString * const RACSequenceExampleExpectedValues = @"RACSequenceExampleExpectedValues"; + +QuickSharedExampleGroupsBegin(RACSequenceExampleGroups); + +qck_sharedExamples(RACSequenceExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block RACSequence *sequence; + __block NSArray *values; + + qck_beforeEach(^{ + sequence = exampleContext()[RACSequenceExampleSequence]; + values = [exampleContext()[RACSequenceExampleExpectedValues] copy]; + }); + + qck_it(@"should implement ", ^{ + NSMutableArray *collectedValues = [NSMutableArray array]; + for (id value in sequence) { + [collectedValues addObject:value]; + } + + expect(collectedValues).to(equal(values)); + }); + + qck_it(@"should return an array", ^{ + expect(sequence.array).to(equal(values)); + }); + + qck_describe(@"-signalWithScheduler:", ^{ + qck_it(@"should return an immediately scheduled signal", ^{ + RACSignal *signal = [sequence signalWithScheduler:RACScheduler.immediateScheduler]; + expect(signal.toArray).to(equal(values)); + }); + + qck_it(@"should return a background scheduled signal", ^{ + RACSignal *signal = [sequence signalWithScheduler:[RACScheduler scheduler]]; + expect(signal.toArray).to(equal(values)); + }); + + qck_it(@"should only evaluate one value per scheduling", ^{ + RACSignal *signal = [sequence signalWithScheduler:RACScheduler.mainThreadScheduler]; + + __block BOOL flag = YES; + __block BOOL completed = NO; + [signal subscribeNext:^(id x) { + expect(@(flag)).to(beTruthy()); + flag = NO; + + [RACScheduler.mainThreadScheduler schedule:^{ + // This should get executed before the next value (which + // verifies that it's YES). + flag = YES; + }]; + } completed:^{ + completed = YES; + }]; + + expect(@(completed)).toEventually(beTruthy()); + }); + }); + + qck_it(@"should be equal to itself", ^{ + expect(sequence).to(equal(sequence)); + }); + + qck_it(@"should be equal to the same sequence of values", ^{ + RACSequence *newSequence = RACSequence.empty; + for (id value in values) { + RACSequence *valueSeq = [RACSequence return:value]; + expect(valueSeq).notTo(beNil()); + + newSequence = [newSequence concat:valueSeq]; + } + + expect(sequence).to(equal(newSequence)); + expect(@(sequence.hash)).to(equal(@(newSequence.hash))); + }); + + qck_it(@"should not be equal to a different sequence of values", ^{ + RACSequence *anotherSequence = [RACSequence return:@(-1)]; + expect(sequence).notTo(equal(anotherSequence)); + }); + + qck_it(@"should return an identical object for -copy", ^{ + expect([sequence copy]).to(beIdenticalTo(sequence)); + }); + + qck_it(@"should archive", ^{ + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:sequence]; + expect(data).notTo(beNil()); + + RACSequence *unarchived = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + expect(unarchived).to(equal(sequence)); + }); + + qck_it(@"should fold right", ^{ + RACSequence *result = [sequence foldRightWithStart:[RACSequence empty] reduce:^(id first, RACSequence *rest) { + return [rest.head startWith:first]; + }]; + expect(result.array).to(equal(values)); + }); + + qck_it(@"should fold left", ^{ + RACSequence *result = [sequence foldLeftWithStart:[RACSequence empty] reduce:^(RACSequence *first, id rest) { + return [first concat:[RACSequence return:rest]]; + }]; + expect(result.array).to(equal(values)); + }); +}); + +QuickSharedExampleGroupsEnd diff --git a/ReactiveCocoaTests/RACSequenceSpec.m b/ReactiveCocoaTests/RACSequenceSpec.m new file mode 100644 index 0000000000..760aff3434 --- /dev/null +++ b/ReactiveCocoaTests/RACSequenceSpec.m @@ -0,0 +1,443 @@ +// +// RACSequenceSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-01. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSequenceExamples.h" +#import "RACStreamExamples.h" + +#import "NSArray+RACSequenceAdditions.h" +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACPropertySubscribing.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACSequence.h" +#import "RACUnit.h" + +QuickSpecBegin(RACSequenceSpec) + +qck_describe(@"RACStream", ^{ + id verifyValues = ^(RACSequence *sequence, NSArray *expectedValues) { + NSMutableArray *collectedValues = [NSMutableArray array]; + while (sequence.head != nil) { + [collectedValues addObject:sequence.head]; + sequence = sequence.tail; + } + + expect(collectedValues).to(equal(expectedValues)); + }; + + __block RACSequence *infiniteSequence = [RACSequence sequenceWithHeadBlock:^{ + return RACUnit.defaultUnit; + } tailBlock:^{ + return infiniteSequence; + }]; + + qck_itBehavesLike(RACStreamExamples, ^{ + return @{ + RACStreamExamplesClass: RACSequence.class, + RACStreamExamplesVerifyValuesBlock: verifyValues, + RACStreamExamplesInfiniteStream: infiniteSequence + }; + }); +}); + +qck_describe(@"+sequenceWithHeadBlock:tailBlock:", ^{ + __block RACSequence *sequence; + __block BOOL headInvoked; + __block BOOL tailInvoked; + + qck_beforeEach(^{ + headInvoked = NO; + tailInvoked = NO; + + sequence = [RACSequence sequenceWithHeadBlock:^{ + headInvoked = YES; + return @0; + } tailBlock:^{ + tailInvoked = YES; + return [RACSequence return:@1]; + }]; + + expect(sequence).notTo(beNil()); + }); + + qck_it(@"should use the values from the head and tail blocks", ^{ + expect(sequence.head).to(equal(@0)); + expect(sequence.tail.head).to(equal(@1)); + expect(sequence.tail.tail).to(beNil()); + }); + + qck_it(@"should lazily invoke head and tail blocks", ^{ + expect(@(headInvoked)).to(beFalsy()); + expect(@(tailInvoked)).to(beFalsy()); + + expect(sequence.head).to(equal(@0)); + expect(@(headInvoked)).to(beTruthy()); + expect(@(tailInvoked)).to(beFalsy()); + + expect(sequence.tail).notTo(beNil()); + expect(@(tailInvoked)).to(beTruthy()); + }); + + qck_afterEach(^{ + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: sequence, + RACSequenceExampleExpectedValues: @[ @0, @1 ] + }; + }); + }); +}); + +qck_describe(@"empty sequences", ^{ + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: [RACSequence empty], + RACSequenceExampleExpectedValues: @[] + }; + }); +}); + +qck_describe(@"non-empty sequences", ^{ + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: [[[RACSequence return:@0] concat:[RACSequence return:@1]] concat:[RACSequence return:@2]], + RACSequenceExampleExpectedValues: @[ @0, @1, @2 ] + }; + }); +}); + +qck_describe(@"eager sequences", ^{ + __block RACSequence *lazySequence; + __block BOOL headInvoked; + __block BOOL tailInvoked; + + NSArray *values = @[ @0, @1 ]; + + qck_beforeEach(^{ + headInvoked = NO; + tailInvoked = NO; + + lazySequence = [RACSequence sequenceWithHeadBlock:^{ + headInvoked = YES; + return @0; + } tailBlock:^{ + tailInvoked = YES; + return [RACSequence return:@1]; + }]; + + expect(lazySequence).notTo(beNil()); + }); + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: lazySequence.eagerSequence, + RACSequenceExampleExpectedValues: values + }; + }); + + qck_it(@"should evaluate all values immediately", ^{ + RACSequence *eagerSequence = lazySequence.eagerSequence; + expect(@(headInvoked)).to(beTruthy()); + expect(@(tailInvoked)).to(beTruthy()); + expect(eagerSequence.array).to(equal(values)); + }); +}); + +qck_describe(@"-take:", ^{ + qck_it(@"should complete take: without needing the head of the second item in the sequence", ^{ + __block NSUInteger valuesTaken = 0; + + __block RACSequence *sequence = [RACSequence sequenceWithHeadBlock:^{ + ++valuesTaken; + return RACUnit.defaultUnit; + } tailBlock:^{ + return sequence; + }]; + + NSArray *values = [sequence take:1].array; + expect(values).to(equal(@[ RACUnit.defaultUnit ])); + expect(@(valuesTaken)).to(equal(@1)); + }); +}); + +qck_describe(@"-bind:", ^{ + qck_it(@"should only evaluate head when the resulting sequence is evaluated", ^{ + __block BOOL headInvoked = NO; + + RACSequence *original = [RACSequence sequenceWithHeadBlock:^{ + headInvoked = YES; + return RACUnit.defaultUnit; + } tailBlock:^ id { + return nil; + }]; + + RACSequence *bound = [original bind:^{ + return ^(id value, BOOL *stop) { + return [RACSequence return:value]; + }; + }]; + + expect(bound).notTo(beNil()); + expect(@(headInvoked)).to(beFalsy()); + + expect(bound.head).to(equal(RACUnit.defaultUnit)); + expect(@(headInvoked)).to(beTruthy()); + }); +}); + +qck_describe(@"-objectEnumerator", ^{ + qck_it(@"should only evaluate head as it's enumerated", ^{ + __block BOOL firstHeadInvoked = NO; + __block BOOL secondHeadInvoked = NO; + __block BOOL thirdHeadInvoked = NO; + + RACSequence *sequence = [RACSequence sequenceWithHeadBlock:^id{ + firstHeadInvoked = YES; + return @1; + } tailBlock:^RACSequence *{ + return [RACSequence sequenceWithHeadBlock:^id{ + secondHeadInvoked = YES; + return @2; + } tailBlock:^RACSequence *{ + return [RACSequence sequenceWithHeadBlock:^id{ + thirdHeadInvoked = YES; + return @3; + } tailBlock:^RACSequence *{ + return RACSequence.empty; + }]; + }]; + }]; + NSEnumerator *enumerator = sequence.objectEnumerator; + + expect(@(firstHeadInvoked)).to(beFalsy()); + expect(@(secondHeadInvoked)).to(beFalsy()); + expect(@(thirdHeadInvoked)).to(beFalsy()); + + expect([enumerator nextObject]).to(equal(@1)); + + expect(@(firstHeadInvoked)).to(beTruthy()); + expect(@(secondHeadInvoked)).to(beFalsy()); + expect(@(thirdHeadInvoked)).to(beFalsy()); + + expect([enumerator nextObject]).to(equal(@2)); + + expect(@(secondHeadInvoked)).to(beTruthy()); + expect(@(thirdHeadInvoked)).to(beFalsy()); + + expect([enumerator nextObject]).to(equal(@3)); + + expect(@(thirdHeadInvoked)).to(beTruthy()); + + expect([enumerator nextObject]).to(beNil()); + }); + + qck_it(@"should let the sequence dealloc as it's enumerated", ^{ + __block BOOL firstSequenceDeallocd = NO; + __block BOOL secondSequenceDeallocd = NO; + __block BOOL thirdSequenceDeallocd = NO; + + NSEnumerator *enumerator = nil; + + @autoreleasepool { + RACSequence *thirdSequence __attribute__((objc_precise_lifetime)) = [RACSequence sequenceWithHeadBlock:^id{ + return @3; + } tailBlock:^RACSequence *{ + return RACSequence.empty; + }]; + [thirdSequence.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + thirdSequenceDeallocd = YES; + }]]; + + RACSequence *secondSequence __attribute__((objc_precise_lifetime)) = [RACSequence sequenceWithHeadBlock:^id{ + return @2; + } tailBlock:^RACSequence *{ + return thirdSequence; + }]; + [secondSequence.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + secondSequenceDeallocd = YES; + }]]; + + RACSequence *firstSequence __attribute__((objc_precise_lifetime)) = [RACSequence sequenceWithHeadBlock:^id{ + return @1; + } tailBlock:^RACSequence *{ + return secondSequence; + }]; + [firstSequence.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + firstSequenceDeallocd = YES; + }]]; + + enumerator = firstSequence.objectEnumerator; + } + + @autoreleasepool { + expect([enumerator nextObject]).to(equal(@1)); + } + + @autoreleasepool { + expect([enumerator nextObject]).to(equal(@2)); + } + expect(@(firstSequenceDeallocd)).toEventually(beTruthy()); + + @autoreleasepool { + expect([enumerator nextObject]).to(equal(@3)); + } + expect(@(secondSequenceDeallocd)).toEventually(beTruthy()); + + @autoreleasepool { + expect([enumerator nextObject]).to(beNil()); + } + expect(@(thirdSequenceDeallocd)).toEventually(beTruthy()); + }); +}); + +qck_it(@"shouldn't overflow the stack when deallocated on a background queue", ^{ + NSUInteger length = 10000; + NSMutableArray *values = [NSMutableArray arrayWithCapacity:length]; + for (NSUInteger i = 0; i < length; ++i) { + [values addObject:@(i)]; + } + + __block BOOL finished = NO; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + @autoreleasepool { + [[values.rac_sequence map:^(id value) { + return value; + }] array]; + } + + finished = YES; + }); + + expect(@(finished)).toEventually(beTruthy()); +}); + +qck_describe(@"-foldLeftWithStart:reduce:", ^{ + qck_it(@"should reduce with start first", ^{ + RACSequence *sequence = [[[RACSequence return:@0] concat:[RACSequence return:@1]] concat:[RACSequence return:@2]]; + NSNumber *result = [sequence foldLeftWithStart:@3 reduce:^(NSNumber *first, NSNumber *rest) { + return first; + }]; + expect(result).to(equal(@3)); + }); + + qck_it(@"should be left associative", ^{ + RACSequence *sequence = [[[RACSequence return:@1] concat:[RACSequence return:@2]] concat:[RACSequence return:@3]]; + NSNumber *result = [sequence foldLeftWithStart:@0 reduce:^(NSNumber *first, NSNumber *rest) { + int difference = first.intValue - rest.intValue; + return @(difference); + }]; + expect(result).to(equal(@-6)); + }); +}); + +qck_describe(@"-foldRightWithStart:reduce:", ^{ + qck_it(@"should be lazy", ^{ + __block BOOL headInvoked = NO; + __block BOOL tailInvoked = NO; + RACSequence *sequence = [RACSequence sequenceWithHeadBlock:^{ + headInvoked = YES; + return @0; + } tailBlock:^{ + tailInvoked = YES; + return [RACSequence return:@1]; + }]; + + NSNumber *result = [sequence foldRightWithStart:@2 reduce:^(NSNumber *first, RACSequence *rest) { + return first; + }]; + + expect(result).to(equal(@0)); + expect(@(headInvoked)).to(beTruthy()); + expect(@(tailInvoked)).to(beFalsy()); + }); + + qck_it(@"should reduce with start last", ^{ + RACSequence *sequence = [[[RACSequence return:@0] concat:[RACSequence return:@1]] concat:[RACSequence return:@2]]; + NSNumber *result = [sequence foldRightWithStart:@3 reduce:^(NSNumber *first, RACSequence *rest) { + return rest.head; + }]; + expect(result).to(equal(@3)); + }); + + qck_it(@"should be right associative", ^{ + RACSequence *sequence = [[[RACSequence return:@1] concat:[RACSequence return:@2]] concat:[RACSequence return:@3]]; + NSNumber *result = [sequence foldRightWithStart:@0 reduce:^(NSNumber *first, RACSequence *rest) { + int difference = first.intValue - [rest.head intValue]; + return @(difference); + }]; + expect(result).to(equal(@2)); + }); +}); + +qck_describe(@"-any", ^{ + __block RACSequence *sequence; + qck_beforeEach(^{ + sequence = [[[RACSequence return:@0] concat:[RACSequence return:@1]] concat:[RACSequence return:@2]]; + }); + + qck_it(@"should return true when at least one exists", ^{ + BOOL result = [sequence any:^ BOOL (NSNumber *value) { + return value.integerValue > 0; + }]; + expect(@(result)).to(beTruthy()); + }); + + qck_it(@"should return false when no such thing exists", ^{ + BOOL result = [sequence any:^ BOOL (NSNumber *value) { + return value.integerValue == 3; + }]; + expect(@(result)).to(beFalsy()); + }); +}); + +qck_describe(@"-all", ^{ + __block RACSequence *sequence; + qck_beforeEach(^{ + sequence = [[[RACSequence return:@0] concat:[RACSequence return:@1]] concat:[RACSequence return:@2]]; + }); + + qck_it(@"should return true when all values pass", ^{ + BOOL result = [sequence all:^ BOOL (NSNumber *value) { + return value.integerValue >= 0; + }]; + expect(@(result)).to(beTruthy()); + }); + + qck_it(@"should return false when at least one value fails", ^{ + BOOL result = [sequence all:^ BOOL (NSNumber *value) { + return value.integerValue < 2; + }]; + expect(@(result)).to(beFalsy()); + }); +}); + +qck_describe(@"-objectPassingTest:", ^{ + __block RACSequence *sequence; + qck_beforeEach(^{ + sequence = [[[RACSequence return:@0] concat:[RACSequence return:@1]] concat:[RACSequence return:@2]]; + }); + + qck_it(@"should return leftmost object that passes the test", ^{ + NSNumber *result = [sequence objectPassingTest:^ BOOL (NSNumber *value) { + return value.intValue > 0; + }]; + expect(result).to(equal(@1)); + }); + + qck_it(@"should return nil if no objects pass the test", ^{ + NSNumber *result = [sequence objectPassingTest:^ BOOL (NSNumber *value) { + return value.intValue < 0; + }]; + expect(result).to(beNil()); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACSerialDisposableSpec.m b/ReactiveCocoaTests/RACSerialDisposableSpec.m new file mode 100644 index 0000000000..64aeeb5579 --- /dev/null +++ b/ReactiveCocoaTests/RACSerialDisposableSpec.m @@ -0,0 +1,140 @@ +// +// RACSerialDisposableSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-07-22. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSerialDisposable.h" + +QuickSpecBegin(RACSerialDisposableSpec) + +qck_it(@"should initialize with -init", ^{ + RACSerialDisposable *serial = [[RACSerialDisposable alloc] init]; + expect(serial).notTo(beNil()); + expect(serial.disposable).to(beNil()); +}); + +qck_it(@"should initialize an inner disposable with -initWithBlock:", ^{ + __block BOOL disposed = NO; + RACSerialDisposable *serial = [RACSerialDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + expect(serial).notTo(beNil()); + expect(serial.disposable).notTo(beNil()); + + [serial.disposable dispose]; + expect(@(serial.disposed)).to(beFalsy()); + expect(@(disposed)).to(beTruthy()); +}); + +qck_it(@"should initialize with a disposable", ^{ + RACDisposable *inner = [[RACDisposable alloc] init]; + RACSerialDisposable *serial = [RACSerialDisposable serialDisposableWithDisposable:inner]; + expect(serial).notTo(beNil()); + expect(serial.disposable).to(equal(inner)); +}); + +qck_it(@"should dispose of the inner disposable", ^{ + __block BOOL disposed = NO; + RACDisposable *inner = [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + RACSerialDisposable *serial = [RACSerialDisposable serialDisposableWithDisposable:inner]; + expect(@(serial.disposed)).to(beFalsy()); + expect(@(disposed)).to(beFalsy()); + + [serial dispose]; + expect(@(serial.disposed)).to(beTruthy()); + expect(serial.disposable).to(beNil()); + expect(@(disposed)).to(beTruthy()); +}); + +qck_it(@"should dispose of a new inner disposable if it's already been disposed", ^{ + __block BOOL disposed = NO; + RACDisposable *inner = [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + RACSerialDisposable *serial = [[RACSerialDisposable alloc] init]; + expect(@(serial.disposed)).to(beFalsy()); + + [serial dispose]; + expect(@(serial.disposed)).to(beTruthy()); + expect(@(disposed)).to(beFalsy()); + + serial.disposable = inner; + expect(@(disposed)).to(beTruthy()); + expect(serial.disposable).to(beNil()); +}); + +qck_it(@"should allow the inner disposable to be set to nil", ^{ + __block BOOL disposed = NO; + RACDisposable *inner = [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + + RACSerialDisposable *serial = [RACSerialDisposable serialDisposableWithDisposable:inner]; + expect(@(disposed)).to(beFalsy()); + + serial.disposable = nil; + expect(serial.disposable).to(beNil()); + + serial.disposable = inner; + expect(serial.disposable).to(equal(inner)); + + [serial dispose]; + expect(@(disposed)).to(beTruthy()); + expect(serial.disposable).to(beNil()); +}); + +qck_it(@"should swap inner disposables", ^{ + __block BOOL firstDisposed = NO; + RACDisposable *first = [RACDisposable disposableWithBlock:^{ + firstDisposed = YES; + }]; + + __block BOOL secondDisposed = NO; + RACDisposable *second = [RACDisposable disposableWithBlock:^{ + secondDisposed = YES; + }]; + + RACSerialDisposable *serial = [RACSerialDisposable serialDisposableWithDisposable:first]; + expect([serial swapInDisposable:second]).to(equal(first)); + + expect(@(serial.disposed)).to(beFalsy()); + expect(@(firstDisposed)).to(beFalsy()); + expect(@(secondDisposed)).to(beFalsy()); + + [serial dispose]; + expect(@(serial.disposed)).to(beTruthy()); + expect(serial.disposable).to(beNil()); + + expect(@(firstDisposed)).to(beFalsy()); + expect(@(secondDisposed)).to(beTruthy()); +}); + +qck_it(@"should release the inner disposable upon deallocation", ^{ + __weak RACDisposable *weakInnerDisposable; + __weak RACSerialDisposable *weakSerialDisposable; + + @autoreleasepool { + RACDisposable *innerDisposable __attribute__((objc_precise_lifetime)) = [[RACDisposable alloc] init]; + weakInnerDisposable = innerDisposable; + + RACSerialDisposable *serialDisposable __attribute__((objc_precise_lifetime)) = [[RACSerialDisposable alloc] init]; + serialDisposable.disposable = innerDisposable; + weakSerialDisposable = serialDisposable; + } + + expect(weakSerialDisposable).to(beNil()); + expect(weakInnerDisposable).to(beNil()); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACSignalSpec.m b/ReactiveCocoaTests/RACSignalSpec.m new file mode 100644 index 0000000000..8edf6debc7 --- /dev/null +++ b/ReactiveCocoaTests/RACSignalSpec.m @@ -0,0 +1,3879 @@ +// +// RACSignalSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 3/2/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACPropertySignalExamples.h" +#import "RACSequenceExamples.h" +#import "RACStreamExamples.h" +#import "RACTestObject.h" + +#import "EXTKeyPathCoding.h" +#import "NSObject+RACDeallocating.h" +#import "NSObject+RACPropertySubscribing.h" +#import "RACBehaviorSubject.h" +#import "RACCommand.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACEvent.h" +#import "RACGroupedSignal.h" +#import "RACMulticastConnection.h" +#import "RACReplaySubject.h" +#import "RACScheduler.h" +#import "RACSignal+Operations.h" +#import "RACSubject.h" +#import "RACSubscriber+Private.h" +#import "RACSubscriber.h" +#import "RACTestScheduler.h" +#import "RACTuple.h" +#import "RACUnit.h" +#import + +// Set in a beforeAll below. +static NSError *RACSignalTestError; + +static NSString * const RACSignalMergeConcurrentCompletionExampleGroup = @"RACSignalMergeConcurrentCompletionExampleGroup"; +static NSString * const RACSignalMaxConcurrent = @"RACSignalMaxConcurrent"; + +QuickSharedExampleGroupsBegin(mergeConcurrentCompletionName) + +qck_sharedExamples(RACSignalMergeConcurrentCompletionExampleGroup, ^(QCKDSLSharedExampleContext exampleContext) { + qck_it(@"should complete only after the source and all its signals have completed", ^{ + RACSubject *subject1 = [RACSubject subject]; + RACSubject *subject2 = [RACSubject subject]; + RACSubject *subject3 = [RACSubject subject]; + + RACSubject *signalsSubject = [RACSubject subject]; + __block BOOL completed = NO; + [[signalsSubject flatten:[exampleContext()[RACSignalMaxConcurrent] unsignedIntegerValue]] subscribeCompleted:^{ + completed = YES; + }]; + + [signalsSubject sendNext:subject1]; + [subject1 sendCompleted]; + + expect(@(completed)).to(beFalsy()); + + [signalsSubject sendNext:subject2]; + [signalsSubject sendNext:subject3]; + + [signalsSubject sendCompleted]; + + expect(@(completed)).to(beFalsy()); + + [subject2 sendCompleted]; + + expect(@(completed)).to(beFalsy()); + + [subject3 sendCompleted]; + + expect(@(completed)).to(beTruthy()); + }); +}); + +QuickSharedExampleGroupsEnd + +QuickSpecBegin(RACSignalSpec) + +qck_beforeSuite(^{ + // We do this instead of a macro to ensure that to(equal() will work + // correctly (by matching identity), even if -[NSError isEqual:] is broken. + RACSignalTestError = [NSError errorWithDomain:@"foo" code:100 userInfo:nil]; +}); + +qck_describe(@"RACStream", ^{ + id verifyValues = ^(RACSignal *signal, NSArray *expectedValues) { + expect(signal).notTo(beNil()); + + NSMutableArray *collectedValues = [NSMutableArray array]; + + __block BOOL success = NO; + __block NSError *error = nil; + [signal subscribeNext:^(id value) { + [collectedValues addObject:value]; + } error:^(NSError *receivedError) { + error = receivedError; + } completed:^{ + success = YES; + }]; + + expect(@(success)).toEventually(beTruthy()); + expect(error).to(beNil()); + expect(collectedValues).to(equal(expectedValues)); + }; + + RACSignal *infiniteSignal = [RACSignal createSignal:^(id subscriber) { + __block volatile int32_t done = 0; + + [RACScheduler.mainThreadScheduler schedule:^{ + while (!done) { + [subscriber sendNext:RACUnit.defaultUnit]; + } + }]; + + return [RACDisposable disposableWithBlock:^{ + OSAtomicIncrement32Barrier(&done); + }]; + }]; + + qck_itBehavesLike(RACStreamExamples, ^{ + return @{ + RACStreamExamplesClass: RACSignal.class, + RACStreamExamplesVerifyValuesBlock: verifyValues, + RACStreamExamplesInfiniteStream: infiniteSignal + }; + }); +}); + +qck_describe(@"-bind:", ^{ + __block RACSubject *signals; + __block BOOL disposed; + __block id lastValue; + __block RACSubject *values; + + qck_beforeEach(^{ + // Tests send a (RACSignal, BOOL) pair that are used below in -bind:. + signals = [RACSubject subject]; + + disposed = NO; + RACSignal *source = [RACSignal createSignal:^(id subscriber) { + [signals subscribe:subscriber]; + + return [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + }]; + + RACSignal *bind = [source bind:^{ + return ^(RACTuple *x, BOOL *stop) { + RACTupleUnpack(RACSignal *signal, NSNumber *stopValue) = x; + *stop = stopValue.boolValue; + return signal; + }; + }]; + + lastValue = nil; + [bind subscribeNext:^(id x) { + lastValue = x; + }]; + + // Send `bind` an open ended subject to subscribe to( These tests make + // use of this in two ways: + // 1. Used to test a regression bug where -bind: would not actually + // stop when instructed to. This bug manifested itself only when + // there were subscriptions that lived on past the point at which + // -bind: was stopped. This subject represents such a subscription. + // 2. Test that values sent by this subject are received by `bind`'s + // subscriber, even *after* -bind: has been instructed to stop. + values = [RACSubject subject]; + [signals sendNext:RACTuplePack(values, @NO)]; + expect(@(disposed)).to(beFalsy()); + }); + + qck_it(@"should dispose source signal when stopped with nil signal", ^{ + // Tell -bind: to stop by sending it a `nil` signal. + [signals sendNext:RACTuplePack(nil, @NO)]; + expect(@(disposed)).to(beTruthy()); + + // Should still receive values sent after stopping. + expect(lastValue).to(beNil()); + [values sendNext:RACUnit.defaultUnit]; + expect(lastValue).to(equal(RACUnit.defaultUnit)); + }); + + qck_it(@"should dispose source signal when stop flag set to YES", ^{ + // Tell -bind: to stop by setting the stop flag to YES. + [signals sendNext:RACTuplePack([RACSignal return:@1], @YES)]; + expect(@(disposed)).to(beTruthy()); + + // Should still recieve last signal sent at the time of setting stop to YES. + expect(lastValue).to(equal(@1)); + + // Should still receive values sent after stopping. + [values sendNext:@2]; + expect(lastValue).to(equal(@2)); + }); + + qck_it(@"should properly stop subscribing to new signals after error", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:@0]; + [subscriber sendNext:@1]; + return nil; + }]; + + __block BOOL subscribedAfterError = NO; + RACSignal *bind = [signal bind:^{ + return ^(NSNumber *x, BOOL *stop) { + if (x.integerValue == 0) return [RACSignal error:nil]; + + return [RACSignal defer:^{ + subscribedAfterError = YES; + return [RACSignal empty]; + }]; + }; + }]; + + [bind subscribeCompleted:^{}]; + expect(@(subscribedAfterError)).to(beFalsy()); + }); + + qck_it(@"should not subscribe to signals following error in +merge:", ^{ + __block BOOL firstSubscribed = NO; + __block BOOL secondSubscribed = NO; + __block BOOL errored = NO; + + RACSignal *signal = [[RACSignal + merge:@[ + [RACSignal defer:^{ + firstSubscribed = YES; + return [RACSignal error:nil]; + }], + [RACSignal defer:^{ + secondSubscribed = YES; + return [RACSignal return:nil]; + }] + ]] + doError:^(NSError *error) { + errored = YES; + }]; + + [signal subscribeCompleted:^{}]; + + expect(@(firstSubscribed)).to(beTruthy()); + expect(@(secondSubscribed)).to(beFalsy()); + expect(@(errored)).to(beTruthy()); + }); +}); + +qck_describe(@"subscribing", ^{ + __block RACSignal *signal = nil; + id nextValueSent = @"1"; + + qck_beforeEach(^{ + signal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:nextValueSent]; + [subscriber sendCompleted]; + return nil; + }]; + }); + + qck_it(@"should get next values", ^{ + __block id nextValueReceived = nil; + [signal subscribeNext:^(id x) { + nextValueReceived = x; + } error:^(NSError *error) { + + } completed:^{ + + }]; + + expect(nextValueReceived).to(equal(nextValueSent)); + }); + + qck_it(@"should get completed", ^{ + __block BOOL didGetCompleted = NO; + [signal subscribeNext:^(id x) { + + } error:^(NSError *error) { + + } completed:^{ + didGetCompleted = YES; + }]; + + expect(@(didGetCompleted)).to(beTruthy()); + }); + + qck_it(@"should not get an error", ^{ + __block BOOL didGetError = NO; + [signal subscribeNext:^(id x) { + + } error:^(NSError *error) { + didGetError = YES; + } completed:^{ + + }]; + + expect(@(didGetError)).to(beFalsy()); + }); + + qck_it(@"shouldn't get anything after dispose", ^{ + RACTestScheduler *scheduler = [[RACTestScheduler alloc] init]; + NSMutableArray *receivedValues = [NSMutableArray array]; + + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:@0]; + + [scheduler afterDelay:0 schedule:^{ + [subscriber sendNext:@1]; + }]; + + return nil; + }]; + + RACDisposable *disposable = [signal subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + NSArray *expectedValues = @[ @0 ]; + expect(receivedValues).to(equal(expectedValues)); + + [disposable dispose]; + [scheduler stepAll]; + + expect(receivedValues).to(equal(expectedValues)); + }); + + qck_it(@"should have a current scheduler in didSubscribe block", ^{ + __block RACScheduler *currentScheduler; + RACSignal *signal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + currentScheduler = RACScheduler.currentScheduler; + [subscriber sendCompleted]; + return nil; + }]; + + [signal subscribeNext:^(id x) {}]; + expect(currentScheduler).notTo(beNil()); + + currentScheduler = nil; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [signal subscribeNext:^(id x) {}]; + }); + expect(currentScheduler).toEventuallyNot(beNil()); + }); + + qck_it(@"should automatically dispose of other subscriptions from +createSignal:", ^{ + __block BOOL innerDisposed = NO; + __block id innerSubscriber = nil; + + RACSignal *innerSignal = [RACSignal createSignal:^(id subscriber) { + // Keep the subscriber alive so it doesn't trigger disposal on dealloc + innerSubscriber = subscriber; + return [RACDisposable disposableWithBlock:^{ + innerDisposed = YES; + }]; + }]; + + RACSignal *outerSignal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [innerSignal subscribe:subscriber]; + return nil; + }]; + + RACDisposable *disposable = [outerSignal subscribeCompleted:^{}]; + expect(disposable).notTo(beNil()); + expect(@(innerDisposed)).to(beFalsy()); + + [disposable dispose]; + expect(@(innerDisposed)).to(beTruthy()); + }); +}); + +qck_describe(@"-takeUntil:", ^{ + qck_it(@"should support value as trigger", ^{ + __block BOOL shouldBeGettingItems = YES; + RACSubject *subject = [RACSubject subject]; + RACSubject *cutOffSubject = [RACSubject subject]; + [[subject takeUntil:cutOffSubject] subscribeNext:^(id x) { + expect(@(shouldBeGettingItems)).to(beTruthy()); + }]; + + shouldBeGettingItems = YES; + [subject sendNext:@"test 1"]; + [subject sendNext:@"test 2"]; + + [cutOffSubject sendNext:[RACUnit defaultUnit]]; + + shouldBeGettingItems = NO; + [subject sendNext:@"test 3"]; + }); + + qck_it(@"should support completion as trigger", ^{ + __block BOOL shouldBeGettingItems = YES; + RACSubject *subject = [RACSubject subject]; + RACSubject *cutOffSubject = [RACSubject subject]; + [[subject takeUntil:cutOffSubject] subscribeNext:^(id x) { + expect(@(shouldBeGettingItems)).to(beTruthy()); + }]; + + [cutOffSubject sendCompleted]; + + shouldBeGettingItems = NO; + [subject sendNext:@"should not go through"]; + }); + + qck_it(@"should squelch any values sent immediately upon subscription", ^{ + RACSignal *valueSignal = [RACSignal return:RACUnit.defaultUnit]; + RACSignal *cutOffSignal = [RACSignal empty]; + + __block BOOL gotNext = NO; + __block BOOL completed = NO; + + [[valueSignal takeUntil:cutOffSignal] subscribeNext:^(id _) { + gotNext = YES; + } completed:^{ + completed = YES; + }]; + + expect(@(gotNext)).to(beFalsy()); + expect(@(completed)).to(beTruthy()); + }); +}); + +qck_describe(@"-takeUntilReplacement:", ^{ + qck_it(@"should forward values from the receiver until it's replaced", ^{ + RACSubject *receiver = [RACSubject subject]; + RACSubject *replacement = [RACSubject subject]; + + NSMutableArray *receivedValues = [NSMutableArray array]; + + [[receiver takeUntilReplacement:replacement] subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + expect(receivedValues).to(equal(@[])); + + [receiver sendNext:@1]; + expect(receivedValues).to(equal(@[ @1 ])); + + [receiver sendNext:@2]; + expect(receivedValues).to(equal((@[ @1, @2 ]))); + + [replacement sendNext:@3]; + expect(receivedValues).to(equal((@[ @1, @2, @3 ]))); + + [receiver sendNext:@4]; + expect(receivedValues).to(equal((@[ @1, @2, @3 ]))); + + [replacement sendNext:@5]; + expect(receivedValues).to(equal((@[ @1, @2, @3, @5 ]))); + }); + + qck_it(@"should forward error from the receiver", ^{ + RACSubject *receiver = [RACSubject subject]; + __block BOOL receivedError = NO; + + [[receiver takeUntilReplacement:RACSignal.never] subscribeError:^(NSError *error) { + receivedError = YES; + }]; + + [receiver sendError:nil]; + expect(@(receivedError)).to(beTruthy()); + }); + + qck_it(@"should not forward completed from the receiver", ^{ + RACSubject *receiver = [RACSubject subject]; + __block BOOL receivedCompleted = NO; + + [[receiver takeUntilReplacement:RACSignal.never] subscribeCompleted: ^{ + receivedCompleted = YES; + }]; + + [receiver sendCompleted]; + expect(@(receivedCompleted)).to(beFalsy()); + }); + + qck_it(@"should forward error from the replacement signal", ^{ + RACSubject *replacement = [RACSubject subject]; + __block BOOL receivedError = NO; + + [[RACSignal.never takeUntilReplacement:replacement] subscribeError:^(NSError *error) { + receivedError = YES; + }]; + + [replacement sendError:nil]; + expect(@(receivedError)).to(beTruthy()); + }); + + qck_it(@"should forward completed from the replacement signal", ^{ + RACSubject *replacement = [RACSubject subject]; + __block BOOL receivedCompleted = NO; + + [[RACSignal.never takeUntilReplacement:replacement] subscribeCompleted: ^{ + receivedCompleted = YES; + }]; + + [replacement sendCompleted]; + expect(@(receivedCompleted)).to(beTruthy()); + }); + + qck_it(@"should not forward values from the receiver if both send synchronously", ^{ + RACSignal *receiver = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendNext:@2]; + [subscriber sendNext:@3]; + return nil; + }]; + RACSignal *replacement = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@4]; + [subscriber sendNext:@5]; + [subscriber sendNext:@6]; + return nil; + }]; + + NSMutableArray *receivedValues = [NSMutableArray array]; + + [[receiver takeUntilReplacement:replacement] subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + expect(receivedValues).to(equal((@[ @4, @5, @6 ]))); + }); + + qck_it(@"should dispose of the receiver when it's disposed of", ^{ + __block BOOL receiverDisposed = NO; + RACSignal *receiver = [RACSignal createSignal:^(id subscriber) { + return [RACDisposable disposableWithBlock:^{ + receiverDisposed = YES; + }]; + }]; + + [[[receiver takeUntilReplacement:RACSignal.never] subscribeCompleted:^{}] dispose]; + + expect(@(receiverDisposed)).to(beTruthy()); + }); + + qck_it(@"should dispose of the replacement signal when it's disposed of", ^{ + __block BOOL replacementDisposed = NO; + RACSignal *replacement = [RACSignal createSignal:^(id subscriber) { + return [RACDisposable disposableWithBlock:^{ + replacementDisposed = YES; + }]; + }]; + + [[[RACSignal.never takeUntilReplacement:replacement] subscribeCompleted:^{}] dispose]; + + expect(@(replacementDisposed)).to(beTruthy()); + }); + + qck_it(@"should dispose of the receiver when the replacement signal sends an event", ^{ + __block BOOL receiverDisposed = NO; + __block id receiverSubscriber = nil; + RACSignal *receiver = [RACSignal createSignal:^(id subscriber) { + // Keep the subscriber alive so it doesn't trigger disposal on dealloc + receiverSubscriber = subscriber; + return [RACDisposable disposableWithBlock:^{ + receiverDisposed = YES; + }]; + }]; + RACSubject *replacement = [RACSubject subject]; + + [[receiver takeUntilReplacement:replacement] subscribeCompleted:^{}]; + + expect(@(receiverDisposed)).to(beFalsy()); + + [replacement sendNext:nil]; + + expect(@(receiverDisposed)).to(beTruthy()); + }); +}); + +qck_describe(@"disposal", ^{ + qck_it(@"should dispose of the didSubscribe disposable", ^{ + __block BOOL innerDisposed = NO; + RACSignal *signal = [RACSignal createSignal:^(id subscriber) { + return [RACDisposable disposableWithBlock:^{ + innerDisposed = YES; + }]; + }]; + + expect(@(innerDisposed)).to(beFalsy()); + + RACDisposable *disposable = [signal subscribeNext:^(id x) {}]; + expect(disposable).notTo(beNil()); + + [disposable dispose]; + expect(@(innerDisposed)).to(beTruthy()); + }); + + qck_it(@"should dispose of the didSubscribe disposable asynchronously", ^{ + __block BOOL innerDisposed = NO; + RACSignal *signal = [RACSignal createSignal:^(id subscriber) { + return [RACDisposable disposableWithBlock:^{ + innerDisposed = YES; + }]; + }]; + + [[RACScheduler scheduler] schedule:^{ + RACDisposable *disposable = [signal subscribeNext:^(id x) {}]; + [disposable dispose]; + }]; + + expect(@(innerDisposed)).toEventually(beTruthy()); + }); +}); + +qck_describe(@"querying", ^{ + __block RACSignal *signal = nil; + id nextValueSent = @"1"; + + qck_beforeEach(^{ + signal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:nextValueSent]; + [subscriber sendNext:@"other value"]; + [subscriber sendCompleted]; + return nil; + }]; + }); + + qck_it(@"should return first 'next' value with -firstOrDefault:success:error:", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendNext:@2]; + [subscriber sendNext:@3]; + [subscriber sendCompleted]; + return nil; + }]; + + expect(signal).notTo(beNil()); + + __block BOOL success = NO; + __block NSError *error = nil; + expect([signal firstOrDefault:@5 success:&success error:&error]).to(equal(@1)); + expect(@(success)).to(beTruthy()); + expect(error).to(beNil()); + }); + + qck_it(@"should return first default value with -firstOrDefault:success:error:", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendCompleted]; + return nil; + }]; + + expect(signal).notTo(beNil()); + + __block BOOL success = NO; + __block NSError *error = nil; + expect([signal firstOrDefault:@5 success:&success error:&error]).to(equal(@5)); + expect(@(success)).to(beTruthy()); + expect(error).to(beNil()); + }); + + qck_it(@"should return error with -firstOrDefault:success:error:", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendError:RACSignalTestError]; + return nil; + }]; + + expect(signal).notTo(beNil()); + + __block BOOL success = NO; + __block NSError *error = nil; + expect([signal firstOrDefault:@5 success:&success error:&error]).to(equal(@5)); + expect(@(success)).to(beFalsy()); + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"shouldn't crash when returning an error from a background scheduler", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [[RACScheduler scheduler] schedule:^{ + [subscriber sendError:RACSignalTestError]; + }]; + + return nil; + }]; + + expect(signal).notTo(beNil()); + + __block BOOL success = NO; + __block NSError *error = nil; + expect([signal firstOrDefault:@5 success:&success error:&error]).to(equal(@5)); + expect(@(success)).to(beFalsy()); + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"should terminate the subscription after returning from -firstOrDefault:success:error:", ^{ + __block BOOL disposed = NO; + RACSignal *signal = [RACSignal createSignal:^(id subscriber) { + [subscriber sendNext:RACUnit.defaultUnit]; + + return [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + }]; + + expect(signal).notTo(beNil()); + expect(@(disposed)).to(beFalsy()); + + expect([signal firstOrDefault:nil success:NULL error:NULL]).to(equal(RACUnit.defaultUnit)); + expect(@(disposed)).to(beTruthy()); + }); + + qck_it(@"should return YES from -waitUntilCompleted: when successful", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:RACUnit.defaultUnit]; + [subscriber sendCompleted]; + return nil; + }]; + + __block NSError *error = nil; + expect(@([signal waitUntilCompleted:&error])).to(beTruthy()); + expect(error).to(beNil()); + }); + + qck_it(@"should return NO from -waitUntilCompleted: upon error", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:RACUnit.defaultUnit]; + [subscriber sendError:RACSignalTestError]; + return nil; + }]; + + __block NSError *error = nil; + expect(@([signal waitUntilCompleted:&error])).to(beFalsy()); + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"should return a delayed value from -asynchronousFirstOrDefault:success:error:", ^{ + RACSignal *signal = [[RACSignal return:RACUnit.defaultUnit] delay:0]; + + __block BOOL scheduledBlockRan = NO; + [RACScheduler.mainThreadScheduler schedule:^{ + scheduledBlockRan = YES; + }]; + + expect(@(scheduledBlockRan)).to(beFalsy()); + + BOOL success = NO; + NSError *error = nil; + id value = [signal asynchronousFirstOrDefault:nil success:&success error:&error]; + + expect(@(scheduledBlockRan)).to(beTruthy()); + + expect(value).to(equal(RACUnit.defaultUnit)); + expect(@(success)).to(beTruthy()); + expect(error).to(beNil()); + }); + + qck_it(@"should return a default value from -asynchronousFirstOrDefault:success:error:", ^{ + RACSignal *signal = [[RACSignal error:RACSignalTestError] delay:0]; + + __block BOOL scheduledBlockRan = NO; + [RACScheduler.mainThreadScheduler schedule:^{ + scheduledBlockRan = YES; + }]; + + expect(@(scheduledBlockRan)).to(beFalsy()); + + BOOL success = NO; + NSError *error = nil; + id value = [signal asynchronousFirstOrDefault:RACUnit.defaultUnit success:&success error:&error]; + + expect(@(scheduledBlockRan)).to(beTruthy()); + + expect(value).to(equal(RACUnit.defaultUnit)); + expect(@(success)).to(beFalsy()); + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"should return a delayed error from -asynchronousFirstOrDefault:success:error:", ^{ + RACSignal *signal = [[RACSignal + createSignal:^(id subscriber) { + return [[RACScheduler scheduler] schedule:^{ + [subscriber sendError:RACSignalTestError]; + }]; + }] + deliverOn:RACScheduler.mainThreadScheduler]; + + __block NSError *error = nil; + __block BOOL success = NO; + expect([signal asynchronousFirstOrDefault:nil success:&success error:&error]).to(beNil()); + + expect(@(success)).to(beFalsy()); + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"should terminate the subscription after returning from -asynchronousFirstOrDefault:success:error:", ^{ + __block BOOL disposed = NO; + RACSignal *signal = [RACSignal createSignal:^(id subscriber) { + [[RACScheduler scheduler] schedule:^{ + [subscriber sendNext:RACUnit.defaultUnit]; + }]; + + return [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + }]; + + expect(signal).notTo(beNil()); + expect(@(disposed)).to(beFalsy()); + + expect([signal asynchronousFirstOrDefault:nil success:NULL error:NULL]).to(equal(RACUnit.defaultUnit)); + expect(@(disposed)).toEventually(beTruthy()); + }); + + qck_it(@"should return a delayed success from -asynchronouslyWaitUntilCompleted:", ^{ + RACSignal *signal = [[RACSignal return:RACUnit.defaultUnit] delay:0]; + + __block BOOL scheduledBlockRan = NO; + [RACScheduler.mainThreadScheduler schedule:^{ + scheduledBlockRan = YES; + }]; + + expect(@(scheduledBlockRan)).to(beFalsy()); + + NSError *error = nil; + BOOL success = [signal asynchronouslyWaitUntilCompleted:&error]; + + expect(@(scheduledBlockRan)).to(beTruthy()); + + expect(@(success)).to(beTruthy()); + expect(error).to(beNil()); + }); +}); + +qck_describe(@"continuation", ^{ + qck_it(@"should repeat after completion", ^{ + __block NSUInteger numberOfSubscriptions = 0; + RACScheduler *scheduler = [RACScheduler scheduler]; + + RACSignal *signal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + return [scheduler schedule:^{ + if (numberOfSubscriptions == 3) { + [subscriber sendError:RACSignalTestError]; + return; + } + + numberOfSubscriptions++; + + [subscriber sendNext:@"1"]; + [subscriber sendCompleted]; + [subscriber sendError:RACSignalTestError]; + }]; + }]; + + __block NSUInteger nextCount = 0; + __block BOOL gotCompleted = NO; + [[signal repeat] subscribeNext:^(id x) { + nextCount++; + } error:^(NSError *error) { + + } completed:^{ + gotCompleted = YES; + }]; + + expect(@(nextCount)).toEventually(equal(@3)); + expect(@(gotCompleted)).to(beFalsy()); + }); + + qck_it(@"should stop repeating when disposed", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendCompleted]; + return nil; + }]; + + NSMutableArray *values = [NSMutableArray array]; + + __block BOOL completed = NO; + __block RACDisposable *disposable = [[signal repeat] subscribeNext:^(id x) { + [values addObject:x]; + [disposable dispose]; + } completed:^{ + completed = YES; + }]; + + expect(values).toEventually(equal(@[ @1 ])); + expect(@(completed)).to(beFalsy()); + }); + + qck_it(@"should stop repeating when disposed by -take:", ^{ + RACSignal *signal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendCompleted]; + return nil; + }]; + + NSMutableArray *values = [NSMutableArray array]; + + __block BOOL completed = NO; + [[[signal repeat] take:1] subscribeNext:^(id x) { + [values addObject:x]; + } completed:^{ + completed = YES; + }]; + + expect(values).toEventually(equal(@[ @1 ])); + expect(@(completed)).to(beTruthy()); + }); +}); + +qck_describe(@"+combineLatestWith:", ^{ + __block RACSubject *subject1 = nil; + __block RACSubject *subject2 = nil; + __block RACSignal *combined = nil; + + qck_beforeEach(^{ + subject1 = [RACSubject subject]; + subject2 = [RACSubject subject]; + combined = [RACSignal combineLatest:@[ subject1, subject2 ]]; + }); + + qck_it(@"should send next only once both signals send next", ^{ + __block RACTuple *tuple; + + [combined subscribeNext:^(id x) { + tuple = x; + }]; + + expect(tuple).to(beNil()); + + [subject1 sendNext:@"1"]; + expect(tuple).to(beNil()); + + [subject2 sendNext:@"2"]; + expect(tuple).to(equal(RACTuplePack(@"1", @"2"))); + }); + + qck_it(@"should send nexts when either signal sends multiple times", ^{ + NSMutableArray *results = [NSMutableArray array]; + [combined subscribeNext:^(id x) { + [results addObject:x]; + }]; + + [subject1 sendNext:@"1"]; + [subject2 sendNext:@"2"]; + + [subject1 sendNext:@"3"]; + [subject2 sendNext:@"4"]; + + expect(results[0]).to(equal(RACTuplePack(@"1", @"2"))); + expect(results[1]).to(equal(RACTuplePack(@"3", @"2"))); + expect(results[2]).to(equal(RACTuplePack(@"3", @"4"))); + }); + + qck_it(@"should complete when only both signals complete", ^{ + __block BOOL completed = NO; + + [combined subscribeCompleted:^{ + completed = YES; + }]; + + expect(@(completed)).to(beFalsy()); + + [subject1 sendCompleted]; + expect(@(completed)).to(beFalsy()); + + [subject2 sendCompleted]; + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should error when either signal errors", ^{ + __block NSError *receivedError = nil; + [combined subscribeError:^(NSError *error) { + receivedError = error; + }]; + + [subject1 sendError:RACSignalTestError]; + expect(receivedError).to(equal(RACSignalTestError)); + }); + + qck_it(@"shouldn't create a retain cycle", ^{ + __block BOOL subjectDeallocd = NO; + __block BOOL signalDeallocd = NO; + + @autoreleasepool { + RACSubject *subject __attribute__((objc_precise_lifetime)) = [RACSubject subject]; + [subject.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + subjectDeallocd = YES; + }]]; + + RACSignal *signal __attribute__((objc_precise_lifetime)) = [RACSignal combineLatest:@[ subject ]]; + [signal.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + signalDeallocd = YES; + }]]; + + [signal subscribeCompleted:^{}]; + [subject sendCompleted]; + } + + expect(@(subjectDeallocd)).toEventually(beTruthy()); + expect(@(signalDeallocd)).toEventually(beTruthy()); + }); + + qck_it(@"should combine the same signal", ^{ + RACSignal *combined = [subject1 combineLatestWith:subject1]; + + __block RACTuple *tuple; + [combined subscribeNext:^(id x) { + tuple = x; + }]; + + [subject1 sendNext:@"foo"]; + expect(tuple).to(equal(RACTuplePack(@"foo", @"foo"))); + + [subject1 sendNext:@"bar"]; + expect(tuple).to(equal(RACTuplePack(@"bar", @"bar"))); + }); + + qck_it(@"should combine the same side-effecting signal", ^{ + __block NSUInteger counter = 0; + RACSignal *sideEffectingSignal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@(++counter)]; + [subscriber sendCompleted]; + return nil; + }]; + + RACSignal *combined = [sideEffectingSignal combineLatestWith:sideEffectingSignal]; + expect(@(counter)).to(equal(@0)); + + NSMutableArray *receivedValues = [NSMutableArray array]; + [combined subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + expect(@(counter)).to(equal(@2)); + + NSArray *expected = @[ RACTuplePack(@1, @2) ]; + expect(receivedValues).to(equal(expected)); + }); +}); + +qck_describe(@"+combineLatest:", ^{ + qck_it(@"should return tuples even when only combining one signal", ^{ + RACSubject *subject = [RACSubject subject]; + + __block RACTuple *tuple; + [[RACSignal combineLatest:@[ subject ]] subscribeNext:^(id x) { + tuple = x; + }]; + + [subject sendNext:@"foo"]; + expect(tuple).to(equal(RACTuplePack(@"foo"))); + }); + + qck_it(@"should complete immediately when not given any signals", ^{ + RACSignal *signal = [RACSignal combineLatest:@[]]; + + __block BOOL completed = NO; + [signal subscribeCompleted:^{ + completed = YES; + }]; + + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should only complete after all its signals complete", ^{ + RACSubject *subject1 = [RACSubject subject]; + RACSubject *subject2 = [RACSubject subject]; + RACSubject *subject3 = [RACSubject subject]; + RACSignal *combined = [RACSignal combineLatest:@[ subject1, subject2, subject3 ]]; + + __block BOOL completed = NO; + [combined subscribeCompleted:^{ + completed = YES; + }]; + + expect(@(completed)).to(beFalsy()); + + [subject1 sendCompleted]; + expect(@(completed)).to(beFalsy()); + + [subject2 sendCompleted]; + expect(@(completed)).to(beFalsy()); + + [subject3 sendCompleted]; + expect(@(completed)).to(beTruthy()); + }); +}); + +qck_describe(@"+combineLatest:reduce:", ^{ + __block RACSubject *subject1; + __block RACSubject *subject2; + __block RACSubject *subject3; + + qck_beforeEach(^{ + subject1 = [RACSubject subject]; + subject2 = [RACSubject subject]; + subject3 = [RACSubject subject]; + }); + + qck_it(@"should send nils for nil values", ^{ + __block id receivedVal1; + __block id receivedVal2; + __block id receivedVal3; + + RACSignal *combined = [RACSignal combineLatest:@[ subject1, subject2, subject3 ] reduce:^ id (id val1, id val2, id val3) { + receivedVal1 = val1; + receivedVal2 = val2; + receivedVal3 = val3; + return nil; + }]; + + __block BOOL gotValue = NO; + [combined subscribeNext:^(id x) { + gotValue = YES; + }]; + + [subject1 sendNext:nil]; + [subject2 sendNext:nil]; + [subject3 sendNext:nil]; + + expect(@(gotValue)).to(beTruthy()); + expect(receivedVal1).to(beNil()); + expect(receivedVal2).to(beNil()); + expect(receivedVal3).to(beNil()); + }); + + qck_it(@"should send the return result of the reduce block", ^{ + RACSignal *combined = [RACSignal combineLatest:@[ subject1, subject2, subject3 ] reduce:^(NSString *string1, NSString *string2, NSString *string3) { + return [NSString stringWithFormat:@"%@: %@%@", string1, string2, string3]; + }]; + + __block id received; + [combined subscribeNext:^(id x) { + received = x; + }]; + + [subject1 sendNext:@"hello"]; + [subject2 sendNext:@"world"]; + [subject3 sendNext:@"!!1"]; + + expect(received).to(equal(@"hello: world!!1")); + }); + + qck_it(@"should handle multiples of the same signals", ^{ + RACSignal *combined = [RACSignal combineLatest:@[ subject1, subject2, subject1, subject3 ] reduce:^(NSString *string1, NSString *string2, NSString *string3, NSString *string4) { + return [NSString stringWithFormat:@"%@ : %@ = %@ : %@", string1, string2, string3, string4]; + }]; + + NSMutableArray *receivedValues = NSMutableArray.array; + + [combined subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + [subject1 sendNext:@"apples"]; + expect(receivedValues.lastObject).to(beNil()); + + [subject2 sendNext:@"oranges"]; + expect(receivedValues.lastObject).to(beNil()); + + [subject3 sendNext:@"cattle"]; + expect(receivedValues.lastObject).to(equal(@"apples : oranges = apples : cattle")); + + [subject1 sendNext:@"horses"]; + expect(receivedValues.lastObject).to(equal(@"horses : oranges = horses : cattle")); + }); + + qck_it(@"should handle multiples of the same side-effecting signal", ^{ + __block NSUInteger counter = 0; + RACSignal *sideEffectingSignal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:@(++counter)]; + [subscriber sendCompleted]; + return nil; + }]; + + RACSignal *combined = [RACSignal combineLatest:@[ sideEffectingSignal, sideEffectingSignal, sideEffectingSignal ] reduce:^(id x, id y, id z) { + return [NSString stringWithFormat:@"%@%@%@", x, y, z]; + }]; + + NSMutableArray *receivedValues = [NSMutableArray array]; + expect(@(counter)).to(equal(@0)); + + [combined subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + expect(@(counter)).to(equal(@3)); + expect(receivedValues).to(equal(@[ @"123" ])); + }); +}); + +qck_describe(@"distinctUntilChanged", ^{ + qck_it(@"should only send values that are distinct from the previous value", ^{ + RACSignal *sub = [[RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendNext:@2]; + [subscriber sendNext:@2]; + [subscriber sendNext:@1]; + [subscriber sendNext:@1]; + [subscriber sendCompleted]; + return nil; + }] distinctUntilChanged]; + + NSArray *values = sub.toArray; + NSArray *expected = @[ @1, @2, @1 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"shouldn't consider nils to always be distinct", ^{ + RACSignal *sub = [[RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendNext:nil]; + [subscriber sendNext:nil]; + [subscriber sendNext:nil]; + [subscriber sendNext:@1]; + [subscriber sendCompleted]; + return nil; + }] distinctUntilChanged]; + + NSArray *values = sub.toArray; + NSArray *expected = @[ @1, [NSNull null], @1 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should consider initial nil to be distinct", ^{ + RACSignal *sub = [[RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:nil]; + [subscriber sendNext:nil]; + [subscriber sendNext:@1]; + [subscriber sendCompleted]; + return nil; + }] distinctUntilChanged]; + + NSArray *values = sub.toArray; + NSArray *expected = @[ [NSNull null], @1 ]; + expect(values).to(equal(expected)); + }); +}); + +qck_describe(@"RACObserve", ^{ + __block RACTestObject *testObject; + + qck_beforeEach(^{ + testObject = [[RACTestObject alloc] init]; + }); + + qck_it(@"should work with object properties", ^{ + NSArray *expected = @[ @"hello", @"world" ]; + testObject.objectValue = expected[0]; + + NSMutableArray *valuesReceived = [NSMutableArray array]; + [RACObserve(testObject, objectValue) subscribeNext:^(id x) { + [valuesReceived addObject:x]; + }]; + + testObject.objectValue = expected[1]; + + expect(valuesReceived).to(equal(expected)); + }); + + qck_it(@"should work with non-object properties", ^{ + NSArray *expected = @[ @42, @43 ]; + testObject.integerValue = [expected[0] integerValue]; + + NSMutableArray *valuesReceived = [NSMutableArray array]; + [RACObserve(testObject, integerValue) subscribeNext:^(id x) { + [valuesReceived addObject:x]; + }]; + + testObject.integerValue = [expected[1] integerValue]; + + expect(valuesReceived).to(equal(expected)); + }); + + qck_it(@"should read the initial value upon subscription", ^{ + testObject.objectValue = @"foo"; + + RACSignal *signal = RACObserve(testObject, objectValue); + testObject.objectValue = @"bar"; + + expect([signal first]).to(equal(@"bar")); + }); +}); + +qck_describe(@"-setKeyPath:onObject:", ^{ + id setupBlock = ^(RACTestObject *testObject, NSString *keyPath, id nilValue, RACSignal *signal) { + [signal setKeyPath:keyPath onObject:testObject nilValue:nilValue]; + }; + + qck_itBehavesLike(RACPropertySignalExamples, ^{ + return @{ RACPropertySignalExamplesSetupBlock: setupBlock }; + }); + + qck_it(@"shouldn't send values to dealloc'd objects", ^{ + RACSubject *subject = [RACSubject subject]; + @autoreleasepool { + RACTestObject *testObject __attribute__((objc_precise_lifetime)) = [[RACTestObject alloc] init]; + [subject setKeyPath:@keypath(testObject.objectValue) onObject:testObject]; + expect(testObject.objectValue).to(beNil()); + + [subject sendNext:@1]; + expect(testObject.objectValue).to(equal(@1)); + + [subject sendNext:@2]; + expect(testObject.objectValue).to(equal(@2)); + } + + // This shouldn't do anything. + [subject sendNext:@3]; + }); + + qck_it(@"should allow a new derivation after the signal's completed", ^{ + RACSubject *subject1 = [RACSubject subject]; + RACTestObject *testObject = [[RACTestObject alloc] init]; + [subject1 setKeyPath:@keypath(testObject.objectValue) onObject:testObject]; + [subject1 sendCompleted]; + + RACSubject *subject2 = [RACSubject subject]; + // This will assert if the previous completion didn't dispose of the + // subscription. + [subject2 setKeyPath:@keypath(testObject.objectValue) onObject:testObject]; + }); + + qck_it(@"should set the given value when nil is received", ^{ + RACSubject *subject = [RACSubject subject]; + RACTestObject *testObject = [[RACTestObject alloc] init]; + [subject setKeyPath:@keypath(testObject.integerValue) onObject:testObject nilValue:@5]; + + [subject sendNext:@1]; + expect(@(testObject.integerValue)).to(equal(@1)); + + [subject sendNext:nil]; + expect(@(testObject.integerValue)).to(equal(@5)); + + [subject sendCompleted]; + expect(@(testObject.integerValue)).to(equal(@5)); + }); + + qck_it(@"should keep object alive over -sendNext:", ^{ + RACSubject *subject = [RACSubject subject]; + __block RACTestObject *testObject = [[RACTestObject alloc] init]; + __block id deallocValue; + + __unsafe_unretained RACTestObject *unsafeTestObject = testObject; + [testObject.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocValue = unsafeTestObject.slowObjectValue; + }]]; + + [subject setKeyPath:@keypath(testObject.slowObjectValue) onObject:testObject]; + expect(testObject.slowObjectValue).to(beNil()); + + // Attempt to deallocate concurrently. + [[RACScheduler scheduler] afterDelay:0.01 schedule:^{ + testObject = nil; + }]; + + expect(deallocValue).to(beNil()); + [subject sendNext:@1]; + expect(deallocValue).to(equal(@1)); + }); +}); + +qck_describe(@"memory management", ^{ + qck_it(@"should dealloc signals if the signal does nothing", ^{ + __block BOOL deallocd = NO; + @autoreleasepool { + RACSignal *signal __attribute__((objc_precise_lifetime)) = [RACSignal createSignal:^ id (id subscriber) { + return nil; + }]; + + [signal.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocd = YES; + }]]; + } + + expect(@(deallocd)).toEventually(beTruthy()); + }); + + qck_it(@"should dealloc signals if the signal immediately completes", ^{ + __block BOOL deallocd = NO; + @autoreleasepool { + __block BOOL done = NO; + + RACSignal *signal __attribute__((objc_precise_lifetime)) = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendCompleted]; + return nil; + }]; + + [signal.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocd = YES; + }]]; + + [signal subscribeCompleted:^{ + done = YES; + }]; + + expect(@(done)).toEventually(beTruthy()); + } + + expect(@(deallocd)).toEventually(beTruthy()); + }); + + qck_it(@"should dealloc a replay subject if it completes immediately", ^{ + __block BOOL completed = NO; + __block BOOL deallocd = NO; + @autoreleasepool { + RACReplaySubject *subject __attribute__((objc_precise_lifetime)) = [RACReplaySubject subject]; + [subject sendCompleted]; + + [subject.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocd = YES; + }]]; + + [subject subscribeCompleted:^{ + completed = YES; + }]; + } + + expect(@(completed)).toEventually(beTruthy()); + expect(@(deallocd)).toEventually(beTruthy()); + }); + + qck_it(@"should dealloc if the signal was created on a background queue", ^{ + __block BOOL completed = NO; + __block BOOL deallocd = NO; + @autoreleasepool { + [[RACScheduler scheduler] schedule:^{ + RACSignal *signal __attribute__((objc_precise_lifetime)) = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendCompleted]; + return nil; + }]; + + [signal.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocd = YES; + }]]; + + [signal subscribeCompleted:^{ + completed = YES; + }]; + }]; + } + + expect(@(completed)).toEventually(beTruthy()); + expect(@(deallocd)).toEventually(beTruthy()); + }); + + qck_it(@"should dealloc if the signal was created on a background queue, never gets any subscribers, and the background queue gets delayed", ^{ + __block BOOL deallocd = NO; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + + @autoreleasepool { + [[RACScheduler scheduler] schedule:^{ + RACSignal *signal __attribute__((objc_precise_lifetime)) = [RACSignal createSignal:^ id (id subscriber) { + return nil; + }]; + + [signal.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + deallocd = YES; + dispatch_semaphore_signal(semaphore); + }]]; + + [NSThread sleepForTimeInterval:1]; + + expect(@(deallocd)).to(beFalsy()); + }]; + } + + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + expect(@(deallocd)).to(beTruthy()); + }); + + qck_it(@"should retain intermediate signals when subscribing", ^{ + RACSubject *subject = [RACSubject subject]; + expect(subject).notTo(beNil()); + + __block BOOL gotNext = NO; + __block BOOL completed = NO; + + RACDisposable *disposable; + + @autoreleasepool { + RACSignal *intermediateSignal = [subject doNext:^(id _) { + gotNext = YES; + }]; + + expect(intermediateSignal).notTo(beNil()); + + disposable = [intermediateSignal subscribeCompleted:^{ + completed = YES; + }]; + } + + [subject sendNext:@5]; + expect(@(gotNext)).to(beTruthy()); + + [subject sendCompleted]; + expect(@(completed)).to(beTruthy()); + + [disposable dispose]; + }); +}); + +qck_describe(@"-merge:", ^{ + __block RACSubject *sub1; + __block RACSubject *sub2; + __block RACSignal *merged; + qck_beforeEach(^{ + sub1 = [RACSubject subject]; + sub2 = [RACSubject subject]; + merged = [sub1 merge:sub2]; + }); + + qck_it(@"should send all values from both signals", ^{ + NSMutableArray *values = [NSMutableArray array]; + [merged subscribeNext:^(id x) { + [values addObject:x]; + }]; + + [sub1 sendNext:@1]; + [sub2 sendNext:@2]; + [sub2 sendNext:@3]; + [sub1 sendNext:@4]; + + NSArray *expected = @[ @1, @2, @3, @4 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should send an error if one occurs", ^{ + __block NSError *errorReceived; + [merged subscribeError:^(NSError *error) { + errorReceived = error; + }]; + + [sub1 sendError:RACSignalTestError]; + expect(errorReceived).to(equal(RACSignalTestError)); + }); + + qck_it(@"should complete only after both signals complete", ^{ + NSMutableArray *values = [NSMutableArray array]; + __block BOOL completed = NO; + [merged subscribeNext:^(id x) { + [values addObject:x]; + } completed:^{ + completed = YES; + }]; + + [sub1 sendNext:@1]; + [sub2 sendNext:@2]; + [sub2 sendNext:@3]; + [sub2 sendCompleted]; + expect(@(completed)).to(beFalsy()); + + [sub1 sendNext:@4]; + [sub1 sendCompleted]; + expect(@(completed)).to(beTruthy()); + + NSArray *expected = @[ @1, @2, @3, @4 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should complete only after both signals complete for any number of subscribers", ^{ + __block BOOL completed1 = NO; + __block BOOL completed2 = NO; + [merged subscribeCompleted:^{ + completed1 = YES; + }]; + + [merged subscribeCompleted:^{ + completed2 = YES; + }]; + + expect(@(completed1)).to(beFalsy()); + expect(@(completed2)).to(beFalsy()); + + [sub1 sendCompleted]; + [sub2 sendCompleted]; + expect(@(completed1)).to(beTruthy()); + expect(@(completed2)).to(beTruthy()); + }); +}); + +qck_describe(@"+merge:", ^{ + __block RACSubject *sub1; + __block RACSubject *sub2; + __block RACSignal *merged; + qck_beforeEach(^{ + sub1 = [RACSubject subject]; + sub2 = [RACSubject subject]; + merged = [RACSignal merge:@[ sub1, sub2 ].objectEnumerator]; + }); + + qck_it(@"should send all values from both signals", ^{ + NSMutableArray *values = [NSMutableArray array]; + [merged subscribeNext:^(id x) { + [values addObject:x]; + }]; + + [sub1 sendNext:@1]; + [sub2 sendNext:@2]; + [sub2 sendNext:@3]; + [sub1 sendNext:@4]; + + NSArray *expected = @[ @1, @2, @3, @4 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should send an error if one occurs", ^{ + __block NSError *errorReceived; + [merged subscribeError:^(NSError *error) { + errorReceived = error; + }]; + + [sub1 sendError:RACSignalTestError]; + expect(errorReceived).to(equal(RACSignalTestError)); + }); + + qck_it(@"should complete only after both signals complete", ^{ + NSMutableArray *values = [NSMutableArray array]; + __block BOOL completed = NO; + [merged subscribeNext:^(id x) { + [values addObject:x]; + } completed:^{ + completed = YES; + }]; + + [sub1 sendNext:@1]; + [sub2 sendNext:@2]; + [sub2 sendNext:@3]; + [sub2 sendCompleted]; + expect(@(completed)).to(beFalsy()); + + [sub1 sendNext:@4]; + [sub1 sendCompleted]; + expect(@(completed)).to(beTruthy()); + + NSArray *expected = @[ @1, @2, @3, @4 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should complete immediately when not given any signals", ^{ + RACSignal *signal = [RACSignal merge:@[].objectEnumerator]; + + __block BOOL completed = NO; + [signal subscribeCompleted:^{ + completed = YES; + }]; + + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should complete only after both signals complete for any number of subscribers", ^{ + __block BOOL completed1 = NO; + __block BOOL completed2 = NO; + [merged subscribeCompleted:^{ + completed1 = YES; + }]; + + [merged subscribeCompleted:^{ + completed2 = YES; + }]; + + expect(@(completed1)).to(beFalsy()); + expect(@(completed2)).to(beFalsy()); + + [sub1 sendCompleted]; + [sub2 sendCompleted]; + expect(@(completed1)).to(beTruthy()); + expect(@(completed2)).to(beTruthy()); + }); +}); + +qck_describe(@"-flatten:", ^{ + __block BOOL subscribedTo1 = NO; + __block BOOL subscribedTo2 = NO; + __block BOOL subscribedTo3 = NO; + __block RACSignal *sub1; + __block RACSignal *sub2; + __block RACSignal *sub3; + __block RACSubject *subject1; + __block RACSubject *subject2; + __block RACSubject *subject3; + __block RACSubject *signalsSubject; + __block NSMutableArray *values; + + qck_beforeEach(^{ + subscribedTo1 = NO; + subject1 = [RACSubject subject]; + sub1 = [RACSignal defer:^{ + subscribedTo1 = YES; + return subject1; + }]; + + subscribedTo2 = NO; + subject2 = [RACSubject subject]; + sub2 = [RACSignal defer:^{ + subscribedTo2 = YES; + return subject2; + }]; + + subscribedTo3 = NO; + subject3 = [RACSubject subject]; + sub3 = [RACSignal defer:^{ + subscribedTo3 = YES; + return subject3; + }]; + + signalsSubject = [RACSubject subject]; + + values = [NSMutableArray array]; + }); + + qck_describe(@"when its max is 0", ^{ + qck_it(@"should merge all the signals concurrently", ^{ + [[signalsSubject flatten:0] subscribeNext:^(id x) { + [values addObject:x]; + }]; + + expect(@(subscribedTo1)).to(beFalsy()); + expect(@(subscribedTo2)).to(beFalsy()); + expect(@(subscribedTo3)).to(beFalsy()); + + [signalsSubject sendNext:sub1]; + [signalsSubject sendNext:sub2]; + + expect(@(subscribedTo1)).to(beTruthy()); + expect(@(subscribedTo2)).to(beTruthy()); + expect(@(subscribedTo3)).to(beFalsy()); + + [subject1 sendNext:@1]; + + [signalsSubject sendNext:sub3]; + + expect(@(subscribedTo1)).to(beTruthy()); + expect(@(subscribedTo2)).to(beTruthy()); + expect(@(subscribedTo3)).to(beTruthy()); + + [subject1 sendCompleted]; + + [subject2 sendNext:@2]; + [subject2 sendCompleted]; + + [subject3 sendNext:@3]; + [subject3 sendCompleted]; + + NSArray *expected = @[ @1, @2, @3 ]; + expect(values).to(equal(expected)); + }); + + qck_itBehavesLike(RACSignalMergeConcurrentCompletionExampleGroup, ^{ + return @{ RACSignalMaxConcurrent: @0 }; + }); + }); + + qck_describe(@"when its max is > 0", ^{ + qck_it(@"should merge only the given number at a time", ^{ + [[signalsSubject flatten:1] subscribeNext:^(id x) { + [values addObject:x]; + }]; + + expect(@(subscribedTo1)).to(beFalsy()); + expect(@(subscribedTo2)).to(beFalsy()); + expect(@(subscribedTo3)).to(beFalsy()); + + [signalsSubject sendNext:sub1]; + [signalsSubject sendNext:sub2]; + + expect(@(subscribedTo1)).to(beTruthy()); + expect(@(subscribedTo2)).to(beFalsy()); + expect(@(subscribedTo3)).to(beFalsy()); + + [subject1 sendNext:@1]; + + [signalsSubject sendNext:sub3]; + + expect(@(subscribedTo1)).to(beTruthy()); + expect(@(subscribedTo2)).to(beFalsy()); + expect(@(subscribedTo3)).to(beFalsy()); + + [signalsSubject sendCompleted]; + + expect(@(subscribedTo1)).to(beTruthy()); + expect(@(subscribedTo2)).to(beFalsy()); + expect(@(subscribedTo3)).to(beFalsy()); + + [subject1 sendCompleted]; + + expect(@(subscribedTo2)).to(beTruthy()); + expect(@(subscribedTo3)).to(beFalsy()); + + [subject2 sendNext:@2]; + [subject2 sendCompleted]; + + expect(@(subscribedTo3)).to(beTruthy()); + + [subject3 sendNext:@3]; + [subject3 sendCompleted]; + + NSArray *expected = @[ @1, @2, @3 ]; + expect(values).to(equal(expected)); + }); + + qck_itBehavesLike(RACSignalMergeConcurrentCompletionExampleGroup, ^{ + return @{ RACSignalMaxConcurrent: @1 }; + }); + }); + + qck_it(@"shouldn't create a retain cycle", ^{ + __block BOOL subjectDeallocd = NO; + __block BOOL signalDeallocd = NO; + @autoreleasepool { + RACSubject *subject __attribute__((objc_precise_lifetime)) = [RACSubject subject]; + [subject.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + subjectDeallocd = YES; + }]]; + + RACSignal *signal __attribute__((objc_precise_lifetime)) = [subject flatten]; + [signal.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + signalDeallocd = YES; + }]]; + + [signal subscribeCompleted:^{}]; + + [subject sendCompleted]; + } + + expect(@(subjectDeallocd)).toEventually(beTruthy()); + expect(@(signalDeallocd)).toEventually(beTruthy()); + }); + + qck_it(@"should not crash when disposing while subscribing", ^{ + RACDisposable *disposable = [[signalsSubject flatten:0] subscribeCompleted:^{ + }]; + + [signalsSubject sendNext:[RACSignal createSignal:^ RACDisposable * (id subscriber) { + [disposable dispose]; + [subscriber sendCompleted]; + return nil; + }]]; + + [signalsSubject sendCompleted]; + }); + + qck_it(@"should dispose after last synchronous signal subscription and should not crash", ^{ + + RACSignal *flattened = [signalsSubject flatten:1]; + RACDisposable *flattenDisposable = [flattened subscribeCompleted:^{}]; + + RACSignal *syncSignal = [RACSignal createSignal:^ RACDisposable *(id subscriber) { + expect(@(flattenDisposable.disposed)).to(beFalsy()); + [subscriber sendCompleted]; + expect(@(flattenDisposable.disposed)).to(beTruthy()); + return nil; + }]; + + RACSignal *asyncSignal = [sub1 delay:0]; + + [signalsSubject sendNext:asyncSignal]; + [signalsSubject sendNext:syncSignal]; + + [signalsSubject sendCompleted]; + + [subject1 sendCompleted]; + + expect(@(flattenDisposable.disposed)).toEventually(beTruthy()); + }); + + qck_it(@"should not crash when disposed because of takeUntil:", ^{ + for (int i = 0; i < 100; i++) { + RACSubject *flattenedReceiver = [RACSubject subject]; + RACSignal *done = [flattenedReceiver map:^(NSNumber *n) { + return @(n.integerValue == 1); + }]; + + RACSignal *flattened = [signalsSubject flatten:1]; + + RACDisposable *flattenDisposable = [[flattened takeUntil:[done ignore:@NO]] subscribe:flattenedReceiver]; + + RACSignal *syncSignal = [RACSignal createSignal:^ RACDisposable *(id subscriber) { + expect(@(flattenDisposable.disposed)).to(beFalsy()); + [subscriber sendNext:@1]; + expect(@(flattenDisposable.disposed)).to(beTruthy()); + [subscriber sendCompleted]; + return nil; + }]; + + RACSignal *asyncSignal = [sub1 delay:0]; + [subject1 sendNext:@0]; + + [signalsSubject sendNext:asyncSignal]; + [signalsSubject sendNext:syncSignal]; + [signalsSubject sendCompleted]; + + [subject1 sendCompleted]; + + expect(@(flattenDisposable.disposed)).toEventually(beTruthy()); + } + }); +}); + +qck_describe(@"-switchToLatest", ^{ + __block RACSubject *subject; + + __block NSMutableArray *values; + __block NSError *lastError = nil; + __block BOOL completed = NO; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + + values = [NSMutableArray array]; + lastError = nil; + completed = NO; + + [[subject switchToLatest] subscribeNext:^(id x) { + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + [values addObject:x]; + } error:^(NSError *error) { + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + lastError = error; + } completed:^{ + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + completed = YES; + }]; + }); + + qck_it(@"should send values from the most recent signal", ^{ + [subject sendNext:[RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendNext:@2]; + return nil; + }]]; + + [subject sendNext:[RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@3]; + [subscriber sendNext:@4]; + return nil; + }]]; + + NSArray *expected = @[ @1, @2, @3, @4 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should send errors from the most recent signal", ^{ + [subject sendNext:[RACSignal createSignal:^ id (id subscriber) { + [subscriber sendError:[NSError errorWithDomain:@"" code:-1 userInfo:nil]]; + return nil; + }]]; + + expect(lastError).notTo(beNil()); + }); + + qck_it(@"should not send completed if only the switching signal completes", ^{ + [subject sendNext:RACSignal.never]; + + expect(@(completed)).to(beFalsy()); + + [subject sendCompleted]; + expect(@(completed)).to(beFalsy()); + }); + + qck_it(@"should send completed when the switching signal completes and the last sent signal does", ^{ + [subject sendNext:RACSignal.empty]; + + expect(@(completed)).to(beFalsy()); + + [subject sendCompleted]; + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should accept nil signals", ^{ + [subject sendNext:nil]; + [subject sendNext:[RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendNext:@2]; + return nil; + }]]; + + NSArray *expected = @[ @1, @2 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should return a cold signal", ^{ + __block NSUInteger subscriptions = 0; + RACSignal *signalOfSignals = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + subscriptions++; + [subscriber sendNext:[RACSignal empty]]; + return nil; + }]; + + RACSignal *switched = [signalOfSignals switchToLatest]; + + [[switched publish] connect]; + expect(@(subscriptions)).to(equal(@1)); + + [[switched publish] connect]; + expect(@(subscriptions)).to(equal(@2)); + }); +}); + +qck_describe(@"+switch:cases:default:", ^{ + __block RACSubject *keySubject; + + __block RACSubject *subjectZero; + __block RACSubject *subjectOne; + __block RACSubject *subjectTwo; + + __block RACSubject *defaultSubject; + + __block NSMutableArray *values; + __block NSError *lastError = nil; + __block BOOL completed = NO; + + qck_beforeEach(^{ + keySubject = [RACSubject subject]; + + subjectZero = [RACSubject subject]; + subjectOne = [RACSubject subject]; + subjectTwo = [RACSubject subject]; + + defaultSubject = [RACSubject subject]; + + values = [NSMutableArray array]; + lastError = nil; + completed = NO; + }); + + qck_describe(@"switching between values with a default", ^{ + __block RACSignal *switchSignal; + + qck_beforeEach(^{ + switchSignal = [RACSignal switch:keySubject cases:@{ + @0: subjectZero, + @1: subjectOne, + @2: subjectTwo, + } default:[RACSignal never]]; + + [switchSignal subscribeNext:^(id x) { + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + [values addObject:x]; + } error:^(NSError *error) { + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + lastError = error; + } completed:^{ + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + completed = YES; + }]; + }); + + qck_it(@"should not send any values before a key is sent", ^{ + [subjectZero sendNext:RACUnit.defaultUnit]; + [subjectOne sendNext:RACUnit.defaultUnit]; + [subjectTwo sendNext:RACUnit.defaultUnit]; + + expect(values).to(equal(@[])); + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + }); + + qck_it(@"should send events based on the latest key", ^{ + [keySubject sendNext:@0]; + + [subjectZero sendNext:@"zero"]; + [subjectZero sendNext:@"zero"]; + [subjectOne sendNext:@"one"]; + [subjectTwo sendNext:@"two"]; + + NSArray *expected = @[ @"zero", @"zero" ]; + expect(values).to(equal(expected)); + + [keySubject sendNext:@1]; + + [subjectZero sendNext:@"zero"]; + [subjectOne sendNext:@"one"]; + [subjectTwo sendNext:@"two"]; + + expected = @[ @"zero", @"zero", @"one" ]; + expect(values).to(equal(expected)); + + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + [keySubject sendNext:@2]; + + [subjectZero sendError:[NSError errorWithDomain:@"" code:-1 userInfo:nil]]; + [subjectOne sendError:[NSError errorWithDomain:@"" code:-1 userInfo:nil]]; + expect(lastError).to(beNil()); + + [subjectTwo sendError:[NSError errorWithDomain:@"" code:-1 userInfo:nil]]; + expect(lastError).notTo(beNil()); + }); + + qck_it(@"should not send completed when only the key signal completes", ^{ + [keySubject sendNext:@0]; + [subjectZero sendNext:@"zero"]; + [keySubject sendCompleted]; + + expect(values).to(equal(@[ @"zero" ])); + expect(@(completed)).to(beFalsy()); + }); + + qck_it(@"should send completed when the key signal and the latest sent signal complete", ^{ + [keySubject sendNext:@0]; + [subjectZero sendNext:@"zero"]; + [keySubject sendCompleted]; + [subjectZero sendCompleted]; + + expect(values).to(equal(@[ @"zero" ])); + expect(@(completed)).to(beTruthy()); + }); + }); + + qck_it(@"should use the default signal if key that was sent does not have an associated signal", ^{ + [[RACSignal + switch:keySubject + cases:@{ + @0: subjectZero, + @1: subjectOne, + } + default:defaultSubject] + subscribeNext:^(id x) { + [values addObject:x]; + }]; + + [keySubject sendNext:@"not a valid key"]; + [defaultSubject sendNext:@"default"]; + + expect(values).to(equal(@[ @"default" ])); + + [keySubject sendNext:nil]; + [defaultSubject sendNext:@"default"]; + + expect(values).to(equal((@[ @"default", @"default" ]))); + }); + + qck_it(@"should send an error if key that was sent does not have an associated signal and there's no default", ^{ + [[RACSignal + switch:keySubject + cases:@{ + @0: subjectZero, + @1: subjectOne, + } + default:nil] + subscribeNext:^(id x) { + [values addObject:x]; + } error:^(NSError *error) { + lastError = error; + }]; + + [keySubject sendNext:@0]; + [subjectZero sendNext:@"zero"]; + + expect(values).to(equal(@[ @"zero" ])); + expect(lastError).to(beNil()); + + [keySubject sendNext:nil]; + + expect(values).to(equal(@[ @"zero" ])); + expect(lastError).notTo(beNil()); + expect(lastError.domain).to(equal(RACSignalErrorDomain)); + expect(@(lastError.code)).to(equal(@(RACSignalErrorNoMatchingCase))); + }); + + qck_it(@"should match RACTupleNil case when a nil value is sent", ^{ + [[RACSignal + switch:keySubject + cases:@{ + RACTupleNil.tupleNil: subjectZero, + } + default:defaultSubject] + subscribeNext:^(id x) { + [values addObject:x]; + }]; + + [keySubject sendNext:nil]; + [subjectZero sendNext:@"zero"]; + expect(values).to(equal(@[ @"zero" ])); + }); +}); + +qck_describe(@"+if:then:else", ^{ + __block RACSubject *boolSubject; + __block RACSubject *trueSubject; + __block RACSubject *falseSubject; + + __block NSMutableArray *values; + __block NSError *lastError = nil; + __block BOOL completed = NO; + + qck_beforeEach(^{ + boolSubject = [RACSubject subject]; + trueSubject = [RACSubject subject]; + falseSubject = [RACSubject subject]; + + values = [NSMutableArray array]; + lastError = nil; + completed = NO; + + [[RACSignal if:boolSubject then:trueSubject else:falseSubject] subscribeNext:^(id x) { + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + [values addObject:x]; + } error:^(NSError *error) { + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + lastError = error; + } completed:^{ + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + completed = YES; + }]; + }); + + qck_it(@"should not send any values before a boolean is sent", ^{ + [trueSubject sendNext:RACUnit.defaultUnit]; + [falseSubject sendNext:RACUnit.defaultUnit]; + + expect(values).to(equal(@[])); + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + }); + + qck_it(@"should send events based on the latest boolean", ^{ + [boolSubject sendNext:@YES]; + + [trueSubject sendNext:@"foo"]; + [falseSubject sendNext:@"buzz"]; + [trueSubject sendNext:@"bar"]; + + NSArray *expected = @[ @"foo", @"bar" ]; + expect(values).to(equal(expected)); + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + [boolSubject sendNext:@NO]; + + [trueSubject sendNext:@"baz"]; + [falseSubject sendNext:@"buzz"]; + [trueSubject sendNext:@"barfoo"]; + + expected = @[ @"foo", @"bar", @"buzz" ]; + expect(values).to(equal(expected)); + expect(lastError).to(beNil()); + expect(@(completed)).to(beFalsy()); + + [trueSubject sendError:[NSError errorWithDomain:@"" code:-1 userInfo:nil]]; + expect(lastError).to(beNil()); + + [falseSubject sendError:[NSError errorWithDomain:@"" code:-1 userInfo:nil]]; + expect(lastError).notTo(beNil()); + }); + + qck_it(@"should not send completed when only the BOOL signal completes", ^{ + [boolSubject sendNext:@YES]; + [trueSubject sendNext:@"foo"]; + [boolSubject sendCompleted]; + + expect(values).to(equal(@[ @"foo" ])); + expect(@(completed)).to(beFalsy()); + }); + + qck_it(@"should send completed when the BOOL signal and the latest sent signal complete", ^{ + [boolSubject sendNext:@YES]; + [trueSubject sendNext:@"foo"]; + [trueSubject sendCompleted]; + [boolSubject sendCompleted]; + + expect(values).to(equal(@[ @"foo" ])); + expect(@(completed)).to(beTruthy()); + }); +}); + +qck_describe(@"+interval:onScheduler: and +interval:onScheduler:withLeeway:", ^{ + static const NSTimeInterval interval = 0.1; + static const NSTimeInterval leeway = 0.2; + + __block void (^testTimer)(RACSignal *, NSNumber *, NSNumber *) = nil; + + qck_beforeEach(^{ + testTimer = [^(RACSignal *timer, NSNumber *minInterval, NSNumber *leeway) { + __block NSUInteger nextsReceived = 0; + + NSTimeInterval startTime = NSDate.timeIntervalSinceReferenceDate; + [[timer take:3] subscribeNext:^(NSDate *date) { + ++nextsReceived; + + NSTimeInterval currentTime = date.timeIntervalSinceReferenceDate; + + // Uniformly distribute the expected interval for all + // received values. We do this instead of saving a timestamp + // because a delayed interval may cause the _next_ value to + // send sooner than the interval. + NSTimeInterval expectedMinInterval = minInterval.doubleValue * nextsReceived; + NSTimeInterval expectedMaxInterval = expectedMinInterval + leeway.doubleValue * 3 + 0.05; + + expect(@(currentTime - startTime)).to(beGreaterThanOrEqualTo(@(expectedMinInterval))); + expect(@(currentTime - startTime)).to(beLessThanOrEqualTo(@(expectedMaxInterval))); + }]; + + expect(@(nextsReceived)).toEventually(equal(@3)); + } copy]; + }); + + qck_describe(@"+interval:onScheduler:", ^{ + qck_it(@"should work on the main thread scheduler", ^{ + testTimer([RACSignal interval:interval onScheduler:RACScheduler.mainThreadScheduler], @(interval), @0); + }); + + qck_it(@"should work on a background scheduler", ^{ + testTimer([RACSignal interval:interval onScheduler:[RACScheduler scheduler]], @(interval), @0); + }); + }); + + qck_describe(@"+interval:onScheduler:withLeeway:", ^{ + qck_it(@"should work on the main thread scheduler", ^{ + testTimer([RACSignal interval:interval onScheduler:RACScheduler.mainThreadScheduler withLeeway:leeway], @(interval), @(leeway)); + }); + + qck_it(@"should work on a background scheduler", ^{ + testTimer([RACSignal interval:interval onScheduler:[RACScheduler scheduler] withLeeway:leeway], @(interval), @(leeway)); + }); + }); +}); + +qck_describe(@"-timeout:onScheduler:", ^{ + __block RACSubject *subject; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + }); + + qck_it(@"should time out", ^{ + RACTestScheduler *scheduler = [[RACTestScheduler alloc] init]; + + __block NSError *receivedError = nil; + [[subject timeout:1 onScheduler:scheduler] subscribeError:^(NSError *e) { + receivedError = e; + }]; + + expect(receivedError).to(beNil()); + + [scheduler stepAll]; + expect(receivedError).toEventuallyNot(beNil()); + expect(receivedError.domain).to(equal(RACSignalErrorDomain)); + expect(@(receivedError.code)).to(equal(@(RACSignalErrorTimedOut))); + }); + + qck_it(@"should pass through events while not timed out", ^{ + __block id next = nil; + __block BOOL completed = NO; + [[subject timeout:1 onScheduler:RACScheduler.mainThreadScheduler] subscribeNext:^(id x) { + next = x; + } completed:^{ + completed = YES; + }]; + + [subject sendNext:RACUnit.defaultUnit]; + expect(next).to(equal(RACUnit.defaultUnit)); + + [subject sendCompleted]; + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should not time out after disposal", ^{ + RACTestScheduler *scheduler = [[RACTestScheduler alloc] init]; + + __block NSError *receivedError = nil; + RACDisposable *disposable = [[subject timeout:1 onScheduler:scheduler] subscribeError:^(NSError *e) { + receivedError = e; + }]; + + [disposable dispose]; + [scheduler stepAll]; + expect(receivedError).to(beNil()); + }); +}); + +qck_describe(@"-delay:", ^{ + __block RACSubject *subject; + __block RACSignal *delayedSignal; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + delayedSignal = [subject delay:0]; + }); + + qck_it(@"should delay nexts", ^{ + __block id next = nil; + [delayedSignal subscribeNext:^(id x) { + next = x; + }]; + + [subject sendNext:@"foo"]; + expect(next).to(beNil()); + expect(next).toEventually(equal(@"foo")); + }); + + qck_it(@"should delay completed", ^{ + __block BOOL completed = NO; + [delayedSignal subscribeCompleted:^{ + completed = YES; + }]; + + [subject sendCompleted]; + expect(@(completed)).to(beFalsy()); + expect(@(completed)).toEventually(beTruthy()); + }); + + qck_it(@"should not delay errors", ^{ + __block NSError *error = nil; + [delayedSignal subscribeError:^(NSError *e) { + error = e; + }]; + + [subject sendError:RACSignalTestError]; + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"should cancel delayed events when disposed", ^{ + __block id next = nil; + RACDisposable *disposable = [delayedSignal subscribeNext:^(id x) { + next = x; + }]; + + [subject sendNext:@"foo"]; + + __block BOOL done = NO; + [RACScheduler.mainThreadScheduler after:[NSDate date] schedule:^{ + done = YES; + }]; + + [disposable dispose]; + + expect(@(done)).toEventually(beTruthy()); + expect(next).to(beNil()); + }); +}); + +qck_describe(@"-catch:", ^{ + qck_it(@"should subscribe to ensuing signal on error", ^{ + RACSubject *subject = [RACSubject subject]; + + RACSignal *signal = [subject catch:^(NSError *error) { + return [RACSignal return:@41]; + }]; + + __block id value = nil; + [signal subscribeNext:^(id x) { + value = x; + }]; + + [subject sendError:RACSignalTestError]; + expect(value).to(equal(@41)); + }); + + qck_it(@"should prevent source error from propagating", ^{ + RACSubject *subject = [RACSubject subject]; + + RACSignal *signal = [subject catch:^(NSError *error) { + return [RACSignal empty]; + }]; + + __block BOOL errorReceived = NO; + [signal subscribeError:^(NSError *error) { + errorReceived = YES; + }]; + + [subject sendError:RACSignalTestError]; + expect(@(errorReceived)).to(beFalsy()); + }); + + qck_it(@"should propagate error from ensuing signal", ^{ + RACSubject *subject = [RACSubject subject]; + + NSError *secondaryError = [NSError errorWithDomain:@"bubs" code:41 userInfo:nil]; + RACSignal *signal = [subject catch:^(NSError *error) { + return [RACSignal error:secondaryError]; + }]; + + __block NSError *errorReceived = nil; + [signal subscribeError:^(NSError *error) { + errorReceived = error; + }]; + + [subject sendError:RACSignalTestError]; + expect(errorReceived).to(equal(secondaryError)); + }); + + qck_it(@"should dispose ensuing signal", ^{ + RACSubject *subject = [RACSubject subject]; + + __block BOOL disposed = NO; + RACSignal *signal = [subject catch:^(NSError *error) { + return [RACSignal createSignal:^(id subscriber) { + return [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + }]; + }]; + + RACDisposable *disposable = [signal subscribeCompleted:^{}]; + [subject sendError:RACSignalTestError]; + [disposable dispose]; + + expect(@(disposed)).toEventually(beTruthy()); + }); +}); + +qck_describe(@"-try:", ^{ + __block RACSubject *subject; + __block NSError *receivedError; + __block NSMutableArray *nextValues; + __block BOOL completed; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + nextValues = [NSMutableArray array]; + completed = NO; + receivedError = nil; + + [[subject try:^(NSString *value, NSError **error) { + if (value != nil) return YES; + + if (error != nil) *error = RACSignalTestError; + + return NO; + }] subscribeNext:^(id x) { + [nextValues addObject:x]; + } error:^(NSError *error) { + receivedError = error; + } completed:^{ + completed = YES; + }]; + }); + + qck_it(@"should pass values while YES is returned from the tryBlock", ^{ + [subject sendNext:@"foo"]; + [subject sendNext:@"bar"]; + [subject sendNext:@"baz"]; + [subject sendNext:@"buzz"]; + [subject sendCompleted]; + + NSArray *receivedValues = [nextValues copy]; + NSArray *expectedValues = @[ @"foo", @"bar", @"baz", @"buzz" ]; + + expect(receivedError).to(beNil()); + expect(receivedValues).to(equal(expectedValues)); + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should pass values until NO is returned from the tryBlock", ^{ + [subject sendNext:@"foo"]; + [subject sendNext:@"bar"]; + [subject sendNext:nil]; + [subject sendNext:@"buzz"]; + [subject sendCompleted]; + + NSArray *receivedValues = [nextValues copy]; + NSArray *expectedValues = @[ @"foo", @"bar" ]; + + expect(receivedError).to(equal(RACSignalTestError)); + expect(receivedValues).to(equal(expectedValues)); + expect(@(completed)).to(beFalsy()); + }); +}); + +qck_describe(@"-tryMap:", ^{ + __block RACSubject *subject; + __block NSError *receivedError; + __block NSMutableArray *nextValues; + __block BOOL completed; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + nextValues = [NSMutableArray array]; + completed = NO; + receivedError = nil; + + [[subject tryMap:^ id (NSString *value, NSError **error) { + if (value != nil) return [NSString stringWithFormat:@"%@_a", value]; + + if (error != nil) *error = RACSignalTestError; + + return nil; + }] subscribeNext:^(id x) { + [nextValues addObject:x]; + } error:^(NSError *error) { + receivedError = error; + } completed:^{ + completed = YES; + }]; + }); + + qck_it(@"should map values with the mapBlock", ^{ + [subject sendNext:@"foo"]; + [subject sendNext:@"bar"]; + [subject sendNext:@"baz"]; + [subject sendNext:@"buzz"]; + [subject sendCompleted]; + + NSArray *receivedValues = [nextValues copy]; + NSArray *expectedValues = @[ @"foo_a", @"bar_a", @"baz_a", @"buzz_a" ]; + + expect(receivedError).to(beNil()); + expect(receivedValues).to(equal(expectedValues)); + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should map values with the mapBlock, until the mapBlock returns nil", ^{ + [subject sendNext:@"foo"]; + [subject sendNext:@"bar"]; + [subject sendNext:nil]; + [subject sendNext:@"buzz"]; + [subject sendCompleted]; + + NSArray *receivedValues = [nextValues copy]; + NSArray *expectedValues = @[ @"foo_a", @"bar_a" ]; + + expect(receivedError).to(equal(RACSignalTestError)); + expect(receivedValues).to(equal(expectedValues)); + expect(@(completed)).to(beFalsy()); + }); +}); + +qck_describe(@"throttling", ^{ + __block RACSubject *subject; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + }); + + qck_describe(@"-throttle:", ^{ + __block RACSignal *throttledSignal; + + qck_beforeEach(^{ + throttledSignal = [subject throttle:0]; + }); + + qck_it(@"should throttle nexts", ^{ + NSMutableArray *valuesReceived = [NSMutableArray array]; + [throttledSignal subscribeNext:^(id x) { + [valuesReceived addObject:x]; + }]; + + [subject sendNext:@"foo"]; + [subject sendNext:@"bar"]; + expect(valuesReceived).to(equal(@[])); + + NSArray *expected = @[ @"bar" ]; + expect(valuesReceived).toEventually(equal(expected)); + + [subject sendNext:@"buzz"]; + expect(valuesReceived).to(equal(expected)); + + expected = @[ @"bar", @"buzz" ]; + expect(valuesReceived).toEventually(equal(expected)); + }); + + qck_it(@"should forward completed immediately", ^{ + __block BOOL completed = NO; + [throttledSignal subscribeCompleted:^{ + completed = YES; + }]; + + [subject sendCompleted]; + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should forward errors immediately", ^{ + __block NSError *error = nil; + [throttledSignal subscribeError:^(NSError *e) { + error = e; + }]; + + [subject sendError:RACSignalTestError]; + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"should cancel future nexts when disposed", ^{ + __block id next = nil; + RACDisposable *disposable = [throttledSignal subscribeNext:^(id x) { + next = x; + }]; + + [subject sendNext:@"foo"]; + + __block BOOL done = NO; + [RACScheduler.mainThreadScheduler after:[NSDate date] schedule:^{ + done = YES; + }]; + + [disposable dispose]; + + expect(@(done)).toEventually(beTruthy()); + expect(next).to(beNil()); + }); + }); + + qck_describe(@"-throttle:valuesPassingTest:", ^{ + __block RACSignal *throttledSignal; + __block BOOL shouldThrottle; + + qck_beforeEach(^{ + shouldThrottle = YES; + + __block id value = nil; + throttledSignal = [[subject + doNext:^(id x) { + value = x; + }] + throttle:0 valuesPassingTest:^(id x) { + // Make sure that we're given the latest value. + expect(x).to(beIdenticalTo(value)); + + return shouldThrottle; + }]; + + expect(throttledSignal).notTo(beNil()); + }); + + qck_describe(@"nexts", ^{ + __block NSMutableArray *valuesReceived; + __block NSMutableArray *expected; + + qck_beforeEach(^{ + expected = [[NSMutableArray alloc] init]; + valuesReceived = [[NSMutableArray alloc] init]; + + [throttledSignal subscribeNext:^(id x) { + [valuesReceived addObject:x]; + }]; + }); + + qck_it(@"should forward unthrottled values immediately", ^{ + shouldThrottle = NO; + [subject sendNext:@"foo"]; + + [expected addObject:@"foo"]; + expect(valuesReceived).to(equal(expected)); + }); + + qck_it(@"should delay throttled values", ^{ + [subject sendNext:@"bar"]; + expect(valuesReceived).to(equal(expected)); + + [expected addObject:@"bar"]; + expect(valuesReceived).toEventually(equal(expected)); + }); + + qck_it(@"should drop buffered values when a throttled value arrives", ^{ + [subject sendNext:@"foo"]; + [subject sendNext:@"bar"]; + [subject sendNext:@"buzz"]; + expect(valuesReceived).to(equal(expected)); + + [expected addObject:@"buzz"]; + expect(valuesReceived).toEventually(equal(expected)); + }); + + qck_it(@"should drop buffered values when an immediate value arrives", ^{ + [subject sendNext:@"foo"]; + [subject sendNext:@"bar"]; + + shouldThrottle = NO; + [subject sendNext:@"buzz"]; + [expected addObject:@"buzz"]; + expect(valuesReceived).to(equal(expected)); + + // Make sure that nothing weird happens when sending another + // throttled value. + shouldThrottle = YES; + [subject sendNext:@"baz"]; + expect(valuesReceived).to(equal(expected)); + + [expected addObject:@"baz"]; + expect(valuesReceived).toEventually(equal(expected)); + }); + + qck_it(@"should not be resent upon completion", ^{ + [subject sendNext:@"bar"]; + [expected addObject:@"bar"]; + expect(valuesReceived).toEventually(equal(expected)); + + [subject sendCompleted]; + expect(valuesReceived).to(equal(expected)); + }); + }); + + qck_it(@"should forward completed immediately", ^{ + __block BOOL completed = NO; + [throttledSignal subscribeCompleted:^{ + completed = YES; + }]; + + [subject sendCompleted]; + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should forward errors immediately", ^{ + __block NSError *error = nil; + [throttledSignal subscribeError:^(NSError *e) { + error = e; + }]; + + [subject sendError:RACSignalTestError]; + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"should cancel future nexts when disposed", ^{ + __block id next = nil; + RACDisposable *disposable = [throttledSignal subscribeNext:^(id x) { + next = x; + }]; + + [subject sendNext:@"foo"]; + + __block BOOL done = NO; + [RACScheduler.mainThreadScheduler after:[NSDate date] schedule:^{ + done = YES; + }]; + + [disposable dispose]; + + expect(@(done)).toEventually(beTruthy()); + expect(next).to(beNil()); + }); + }); +}); + +qck_describe(@"-then:", ^{ + qck_it(@"should continue onto returned signal", ^{ + RACSubject *subject = [RACSubject subject]; + + __block id value = nil; + [[subject then:^{ + return [RACSignal return:@2]; + }] subscribeNext:^(id x) { + value = x; + }]; + + [subject sendNext:@1]; + + // The value shouldn't change until the first signal completes. + expect(value).to(beNil()); + + [subject sendCompleted]; + + expect(value).to(equal(@2)); + }); + + qck_it(@"should sequence even if no next value is sent", ^{ + RACSubject *subject = [RACSubject subject]; + + __block id value = nil; + [[subject then:^{ + return [RACSignal return:RACUnit.defaultUnit]; + }] subscribeNext:^(id x) { + value = x; + }]; + + [subject sendCompleted]; + + expect(value).to(equal(RACUnit.defaultUnit)); + }); +}); + +qck_describe(@"-sequence", ^{ + RACSignal *signal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendNext:@2]; + [subscriber sendNext:@3]; + [subscriber sendNext:@4]; + [subscriber sendCompleted]; + return nil; + }]; + + qck_itBehavesLike(RACSequenceExamples, ^{ + return @{ + RACSequenceExampleSequence: signal.sequence, + RACSequenceExampleExpectedValues: @[ @1, @2, @3, @4 ] + }; + }); +}); + +qck_it(@"should complete take: even if the original signal doesn't", ^{ + RACSignal *sendOne = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + [subscriber sendNext:RACUnit.defaultUnit]; + return nil; + }]; + + __block id value = nil; + __block BOOL completed = NO; + [[sendOne take:1] subscribeNext:^(id received) { + value = received; + } completed:^{ + completed = YES; + }]; + + expect(value).to(equal(RACUnit.defaultUnit)); + expect(@(completed)).to(beTruthy()); +}); + +qck_describe(@"+zip:", ^{ + __block RACSubject *subject1 = nil; + __block RACSubject *subject2 = nil; + __block BOOL hasSentError = NO; + __block BOOL hasSentCompleted = NO; + __block RACDisposable *disposable = nil; + __block void (^send2NextAndErrorTo1)(void) = nil; + __block void (^send3NextAndErrorTo1)(void) = nil; + __block void (^send2NextAndCompletedTo2)(void) = nil; + __block void (^send3NextAndCompletedTo2)(void) = nil; + + qck_beforeEach(^{ + send2NextAndErrorTo1 = [^{ + [subject1 sendNext:@1]; + [subject1 sendNext:@2]; + [subject1 sendError:RACSignalTestError]; + } copy]; + send3NextAndErrorTo1 = [^{ + [subject1 sendNext:@1]; + [subject1 sendNext:@2]; + [subject1 sendNext:@3]; + [subject1 sendError:RACSignalTestError]; + } copy]; + send2NextAndCompletedTo2 = [^{ + [subject2 sendNext:@1]; + [subject2 sendNext:@2]; + [subject2 sendCompleted]; + } copy]; + send3NextAndCompletedTo2 = [^{ + [subject2 sendNext:@1]; + [subject2 sendNext:@2]; + [subject2 sendNext:@3]; + [subject2 sendCompleted]; + } copy]; + subject1 = [RACSubject subject]; + subject2 = [RACSubject subject]; + hasSentError = NO; + hasSentCompleted = NO; + disposable = [[RACSignal zip:@[ subject1, subject2 ]] subscribeError:^(NSError *error) { + hasSentError = YES; + } completed:^{ + hasSentCompleted = YES; + }]; + }); + + qck_afterEach(^{ + [disposable dispose]; + }); + + qck_it(@"should complete as soon as no new zipped values are possible", ^{ + [subject1 sendNext:@1]; + [subject2 sendNext:@1]; + expect(@(hasSentCompleted)).to(beFalsy()); + + [subject1 sendNext:@2]; + [subject1 sendCompleted]; + expect(@(hasSentCompleted)).to(beFalsy()); + + [subject2 sendNext:@2]; + expect(@(hasSentCompleted)).to(beTruthy()); + }); + + qck_it(@"outcome should not be dependent on order of signals", ^{ + [subject2 sendCompleted]; + expect(@(hasSentCompleted)).to(beTruthy()); + }); + + qck_it(@"should forward errors sent earlier than (time-wise) and before (position-wise) a complete", ^{ + send2NextAndErrorTo1(); + send3NextAndCompletedTo2(); + expect(@(hasSentError)).to(beTruthy()); + expect(@(hasSentCompleted)).to(beFalsy()); + }); + + qck_it(@"should forward errors sent earlier than (time-wise) and after (position-wise) a complete", ^{ + send3NextAndErrorTo1(); + send2NextAndCompletedTo2(); + expect(@(hasSentError)).to(beTruthy()); + expect(@(hasSentCompleted)).to(beFalsy()); + }); + + qck_it(@"should forward errors sent later than (time-wise) and before (position-wise) a complete", ^{ + send3NextAndCompletedTo2(); + send2NextAndErrorTo1(); + expect(@(hasSentError)).to(beTruthy()); + expect(@(hasSentCompleted)).to(beFalsy()); + }); + + qck_it(@"should ignore errors sent later than (time-wise) and after (position-wise) a complete", ^{ + send2NextAndCompletedTo2(); + send3NextAndErrorTo1(); + expect(@(hasSentError)).to(beFalsy()); + expect(@(hasSentCompleted)).to(beTruthy()); + }); + + qck_it(@"should handle signals sending values unevenly", ^{ + __block NSError *receivedError = nil; + __block BOOL hasCompleted = NO; + + RACSubject *a = [RACSubject subject]; + RACSubject *b = [RACSubject subject]; + RACSubject *c = [RACSubject subject]; + + NSMutableArray *receivedValues = NSMutableArray.array; + NSArray *expectedValues = nil; + + [[RACSignal zip:@[ a, b, c ] reduce:^(NSNumber *a, NSNumber *b, NSNumber *c) { + return [NSString stringWithFormat:@"%@%@%@", a, b, c]; + }] subscribeNext:^(id x) { + [receivedValues addObject:x]; + } error:^(NSError *error) { + receivedError = error; + } completed:^{ + hasCompleted = YES; + }]; + + [a sendNext:@1]; + [a sendNext:@2]; + [a sendNext:@3]; + + [b sendNext:@1]; + + [c sendNext:@1]; + [c sendNext:@2]; + + // a: [===......] + // b: [=........] + // c: [==.......] + + expectedValues = @[ @"111" ]; + expect(receivedValues).to(equal(expectedValues)); + expect(receivedError).to(beNil()); + expect(@(hasCompleted)).to(beFalsy()); + + [b sendNext:@2]; + [b sendNext:@3]; + [b sendNext:@4]; + [b sendCompleted]; + + // a: [===......] + // b: [====C....] + // c: [==.......] + + expectedValues = @[ @"111", @"222" ]; + expect(receivedValues).to(equal(expectedValues)); + expect(receivedError).to(beNil()); + expect(@(hasCompleted)).to(beFalsy()); + + [c sendNext:@3]; + [c sendNext:@4]; + [c sendNext:@5]; + [c sendError:RACSignalTestError]; + + // a: [===......] + // b: [====C....] + // c: [=====E...] + + expectedValues = @[ @"111", @"222", @"333" ]; + expect(receivedValues).to(equal(expectedValues)); + expect(receivedError).to(equal(RACSignalTestError)); + expect(@(hasCompleted)).to(beFalsy()); + + [a sendNext:@4]; + [a sendNext:@5]; + [a sendNext:@6]; + [a sendNext:@7]; + + // a: [=======..] + // b: [====C....] + // c: [=====E...] + + expectedValues = @[ @"111", @"222", @"333" ]; + expect(receivedValues).to(equal(expectedValues)); + expect(receivedError).to(equal(RACSignalTestError)); + expect(@(hasCompleted)).to(beFalsy()); + }); + + qck_it(@"should handle multiples of the same side-effecting signal", ^{ + __block NSUInteger counter = 0; + RACSignal *sideEffectingSignal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + ++counter; + [subscriber sendNext:@1]; + [subscriber sendCompleted]; + return nil; + }]; + RACSignal *combined = [RACSignal zip:@[ sideEffectingSignal, sideEffectingSignal ] reduce:^ NSString * (id x, id y) { + return [NSString stringWithFormat:@"%@%@", x, y]; + }]; + NSMutableArray *receivedValues = NSMutableArray.array; + + expect(@(counter)).to(equal(@0)); + + [combined subscribeNext:^(id x) { + [receivedValues addObject:x]; + }]; + + expect(@(counter)).to(equal(@2)); + expect(receivedValues).to(equal(@[ @"11" ])); + }); +}); + +qck_describe(@"-sample:", ^{ + qck_it(@"should send the latest value when the sampler signal fires", ^{ + RACSubject *subject = [RACSubject subject]; + RACSubject *sampleSubject = [RACSubject subject]; + RACSignal *sampled = [subject sample:sampleSubject]; + NSMutableArray *values = [NSMutableArray array]; + [sampled subscribeNext:^(id x) { + [values addObject:x]; + }]; + + [sampleSubject sendNext:RACUnit.defaultUnit]; + expect(values).to(equal(@[])); + + [subject sendNext:@1]; + [subject sendNext:@2]; + expect(values).to(equal(@[])); + + [sampleSubject sendNext:RACUnit.defaultUnit]; + NSArray *expected = @[ @2 ]; + expect(values).to(equal(expected)); + + [subject sendNext:@3]; + expect(values).to(equal(expected)); + + [sampleSubject sendNext:RACUnit.defaultUnit]; + expected = @[ @2, @3 ]; + expect(values).to(equal(expected)); + + [sampleSubject sendNext:RACUnit.defaultUnit]; + expected = @[ @2, @3, @3 ]; + expect(values).to(equal(expected)); + }); +}); + +qck_describe(@"-collect", ^{ + __block RACSubject *subject; + __block RACSignal *collected; + + __block id value; + __block BOOL hasCompleted; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + collected = [subject collect]; + + value = nil; + hasCompleted = NO; + + [collected subscribeNext:^(id x) { + value = x; + } completed:^{ + hasCompleted = YES; + }]; + }); + + qck_it(@"should send a single array when the original signal completes", ^{ + NSArray *expected = @[ @1, @2, @3 ]; + + [subject sendNext:@1]; + [subject sendNext:@2]; + [subject sendNext:@3]; + expect(value).to(beNil()); + + [subject sendCompleted]; + expect(value).to(equal(expected)); + expect(@(hasCompleted)).to(beTruthy()); + }); + + qck_it(@"should add NSNull to an array for nil values", ^{ + NSArray *expected = @[ NSNull.null, @1, NSNull.null ]; + + [subject sendNext:nil]; + [subject sendNext:@1]; + [subject sendNext:nil]; + expect(value).to(beNil()); + + [subject sendCompleted]; + expect(value).to(equal(expected)); + expect(@(hasCompleted)).to(beTruthy()); + }); +}); + +qck_describe(@"-bufferWithTime:", ^{ + __block RACTestScheduler *scheduler; + + __block RACSubject *input; + __block RACSignal *bufferedInput; + __block RACTuple *latestValue; + + qck_beforeEach(^{ + scheduler = [[RACTestScheduler alloc] init]; + + input = [RACSubject subject]; + bufferedInput = [input bufferWithTime:1 onScheduler:scheduler]; + latestValue = nil; + + [bufferedInput subscribeNext:^(RACTuple *x) { + latestValue = x; + }]; + }); + + qck_it(@"should buffer nexts", ^{ + [input sendNext:@1]; + [input sendNext:@2]; + + [scheduler stepAll]; + expect(latestValue).to(equal(RACTuplePack(@1, @2))); + + [input sendNext:@3]; + [input sendNext:@4]; + + [scheduler stepAll]; + expect(latestValue).to(equal(RACTuplePack(@3, @4))); + }); + + qck_it(@"should not perform buffering until a value is sent", ^{ + [input sendNext:@1]; + [input sendNext:@2]; + [scheduler stepAll]; + expect(latestValue).to(equal(RACTuplePack(@1, @2))); + + [scheduler stepAll]; + expect(latestValue).to(equal(RACTuplePack(@1, @2))); + + [input sendNext:@3]; + [input sendNext:@4]; + [scheduler stepAll]; + expect(latestValue).to(equal(RACTuplePack(@3, @4))); + }); + + qck_it(@"should flush any buffered nexts upon completion", ^{ + [input sendNext:@1]; + [input sendCompleted]; + [scheduler stepAll]; + expect(latestValue).to(equal(RACTuplePack(@1))); + }); + + qck_it(@"should support NSNull values", ^{ + [input sendNext:NSNull.null]; + [scheduler stepAll]; + expect(latestValue).to(equal(RACTuplePack(NSNull.null))); + }); + + qck_it(@"should buffer nil values", ^{ + [input sendNext:nil]; + [scheduler stepAll]; + expect(latestValue).to(equal(RACTuplePack(nil))); + }); +}); + +qck_describe(@"-concat", ^{ + __block RACSubject *subject; + + __block RACSignal *oneSignal; + __block RACSignal *twoSignal; + __block RACSignal *threeSignal; + + __block RACSignal *errorSignal; + __block RACSignal *completedSignal; + + qck_beforeEach(^{ + subject = [RACReplaySubject subject]; + + oneSignal = [RACSignal return:@1]; + twoSignal = [RACSignal return:@2]; + threeSignal = [RACSignal return:@3]; + + errorSignal = [RACSignal error:RACSignalTestError]; + completedSignal = RACSignal.empty; + }); + + qck_it(@"should concatenate the values of inner signals", ^{ + [subject sendNext:oneSignal]; + [subject sendNext:twoSignal]; + [subject sendNext:completedSignal]; + [subject sendNext:threeSignal]; + + NSMutableArray *values = [NSMutableArray array]; + [[subject concat] subscribeNext:^(id x) { + [values addObject:x]; + }]; + + NSArray *expected = @[ @1, @2, @3 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should complete only after all signals complete", ^{ + RACReplaySubject *valuesSubject = [RACReplaySubject subject]; + + [subject sendNext:valuesSubject]; + [subject sendCompleted]; + + [valuesSubject sendNext:@1]; + [valuesSubject sendNext:@2]; + [valuesSubject sendCompleted]; + + NSArray *expected = @[ @1, @2 ]; + expect([[subject concat] toArray]).to(equal(expected)); + }); + + qck_it(@"should pass through errors", ^{ + [subject sendNext:errorSignal]; + + NSError *error = nil; + [[subject concat] firstOrDefault:nil success:NULL error:&error]; + expect(error).to(equal(RACSignalTestError)); + }); + + qck_it(@"should concat signals sent later", ^{ + [subject sendNext:oneSignal]; + + NSMutableArray *values = [NSMutableArray array]; + [[subject concat] subscribeNext:^(id x) { + [values addObject:x]; + }]; + + NSArray *expected = @[ @1 ]; + expect(values).to(equal(expected)); + + [subject sendNext:[twoSignal delay:0]]; + + expected = @[ @1, @2 ]; + expect(values).toEventually(equal(expected)); + + [subject sendNext:threeSignal]; + + expected = @[ @1, @2, @3 ]; + expect(values).to(equal(expected)); + }); + + qck_it(@"should dispose the current signal", ^{ + __block BOOL disposed = NO; + __block id innerSubscriber = nil; + RACSignal *innerSignal = [RACSignal createSignal:^(id subscriber) { + // Keep the subscriber alive so it doesn't trigger disposal on dealloc + innerSubscriber = subscriber; + return [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + }]; + + RACDisposable *concatDisposable = [[subject concat] subscribeCompleted:^{}]; + + [subject sendNext:innerSignal]; + expect(@(disposed)).notTo(beTruthy()); + + [concatDisposable dispose]; + expect(@(disposed)).to(beTruthy()); + }); + + qck_it(@"should dispose later signals", ^{ + __block BOOL disposed = NO; + __block id laterSubscriber = nil; + RACSignal *laterSignal = [RACSignal createSignal:^(id subscriber) { + // Keep the subscriber alive so it doesn't trigger disposal on dealloc + laterSubscriber = subscriber; + return [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + }]; + + RACSubject *firstSignal = [RACSubject subject]; + RACSignal *outerSignal = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:firstSignal]; + [subscriber sendNext:laterSignal]; + return nil; + }]; + + RACDisposable *concatDisposable = [[outerSignal concat] subscribeCompleted:^{}]; + + [firstSignal sendCompleted]; + expect(@(disposed)).notTo(beTruthy()); + + [concatDisposable dispose]; + expect(@(disposed)).to(beTruthy()); + }); +}); + +qck_describe(@"-initially:", ^{ + __block RACSubject *subject; + + __block NSUInteger initiallyInvokedCount; + __block RACSignal *signal; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + + initiallyInvokedCount = 0; + signal = [subject initially:^{ + ++initiallyInvokedCount; + }]; + }); + + qck_it(@"should not run without a subscription", ^{ + [subject sendCompleted]; + expect(@(initiallyInvokedCount)).to(equal(@0)); + }); + + qck_it(@"should run on subscription", ^{ + [signal subscribe:[RACSubscriber new]]; + expect(@(initiallyInvokedCount)).to(equal(@1)); + }); + + qck_it(@"should re-run for each subscription", ^{ + [signal subscribe:[RACSubscriber new]]; + [signal subscribe:[RACSubscriber new]]; + expect(@(initiallyInvokedCount)).to(equal(@2)); + }); +}); + +qck_describe(@"-finally:", ^{ + __block RACSubject *subject; + + __block BOOL finallyInvoked; + __block RACSignal *signal; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + + finallyInvoked = NO; + signal = [subject finally:^{ + finallyInvoked = YES; + }]; + }); + + qck_it(@"should not run finally without a subscription", ^{ + [subject sendCompleted]; + expect(@(finallyInvoked)).to(beFalsy()); + }); + + qck_describe(@"with a subscription", ^{ + __block RACDisposable *disposable; + + qck_beforeEach(^{ + disposable = [signal subscribeCompleted:^{}]; + }); + + qck_afterEach(^{ + [disposable dispose]; + }); + + qck_it(@"should not run finally upon next", ^{ + [subject sendNext:RACUnit.defaultUnit]; + expect(@(finallyInvoked)).to(beFalsy()); + }); + + qck_it(@"should run finally upon completed", ^{ + [subject sendCompleted]; + expect(@(finallyInvoked)).to(beTruthy()); + }); + + qck_it(@"should run finally upon error", ^{ + [subject sendError:nil]; + expect(@(finallyInvoked)).to(beTruthy()); + }); + }); +}); + +qck_describe(@"-ignoreValues", ^{ + __block RACSubject *subject; + + __block BOOL gotNext; + __block BOOL gotCompleted; + __block NSError *receivedError; + + qck_beforeEach(^{ + subject = [RACSubject subject]; + + gotNext = NO; + gotCompleted = NO; + receivedError = nil; + + [[subject ignoreValues] subscribeNext:^(id _) { + gotNext = YES; + } error:^(NSError *error) { + receivedError = error; + } completed:^{ + gotCompleted = YES; + }]; + }); + + qck_it(@"should skip nexts and pass through completed", ^{ + [subject sendNext:RACUnit.defaultUnit]; + [subject sendCompleted]; + + expect(@(gotNext)).to(beFalsy()); + expect(@(gotCompleted)).to(beTruthy()); + expect(receivedError).to(beNil()); + }); + + qck_it(@"should skip nexts and pass through errors", ^{ + [subject sendNext:RACUnit.defaultUnit]; + [subject sendError:RACSignalTestError]; + + expect(@(gotNext)).to(beFalsy()); + expect(@(gotCompleted)).to(beFalsy()); + expect(receivedError).to(equal(RACSignalTestError)); + }); +}); + +qck_describe(@"-materialize", ^{ + qck_it(@"should convert nexts and completed into RACEvents", ^{ + NSArray *events = [[[RACSignal return:RACUnit.defaultUnit] materialize] toArray]; + NSArray *expected = @[ + [RACEvent eventWithValue:RACUnit.defaultUnit], + RACEvent.completedEvent + ]; + + expect(events).to(equal(expected)); + }); + + qck_it(@"should convert errors into RACEvents and complete", ^{ + NSArray *events = [[[RACSignal error:RACSignalTestError] materialize] toArray]; + NSArray *expected = @[ [RACEvent eventWithError:RACSignalTestError] ]; + expect(events).to(equal(expected)); + }); +}); + +qck_describe(@"-dematerialize", ^{ + qck_it(@"should convert nexts from RACEvents", ^{ + RACSignal *events = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:[RACEvent eventWithValue:@1]]; + [subscriber sendNext:[RACEvent eventWithValue:@2]]; + [subscriber sendCompleted]; + return nil; + }]; + + NSArray *expected = @[ @1, @2 ]; + expect([[events dematerialize] toArray]).to(equal(expected)); + }); + + qck_it(@"should convert completed from a RACEvent", ^{ + RACSignal *events = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:[RACEvent eventWithValue:@1]]; + [subscriber sendNext:RACEvent.completedEvent]; + [subscriber sendNext:[RACEvent eventWithValue:@2]]; + [subscriber sendCompleted]; + return nil; + }]; + + NSArray *expected = @[ @1 ]; + expect([[events dematerialize] toArray]).to(equal(expected)); + }); + + qck_it(@"should convert error from a RACEvent", ^{ + RACSignal *events = [RACSignal createSignal:^ id (id subscriber) { + [subscriber sendNext:[RACEvent eventWithError:RACSignalTestError]]; + [subscriber sendNext:[RACEvent eventWithValue:@1]]; + [subscriber sendCompleted]; + return nil; + }]; + + __block NSError *error = nil; + expect([[events dematerialize] firstOrDefault:nil success:NULL error:&error]).to(beNil()); + expect(error).to(equal(RACSignalTestError)); + }); +}); + +qck_describe(@"-not", ^{ + qck_it(@"should invert every BOOL sent", ^{ + RACSubject *subject = [RACReplaySubject subject]; + [subject sendNext:@NO]; + [subject sendNext:@YES]; + [subject sendCompleted]; + NSArray *results = [[subject not] toArray]; + NSArray *expected = @[ @YES, @NO ]; + expect(results).to(equal(expected)); + }); +}); + +qck_describe(@"-and", ^{ + qck_it(@"should return YES if all YES values are sent", ^{ + RACSubject *subject = [RACReplaySubject subject]; + + [subject sendNext:RACTuplePack(@YES, @NO, @YES)]; + [subject sendNext:RACTuplePack(@NO, @NO, @NO)]; + [subject sendNext:RACTuplePack(@YES, @YES, @YES)]; + [subject sendCompleted]; + + NSArray *results = [[subject and] toArray]; + NSArray *expected = @[ @NO, @NO, @YES ]; + + expect(results).to(equal(expected)); + }); +}); + +qck_describe(@"-or", ^{ + qck_it(@"should return YES for any YES values sent", ^{ + RACSubject *subject = [RACReplaySubject subject]; + + [subject sendNext:RACTuplePack(@YES, @NO, @YES)]; + [subject sendNext:RACTuplePack(@NO, @NO, @NO)]; + [subject sendCompleted]; + + NSArray *results = [[subject or] toArray]; + NSArray *expected = @[ @YES, @NO ]; + + expect(results).to(equal(expected)); + }); +}); + +qck_describe(@"-groupBy:", ^{ + qck_it(@"should send completed to all grouped signals.", ^{ + RACSubject *subject = [RACReplaySubject subject]; + + __block NSUInteger groupedSignalCount = 0; + __block NSUInteger completedGroupedSignalCount = 0; + [[subject groupBy:^(NSNumber *number) { + return @(floorf(number.floatValue)); + }] subscribeNext:^(RACGroupedSignal *groupedSignal) { + ++groupedSignalCount; + + [groupedSignal subscribeCompleted:^{ + ++completedGroupedSignalCount; + }]; + }]; + + [subject sendNext:@1]; + [subject sendNext:@2]; + [subject sendCompleted]; + + expect(@(completedGroupedSignalCount)).to(equal(@(groupedSignalCount))); + }); + + qck_it(@"should send error to all grouped signals.", ^{ + RACSubject *subject = [RACReplaySubject subject]; + + __block NSUInteger groupedSignalCount = 0; + __block NSUInteger erroneousGroupedSignalCount = 0; + [[subject groupBy:^(NSNumber *number) { + return @(floorf(number.floatValue)); + }] subscribeNext:^(RACGroupedSignal *groupedSignal) { + ++groupedSignalCount; + + [groupedSignal subscribeError:^(NSError *error) { + ++erroneousGroupedSignalCount; + + expect(error.domain).to(equal(@"TestDomain")); + expect(@(error.code)).to(equal(@123)); + }]; + }]; + + [subject sendNext:@1]; + [subject sendNext:@2]; + [subject sendError:[NSError errorWithDomain:@"TestDomain" code:123 userInfo:nil]]; + + expect(@(erroneousGroupedSignalCount)).to(equal(@(groupedSignalCount))); + }); +}); + +qck_describe(@"starting signals", ^{ + qck_describe(@"+startLazilyWithScheduler:block:", ^{ + __block NSUInteger invokedCount = 0; + __block void (^subscribe)(void); + + qck_beforeEach(^{ + invokedCount = 0; + + RACSignal *signal = [RACSignal startLazilyWithScheduler:RACScheduler.immediateScheduler block:^(id subscriber) { + invokedCount++; + [subscriber sendNext:@42]; + [subscriber sendCompleted]; + }]; + + subscribe = [^{ + [signal subscribe:[RACSubscriber subscriberWithNext:nil error:nil completed:nil]]; + } copy]; + }); + + qck_it(@"should only invoke the block on subscription", ^{ + expect(@(invokedCount)).to(equal(@0)); + subscribe(); + expect(@(invokedCount)).to(equal(@1)); + }); + + qck_it(@"should only invoke the block once", ^{ + expect(@(invokedCount)).to(equal(@0)); + subscribe(); + expect(@(invokedCount)).to(equal(@1)); + subscribe(); + expect(@(invokedCount)).to(equal(@1)); + subscribe(); + expect(@(invokedCount)).to(equal(@1)); + }); + + qck_it(@"should invoke the block on the given scheduler", ^{ + RACScheduler *scheduler = [RACScheduler scheduler]; + __block RACScheduler *currentScheduler; + [[[RACSignal + startLazilyWithScheduler:scheduler block:^(id subscriber) { + currentScheduler = RACScheduler.currentScheduler; + }] + publish] + connect]; + + expect(currentScheduler).toEventually(equal(scheduler)); + }); + }); + + qck_describe(@"+startEagerlyWithScheduler:block:", ^{ + qck_it(@"should immediately invoke the block", ^{ + __block BOOL blockInvoked = NO; + [RACSignal startEagerlyWithScheduler:[RACScheduler scheduler] block:^(id subscriber) { + blockInvoked = YES; + }]; + + expect(@(blockInvoked)).toEventually(beTruthy()); + }); + + qck_it(@"should only invoke the block once", ^{ + __block NSUInteger invokedCount = 0; + RACSignal *signal = [RACSignal startEagerlyWithScheduler:RACScheduler.immediateScheduler block:^(id subscriber) { + invokedCount++; + }]; + + expect(@(invokedCount)).to(equal(@1)); + + [[signal publish] connect]; + expect(@(invokedCount)).to(equal(@1)); + + [[signal publish] connect]; + expect(@(invokedCount)).to(equal(@1)); + }); + + qck_it(@"should invoke the block on the given scheduler", ^{ + RACScheduler *scheduler = [RACScheduler scheduler]; + __block RACScheduler *currentScheduler; + [RACSignal startEagerlyWithScheduler:scheduler block:^(id subscriber) { + currentScheduler = RACScheduler.currentScheduler; + }]; + + expect(currentScheduler).toEventually(equal(scheduler)); + }); + }); +}); + +qck_describe(@"-toArray", ^{ + __block RACSubject *subject; + + qck_beforeEach(^{ + subject = [RACReplaySubject subject]; + }); + + qck_it(@"should return an array which contains NSNulls for nil values", ^{ + NSArray *expected = @[ NSNull.null, @1, NSNull.null ]; + + [subject sendNext:nil]; + [subject sendNext:@1]; + [subject sendNext:nil]; + [subject sendCompleted]; + + expect([subject toArray]).to(equal(expected)); + }); + + qck_it(@"should return nil upon error", ^{ + [subject sendError:nil]; + expect([subject toArray]).to(beNil()); + }); + + qck_it(@"should return nil upon error even if some nexts were sent", ^{ + [subject sendNext:@1]; + [subject sendNext:@2]; + [subject sendError:nil]; + + expect([subject toArray]).to(beNil()); + }); +}); + +qck_describe(@"-ignore:", ^{ + qck_it(@"should ignore nil", ^{ + RACSignal *signal = [[RACSignal + createSignal:^ id (id subscriber) { + [subscriber sendNext:@1]; + [subscriber sendNext:nil]; + [subscriber sendNext:@3]; + [subscriber sendNext:@4]; + [subscriber sendNext:nil]; + [subscriber sendCompleted]; + return nil; + }] + ignore:nil]; + + NSArray *expected = @[ @1, @3, @4 ]; + expect([signal toArray]).to(equal(expected)); + }); +}); + +qck_describe(@"-replayLazily", ^{ + __block NSUInteger subscriptionCount; + __block BOOL disposed; + + __block RACSignal *signal; + __block RACSubject *disposeSubject; + __block RACSignal *replayedSignal; + + qck_beforeEach(^{ + subscriptionCount = 0; + disposed = NO; + + signal = [RACSignal createSignal:^ RACDisposable * (id subscriber) { + subscriptionCount++; + [subscriber sendNext:RACUnit.defaultUnit]; + + RACDisposable *schedulingDisposable = [RACScheduler.mainThreadScheduler schedule:^{ + [subscriber sendNext:RACUnit.defaultUnit]; + [subscriber sendCompleted]; + }]; + + return [RACDisposable disposableWithBlock:^{ + [schedulingDisposable dispose]; + disposed = YES; + }]; + }]; + + disposeSubject = [RACSubject subject]; + replayedSignal = [[signal takeUntil:disposeSubject] replayLazily]; + }); + + qck_it(@"should forward the input signal upon subscription", ^{ + expect(@(subscriptionCount)).to(equal(@0)); + + expect(@([replayedSignal asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy()); + expect(@(subscriptionCount)).to(equal(@1)); + }); + + qck_it(@"should replay the input signal for future subscriptions", ^{ + NSArray *events = [[[replayedSignal materialize] collect] asynchronousFirstOrDefault:nil success:NULL error:NULL]; + expect(events).notTo(beNil()); + + expect([[[replayedSignal materialize] collect] asynchronousFirstOrDefault:nil success:NULL error:NULL]).to(equal(events)); + expect(@(subscriptionCount)).to(equal(@1)); + }); + + qck_it(@"should replay even after disposal", ^{ + __block NSUInteger valueCount = 0; + [replayedSignal subscribeNext:^(id x) { + valueCount++; + }]; + + [disposeSubject sendCompleted]; + expect(@(valueCount)).to(equal(@1)); + expect(@([[replayedSignal toArray] count])).to(equal(@(valueCount))); + }); +}); + +qck_describe(@"-reduceApply", ^{ + qck_it(@"should apply a block to the rest of a tuple", ^{ + RACSubject *subject = [RACReplaySubject subject]; + + id sum = ^(NSNumber *a, NSNumber *b) { + return @(a.intValue + b.intValue); + }; + id madd = ^(NSNumber *a, NSNumber *b, NSNumber *c) { + return @(a.intValue * b.intValue + c.intValue); + }; + + [subject sendNext:RACTuplePack(sum, @1, @2)]; + [subject sendNext:RACTuplePack(madd, @2, @3, @1)]; + [subject sendCompleted]; + + NSArray *results = [[subject reduceApply] toArray]; + NSArray *expected = @[ @3, @7 ]; + + expect(results).to(equal(expected)); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACStreamExamples.h b/ReactiveCocoaTests/RACStreamExamples.h new file mode 100644 index 0000000000..318a6a85e8 --- /dev/null +++ b/ReactiveCocoaTests/RACStreamExamples.h @@ -0,0 +1,26 @@ +// +// RACStreamExamples.h +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-01. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +// The name of the shared examples for a RACStream subclass. +extern NSString * const RACStreamExamples; + +// The RACStream subclass to test. +extern NSString * const RACStreamExamplesClass; + +// An infinite RACStream to test, making sure that certain operations +// terminate. +// +// The stream should contain infinite RACUnit values. +extern NSString * const RACStreamExamplesInfiniteStream; + +// A block with the signature: +// +// void (^)(RACStream *stream, NSArray *expectedValues) +// +// … used to verify that a stream contains the expected values. +extern NSString * const RACStreamExamplesVerifyValuesBlock; diff --git a/ReactiveCocoaTests/RACStreamExamples.m b/ReactiveCocoaTests/RACStreamExamples.m new file mode 100644 index 0000000000..beccc31422 --- /dev/null +++ b/ReactiveCocoaTests/RACStreamExamples.m @@ -0,0 +1,668 @@ +// +// RACStreamExamples.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-01. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACStreamExamples.h" + +#import "RACStream.h" +#import "RACUnit.h" +#import "RACTuple.h" + +NSString * const RACStreamExamples = @"RACStreamExamples"; +NSString * const RACStreamExamplesClass = @"RACStreamExamplesClass"; +NSString * const RACStreamExamplesInfiniteStream = @"RACStreamExamplesInfiniteStream"; +NSString * const RACStreamExamplesVerifyValuesBlock = @"RACStreamExamplesVerifyValuesBlock"; + +QuickSharedExampleGroupsBegin(RACStreamExampleGroups) + +qck_sharedExamples(RACStreamExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block Class streamClass; + __block void (^verifyValues)(RACStream *, NSArray *); + __block RACStream *infiniteStream; + + __block RACStream *(^streamWithValues)(NSArray *); + + qck_beforeEach(^{ + streamClass = exampleContext()[RACStreamExamplesClass]; + verifyValues = exampleContext()[RACStreamExamplesVerifyValuesBlock]; + infiniteStream = exampleContext()[RACStreamExamplesInfiniteStream]; + streamWithValues = [^(NSArray *values) { + RACStream *stream = [streamClass empty]; + + for (id value in values) { + stream = [stream concat:[streamClass return:value]]; + } + + return stream; + } copy]; + }); + + qck_it(@"should return an empty stream", ^{ + RACStream *stream = [streamClass empty]; + verifyValues(stream, @[]); + }); + + qck_it(@"should lift a value into a stream", ^{ + RACStream *stream = [streamClass return:RACUnit.defaultUnit]; + verifyValues(stream, @[ RACUnit.defaultUnit ]); + }); + + qck_describe(@"-concat:", ^{ + qck_it(@"should concatenate two streams", ^{ + RACStream *stream = [[streamClass return:@0] concat:[streamClass return:@1]]; + verifyValues(stream, @[ @0, @1 ]); + }); + + qck_it(@"should concatenate three streams", ^{ + RACStream *stream = [[[streamClass return:@0] concat:[streamClass return:@1]] concat:[streamClass return:@2]]; + verifyValues(stream, @[ @0, @1, @2 ]); + }); + + qck_it(@"should concatenate around an empty stream", ^{ + RACStream *stream = [[[streamClass return:@0] concat:[streamClass empty]] concat:[streamClass return:@2]]; + verifyValues(stream, @[ @0, @2 ]); + }); + }); + + qck_it(@"should flatten", ^{ + RACStream *stream = [[streamClass return:[streamClass return:RACUnit.defaultUnit]] flatten]; + verifyValues(stream, @[ RACUnit.defaultUnit ]); + }); + + qck_describe(@"-bind:", ^{ + qck_it(@"should return the result of binding a single value", ^{ + RACStream *stream = [[streamClass return:@0] bind:^{ + return ^(NSNumber *value, BOOL *stop) { + NSNumber *newValue = @(value.integerValue + 1); + return [streamClass return:newValue]; + }; + }]; + + verifyValues(stream, @[ @1 ]); + }); + + qck_it(@"should concatenate the result of binding multiple values", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1 ]); + RACStream *stream = [baseStream bind:^{ + return ^(NSNumber *value, BOOL *stop) { + NSNumber *newValue = @(value.integerValue + 1); + return [streamClass return:newValue]; + }; + }]; + + verifyValues(stream, @[ @1, @2 ]); + }); + + qck_it(@"should concatenate with an empty result from binding a value", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1, @2 ]); + RACStream *stream = [baseStream bind:^{ + return ^(NSNumber *value, BOOL *stop) { + if (value.integerValue == 1) return [streamClass empty]; + + NSNumber *newValue = @(value.integerValue + 1); + return [streamClass return:newValue]; + }; + }]; + + verifyValues(stream, @[ @1, @3 ]); + }); + + qck_it(@"should terminate immediately when returning nil", ^{ + RACStream *stream = [infiniteStream bind:^{ + return ^ id (id _, BOOL *stop) { + return nil; + }; + }]; + + verifyValues(stream, @[]); + }); + + qck_it(@"should terminate after one value when setting 'stop'", ^{ + RACStream *stream = [infiniteStream bind:^{ + return ^ id (id value, BOOL *stop) { + *stop = YES; + return [streamClass return:value]; + }; + }]; + + verifyValues(stream, @[ RACUnit.defaultUnit ]); + }); + + qck_it(@"should terminate immediately when returning nil and setting 'stop'", ^{ + RACStream *stream = [infiniteStream bind:^{ + return ^ id (id _, BOOL *stop) { + *stop = YES; + return nil; + }; + }]; + + verifyValues(stream, @[]); + }); + + qck_it(@"should be restartable even with block state", ^{ + NSArray *values = @[ @0, @1, @2 ]; + RACStream *baseStream = streamWithValues(values); + + RACStream *countingStream = [baseStream bind:^{ + __block NSUInteger counter = 0; + + return ^(id x, BOOL *stop) { + return [streamClass return:@(counter++)]; + }; + }]; + + verifyValues(countingStream, @[ @0, @1, @2 ]); + verifyValues(countingStream, @[ @0, @1, @2 ]); + }); + + qck_it(@"should be interleavable even with block state", ^{ + NSArray *values = @[ @0, @1, @2 ]; + RACStream *baseStream = streamWithValues(values); + + RACStream *countingStream = [baseStream bind:^{ + __block NSUInteger counter = 0; + + return ^(id x, BOOL *stop) { + return [streamClass return:@(counter++)]; + }; + }]; + + // Just so +zip:reduce: thinks this is a unique stream. + RACStream *anotherStream = [[streamClass empty] concat:countingStream]; + + RACStream *zipped = [streamClass zip:@[ countingStream, anotherStream ] reduce:^(NSNumber *v1, NSNumber *v2) { + return @(v1.integerValue + v2.integerValue); + }]; + + verifyValues(zipped, @[ @0, @2, @4 ]); + }); + }); + + qck_describe(@"-flattenMap:", ^{ + qck_it(@"should return a single mapped result", ^{ + RACStream *stream = [[streamClass return:@0] flattenMap:^(NSNumber *value) { + NSNumber *newValue = @(value.integerValue + 1); + return [streamClass return:newValue]; + }]; + + verifyValues(stream, @[ @1 ]); + }); + + qck_it(@"should concatenate the results of mapping multiple values", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1 ]); + RACStream *stream = [baseStream flattenMap:^(NSNumber *value) { + NSNumber *newValue = @(value.integerValue + 1); + return [streamClass return:newValue]; + }]; + + verifyValues(stream, @[ @1, @2 ]); + }); + + qck_it(@"should concatenate with an empty result from mapping a value", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1, @2 ]); + RACStream *stream = [baseStream flattenMap:^(NSNumber *value) { + if (value.integerValue == 1) return [streamClass empty]; + + NSNumber *newValue = @(value.integerValue + 1); + return [streamClass return:newValue]; + }]; + + verifyValues(stream, @[ @1, @3 ]); + }); + + qck_it(@"should treat nil streams like empty streams", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1, @2 ]); + RACStream *stream = [baseStream flattenMap:^ RACStream * (NSNumber *value) { + if (value.integerValue == 1) return nil; + + NSNumber *newValue = @(value.integerValue + 1); + return [streamClass return:newValue]; + }]; + + verifyValues(stream, @[ @1, @3 ]); + }); + }); + + qck_it(@"should map", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1, @2 ]); + RACStream *stream = [baseStream map:^(NSNumber *value) { + return @(value.integerValue + 1); + }]; + + verifyValues(stream, @[ @1, @2, @3 ]); + }); + + qck_it(@"should map and replace", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1, @2 ]); + RACStream *stream = [baseStream mapReplace:RACUnit.defaultUnit]; + + verifyValues(stream, @[ RACUnit.defaultUnit, RACUnit.defaultUnit, RACUnit.defaultUnit ]); + }); + + qck_it(@"should filter", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1, @2, @3, @4, @5, @6 ]); + RACStream *stream = [baseStream filter:^ BOOL (NSNumber *value) { + return value.integerValue % 2 == 0; + }]; + + verifyValues(stream, @[ @0, @2, @4, @6 ]); + }); + + qck_describe(@"-ignore:", ^{ + qck_it(@"should ignore a value", ^{ + RACStream *baseStream = streamWithValues(@[ @0, @1, @2, @3, @4, @5, @6 ]); + RACStream *stream = [baseStream ignore:@1]; + + verifyValues(stream, @[ @0, @2, @3, @4, @5, @6 ]); + }); + + qck_it(@"should ignore based on object equality", ^{ + RACStream *baseStream = streamWithValues(@[ @"0", @"1", @"2", @"3", @"4", @"5", @"6" ]); + + NSMutableString *valueToIgnore = [[NSMutableString alloc] init]; + [valueToIgnore appendString:@"1"]; + RACStream *stream = [baseStream ignore:valueToIgnore]; + + verifyValues(stream, @[ @"0", @"2", @"3", @"4", @"5", @"6" ]); + }); + }); + + qck_it(@"should start with a value", ^{ + RACStream *stream = [[streamClass return:@1] startWith:@0]; + verifyValues(stream, @[ @0, @1 ]); + }); + + qck_describe(@"-skip:", ^{ + __block NSArray *values; + __block RACStream *stream; + + qck_beforeEach(^{ + values = @[ @0, @1, @2 ]; + stream = streamWithValues(values); + }); + + qck_it(@"should skip any valid number of values", ^{ + for (NSUInteger i = 0; i < values.count; i++) { + verifyValues([stream skip:i], [values subarrayWithRange:NSMakeRange(i, values.count - i)]); + } + }); + + qck_it(@"should return an empty stream when skipping too many values", ^{ + verifyValues([stream skip:4], @[]); + }); + }); + + qck_describe(@"-take:", ^{ + qck_describe(@"with three values", ^{ + __block NSArray *values; + __block RACStream *stream; + + qck_beforeEach(^{ + values = @[ @0, @1, @2 ]; + stream = streamWithValues(values); + }); + + qck_it(@"should take any valid number of values", ^{ + for (NSUInteger i = 0; i < values.count; i++) { + verifyValues([stream take:i], [values subarrayWithRange:NSMakeRange(0, i)]); + } + }); + + qck_it(@"should return the same stream when taking too many values", ^{ + verifyValues([stream take:4], values); + }); + }); + + qck_it(@"should take and terminate from an infinite stream", ^{ + verifyValues([infiniteStream take:0], @[]); + verifyValues([infiniteStream take:1], @[ RACUnit.defaultUnit ]); + verifyValues([infiniteStream take:2], @[ RACUnit.defaultUnit, RACUnit.defaultUnit ]); + }); + + qck_it(@"should take and terminate from a single-item stream", ^{ + NSArray *values = @[ RACUnit.defaultUnit ]; + RACStream *stream = streamWithValues(values); + verifyValues([stream take:1], values); + }); + }); + + qck_describe(@"zip stream creation methods", ^{ + __block NSArray *valuesOne; + + __block RACStream *streamOne; + __block RACStream *streamTwo; + __block RACStream *streamThree; + __block NSArray *threeStreams; + + __block NSArray *oneStreamTuples; + __block NSArray *twoStreamTuples; + __block NSArray *threeStreamTuples; + + qck_beforeEach(^{ + valuesOne = @[ @"Ada", @"Bob", @"Dea" ]; + NSArray *valuesTwo = @[ @"eats", @"cooks", @"jumps" ]; + NSArray *valuesThree = @[ @"fish", @"bear", @"rock" ]; + + streamOne = streamWithValues(valuesOne); + streamTwo = streamWithValues(valuesTwo); + streamThree = streamWithValues(valuesThree); + threeStreams = @[ streamOne, streamTwo, streamThree ]; + + oneStreamTuples = @[ + RACTuplePack(valuesOne[0]), + RACTuplePack(valuesOne[1]), + RACTuplePack(valuesOne[2]), + ]; + + twoStreamTuples = @[ + RACTuplePack(valuesOne[0], valuesTwo[0]), + RACTuplePack(valuesOne[1], valuesTwo[1]), + RACTuplePack(valuesOne[2], valuesTwo[2]), + ]; + + threeStreamTuples = @[ + RACTuplePack(valuesOne[0], valuesTwo[0], valuesThree[0]), + RACTuplePack(valuesOne[1], valuesTwo[1], valuesThree[1]), + RACTuplePack(valuesOne[2], valuesTwo[2], valuesThree[2]), + ]; + }); + + qck_describe(@"-zipWith:", ^{ + qck_it(@"should make a stream of tuples", ^{ + RACStream *stream = [streamOne zipWith:streamTwo]; + verifyValues(stream, twoStreamTuples); + }); + + qck_it(@"should truncate streams", ^{ + RACStream *shortStream = streamWithValues(@[ @"now", @"later" ]); + RACStream *stream = [streamOne zipWith:shortStream]; + + verifyValues(stream, @[ + RACTuplePack(valuesOne[0], @"now"), + RACTuplePack(valuesOne[1], @"later") + ]); + }); + + qck_it(@"should work on infinite streams", ^{ + RACStream *stream = [streamOne zipWith:infiniteStream]; + verifyValues(stream, @[ + RACTuplePack(valuesOne[0], RACUnit.defaultUnit), + RACTuplePack(valuesOne[1], RACUnit.defaultUnit), + RACTuplePack(valuesOne[2], RACUnit.defaultUnit) + ]); + }); + + qck_it(@"should handle multiples of the same stream", ^{ + RACStream *stream = [streamOne zipWith:streamOne]; + verifyValues(stream, @[ + RACTuplePack(valuesOne[0], valuesOne[0]), + RACTuplePack(valuesOne[1], valuesOne[1]), + RACTuplePack(valuesOne[2], valuesOne[2]), + ]); + }); + }); + + qck_describe(@"+zip:reduce:", ^{ + qck_it(@"should reduce values", ^{ + RACStream *stream = [streamClass zip:threeStreams reduce:^ NSString * (id x, id y, id z) { + return [NSString stringWithFormat:@"%@ %@ %@", x, y, z]; + }]; + verifyValues(stream, @[ @"Ada eats fish", @"Bob cooks bear", @"Dea jumps rock" ]); + }); + + qck_it(@"should truncate streams", ^{ + RACStream *shortStream = streamWithValues(@[ @"now", @"later" ]); + NSArray *streams = [threeStreams arrayByAddingObject:shortStream]; + RACStream *stream = [streamClass zip:streams reduce:^ NSString * (id w, id x, id y, id z) { + return [NSString stringWithFormat:@"%@ %@ %@ %@", w, x, y, z]; + }]; + verifyValues(stream, @[ @"Ada eats fish now", @"Bob cooks bear later" ]); + }); + + qck_it(@"should work on infinite streams", ^{ + NSArray *streams = [threeStreams arrayByAddingObject:infiniteStream]; + RACStream *stream = [streamClass zip:streams reduce:^ NSString * (id w, id x, id y, id z) { + return [NSString stringWithFormat:@"%@ %@ %@", w, x, y]; + }]; + verifyValues(stream, @[ @"Ada eats fish", @"Bob cooks bear", @"Dea jumps rock" ]); + }); + + qck_it(@"should handle multiples of the same stream", ^{ + NSArray *streams = @[ streamOne, streamOne, streamTwo, streamThree, streamTwo, streamThree ]; + RACStream *stream = [streamClass zip:streams reduce:^ NSString * (id x1, id x2, id y1, id z1, id y2, id z2) { + return [NSString stringWithFormat:@"%@ %@ %@ %@ %@ %@", x1, x2, y1, z1, y2, z2]; + }]; + verifyValues(stream, @[ @"Ada Ada eats fish eats fish", @"Bob Bob cooks bear cooks bear", @"Dea Dea jumps rock jumps rock" ]); + }); + }); + + qck_describe(@"+zip:", ^{ + qck_it(@"should make a stream of tuples out of single value", ^{ + RACStream *stream = [streamClass zip:@[ streamOne ]]; + verifyValues(stream, oneStreamTuples); + }); + + qck_it(@"should make a stream of tuples out of an array of streams", ^{ + RACStream *stream = [streamClass zip:threeStreams]; + verifyValues(stream, threeStreamTuples); + }); + + qck_it(@"should make an empty stream if given an empty array", ^{ + RACStream *stream = [streamClass zip:@[]]; + verifyValues(stream, @[]); + }); + + qck_it(@"should make a stream of tuples out of an enumerator of streams", ^{ + RACStream *stream = [streamClass zip:threeStreams.objectEnumerator]; + verifyValues(stream, threeStreamTuples); + }); + + qck_it(@"should make an empty stream if given an empty enumerator", ^{ + RACStream *stream = [streamClass zip:@[].objectEnumerator]; + verifyValues(stream, @[]); + }); + }); + }); + + qck_describe(@"+concat:", ^{ + __block NSArray *streams = nil; + __block NSArray *result = nil; + + qck_beforeEach(^{ + RACStream *a = [streamClass return:@0]; + RACStream *b = [streamClass empty]; + RACStream *c = streamWithValues(@[ @1, @2, @3 ]); + RACStream *d = [streamClass return:@4]; + RACStream *e = [streamClass return:@5]; + RACStream *f = [streamClass empty]; + RACStream *g = [streamClass empty]; + RACStream *h = streamWithValues(@[ @6, @7 ]); + streams = @[ a, b, c, d, e, f, g, h ]; + result = @[ @0, @1, @2, @3, @4, @5, @6, @7 ]; + }); + + qck_it(@"should concatenate an array of streams", ^{ + RACStream *stream = [streamClass concat:streams]; + verifyValues(stream, result); + }); + + qck_it(@"should concatenate an enumerator of streams", ^{ + RACStream *stream = [streamClass concat:streams.objectEnumerator]; + verifyValues(stream, result); + }); + }); + + qck_describe(@"scanning", ^{ + NSArray *values = @[ @1, @2, @3, @4 ]; + + __block RACStream *stream; + + qck_beforeEach(^{ + stream = streamWithValues(values); + }); + + qck_it(@"should scan", ^{ + RACStream *scanned = [stream scanWithStart:@0 reduce:^(NSNumber *running, NSNumber *next) { + return @(running.integerValue + next.integerValue); + }]; + + verifyValues(scanned, @[ @1, @3, @6, @10 ]); + }); + + qck_it(@"should scan with index", ^{ + RACStream *scanned = [stream scanWithStart:@0 reduceWithIndex:^(NSNumber *running, NSNumber *next, NSUInteger index) { + return @(running.integerValue + next.integerValue + (NSInteger)index); + }]; + + verifyValues(scanned, @[ @1, @4, @9, @16 ]); + }); + }); + + qck_describe(@"taking with a predicate", ^{ + NSArray *values = @[ @0, @1, @2, @3, @0, @2, @4 ]; + + __block RACStream *stream; + + qck_beforeEach(^{ + stream = streamWithValues(values); + }); + + qck_it(@"should take until a predicate is true", ^{ + RACStream *taken = [stream takeUntilBlock:^ BOOL (NSNumber *x) { + return x.integerValue >= 3; + }]; + + verifyValues(taken, @[ @0, @1, @2 ]); + }); + + qck_it(@"should take while a predicate is true", ^{ + RACStream *taken = [stream takeWhileBlock:^ BOOL (NSNumber *x) { + return x.integerValue <= 1; + }]; + + verifyValues(taken, @[ @0, @1 ]); + }); + + qck_it(@"should take a full stream", ^{ + RACStream *taken = [stream takeWhileBlock:^ BOOL (NSNumber *x) { + return x.integerValue <= 10; + }]; + + verifyValues(taken, values); + }); + + qck_it(@"should return an empty stream", ^{ + RACStream *taken = [stream takeWhileBlock:^ BOOL (NSNumber *x) { + return x.integerValue < 0; + }]; + + verifyValues(taken, @[]); + }); + + qck_it(@"should terminate an infinite stream", ^{ + RACStream *infiniteCounter = [infiniteStream scanWithStart:@0 reduce:^(NSNumber *running, id _) { + return @(running.unsignedIntegerValue + 1); + }]; + + RACStream *taken = [infiniteCounter takeWhileBlock:^ BOOL (NSNumber *x) { + return x.integerValue <= 5; + }]; + + verifyValues(taken, @[ @1, @2, @3, @4, @5 ]); + }); + }); + + qck_describe(@"skipping with a predicate", ^{ + NSArray *values = @[ @0, @1, @2, @3, @0, @2, @4 ]; + + __block RACStream *stream; + + qck_beforeEach(^{ + stream = streamWithValues(values); + }); + + qck_it(@"should skip until a predicate is true", ^{ + RACStream *taken = [stream skipUntilBlock:^ BOOL (NSNumber *x) { + return x.integerValue >= 3; + }]; + + verifyValues(taken, @[ @3, @0, @2, @4 ]); + }); + + qck_it(@"should skip while a predicate is true", ^{ + RACStream *taken = [stream skipWhileBlock:^ BOOL (NSNumber *x) { + return x.integerValue <= 1; + }]; + + verifyValues(taken, @[ @2, @3, @0, @2, @4 ]); + }); + + qck_it(@"should skip a full stream", ^{ + RACStream *taken = [stream skipWhileBlock:^ BOOL (NSNumber *x) { + return x.integerValue <= 10; + }]; + + verifyValues(taken, @[]); + }); + + qck_it(@"should finish skipping immediately", ^{ + RACStream *taken = [stream skipWhileBlock:^ BOOL (NSNumber *x) { + return x.integerValue < 0; + }]; + + verifyValues(taken, values); + }); + }); + + qck_describe(@"-combinePreviousWithStart:reduce:", ^{ + NSArray *values = @[ @1, @2, @3 ]; + __block RACStream *stream; + qck_beforeEach(^{ + stream = streamWithValues(values); + }); + + qck_it(@"should pass the previous next into the reduce block", ^{ + NSMutableArray *previouses = [NSMutableArray array]; + RACStream *mapped = [stream combinePreviousWithStart:nil reduce:^(id previous, id next) { + [previouses addObject:previous ?: RACTupleNil.tupleNil]; + return next; + }]; + + verifyValues(mapped, @[ @1, @2, @3 ]); + + NSArray *expected = @[ RACTupleNil.tupleNil, @1, @2 ]; + expect(previouses).to(equal(expected)); + }); + + qck_it(@"should send the combined value", ^{ + RACStream *mapped = [stream combinePreviousWithStart:@1 reduce:^(NSNumber *previous, NSNumber *next) { + return [NSString stringWithFormat:@"%lu - %lu", (unsigned long)previous.unsignedIntegerValue, (unsigned long)next.unsignedIntegerValue]; + }]; + + verifyValues(mapped, @[ @"1 - 1", @"1 - 2", @"2 - 3" ]); + }); + }); + + qck_it(@"should reduce tuples", ^{ + RACStream *stream = streamWithValues(@[ + RACTuplePack(@"foo", @"bar"), + RACTuplePack(@"buzz", @"baz"), + RACTuplePack(@"", @"_") + ]); + + RACStream *reduced = [stream reduceEach:^(NSString *a, NSString *b) { + return [a stringByAppendingString:b]; + }]; + + verifyValues(reduced, @[ @"foobar", @"buzzbaz", @"_" ]); + }); +}); + +QuickSharedExampleGroupsEnd diff --git a/ReactiveCocoaTests/RACSubclassObject.h b/ReactiveCocoaTests/RACSubclassObject.h new file mode 100644 index 0000000000..062caffb88 --- /dev/null +++ b/ReactiveCocoaTests/RACSubclassObject.h @@ -0,0 +1,26 @@ +// +// RACSubclassObject.h +// ReactiveCocoa +// +// Created by Josh Abernathy on 3/18/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTestObject.h" + +@interface RACSubclassObject : RACTestObject + +// Set whenever -forwardInvocation: is invoked on the receiver. +@property (nonatomic, assign) SEL forwardedSelector; + +// Invokes the superclass implementation with `objectValue` concatenated to +// "SUBCLASS". +- (NSString *)combineObjectValue:(id)objectValue andIntegerValue:(NSInteger)integerValue; + +// Asynchronously invokes the superclass implementation on the current scheduler. +- (void)setObjectValue:(id)objectValue andSecondObjectValue:(id)secondObjectValue; + +@end diff --git a/ReactiveCocoaTests/RACSubclassObject.m b/ReactiveCocoaTests/RACSubclassObject.m new file mode 100644 index 0000000000..41e61f7d64 --- /dev/null +++ b/ReactiveCocoaTests/RACSubclassObject.m @@ -0,0 +1,38 @@ +// +// RACSubclassObject.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 3/18/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import "RACSubclassObject.h" +#import "RACScheduler.h" + +@implementation RACSubclassObject + +- (void)forwardInvocation:(NSInvocation *)invocation { + self.forwardedSelector = invocation.selector; +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { + NSParameterAssert(selector != NULL); + + NSMethodSignature *signature = [super methodSignatureForSelector:selector]; + if (signature != nil) return signature; + + return [super methodSignatureForSelector:@selector(description)]; +} + +- (NSString *)combineObjectValue:(id)objectValue andIntegerValue:(NSInteger)integerValue { + NSString *appended = [[objectValue description] stringByAppendingString:@"SUBCLASS"]; + return [super combineObjectValue:appended andIntegerValue:integerValue]; +} + +- (void)setObjectValue:(id)objectValue andSecondObjectValue:(id)secondObjectValue { + [RACScheduler.currentScheduler schedule:^{ + [super setObjectValue:objectValue andSecondObjectValue:secondObjectValue]; + }]; +} + +@end diff --git a/ReactiveCocoaTests/RACSubjectSpec.m b/ReactiveCocoaTests/RACSubjectSpec.m new file mode 100644 index 0000000000..ab3ec68085 --- /dev/null +++ b/ReactiveCocoaTests/RACSubjectSpec.m @@ -0,0 +1,334 @@ +// +// RACSubjectSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 6/24/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSubscriberExamples.h" + +#import +#import "EXTScope.h" +#import "RACBehaviorSubject.h" +#import "RACDisposable.h" +#import "RACReplaySubject.h" +#import "RACScheduler.h" +#import "RACSignal+Operations.h" +#import "RACSubject.h" +#import "RACUnit.h" + +QuickSpecBegin(RACSubjectSpec) + +qck_describe(@"RACSubject", ^{ + __block RACSubject *subject; + __block NSMutableArray *values; + + __block BOOL success; + __block NSError *error; + + qck_beforeEach(^{ + values = [NSMutableArray array]; + + subject = [RACSubject subject]; + success = YES; + error = nil; + + [subject subscribeNext:^(id value) { + [values addObject:value]; + } error:^(NSError *e) { + error = e; + success = NO; + } completed:^{ + success = YES; + }]; + }); + + qck_itBehavesLike(RACSubscriberExamples, ^{ + return @{ + RACSubscriberExampleSubscriber: subject, + RACSubscriberExampleValuesReceivedBlock: [^{ return [values copy]; } copy], + RACSubscriberExampleErrorReceivedBlock: [^{ return error; } copy], + RACSubscriberExampleSuccessBlock: [^{ return success; } copy] + }; + }); +}); + +qck_describe(@"RACReplaySubject", ^{ + __block RACReplaySubject *subject = nil; + + qck_describe(@"with a capacity of 1", ^{ + qck_beforeEach(^{ + subject = [RACReplaySubject replaySubjectWithCapacity:1]; + }); + + qck_it(@"should send the last value", ^{ + id firstValue = @"blah"; + id secondValue = @"more blah"; + + [subject sendNext:firstValue]; + [subject sendNext:secondValue]; + + __block id valueReceived = nil; + [subject subscribeNext:^(id x) { + valueReceived = x; + }]; + + expect(valueReceived).to(equal(secondValue)); + }); + + qck_it(@"should send the last value to new subscribers after completion", ^{ + id firstValue = @"blah"; + id secondValue = @"more blah"; + + __block id valueReceived = nil; + __block NSUInteger nextsReceived = 0; + + [subject sendNext:firstValue]; + [subject sendNext:secondValue]; + + expect(@(nextsReceived)).to(equal(@0)); + expect(valueReceived).to(beNil()); + + [subject sendCompleted]; + + [subject subscribeNext:^(id x) { + valueReceived = x; + nextsReceived++; + }]; + + expect(@(nextsReceived)).to(equal(@1)); + expect(valueReceived).to(equal(secondValue)); + }); + + qck_it(@"should not send any values to new subscribers if none were sent originally", ^{ + [subject sendCompleted]; + + __block BOOL nextInvoked = NO; + [subject subscribeNext:^(id x) { + nextInvoked = YES; + }]; + + expect(@(nextInvoked)).to(beFalsy()); + }); + + qck_it(@"should resend errors", ^{ + NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:nil]; + [subject sendError:error]; + + __block BOOL errorSent = NO; + [subject subscribeError:^(NSError *sentError) { + expect(sentError).to(equal(error)); + errorSent = YES; + }]; + + expect(@(errorSent)).to(beTruthy()); + }); + + qck_it(@"should resend nil errors", ^{ + [subject sendError:nil]; + + __block BOOL errorSent = NO; + [subject subscribeError:^(NSError *sentError) { + expect(sentError).to(beNil()); + errorSent = YES; + }]; + + expect(@(errorSent)).to(beTruthy()); + }); + }); + + qck_describe(@"with an unlimited capacity", ^{ + qck_beforeEach(^{ + subject = [RACReplaySubject subject]; + }); + + qck_itBehavesLike(RACSubscriberExamples, ^{ + return @{ + RACSubscriberExampleSubscriber: subject, + RACSubscriberExampleValuesReceivedBlock: [^{ + NSMutableArray *values = [NSMutableArray array]; + + // This subscription should synchronously dump all values already + // received into 'values'. + [subject subscribeNext:^(id value) { + [values addObject:value]; + }]; + + return values; + } copy], + RACSubscriberExampleErrorReceivedBlock: [^{ + __block NSError *error = nil; + + [subject subscribeError:^(NSError *x) { + error = x; + }]; + + return error; + } copy], + RACSubscriberExampleSuccessBlock: [^{ + __block BOOL success = YES; + + [subject subscribeError:^(NSError *x) { + success = NO; + }]; + + return success; + } copy] + }; + }); + + qck_it(@"should send both values to new subscribers after completion", ^{ + id firstValue = @"blah"; + id secondValue = @"more blah"; + + [subject sendNext:firstValue]; + [subject sendNext:secondValue]; + [subject sendCompleted]; + + __block BOOL completed = NO; + NSMutableArray *valuesReceived = [NSMutableArray array]; + [subject subscribeNext:^(id x) { + [valuesReceived addObject:x]; + } completed:^{ + completed = YES; + }]; + + expect(@(valuesReceived.count)).to(equal(@2)); + NSArray *expected = [NSArray arrayWithObjects:firstValue, secondValue, nil]; + expect(valuesReceived).to(equal(expected)); + expect(@(completed)).to(beTruthy()); + }); + + qck_it(@"should send values in the same order live as when replaying", ^{ + NSUInteger count = 49317; + + // Just leak it, ain't no thang. + __unsafe_unretained volatile id *values = (__unsafe_unretained id *)calloc(count, sizeof(*values)); + __block volatile int32_t nextIndex = 0; + + [subject subscribeNext:^(NSNumber *value) { + int32_t indexPlusOne = OSAtomicIncrement32(&nextIndex); + values[indexPlusOne - 1] = value; + }]; + + dispatch_queue_t queue = dispatch_queue_create("com.github.ReactiveCocoa.RACSubjectSpec", DISPATCH_QUEUE_CONCURRENT); + dispatch_suspend(queue); + + for (NSUInteger i = 0; i < count; i++) { + dispatch_async(queue, ^{ + [subject sendNext:@(i)]; + }); + } + + dispatch_resume(queue); + dispatch_barrier_sync(queue, ^{ + [subject sendCompleted]; + }); + + OSMemoryBarrier(); + + NSArray *liveValues = [NSArray arrayWithObjects:(id *)values count:(NSUInteger)nextIndex]; + expect(@(liveValues.count)).to(equal(@(count))); + + NSArray *replayedValues = subject.toArray; + expect(@(replayedValues.count)).to(equal(@(count))); + + // It should return the same ordering for multiple invocations too. + expect(replayedValues).to(equal(subject.toArray)); + + [replayedValues enumerateObjectsUsingBlock:^(id value, NSUInteger index, BOOL *stop) { + expect(liveValues[index]).to(equal(value)); + }]; + }); + + qck_it(@"should have a current scheduler when replaying", ^{ + [subject sendNext:RACUnit.defaultUnit]; + + __block RACScheduler *currentScheduler; + [subject subscribeNext:^(id x) { + currentScheduler = RACScheduler.currentScheduler; + }]; + + expect(currentScheduler).notTo(beNil()); + + currentScheduler = nil; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [subject subscribeNext:^(id x) { + currentScheduler = RACScheduler.currentScheduler; + }]; + }); + + expect(currentScheduler).toEventuallyNot(beNil()); + }); + + qck_it(@"should stop replaying when the subscription is disposed", ^{ + NSMutableArray *values = [NSMutableArray array]; + + [subject sendNext:@0]; + [subject sendNext:@1]; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + __block RACDisposable *disposable = [subject subscribeNext:^(id x) { + expect(disposable).notTo(beNil()); + + [values addObject:x]; + [disposable dispose]; + }]; + }); + + expect(values).toEventually(equal(@[ @0 ])); + }); + + qck_it(@"should finish replaying before completing", ^{ + [subject sendNext:@1]; + + __block id received; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [subject subscribeNext:^(id x) { + received = x; + }]; + + [subject sendCompleted]; + }); + + expect(received).toEventually(equal(@1)); + }); + + qck_it(@"should finish replaying before erroring", ^{ + [subject sendNext:@1]; + + __block id received; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [subject subscribeNext:^(id x) { + received = x; + }]; + + [subject sendError:[NSError errorWithDomain:@"blah" code:-99 userInfo:nil]]; + }); + + expect(received).toEventually(equal(@1)); + }); + + qck_it(@"should finish replaying before sending new values", ^{ + [subject sendNext:@1]; + + NSMutableArray *received = [NSMutableArray array]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [subject subscribeNext:^(id x) { + [received addObject:x]; + }]; + + [subject sendNext:@2]; + }); + + NSArray *expected = @[ @1, @2 ]; + expect(received).toEventually(equal(expected)); + }); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACSubscriberExamples.h b/ReactiveCocoaTests/RACSubscriberExamples.h new file mode 100644 index 0000000000..edc9e5abf9 --- /dev/null +++ b/ReactiveCocoaTests/RACSubscriberExamples.h @@ -0,0 +1,23 @@ +// +// RACSubscriberExamples.h +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-27. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +// The name of the shared examples for implementors of . +extern NSString * const RACSubscriberExamples; + +// id +extern NSString * const RACSubscriberExampleSubscriber; + +// A block which returns an NSArray of the values received so far. +extern NSString * const RACSubscriberExampleValuesReceivedBlock; + +// A block which returns any NSError received so far. +extern NSString * const RACSubscriberExampleErrorReceivedBlock; + +// A block which returns a BOOL indicating whether the subscriber is successful +// so far. +extern NSString * const RACSubscriberExampleSuccessBlock; diff --git a/ReactiveCocoaTests/RACSubscriberExamples.m b/ReactiveCocoaTests/RACSubscriberExamples.m new file mode 100644 index 0000000000..cdc5031aff --- /dev/null +++ b/ReactiveCocoaTests/RACSubscriberExamples.m @@ -0,0 +1,188 @@ +// +// RACSubscriberExamples.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-27. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSubscriberExamples.h" + +#import "NSObject+RACDeallocating.h" +#import "RACCompoundDisposable.h" +#import "RACDisposable.h" +#import "RACSubject.h" +#import "RACSubscriber.h" + +NSString * const RACSubscriberExamples = @"RACSubscriberExamples"; +NSString * const RACSubscriberExampleSubscriber = @"RACSubscriberExampleSubscriber"; +NSString * const RACSubscriberExampleValuesReceivedBlock = @"RACSubscriberExampleValuesReceivedBlock"; +NSString * const RACSubscriberExampleErrorReceivedBlock = @"RACSubscriberExampleErrorReceivedBlock"; +NSString * const RACSubscriberExampleSuccessBlock = @"RACSubscriberExampleSuccessBlock"; + +QuickSharedExampleGroupsBegin(RACSubscriberExampleGroups) + +qck_sharedExamples(RACSubscriberExamples, ^(QCKDSLSharedExampleContext exampleContext) { + __block NSArray * (^valuesReceived)(void); + __block NSError * (^errorReceived)(void); + __block BOOL (^success)(void); + __block id subscriber; + + qck_beforeEach(^{ + valuesReceived = exampleContext()[RACSubscriberExampleValuesReceivedBlock]; + errorReceived = exampleContext()[RACSubscriberExampleErrorReceivedBlock]; + success = exampleContext()[RACSubscriberExampleSuccessBlock]; + subscriber = exampleContext()[RACSubscriberExampleSubscriber]; + expect(subscriber).notTo(beNil()); + }); + + qck_it(@"should accept a nil error", ^{ + [subscriber sendError:nil]; + + expect(@(success())).to(beFalsy()); + expect(errorReceived()).to(beNil()); + expect(valuesReceived()).to(equal(@[])); + }); + + qck_describe(@"with values", ^{ + __block NSSet *values; + + qck_beforeEach(^{ + NSMutableSet *mutableValues = [NSMutableSet set]; + for (NSUInteger i = 0; i < 20; i++) { + [mutableValues addObject:@(i)]; + } + + values = [mutableValues copy]; + }); + + qck_it(@"should send nexts serially, even when delivered from multiple threads", ^{ + NSArray *allValues = values.allObjects; + dispatch_apply(allValues.count, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), [^(size_t index) { + [subscriber sendNext:allValues[index]]; + } copy]); + + expect(@(success())).to(beTruthy()); + expect(errorReceived()).to(beNil()); + + NSSet *valuesReceivedSet = [NSSet setWithArray:valuesReceived()]; + expect(valuesReceivedSet).to(equal(values)); + }); + }); + + qck_describe(@"multiple subscriptions", ^{ + __block RACSubject *first; + __block RACSubject *second; + + qck_beforeEach(^{ + first = [RACSubject subject]; + [first subscribe:subscriber]; + + second = [RACSubject subject]; + [second subscribe:subscriber]; + }); + + qck_it(@"should send values from all subscriptions", ^{ + [first sendNext:@"foo"]; + [second sendNext:@"bar"]; + [first sendNext:@"buzz"]; + [second sendNext:@"baz"]; + + expect(@(success())).to(beTruthy()); + expect(errorReceived()).to(beNil()); + + NSArray *expected = @[ @"foo", @"bar", @"buzz", @"baz" ]; + expect(valuesReceived()).to(equal(expected)); + }); + + qck_it(@"should terminate after the first error from any subscription", ^{ + NSError *error = [NSError errorWithDomain:@"" code:-1 userInfo:nil]; + + [first sendNext:@"foo"]; + [second sendError:error]; + [first sendNext:@"buzz"]; + + expect(@(success())).to(beFalsy()); + expect(errorReceived()).to(equal(error)); + + NSArray *expected = @[ @"foo" ]; + expect(valuesReceived()).to(equal(expected)); + }); + + qck_it(@"should terminate after the first completed from any subscription", ^{ + [first sendNext:@"foo"]; + [second sendNext:@"bar"]; + [first sendCompleted]; + [second sendNext:@"baz"]; + + expect(@(success())).to(beTruthy()); + expect(errorReceived()).to(beNil()); + + NSArray *expected = @[ @"foo", @"bar" ]; + expect(valuesReceived()).to(equal(expected)); + }); + + qck_it(@"should dispose of all current subscriptions upon termination", ^{ + __block BOOL firstDisposed = NO; + RACSignal *firstDisposableSignal = [RACSignal createSignal:^(id subscriber) { + return [RACDisposable disposableWithBlock:^{ + firstDisposed = YES; + }]; + }]; + + __block BOOL secondDisposed = NO; + RACSignal *secondDisposableSignal = [RACSignal createSignal:^(id subscriber) { + return [RACDisposable disposableWithBlock:^{ + secondDisposed = YES; + }]; + }]; + + [firstDisposableSignal subscribe:subscriber]; + [secondDisposableSignal subscribe:subscriber]; + + expect(@(firstDisposed)).to(beFalsy()); + expect(@(secondDisposed)).to(beFalsy()); + + [first sendCompleted]; + + expect(@(firstDisposed)).to(beTruthy()); + expect(@(secondDisposed)).to(beTruthy()); + }); + + qck_it(@"should dispose of future subscriptions upon termination", ^{ + __block BOOL disposed = NO; + RACSignal *disposableSignal = [RACSignal createSignal:^(id subscriber) { + return [RACDisposable disposableWithBlock:^{ + disposed = YES; + }]; + }]; + + [first sendCompleted]; + expect(@(disposed)).to(beFalsy()); + + [disposableSignal subscribe:subscriber]; + expect(@(disposed)).to(beTruthy()); + }); + }); + + qck_describe(@"memory management", ^{ + qck_it(@"should not retain disposed disposables", ^{ + __block BOOL disposableDeallocd = NO; + @autoreleasepool { + RACCompoundDisposable *disposable __attribute__((objc_precise_lifetime)) = [RACCompoundDisposable disposableWithBlock:^{}]; + [disposable.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{ + disposableDeallocd = YES; + }]]; + + [subscriber didSubscribeWithDisposable:disposable]; + [disposable dispose]; + } + expect(@(disposableDeallocd)).to(beTruthy()); + }); + }); +}); + +QuickSharedExampleGroupsEnd diff --git a/ReactiveCocoaTests/RACSubscriberSpec.m b/ReactiveCocoaTests/RACSubscriberSpec.m new file mode 100644 index 0000000000..20a58ddf2f --- /dev/null +++ b/ReactiveCocoaTests/RACSubscriberSpec.m @@ -0,0 +1,130 @@ +// +// RACSubscriberSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-11-27. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSubscriberExamples.h" + +#import "RACSubscriber.h" +#import "RACSubscriber+Private.h" +#import + +QuickSpecBegin(RACSubscriberSpec) + +__block RACSubscriber *subscriber; +__block NSMutableArray *values; + +__block volatile BOOL finished; +__block volatile int32_t nextsAfterFinished; + +__block BOOL success; +__block NSError *error; + +qck_beforeEach(^{ + values = [NSMutableArray array]; + + finished = NO; + nextsAfterFinished = 0; + + success = YES; + error = nil; + + subscriber = [RACSubscriber subscriberWithNext:^(id value) { + if (finished) OSAtomicIncrement32Barrier(&nextsAfterFinished); + + [values addObject:value]; + } error:^(NSError *e) { + error = e; + success = NO; + } completed:^{ + success = YES; + }]; +}); + +qck_itBehavesLike(RACSubscriberExamples, ^{ + return @{ + RACSubscriberExampleSubscriber: subscriber, + RACSubscriberExampleValuesReceivedBlock: [^{ return [values copy]; } copy], + RACSubscriberExampleErrorReceivedBlock: [^{ return error; } copy], + RACSubscriberExampleSuccessBlock: [^{ return success; } copy] + }; +}); + +qck_describe(@"finishing", ^{ + __block void (^sendValues)(void); + __block BOOL expectedSuccess; + + __block dispatch_group_t dispatchGroup; + __block dispatch_queue_t concurrentQueue; + + qck_beforeEach(^{ + dispatchGroup = dispatch_group_create(); + expect(dispatchGroup).notTo(beNil()); + + concurrentQueue = dispatch_queue_create("com.github.ReactiveCocoa.RACSubscriberSpec", DISPATCH_QUEUE_CONCURRENT); + expect(concurrentQueue).notTo(beNil()); + + dispatch_suspend(concurrentQueue); + + sendValues = [^{ + for (NSUInteger i = 0; i < 15; i++) { + dispatch_group_async(dispatchGroup, concurrentQueue, ^{ + [subscriber sendNext:@(i)]; + }); + } + } copy]; + + sendValues(); + }); + + qck_afterEach(^{ + sendValues(); + dispatch_resume(concurrentQueue); + + // Time out after one second. + dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)); + expect(@(dispatch_group_wait(dispatchGroup, time))).to(equal(@0)); + + dispatchGroup = NULL; + concurrentQueue = NULL; + + expect(@(nextsAfterFinished)).to(equal(@0)); + + if (expectedSuccess) { + expect(@(success)).to(beTruthy()); + expect(error).to(beNil()); + } else { + expect(@(success)).to(beFalsy()); + } + }); + + qck_it(@"should never invoke next after sending completed", ^{ + expectedSuccess = YES; + + dispatch_group_async(dispatchGroup, concurrentQueue, ^{ + [subscriber sendCompleted]; + + finished = YES; + OSMemoryBarrier(); + }); + }); + + qck_it(@"should never invoke next after sending error", ^{ + expectedSuccess = NO; + + dispatch_group_async(dispatchGroup, concurrentQueue, ^{ + [subscriber sendError:nil]; + + finished = YES; + OSMemoryBarrier(); + }); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACSubscriptingAssignmentTrampolineSpec.m b/ReactiveCocoaTests/RACSubscriptingAssignmentTrampolineSpec.m new file mode 100644 index 0000000000..e83d02bcad --- /dev/null +++ b/ReactiveCocoaTests/RACSubscriptingAssignmentTrampolineSpec.m @@ -0,0 +1,36 @@ +// +// RACSubscriptingAssignmentTrampolineSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 9/24/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSubscriptingAssignmentTrampoline.h" +#import "RACPropertySignalExamples.h" +#import "RACTestObject.h" +#import "RACSubject.h" + +QuickSpecBegin(RACSubscriptingAssignmentTrampolineSpec) + +id setupBlock = ^(RACTestObject *testObject, NSString *keyPath, id nilValue, RACSignal *signal) { + [[RACSubscriptingAssignmentTrampoline alloc] initWithTarget:testObject nilValue:nilValue][keyPath] = signal; +}; + +qck_itBehavesLike(RACPropertySignalExamples, ^{ + return @{ RACPropertySignalExamplesSetupBlock: setupBlock }; +}); + +qck_it(@"should expand the RAC macro properly", ^{ + RACSubject *subject = [RACSubject subject]; + RACTestObject *testObject = [[RACTestObject alloc] init]; + RAC(testObject, objectValue) = subject; + + [subject sendNext:@1]; + expect(testObject.objectValue).to(equal(@1)); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACTargetQueueSchedulerSpec.m b/ReactiveCocoaTests/RACTargetQueueSchedulerSpec.m new file mode 100644 index 0000000000..cdf0b9663c --- /dev/null +++ b/ReactiveCocoaTests/RACTargetQueueSchedulerSpec.m @@ -0,0 +1,49 @@ +// +// RACTargetQueueSchedulerSpec.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 6/7/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTargetQueueScheduler.h" +#import + +QuickSpecBegin(RACTargetQueueSchedulerSpec) + +qck_it(@"should have a valid current scheduler", ^{ + dispatch_queue_t queue = dispatch_queue_create("test-queue", DISPATCH_QUEUE_SERIAL); + RACScheduler *scheduler = [[RACTargetQueueScheduler alloc] initWithName:@"test-scheduler" targetQueue:queue]; + __block RACScheduler *currentScheduler; + [scheduler schedule:^{ + currentScheduler = RACScheduler.currentScheduler; + }]; + + expect(currentScheduler).toEventually(equal(scheduler)); +}); + +qck_it(@"should schedule blocks FIFO even when given a concurrent queue", ^{ + dispatch_queue_t queue = dispatch_queue_create("test-queue", DISPATCH_QUEUE_CONCURRENT); + RACScheduler *scheduler = [[RACTargetQueueScheduler alloc] initWithName:@"test-scheduler" targetQueue:queue]; + __block volatile int32_t startedCount = 0; + __block volatile uint32_t waitInFirst = 1; + [scheduler schedule:^{ + OSAtomicIncrement32Barrier(&startedCount); + while (waitInFirst == 1) ; + }]; + + [scheduler schedule:^{ + OSAtomicIncrement32Barrier(&startedCount); + }]; + + expect(@(startedCount)).toEventually(equal(@1)); + + OSAtomicAnd32Barrier(0, &waitInFirst); + + expect(@(startedCount)).toEventually(equal(@2)); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACTestExampleScheduler.h b/ReactiveCocoaTests/RACTestExampleScheduler.h new file mode 100644 index 0000000000..0470d98c44 --- /dev/null +++ b/ReactiveCocoaTests/RACTestExampleScheduler.h @@ -0,0 +1,15 @@ +// +// RACTestExampleScheduler.h +// ReactiveCocoa +// +// Created by Josh Abernathy on 6/7/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import + +@interface RACTestExampleScheduler : RACQueueScheduler + +- (id)initWithQueue:(dispatch_queue_t)queue; + +@end diff --git a/ReactiveCocoaTests/RACTestExampleScheduler.m b/ReactiveCocoaTests/RACTestExampleScheduler.m new file mode 100644 index 0000000000..859055c9bb --- /dev/null +++ b/ReactiveCocoaTests/RACTestExampleScheduler.m @@ -0,0 +1,39 @@ +// +// RACTestExampleScheduler.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 6/7/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import "RACTestExampleScheduler.h" +#import "RACQueueScheduler+Subclass.h" + +@implementation RACTestExampleScheduler + +#pragma mark Lifecycle + +- (id)initWithQueue:(dispatch_queue_t)queue { + return [super initWithName:nil queue:queue]; +} + +#pragma mark RACScheduler + +- (RACDisposable *)schedule:(void (^)(void))block { + dispatch_async(self.queue, ^{ + [self performAsCurrentScheduler:block]; + }); + + return nil; +} + +- (RACDisposable *)after:(NSDate *)date schedule:(void (^)(void))block { + dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)([date timeIntervalSinceNow] * NSEC_PER_SEC)); + dispatch_after(when, self.queue, ^{ + [self performAsCurrentScheduler:block]; + }); + + return nil; +} + +@end diff --git a/ReactiveCocoaTests/RACTestObject.h b/ReactiveCocoaTests/RACTestObject.h new file mode 100644 index 0000000000..06ae31d900 --- /dev/null +++ b/ReactiveCocoaTests/RACTestObject.h @@ -0,0 +1,87 @@ +// +// RACTestObject.h +// ReactiveCocoa +// +// Created by Josh Abernathy on 9/18/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +typedef struct { + long long integerField; + double doubleField; +} RACTestStruct; + +@protocol RACTestProtocol + +@optional +- (void)optionalProtocolMethodWithObjectValue:(id)objectValue; + +@end + +@interface RACTestObject : NSObject + +@property (nonatomic, strong) id objectValue; +@property (nonatomic, strong) id secondObjectValue; +@property (nonatomic, strong) RACTestObject *strongTestObjectValue; +@property (nonatomic, weak) RACTestObject *weakTestObjectValue; +@property (nonatomic, weak) id weakObjectWithProtocol; +@property (nonatomic, assign) NSInteger integerValue; +// Holds a copy of the string. +@property (nonatomic, assign) char *charPointerValue; +// Holds a copy of the string. +@property (nonatomic, assign) const char *constCharPointerValue; +@property (nonatomic, assign) CGRect rectValue; +@property (nonatomic, assign) CGSize sizeValue; +@property (nonatomic, assign) CGPoint pointValue; +@property (nonatomic, assign) NSRange rangeValue; +@property (nonatomic, assign) RACTestStruct structValue; +@property (nonatomic, assign) _Bool c99BoolValue; +@property (nonatomic, copy) NSString *stringValue; +@property (nonatomic, copy) NSArray *arrayValue; +@property (nonatomic, copy) NSSet *setValue; +@property (nonatomic, copy) NSOrderedSet *orderedSetValue; +@property (nonatomic, strong) id slowObjectValue; + +// Returns a new object each time, with the integerValue set to 42. +@property (nonatomic, copy, readonly) RACTestObject *dynamicObjectProperty; + +// Returns a new object each time, with the integerValue set to 42. +- (RACTestObject *)dynamicObjectMethod; + +// Whether to allow -setNilValueForKey: to be invoked without throwing an +// exception. +@property (nonatomic, assign) BOOL catchSetNilValueForKey; + +// Has -setObjectValue:andIntegerValue: been called? +@property (nonatomic, assign) BOOL hasInvokedSetObjectValueAndIntegerValue; + +// Has -setObjectValue:andSecondObjectValue: been called? +@property (nonatomic, assign) BOOL hasInvokedSetObjectValueAndSecondObjectValue; + +- (void)setObjectValue:(id)objectValue andIntegerValue:(NSInteger)integerValue; +- (void)setObjectValue:(id)objectValue andSecondObjectValue:(id)secondObjectValue; + +// Returns a string of the form "objectValue: integerValue". +- (NSString *)combineObjectValue:(id)objectValue andIntegerValue:(NSInteger)integerValue; +- (NSString *)combineObjectValue:(id)objectValue andSecondObjectValue:(id)secondObjectValue; + +- (void)lifeIsGood:(id)sender; + ++ (void)lifeIsGood:(id)sender; + +- (NSRange)returnRangeValueWithObjectValue:(id)objectValue andIntegerValue:(NSInteger)integerValue; + +// Writes 5 to the int pointed to by intPointer. +- (void)write5ToIntPointer:(int *)intPointer; + +- (NSInteger)doubleInteger:(NSInteger)integer; +- (char *)doubleString:(char *)string; +- (const char *)doubleConstString:(const char *)string; +- (RACTestStruct)doubleStruct:(RACTestStruct)testStruct; + +- (dispatch_block_t)wrapBlock:(dispatch_block_t)block; + +@end diff --git a/ReactiveCocoaTests/RACTestObject.m b/ReactiveCocoaTests/RACTestObject.m new file mode 100644 index 0000000000..f590703f2b --- /dev/null +++ b/ReactiveCocoaTests/RACTestObject.m @@ -0,0 +1,121 @@ +// +// RACTestObject.m +// ReactiveCocoa +// +// Created by Josh Abernathy on 9/18/12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import "RACTestObject.h" + +@implementation RACTestObject + +- (void)dealloc { + free(_charPointerValue); + free((void *)_constCharPointerValue); +} + +- (void)setNilValueForKey:(NSString *)key { + if (!self.catchSetNilValueForKey) [super setNilValueForKey:key]; +} + +- (void)setCharPointerValue:(char *)charPointerValue { + if (charPointerValue == _charPointerValue) return; + free(_charPointerValue); + _charPointerValue = strdup(charPointerValue); +} + +- (void)setConstCharPointerValue:(const char *)constCharPointerValue { + if (constCharPointerValue == _constCharPointerValue) return; + free((void *)_constCharPointerValue); + _constCharPointerValue = strdup(constCharPointerValue); +} + +- (void)setObjectValue:(id)objectValue andIntegerValue:(NSInteger)integerValue { + self.hasInvokedSetObjectValueAndIntegerValue = YES; + self.objectValue = objectValue; + self.integerValue = integerValue; +} + +- (void)setObjectValue:(id)objectValue andSecondObjectValue:(id)secondObjectValue { + self.hasInvokedSetObjectValueAndSecondObjectValue = YES; + self.objectValue = objectValue; + self.secondObjectValue = secondObjectValue; +} + +- (void)setSlowObjectValue:(id)value { + [NSThread sleepForTimeInterval:0.02]; + _slowObjectValue = value; +} + +- (NSString *)combineObjectValue:(id)objectValue andIntegerValue:(NSInteger)integerValue { + return [NSString stringWithFormat:@"%@: %ld", objectValue, (long)integerValue]; +} + +- (NSString *)combineObjectValue:(id)objectValue andSecondObjectValue:(id)secondObjectValue { + return [NSString stringWithFormat:@"%@: %@", objectValue, secondObjectValue]; +} + +- (void)lifeIsGood:(id)sender { + +} + ++ (void)lifeIsGood:(id)sender { + +} + +- (NSRange)returnRangeValueWithObjectValue:(id)objectValue andIntegerValue:(NSInteger)integerValue { + return NSMakeRange((NSUInteger)[objectValue integerValue], (NSUInteger)integerValue); +} + +- (RACTestObject *)dynamicObjectProperty { + return [self dynamicObjectMethod]; +} + +- (RACTestObject *)dynamicObjectMethod { + RACTestObject *testObject = [[RACTestObject alloc] init]; + testObject.integerValue = 42; + return testObject; +} + +- (void)write5ToIntPointer:(int *)intPointer { + NSCParameterAssert(intPointer != NULL); + *intPointer = 5; +} + +- (NSInteger)doubleInteger:(NSInteger)integer { + return integer * 2; +} + +- (char *)doubleString:(char *)string { + size_t doubledSize = strlen(string) * 2 + 1; + char *doubledString = malloc(sizeof(char) * doubledSize); + + doubledString[0] = '\0'; + strlcat(doubledString, string, doubledSize); + strlcat(doubledString, string, doubledSize); + + dispatch_async(dispatch_get_main_queue(), ^{ + free(doubledString); + }); + + return doubledString; +} + +- (const char *)doubleConstString:(const char *)string { + return [self doubleString:(char *)string]; +} + +- (RACTestStruct)doubleStruct:(RACTestStruct)testStruct { + testStruct.integerField *= 2; + testStruct.doubleField *= 2; + return testStruct; +} + +- (dispatch_block_t)wrapBlock:(dispatch_block_t)block { + return ^{ + block(); + }; +} + +@end diff --git a/ReactiveCocoaTests/RACTestSchedulerSpec.m b/ReactiveCocoaTests/RACTestSchedulerSpec.m new file mode 100644 index 0000000000..4c5460bc4b --- /dev/null +++ b/ReactiveCocoaTests/RACTestSchedulerSpec.m @@ -0,0 +1,178 @@ +// +// RACTestSchedulerSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-07-06. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTestScheduler.h" + +QuickSpecBegin(RACTestSchedulerSpec) + +__block RACTestScheduler *scheduler; + +qck_beforeEach(^{ + scheduler = [[RACTestScheduler alloc] init]; + expect(scheduler).notTo(beNil()); +}); + +qck_it(@"should do nothing when stepping while empty", ^{ + [scheduler step]; + [scheduler step:5]; + [scheduler stepAll]; +}); + +qck_it(@"should execute the earliest enqueued block when stepping", ^{ + __block BOOL firstExecuted = NO; + [scheduler schedule:^{ + firstExecuted = YES; + }]; + + __block BOOL secondExecuted = NO; + [scheduler schedule:^{ + secondExecuted = YES; + }]; + + expect(@(firstExecuted)).to(beFalsy()); + expect(@(secondExecuted)).to(beFalsy()); + + [scheduler step]; + expect(@(firstExecuted)).to(beTruthy()); + expect(@(secondExecuted)).to(beFalsy()); + + [scheduler step]; + expect(@(secondExecuted)).to(beTruthy()); +}); + +qck_it(@"should step multiple times", ^{ + __block BOOL firstExecuted = NO; + [scheduler schedule:^{ + firstExecuted = YES; + }]; + + __block BOOL secondExecuted = NO; + [scheduler schedule:^{ + secondExecuted = YES; + }]; + + __block BOOL thirdExecuted = NO; + [scheduler schedule:^{ + thirdExecuted = YES; + }]; + + expect(@(firstExecuted)).to(beFalsy()); + expect(@(secondExecuted)).to(beFalsy()); + expect(@(thirdExecuted)).to(beFalsy()); + + [scheduler step:2]; + expect(@(firstExecuted)).to(beTruthy()); + expect(@(secondExecuted)).to(beTruthy()); + expect(@(thirdExecuted)).to(beFalsy()); + + [scheduler step:1]; + expect(@(thirdExecuted)).to(beTruthy()); +}); + +qck_it(@"should step through all scheduled blocks", ^{ + __block NSUInteger executions = 0; + for (NSUInteger i = 0; i < 10; i++) { + [scheduler schedule:^{ + executions++; + }]; + } + + expect(@(executions)).to(equal(@0)); + + [scheduler stepAll]; + expect(@(executions)).to(equal(@10)); +}); + +qck_it(@"should execute blocks in date order when stepping", ^{ + __block BOOL laterExecuted = NO; + [scheduler after:[NSDate distantFuture] schedule:^{ + laterExecuted = YES; + }]; + + __block BOOL earlierExecuted = NO; + [scheduler after:[NSDate dateWithTimeIntervalSinceNow:20] schedule:^{ + earlierExecuted = YES; + }]; + + expect(@(earlierExecuted)).to(beFalsy()); + expect(@(laterExecuted)).to(beFalsy()); + + [scheduler step]; + expect(@(earlierExecuted)).to(beTruthy()); + expect(@(laterExecuted)).to(beFalsy()); + + [scheduler step]; + expect(@(laterExecuted)).to(beTruthy()); +}); + +qck_it(@"should execute delayed blocks in date order when stepping", ^{ + __block BOOL laterExecuted = NO; + [scheduler afterDelay:100 schedule:^{ + laterExecuted = YES; + }]; + + __block BOOL earlierExecuted = NO; + [scheduler afterDelay:50 schedule:^{ + earlierExecuted = YES; + }]; + + expect(@(earlierExecuted)).to(beFalsy()); + expect(@(laterExecuted)).to(beFalsy()); + + [scheduler step]; + expect(@(earlierExecuted)).to(beTruthy()); + expect(@(laterExecuted)).to(beFalsy()); + + [scheduler step]; + expect(@(laterExecuted)).to(beTruthy()); +}); + +qck_it(@"should execute a repeating blocks in date order", ^{ + __block NSUInteger firstExecutions = 0; + [scheduler after:[NSDate dateWithTimeIntervalSinceNow:20] repeatingEvery:5 withLeeway:0 schedule:^{ + firstExecutions++; + }]; + + __block NSUInteger secondExecutions = 0; + [scheduler after:[NSDate dateWithTimeIntervalSinceNow:22] repeatingEvery:10 withLeeway:0 schedule:^{ + secondExecutions++; + }]; + + expect(@(firstExecutions)).to(equal(@0)); + expect(@(secondExecutions)).to(equal(@0)); + + // 20 ticks + [scheduler step]; + expect(@(firstExecutions)).to(equal(@1)); + expect(@(secondExecutions)).to(equal(@0)); + + // 22 ticks + [scheduler step]; + expect(@(firstExecutions)).to(equal(@1)); + expect(@(secondExecutions)).to(equal(@1)); + + // 25 ticks + [scheduler step]; + expect(@(firstExecutions)).to(equal(@2)); + expect(@(secondExecutions)).to(equal(@1)); + + // 30 ticks + [scheduler step]; + expect(@(firstExecutions)).to(equal(@3)); + expect(@(secondExecutions)).to(equal(@1)); + + // 32 ticks + [scheduler step]; + expect(@(firstExecutions)).to(equal(@3)); + expect(@(secondExecutions)).to(equal(@2)); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/RACTestUIButton.h b/ReactiveCocoaTests/RACTestUIButton.h new file mode 100644 index 0000000000..03e97161e1 --- /dev/null +++ b/ReactiveCocoaTests/RACTestUIButton.h @@ -0,0 +1,16 @@ +// +// RACTestUIButton.h +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-06-15. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import + +// Enables use of -sendActionsForControlEvents: in unit tests. +@interface RACTestUIButton : UIButton + ++ (instancetype)button; + +@end diff --git a/ReactiveCocoaTests/RACTestUIButton.m b/ReactiveCocoaTests/RACTestUIButton.m new file mode 100644 index 0000000000..48b2674908 --- /dev/null +++ b/ReactiveCocoaTests/RACTestUIButton.m @@ -0,0 +1,27 @@ +// +// RACTestUIButton.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2013-06-15. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import "RACTestUIButton.h" + +@implementation RACTestUIButton + ++ (instancetype)button { + RACTestUIButton *button = [self buttonWithType:UIButtonTypeCustom]; + return button; +} + +// Required for unit testing – controls don't work normally +// outside of normal apps. +-(void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [target performSelector:action withObject:self]; +#pragma clang diagnostic pop +} + +@end diff --git a/ReactiveCocoaTests/RACTupleSpec.m b/ReactiveCocoaTests/RACTupleSpec.m new file mode 100644 index 0000000000..5cbd49e922 --- /dev/null +++ b/ReactiveCocoaTests/RACTupleSpec.m @@ -0,0 +1,123 @@ +// +// RACTupleSpec.m +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2012-12-12. +// Copyright (c) 2012 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACTuple.h" +#import "RACUnit.h" + +QuickSpecBegin(RACTupleSpec) + +qck_describe(@"RACTupleUnpack", ^{ + qck_it(@"should unpack a single value", ^{ + RACTupleUnpack(RACUnit *value) = [RACTuple tupleWithObjects:RACUnit.defaultUnit, nil]; + expect(value).to(equal(RACUnit.defaultUnit)); + }); + + qck_it(@"should translate RACTupleNil", ^{ + RACTupleUnpack(id value) = [RACTuple tupleWithObjects:RACTupleNil.tupleNil, nil]; + expect(value).to(beNil()); + }); + + qck_it(@"should unpack multiple values", ^{ + RACTupleUnpack(NSString *str, NSNumber *num) = [RACTuple tupleWithObjects:@"foobar", @5, nil]; + + expect(str).to(equal(@"foobar")); + expect(num).to(equal(@5)); + }); + + qck_it(@"should fill in missing values with nil", ^{ + RACTupleUnpack(NSString *str, NSNumber *num) = [RACTuple tupleWithObjects:@"foobar", nil]; + + expect(str).to(equal(@"foobar")); + expect(num).to(beNil()); + }); + + qck_it(@"should skip any values not assigned to", ^{ + RACTupleUnpack(NSString *str, NSNumber *num) = [RACTuple tupleWithObjects:@"foobar", @5, RACUnit.defaultUnit, nil]; + + expect(str).to(equal(@"foobar")); + expect(num).to(equal(@5)); + }); + + qck_it(@"should keep an unpacked value alive when captured in a block", ^{ + __weak id weakPtr = nil; + id (^block)(void) = nil; + + @autoreleasepool { + RACTupleUnpack(NSString *str) = [RACTuple tupleWithObjects:[[NSMutableString alloc] init], nil]; + + weakPtr = str; + expect(weakPtr).notTo(beNil()); + + block = [^{ + return str; + } copy]; + } + + expect(weakPtr).notTo(beNil()); + expect(block()).to(equal(weakPtr)); + }); +}); + +qck_describe(@"RACTuplePack", ^{ + qck_it(@"should pack a single value", ^{ + RACTuple *tuple = [RACTuple tupleWithObjects:RACUnit.defaultUnit, nil]; + expect(RACTuplePack(RACUnit.defaultUnit)).to(equal(tuple)); + }); + + qck_it(@"should translate nil", ^{ + RACTuple *tuple = [RACTuple tupleWithObjects:RACTupleNil.tupleNil, nil]; + expect(RACTuplePack(nil)).to(equal(tuple)); + }); + + qck_it(@"should pack multiple values", ^{ + NSString *string = @"foobar"; + NSNumber *number = @5; + RACTuple *tuple = [RACTuple tupleWithObjects:string, number, nil]; + expect(RACTuplePack(string, number)).to(equal(tuple)); + }); +}); + +qck_describe(@"-tupleByAddingObject:", ^{ + __block RACTuple *tuple; + + qck_beforeEach(^{ + tuple = RACTuplePack(@"foo", nil, @"bar"); + }); + + qck_it(@"should add a non-nil object", ^{ + RACTuple *newTuple = [tuple tupleByAddingObject:@"buzz"]; + expect(@(newTuple.count)).to(equal(@4)); + expect(newTuple[0]).to(equal(@"foo")); + expect(newTuple[1]).to(beNil()); + expect(newTuple[2]).to(equal(@"bar")); + expect(newTuple[3]).to(equal(@"buzz")); + }); + + qck_it(@"should add nil", ^{ + RACTuple *newTuple = [tuple tupleByAddingObject:nil]; + expect(@(newTuple.count)).to(equal(@4)); + expect(newTuple[0]).to(equal(@"foo")); + expect(newTuple[1]).to(beNil()); + expect(newTuple[2]).to(equal(@"bar")); + expect(newTuple[3]).to(beNil()); + }); + + qck_it(@"should add NSNull", ^{ + RACTuple *newTuple = [tuple tupleByAddingObject:NSNull.null]; + expect(@(newTuple.count)).to(equal(@4)); + expect(newTuple[0]).to(equal(@"foo")); + expect(newTuple[1]).to(beNil()); + expect(newTuple[2]).to(equal(@"bar")); + expect(newTuple[3]).to(equal(NSNull.null)); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/SwiftSpec.swift b/ReactiveCocoaTests/SwiftSpec.swift new file mode 100644 index 0000000000..3313ad8240 --- /dev/null +++ b/ReactiveCocoaTests/SwiftSpec.swift @@ -0,0 +1,19 @@ +// +// SwiftSpec.swift +// ReactiveCocoa +// +// Created by Justin Spahr-Summers on 2014-10-14. +// Copyright (c) 2014 GitHub. All rights reserved. +// + +import Foundation +import Nimble +import Quick + +// Without this, the Swift stdlib won't be linked into the test target (even if +// “Embedded Content Contains Swift Code” is enabled). +class SwiftSpec: QuickSpec { + override func spec() { + expect(true).to(beTruthy()) + } +} diff --git a/ReactiveCocoaTests/UIActionSheetRACSupportSpec.m b/ReactiveCocoaTests/UIActionSheetRACSupportSpec.m new file mode 100644 index 0000000000..7bac73c926 --- /dev/null +++ b/ReactiveCocoaTests/UIActionSheetRACSupportSpec.m @@ -0,0 +1,39 @@ +// +// UIActionSheetRACSupportSpec.m +// ReactiveCocoa +// +// Created by Dave Lee on 2013-06-22. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACSignal.h" +#import "RACSignal+Operations.h" +#import "UIActionSheet+RACSignalSupport.h" + +QuickSpecBegin(UIActionSheetRACSupportSpec) + +qck_describe(@"-rac_buttonClickedSignal", ^{ + __block UIActionSheet *actionSheet; + + qck_beforeEach(^{ + actionSheet = [[UIActionSheet alloc] init]; + [actionSheet addButtonWithTitle:@"Button 0"]; + [actionSheet addButtonWithTitle:@"Button 1"]; + expect(actionSheet).notTo(beNil()); + }); + + qck_it(@"should send the index of the clicked button", ^{ + __block NSNumber *index = nil; + [actionSheet.rac_buttonClickedSignal subscribeNext:^(NSNumber *i) { + index = i; + }]; + + [actionSheet.delegate actionSheet:actionSheet clickedButtonAtIndex:1]; + expect(index).to(equal(@1)); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/UIAlertViewRACSupportSpec.m b/ReactiveCocoaTests/UIAlertViewRACSupportSpec.m new file mode 100644 index 0000000000..29bab43b6a --- /dev/null +++ b/ReactiveCocoaTests/UIAlertViewRACSupportSpec.m @@ -0,0 +1,47 @@ +// +// UIAlertViewRACSupportSpec.m +// ReactiveCocoa +// +// Created by Henrik Hodne on 6/16/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import +#import "RACSignal.h" +#import "UIAlertView+RACSignalSupport.h" + +QuickSpecBegin(UIAlertViewRACSupportSpec) + +qck_describe(@"UIAlertView", ^{ + __block UIAlertView *alertView; + + qck_beforeEach(^{ + alertView = [[UIAlertView alloc] initWithFrame:CGRectZero]; + expect(alertView).notTo(beNil()); + }); + + qck_it(@"sends the index of the clicked button to the buttonClickedSignal when a button is clicked", ^{ + __block NSInteger index = -1; + [alertView.rac_buttonClickedSignal subscribeNext:^(NSNumber *sentIndex) { + index = sentIndex.integerValue; + }]; + + [alertView.delegate alertView:alertView clickedButtonAtIndex:2]; + expect(@(index)).to(equal(@2)); + }); + + qck_it(@"sends the index of the appropriate button to the willDismissSignal when dismissed programatically", ^{ + __block NSInteger index = -1; + [alertView.rac_willDismissSignal subscribeNext:^(NSNumber *sentIndex) { + index = sentIndex.integerValue; + }]; + + [alertView.delegate alertView:alertView willDismissWithButtonIndex:2]; + expect(@(index)).to(equal(@2)); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/UIBarButtonItemRACSupportSpec.m b/ReactiveCocoaTests/UIBarButtonItemRACSupportSpec.m new file mode 100644 index 0000000000..783dbbd27f --- /dev/null +++ b/ReactiveCocoaTests/UIBarButtonItemRACSupportSpec.m @@ -0,0 +1,43 @@ +// +// UIBarButtonItemRACSupportSpec.m +// ReactiveCocoa +// +// Created by Kyle LeNeau on 4/13/13. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACControlCommandExamples.h" + +#import "UIBarButtonItem+RACCommandSupport.h" +#import "RACCommand.h" +#import "RACDisposable.h" + +QuickSpecBegin(UIBarButtonItemRACSupportSpec) + +qck_describe(@"UIBarButtonItem", ^{ + __block UIBarButtonItem *button; + + qck_beforeEach(^{ + button = [[UIBarButtonItem alloc] init]; + expect(button).notTo(beNil()); + }); + + qck_itBehavesLike(RACControlCommandExamples, ^{ + return @{ + RACControlCommandExampleControl: button, + RACControlCommandExampleActivateBlock: ^(UIBarButtonItem *button) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[button.target methodSignatureForSelector:button.action]]; + invocation.selector = button.action; + + id target = button.target; + [invocation setArgument:&target atIndex:2]; + [invocation invokeWithTarget:target]; + } + }; + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/UIButtonRACSupportSpec.m b/ReactiveCocoaTests/UIButtonRACSupportSpec.m new file mode 100644 index 0000000000..10094c4def --- /dev/null +++ b/ReactiveCocoaTests/UIButtonRACSupportSpec.m @@ -0,0 +1,42 @@ +// +// UIButtonRACSupportSpec.m +// ReactiveCocoa +// +// Created by Ash Furrow on 2013-06-06. +// Copyright (c) 2013 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "RACControlCommandExamples.h" +#import "RACTestUIButton.h" + +#import "UIButton+RACCommandSupport.h" +#import "RACCommand.h" +#import "RACDisposable.h" + +QuickSpecBegin(UIButtonRACSupportSpec) + +qck_describe(@"UIButton", ^{ + __block UIButton *button; + + qck_beforeEach(^{ + button = [RACTestUIButton button]; + expect(button).notTo(beNil()); + }); + + qck_itBehavesLike(RACControlCommandExamples, ^{ + return @{ + RACControlCommandExampleControl: button, + RACControlCommandExampleActivateBlock: ^(UIButton *button) { + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Warc-performSelector-leaks" + [button sendActionsForControlEvents:UIControlEventTouchUpInside]; + #pragma clang diagnostic pop + } + }; + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/UIImagePickerControllerRACSupportSpec.m b/ReactiveCocoaTests/UIImagePickerControllerRACSupportSpec.m new file mode 100644 index 0000000000..beafc0589a --- /dev/null +++ b/ReactiveCocoaTests/UIImagePickerControllerRACSupportSpec.m @@ -0,0 +1,54 @@ +// +// UIImagePickerControllerRACSupportSpec.m +// ReactiveCocoa +// +// Created by Timur Kuchkarov on 17.04.14. +// Copyright (c) 2014 GitHub, Inc. All rights reserved. +// + +#import +#import + +#import "UIImagePickerController+RACSignalSupport.h" +#import "RACSignal.h" + +QuickSpecBegin(UIImagePickerControllerRACSupportSpec) + +qck_describe(@"UIImagePickerController", ^{ + __block UIImagePickerController *imagePicker; + + qck_beforeEach(^{ + imagePicker = [[UIImagePickerController alloc] init]; + expect(imagePicker).notTo(beNil()); + }); + + qck_it(@"sends the user info dictionary after confirmation", ^{ + __block NSDictionary *selectedImageUserInfo = nil; + [imagePicker.rac_imageSelectedSignal subscribeNext:^(NSDictionary *userInfo) { + selectedImageUserInfo = userInfo; + }]; + + NSDictionary *info = @{ + UIImagePickerControllerMediaType: @"public.image", + UIImagePickerControllerMediaMetadata: @{} + }; + [imagePicker.delegate imagePickerController:imagePicker didFinishPickingMediaWithInfo:info]; + expect(selectedImageUserInfo).to(equal(info)); + }); + + qck_it(@"cancels image picking process", ^{ + __block BOOL didSend = NO; + __block BOOL didComplete = NO; + [imagePicker.rac_imageSelectedSignal subscribeNext:^(NSDictionary *userInfo) { + didSend = YES; + } completed:^{ + didComplete = YES; + }]; + + [imagePicker.delegate imagePickerControllerDidCancel:imagePicker]; + expect(@(didSend)).to(beFalsy()); + expect(@(didComplete)).to(beTruthy()); + }); +}); + +QuickSpecEnd diff --git a/ReactiveCocoaTests/test-data.json b/ReactiveCocoaTests/test-data.json new file mode 100644 index 0000000000..0599ee5fe0 --- /dev/null +++ b/ReactiveCocoaTests/test-data.json @@ -0,0 +1,5 @@ +[ + { "item": 1 }, + { "item": 2 }, + { "item": 3 } +] diff --git a/script/cibuild b/script/cibuild index d64c6abd26..fa57412abb 100755 --- a/script/cibuild +++ b/script/cibuild @@ -17,7 +17,7 @@ config () # # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will # take precedence. - : ${XCWORKSPACE="ReactiveCocoaFramework/ReactiveCocoa.xcworkspace"} + : ${XCWORKSPACE=$(find_pattern "*.xcworkspace")} # The project to build. # @@ -26,7 +26,7 @@ config () # # Only one of `XCWORKSPACE` and `XCODEPROJ` needs to be set. The former will # take precedence. - : ${XCODEPROJ="ReactiveCocoaFramework/ReactiveCocoa.xcodeproj"} + : ${XCODEPROJ=$(find_pattern "*.xcodeproj")} # A bootstrap script to run before building. # @@ -40,7 +40,7 @@ config () # # Individual names can be quoted to avoid word splitting. : ${SCHEMES:=$(xcodebuild -list -project "$XCODEPROJ" 2>/dev/null | awk -f "$SCRIPT_DIR/schemes.awk")} - + export XCWORKSPACE export XCODEPROJ export BOOTSTRAP @@ -120,16 +120,27 @@ build_scheme () local awkstatus=$? - if [ "$awkstatus" -ne "0" ] + if [ "$awkstatus" -eq "1" ] then - # Unit tests aren't supported. - action=build + # SDK not found, try for iphonesimulator. + sdkflag="-sdk iphonesimulator" + + # Determine whether the unit tests will run with iphonesimulator + run_xctool $sdkflag -scheme "$scheme" run-tests | parse_build + + awkstatus=$? + + if [ "$awkstatus" -ne "0" ] + then + # Unit tests will not run on iphonesimulator. + sdkflag="" + fi fi - if [ "$awkstatus" -eq "1" ] + if [ "$awkstatus" -ne "0" ] then - # Build for iOS. - sdkflag="-sdk iphonesimulator" + # Unit tests aren't supported. + action=build fi run_xctool $sdkflag -scheme "$scheme" $action diff --git a/script/schemes.awk b/script/schemes.awk index d101b4fd34..4c94df914a 100644 --- a/script/schemes.awk +++ b/script/schemes.awk @@ -2,10 +2,8 @@ BEGIN { FS = "\n"; } -/Targets:/ { +/Schemes:/ { while (getline && $0 != "") { - if ($0 ~ /Test/) continue; - sub(/^ +/, ""); print "'" $0 "'"; }