diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..224bff5 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/Pods \ No newline at end of file diff --git a/.swiftlint.yml b/.swiftlint.yml index 208ace2..c7da76a 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -4,6 +4,7 @@ disabled_rules: excluded: - SnapTests + - Pods file_length: warning: 200 diff --git a/.travis.yml b/.travis.yml index 5e9932f..974da22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,12 @@ language: objective-c +cache: cocoapods osx_image: xcode9.2 sudo: required install: - ./.scripts/install-swiftlint.sh + - pod install script: - swiftlint - - xcodebuild -scheme Snap -project ./Snap.xcodeproj -destination 'platform=iOS Simulator,name=iPhone 7' test \ No newline at end of file + - xcodebuild -scheme Snap -workspace ./Snap.xcworkspace -destination 'platform=iOS Simulator,name=iPhone 7' test | xcpretty \ No newline at end of file diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..b8e5a75 --- /dev/null +++ b/Podfile @@ -0,0 +1,13 @@ +platform :ios, '9.0' + +target 'Snap' do + use_frameworks! + + # Pods for Snap + + target 'SnapTests' do + inherit! :search_paths + pod 'CwlPreconditionTesting', :git => 'https://github.com/mattgallagher/CwlPreconditionTesting.git' + pod 'CwlCatchException', :git => 'https://github.com/mattgallagher/CwlCatchException.git' + end +end diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..e4d6855 --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,30 @@ +PODS: + - CwlCatchException (1.0.2) + - CwlPreconditionTesting (1.1.0): + - CwlCatchException + +DEPENDENCIES: + - CwlCatchException (from `https://github.com/mattgallagher/CwlCatchException.git`) + - CwlPreconditionTesting (from `https://github.com/mattgallagher/CwlPreconditionTesting.git`) + +EXTERNAL SOURCES: + CwlCatchException: + :git: https://github.com/mattgallagher/CwlCatchException.git + CwlPreconditionTesting: + :git: https://github.com/mattgallagher/CwlPreconditionTesting.git + +CHECKOUT OPTIONS: + CwlCatchException: + :commit: b14c111e9b33cd142bd4bc75c482cfd5c3490923 + :git: https://github.com/mattgallagher/CwlCatchException.git + CwlPreconditionTesting: + :commit: b2e4800abf854366d4492051069cce7b44d20ba1 + :git: https://github.com/mattgallagher/CwlPreconditionTesting.git + +SPEC CHECKSUMS: + CwlCatchException: 70a52ae44ea5d46db7bd385f801a94942420cd8c + CwlPreconditionTesting: d9b35890c80b34668cd90da5bef077fd817a99fc + +PODFILE CHECKSUM: 540c3fa6ae55d09ebef0fe29fae919227da61157 + +COCOAPODS: 1.4.0.beta.2 diff --git a/Snap.xcodeproj/project.pbxproj b/Snap.xcodeproj/project.pbxproj index 74f7efb..d8c65d1 100644 --- a/Snap.xcodeproj/project.pbxproj +++ b/Snap.xcodeproj/project.pbxproj @@ -11,6 +11,9 @@ 1C0FF4551FC82234003B8B22 /* UIImage+Normalized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C0FF4541FC82234003B8B22 /* UIImage+Normalized.swift */; }; 1C0FF4571FC823A5003B8B22 /* AddAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C0FF4561FC823A5003B8B22 /* AddAttachment.swift */; }; 1C0FF4591FC8294A003B8B22 /* UIImage+Diff.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C0FF4581FC8294A003B8B22 /* UIImage+Diff.swift */; }; + 1C5B824B1FE3E288006A245B /* TestTargetSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C5B824A1FE3E288006A245B /* TestTargetSpec.swift */; }; + 1C5B824E1FE3E412006A245B /* EnvironmentStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C5B824D1FE3E412006A245B /* EnvironmentStub.swift */; }; + 1C5B82561FE40666006A245B /* XCTestCase+CustomAsserts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C5B82551FE40666006A245B /* XCTestCase+CustomAsserts.swift */; }; 1C7F066B1FC884110078CA7A /* Recordable+XCTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C7F06691FC8840B0078CA7A /* Recordable+XCTestCase.swift */; }; 1C8D0D561FCDE6AE00A87260 /* CALayerImageSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C8D0D551FCDE6AE00A87260 /* CALayerImageSpec.swift */; }; 1C8D0D591FCDE95100A87260 /* UIImageNormalizedSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C8D0D581FCDE95100A87260 /* UIImageNormalizedSpec.swift */; }; @@ -70,6 +73,8 @@ FC7244381FDAD1D800DC94E6 /* Path.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5FC1FC70D5500EF28C2 /* Path.swift */; }; FC7244391FDAD1D800DC94E6 /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5F71FC70C3B00EF28C2 /* Environment.swift */; }; FC72443A1FDAD1D800DC94E6 /* ApplicationEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1C92E5F91FC70CAD00EF28C2 /* ApplicationEnvironment.swift */; }; + 75EDFF3A54FE584F81497817 /* Pods_SnapTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6F75B2C4707E8B89C6EA0C60 /* Pods_SnapTests.framework */; }; + D260F0D2E59D051381E2578D /* Pods_Snap.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA19B2B7B2A7726EE4ACCB1B /* Pods_Snap.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -87,6 +92,9 @@ 1C0FF4541FC82234003B8B22 /* UIImage+Normalized.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Normalized.swift"; sourceTree = ""; }; 1C0FF4561FC823A5003B8B22 /* AddAttachment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddAttachment.swift; sourceTree = ""; }; 1C0FF4581FC8294A003B8B22 /* UIImage+Diff.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Diff.swift"; sourceTree = ""; }; + 1C5B824A1FE3E288006A245B /* TestTargetSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestTargetSpec.swift; sourceTree = ""; }; + 1C5B824D1FE3E412006A245B /* EnvironmentStub.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentStub.swift; sourceTree = ""; }; + 1C5B82551FE40666006A245B /* XCTestCase+CustomAsserts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTestCase+CustomAsserts.swift"; sourceTree = ""; }; 1C7F06691FC8840B0078CA7A /* Recordable+XCTestCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Recordable+XCTestCase.swift"; sourceTree = ""; }; 1C8D0D551FCDE6AE00A87260 /* CALayerImageSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CALayerImageSpec.swift; sourceTree = ""; }; 1C8D0D581FCDE95100A87260 /* UIImageNormalizedSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImageNormalizedSpec.swift; sourceTree = ""; }; @@ -123,6 +131,12 @@ 1CD1970D1FC839AE00263A55 /* Assembly+Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Assembly+Utils.swift"; sourceTree = ""; }; 1CD197111FC839C400263A55 /* Assembly+Matchers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Assembly+Matchers.swift"; sourceTree = ""; }; 1CEF930B1FDA9FB800C5CDA6 /* TestTarget+Reference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TestTarget+Reference.swift"; sourceTree = ""; }; + 560BE953836BE3D24C1C45A9 /* Pods-Snap.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Snap.release.xcconfig"; path = "Pods/Target Support Files/Pods-Snap/Pods-Snap.release.xcconfig"; sourceTree = ""; }; + 6F75B2C4707E8B89C6EA0C60 /* Pods_SnapTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_SnapTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + A804418F60776A5AE4188C28 /* Pods-SnapTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SnapTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SnapTests/Pods-SnapTests.debug.xcconfig"; sourceTree = ""; }; + D14498CA79AC7192B3C31DBF /* Pods-Snap.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Snap.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Snap/Pods-Snap.debug.xcconfig"; sourceTree = ""; }; + EA19B2B7B2A7726EE4ACCB1B /* Pods_Snap.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Snap.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F852769B4219F38340E8ECFF /* Pods-SnapTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SnapTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-SnapTests/Pods-SnapTests.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -130,6 +144,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D260F0D2E59D051381E2578D /* Pods_Snap.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -138,15 +153,58 @@ buildActionMask = 2147483647; files = ( 1C92E5C31FC6E47300EF28C2 /* Snap.framework in Frameworks */, + 75EDFF3A54FE584F81497817 /* Pods_SnapTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 1C5B82481FE3E274006A245B /* Domain */ = { + isa = PBXGroup; + children = ( + 1C5B82491FE3E274006A245B /* Model */, + ); + path = Domain; + sourceTree = ""; + }; + 1C5B82491FE3E274006A245B /* Model */ = { + isa = PBXGroup; + children = ( + 1C5B824A1FE3E288006A245B /* TestTargetSpec.swift */, + 1C5B824C1FE3E3F5006A245B /* Test Doubles */, + ); + path = Model; + sourceTree = ""; + }; + 1C5B824C1FE3E3F5006A245B /* Test Doubles */ = { + isa = PBXGroup; + children = ( + 1C5B824D1FE3E412006A245B /* EnvironmentStub.swift */, + ); + path = "Test Doubles"; + sourceTree = ""; + }; + 1C5B82531FE4064F006A245B /* Extension */ = { + isa = PBXGroup; + children = ( + 1C5B82541FE4064F006A245B /* XCTestCase */, + ); + path = Extension; + sourceTree = ""; + }; + 1C5B82541FE4064F006A245B /* XCTestCase */ = { + isa = PBXGroup; + children = ( + 1C5B82551FE40666006A245B /* XCTestCase+CustomAsserts.swift */, + ); + path = XCTestCase; + sourceTree = ""; + }; 1C8D0D511FCDE68A00A87260 /* Core */ = { isa = PBXGroup; children = ( + 1C5B82481FE3E274006A245B /* Domain */, 1C8D0D521FCDE68A00A87260 /* Infrastructure */, ); path = Core; @@ -189,6 +247,7 @@ 1C8D0D5A1FCDEA2D00A87260 /* Resources */ = { isa = PBXGroup; children = ( + 1C5B82531FE4064F006A245B /* Extension */, 1C8D0D5B1FCDEA2D00A87260 /* Image */, ); path = Resources; @@ -227,6 +286,7 @@ 1C92E5C61FC6E47300EF28C2 /* SnapTests */, 1C92E5BA1FC6E47300EF28C2 /* Products */, 1C92E5D61FC6E52100EF28C2 /* Frameworks */, + 52BFE47264FBF47A74E3A154 /* Pods */, ); sourceTree = ""; }; @@ -263,6 +323,8 @@ isa = PBXGroup; children = ( 1C92E5D71FC6E52100EF28C2 /* XCTest.framework */, + EA19B2B7B2A7726EE4ACCB1B /* Pods_Snap.framework */, + 6F75B2C4707E8B89C6EA0C60 /* Pods_SnapTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -422,6 +484,17 @@ path = Assembly; sourceTree = ""; }; + 52BFE47264FBF47A74E3A154 /* Pods */ = { + isa = PBXGroup; + children = ( + D14498CA79AC7192B3C31DBF /* Pods-Snap.debug.xcconfig */, + 560BE953836BE3D24C1C45A9 /* Pods-Snap.release.xcconfig */, + A804418F60776A5AE4188C28 /* Pods-SnapTests.debug.xcconfig */, + F852769B4219F38340E8ECFF /* Pods-SnapTests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -439,10 +512,12 @@ isa = PBXNativeTarget; buildConfigurationList = 1C92E5CD1FC6E47300EF28C2 /* Build configuration list for PBXNativeTarget "Snap" */; buildPhases = ( + 0E7F7AFCCA53F15C4A753503 /* [CP] Check Pods Manifest.lock */, 1C92E5B41FC6E47300EF28C2 /* Sources */, 1C92E5B51FC6E47300EF28C2 /* Frameworks */, 1C92E5B61FC6E47300EF28C2 /* Headers */, 1C92E5B71FC6E47300EF28C2 /* Resources */, + 7D360E1D2DBE8E37464EB9B3 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -457,10 +532,13 @@ isa = PBXNativeTarget; buildConfigurationList = 1C92E5D01FC6E47300EF28C2 /* Build configuration list for PBXNativeTarget "SnapTests" */; buildPhases = ( + 02177E8C983A84F2B8933142 /* [CP] Check Pods Manifest.lock */, 1C7F066C1FC889DC0078CA7A /* Swiftlint */, 1C92E5BE1FC6E47300EF28C2 /* Sources */, 1C92E5BF1FC6E47300EF28C2 /* Frameworks */, 1C92E5C01FC6E47300EF28C2 /* Resources */, + 4B2C956E692B355B2F811DFE /* [CP] Embed Pods Frameworks */, + FE26D11976EECC9F3B7F1A3F /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -531,6 +609,42 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 02177E8C983A84F2B8933142 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-SnapTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 0E7F7AFCCA53F15C4A753503 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Snap-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; 1C7F066C1FC889DC0078CA7A /* Swiftlint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -545,6 +659,56 @@ shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; }; + 4B2C956E692B355B2F811DFE /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-SnapTests/Pods-SnapTests-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/CwlCatchException/CwlCatchException.framework", + "${BUILT_PRODUCTS_DIR}/CwlPreconditionTesting/CwlPreconditionTesting.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CwlCatchException.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CwlPreconditionTesting.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SnapTests/Pods-SnapTests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 7D360E1D2DBE8E37464EB9B3 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Snap/Pods-Snap-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + FE26D11976EECC9F3B7F1A3F /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SnapTests/Pods-SnapTests-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -601,13 +765,16 @@ 1C92E5E81FC6F28500EF28C2 /* Matcher.swift in Sources */, 1C92E5E11FC6E87000EF28C2 /* UIView+Render.swift in Sources */, 1C92A5141FC9808100E6C817 /* Interoperability.swift in Sources */, + 1C5B824E1FE3E412006A245B /* EnvironmentStub.swift in Sources */, 1C92E6051FC736FF00EF28C2 /* CompareImages.swift in Sources */, 1CEF930D1FDA9FC100C5CDA6 /* TestTarget+Reference.swift in Sources */, 1C92E6081FC742AA00EF28C2 /* UIImage+Compare.swift in Sources */, + 1C5B824B1FE3E288006A245B /* TestTargetSpec.swift in Sources */, 1CD1970A1FC8397E00263A55 /* Assembly.swift in Sources */, 1C8D0D591FCDE95100A87260 /* UIImageNormalizedSpec.swift in Sources */, 1C0FF4591FC8294A003B8B22 /* UIImage+Diff.swift in Sources */, 1C92E5EF1FC6F99100EF28C2 /* Recordable.swift in Sources */, + 1C5B82561FE40666006A245B /* XCTestCase+CustomAsserts.swift in Sources */, 1C92E5FA1FC70CAD00EF28C2 /* ApplicationEnvironment.swift in Sources */, 1C92E5EC1FC6F2E300EF28C2 /* SnapshotViewExpectation.swift in Sources */, 1CD1970C1FC839A200263A55 /* Assembly+Actions.swift in Sources */, @@ -749,6 +916,7 @@ }; 1C92E5CE1FC6E47300EF28C2 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = D14498CA79AC7192B3C31DBF /* Pods-Snap.debug.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; @@ -782,6 +950,7 @@ }; 1C92E5CF1FC6E47300EF28C2 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 560BE953836BE3D24C1C45A9 /* Pods-Snap.release.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = ""; @@ -814,6 +983,7 @@ }; 1C92E5D11FC6E47300EF28C2 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = A804418F60776A5AE4188C28 /* Pods-SnapTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; @@ -832,6 +1002,7 @@ }; 1C92E5D21FC6E47300EF28C2 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = F852769B4219F38340E8ECFF /* Pods-SnapTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CLANG_ENABLE_MODULES = YES; diff --git a/Snap.xcodeproj/xcshareddata/xcschemes/Snap.xcscheme b/Snap.xcodeproj/xcshareddata/xcschemes/Snap.xcscheme index cfa7d63..637e8b3 100644 --- a/Snap.xcodeproj/xcshareddata/xcschemes/Snap.xcscheme +++ b/Snap.xcodeproj/xcshareddata/xcschemes/Snap.xcscheme @@ -1,6 +1,6 @@ + + + + + + diff --git a/Snap/Core/Application/Actions/CompareImages.swift b/Snap/Core/Application/Actions/CompareImages.swift index f7c28ac..fe4a5e8 100644 --- a/Snap/Core/Application/Actions/CompareImages.swift +++ b/Snap/Core/Application/Actions/CompareImages.swift @@ -22,13 +22,13 @@ struct CompareImages { } let reference = testTarget.reference(for: .reference).path - guard fileManager.fileExists(atPath: reference.absoluteString) else { - XCTFail("🚫 Reference image not found [`\(reference)`]") + guard fileManager.fileExists(atPath: reference.path) else { + XCTFail("🚫 Reference image not found [`\(reference.path)`]") return } - guard let referenceImage = UIImage(contentsOfFile: reference.standardizedFileURL.absoluteString) else { - XCTFail("🚫 Error loading reference image [`\(reference)`]") + guard let referenceImage = UIImage(contentsOfFile: reference.path) else { + XCTFail("🚫 Error loading reference image [`\(reference.path)`]") return } @@ -43,13 +43,13 @@ struct CompareImages { try referenceImage.compare(with: processedImage) } catch CompareError.notEqualSize(let referenceSize, let comparedSize) { self.process(failedImage: processedImage, reference: referenceImage, testTarget: testTarget) - XCTFail("📏 Image sizes should be equals, reference image size: \(referenceSize), compared image size: \(comparedSize)") + XCTFail("📏 Image sizes should be equals, reference image size: \(referenceSize), compared image size: \(comparedSize)") } catch CompareError.invalidImageSize { self.process(failedImage: processedImage, reference: referenceImage, testTarget: testTarget) - XCTFail("📏 One of the images has 0 size") + XCTFail("📏 One of the images has 0 size") } catch CompareError.notEquals { self.process(failedImage: processedImage, reference: referenceImage, testTarget: testTarget) - XCTFail("≠ Images are not equal") + XCTFail("≠ Images are not equal") } catch CompareError.notEqualMetadata { self.process(failedImage: processedImage, reference: referenceImage, testTarget: testTarget) XCTFail("👾 Images have different metadata information") diff --git a/Snap/Core/Application/Actions/ExtractViewImage.swift b/Snap/Core/Application/Actions/ExtractViewImage.swift index bcac0f9..690e57b 100644 --- a/Snap/Core/Application/Actions/ExtractViewImage.swift +++ b/Snap/Core/Application/Actions/ExtractViewImage.swift @@ -2,7 +2,7 @@ import UIKit import XCTest struct ExtractViewImage { - + private let saveImageToDisk: SaveImageToDisk private let addAttachment: AddAttachment @@ -20,6 +20,6 @@ struct ExtractViewImage { saveImageToDisk.execute(with: image, with: testTarget.reference(for: .reference)) addAttachment.execute(with: image, type: .reference) - XCTFail("⚠️ Test ran in record mode, reference image has been saved to \(testTarget.reference(for: .reference).path), now remove `isRecording` in order to perform the snapshot comparsion.") + XCTFail("⚠️ Test ran in record mode, reference image has been saved to \(testTarget.reference(for: .reference).path.path), now remove `isRecording` in order to perform the snapshot comparsion.") } } diff --git a/Snap/Core/Application/Actions/SaveImageToDisk.swift b/Snap/Core/Application/Actions/SaveImageToDisk.swift index 7e6905d..5faed49 100644 --- a/Snap/Core/Application/Actions/SaveImageToDisk.swift +++ b/Snap/Core/Application/Actions/SaveImageToDisk.swift @@ -4,7 +4,7 @@ struct SaveImageToDisk { private let environment: Environment private let fileManager: FileManager - + init(environment: Environment, fileManager: FileManager) { @@ -16,11 +16,11 @@ struct SaveImageToDisk { let referenceImage = UIImagePNGRepresentation(image) do { - try fileManager.createDirectory(atPath: reference.directory.absoluteString, withIntermediateDirectories: true) + try fileManager.createDirectory(atPath: reference.directory.path, withIntermediateDirectories: true) } catch { fatalError("🚨 Error creating reference image directory ['\(reference.directory)']") } - guard fileManager.createFile(atPath: reference.path.absoluteString, contents: referenceImage) else { + guard fileManager.createFile(atPath: reference.path.path, contents: referenceImage) else { fatalError("🚨 Error saving reference image into ['\(reference.path)']") } } diff --git a/Snap/Core/Domain/Model/TestTarget+Reference.swift b/Snap/Core/Domain/Model/TestTarget+Reference.swift index 93f4525..91d674b 100644 --- a/Snap/Core/Domain/Model/TestTarget+Reference.swift +++ b/Snap/Core/Domain/Model/TestTarget+Reference.swift @@ -13,7 +13,7 @@ extension TestTarget { let functionName = function.replacingOccurrences(of: "()", with: "").lowercased() let path = "\(self.path(for: type))\(classFile)/" let directory = url.appendingPathComponent(path) - let name = named ?? functionName + let name = (named ?? functionName).replacingOccurrences(of: " ", with: "_") let pathUrl = directory.appendingPathComponent("\(type.rawValue)_\(name)\(scale).png") return Reference( @@ -32,14 +32,14 @@ extension TestTarget { guard let referenceImagePath = environment.get(Path.referenceImage) else { fatalError("🚧 You need to configure the reference image path environment variable `\(Path.referenceImage)`") } - + let fileURL = URL(fileURLWithPath: referenceImagePath) var isDir: ObjCBool = true - let referenceImagePathExists = fileManager.fileExists(atPath: referenceImagePath, isDirectory: &isDir) + let referenceImagePathExists = fileManager.fileExists(atPath: fileURL.path, isDirectory: &isDir) - guard referenceImagePathExists, let url = URL(string: referenceImagePath) else { + guard referenceImagePathExists else { fatalError("🚫 Provided path ['\(referenceImagePath)'] for `\(Path.referenceImage)` is invalid") } - return url + return fileURL } private func path(for type: Type) -> String { diff --git a/SnapTests/Core/Domain/Model/Test Doubles/EnvironmentStub.swift b/SnapTests/Core/Domain/Model/Test Doubles/EnvironmentStub.swift new file mode 100644 index 0000000..0a4d3d3 --- /dev/null +++ b/SnapTests/Core/Domain/Model/Test Doubles/EnvironmentStub.swift @@ -0,0 +1,9 @@ +import Foundation + +final class EnvironmentStub: Environment { + var keys = [String: String]() + + func get(_ key: String) -> String? { + return keys[key] + } +} diff --git a/SnapTests/Core/Domain/Model/TestTargetSpec.swift b/SnapTests/Core/Domain/Model/TestTargetSpec.swift new file mode 100644 index 0000000..46f5dbf --- /dev/null +++ b/SnapTests/Core/Domain/Model/TestTargetSpec.swift @@ -0,0 +1,133 @@ +import XCTest + +final class TestTargetSpec: XCTestCase { + + private var environment: EnvironmentStub! + + override func setUp() { + super.setUp() + environment = EnvironmentStub() + } + + override func tearDown() { + environment = nil + super.tearDown() + } + + func test_should_throw_assertion_if_environment_path_is_not_set() { + givenEnviromentIsNotSet() + + let reference = givenTestTarget() + + assertThrowException() { + let _ = reference.reference(for: .reference).path + } + } + + func test_should_no_throw_if_environment_path_is_set() { + givenEnvironment() + + let reference = givenTestTarget() + + assertNoThrowException() { + let _ = reference.reference(for: .reference).path + } + } + + func test_should_throw_assertion_if_given_path_is_invalid() { + givenEnvironment(with: "invalid/path/") + + let reference = givenTestTarget() + + assertThrowException() { + let _ = reference.reference(for: .reference).path + } + } + + func test_should_return_correct_path_for_test_target() { + givenEnvironment() + + let reference = givenTestTarget() + + let referencePath = reference.reference(for: .reference).path + let expectedPath = "\(currentPath)/Snap/file/reference_function@2x.png" + + XCTAssertEqual(referencePath.path, expectedPath) + } + + func test_should_return_correct_path_for_test_target_with_reference_path_with_spaces() { + givenEnvironment() + + let reference = givenTestTarget( + with: "function name" + ) + + let referencePath = reference.reference(for: .reference).path + let expectedPath = "\(currentPath)/Snap/file/reference_function_name@2x.png" + + XCTAssertEqual(referencePath.path, expectedPath) + } + + func test_should_return_correct_path_for_test_target_with_custom_name() { + givenEnvironment() + + let reference = givenTestTarget( + with: "function name", + named: "custom name" + ) + + let referencePath = reference.reference(for: .reference).path + let expectedPath = "\(currentPath)/Snap/file/reference_custom_name@2x.png" + + XCTAssertEqual(referencePath.path, expectedPath) + } + + func test_should_return_correct_path_for_different_test_targets() { + givenEnvironment() + + let reference = givenTestTarget( + with: "function name", + named: "custom name" + ) + + let referencePath = reference.reference(for: .reference).path + let failedPath = reference.reference(for: .failed).path + let diffPath = reference.reference(for: .diff).path + + let expectedReferencePath = "\(currentPath)/Snap/file/reference_custom_name@2x.png" + let expectedFailedPath = "\(currentPath)/Snap/Failed/file/failed_custom_name@2x.png" + let expectedDiffPath = "\(currentPath)/Snap/Diff/file/diff_custom_name@2x.png" + + XCTAssertEqual(referencePath.path, expectedReferencePath) + XCTAssertEqual(failedPath.path, expectedFailedPath) + XCTAssertEqual(diffPath.path, expectedDiffPath) + } +} + +// MARK: - Helpers + +extension TestTargetSpec { + private func givenEnviromentIsNotSet() { + environment.keys[Path.referenceImage] = nil + } + + private func givenEnvironment(with path: String? = FileManager.default.currentDirectoryPath) { + environment.keys[Path.referenceImage] = path + } + + private func givenTestTarget(with function: String = "function", + file: String = "file", + named: String? = nil) -> TestTarget + { + return TestTarget( + function: function, + file: file, + named: named, + fileManager: .default, + environment: environment + ) + } + var currentPath: String { + return FileManager.default.currentDirectoryPath + } +} diff --git a/SnapTests/Core/Infrastructure/Extension/CALayer/CALayerImageSpec.swift b/SnapTests/Core/Infrastructure/Extension/CALayer/CALayerImageSpec.swift index 266000b..7f94527 100644 --- a/SnapTests/Core/Infrastructure/Extension/CALayer/CALayerImageSpec.swift +++ b/SnapTests/Core/Infrastructure/Extension/CALayer/CALayerImageSpec.swift @@ -1,7 +1,7 @@ import XCTest import UIKit -class CALayerImageSpec: XCTestCase { +final class CALayerImageSpec: XCTestCase { func test_should_render_image_from_calayer() { let layer = CALayer() diff --git a/SnapTests/Core/Infrastructure/Extension/UIImage/UIImageCompareSpec.swift b/SnapTests/Core/Infrastructure/Extension/UIImage/UIImageCompareSpec.swift index 1a83518..1c5a811 100644 --- a/SnapTests/Core/Infrastructure/Extension/UIImage/UIImageCompareSpec.swift +++ b/SnapTests/Core/Infrastructure/Extension/UIImage/UIImageCompareSpec.swift @@ -1,6 +1,6 @@ import XCTest -class UIImageCompareSpec: XCTestCase { +final class UIImageCompareSpec: XCTestCase { func test_should_throw_if_image_sizes_are_not_the_equals() throws { let image1 = Image.fixture(.camera, from: self) diff --git a/SnapTests/Core/Infrastructure/Extension/UIImage/UIImageNormalizedSpec.swift b/SnapTests/Core/Infrastructure/Extension/UIImage/UIImageNormalizedSpec.swift index ddb0854..743dfca 100644 --- a/SnapTests/Core/Infrastructure/Extension/UIImage/UIImageNormalizedSpec.swift +++ b/SnapTests/Core/Infrastructure/Extension/UIImage/UIImageNormalizedSpec.swift @@ -1,7 +1,7 @@ import XCTest import UIKit -class UIImageNormalizedSpec: XCTestCase { +final class UIImageNormalizedSpec: XCTestCase { func test_should_normalize_image_into_data() { let image = Image.fixture(from: self) diff --git a/SnapTests/Resources/Extension/XCTestCase/XCTestCase+CustomAsserts.swift b/SnapTests/Resources/Extension/XCTestCase/XCTestCase+CustomAsserts.swift new file mode 100644 index 0000000..97745f2 --- /dev/null +++ b/SnapTests/Resources/Extension/XCTestCase/XCTestCase+CustomAsserts.swift @@ -0,0 +1,20 @@ +import XCTest +import CwlCatchException +import CwlPreconditionTesting + +extension XCTestCase { + func assertThrowException(f: @escaping () -> Void) { + let instruction = catchBadInstruction { + f() + } + + guard let _ = instruction else { + XCTFail("No exceptions were thrown") + return + } + } + + func assertNoThrowException(f: @escaping () -> Void) { + XCTAssertNil(catchBadInstruction { f() }) + } +}