Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 41 additions & 5 deletions FBSnapshotTestCase/FBSnapshotTestCase.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#import <FBSnapshotTestCase/FBSnapshotTestCase.h>
#import <FBSnapshotTestCase/FBSnapshotTestController.h>
#import <Availability.h>

@implementation FBSnapshotTestCase
{
Expand Down Expand Up @@ -122,17 +123,52 @@ - (NSString *)snapshotVerifyViewOrLayer:(id)viewOrLayer
}
}
}

if (!testSuccess) {
return [NSString stringWithFormat:@"Snapshot comparison failed: %@", errors.firstObject];
}

[self addAttachmentsWithErrors:errors identifier:identifier];

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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this possible? Looking at L102-L105, it is doing this:

     BOOL referenceImageSaved = [self _compareSnapshotOfViewOrLayer:viewOrLayer referenceImagesDirectory:referenceImagesDirectory identifier:(identifier) tolerance:tolerance error:&error];
     if (!referenceImageSaved) {
       [errors addObject:error];
     }

When self.recordMode is on, compareSnapshotOfViewOrLayer:... the BOOL from the function relates to whether or not the reference image was saved.

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

return nil;
}

- (void) addAttachmentsWithErrors:(NSArray<NSError *> *)errors identifier:(NSString *)identifier {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An internal method should be prefixed with _, there should be no space between the return type and the start of the method name, and the first opening brace should be on a new line

#if defined(__IPHONE_11_0) || defined(__TVOS_11_0)
if (self.recordMode) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would pass this in to the method, say as ranInRecordMode

UIImage* image = [_snapshotController referenceImageForSelector:self.invocation.selector identifier:identifier error:nil];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* aligned with the variable

if (image) {
XCTAttachment *attachement = [XCTAttachment attachmentWithImage:image];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/attachement/attachment

attachement.name = @"Reference Image";
[self addAttachment:attachement];
}
} else if (errors.firstObject != nil) {
NSError *error = errors.firstObject;
if (error.userInfo[FBReferenceImageKey] != nil) {
XCTAttachment *attachement = [XCTAttachment attachmentWithImage:error.userInfo[FBReferenceImageKey]];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/attachement/attachment

attachement.name = @"Reference Image";
[self addAttachment:attachement];
}
if (error.userInfo[FBCapturedImageKey] != nil) {
XCTAttachment *attachement = [XCTAttachment attachmentWithImage:error.userInfo[FBCapturedImageKey]];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/attachement/attachment

attachement.name = @"Captured Image";
[self addAttachment:attachement];
}
if (error.userInfo[FBDiffedImageKey] != nil) {
XCTAttachment *attachement = [XCTAttachment attachmentWithImage:error.userInfo[FBDiffedImageKey]];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/attachement/attachment

attachement.name = @"Diffed Image";
[self addAttachment:attachement];
}
}
#endif
}

- (BOOL)compareSnapshotOfLayer:(CALayer *)layer
referenceImagesDirectory:(NSString *)referenceImagesDirectory
identifier:(NSString *)identifier
Expand Down
53 changes: 5 additions & 48 deletions FBSnapshotTestCase/SwiftSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,58 +11,15 @@
#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)
if let errorDescription = snapshotVerifyViewOrLayer(view, identifier: identifier, suffixes: suffixes, tolerance: tolerance, defaultReferenceDirectory: FB_REFERENCE_IMAGE_DIR) {
XCTFail(errorDescription, 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) {
Copy link
Collaborator

@alanzeino alanzeino Mar 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there's a good reason why SwiftSupport.swift uses its own FBSnapshotVerifyViewOrLayer function instead of leveraging the Objective-C one. This should probably stay as is, with modifications to support this new attachment feature though.

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: \(String(describing: error))", file: file, line: line)
if let errorDescription = snapshotVerifyViewOrLayer(layer, identifier: identifier, suffixes: suffixes, tolerance: tolerance, defaultReferenceDirectory: FB_REFERENCE_IMAGE_DIR) {
XCTFail(errorDescription, 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
Expand Down