Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…t-case into andrewli/add-color-tolerance

* 'master' of https://github.com/facebook/ios-snapshot-test-case:
  Fix documentation warnings (facebookarchive#205)
  Add Reference to IMAGE_DIFF_DIR (facebookarchive#201)
  Update pod version and change log (facebookarchive#199)
  Bump version to 2.1.4 (facebookarchive#198)
  Replace big macro with Objective-C method for easier debugging. (facebookarchive#180)
  Merge Swift 3 in master (facebookarchive#194)
  Fix pod verification (facebookarchive#193)
  Bump version to 2.3 (facebookarchive#192)
  Revert "Merge Swift 3 into master" (facebookarchive#191)
  Merge Swift 3 into master (facebookarchive#189)
  • Loading branch information
Andrew Li committed Jan 26, 2017
2 parents e8eff24 + ec0906c commit 173c0f9
Show file tree
Hide file tree
Showing 14 changed files with 232 additions and 59 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
language: objective-c
osx_image: xcode7.3
osx_image: xcode8
before_script:
- gem install cocoapods -v 1.0.0 --no-ri --no-rdoc
script:
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

All notable changes to this project will be documented in this file.

## 2.1.4

- Swift 3 support (#194)
- Replace big macro with Objective-C method for easier debugging (#180)

## 2.1.3

- Allow to compile with Xcode 7 and Xcode 8 Swift 2.3 (#179)

## 2.1.2

- Disabled Bitcode for tvOS target (#169)
Expand Down
2 changes: 1 addition & 1 deletion FBSnapshotTestCase.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "FBSnapshotTestCase"
s.version = "2.1.2"
s.version = "2.1.4"
s.summary = "Snapshot view unit tests for iOS"
s.description = <<-DESC
A "snapshot test case" takes a configured UIView or CALayer
Expand Down
8 changes: 8 additions & 0 deletions FBSnapshotTestCase.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -344,9 +344,11 @@
};
B31987EF1AB782D000B0A900 = {
CreatedOnToolsVersion = 6.1.1;
LastSwiftMigration = 0800;
};
B31987FA1AB782D100B0A900 = {
CreatedOnToolsVersion = 6.1.1;
LastSwiftMigration = 0800;
};
};
};
Expand Down Expand Up @@ -501,6 +503,7 @@
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
Expand Down Expand Up @@ -532,6 +535,7 @@
PRODUCT_NAME = FBSnapshotTestCase;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
};
Expand Down Expand Up @@ -678,6 +682,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.FBSnapshotTestCase;
PRODUCT_NAME = FBSnapshotTestCase;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand Down Expand Up @@ -705,6 +710,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.facebook.FBSnapshotTestCase;
PRODUCT_NAME = FBSnapshotTestCase;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand All @@ -723,6 +729,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -737,6 +744,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand Down
53 changes: 16 additions & 37 deletions FBSnapshotTestCase/FBSnapshotTestCase.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,43 +62,9 @@

#define FBSnapshotVerifyViewOrLayerWithOptions(what__, viewOrLayer__, identifier__, suffixes__, tolerance__) \
{ \
NSString *referenceImageDirectory = [self getReferenceImageDirectoryWithDefault:(@ FB_REFERENCE_IMAGE_DIR)]; \
XCTAssertNotNil(referenceImageDirectory, @"Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.");\
XCTAssertTrue((suffixes__.count > 0), @"Suffixes set cannot be empty %@", suffixes__); \
\
BOOL testSuccess__ = NO; \
NSError *error__ = nil; \
NSMutableArray *errors__ = [NSMutableArray array]; \
\
if (self.recordMode) { \
\
NSString *referenceImagesDirectory__ = [NSString stringWithFormat:@"%@%@", referenceImageDirectory, suffixes__.firstObject]; \
BOOL referenceImageSaved__ = [self compareSnapshotOf ## what__ :(viewOrLayer__) referenceImagesDirectory:referenceImagesDirectory__ identifier:(identifier__) tolerance:(tolerance__) error:&error__]; \
if (!referenceImageSaved__) { \
[errors__ addObject:error__]; \
} \
} else { \
\
for (NSString *suffix__ in suffixes__) { \
NSString *referenceImagesDirectory__ = [NSString stringWithFormat:@"%@%@", referenceImageDirectory, suffix__]; \
BOOL referenceImageAvailable = [self referenceImageRecordedInDirectory:referenceImagesDirectory__ identifier:(identifier__) error:&error__]; \
\
if (referenceImageAvailable) { \
BOOL comparisonSuccess__ = [self compareSnapshotOf ## what__ :(viewOrLayer__) referenceImagesDirectory:referenceImagesDirectory__ identifier:(identifier__) tolerance:(tolerance__) error:&error__]; \
[errors__ removeAllObjects]; \
if (comparisonSuccess__) { \
testSuccess__ = YES; \
break; \
} else { \
[errors__ addObject:error__]; \
} \
} else { \
[errors__ addObject:error__]; \
} \
} \
} \
XCTAssertTrue(testSuccess__, @"Snapshot comparison failed: %@", errors__.firstObject); \
XCTAssertFalse(self.recordMode, @"Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!"); \
NSString *errorDescription = [self snapshotVerifyViewOrLayer:viewOrLayer__ identifier:identifier__ suffixes:suffixes__ tolerance:tolerance__]; \
BOOL noErrors = (errorDescription == nil); \
XCTAssertTrue(noErrors, @"%@", errorDescription); \
}


Expand Down Expand Up @@ -148,6 +114,19 @@
- (void)setUp NS_REQUIRES_SUPER;
- (void)tearDown NS_REQUIRES_SUPER;

/**
Performs the comparison or records a snapshot of the layer if recordMode is YES.
@param viewOrLayer The UIView or CALayer to snapshot
@param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method.
@param suffixes An NSOrderedSet of strings for the different suffixes
@param tolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care
@returns nil if the comparison (or saving of the reference image) succeeded. Otherwise it contains an error description.
*/
- (NSString *)snapshotVerifyViewOrLayer:(id)viewOrLayer
identifier:(NSString *)identifier
suffixes:(NSOrderedSet *)suffixes
tolerance:(CGFloat)tolerance;

/**
Performs the comparison or records a snapshot of the layer if recordMode is YES.
@param layer The Layer to snapshot
Expand Down
56 changes: 56 additions & 0 deletions FBSnapshotTestCase/FBSnapshotTestCase.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,62 @@ - (void)setUsesDrawViewHierarchyInRect:(BOOL)usesDrawViewHierarchyInRect

#pragma mark - Public API

- (NSString *)snapshotVerifyViewOrLayer:(id)viewOrLayer
identifier:(NSString *)identifier
suffixes:(NSOrderedSet *)suffixes
tolerance:(CGFloat)tolerance
{
if (nil == viewOrLayer) {
return @"Object to be snapshotted must not be nil";
}
NSString *referenceImageDirectory = [self getReferenceImageDirectoryWithDefault:(@ FB_REFERENCE_IMAGE_DIR)];
if (referenceImageDirectory == nil) {
return @"Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.";
}
if (suffixes.count == 0) {
return [NSString stringWithFormat:@"Suffixes set cannot be empty %@", suffixes];
}

BOOL testSuccess = NO;
NSError *error = nil;
NSMutableArray *errors = [NSMutableArray array];

if (self.recordMode) {
NSString *referenceImagesDirectory = [NSString stringWithFormat:@"%@%@", referenceImageDirectory, suffixes.firstObject];
BOOL referenceImageSaved = [self _compareSnapshotOfViewOrLayer:viewOrLayer referenceImagesDirectory:referenceImagesDirectory identifier:(identifier) tolerance:tolerance error:&error];
if (!referenceImageSaved) {
[errors addObject:error];
}
} else {
for (NSString *suffix in suffixes) {
NSString *referenceImagesDirectory = [NSString stringWithFormat:@"%@%@", referenceImageDirectory, suffix];
BOOL referenceImageAvailable = [self referenceImageRecordedInDirectory:referenceImagesDirectory identifier:(identifier) error:&error];

if (referenceImageAvailable) {
BOOL comparisonSuccess = [self _compareSnapshotOfViewOrLayer:viewOrLayer referenceImagesDirectory:referenceImagesDirectory identifier:identifier tolerance:tolerance error:&error];
[errors removeAllObjects];
if (comparisonSuccess) {
testSuccess = YES;
break;
} else {
[errors addObject:error];
}
} else {
[errors addObject:error];
}
}
}

if (!testSuccess) {
return [NSString stringWithFormat:@"Snapshot comparison failed: %@", errors.firstObject];
}
if (self.recordMode) {
return @"Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!";
}

return nil;
}

- (BOOL)compareSnapshotOfLayer:(CALayer *)layer
referenceImagesDirectory:(NSString *)referenceImagesDirectory
identifier:(NSString *)identifier
Expand Down
6 changes: 3 additions & 3 deletions FBSnapshotTestCase/FBSnapshotTestController.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ extern NSString *const FBDiffedImageKey;
@param layer The Layer to snapshot.
@param selector The test method being run.
@param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method.
@param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc).
@param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc).
@returns YES if the comparison (or saving of the reference image) succeeded.
*/
- (BOOL)compareSnapshotOfLayer:(CALayer *)layer
Expand All @@ -102,7 +102,7 @@ extern NSString *const FBDiffedImageKey;
@param view The view to snapshot.
@param selector The test method being run.
@param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method.
@param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc).
@param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc).
@returns YES if the comparison (or saving of the reference image) succeeded.
*/
- (BOOL)compareSnapshotOfView:(UIView *)view
Expand All @@ -112,7 +112,7 @@ extern NSString *const FBDiffedImageKey;

/**
Performs the comparison of a view or layer.
@param view The view or layer to snapshot.
@param viewOrLayer The view or layer to snapshot.
@param selector The test method being run.
@param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method.
@param tolerance The percentage of pixels that can differ and still be considered 'identical'
Expand Down
59 changes: 59 additions & 0 deletions FBSnapshotTestCase/SwiftSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,64 @@
*
*/

#if swift(>=3)
public extension FBSnapshotTestCase {
public func FBSnapshotVerifyView(_ view: UIView, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), tolerance: CGFloat = 0, file: StaticString = #file, line: UInt = #line) {
FBSnapshotVerifyViewOrLayer(view, identifier: identifier, suffixes: suffixes, tolerance: tolerance, file: file, line: line)
}

public func FBSnapshotVerifyLayer(_ layer: CALayer, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), tolerance: CGFloat = 0, file: StaticString = #file, line: UInt = #line) {
FBSnapshotVerifyViewOrLayer(layer, identifier: identifier, suffixes: suffixes, tolerance: tolerance, file: file, line: line)
}

private func FBSnapshotVerifyViewOrLayer(_ viewOrLayer: AnyObject, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), tolerance: CGFloat = 0, file: StaticString = #file, line: UInt = #line) {
let envReferenceImageDirectory = self.getReferenceImageDirectory(withDefault: FB_REFERENCE_IMAGE_DIR)
var error: NSError?
var comparisonSuccess = false

if let envReferenceImageDirectory = envReferenceImageDirectory {
for suffix in suffixes {
let referenceImagesDirectory = "\(envReferenceImageDirectory)\(suffix)"
if viewOrLayer.isKind(of: UIView.self) {
do {
try compareSnapshot(of: viewOrLayer as! UIView, referenceImagesDirectory: referenceImagesDirectory, identifier: identifier, tolerance: tolerance)
comparisonSuccess = true
} catch let error1 as NSError {
error = error1
comparisonSuccess = false
}
} else if viewOrLayer.isKind(of: CALayer.self) {
do {
try compareSnapshot(of: viewOrLayer as! CALayer, referenceImagesDirectory: referenceImagesDirectory, identifier: identifier, tolerance: tolerance)
comparisonSuccess = true
} catch let error1 as NSError {
error = error1
comparisonSuccess = false
}
} else {
assertionFailure("Only UIView and CALayer classes can be snapshotted")
}

assert(recordMode == false, message: "Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!", file: file, line: line)

if comparisonSuccess || recordMode {
break
}

assert(comparisonSuccess, message: "Snapshot comparison failed: \(error)", file: file, line: line)
}
} else {
XCTFail("Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.")
}
}

func assert(_ assertion: Bool, message: String, file: StaticString, line: UInt) {
if !assertion {
XCTFail(message, file: file, line: line)
}
}
}
#else
public extension FBSnapshotTestCase {
public func FBSnapshotVerifyView(view: UIView, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), tolerance: CGFloat = 0, colorTolerance: CGFloat = 0, file: StaticString = #file, line: UInt = #line) {
FBSnapshotVerifyViewOrLayer(view, identifier: identifier, suffixes: suffixes, tolerance: tolerance, colorTolerance: colorTolerance,file: file, line: line)
Expand Down Expand Up @@ -64,3 +122,4 @@ public extension FBSnapshotTestCase {
}
}
}
#endif
Loading

0 comments on commit 173c0f9

Please sign in to comment.