7#import <XCTest/XCTest.h>
17- (instancetype)initWithGoldenNamePrefix:(NSString*)prefix {
20 _goldenName = [prefix stringByAppendingString:_platformName()];
21 NSBundle* bundle = [NSBundle bundleForClass:[
self class]];
22 NSURL* goldenURL = [bundle URLForResource:_goldenName withExtension:@"png"];
23 NSData* data = [NSData dataWithContentsOfURL:goldenURL];
24 _image = [[UIImage alloc] initWithData:data];
29- (
BOOL)compareGoldenToImage:(UIImage*)image rmesThreshold:(
double)rmesThreshold {
31 os_log_error(OS_LOG_DEFAULT,
"GOLDEN DIFF FAILED: image does not exists.");
34 CGImageRef imageRefA = [
self.image CGImage];
35 CGImageRef imageRefB = [image CGImage];
37 NSUInteger widthA = CGImageGetWidth(imageRefA);
38 NSUInteger heightA = CGImageGetHeight(imageRefA);
39 NSUInteger widthB = CGImageGetWidth(imageRefB);
40 NSUInteger heightB = CGImageGetHeight(imageRefB);
42 if (widthA != widthB || heightA != heightB) {
43 os_log_error(OS_LOG_DEFAULT,
"GOLDEN DIFF FAILED: images sizes do not match.");
46 NSUInteger bytesPerPixel = 4;
47 NSUInteger
size = widthA * heightA * bytesPerPixel;
48 NSMutableData* rawA = [NSMutableData dataWithLength:size];
49 NSMutableData* rawB = [NSMutableData dataWithLength:size];
52 os_log_error(OS_LOG_DEFAULT,
"GOLDEN DIFF FAILED: image data length do not match.");
56 CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
58 NSUInteger bytesPerRow = bytesPerPixel * widthA;
59 NSUInteger bitsPerComponent = 8;
60 CGContextRef contextA =
61 CGBitmapContextCreate(rawA.mutableBytes, widthA, heightA, bitsPerComponent, bytesPerRow,
62 colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
64 CGContextDrawImage(contextA, CGRectMake(0, 0, widthA, heightA), imageRefA);
65 CGContextRelease(contextA);
67 CGContextRef contextB =
68 CGBitmapContextCreate(rawB.mutableBytes, widthA, heightA, bitsPerComponent, bytesPerRow,
69 colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
70 CGColorSpaceRelease(colorSpace);
72 CGContextDrawImage(contextB, CGRectMake(0, 0, widthA, heightA), imageRefB);
73 CGContextRelease(contextB);
75 const char* apos = rawA.mutableBytes;
76 const char* bpos = rawB.mutableBytes;
78 for (
size_t i = 0; i <
size; ++i, ++apos, ++bpos) {
80 if (*apos == 0 && *bpos == 0 && i % 4 == 0) {
87 double diff = aval - bval;
91 double rmse =
sqrt(sum / size);
92 if (rmse > rmesThreshold) {
95 "GOLDEN DIFF FAILED: image diff greater than threshold. Current diff: %@, threshold: %@",
96 @(rmse), @(rmesThreshold));
103 NSString* systemVersion = UIDevice.currentDevice.systemVersion;
104 NSString* simulatorName =
105 [[NSProcessInfo processInfo].environment objectForKey:@"SIMULATOR_DEVICE_NAME"];
107 return [NSString stringWithFormat:@"%@_%@_simulator", simulatorName, systemVersion];
111 sysctlbyname(
"hw.model", NULL, &size, NULL, 0);
112 char* answer = malloc(size);
113 sysctlbyname(
"hw.model", answer, &size, NULL, 0);
115 NSString* results = [NSString stringWithUTF8String:answer];