//
// FakeXCTest
//
// Copyright (c) 2014 Apple. All rights reserved.
//
#import <mach/mach.h>
#import <mach/mach_time.h>
#import "FakeXCTestCase.h"
static uint64_t
relative_nano_time(void)
{
static uint64_t factor;
uint64_t now;
now = mach_absolute_time();
if (factor == 0) {
mach_timebase_info_data_t base;
(void)mach_timebase_info(&base);
factor = base.numer / base.denom;
}
return now * factor;
}
#define MAXTESTRUN 5
@interface XCTestCase () {
uint64_t _start;
uint64_t _testRuns[MAXTESTRUN];
unsigned _testrun;
}
@end
@implementation XCTestCase
+ (NSArray *)defaultPerformanceMetrics {
return NULL;
}
- (void)setUp {
}
- (void)tearDown {
}
- (void)measureBlock:(void (^)(void))block
{
[self measureMetrics:@[ [XCTestCase defaultPerformanceMetrics] ] automaticallyStartMeasuring:YES forBlock:block];
}
- (void)measureMetrics:(NSArray *)metrics automaticallyStartMeasuring:(BOOL)automaticallyStartMeasuring forBlock:(void (^)(void))block;
{
unsigned long n;
uint64_t sum = 0, mean;
double stddiv = 0.0;
(void)metrics;
for (_testrun = 0; _testrun < MAXTESTRUN; _testrun++) {
_start = 0;
if (automaticallyStartMeasuring)
[self startMeasuring];
block();
if (automaticallyStartMeasuring)
[self stopMeasuring];
}
printf("TIME for (n = 0; n < MAXTESTRUN; n++) {
printf(" n == MAXTESTRUN - 1 ? "" : " ");
sum += _testRuns[n];
}
mean = sum / MAXTESTRUN;
for (n = 0; n < MAXTESTRUN; n++) {
int64_t t = (int64_t)(mean - _testRuns[n]);
stddiv += t * t;
}
stddiv = sqrt(stddiv / MAXTESTRUN);
printf("] seconds average: (double)mean / NSEC_PER_SEC, 100 * stddiv / mean);
}
- (void)startMeasuring
{
_start = relative_nano_time();
}
- (void)stopMeasuring
{
uint64_t stop = relative_nano_time();
if (_start == 0)
@throw [NSException exceptionWithName:@"startMeasuringNeverCalled"
reason:@"test case failure"
userInfo:nil];
if (_testrun >= MAXTESTRUN) abort();
_testRuns[_testrun] = stop - _start;
_start = 0;
}
@end