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.
Files changed (316) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +20 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG +20 -0
  5. data/Demo/Demo/ASHAppDelegate.h +15 -0
  6. data/Demo/Demo/ASHAppDelegate.m +18 -0
  7. data/Demo/Demo/ASHViewController.h +13 -0
  8. data/Demo/Demo/ASHViewController.m +30 -0
  9. data/Demo/Demo/Base.lproj/Main.storyboard +30 -0
  10. data/Demo/Demo/Demo-Info.plist +40 -0
  11. data/Demo/Demo/Demo-Prefix.pch +16 -0
  12. data/Demo/Demo/Images.xcassets/AppIcon.appiconset/Contents.json +23 -0
  13. data/Demo/Demo/Images.xcassets/LaunchImage.launchimage/Contents.json +23 -0
  14. data/Demo/Demo/en.lproj/InfoPlist.strings +2 -0
  15. data/Demo/Demo/main.m +18 -0
  16. data/Demo/Demo.xcodeproj/project.pbxproj +517 -0
  17. data/Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  18. data/Demo/Demo.xcodeproj/project.xcworkspace/xcshareddata/Demo.xccheckout +41 -0
  19. data/Demo/Demo.xcodeproj/project.xcworkspace/xcuserdata/ash.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  20. data/Demo/Demo.xcodeproj/xcshareddata/xcschemes/Demo.xcscheme +96 -0
  21. data/Demo/Demo.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/xcschememanagement.plist +27 -0
  22. data/Demo/Demo.xcodeproj/xcuserdata/orta.xcuserdatad/xcschemes/xcschememanagement.plist +27 -0
  23. data/Demo/Demo.xcworkspace/contents.xcworkspacedata +1 -0
  24. data/Demo/Demo.xcworkspace/xcshareddata/Demo.xccheckout +41 -0
  25. data/Demo/Demo.xcworkspace/xcuserdata/ash.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  26. data/Demo/Demo.xcworkspace/xcuserdata/orta.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  27. data/Demo/DemoTests/DemoTests-Info.plist +22 -0
  28. data/Demo/DemoTests/DemoTests.m +52 -0
  29. data/Demo/DemoTests/ReferenceImages/ASHViewControllerSpec/a_view_controller_with_a_loaded_view_should_have_a_valid_snapshot@2x.png +0 -0
  30. data/Demo/DemoTests/ReferenceImages/ASHViewControllerSpec/views_should_be_green@2x.png +0 -0
  31. data/Demo/DemoTests/ReferenceImages/ASHViewControllerSpec/views_should_be_red@2x.png +0 -0
  32. data/Demo/DemoTests/en.lproj/InfoPlist.strings +2 -0
  33. data/Demo/Makefile +15 -0
  34. data/Demo/Podfile +16 -0
  35. data/Demo/Podfile.lock +21 -0
  36. data/Demo/Pods/BuildHeaders/Expecta/EXPBackwardCompatibility.h +42 -0
  37. data/Demo/Pods/BuildHeaders/Expecta/EXPBlockDefinedMatcher.h +25 -0
  38. data/Demo/Pods/BuildHeaders/Expecta/EXPDefines.h +17 -0
  39. data/Demo/Pods/BuildHeaders/Expecta/EXPDoubleTuple.h +13 -0
  40. data/Demo/Pods/BuildHeaders/Expecta/EXPExpect.h +45 -0
  41. data/Demo/Pods/BuildHeaders/Expecta/EXPFloatTuple.h +13 -0
  42. data/Demo/Pods/BuildHeaders/Expecta/EXPMatcher.h +20 -0
  43. data/Demo/Pods/BuildHeaders/Expecta/EXPMatcherHelpers.h +4 -0
  44. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beCloseTo.h +7 -0
  45. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beFalsy.h +3 -0
  46. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beGreaterThan.h +6 -0
  47. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beGreaterThanOrEqualTo.h +6 -0
  48. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beIdenticalTo.h +10 -0
  49. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beInTheRangeOf.h +6 -0
  50. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beInstanceOf.h +7 -0
  51. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beKindOf.h +5 -0
  52. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beLessThan.h +6 -0
  53. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beLessThanOrEqualTo.h +6 -0
  54. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beNil.h +5 -0
  55. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beSubclassOf.h +5 -0
  56. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beSupersetOf.h +4 -0
  57. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beTruthy.h +3 -0
  58. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+beginWith.h +5 -0
  59. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+conformTo.h +3 -0
  60. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+contain.h +5 -0
  61. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+endWith.h +3 -0
  62. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+equal.h +5 -0
  63. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+haveCountOf.h +10 -0
  64. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+notify.h +4 -0
  65. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+raise.h +4 -0
  66. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+raiseWithReason.h +3 -0
  67. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers+respondTo.h +3 -0
  68. data/Demo/Pods/BuildHeaders/Expecta/EXPMatchers.h +24 -0
  69. data/Demo/Pods/BuildHeaders/Expecta/EXPUnsupportedObject.h +11 -0
  70. data/Demo/Pods/BuildHeaders/Expecta/Expecta.h +27 -0
  71. data/Demo/Pods/BuildHeaders/Expecta/ExpectaSupport.h +64 -0
  72. data/Demo/Pods/BuildHeaders/Expecta/NSObject+Expecta.h +14 -0
  73. data/Demo/Pods/BuildHeaders/Expecta/NSValue+Expecta.h +8 -0
  74. data/Demo/Pods/BuildHeaders/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h +21 -0
  75. data/Demo/Pods/BuildHeaders/FBSnapshotTestCase/FBSnapshotTestCase.h +87 -0
  76. data/Demo/Pods/BuildHeaders/FBSnapshotTestCase/FBSnapshotTestController.h +147 -0
  77. data/Demo/Pods/BuildHeaders/FBSnapshotTestCase/UIImage+Compare.h +37 -0
  78. data/Demo/Pods/BuildHeaders/FBSnapshotTestCase/UIImage+Diff.h +37 -0
  79. data/Demo/Pods/BuildHeaders/Specta/SPTExample.h +14 -0
  80. data/Demo/Pods/BuildHeaders/Specta/SPTExampleGroup.h +40 -0
  81. data/Demo/Pods/BuildHeaders/Specta/SPTNestedReporter.h +5 -0
  82. data/Demo/Pods/BuildHeaders/Specta/SPTReporter.h +33 -0
  83. data/Demo/Pods/BuildHeaders/Specta/SPTSharedExampleGroups.h +17 -0
  84. data/Demo/Pods/BuildHeaders/Specta/SPTSpec.h +21 -0
  85. data/Demo/Pods/BuildHeaders/Specta/SPTXCTestCase.h +27 -0
  86. data/Demo/Pods/BuildHeaders/Specta/SPTXCTestReporter.h +9 -0
  87. data/Demo/Pods/BuildHeaders/Specta/Specta.h +70 -0
  88. data/Demo/Pods/BuildHeaders/Specta/SpectaSupport.h +46 -0
  89. data/Demo/Pods/BuildHeaders/Specta/SpectaTypes.h +3 -0
  90. data/Demo/Pods/BuildHeaders/Specta/SpectaUtility.h +14 -0
  91. data/Demo/Pods/BuildHeaders/Specta/XCTestCase+Specta.h +4 -0
  92. data/Demo/Pods/BuildHeaders/Specta/XCTestLog+Specta.h +7 -0
  93. data/Demo/Pods/BuildHeaders/Specta/XCTestRun+Specta.h +8 -0
  94. data/Demo/Pods/Expecta/LICENSE +19 -0
  95. data/Demo/Pods/Expecta/README.md +308 -0
  96. data/Demo/Pods/Expecta/src/EXPBackwardCompatibility.h +42 -0
  97. data/Demo/Pods/Expecta/src/EXPBackwardCompatibility.m +17 -0
  98. data/Demo/Pods/Expecta/src/EXPBlockDefinedMatcher.h +25 -0
  99. data/Demo/Pods/Expecta/src/EXPBlockDefinedMatcher.m +60 -0
  100. data/Demo/Pods/Expecta/src/EXPDefines.h +17 -0
  101. data/Demo/Pods/Expecta/src/EXPDoubleTuple.h +13 -0
  102. data/Demo/Pods/Expecta/src/EXPDoubleTuple.m +42 -0
  103. data/Demo/Pods/Expecta/src/EXPExpect.h +45 -0
  104. data/Demo/Pods/Expecta/src/EXPExpect.m +214 -0
  105. data/Demo/Pods/Expecta/src/EXPFloatTuple.h +13 -0
  106. data/Demo/Pods/Expecta/src/EXPFloatTuple.m +42 -0
  107. data/Demo/Pods/Expecta/src/EXPMatcher.h +20 -0
  108. data/Demo/Pods/Expecta/src/EXPUnsupportedObject.h +11 -0
  109. data/Demo/Pods/Expecta/src/EXPUnsupportedObject.m +20 -0
  110. data/Demo/Pods/Expecta/src/Expecta.h +27 -0
  111. data/Demo/Pods/Expecta/src/Expecta.m +15 -0
  112. data/Demo/Pods/Expecta/src/ExpectaSupport.h +64 -0
  113. data/Demo/Pods/Expecta/src/ExpectaSupport.m +187 -0
  114. data/Demo/Pods/Expecta/src/NSObject+Expecta.h +14 -0
  115. data/Demo/Pods/Expecta/src/NSValue+Expecta.h +8 -0
  116. data/Demo/Pods/Expecta/src/NSValue+Expecta.m +21 -0
  117. data/Demo/Pods/Expecta/src/matchers/EXPMatcherHelpers.h +4 -0
  118. data/Demo/Pods/Expecta/src/matchers/EXPMatcherHelpers.m +9 -0
  119. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beCloseTo.h +7 -0
  120. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beCloseTo.m +49 -0
  121. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beFalsy.h +3 -0
  122. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beFalsy.m +24 -0
  123. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beGreaterThan.h +6 -0
  124. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beGreaterThan.m +20 -0
  125. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beGreaterThanOrEqualTo.h +6 -0
  126. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beGreaterThanOrEqualTo.m +20 -0
  127. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beIdenticalTo.h +10 -0
  128. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beIdenticalTo.m +24 -0
  129. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beInTheRangeOf.h +6 -0
  130. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beInTheRangeOf.m +30 -0
  131. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beInstanceOf.h +7 -0
  132. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beInstanceOf.m +27 -0
  133. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beKindOf.h +5 -0
  134. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beKindOf.m +27 -0
  135. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beLessThan.h +6 -0
  136. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beLessThan.m +20 -0
  137. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beLessThanOrEqualTo.h +6 -0
  138. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beLessThanOrEqualTo.m +20 -0
  139. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beNil.h +5 -0
  140. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beNil.m +16 -0
  141. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beSubclassOf.h +5 -0
  142. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beSubclassOf.m +27 -0
  143. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beSupersetOf.h +4 -0
  144. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beSupersetOf.m +57 -0
  145. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beTruthy.h +3 -0
  146. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beTruthy.m +24 -0
  147. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beginWith.h +5 -0
  148. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+beginWith.m +49 -0
  149. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+conformTo.h +3 -0
  150. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+conformTo.m +33 -0
  151. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+contain.h +5 -0
  152. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+contain.m +38 -0
  153. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+endWith.h +3 -0
  154. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+endWith.m +49 -0
  155. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+equal.h +5 -0
  156. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+equal.m +24 -0
  157. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+haveCountOf.h +10 -0
  158. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+haveCountOf.m +36 -0
  159. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+notify.h +4 -0
  160. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+notify.m +63 -0
  161. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+raise.h +4 -0
  162. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+raise.m +30 -0
  163. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+raiseWithReason.h +3 -0
  164. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+raiseWithReason.m +35 -0
  165. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+respondTo.h +3 -0
  166. data/Demo/Pods/Expecta/src/matchers/EXPMatchers+respondTo.m +28 -0
  167. data/Demo/Pods/Expecta/src/matchers/EXPMatchers.h +24 -0
  168. data/Demo/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h +21 -0
  169. data/Demo/Pods/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.m +308 -0
  170. data/Demo/Pods/Expecta+Snapshots/LICENSE.md +22 -0
  171. data/Demo/Pods/Expecta+Snapshots/README.md +85 -0
  172. data/Demo/Pods/FBSnapshotTestCase/FBSnapshotTestCase.h +87 -0
  173. data/Demo/Pods/FBSnapshotTestCase/FBSnapshotTestCase.m +82 -0
  174. data/Demo/Pods/FBSnapshotTestCase/FBSnapshotTestController.h +147 -0
  175. data/Demo/Pods/FBSnapshotTestCase/FBSnapshotTestController.m +376 -0
  176. data/Demo/Pods/FBSnapshotTestCase/LICENSE +29 -0
  177. data/Demo/Pods/FBSnapshotTestCase/README.md +83 -0
  178. data/Demo/Pods/FBSnapshotTestCase/UIImage+Compare.h +37 -0
  179. data/Demo/Pods/FBSnapshotTestCase/UIImage+Compare.m +87 -0
  180. data/Demo/Pods/FBSnapshotTestCase/UIImage+Diff.h +37 -0
  181. data/Demo/Pods/FBSnapshotTestCase/UIImage+Diff.m +56 -0
  182. data/Demo/Pods/Headers/Expecta/EXPBackwardCompatibility.h +42 -0
  183. data/Demo/Pods/Headers/Expecta/EXPBlockDefinedMatcher.h +25 -0
  184. data/Demo/Pods/Headers/Expecta/EXPDefines.h +17 -0
  185. data/Demo/Pods/Headers/Expecta/EXPDoubleTuple.h +13 -0
  186. data/Demo/Pods/Headers/Expecta/EXPExpect.h +45 -0
  187. data/Demo/Pods/Headers/Expecta/EXPFloatTuple.h +13 -0
  188. data/Demo/Pods/Headers/Expecta/EXPMatcher.h +20 -0
  189. data/Demo/Pods/Headers/Expecta/EXPMatcherHelpers.h +4 -0
  190. data/Demo/Pods/Headers/Expecta/EXPMatchers+beCloseTo.h +7 -0
  191. data/Demo/Pods/Headers/Expecta/EXPMatchers+beFalsy.h +3 -0
  192. data/Demo/Pods/Headers/Expecta/EXPMatchers+beGreaterThan.h +6 -0
  193. data/Demo/Pods/Headers/Expecta/EXPMatchers+beGreaterThanOrEqualTo.h +6 -0
  194. data/Demo/Pods/Headers/Expecta/EXPMatchers+beIdenticalTo.h +10 -0
  195. data/Demo/Pods/Headers/Expecta/EXPMatchers+beInTheRangeOf.h +6 -0
  196. data/Demo/Pods/Headers/Expecta/EXPMatchers+beInstanceOf.h +7 -0
  197. data/Demo/Pods/Headers/Expecta/EXPMatchers+beKindOf.h +5 -0
  198. data/Demo/Pods/Headers/Expecta/EXPMatchers+beLessThan.h +6 -0
  199. data/Demo/Pods/Headers/Expecta/EXPMatchers+beLessThanOrEqualTo.h +6 -0
  200. data/Demo/Pods/Headers/Expecta/EXPMatchers+beNil.h +5 -0
  201. data/Demo/Pods/Headers/Expecta/EXPMatchers+beSubclassOf.h +5 -0
  202. data/Demo/Pods/Headers/Expecta/EXPMatchers+beSupersetOf.h +4 -0
  203. data/Demo/Pods/Headers/Expecta/EXPMatchers+beTruthy.h +3 -0
  204. data/Demo/Pods/Headers/Expecta/EXPMatchers+beginWith.h +5 -0
  205. data/Demo/Pods/Headers/Expecta/EXPMatchers+conformTo.h +3 -0
  206. data/Demo/Pods/Headers/Expecta/EXPMatchers+contain.h +5 -0
  207. data/Demo/Pods/Headers/Expecta/EXPMatchers+endWith.h +3 -0
  208. data/Demo/Pods/Headers/Expecta/EXPMatchers+equal.h +5 -0
  209. data/Demo/Pods/Headers/Expecta/EXPMatchers+haveCountOf.h +10 -0
  210. data/Demo/Pods/Headers/Expecta/EXPMatchers+notify.h +4 -0
  211. data/Demo/Pods/Headers/Expecta/EXPMatchers+raise.h +4 -0
  212. data/Demo/Pods/Headers/Expecta/EXPMatchers+raiseWithReason.h +3 -0
  213. data/Demo/Pods/Headers/Expecta/EXPMatchers+respondTo.h +3 -0
  214. data/Demo/Pods/Headers/Expecta/EXPMatchers.h +24 -0
  215. data/Demo/Pods/Headers/Expecta/EXPUnsupportedObject.h +11 -0
  216. data/Demo/Pods/Headers/Expecta/Expecta.h +27 -0
  217. data/Demo/Pods/Headers/Expecta/ExpectaSupport.h +64 -0
  218. data/Demo/Pods/Headers/Expecta/NSObject+Expecta.h +14 -0
  219. data/Demo/Pods/Headers/Expecta/NSValue+Expecta.h +8 -0
  220. data/Demo/Pods/Headers/Expecta+Snapshots/EXPMatchers+FBSnapshotTest.h +21 -0
  221. data/Demo/Pods/Headers/FBSnapshotTestCase/FBSnapshotTestCase.h +87 -0
  222. data/Demo/Pods/Headers/FBSnapshotTestCase/FBSnapshotTestController.h +147 -0
  223. data/Demo/Pods/Headers/FBSnapshotTestCase/UIImage+Compare.h +37 -0
  224. data/Demo/Pods/Headers/FBSnapshotTestCase/UIImage+Diff.h +37 -0
  225. data/Demo/Pods/Headers/Specta/SPTExample.h +14 -0
  226. data/Demo/Pods/Headers/Specta/SPTExampleGroup.h +40 -0
  227. data/Demo/Pods/Headers/Specta/SPTNestedReporter.h +5 -0
  228. data/Demo/Pods/Headers/Specta/SPTReporter.h +33 -0
  229. data/Demo/Pods/Headers/Specta/SPTSharedExampleGroups.h +17 -0
  230. data/Demo/Pods/Headers/Specta/SPTSpec.h +21 -0
  231. data/Demo/Pods/Headers/Specta/SPTXCTestCase.h +27 -0
  232. data/Demo/Pods/Headers/Specta/SPTXCTestReporter.h +9 -0
  233. data/Demo/Pods/Headers/Specta/Specta.h +70 -0
  234. data/Demo/Pods/Headers/Specta/SpectaSupport.h +46 -0
  235. data/Demo/Pods/Headers/Specta/SpectaTypes.h +3 -0
  236. data/Demo/Pods/Headers/Specta/SpectaUtility.h +14 -0
  237. data/Demo/Pods/Headers/Specta/XCTestCase+Specta.h +4 -0
  238. data/Demo/Pods/Headers/Specta/XCTestLog+Specta.h +7 -0
  239. data/Demo/Pods/Headers/Specta/XCTestRun+Specta.h +8 -0
  240. data/Demo/Pods/Manifest.lock +21 -0
  241. data/Demo/Pods/Pods-DemoTests-EXPMatchers+FBSnapshotTest-Private.xcconfig +6 -0
  242. data/Demo/Pods/Pods-DemoTests-EXPMatchers+FBSnapshotTest-dummy.m +5 -0
  243. data/Demo/Pods/Pods-DemoTests-EXPMatchers+FBSnapshotTest-prefix.pch +5 -0
  244. data/Demo/Pods/Pods-DemoTests-EXPMatchers+FBSnapshotTest.xcconfig +2 -0
  245. data/Demo/Pods/Pods-DemoTests-Expecta+Snapshots-Private.xcconfig +6 -0
  246. data/Demo/Pods/Pods-DemoTests-Expecta+Snapshots-dummy.m +5 -0
  247. data/Demo/Pods/Pods-DemoTests-Expecta+Snapshots-prefix.pch +5 -0
  248. data/Demo/Pods/Pods-DemoTests-Expecta+Snapshots.xcconfig +2 -0
  249. data/Demo/Pods/Pods-DemoTests-Expecta-Private.xcconfig +5 -0
  250. data/Demo/Pods/Pods-DemoTests-Expecta-dummy.m +5 -0
  251. data/Demo/Pods/Pods-DemoTests-Expecta-prefix.pch +5 -0
  252. data/Demo/Pods/Pods-DemoTests-Expecta.xcconfig +1 -0
  253. data/Demo/Pods/Pods-DemoTests-FBSnapshotTestCase-Private.xcconfig +6 -0
  254. data/Demo/Pods/Pods-DemoTests-FBSnapshotTestCase-dummy.m +5 -0
  255. data/Demo/Pods/Pods-DemoTests-FBSnapshotTestCase-prefix.pch +6 -0
  256. data/Demo/Pods/Pods-DemoTests-FBSnapshotTestCase.xcconfig +2 -0
  257. data/Demo/Pods/Pods-DemoTests-Specta-Private.xcconfig +6 -0
  258. data/Demo/Pods/Pods-DemoTests-Specta-dummy.m +5 -0
  259. data/Demo/Pods/Pods-DemoTests-Specta-prefix.pch +5 -0
  260. data/Demo/Pods/Pods-DemoTests-Specta.xcconfig +2 -0
  261. data/Demo/Pods/Pods-DemoTests-acknowledgements.markdown +109 -0
  262. data/Demo/Pods/Pods-DemoTests-acknowledgements.plist +151 -0
  263. data/Demo/Pods/Pods-DemoTests-dummy.m +5 -0
  264. data/Demo/Pods/Pods-DemoTests-environment.h +32 -0
  265. data/Demo/Pods/Pods-DemoTests-resources.sh +68 -0
  266. data/Demo/Pods/Pods-DemoTests.xcconfig +6 -0
  267. data/Demo/Pods/Pods.xcodeproj/project.pbxproj +1390 -0
  268. data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests-Expecta+Snapshots.xcscheme +59 -0
  269. data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests-Expecta.xcscheme +59 -0
  270. data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests-FBSnapshotTestCase.xcscheme +59 -0
  271. data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests-Specta.xcscheme +59 -0
  272. data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/Pods-DemoTests.xcscheme +59 -0
  273. data/Demo/Pods/Pods.xcodeproj/xcuserdata/ash.xcuserdatad/xcschemes/xcschememanagement.plist +62 -0
  274. data/Demo/Pods/Specta/LICENSE +20 -0
  275. data/Demo/Pods/Specta/README.md +146 -0
  276. data/Demo/Pods/Specta/src/SPTExample.h +14 -0
  277. data/Demo/Pods/Specta/src/SPTExample.m +16 -0
  278. data/Demo/Pods/Specta/src/SPTExampleGroup.h +40 -0
  279. data/Demo/Pods/Specta/src/SPTExampleGroup.m +326 -0
  280. data/Demo/Pods/Specta/src/SPTNestedReporter.h +5 -0
  281. data/Demo/Pods/Specta/src/SPTNestedReporter.m +194 -0
  282. data/Demo/Pods/Specta/src/SPTReporter.h +33 -0
  283. data/Demo/Pods/Specta/src/SPTReporter.m +134 -0
  284. data/Demo/Pods/Specta/src/SPTSharedExampleGroups.h +17 -0
  285. data/Demo/Pods/Specta/src/SPTSharedExampleGroups.m +62 -0
  286. data/Demo/Pods/Specta/src/SPTSpec.h +21 -0
  287. data/Demo/Pods/Specta/src/SPTSpec.m +31 -0
  288. data/Demo/Pods/Specta/src/SPTXCTestCase.h +27 -0
  289. data/Demo/Pods/Specta/src/SPTXCTestCase.m +151 -0
  290. data/Demo/Pods/Specta/src/SPTXCTestReporter.h +9 -0
  291. data/Demo/Pods/Specta/src/SPTXCTestReporter.m +11 -0
  292. data/Demo/Pods/Specta/src/Specta.h +70 -0
  293. data/Demo/Pods/Specta/src/Specta.m +144 -0
  294. data/Demo/Pods/Specta/src/SpectaSupport.h +46 -0
  295. data/Demo/Pods/Specta/src/SpectaTypes.h +3 -0
  296. data/Demo/Pods/Specta/src/SpectaUtility.h +14 -0
  297. data/Demo/Pods/Specta/src/SpectaUtility.m +65 -0
  298. data/Demo/Pods/Specta/src/XCTestCase+Specta.h +4 -0
  299. data/Demo/Pods/Specta/src/XCTestCase+Specta.m +26 -0
  300. data/Demo/Pods/Specta/src/XCTestLog+Specta.h +7 -0
  301. data/Demo/Pods/Specta/src/XCTestLog+Specta.m +49 -0
  302. data/Demo/Pods/Specta/src/XCTestRun+Specta.h +8 -0
  303. data/Demo/Pods/Specta/src/XCTestRun+Specta.m +44 -0
  304. data/Gemfile +5 -0
  305. data/LICENSE +21 -0
  306. data/README.md +146 -0
  307. data/Rakefile +7 -0
  308. data/second_curtain.gemspec +20 -0
  309. data/spec/sample_output.txt +79 -0
  310. data/spec/second_shutter/kaleidoscope_command_spec.rb +25 -0
  311. data/spec/second_shutter/parser_spec.rb +39 -0
  312. data/spec/second_shutter/test_suite_spec.rb +32 -0
  313. data/spec/second_shutter/upload_manager_spec.rb +60 -0
  314. data/spec/second_shutter/upload_spec.rb +34 -0
  315. data/spec/second_shutter/xcode_test_case_spec.rb +22 -0
  316. 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
+ [![Build Status](https://travis-ci.org/dblock/ios-snapshot-test-case-expecta.png)](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