mirror of
https://github.com/zhigang1992/ReactiveViewModel.git
synced 2026-01-12 22:51:31 +08:00
193 lines
4.7 KiB
Objective-C
193 lines
4.7 KiB
Objective-C
//
|
|
// RVMViewModelSpec.m
|
|
// ReactiveViewModel
|
|
//
|
|
// Created by Josh Abernathy on 9/11/12.
|
|
// Copyright (c) 2012 GitHub. All rights reserved.
|
|
//
|
|
|
|
#import "RVMTestViewModel.h"
|
|
|
|
SpecBegin(RVMViewModel)
|
|
|
|
__block RVMTestViewModel *viewModel;
|
|
|
|
beforeEach(^{
|
|
viewModel = [[RVMTestViewModel alloc] initWithModel:@"foobar"];
|
|
});
|
|
|
|
describe(@"active property", ^{
|
|
it(@"should default to NO", ^{
|
|
expect(viewModel.active).to.beFalsy();
|
|
});
|
|
|
|
it(@"should send on didBecomeActiveSignal when set to YES", ^{
|
|
__block NSUInteger nextEvents = 0;
|
|
[viewModel.didBecomeActiveSignal subscribeNext:^(RVMViewModel *viewModel) {
|
|
expect(viewModel).to.beIdenticalTo(viewModel);
|
|
expect(viewModel.active).to.beTruthy();
|
|
|
|
nextEvents++;
|
|
}];
|
|
|
|
expect(nextEvents).to.equal(0);
|
|
|
|
viewModel.active = YES;
|
|
expect(nextEvents).to.equal(1);
|
|
|
|
// Indistinct changes should not trigger the signal again.
|
|
viewModel.active = YES;
|
|
expect(nextEvents).to.equal(1);
|
|
|
|
viewModel.active = NO;
|
|
viewModel.active = YES;
|
|
expect(nextEvents).to.equal(2);
|
|
});
|
|
|
|
it(@"should send on didBecomeInactiveSignal when set to NO", ^{
|
|
__block NSUInteger nextEvents = 0;
|
|
[viewModel.didBecomeInactiveSignal subscribeNext:^(RVMViewModel *viewModel) {
|
|
expect(viewModel).to.beIdenticalTo(viewModel);
|
|
expect(viewModel.active).to.beFalsy();
|
|
|
|
nextEvents++;
|
|
}];
|
|
|
|
expect(nextEvents).to.equal(1);
|
|
|
|
viewModel.active = YES;
|
|
viewModel.active = NO;
|
|
expect(nextEvents).to.equal(2);
|
|
|
|
// Indistinct changes should not trigger the signal again.
|
|
viewModel.active = NO;
|
|
expect(nextEvents).to.equal(2);
|
|
});
|
|
|
|
describe(@"signal manipulation", ^{
|
|
__block NSMutableArray *values;
|
|
__block NSArray *expectedValues;
|
|
__block BOOL completed;
|
|
__block BOOL deallocated;
|
|
|
|
__block RVMTestViewModel * (^createViewModel)();
|
|
|
|
beforeEach(^{
|
|
values = [NSMutableArray array];
|
|
expectedValues = @[];
|
|
completed = NO;
|
|
deallocated = NO;
|
|
|
|
createViewModel = ^{
|
|
RVMTestViewModel *viewModel = [[RVMTestViewModel alloc] initWithModel:nil];
|
|
[viewModel.rac_deallocDisposable addDisposable:[RACDisposable disposableWithBlock:^{
|
|
deallocated = YES;
|
|
}]];
|
|
|
|
viewModel.active = YES;
|
|
return viewModel;
|
|
};
|
|
});
|
|
|
|
afterEach(^{
|
|
expect(deallocated).will.beTruthy();
|
|
expect(completed).to.beTruthy();
|
|
});
|
|
|
|
it(@"should forward a signal", ^{
|
|
@autoreleasepool {
|
|
RVMTestViewModel *viewModel __attribute__((objc_precise_lifetime)) = createViewModel();
|
|
|
|
RACSignal *input = [RACSignal createSignal:^ id (id<RACSubscriber> subscriber) {
|
|
[subscriber sendNext:@1];
|
|
[subscriber sendNext:@2];
|
|
return nil;
|
|
}];
|
|
|
|
[[viewModel
|
|
forwardSignalWhileActive:input]
|
|
subscribeNext:^(NSNumber *x) {
|
|
[values addObject:x];
|
|
} completed:^{
|
|
completed = YES;
|
|
}];
|
|
|
|
expectedValues = @[ @1, @2 ];
|
|
expect(values).to.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
|
|
viewModel.active = NO;
|
|
|
|
expect(values).to.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
|
|
viewModel.active = YES;
|
|
|
|
expectedValues = @[ @1, @2, @1, @2 ];
|
|
expect(values).to.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
}
|
|
});
|
|
|
|
it(@"should throttle a signal", ^{
|
|
@autoreleasepool {
|
|
RVMTestViewModel *viewModel __attribute__((objc_precise_lifetime)) = createViewModel();
|
|
RACSubject *subject = [RACSubject subject];
|
|
|
|
[[viewModel
|
|
throttleSignalWhileInactive:[subject startWith:@0]]
|
|
subscribeNext:^(NSNumber *x) {
|
|
[values addObject:x];
|
|
} completed:^{
|
|
completed = YES;
|
|
}];
|
|
|
|
expectedValues = @[ @0 ];
|
|
expect(values).to.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
|
|
[subject sendNext:@1];
|
|
|
|
expectedValues = @[ @0, @1 ];
|
|
expect(values).to.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
|
|
viewModel.active = NO;
|
|
|
|
// Since the VM is inactive, these events should be throttled.
|
|
[subject sendNext:@2];
|
|
[subject sendNext:@3];
|
|
|
|
expect(values).to.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
|
|
expectedValues = @[ @0, @1, @3 ];
|
|
expect(values).will.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
|
|
// After reactivating, we should still get this event.
|
|
[subject sendNext:@4];
|
|
viewModel.active = YES;
|
|
|
|
expectedValues = @[ @0, @1, @3, @4 ];
|
|
expect(values).will.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
|
|
// And now new events should be instant.
|
|
[subject sendNext:@5];
|
|
|
|
expectedValues = @[ @0, @1, @3, @4, @5 ];
|
|
expect(values).to.equal(expectedValues);
|
|
expect(completed).to.beFalsy();
|
|
|
|
[subject sendCompleted];
|
|
|
|
expect(values).to.equal(expectedValues);
|
|
expect(completed).to.beTruthy();
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
SpecEnd
|