src/iOSSnapshotTestCaseTests/FBSnapshotControllerTests.m (164 lines of code) (raw):
/*
* Copyright (c) 2017-2018, Uber Technologies, Inc.
* Copyright (c) 2015-2018, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
#import <XCTest/XCTest.h>
#if BAZEL
@import iOSSnapshotTestCaseCore;
@import UIKit;
@import CoreGraphics;
@import QuartzCore;
#else
#import "FBSnapshotTestCase.h"
#endif
@interface FBSnapshotControllerTests : XCTestCase
@end
@implementation FBSnapshotControllerTests
#pragma mark - Tests
- (void)testCompareReferenceImageToImageShouldBeEqual
{
UIImage *referenceImage = [self _bundledImageNamed:@"square" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"square-copy" type:@"png"];
XCTAssertNotNil(testImage);
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
NSError *error = nil;
XCTAssertTrue([controller compareReferenceImage:referenceImage toImage:testImage overallTolerance:0 error:&error]);
XCTAssertNil(error);
}
- (void)testCompareReferenceImageToImageShouldNotBeEqual
{
UIImage *referenceImage = [self _bundledImageNamed:@"square" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"square_with_text" type:@"png"];
XCTAssertNotNil(testImage);
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
NSError *error = nil;
XCTAssertFalse([controller compareReferenceImage:referenceImage toImage:testImage overallTolerance:0 error:&error]);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, FBSnapshotTestControllerErrorCodeImagesDifferent);
}
- (void)testCompareReferenceImageWithVeryLowToleranceShouldNotMatch
{
UIImage *referenceImage = [self _bundledImageNamed:@"square" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"square_with_pixel" type:@"png"];
XCTAssertNotNil(testImage);
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
// With virtually no margin for error, this should fail to be equal
NSError *error = nil;
XCTAssertFalse([controller compareReferenceImage:referenceImage toImage:testImage overallTolerance:.0001 error:&error]);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, FBSnapshotTestControllerErrorCodeImagesDifferent);
}
- (void)testCompareReferenceImageWithVeryLowToleranceShouldMatch
{
UIImage *referenceImage = [self _bundledImageNamed:@"square" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"square_with_pixel" type:@"png"];
XCTAssertNotNil(testImage);
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
// With some tolerance these should be considered the same
NSError *error = nil;
XCTAssertTrue([controller compareReferenceImage:referenceImage toImage:testImage overallTolerance:.001 error:&error]);
XCTAssertNil(error);
}
- (void)testCompareReferenceImageWithDifferentSizes
{
UIImage *referenceImage = [self _bundledImageNamed:@"square" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"rect" type:@"png"];
XCTAssertNotNil(testImage);
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
// With some tolerance these should be considered the same
NSError *error = nil;
XCTAssertFalse([controller compareReferenceImage:referenceImage toImage:testImage overallTolerance:0 error:&error]);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, FBSnapshotTestControllerErrorCodeImagesDifferentSizes);
}
- (void)testFailedImageWithFileNameOptionShouldHaveEachOptionInName
{
UIImage *referenceImage = [self _bundledImageNamed:@"square" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"square_with_pixel" type:@"png"];
XCTAssertNotNil(testImage);
NSUInteger FBSnapshotTestCaseFileNameIncludeOptionMaxOffset = 4;
for (NSUInteger i = 0; i <= FBSnapshotTestCaseFileNameIncludeOptionMaxOffset; i++) {
FBSnapshotTestCaseFileNameIncludeOption options = 1 << i;
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
[controller setFileNameOptions:options];
NSString *referenceImagesDirectory = @"/dev/null/";
[controller setReferenceImagesDirectory:referenceImagesDirectory];
NSError *error = nil;
SEL selector = @selector(fileNameOptions);
[controller referenceImageForSelector:selector identifier:@"" error:&error];
XCTAssertNotNil(error);
NSString *deviceIncludedReferencePath = FBFileNameIncludeNormalizedFileNameFromOption(NSStringFromSelector(selector), options);
NSString *filePath = (NSString *)[error.userInfo objectForKey:FBReferenceImageFilePathKey];
XCTAssertTrue([filePath containsString:deviceIncludedReferencePath]);
NSString *expectedFilePath = [NSString stringWithFormat:@"%@%@.png", referenceImagesDirectory, deviceIncludedReferencePath];
XCTAssertEqualObjects(expectedFilePath, filePath);
}
}
- (void)testFailedImageWithFileNameOptionShouldHaveAllOptionsInName
{
UIImage *referenceImage = [self _bundledImageNamed:@"square" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"square_with_pixel" type:@"png"];
XCTAssertNotNil(testImage);
FBSnapshotTestCaseFileNameIncludeOption options = (FBSnapshotTestCaseFileNameIncludeOptionDevice | FBSnapshotTestCaseFileNameIncludeOptionOS | FBSnapshotTestCaseFileNameIncludeOptionScreenSize | FBSnapshotTestCaseFileNameIncludeOptionScreenScale);
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
[controller setFileNameOptions:options];
NSString *referenceImagesDirectory = @"/dev/null/";
[controller setReferenceImagesDirectory:referenceImagesDirectory];
NSError *error = nil;
SEL selector = @selector(fileNameOptions);
[controller referenceImageForSelector:selector identifier:@"" error:&error];
XCTAssertNotNil(error);
NSString *allOptionsIncludedReferencePath = FBFileNameIncludeNormalizedFileNameFromOption(NSStringFromSelector(selector), options);
NSString *filePath = (NSString *)[error.userInfo objectForKey:FBReferenceImageFilePathKey];
XCTAssertTrue([filePath containsString:allOptionsIncludedReferencePath]);
// Manually constructing expected filePath to make sure it looks correct
NSString *expectedFilePath = [NSString stringWithFormat:@"%@%@_%@_%@_%.0fx%.0f@%.fx.png",
referenceImagesDirectory,
NSStringFromSelector(selector),
[[UIDevice currentDevice].model stringByReplacingOccurrencesOfString:@" " withString:@"_"],
[[UIDevice currentDevice].systemVersion stringByReplacingOccurrencesOfString:@"." withString:@"_"],
[UIScreen mainScreen].bounds.size.width,
[UIScreen mainScreen].bounds.size.height,
[[UIScreen mainScreen] scale]];
XCTAssertEqualObjects(expectedFilePath, filePath);
}
- (void)testCompareReferenceImageWithLowPixelToleranceShouldNotMatch
{
UIImage *referenceImage = [self _bundledImageNamed:@"square" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"square_with_pixel" type:@"png"];
XCTAssertNotNil(testImage);
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
// With virtually no margin for error, this should fail to be equal
NSError *error = nil;
XCTAssertFalse([controller compareReferenceImage:referenceImage toImage:testImage perPixelTolerance:.06 overallTolerance:0 error:&error]);
XCTAssertNotNil(error);
XCTAssertEqual(error.code, FBSnapshotTestControllerErrorCodeImagesDifferent);
}
- (void)testCompareReferenceImageWithLowPixelToleranceShouldMatch
{
UIImage *referenceImage = [self _bundledImageNamed:@"rect" type:@"png"];
XCTAssertNotNil(referenceImage);
UIImage *testImage = [self _bundledImageNamed:@"rect_shade" type:@"png"];
XCTAssertNotNil(testImage);
id testClass = nil;
FBSnapshotTestController *controller = [[FBSnapshotTestController alloc] initWithTestClass:testClass];
// With some tolerance these should be considered the same
NSError *error = nil;
XCTAssertTrue([controller compareReferenceImage:referenceImage toImage:testImage perPixelTolerance:.06 overallTolerance:0 error:&error]);
XCTAssertNil(error);
}
#pragma mark - Private helper methods
- (UIImage *)_bundledImageNamed:(NSString *)name type:(NSString *)type
{
NSBundle *bundle = [NSBundle bundleForClass:[FBSnapshotControllerTests class]];
NSString *path = [bundle pathForResource:name ofType:type];
NSData *data = [[NSData alloc] initWithContentsOfFile:path];
return [[UIImage alloc] initWithData:data];
}
@end