114 lines
3.5 KiB
Objective-C
114 lines
3.5 KiB
Objective-C
//
|
||
// TestBase.h
|
||
// TrustHttpDNS
|
||
//
|
||
// Created by ElonChan(地风) on 2017/4/14.
|
||
// Copyright © 2017�trustapp.com. All rights reserved.
|
||
//
|
||
|
||
#import "XCTestCase+AsyncTesting.h"
|
||
#import "objc/runtime.h"
|
||
|
||
static void *kLoopUntil_Key = "LoopUntil_Key";
|
||
static void *kNotified_Key = "kNotified_Key";
|
||
static void *kNotifiedStatus_Key = "kNotifiedStatus_Key";
|
||
static void *kExpectedStatus_Key = "kExpectedStatus_Key";
|
||
|
||
@implementation XCTestCase (AsyncTesting)
|
||
|
||
#pragma mark - Public
|
||
|
||
|
||
- (void)waitForStatus:(XCTAsyncTestCaseStatus)status timeout:(NSTimeInterval)timeout {
|
||
self.notified = NO;
|
||
self.expectedStatus = status;
|
||
self.loopUntil = [NSDate dateWithTimeIntervalSinceNow:timeout];
|
||
|
||
NSDate *dt = [NSDate dateWithTimeIntervalSinceNow:0.1];
|
||
while (!self.notified && [self.loopUntil timeIntervalSinceNow] > 0) {
|
||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
|
||
beforeDate:dt];
|
||
dt = [NSDate dateWithTimeIntervalSinceNow:0.1];
|
||
}
|
||
|
||
// Only assert when notified. Do not assert when timed out
|
||
// Fail if not notified
|
||
if (self.notified) {
|
||
XCTAssertEqual(self.notifiedStatus, self.expectedStatus, @"Notified status does not match the expected status.");
|
||
} else {
|
||
XCTFail(@"Async test timed out.");
|
||
}
|
||
}
|
||
|
||
- (void)waitForTimeout:(NSTimeInterval)timeout {
|
||
self.notified = NO;
|
||
self.expectedStatus = XCTAsyncTestCaseStatusUnknown;
|
||
self.loopUntil = [NSDate dateWithTimeIntervalSinceNow:timeout];
|
||
|
||
NSDate *dt = [NSDate dateWithTimeIntervalSinceNow:0.1];
|
||
while (!self.notified && [self.loopUntil timeIntervalSinceNow] > 0) {
|
||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
|
||
beforeDate:dt];
|
||
dt = [NSDate dateWithTimeIntervalSinceNow:0.1];
|
||
}
|
||
}
|
||
|
||
- (void)notify:(XCTAsyncTestCaseStatus)status {
|
||
self.notifiedStatus = status;
|
||
// self.notified must be set at the last of this method
|
||
self.notified = YES;
|
||
}
|
||
|
||
#pragma nark - Object Association Helpers -
|
||
|
||
- (void)setAssociatedObject:(id)anObject key:(void*)key {
|
||
objc_setAssociatedObject(self, key, anObject, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||
}
|
||
|
||
- (id)getAssociatedObject:(void*)key {
|
||
id anObject = objc_getAssociatedObject(self, key);
|
||
return anObject;
|
||
}
|
||
|
||
#pragma mark - Property Implementations -
|
||
|
||
- (NSDate*)loopUntil {
|
||
return [self getAssociatedObject:kLoopUntil_Key];
|
||
}
|
||
|
||
- (void)setLoopUntil:(NSDate*)value {
|
||
[self setAssociatedObject:value key:kLoopUntil_Key];
|
||
}
|
||
|
||
- (BOOL)notified {
|
||
NSNumber *valueNumber = [self getAssociatedObject:kNotified_Key];
|
||
return [valueNumber boolValue];
|
||
}
|
||
|
||
- (void)setNotified:(BOOL)value {
|
||
NSNumber *valueNumber = [NSNumber numberWithBool:value];
|
||
[self setAssociatedObject:valueNumber key:kNotified_Key];
|
||
}
|
||
|
||
- (XCTAsyncTestCaseStatus)notifiedStatus {
|
||
NSNumber *valueNumber = [self getAssociatedObject:kNotifiedStatus_Key];
|
||
return [valueNumber integerValue];
|
||
}
|
||
|
||
- (void)setNotifiedStatus:(XCTAsyncTestCaseStatus)value {
|
||
NSNumber *valueNumber = [NSNumber numberWithInt:(int)value];
|
||
[self setAssociatedObject:valueNumber key:kNotifiedStatus_Key];
|
||
}
|
||
|
||
- (XCTAsyncTestCaseStatus)expectedStatus {
|
||
NSNumber *valueNumber = [self getAssociatedObject:kExpectedStatus_Key];
|
||
return [valueNumber integerValue];
|
||
}
|
||
|
||
- (void)setExpectedStatus:(XCTAsyncTestCaseStatus)value {
|
||
NSNumber *valueNumber = [NSNumber numberWithInt:(int)value];
|
||
[self setAssociatedObject:valueNumber key:kExpectedStatus_Key];
|
||
}
|
||
|
||
@end
|