Skip to content

Commit

Permalink
Merge branch 'release/0.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
skyweb07 committed Nov 25, 2017
2 parents c8e3d6d + 4cded75 commit dc3e86d
Show file tree
Hide file tree
Showing 15 changed files with 222 additions and 23 deletions.
41 changes: 36 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

* iOS 9.0+
* Xcode 9.0+
* Swift / Objective-C


### 🚀 Getting started
Expand Down Expand Up @@ -46,6 +47,8 @@ pod 'Snap.swift'

1) We first need to record our reference images, in order to do so we have to first go into our test class and set the `isRecording` variable to be `true` so the library knows that we are in record mode and can extract the `reference images`

> Swift
```swift
import XCTest
import Snap_swift
Expand All @@ -58,17 +61,44 @@ class SnapTests: XCTestCase {
}

func test_box_with_text_aligned_to_center() {
let view = BoxWithTextAlignedToCenterView()

expect(view).toMatchSnapshot()
let view = BoxWithTextAlignedToCenterView()
expect(view).toMatchSnapshot()
}
}
```

> Objective-c
```objc
@import XCTest;
#import <Snap_swift/Snap.h>

@interface SnapTests : XCTestCase
@end

@implementation SnapTests

- (void)setUp {
[super setUp];
self.isRecording = YES;
}

- (void)test_box_with_text_aligned_to_center {

UIView *view = [BoxWithTextAlignedToCenterView new];

verifyView(view);
}

@end

```
After executing out test suite if everything was ok we should see that all of our tests failed with a warning similar to
```bash
⚠️ Test ran in record mode, reference image has been saved to /$SNAP_REFERENCE_IMAGE_PATH/testcase.png, now remove `isRecording` in order to perform the snapshot comparison.
⚠️ Test ran in record mode, reference image has been saved to $SNAP_REFERENCE_IMAGE_PATH/testcase.png, now remove `isRecording` in order to perform the snapshot comparison.
```

Expand All @@ -79,11 +109,12 @@ This is ok, it just means that our reference images were saved, we can inspect t
### ☑ TODO:
* [ ] Add tests for project
* [ ] Add `CALayer` matchers
* [ ] Make device agnostic screenshots

### 📝 Notes

