Skip to content

Commit

Permalink
Use a synchroniser combined with states to test expectations that are
Browse files Browse the repository at this point in the history
satisfied asynchronously.
  • Loading branch information
lukeredpath committed Jan 10, 2013
1 parent 0373c2b commit 26070dd
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions Tests/Integration/StateMachineTests.m
Expand Up @@ -15,6 +15,60 @@ - (void)equals:(NSString *)state;

@end

@interface LRSynchroniser : NSObject

+ (id)synchroniser;
+ (id)synchroniserWithTimeout:(NSTimeInterval)timeout;
- (void)waitUntil:(id<LRStatePredicate>)statePredicate;

@end

@implementation LRSynchroniser {
NSTimeInterval _timeout;
}

+ (id)synchroniser
{
return [[self alloc] initWithTimeout:5];
}

+ (id)synchroniserWithTimeout:(NSTimeInterval)timeout
{
return [[self alloc] initWithTimeout:timeout];
}

- (id)initWithTimeout:(NSTimeInterval)timeout
{
self = [super init];
if (self) {
_timeout = timeout;
}
return self;
}

- (void)waitUntil:(id<LRStatePredicate>)statePredicate
{
if ([statePredicate isActive]) return;

NSDate *waitUntil = [NSDate dateWithTimeIntervalSinceNow:_timeout];

BOOL predicateSatisfied = NO;
NSInteger pollingInterval = 0.1;

while (!predicateSatisfied) {
NSDate *runUntil = [NSDate dateWithTimeIntervalSinceNow:pollingInterval];

if ([runUntil earlierDate:waitUntil] == waitUntil) {
break;
}
[[NSRunLoop currentRunLoop] runUntilDate:runUntil];

predicateSatisfied = [statePredicate isActive];
}
}

@end

DEFINE_FUNCTIONAL_TEST_CASE(StateMachineTests) {
LRMockyStateMachine *readiness;
}
Expand Down Expand Up @@ -86,4 +140,46 @@ - (void)testMultipleExpectationsWithStates
assertThat(testCase, passed());
}

- (void)testUsingStatesToTestAsynchronousCode
{
LRSynchroniser *synchroniser = [LRSynchroniser synchroniser];

[readiness transitionTo:@"waiting"];

[context check:^{
[[expectThat(testObject) receives] doSomething]; [then state:readiness becomes:@"ready"];
}];

dispatch_async(dispatch_get_main_queue(), ^{
[testObject doSomething];
});

[synchroniser waitUntil:[readiness equals:@"ready"]];
[context assertSatisfied];

assertThat(testCase, passed());
}

- (void)testUsingStatesToTestAsynchronousCodeWithTimeout
{
LRSynchroniser *synchroniser = [LRSynchroniser synchroniserWithTimeout:0.3];

[readiness transitionTo:@"waiting"];

[context check:^{
[[expectThat(testObject) receives] doSomething]; [then state:readiness becomes:@"ready"];
}];

double delayInFractionalSeconds = 0.4;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInFractionalSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[testObject doSomething];
});

[synchroniser waitUntil:[readiness equals:@"ready"]];
[context assertSatisfied];

assertThat(testCase, failedWithNumberOfFailures(1));
}

END_TEST_CASE

0 comments on commit 26070dd

Please sign in to comment.