second_curtain 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.gitignore +20 -0
- data/.travis.yml +7 -0
- data/CHANGELOG +20 -0
- data/Demo/Demo/ASHAppDelegate.h +15 -0
- data/Demo/Demo/ASHAppDelegate.m +18 -0
- data/Demo/Demo/ASHViewController.h +13 -0
- data/Demo/Demo/ASHViewController.m +30 -0
- data/Demo/Demo/Base.lproj/Main.storyboard +30 -0
- data/Demo/Demo/Demo-Info.plist +40 -0
- data/Demo/Demo/Demo-Prefix.pch +16 -0
- data/Demo/Demo/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
- data/Demo/Demo/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
- data/Demo/Demo/en.lproj/InfoPlist.strings +2 -0
- data/Demo/Demo/main.m +18 -0
- data/Demo/Demo.xcodeproj/project.pbxproj +517 -0
- data/Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/Demo.xccheckout +41 -0
- data/Demo/Demo.xcodeproj/project.xcworkspace/xcuserdata/ash.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme +96 -0
- data/Demo/Demo.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/xcschememanagement.plist +27 -0
- data/Demo/Demo.xcodeproj/xcuserdata/orta.xcuserdatad/xcschemes/xcschememanagement.plist +27 -0
- data/Demo/Demo.xcworkspace/contents.xcworkspacedata +1 -0
- data/Demo/Demo.xcworkspace/xcshareddata/Demo.xccheckout +41 -0
- data/Demo/Demo.xcworkspace/xcuserdata/ash.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/Demo/Demo.xcworkspace/xcuserdata/orta.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/Demo/DemoTests/DemoTests-Info.plist +22 -0
- data/Demo/DemoTests/DemoTests.m +52 -0
- data/Demo/DemoTests/ReferenceImages/ASHViewControllerSpec/a_view_controller_with_a_loaded_view_should_have_a_valid_snapshot@2x.png +0 -0
- data/Demo/DemoTests/ReferenceImages/ASHViewControllerSpec/views_should_be_green@2x.png +0 -0
- data/Demo/DemoTests/ReferenceImages/ASHViewControllerSpec/views_should_be_red@2x.png +0 -0
- data/Demo/DemoTests/en.lproj/InfoPlist.strings +2 -0
- data/Demo/Makefile +15 -0
- data/Demo/Podfile +16 -0
- data/Demo/Podfile.lock +21 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPBackwardCompatibility.h +42 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPBlockDefinedMatcher.h +25 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPDefines.h +17 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPDoubleTuple.h +13 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPExpect.h +45 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPFloatTuple.h +13 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatcher.h +20 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatcherHelpers.h +4 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beCloseTo.h +7 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beFalsy.h +3 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beGreaterThan.h +6 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beGreaterThanOrEqualTo.h +6 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beIdenticalTo.h +10 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beInTheRangeOf.h +6 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beInstanceOf.h +7 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beKindOf.h +5 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beLessThan.h +6 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beLessThanOrEqualTo.h +6 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beNil.h +5 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beSubclassOf.h +5 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beSupersetOf.h +4 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beTruthy.h +3 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beginWith.h +5 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+conformTo.h +3 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+contain.h +5 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+endWith.h +3 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+equal.h +5 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+haveCountOf.h +10 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+notify.h +4 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+raise.h +4 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+raiseWithReason.h +3 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+respondTo.h +3 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers.h +24 -0
- data/Demo/Pods/BuildHeaders/Expecta/EXPUnsupportedObject.h +11 -0
- data/Demo/Pods/BuildHeaders/Expecta/Expecta.h +27 -0
- data/Demo/Pods/BuildHeaders/Expecta/ExpectaSupport.h +64 -0
- data/Demo/Pods/BuildHeaders/Expecta/NSObject+Expecta.h +14 -0
- data/Demo/Pods/BuildHeaders/Expecta/NSValue+Expecta.h +8 -0
- data/Demo/Pods/BuildHeaders/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h +21 -0
- data/Demo/Pods/BuildHeaders/FBSnapshotTestCase/FBSnapshotTestCase.h +87 -0
- data/Demo/Pods/BuildHeaders/FBSnapshotTestCase/FBSnapshotTestController.h +147 -0
- data/Demo/Pods/BuildHeaders/FBSnapshotTestCase/UIImage+Compare.h +37 -0
- data/Demo/Pods/BuildHeaders/FBSnapshotTestCase/UIImage+Diff.h +37 -0
- data/Demo/Pods/BuildHeaders/Specta/SPTExample.h +14 -0
- data/Demo/Pods/BuildHeaders/Specta/SPTExampleGroup.h +40 -0
- data/Demo/Pods/BuildHeaders/Specta/SPTNestedReporter.h +5 -0
- data/Demo/Pods/BuildHeaders/Specta/SPTReporter.h +33 -0
- data/Demo/Pods/BuildHeaders/Specta/SPTSharedExampleGroups.h +17 -0
- data/Demo/Pods/BuildHeaders/Specta/SPTSpec.h +21 -0
- data/Demo/Pods/BuildHeaders/Specta/SPTXCTestCase.h +27 -0
- data/Demo/Pods/BuildHeaders/Specta/SPTXCTestReporter.h +9 -0
- data/Demo/Pods/BuildHeaders/Specta/Specta.h +70 -0
- data/Demo/Pods/BuildHeaders/Specta/SpectaSupport.h +46 -0
- data/Demo/Pods/BuildHeaders/Specta/SpectaTypes.h +3 -0
- data/Demo/Pods/BuildHeaders/Specta/SpectaUtility.h +14 -0
- data/Demo/Pods/BuildHeaders/Specta/XCTestCase+Specta.h +4 -0
- data/Demo/Pods/BuildHeaders/Specta/XCTestLog+Specta.h +7 -0
- data/Demo/Pods/BuildHeaders/Specta/XCTestRun+Specta.h +8 -0
- data/Demo/Pods/Expecta/LICENSE +19 -0
- data/Demo/Pods/Expecta/README.md +308 -0
- data/Demo/Pods/Expecta/src/EXPBackwardCompatibility.h +42 -0
- data/Demo/Pods/Expecta/src/EXPBackwardCompatibility.m +17 -0
- data/Demo/Pods/Expecta/src/EXPBlockDefinedMatcher.h +25 -0
- data/Demo/Pods/Expecta/src/EXPBlockDefinedMatcher.m +60 -0
- data/Demo/Pods/Expecta/src/EXPDefines.h +17 -0
- data/Demo/Pods/Expecta/src/EXPDoubleTuple.h +13 -0
- data/Demo/Pods/Expecta/src/EXPDoubleTuple.m +42 -0
- data/Demo/Pods/Expecta/src/EXPExpect.h +45 -0
- data/Demo/Pods/Expecta/src/EXPExpect.m +214 -0
- data/Demo/Pods/Expecta/src/EXPFloatTuple.h +13 -0
- data/Demo/Pods/Expecta/src/EXPFloatTuple.m +42 -0
- data/Demo/Pods/Expecta/src/EXPMatcher.h +20 -0
- data/Demo/Pods/Expecta/src/EXPUnsupportedObject.h +11 -0
- data/Demo/Pods/Expecta/src/EXPUnsupportedObject.m +20 -0
- data/Demo/Pods/Expecta/src/Expecta.h +27 -0
- data/Demo/Pods/Expecta/src/Expecta.m +15 -0
- data/Demo/Pods/Expecta/src/ExpectaSupport.h +64 -0
- data/Demo/Pods/Expecta/src/ExpectaSupport.m +187 -0
- data/Demo/Pods/Expecta/src/NSObject+Expecta.h +14 -0
- data/Demo/Pods/Expecta/src/NSValue+Expecta.h +8 -0
- data/Demo/Pods/Expecta/src/NSValue+Expecta.m +21 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatcherHelpers.h +4 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatcherHelpers.m +9 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beCloseTo.h +7 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beCloseTo.m +49 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beFalsy.h +3 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beFalsy.m +24 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beGreaterThan.h +6 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beGreaterThan.m +20 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beGreaterThanOrEqualTo.h +6 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beGreaterThanOrEqualTo.m +20 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beIdenticalTo.h +10 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beIdenticalTo.m +24 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beInTheRangeOf.h +6 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beInTheRangeOf.m +30 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beInstanceOf.h +7 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beInstanceOf.m +27 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beKindOf.h +5 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beKindOf.m +27 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beLessThan.h +6 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beLessThan.m +20 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beLessThanOrEqualTo.h +6 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beLessThanOrEqualTo.m +20 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beNil.h +5 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beNil.m +16 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beSubclassOf.h +5 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beSubclassOf.m +27 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beSupersetOf.h +4 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beSupersetOf.m +57 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beTruthy.h +3 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beTruthy.m +24 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beginWith.h +5 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beginWith.m +49 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+conformTo.h +3 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+conformTo.m +33 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+contain.h +5 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+contain.m +38 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+endWith.h +3 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+endWith.m +49 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+equal.h +5 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+equal.m +24 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+haveCountOf.h +10 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+haveCountOf.m +36 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+notify.h +4 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+notify.m +63 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+raise.h +4 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+raise.m +30 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+raiseWithReason.h +3 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+raiseWithReason.m +35 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+respondTo.h +3 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers+respondTo.m +28 -0
- data/Demo/Pods/Expecta/src/matchers/EXPMatchers.h +24 -0
- data/Demo/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h +21 -0
- data/Demo/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.m +308 -0
- data/Demo/Pods/Expecta+Snapshots/LICENSE.md +22 -0
- data/Demo/Pods/Expecta+Snapshots/README.md +85 -0
- data/Demo/Pods/FBSnapshotTestCase/FBSnapshotTestCase.h +87 -0
- data/Demo/Pods/FBSnapshotTestCase/FBSnapshotTestCase.m +82 -0
- data/Demo/Pods/FBSnapshotTestCase/FBSnapshotTestController.h +147 -0
- data/Demo/Pods/FBSnapshotTestCase/FBSnapshotTestController.m +376 -0
- data/Demo/Pods/FBSnapshotTestCase/LICENSE +29 -0
- data/Demo/Pods/FBSnapshotTestCase/README.md +83 -0
- data/Demo/Pods/FBSnapshotTestCase/UIImage+Compare.h +37 -0
- data/Demo/Pods/FBSnapshotTestCase/UIImage+Compare.m +87 -0
- data/Demo/Pods/FBSnapshotTestCase/UIImage+Diff.h +37 -0
- data/Demo/Pods/FBSnapshotTestCase/UIImage+Diff.m +56 -0
- data/Demo/Pods/Headers/Expecta/EXPBackwardCompatibility.h +42 -0
- data/Demo/Pods/Headers/Expecta/EXPBlockDefinedMatcher.h +25 -0
- data/Demo/Pods/Headers/Expecta/EXPDefines.h +17 -0
- data/Demo/Pods/Headers/Expecta/EXPDoubleTuple.h +13 -0
- data/Demo/Pods/Headers/Expecta/EXPExpect.h +45 -0
- data/Demo/Pods/Headers/Expecta/EXPFloatTuple.h +13 -0
- data/Demo/Pods/Headers/Expecta/EXPMatcher.h +20 -0
- data/Demo/Pods/Headers/Expecta/EXPMatcherHelpers.h +4 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beCloseTo.h +7 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beFalsy.h +3 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beGreaterThan.h +6 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beGreaterThanOrEqualTo.h +6 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beIdenticalTo.h +10 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beInTheRangeOf.h +6 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beInstanceOf.h +7 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beKindOf.h +5 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beLessThan.h +6 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beLessThanOrEqualTo.h +6 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beNil.h +5 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beSubclassOf.h +5 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beSupersetOf.h +4 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beTruthy.h +3 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+beginWith.h +5 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+conformTo.h +3 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+contain.h +5 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+endWith.h +3 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+equal.h +5 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+haveCountOf.h +10 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+notify.h +4 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+raise.h +4 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+raiseWithReason.h +3 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers+respondTo.h +3 -0
- data/Demo/Pods/Headers/Expecta/EXPMatchers.h +24 -0
- data/Demo/Pods/Headers/Expecta/EXPUnsupportedObject.h +11 -0
- data/Demo/Pods/Headers/Expecta/Expecta.h +27 -0
- data/Demo/Pods/Headers/Expecta/ExpectaSupport.h +64 -0
- data/Demo/Pods/Headers/Expecta/NSObject+Expecta.h +14 -0
- data/Demo/Pods/Headers/Expecta/NSValue+Expecta.h +8 -0
- data/Demo/Pods/Headers/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h +21 -0
- data/Demo/Pods/Headers/FBSnapshotTestCase/FBSnapshotTestCase.h +87 -0
- data/Demo/Pods/Headers/FBSnapshotTestCase/FBSnapshotTestController.h +147 -0
- data/Demo/Pods/Headers/FBSnapshotTestCase/UIImage+Compare.h +37 -0
- data/Demo/Pods/Headers/FBSnapshotTestCase/UIImage+Diff.h +37 -0
- data/Demo/Pods/Headers/Specta/SPTExample.h +14 -0
- data/Demo/Pods/Headers/Specta/SPTExampleGroup.h +40 -0
- data/Demo/Pods/Headers/Specta/SPTNestedReporter.h +5 -0
- data/Demo/Pods/Headers/Specta/SPTReporter.h +33 -0
- data/Demo/Pods/Headers/Specta/SPTSharedExampleGroups.h +17 -0
- data/Demo/Pods/Headers/Specta/SPTSpec.h +21 -0
- data/Demo/Pods/Headers/Specta/SPTXCTestCase.h +27 -0
- data/Demo/Pods/Headers/Specta/SPTXCTestReporter.h +9 -0
- data/Demo/Pods/Headers/Specta/Specta.h +70 -0
- data/Demo/Pods/Headers/Specta/SpectaSupport.h +46 -0
- data/Demo/Pods/Headers/Specta/SpectaTypes.h +3 -0
- data/Demo/Pods/Headers/Specta/SpectaUtility.h +14 -0
- data/Demo/Pods/Headers/Specta/XCTestCase+Specta.h +4 -0
- data/Demo/Pods/Headers/Specta/XCTestLog+Specta.h +7 -0
- data/Demo/Pods/Headers/Specta/XCTestRun+Specta.h +8 -0
- data/Demo/Pods/Manifest.lock +21 -0
- data/Demo/Pods/Pods-DemoTests-EXPMatchers+FBSnapshotTest-Private.xcconfig +6 -0
- data/Demo/Pods/Pods-DemoTests-EXPMatchers+FBSnapshotTest-dummy.m +5 -0
- data/Demo/Pods/Pods-DemoTests-EXPMatchers+FBSnapshotTest-prefix.pch +5 -0
- data/Demo/Pods/Pods-DemoTests-EXPMatchers+FBSnapshotTest.xcconfig +2 -0
- data/Demo/Pods/Pods-DemoTests-Expecta+Snapshots-Private.xcconfig +6 -0
- data/Demo/Pods/Pods-DemoTests-Expecta+Snapshots-dummy.m +5 -0
- data/Demo/Pods/Pods-DemoTests-Expecta+Snapshots-prefix.pch +5 -0
- data/Demo/Pods/Pods-DemoTests-Expecta+Snapshots.xcconfig +2 -0
- data/Demo/Pods/Pods-DemoTests-Expecta-Private.xcconfig +5 -0
- data/Demo/Pods/Pods-DemoTests-Expecta-dummy.m +5 -0
- data/Demo/Pods/Pods-DemoTests-Expecta-prefix.pch +5 -0
- data/Demo/Pods/Pods-DemoTests-Expecta.xcconfig +1 -0
- data/Demo/Pods/Pods-DemoTests-FBSnapshotTestCase-Private.xcconfig +6 -0
- data/Demo/Pods/Pods-DemoTests-FBSnapshotTestCase-dummy.m +5 -0
- data/Demo/Pods/Pods-DemoTests-FBSnapshotTestCase-prefix.pch +6 -0
- data/Demo/Pods/Pods-DemoTests-FBSnapshotTestCase.xcconfig +2 -0
- data/Demo/Pods/Pods-DemoTests-Specta-Private.xcconfig +6 -0
- data/Demo/Pods/Pods-DemoTests-Specta-dummy.m +5 -0
- data/Demo/Pods/Pods-DemoTests-Specta-prefix.pch +5 -0
- data/Demo/Pods/Pods-DemoTests-Specta.xcconfig +2 -0
- data/Demo/Pods/Pods-DemoTests-acknowledgements.markdown +109 -0
- data/Demo/Pods/Pods-DemoTests-acknowledgements.plist +151 -0
- data/Demo/Pods/Pods-DemoTests-dummy.m +5 -0
- data/Demo/Pods/Pods-DemoTests-environment.h +32 -0
- data/Demo/Pods/Pods-DemoTests-resources.sh +68 -0
- data/Demo/Pods/Pods-DemoTests.xcconfig +6 -0
- data/Demo/Pods/Pods.xcodeproj/project.pbxproj +1390 -0
- data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests-Expecta+Snapshots.xcscheme +59 -0
- data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests-Expecta.xcscheme +59 -0
- data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests-FBSnapshotTestCase.xcscheme +59 -0
- data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests-Specta.xcscheme +59 -0
- data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests.xcscheme +59 -0
- data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/xcschememanagement.plist +62 -0
- data/Demo/Pods/Specta/LICENSE +20 -0
- data/Demo/Pods/Specta/README.md +146 -0
- data/Demo/Pods/Specta/src/SPTExample.h +14 -0
- data/Demo/Pods/Specta/src/SPTExample.m +16 -0
- data/Demo/Pods/Specta/src/SPTExampleGroup.h +40 -0
- data/Demo/Pods/Specta/src/SPTExampleGroup.m +326 -0
- data/Demo/Pods/Specta/src/SPTNestedReporter.h +5 -0
- data/Demo/Pods/Specta/src/SPTNestedReporter.m +194 -0
- data/Demo/Pods/Specta/src/SPTReporter.h +33 -0
- data/Demo/Pods/Specta/src/SPTReporter.m +134 -0
- data/Demo/Pods/Specta/src/SPTSharedExampleGroups.h +17 -0
- data/Demo/Pods/Specta/src/SPTSharedExampleGroups.m +62 -0
- data/Demo/Pods/Specta/src/SPTSpec.h +21 -0
- data/Demo/Pods/Specta/src/SPTSpec.m +31 -0
- data/Demo/Pods/Specta/src/SPTXCTestCase.h +27 -0
- data/Demo/Pods/Specta/src/SPTXCTestCase.m +151 -0
- data/Demo/Pods/Specta/src/SPTXCTestReporter.h +9 -0
- data/Demo/Pods/Specta/src/SPTXCTestReporter.m +11 -0
- data/Demo/Pods/Specta/src/Specta.h +70 -0
- data/Demo/Pods/Specta/src/Specta.m +144 -0
- data/Demo/Pods/Specta/src/SpectaSupport.h +46 -0
- data/Demo/Pods/Specta/src/SpectaTypes.h +3 -0
- data/Demo/Pods/Specta/src/SpectaUtility.h +14 -0
- data/Demo/Pods/Specta/src/SpectaUtility.m +65 -0
- data/Demo/Pods/Specta/src/XCTestCase+Specta.h +4 -0
- data/Demo/Pods/Specta/src/XCTestCase+Specta.m +26 -0
- data/Demo/Pods/Specta/src/XCTestLog+Specta.h +7 -0
- data/Demo/Pods/Specta/src/XCTestLog+Specta.m +49 -0
- data/Demo/Pods/Specta/src/XCTestRun+Specta.h +8 -0
- data/Demo/Pods/Specta/src/XCTestRun+Specta.m +44 -0
- data/Gemfile +5 -0
- data/LICENSE +21 -0
- data/README.md +146 -0
- data/Rakefile +7 -0
- data/second_curtain.gemspec +20 -0
- data/spec/sample_output.txt +79 -0
- data/spec/second_shutter/kaleidoscope_command_spec.rb +25 -0
- data/spec/second_shutter/parser_spec.rb +39 -0
- data/spec/second_shutter/test_suite_spec.rb +32 -0
- data/spec/second_shutter/upload_manager_spec.rb +60 -0
- data/spec/second_shutter/upload_spec.rb +34 -0
- data/spec/second_shutter/xcode_test_case_spec.rb +22 -0
- metadata +315 -1
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
//
|
|
2
|
+
// EXPMatchers+FBSnapshotTest.h
|
|
3
|
+
// Artsy
|
|
4
|
+
//
|
|
5
|
+
// Created by Daniel Doubrovkine on 1/14/14.
|
|
6
|
+
// Copyright (c) 2014 Artsy Inc. All rights reserved.
|
|
7
|
+
//
|
|
8
|
+
|
|
9
|
+
#import "EXPMatchers+FBSnapshotTest.h"
|
|
10
|
+
#import <Expecta/EXPMatcherHelpers.h>
|
|
11
|
+
#import <FBSnapshotTestCase/FBSnapshotTestController.h>
|
|
12
|
+
|
|
13
|
+
@interface EXPExpectFBSnapshotTest()
|
|
14
|
+
@property (nonatomic, strong) NSString *referenceImagesDirectory;
|
|
15
|
+
@end
|
|
16
|
+
|
|
17
|
+
@implementation EXPExpectFBSnapshotTest
|
|
18
|
+
|
|
19
|
+
+ (id)instance
|
|
20
|
+
{
|
|
21
|
+
static EXPExpectFBSnapshotTest *instance = nil;
|
|
22
|
+
static dispatch_once_t onceToken;
|
|
23
|
+
dispatch_once(&onceToken, ^{
|
|
24
|
+
instance = [[self alloc] init];
|
|
25
|
+
});
|
|
26
|
+
return instance;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
+ (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer snapshot:(NSString *)snapshot testCase:(id)testCase record:(BOOL)record referenceDirectory:(NSString *)referenceDirectory error:(NSError **)error
|
|
30
|
+
|
|
31
|
+
{
|
|
32
|
+
FBSnapshotTestController *snapshotController = [[FBSnapshotTestController alloc] initWithTestClass:[testCase class]];
|
|
33
|
+
snapshotController.recordMode = record;
|
|
34
|
+
snapshotController.referenceImagesDirectory = referenceDirectory;
|
|
35
|
+
|
|
36
|
+
if (! snapshotController.referenceImagesDirectory) {
|
|
37
|
+
[NSException raise:@"Missing value for referenceImagesDirectory" format:@"Call [[EXPExpectFBSnapshotTest instance] setReferenceImagesDirectory"];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return [snapshotController compareSnapshotOfViewOrLayer:viewOrLayer
|
|
41
|
+
selector:NSSelectorFromString(snapshot)
|
|
42
|
+
identifier:nil
|
|
43
|
+
error:error];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
+ (NSString *)combinedError:(NSString *)message test:(NSString *)test error:(NSError *)error
|
|
47
|
+
{
|
|
48
|
+
NSAssert(message, @"missing message");
|
|
49
|
+
NSAssert(test, @"missing test name");
|
|
50
|
+
|
|
51
|
+
NSMutableArray *ary = [NSMutableArray array];
|
|
52
|
+
|
|
53
|
+
[ary addObject:[NSString stringWithFormat:@"%@ %@", message, test]];
|
|
54
|
+
|
|
55
|
+
for(NSString *key in error.userInfo.keyEnumerator) {
|
|
56
|
+
[ary addObject:[NSString stringWithFormat:@" %@: %@", key, [error.userInfo valueForKey:key]]];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return [ary componentsJoinedByString:@"\n"];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@end
|
|
63
|
+
|
|
64
|
+
void setGlobalReferenceImageDir(char *reference) {
|
|
65
|
+
NSString *referenceImagesDirectory = [NSString stringWithFormat:@"%s", reference];
|
|
66
|
+
[[EXPExpectFBSnapshotTest instance] setReferenceImagesDirectory:referenceImagesDirectory];
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
@interface EXPExpect(ReferenceDirExtension)
|
|
70
|
+
- (NSString *)_getDefaultReferenceDirectory;
|
|
71
|
+
@end
|
|
72
|
+
|
|
73
|
+
@implementation EXPExpect(ReferenceDirExtension)
|
|
74
|
+
|
|
75
|
+
- (NSString *)_getDefaultReferenceDirectory
|
|
76
|
+
{
|
|
77
|
+
NSString *globalReference = [[EXPExpectFBSnapshotTest instance] referenceImagesDirectory];
|
|
78
|
+
if (globalReference) {
|
|
79
|
+
return globalReference;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Search the test file's path to find the first folder with the substring "tests"
|
|
83
|
+
// then append "/ReferenceImages" and use that
|
|
84
|
+
|
|
85
|
+
NSString *testFileName = [NSString stringWithCString:self.fileName encoding:NSUTF8StringEncoding];
|
|
86
|
+
NSArray *pathComponents = [testFileName pathComponents];
|
|
87
|
+
|
|
88
|
+
for (NSString *folder in pathComponents) {
|
|
89
|
+
if ([folder.lowercaseString rangeOfString:@"tests"].location != NSNotFound) {
|
|
90
|
+
|
|
91
|
+
NSArray *folderPathComponents = [pathComponents subarrayWithRange:NSMakeRange(0, [pathComponents indexOfObject:folder] + 1)];
|
|
92
|
+
return [NSString stringWithFormat:@"%@/ReferenceImages", [folderPathComponents componentsJoinedByString:@"/"]];
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
[NSException raise:@"Could not infer reference image folder" format:@"You should provide a reference dir using setGlobalReferenceImageDir(FB_REFERENCE_IMAGE_DIR);"];
|
|
98
|
+
return nil;
|
|
99
|
+
}
|
|
100
|
+
@end
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
// If you're bringing in Speca via CocoaPods
|
|
105
|
+
// use the test path to get the test's image file URL
|
|
106
|
+
|
|
107
|
+
#ifdef COCOAPODS_POD_AVAILABLE_Specta
|
|
108
|
+
#import <Specta/Specta.h>
|
|
109
|
+
#import <Specta/SpectaUtility.h>
|
|
110
|
+
#import <Specta/SPTExample.h>
|
|
111
|
+
|
|
112
|
+
NSString *sanitizedTestPath();
|
|
113
|
+
|
|
114
|
+
NSString *sanitizedTestPath(){
|
|
115
|
+
SPTXCTestCase *test = [[NSThread currentThread] threadDictionary][SPTCurrentTestCaseKey];
|
|
116
|
+
|
|
117
|
+
SPTExample *compiledExample = [test spt_getCurrentExample];
|
|
118
|
+
NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"];
|
|
119
|
+
NSString *currentTestName = [[compiledExample.name componentsSeparatedByCharactersInSet:[charSet invertedSet]] componentsJoinedByString:@"_"];
|
|
120
|
+
|
|
121
|
+
return [NSString stringWithFormat:@"%@", currentTestName];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
EXPMatcherImplementationBegin(haveValidSnapshot, (void)){
|
|
125
|
+
__block NSError *error = nil;
|
|
126
|
+
|
|
127
|
+
match(^BOOL{
|
|
128
|
+
NSString *referenceImageDir = [self _getDefaultReferenceDirectory];
|
|
129
|
+
NSString *name = sanitizedTestPath();
|
|
130
|
+
if ([actual isKindOfClass:UIViewController.class]) {
|
|
131
|
+
actual = [actual view];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return [EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:name testCase:[self testCase] record:NO referenceDirectory:referenceImageDir error:&error];
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
failureMessageForTo(^NSString *{
|
|
138
|
+
return [EXPExpectFBSnapshotTest combinedError:@"expected a matching snapshot in" test:sanitizedTestPath() error:error];
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
failureMessageForNotTo(^NSString *{
|
|
142
|
+
return [EXPExpectFBSnapshotTest combinedError:@"expected to not have a matching snapshot in" test:sanitizedTestPath() error:error];
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
EXPMatcherImplementationEnd
|
|
146
|
+
|
|
147
|
+
EXPMatcherImplementationBegin(recordSnapshot, (void)) {
|
|
148
|
+
__block NSError *error = nil;
|
|
149
|
+
|
|
150
|
+
BOOL actualIsViewLayerOrViewController = ([actual isKindOfClass:UIView.class] || [actual isKindOfClass:CALayer.class] || [actual isKindOfClass:UIViewController.class]);
|
|
151
|
+
|
|
152
|
+
prerequisite(^BOOL{
|
|
153
|
+
return actualIsViewLayerOrViewController;
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
match(^BOOL{
|
|
157
|
+
NSString *referenceImageDir = [self _getDefaultReferenceDirectory];
|
|
158
|
+
|
|
159
|
+
// For view controllers do the viewWill/viewDid dance, then pass view through
|
|
160
|
+
if ([actual isKindOfClass:UIViewController.class]) {
|
|
161
|
+
|
|
162
|
+
[actual beginAppearanceTransition:YES animated:NO];
|
|
163
|
+
[actual endAppearanceTransition];
|
|
164
|
+
actual = [actual view];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
[EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:sanitizedTestPath() testCase:[self testCase] record:YES referenceDirectory:referenceImageDir error:&error];
|
|
168
|
+
return NO;
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
failureMessageForTo(^NSString *{
|
|
172
|
+
if (!actualIsViewLayerOrViewController) {
|
|
173
|
+
return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:sanitizedTestPath() error:nil];
|
|
174
|
+
}
|
|
175
|
+
if (error) {
|
|
176
|
+
return [EXPExpectFBSnapshotTest combinedError:@"expected to record a snapshot in" test:sanitizedTestPath() error:error];
|
|
177
|
+
} else {
|
|
178
|
+
return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", sanitizedTestPath()];
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
failureMessageForNotTo(^NSString *{
|
|
183
|
+
if (error) {
|
|
184
|
+
return [EXPExpectFBSnapshotTest combinedError:@"expected to record a snapshot in" test:sanitizedTestPath() error:error];
|
|
185
|
+
} else {
|
|
186
|
+
return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", sanitizedTestPath()];
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
EXPMatcherImplementationEnd
|
|
191
|
+
|
|
192
|
+
#else
|
|
193
|
+
|
|
194
|
+
// If you don't have Speca stub the functions
|
|
195
|
+
|
|
196
|
+
EXPMatcherImplementationBegin(haveValidSnapshot, (void)){
|
|
197
|
+
|
|
198
|
+
prerequisite(^BOOL{
|
|
199
|
+
return NO;
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
failureMessageForTo(^NSString *{
|
|
203
|
+
return @"you need Specta installed via CocoaPods to use haveValidSnapshot, use haveValidSnapshotNamed instead";
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
failureMessageForNotTo(^NSString *{
|
|
207
|
+
return @"you need Specta installed via CocoaPods to use haveValidSnapshot, use haveValidSnapshotNamed instead";
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
EXPMatcherImplementationEnd
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
EXPMatcherImplementationBegin(recordSnapshot, (void)) {
|
|
214
|
+
__block NSError *error = nil;
|
|
215
|
+
|
|
216
|
+
prerequisite(^BOOL{
|
|
217
|
+
return NO;
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
failureMessageForTo(^NSString *{
|
|
221
|
+
return @"you need Specta installed via CocoaPods to use recordSnapshot, use recordSnapshotNamed instead";
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
failureMessageForNotTo(^NSString *{
|
|
225
|
+
return @"you need Specta installed via CocoaPods to use recordSnapshot, use recordSnapshotNamed instead";
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
EXPMatcherImplementationEnd
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
#endif
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
EXPMatcherImplementationBegin(haveValidSnapshotNamed, (NSString *snapshot)){
|
|
236
|
+
BOOL snapshotIsNil = (snapshot == nil);
|
|
237
|
+
__block NSError *error = nil;
|
|
238
|
+
|
|
239
|
+
prerequisite(^BOOL{
|
|
240
|
+
return !(snapshotIsNil);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
match(^BOOL{
|
|
244
|
+
NSString *referenceImageDir = [self _getDefaultReferenceDirectory];
|
|
245
|
+
if ([actual isKindOfClass:UIViewController.class]) {
|
|
246
|
+
actual = [actual view];
|
|
247
|
+
}
|
|
248
|
+
return [EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:snapshot testCase:[self testCase] record:NO referenceDirectory:referenceImageDir error:&error];
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
failureMessageForTo(^NSString *{
|
|
252
|
+
return [EXPExpectFBSnapshotTest combinedError:@"expected a matching snapshot named" test:snapshot error:error];
|
|
253
|
+
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
failureMessageForNotTo(^NSString *{
|
|
257
|
+
return [EXPExpectFBSnapshotTest combinedError:@"expected not to have a matching snapshot named" test:snapshot error:error];
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
EXPMatcherImplementationEnd
|
|
261
|
+
|
|
262
|
+
EXPMatcherImplementationBegin(recordSnapshotNamed, (NSString *snapshot)) {
|
|
263
|
+
BOOL snapshotExists = (snapshot != nil);
|
|
264
|
+
BOOL actualIsViewLayerOrViewController = ([actual isKindOfClass:UIView.class] || [actual isKindOfClass:CALayer.class] || [actual isKindOfClass:UIViewController.class]);
|
|
265
|
+
__block NSError *error = nil;
|
|
266
|
+
id actualRef = actual;
|
|
267
|
+
|
|
268
|
+
prerequisite(^BOOL{
|
|
269
|
+
return actualRef && snapshotExists && actualIsViewLayerOrViewController;
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
match(^BOOL{
|
|
273
|
+
NSString *referenceImageDir = [self _getDefaultReferenceDirectory];
|
|
274
|
+
|
|
275
|
+
// For view controllers do the viewWill/viewDid dance, then pass view through
|
|
276
|
+
if ([actual isKindOfClass:UIViewController.class]) {
|
|
277
|
+
[actual beginAppearanceTransition:YES animated:NO];
|
|
278
|
+
[actual endAppearanceTransition];
|
|
279
|
+
actual = [actual view];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
[EXPExpectFBSnapshotTest compareSnapshotOfViewOrLayer:actual snapshot:snapshot testCase:[self testCase] record:YES referenceDirectory:referenceImageDir error:&error];
|
|
283
|
+
return NO;
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
failureMessageForTo(^NSString *{
|
|
287
|
+
if (!actualIsViewLayerOrViewController) {
|
|
288
|
+
return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:snapshot error:nil];
|
|
289
|
+
}
|
|
290
|
+
if (error) {
|
|
291
|
+
return [EXPExpectFBSnapshotTest combinedError:@"expected to record a matching snapshot named" test:snapshot error:error];
|
|
292
|
+
} else {
|
|
293
|
+
return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", snapshot];
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
failureMessageForNotTo(^NSString *{
|
|
298
|
+
if (!actualIsViewLayerOrViewController) {
|
|
299
|
+
return [EXPExpectFBSnapshotTest combinedError:@"Expected a View, Layer or View Controller." test:snapshot error:nil];
|
|
300
|
+
}
|
|
301
|
+
if (error) {
|
|
302
|
+
return [EXPExpectFBSnapshotTest combinedError:@"expected to record a matching snapshot named" test:snapshot error:error];
|
|
303
|
+
} else {
|
|
304
|
+
return [NSString stringWithFormat:@"snapshot %@ successfully recorded, replace recordSnapshot with a check", snapshot];
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
EXPMatcherImplementationEnd
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2014 Daniel Doubrovkine, Artsy Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
Expecta Matchers for FBSnapshotTestCase
|
|
2
|
+
==============================
|
|
3
|
+
|
|
4
|
+
[Expecta](https://github.com/specta/expecta) matchers for [ios-snapshot-test-case](https://github.com/facebook/ios-snapshot-test-case).
|
|
5
|
+
|
|
6
|
+
[](https://travis-ci.org/dblock/ios-snapshot-test-case-expecta)
|
|
7
|
+
|
|
8
|
+
### Usage
|
|
9
|
+
|
|
10
|
+
Add `EXPMatchers+FBSnapshotTest` to your Podfile, the latest `FBSnapshotTestCase` will come in as a dependency.
|
|
11
|
+
|
|
12
|
+
``` ruby
|
|
13
|
+
pod 'Expecta+Snapshots', '~> 1.0'
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### App setup
|
|
17
|
+
|
|
18
|
+
Use `expect(view).to.recordSnapshotNamed(@"unique snapshot name")` to record a snapshot and `expect(view).to.haveValidSnapshotNamed(@"unique snapshot name")` to check it.
|
|
19
|
+
|
|
20
|
+
If you project was compiled with Specta included, you have two extra methods that use the spec hierarchy to generate the snapshot name for you: `recordSnapshot()` and `haveValidSnapshot()`. You should only call these once per `it()` block.
|
|
21
|
+
|
|
22
|
+
``` Objective-C
|
|
23
|
+
#define EXP_SHORTHAND
|
|
24
|
+
#include <Specta/Specta.h>
|
|
25
|
+
#include <Expecta/Expecta.h>
|
|
26
|
+
#include <EXPMatchers+FBSnapshotTest/EXPMatchers+FBSnapshotTest.h>
|
|
27
|
+
#include "FBExampleView.h"
|
|
28
|
+
|
|
29
|
+
SpecBegin(FBExampleView)
|
|
30
|
+
|
|
31
|
+
describe(@"manual matching", ^{
|
|
32
|
+
|
|
33
|
+
it(@"matches view", ^{
|
|
34
|
+
FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
|
|
35
|
+
expect(view).to.recordSnapshotNamed(@"FBExampleView");
|
|
36
|
+
expect(view).to.haveValidSnapshotNamed(@"FBExampleView");
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it(@"doesn't match a view", ^{
|
|
40
|
+
FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
|
|
41
|
+
expect(view).toNot.haveValidSnapshotNamed(@"FBExampleViewDoesNotExist");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe(@"test name derived matching", ^{
|
|
47
|
+
|
|
48
|
+
it(@"matches view", ^{
|
|
49
|
+
FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
|
|
50
|
+
expect(view).to.recordSnapshot();
|
|
51
|
+
expect(view).to.haveValidSnapshot();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it(@"doesn't match a view", ^{
|
|
55
|
+
FBExampleView *view = [[FBExampleView alloc] initWithFrame:CGRectMake(0, 0, 64, 64)];
|
|
56
|
+
expect(view).toNot.haveValidSnapshot();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
SpecEnd
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Sane defaults
|
|
65
|
+
|
|
66
|
+
`EXPMatchers+FBSnapshotTest` will automatically figure out the tests folder, and [add a reference image](https://github.com/dblock/ios-snapshot-test-case-expecta/blob/master/EXPMatchers%2BFBSnapshotTest.m#L84-L85) directory, if you'd like to override this, you should include a `beforeAll` block setting the `setGlobalReferenceImageDir` in each file containing tests.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
beforeAll(^{
|
|
70
|
+
setGlobalReferenceImageDir(FB_REFERENCE_IMAGE_DIR);
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
### Example
|
|
76
|
+
|
|
77
|
+
A complete project can be found in [FBSnapshotTestCaseDemo](FBSnapshotTestCaseDemo).
|
|
78
|
+
|
|
79
|
+
Notably, take a look at [FBSnapshotTestCaseDemoSpecs.m](FBSnapshotTestCaseDemo/FBSnapshotTestCaseDemoTests/FBSnapshotTestCaseDemoSpecs.m) for a complete example, which is an expanded Specta version version of [FBSnapshotTestCaseDemoTests.m](https://github.com/facebook/ios-snapshot-test-case/blob/master/FBSnapshotTestCaseDemo/FBSnapshotTestCaseDemoTests/FBSnapshotTestCaseDemoTests.m).
|
|
80
|
+
|
|
81
|
+
Finally you can consult the tests for [ARTiledImageView](https://github.com/dblock/ARTiledImageView/tree/master/Demo/DemoTests) or [NAMapKit](https://github.com/neilang/NAMapKit/tree/master/Demo/DemoTests).
|
|
82
|
+
|
|
83
|
+
### License
|
|
84
|
+
|
|
85
|
+
MIT, see [LICENSE](LICENSE.md)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2013, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the BSD-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
+
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#import <QuartzCore/QuartzCore.h>
|
|
12
|
+
|
|
13
|
+
#import <UIKit/UIKit.h>
|
|
14
|
+
|
|
15
|
+
#import <XCTest/XCTest.h>
|
|
16
|
+
|
|
17
|
+
#ifndef FB_REFERENCE_IMAGE_DIR
|
|
18
|
+
#define FB_REFERENCE_IMAGE_DIR "\"$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages\""
|
|
19
|
+
#endif
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though.
|
|
23
|
+
@param view The view to snapshot
|
|
24
|
+
@param identifier An optional identifier, used is there are multiple snapshot tests in a given -test method.
|
|
25
|
+
*/
|
|
26
|
+
#define FBSnapshotVerifyView(view__, identifier__) \
|
|
27
|
+
{ \
|
|
28
|
+
NSError *error__ = nil; \
|
|
29
|
+
NSString *referenceImagesDirectory__ = [NSString stringWithFormat:@"%s", FB_REFERENCE_IMAGE_DIR]; \
|
|
30
|
+
BOOL comparisonSuccess__ = [self compareSnapshotOfView:(view__) referenceImagesDirectory:referenceImagesDirectory__ identifier:(identifier__) error:&error__]; \
|
|
31
|
+
XCTAssertTrue(comparisonSuccess__, @"Snapshot comparison failed: %@", error__); \
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though.
|
|
36
|
+
@param layer The layer to snapshot
|
|
37
|
+
@param identifier An optional identifier, used is there are multiple snapshot tests in a given -test method.
|
|
38
|
+
*/
|
|
39
|
+
#define FBSnapshotVerifyLayer(layer__, identifier__) \
|
|
40
|
+
{ \
|
|
41
|
+
NSError *error__ = nil; \
|
|
42
|
+
NSString *referenceImagesDirectory__ = [NSString stringWithFormat:@"%s", FB_REFERENCE_IMAGE_DIR]; \
|
|
43
|
+
BOOL comparisonSuccess__ = [self compareSnapshotOfLayer:(layer__) referenceImagesDirectory:referenceImagesDirectory__ identifier:(identifier__) error:&error__]; \
|
|
44
|
+
XCTAssertTrue(comparisonSuccess__, @"Snapshot comparison failed: %@", error__); \
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
The base class of view snapshotting tests. If you have small UI component, it's often easier to configure it in a test
|
|
49
|
+
and compare an image of the view to a reference image that write lots of complex layout-code tests.
|
|
50
|
+
|
|
51
|
+
In order to flip the tests in your subclass to record the reference images set `recordMode` to YES before calling
|
|
52
|
+
-[super setUp].
|
|
53
|
+
*/
|
|
54
|
+
@interface FBSnapshotTestCase : XCTestCase
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
When YES, the test macros will save reference images, rather than performing an actual test.
|
|
58
|
+
*/
|
|
59
|
+
@property (readwrite, nonatomic, assign) BOOL recordMode;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
Performs the comparisong or records a snapshot of the layer if recordMode is YES.
|
|
63
|
+
@param layer The Layer to snapshot
|
|
64
|
+
@param referenceImagesDirectory The directory in which reference images are stored.
|
|
65
|
+
@param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method.
|
|
66
|
+
@param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc).
|
|
67
|
+
@returns YES if the comparison (or saving of the reference image) succeeded.
|
|
68
|
+
*/
|
|
69
|
+
- (BOOL)compareSnapshotOfLayer:(CALayer *)layer
|
|
70
|
+
referenceImagesDirectory:(NSString *)referenceImagesDirectory
|
|
71
|
+
identifier:(NSString *)identifier
|
|
72
|
+
error:(NSError **)errorPtr;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
Performs the comparisong or records a snapshot of the view if recordMode is YES.
|
|
76
|
+
@param view The view to snapshot
|
|
77
|
+
@param referenceImagesDirectory The directory in which reference images are stored.
|
|
78
|
+
@param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method.
|
|
79
|
+
@param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc).
|
|
80
|
+
@returns YES if the comparison (or saving of the reference image) succeeded.
|
|
81
|
+
*/
|
|
82
|
+
- (BOOL)compareSnapshotOfView:(UIView *)view
|
|
83
|
+
referenceImagesDirectory:(NSString *)referenceImagesDirectory
|
|
84
|
+
identifier:(NSString *)identifier
|
|
85
|
+
error:(NSError **)errorPtr;
|
|
86
|
+
|
|
87
|
+
@end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2013, Facebook, Inc.
|
|
3
|
+
* All rights reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the BSD-style license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree. An additional grant
|
|
7
|
+
* of patent rights can be found in the PATENTS file in the same directory.
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
#import "FBSnapshotTestCase.h"
|
|
12
|
+
|
|
13
|
+
#import "FBSnapshotTestController.h"
|
|
14
|
+
|
|
15
|
+
@interface FBSnapshotTestCase ()
|
|
16
|
+
|
|
17
|
+
@property (readwrite, nonatomic, retain) FBSnapshotTestController *snapshotController;
|
|
18
|
+
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
@implementation FBSnapshotTestCase
|
|
22
|
+
|
|
23
|
+
- (void)setUp
|
|
24
|
+
{
|
|
25
|
+
[super setUp];
|
|
26
|
+
self.snapshotController = [[FBSnapshotTestController alloc] initWithTestClass:[self class]];
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
- (void)tearDown
|
|
30
|
+
{
|
|
31
|
+
self.snapshotController = nil;
|
|
32
|
+
[super tearDown];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
- (BOOL)recordMode
|
|
36
|
+
{
|
|
37
|
+
return self.snapshotController.recordMode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
- (void)setRecordMode:(BOOL)recordMode
|
|
41
|
+
{
|
|
42
|
+
self.snapshotController.recordMode = recordMode;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
- (BOOL)compareSnapshotOfLayer:(CALayer *)layer
|
|
46
|
+
referenceImagesDirectory:(NSString *)referenceImagesDirectory
|
|
47
|
+
identifier:(NSString *)identifier
|
|
48
|
+
error:(NSError **)errorPtr
|
|
49
|
+
{
|
|
50
|
+
return [self _compareSnapshotOfViewOrLayer:layer
|
|
51
|
+
referenceImagesDirectory:referenceImagesDirectory
|
|
52
|
+
identifier:identifier
|
|
53
|
+
error:errorPtr];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
- (BOOL)compareSnapshotOfView:(UIView *)view
|
|
57
|
+
referenceImagesDirectory:(NSString *)referenceImagesDirectory
|
|
58
|
+
identifier:(NSString *)identifier
|
|
59
|
+
error:(NSError **)errorPtr
|
|
60
|
+
{
|
|
61
|
+
return [self _compareSnapshotOfViewOrLayer:view
|
|
62
|
+
referenceImagesDirectory:referenceImagesDirectory
|
|
63
|
+
identifier:identifier
|
|
64
|
+
error:errorPtr];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#pragma mark -
|
|
68
|
+
#pragma mark Private API
|
|
69
|
+
|
|
70
|
+
- (BOOL)_compareSnapshotOfViewOrLayer:(id)viewOrLayer
|
|
71
|
+
referenceImagesDirectory:(NSString *)referenceImagesDirectory
|
|
72
|
+
identifier:(NSString *)identifier
|
|
73
|
+
error:(NSError **)errorPtr
|
|
74
|
+
{
|
|
75
|
+
_snapshotController.referenceImagesDirectory = referenceImagesDirectory;
|
|
76
|
+
return [_snapshotController compareSnapshotOfViewOrLayer:viewOrLayer
|
|
77
|
+
selector:self.selector
|
|
78
|
+
identifier:identifier
|
|
79
|
+
error:errorPtr];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
@end
|