> As today, you can make assertions on `UIView` and `CALayer` classes.
This project is highly inspired on `Facebook` [FBSnapshotTestCase](https://github.com/facebookarchive/ios-snapshot-test-case/) library, it seems that they had archived the library so I started this one to continue envolving the project and continue with mobile `snapshot-testing`

### 😬 Contributions
Expand Down
4 changes: 2 additions & 2 deletions Snap.swift.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Snap.swift'
s.version = '0.1.0'
s.version = '0.2.0'
s.summary = 'Snapshot testing in a snap'

s.description = <<-DESC
Expand All @@ -15,6 +15,6 @@ Pod::Spec.new do |s|

s.ios.deployment_target = '9.0'

s.source_files = 'Snap/Core/**/*'
s.source_files = 'Snap/Core/**/*', 'Snap/Core/Infrastructure/Interoperability/*.h'
s.frameworks = 'UIKit', 'CoreGraphics', 'XCTest'
end
56 changes: 44 additions & 12 deletions Snap.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
1C0FF4571FC823A5003B8B22 /* AddAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C0FF4561FC823A5003B8B22 /* AddAttachment.swift */; };
1C0FF4591FC8294A003B8B22 /* UIImage+Diff.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C0FF4581FC8294A003B8B22 /* UIImage+Diff.swift */; };
1C7F066B1FC884110078CA7A /* Recordable+XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7F06691FC8840B0078CA7A /* Recordable+XCTestCase.swift */; };
1C92A5061FC9736000E6C817 /* CALayer+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92A5051FC9736000E6C817 /* CALayer+Image.swift */; };
1C92A5091FC975E400E6C817 /* SnapshotLayerMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92A5071FC9759E00E6C817 /* SnapshotLayerMatcher.swift */; };
1C92A50B1FC9776D00E6C817 /* SnapshotLayerExpectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92A50A1FC9776D00E6C817 /* SnapshotLayerExpectation.swift */; };
1C92A5141FC9808100E6C817 /* Interoperability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92A5131FC9808100E6C817 /* Interoperability.swift */; };
1C92E5C31FC6E47300EF28C2 /* Snap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1C92E5B91FC6E47300EF28C2 /* Snap.framework */; };
1C92E5C81FC6E47300EF28C2 /* SnapTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5C71FC6E47300EF28C2 /* SnapTests.swift */; };
1C92E5CA1FC6E47300EF28C2 /* Snap.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C92E5BC1FC6E47300EF28C2 /* Snap.h */; settings = {ATTRIBUTES = (Public, ); }; };
1C92E5E11FC6E87000EF28C2 /* UIView+Render.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5E01FC6E87000EF28C2 /* UIView+Render.swift */; };
1C92E5E51FC6F25500EF28C2 /* Expectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5E41FC6F25500EF28C2 /* Expectation.swift */; };
1C92E5E81FC6F28500EF28C2 /* Matcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5E71FC6F28500EF28C2 /* Matcher.swift */; };
1C92E5EA1FC6F2AC00EF28C2 /* SnapshotViewMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5E91FC6F2AC00EF28C2 /* SnapshotViewMatcher.swift */; };
1C92E5EC1FC6F2E300EF28C2 /* SnapshotViewExpecation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5EB1FC6F2E300EF28C2 /* SnapshotViewExpecation.swift */; };
1C92E5EC1FC6F2E300EF28C2 /* SnapshotViewExpectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5EB1FC6F2E300EF28C2 /* SnapshotViewExpectation.swift */; };
1C92E5EF1FC6F99100EF28C2 /* Recordable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5EE1FC6F99100EF28C2 /* Recordable.swift */; };
1C92E5F41FC70B8A00EF28C2 /* SaveImageToDisk.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5F31FC70B8A00EF28C2 /* SaveImageToDisk.swift */; };
1C92E5F81FC70C3B00EF28C2 /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5F71FC70C3B00EF28C2 /* Environment.swift */; };
Expand Down Expand Up @@ -52,18 +54,21 @@
1C0FF4561FC823A5003B8B22 /* AddAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAttachment.swift; sourceTree = "<group>"; };
1C0FF4581FC8294A003B8B22 /* UIImage+Diff.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Diff.swift"; sourceTree = "<group>"; };
1C7F06691FC8840B0078CA7A /* Recordable+XCTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Recordable+XCTestCase.swift"; sourceTree = "<group>"; };
1C92A5051FC9736000E6C817 /* CALayer+Image.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Image.swift"; sourceTree = "<group>"; };
1C92A5071FC9759E00E6C817 /* SnapshotLayerMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotLayerMatcher.swift; sourceTree = "<group>"; };
1C92A50A1FC9776D00E6C817 /* SnapshotLayerExpectation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotLayerExpectation.swift; sourceTree = "<group>"; };
1C92A5131FC9808100E6C817 /* Interoperability.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Interoperability.swift; sourceTree = "<group>"; };
1C92A5251FC998E200E6C817 /* Snap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Snap.h; sourceTree = "<group>"; };
1C92E5B91FC6E47300EF28C2 /* Snap.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Snap.framework; sourceTree = BUILT_PRODUCTS_DIR; };
1C92E5BC1FC6E47300EF28C2 /* Snap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Snap.h; sourceTree = "<group>"; };
1C92E5BD1FC6E47300EF28C2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1C92E5C21FC6E47300EF28C2 /* SnapTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SnapTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
1C92E5C71FC6E47300EF28C2 /* SnapTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapTests.swift; sourceTree = "<group>"; };
1C92E5C91FC6E47300EF28C2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1C92E5D71FC6E52100EF28C2 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
1C92E5E01FC6E87000EF28C2 /* UIView+Render.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Render.swift"; sourceTree = "<group>"; };
1C92E5E41FC6F25500EF28C2 /* Expectation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Expectation.swift; sourceTree = "<group>"; };
1C92E5E71FC6F28500EF28C2 /* Matcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Matcher.swift; sourceTree = "<group>"; };
1C92E5E91FC6F2AC00EF28C2 /* SnapshotViewMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotViewMatcher.swift; sourceTree = "<group>"; };
1C92E5EB1FC6F2E300EF28C2 /* SnapshotViewExpecation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotViewExpecation.swift; sourceTree = "<group>"; };
1C92E5EB1FC6F2E300EF28C2 /* SnapshotViewExpectation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnapshotViewExpectation.swift; sourceTree = "<group>"; };
1C92E5EE1FC6F99100EF28C2 /* Recordable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Recordable.swift; sourceTree = "<group>"; };
1C92E5F31FC70B8A00EF28C2 /* SaveImageToDisk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SaveImageToDisk.swift; sourceTree = "<group>"; };
1C92E5F71FC70C3B00EF28C2 /* Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Environment.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -99,6 +104,23 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
1C92A5041FC9735500E6C817 /* CALayer */ = {
isa = PBXGroup;
children = (
1C92A5051FC9736000E6C817 /* CALayer+Image.swift */,
);
path = CALayer;
sourceTree = "<group>";
};
1C92A5121FC9808100E6C817 /* Interoperability */ = {
isa = PBXGroup;
children = (
1C92A5131FC9808100E6C817 /* Interoperability.swift */,
1C92A5251FC998E200E6C817 /* Snap.h */,
);
path = Interoperability;
sourceTree = "<group>";
};
1C92E5AF1FC6E47300EF28C2 = {
isa = PBXGroup;
children = (
Expand All @@ -121,7 +143,6 @@
1C92E5BB1FC6E47300EF28C2 /* Snap */ = {
isa = PBXGroup;
children = (
1C92E5BC1FC6E47300EF28C2 /* Snap.h */,
1C92E5BD1FC6E47300EF28C2 /* Info.plist */,
1C92E5DC1FC6E66900EF28C2 /* Core */,
);
Expand Down Expand Up @@ -158,6 +179,7 @@
1C92E5DD1FC6E85300EF28C2 /* Infrastructure */ = {
isa = PBXGroup;
children = (
1C92A5121FC9808100E6C817 /* Interoperability */,
1CD197081FC8393100263A55 /* Assembly */,
1C92E5DE1FC6E85B00EF28C2 /* Extension */,
1C92E5F51FC70C2800EF28C2 /* Utils */,
Expand All @@ -168,6 +190,7 @@
1C92E5DE1FC6E85B00EF28C2 /* Extension */ = {
isa = PBXGroup;
children = (
1C92A5041FC9735500E6C817 /* CALayer */,
1C92E6061FC7429D00EF28C2 /* UIImage */,
1C92E5DF1FC6E86500EF28C2 /* UIView */,
);
Expand Down Expand Up @@ -196,8 +219,8 @@
1C92E5E31FC6F24B00EF28C2 /* Expectation */ = {
isa = PBXGroup;
children = (
1C92E5E41FC6F25500EF28C2 /* Expectation.swift */,
1C92E5EB1FC6F2E300EF28C2 /* SnapshotViewExpecation.swift */,
1C92E5EB1FC6F2E300EF28C2 /* SnapshotViewExpectation.swift */,
1C92A50A1FC9776D00E6C817 /* SnapshotLayerExpectation.swift */,
);
path = Expectation;
sourceTree = "<group>";
Expand All @@ -207,6 +230,7 @@
children = (
1C92E5E71FC6F28500EF28C2 /* Matcher.swift */,
1C92E5E91FC6F2AC00EF28C2 /* SnapshotViewMatcher.swift */,
1C92A5071FC9759E00E6C817 /* SnapshotLayerMatcher.swift */,
);
path = Matcher;
sourceTree = "<group>";
Expand Down Expand Up @@ -303,7 +327,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
1C92E5CA1FC6E47300EF28C2 /* Snap.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -364,6 +387,7 @@
};
1C92E5C11FC6E47300EF28C2 = {
CreatedOnToolsVersion = 9.1;
LastSwiftMigration = 0910;
ProvisioningStyle = Automatic;
};
};
Expand Down Expand Up @@ -433,7 +457,8 @@
buildActionMask = 2147483647;
files = (
1C92E6031FC71DC400EF28C2 /* Reference.swift in Sources */,
1C92E5E51FC6F25500EF28C2 /* Expectation.swift in Sources */,
1C92A50B1FC9776D00E6C817 /* SnapshotLayerExpectation.swift in Sources */,
1C92A5091FC975E400E6C817 /* SnapshotLayerMatcher.swift in Sources */,
1C0FF4551FC82234003B8B22 /* UIImage+Normalized.swift in Sources */,
1C92E5C81FC6E47300EF28C2 /* SnapTests.swift in Sources */,
1C0FF4531FC82229003B8B22 /* UIImage+Context.swift in Sources */,
Expand All @@ -442,19 +467,21 @@
1CD197121FC839C400263A55 /* Assembly+Matchers.swift in Sources */,
1C92E5E81FC6F28500EF28C2 /* Matcher.swift in Sources */,
1C92E5E11FC6E87000EF28C2 /* UIView+Render.swift in Sources */,
1C92A5141FC9808100E6C817 /* Interoperability.swift in Sources */,
1C92E6051FC736FF00EF28C2 /* CompareImages.swift in Sources */,
1C92E6081FC742AA00EF28C2 /* UIImage+Compare.swift in Sources */,
1CD1970A1FC8397E00263A55 /* Assembly.swift in Sources */,
1C0FF4591FC8294A003B8B22 /* UIImage+Diff.swift in Sources */,
1C92E5EF1FC6F99100EF28C2 /* Recordable.swift in Sources */,
1C92E5FA1FC70CAD00EF28C2 /* ApplicationEnvironment.swift in Sources */,
1C92E5EC1FC6F2E300EF28C2 /* SnapshotViewExpecation.swift in Sources */,
1C92E5EC1FC6F2E300EF28C2 /* SnapshotViewExpectation.swift in Sources */,
1CD1970C1FC839A200263A55 /* Assembly+Actions.swift in Sources */,
1C92E60A1FC7825F00EF28C2 /* ExtractViewImage.swift in Sources */,
1C92E6011FC714D700EF28C2 /* TestTarget.swift in Sources */,
1C7F066B1FC884110078CA7A /* Recordable+XCTestCase.swift in Sources */,
1C0FF4571FC823A5003B8B22 /* AddAttachment.swift in Sources */,
1C92E5FD1FC70D5500EF28C2 /* Path.swift in Sources */,
1C92A5061FC9736000E6C817 /* CALayer+Image.swift in Sources */,
1C92E5F41FC70B8A00EF28C2 /* SaveImageToDisk.swift in Sources */,
1C92E5F81FC70C3B00EF28C2 /* Environment.swift in Sources */,
);
Expand Down Expand Up @@ -632,12 +659,15 @@
1C92E5D11FC6E47300EF28C2 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 3ZGLM2XX3U;
INFOPLIST_FILE = SnapTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = in.skydev.SnapTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
Expand All @@ -646,12 +676,14 @@
1C92E5D21FC6E47300EF28C2 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 3ZGLM2XX3U;
INFOPLIST_FILE = SnapTests/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = in.skydev.SnapTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 4.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
Expand Down
1 change: 0 additions & 1 deletion Snap/Core/Application/Expectation/Expectation.swift

This file was deleted.

18 changes: 18 additions & 0 deletions Snap/Core/Application/Expectation/SnapshotLayerExpectation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import UIKit
import XCTest

// MARK: - XCTestCase + CALayer Expectation

extension XCTestCase {
public func expect(_ layer: CALayer, function: String = #function, file: String = #file ) -> Matcher {
let testTarget = TestTarget(
function: function,
file: file
)
return resolver.makeMatcher(
with: layer,
isRecording: isRecording,
tesTarget: testTarget
)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import UIKit
import XCTest

// MARK: - XCTestCase + Expectation
// MARK: - XCTestCase + View Expectation

extension XCTestCase: Expectation {
extension XCTestCase {
public func expect(_ view: UIView, function: String = #function, file: String = #file ) -> Matcher {
let testTarget = TestTarget(
function: function,
Expand Down
35 changes: 35 additions & 0 deletions Snap/Core/Application/Matcher/SnapshotLayerMatcher.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import UIKit

protocol SnapshotLayerMatcherProvider {
func makeMatcher(with layer: CALayer, isRecording: Bool, tesTarget: TestTarget) -> Matcher
}

struct SnapshotLayerMatcher: Matcher {

private let layer: CALayer
private let isRecording: Bool
private let testTarget: TestTarget
private let viewMatcherProvider: SnapshotViewMatcherProvider

init(layer: CALayer,
isRecording: Bool,
testTarget: TestTarget,
viewMatcherProvider: SnapshotViewMatcherProvider)
{
self.layer = layer
self.isRecording = isRecording
self.testTarget = testTarget
self.viewMatcherProvider = viewMatcherProvider
}

func toMatchSnapshot() {
let view = UIView(frame: layer.frame)
view.layer.insertSublayer(layer, at: 0)

viewMatcherProvider.makeMatcher(
with: view,
isRecording: isRecording,
tesTarget: testTarget
).toMatchSnapshot()
}
}
13 changes: 13 additions & 0 deletions Snap/Core/Infrastructure/Assembly/Assembly+Matchers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,16 @@ extension Assembly: SnapshotViewMatcherProvider {
)
}
}

// MARK: - SnapshotLayerMatcherProvider

extension Assembly: SnapshotLayerMatcherProvider {
func makeMatcher(with layer: CALayer, isRecording: Bool, tesTarget: TestTarget) -> Matcher {
return SnapshotLayerMatcher(
layer: layer,
isRecording: isRecording,
testTarget: tesTarget,
viewMatcherProvider: self
)
}
}
14 changes: 14 additions & 0 deletions Snap/Core/Infrastructure/Extension/CALayer/CALayer+Image.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import UIKit

extension CALayer {
/// Extract image from CALayer
func image() -> UIImage? {
defer {
UIGraphicsEndImageContext()
}
UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, contentsScale)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
render(in: context)
return UIGraphicsGetImageFromCurrentImageContext()
}
}
Loading

0 comments on commit dc3e86d

Please sign in to comment.