NSUserDefaultsRACSupportSpec.m 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //
  2. // NSUserDefaultsRACSupportSpec.m
  3. // ReactiveCocoa
  4. //
  5. // Created by Matt Diephouse on 12/19/13.
  6. // Copyright (c) 2013 GitHub, Inc. All rights reserved.
  7. //
  8. #import <Quick/Quick.h>
  9. #import <Nimble/Nimble.h>
  10. #import "NSUserDefaults+RACSupport.h"
  11. #import "RACCompoundDisposable.h"
  12. #import "RACDisposable.h"
  13. #import "RACKVOChannel.h"
  14. #import "NSObject+RACDeallocating.h"
  15. #import "RACSignal+Operations.h"
  16. static NSString * const NSUserDefaultsRACSupportSpecStringDefault = @"NSUserDefaultsRACSupportSpecStringDefault";
  17. static NSString * const NSUserDefaultsRACSupportSpecBoolDefault = @"NSUserDefaultsRACSupportSpecBoolDefault";
  18. @interface TestObserver : NSObject
  19. @property (copy, atomic) NSString *string1;
  20. @property (copy, atomic) NSString *string2;
  21. @property (assign, atomic) BOOL bool1;
  22. @end
  23. @implementation TestObserver
  24. @end
  25. QuickSpecBegin(NSUserDefaultsRACSupportSpec)
  26. __block NSUserDefaults *defaults = nil;
  27. __block TestObserver *observer = nil;
  28. qck_beforeEach(^{
  29. defaults = NSUserDefaults.standardUserDefaults;
  30. observer = [TestObserver new];
  31. });
  32. qck_afterEach(^{
  33. [defaults removeObjectForKey:NSUserDefaultsRACSupportSpecStringDefault];
  34. [defaults removeObjectForKey:NSUserDefaultsRACSupportSpecBoolDefault];
  35. observer = nil;
  36. });
  37. qck_it(@"should set defaults", ^{
  38. RACChannelTo(observer, string1) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault];
  39. RACChannelTo(observer, bool1, @NO) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecBoolDefault];
  40. observer.string1 = @"A string";
  41. observer.bool1 = YES;
  42. expect([defaults objectForKey:NSUserDefaultsRACSupportSpecStringDefault]).toEventually(equal(@"A string"));
  43. expect([defaults objectForKey:NSUserDefaultsRACSupportSpecBoolDefault]).toEventually(equal(@YES));
  44. });
  45. qck_it(@"should read defaults", ^{
  46. RACChannelTo(observer, string1) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault];
  47. RACChannelTo(observer, bool1, @NO) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecBoolDefault];
  48. expect(observer.string1).to(beNil());
  49. expect(@(observer.bool1)).to(equal(@NO));
  50. [defaults setObject:@"Another string" forKey:NSUserDefaultsRACSupportSpecStringDefault];
  51. [defaults setBool:YES forKey:NSUserDefaultsRACSupportSpecBoolDefault];
  52. expect(observer.string1).to(equal(@"Another string"));
  53. expect(@(observer.bool1)).to(equal(@YES));
  54. });
  55. qck_it(@"should be okay to create 2 terminals", ^{
  56. RACChannelTo(observer, string1) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault];
  57. RACChannelTo(observer, string2) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault];
  58. [defaults setObject:@"String 3" forKey:NSUserDefaultsRACSupportSpecStringDefault];
  59. expect(observer.string1).to(equal(@"String 3"));
  60. expect(observer.string2).to(equal(@"String 3"));
  61. });
  62. qck_it(@"should handle removed defaults", ^{
  63. observer.string1 = @"Some string";
  64. observer.bool1 = YES;
  65. RACChannelTo(observer, string1) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault];
  66. RACChannelTo(observer, bool1, @NO) = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecBoolDefault];
  67. [defaults removeObjectForKey:NSUserDefaultsRACSupportSpecStringDefault];
  68. [defaults removeObjectForKey:NSUserDefaultsRACSupportSpecBoolDefault];
  69. expect(observer.string1).to(beNil());
  70. expect(@(observer.bool1)).to(equal(@NO));
  71. });
  72. qck_it(@"shouldn't resend values", ^{
  73. RACChannelTerminal *terminal = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault];
  74. RACChannelTo(observer, string1) = terminal;
  75. RACSignal *sentValue = [terminal replayLast];
  76. observer.string1 = @"Test value";
  77. id value = [sentValue asynchronousFirstOrDefault:nil success:NULL error:NULL];
  78. expect(value).to(beNil());
  79. });
  80. qck_it(@"should complete when the NSUserDefaults deallocates", ^{
  81. __block RACChannelTerminal *terminal;
  82. __block BOOL deallocated = NO;
  83. @autoreleasepool {
  84. NSUserDefaults *customDefaults __attribute__((objc_precise_lifetime)) = [NSUserDefaults new];
  85. [customDefaults.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
  86. deallocated = YES;
  87. }]];
  88. terminal = [customDefaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault];
  89. }
  90. expect(@(deallocated)).to(beTruthy());
  91. expect(@([terminal asynchronouslyWaitUntilCompleted:NULL])).to(beTruthy());
  92. });
  93. qck_it(@"should send an initial value", ^{
  94. [defaults setObject:@"Initial" forKey:NSUserDefaultsRACSupportSpecStringDefault];
  95. RACChannelTerminal *terminal = [defaults rac_channelTerminalForKey:NSUserDefaultsRACSupportSpecStringDefault];
  96. expect([terminal asynchronousFirstOrDefault:nil success:NULL error:NULL]).to(equal(@"Initial"));
  97. });
  98. QuickSpecEnd