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,326 @@
1
+ #import "SPTExampleGroup.h"
2
+ #import "SPTExample.h"
3
+ #import "SPTXCTestCase.h"
4
+ #import "SPTSpec.h"
5
+ #import "SpectaUtility.h"
6
+ #import <libkern/OSAtomic.h>
7
+ #import <objc/runtime.h>
8
+
9
+ static NSArray *ClassesWithClassMethod(SEL classMethodSelector) {
10
+ NSMutableArray *classesWithClassMethod = [[NSMutableArray alloc] init];
11
+
12
+ int numberOfClasses = objc_getClassList(NULL, 0);
13
+ if (numberOfClasses > 0) {
14
+ Class *classes = (Class *)malloc(sizeof(Class) *numberOfClasses);
15
+ numberOfClasses = objc_getClassList(classes, numberOfClasses);
16
+
17
+ for(int classIndex = 0; classIndex < numberOfClasses; classIndex++) {
18
+ Class aClass = classes[classIndex];
19
+
20
+ if (strcmp("UIAccessibilitySafeCategory__NSObject", class_getName(aClass))) {
21
+ Method globalMethod = class_getClassMethod(aClass, classMethodSelector);
22
+ if (globalMethod) {
23
+ [classesWithClassMethod addObject:aClass];
24
+ }
25
+ }
26
+ }
27
+
28
+ free(classes);
29
+ }
30
+
31
+ return classesWithClassMethod;
32
+ }
33
+
34
+ @interface NSObject (SpectaGlobalBeforeAfterEach)
35
+
36
+ + (void)beforeEach;
37
+ + (void)afterEach;
38
+
39
+ @end
40
+
41
+ static NSTimeInterval asyncSpecTimeout = 10.0;
42
+ static const char *asyncBlockSignature = NULL;
43
+
44
+ static void runExampleBlock(id block, NSString *name) {
45
+ if (!SPTIsBlock(block)) {
46
+ return;
47
+ }
48
+
49
+ const char *blockSignature = SPTGetBlockSignature(block);
50
+
51
+ BOOL isAsyncBlock = strcmp(blockSignature, asyncBlockSignature) == 0;
52
+
53
+ if (isAsyncBlock) {
54
+ __block uint32_t complete = 0;
55
+ ((SPTAsyncBlock)block)(^{
56
+ OSAtomicOr32Barrier(1, &complete);
57
+ });
58
+ NSTimeInterval timeout = asyncSpecTimeout;
59
+ NSDate *timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout];
60
+ while (!complete && [timeoutDate timeIntervalSinceNow] > 0) {
61
+ [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
62
+ }
63
+ if (!complete) {
64
+ NSString *message = [NSString stringWithFormat:@"\"%@\" failed to invoke done() callback before timeout (%f seconds)", name, timeout];
65
+ SPTXCTestCase *currentTestCase = SPTCurrentTestCase;
66
+ SPTSpec *spec = [[currentTestCase class] spt_spec];
67
+ [currentTestCase recordFailureWithDescription:message inFile:spec.fileName atLine:spec.lineNumber expected:YES];
68
+ }
69
+ } else {
70
+ ((SPTVoidBlock)block)();
71
+ }
72
+ }
73
+
74
+ @interface SPTExampleGroup ()
75
+
76
+ - (void)incrementExampleCount;
77
+ - (void)resetRanExampleCountIfNeeded;
78
+ - (void)incrementRanExampleCount;
79
+ - (void)runBeforeHooks:(NSString *)compiledName;
80
+ - (void)runAfterHooks:(NSString *)compiledName;
81
+
82
+ @end
83
+
84
+ @implementation SPTExampleGroup
85
+
86
+ + (void)initialize {
87
+ if (asyncBlockSignature == NULL) {
88
+ asyncBlockSignature = SPTGetBlockSignature(^(void (^done)(void)) {});
89
+ }
90
+ }
91
+
92
+ - (id)init {
93
+ self = [super init];
94
+ if (self) {
95
+ self.name = nil;
96
+ self.root = nil;
97
+ self.parent = nil;
98
+ self.children = [NSMutableArray array];
99
+ self.beforeAllArray = [NSMutableArray array];
100
+ self.afterAllArray = [NSMutableArray array];
101
+ self.beforeEachArray = [NSMutableArray array];
102
+ self.afterEachArray = [NSMutableArray array];
103
+ self.sharedExamples = [NSMutableDictionary dictionary];
104
+ self.exampleCount = 0;
105
+ self.ranExampleCount = 0;
106
+ }
107
+ return self;
108
+ }
109
+
110
+ + (void)setAsyncSpecTimeout:(NSTimeInterval)timeout {
111
+ asyncSpecTimeout = timeout;
112
+ }
113
+
114
+ - (id)initWithName:(NSString *)name parent:(SPTExampleGroup *)parent root:(SPTExampleGroup *)root {
115
+ self = [self init];
116
+ if (self) {
117
+ self.name = name;
118
+ self.parent = parent;
119
+ self.root = root;
120
+ }
121
+ return self;
122
+ }
123
+
124
+ - (SPTExampleGroup *)addExampleGroupWithName:(NSString *)name {
125
+ return [self addExampleGroupWithName:name
126
+ focused:NO];
127
+ }
128
+
129
+
130
+ - (SPTExampleGroup *)addExampleGroupWithName:(NSString *)name focused:(BOOL)focused {
131
+ SPTExampleGroup *group = [[SPTExampleGroup alloc] initWithName:name parent:self root:self.root];
132
+ group.focused = focused;
133
+ [self.children addObject:group];
134
+ return group;
135
+ }
136
+
137
+ - (SPTExample *)addExampleWithName:(NSString *)name block:(id)block {
138
+ return [self addExampleWithName:name
139
+ block:block
140
+ focused:NO];
141
+ }
142
+
143
+ - (SPTExample *)addExampleWithName:(NSString *)name block:(id)block focused:(BOOL)focused {
144
+ SPTExample *example;
145
+ @synchronized(self) {
146
+ example = [[SPTExample alloc] initWithName:name block:block];
147
+ example.focused = focused;
148
+ [self.children addObject:example];
149
+ [self incrementExampleCount];
150
+ }
151
+ return example;
152
+ }
153
+
154
+ - (void)incrementExampleCount {
155
+ SPTExampleGroup *group = self;
156
+ while (group != nil) {
157
+ group.exampleCount ++;
158
+ group = group.parent;
159
+ }
160
+ }
161
+
162
+ - (void)resetRanExampleCountIfNeeded {
163
+ SPTExampleGroup *group = self;
164
+ while (group != nil) {
165
+ if (group.ranExampleCount >= group.exampleCount) {
166
+ group.ranExampleCount = 0;
167
+ }
168
+ group = group.parent;
169
+ }
170
+ }
171
+
172
+ - (void)incrementRanExampleCount {
173
+ SPTExampleGroup *group = self;
174
+ while (group != nil) {
175
+ group.ranExampleCount ++;
176
+ group = group.parent;
177
+ }
178
+ }
179
+
180
+ - (void)addBeforeAllBlock:(SPTVoidBlock)block {
181
+ if (!block) return;
182
+ [self.beforeAllArray addObject:[block copy]];
183
+ }
184
+
185
+ - (void)addAfterAllBlock:(SPTVoidBlock)block {
186
+ if (!block) return;
187
+ [self.afterAllArray addObject:[block copy]];
188
+ }
189
+
190
+ - (void)addBeforeEachBlock:(SPTVoidBlock)block {
191
+ if (!block) return;
192
+ [self.beforeEachArray addObject:[block copy]];
193
+ }
194
+
195
+ - (void)addAfterEachBlock:(SPTVoidBlock)block {
196
+ if (!block) return;
197
+ [self.afterEachArray addObject:[block copy]];
198
+ }
199
+
200
+ - (void)runGlobalBeforeEachHooks:(NSString *)compiledName {
201
+ static NSArray *globalBeforeEachClasses;
202
+ static dispatch_once_t onceToken;
203
+ dispatch_once(&onceToken, ^{
204
+ globalBeforeEachClasses = ClassesWithClassMethod(@selector(beforeEach));
205
+ });
206
+
207
+ for (Class class in globalBeforeEachClasses) {
208
+ [class beforeEach];
209
+ }
210
+ }
211
+
212
+ - (void)runGlobalAfterEachHooks:(NSString *)compiledName {
213
+ static NSArray *globalAfterEachClasses;
214
+ static dispatch_once_t onceToken;
215
+ dispatch_once(&onceToken, ^{
216
+ globalAfterEachClasses = ClassesWithClassMethod(@selector(afterEach));
217
+ });
218
+
219
+ for (Class class in globalAfterEachClasses) {
220
+ [class afterEach];
221
+ }
222
+ }
223
+
224
+ - (void)runBeforeHooks:(NSString *)compiledName {
225
+ NSMutableArray *groups = [NSMutableArray array];
226
+ SPTExampleGroup *group = self;
227
+ while (group != nil) {
228
+ [groups insertObject:group atIndex:0];
229
+ group = group.parent;
230
+ }
231
+
232
+ // run beforeAll hooks
233
+ for(group in groups) {
234
+ if (group.ranExampleCount == 0) {
235
+ for(id beforeAllBlock in group.beforeAllArray) {
236
+ runExampleBlock(beforeAllBlock, [NSString stringWithFormat:@"%@ - before all block", compiledName]);
237
+ }
238
+ }
239
+ }
240
+
241
+ // run beforeEach hooks
242
+ [self runGlobalBeforeEachHooks:compiledName];
243
+ for(group in groups) {
244
+ for(id beforeEachBlock in group.beforeEachArray) {
245
+ runExampleBlock(beforeEachBlock, [NSString stringWithFormat:@"%@ - before each block", compiledName]);
246
+ }
247
+ }
248
+ }
249
+
250
+ - (void)runAfterHooks:(NSString *)compiledName {
251
+ NSMutableArray *groups = [NSMutableArray array];
252
+ SPTExampleGroup *group = self;
253
+ while (group != nil) {
254
+ [groups addObject:group];
255
+ group = group.parent;
256
+ }
257
+ // run afterEach hooks
258
+ for(group in groups) {
259
+ for(id afterEachBlock in group.afterEachArray) {
260
+ runExampleBlock(afterEachBlock, [NSString stringWithFormat:@"%@ - after each block", compiledName]);
261
+ }
262
+ }
263
+ [self runGlobalAfterEachHooks:compiledName];
264
+
265
+ // run afterAll hooks
266
+ for(group in groups) {
267
+ if (group.ranExampleCount == group.exampleCount) {
268
+ for(id afterAllBlock in group.afterAllArray) {
269
+ runExampleBlock(afterAllBlock, [NSString stringWithFormat:@"%@ - after all block", compiledName]);
270
+ }
271
+ }
272
+ }
273
+ }
274
+
275
+ - (BOOL)isFocusedOrHasFocusedAncestor {
276
+ SPTExampleGroup *ancestor = self;
277
+ while (ancestor != nil) {
278
+ if (ancestor.focused) {
279
+ return YES;
280
+ } else {
281
+ ancestor = ancestor.parent;
282
+ }
283
+ }
284
+
285
+ return NO;
286
+ }
287
+
288
+ - (NSArray *)compileExamplesWithNameStack:(NSArray *)nameStack {
289
+ BOOL groupIsFocusedOrHasFocusedAncestor = [self isFocusedOrHasFocusedAncestor];
290
+
291
+ NSArray *compiled = @[];
292
+ for(id child in self.children) {
293
+ if ([child isKindOfClass:[SPTExampleGroup class]]) {
294
+ SPTExampleGroup *group = child;
295
+ NSArray *newNameStack = [nameStack arrayByAddingObject:group.name];
296
+ compiled = [compiled arrayByAddingObjectsFromArray:[group compileExamplesWithNameStack:newNameStack]];
297
+ } else if ([child isKindOfClass:[SPTExample class]]) {
298
+ SPTExample *example = child;
299
+ NSArray *newNameStack = [nameStack arrayByAddingObject:example.name];
300
+ NSString *compiledName = [newNameStack componentsJoinedByString:@" "];
301
+
302
+ SPTVoidBlock compiledBlock = example.pending ? nil : ^{
303
+ @synchronized(self.root) {
304
+ [self resetRanExampleCountIfNeeded];
305
+ [self runBeforeHooks:compiledName];
306
+ }
307
+ @try {
308
+ runExampleBlock(example.block, compiledName);
309
+ }
310
+ @finally {
311
+ @synchronized(self.root) {
312
+ [self incrementRanExampleCount];
313
+ [self runAfterHooks:compiledName];
314
+ }
315
+ }
316
+ };
317
+ SPTExample *compiledExample = [[SPTExample alloc] initWithName:compiledName block:compiledBlock];
318
+ compiledExample.pending = example.pending;
319
+ compiledExample.focused = (groupIsFocusedOrHasFocusedAncestor || example.focused);
320
+ compiled = [compiled arrayByAddingObject:compiledExample];
321
+ }
322
+ }
323
+ return compiled;
324
+ }
325
+
326
+ @end
@@ -0,0 +1,5 @@
1
+ #import "SPTReporter.h"
2
+
3
+ @interface SPTNestedReporter : SPTReporter
4
+
5
+ @end
@@ -0,0 +1,194 @@
1
+ #import "SPTNestedReporter.h"
2
+ #import "XCTestRun+Specta.h"
3
+
4
+ @interface SPTNestedReporter ()
5
+
6
+ @property (readwrite, assign, nonatomic) NSInteger nestingLevel;
7
+ @property (readwrite, assign, nonatomic) BOOL indentationEnabled;
8
+
9
+ @end
10
+
11
+ @implementation SPTNestedReporter
12
+
13
+ #pragma mark - Printing
14
+
15
+ - (NSString *)indentation {
16
+ // XCode does not strip whitespace from the beginning of lines that report an error. Indentation should only enabled for non-error text.
17
+
18
+ if (self.indentationEnabled) {
19
+ return [@"" stringByPaddingToLength:(self.nestingLevel * 2)
20
+ withString:@" "
21
+ startingAtIndex:0];
22
+ } else {
23
+ return @"";
24
+ }
25
+ }
26
+
27
+ - (void)withIndentationEnabled:(void(^)(void))block {
28
+ [self withIndentationEnabled:YES block:block];
29
+ }
30
+
31
+ - (void)withIndentationEnabled:(BOOL)indentationEnabled block:(void(^)(void))block {
32
+ BOOL originalValue = self.indentationEnabled;
33
+
34
+ self.indentationEnabled = indentationEnabled;
35
+ @try {
36
+ block();
37
+ } @finally {
38
+ self.indentationEnabled = originalValue;
39
+ }
40
+ }
41
+
42
+ - (void)printIndentation {
43
+ [self printString:self.indentation];
44
+ }
45
+
46
+ - (void)printTestSuiteHeader:(XCTestRun *)testRun {
47
+ [self printIndentation];
48
+ [self printLineWithFormat:@"= %@", testRun.test.name];
49
+ }
50
+
51
+ - (void)printTestSuiteFooter:(XCTestRun *)testRun {
52
+ [self printIndentation];
53
+ [self printLine];
54
+
55
+ if (self.nestingLevel == 0) {
56
+ [self printConciseSummaryOfTestRun:testRun];
57
+ }
58
+ }
59
+
60
+ - (void)printConciseSummaryOfTestRun:(XCTestRun *)testRun {
61
+ NSUInteger numberOfTests = testRun.testCaseCount;
62
+ NSUInteger numberOfFailures = testRun.totalFailureCount;
63
+ NSUInteger numberOfExceptions = testRun.unexpectedExceptionCount;
64
+ NSUInteger numberOfSkippedTests = testRun.spt_skippedTestCaseCount;
65
+ NSUInteger numberOfPendingTests = testRun.spt_pendingTestCaseCount;
66
+
67
+ NSString * runInfo = [[self class] conciseRunInfoWithNumberOfTests:numberOfTests
68
+ numberOfSkippedTests:numberOfSkippedTests
69
+ numberOfFailures:numberOfFailures
70
+ numberOfExceptions:numberOfExceptions
71
+ numberOfPendingTests:numberOfPendingTests];
72
+
73
+ [self printIndentation];
74
+ [self printLine:runInfo];
75
+ }
76
+
77
+ - (void)printTestCaseHeader:(XCTestRun *)testRun {
78
+ [self printIndentation];
79
+ [self printLineWithFormat:@"%@", testRun.test.name];
80
+ }
81
+
82
+ - (void)printTestCaseFooter:(XCTestRun *)testRun {
83
+ [self printIndentation];
84
+ [self printLine];
85
+ }
86
+
87
+ + (NSString *)pluralizeString:(NSString *)singularString
88
+ pluralString:(NSString *)pluralString
89
+ count:(NSInteger)count {
90
+ return (count == 1 || count == -1) ? singularString : pluralString;
91
+ }
92
+
93
+ + (NSString *)conciseRunInfoWithNumberOfTests:(NSUInteger)numberOfTests
94
+ numberOfSkippedTests:(NSUInteger)numberOfSkippedTests
95
+ numberOfFailures:(NSUInteger)numberOfFailures
96
+ numberOfExceptions:(NSUInteger)numberOfExceptions
97
+ numberOfPendingTests:(NSUInteger)numberOfPendingTests {
98
+ NSString * testLabel = [[self class] pluralizeString:@"test"
99
+ pluralString:@"tests"
100
+ count:numberOfTests];
101
+
102
+ NSString * failureLabel = [[self class] pluralizeString:@"failure"
103
+ pluralString:@"failures"
104
+ count:numberOfFailures];
105
+
106
+ NSString * exceptionLabel = [[self class] pluralizeString:@"exception"
107
+ pluralString:@"exceptions"
108
+ count:numberOfExceptions];
109
+
110
+ return [NSString stringWithFormat:@"%lu %@; %lu skipped; %lu %@; %lu %@; %lu pending",
111
+ (unsigned long)numberOfTests,
112
+ testLabel,
113
+ (unsigned long)numberOfSkippedTests,
114
+ (unsigned long)numberOfFailures,
115
+ failureLabel,
116
+ (unsigned long)numberOfExceptions,
117
+ exceptionLabel,
118
+ (unsigned long)numberOfPendingTests];
119
+ }
120
+
121
+ #pragma mark - XCTestObserver
122
+
123
+ - (void)startObserving {
124
+ [super startObserving];
125
+
126
+ self.nestingLevel = 0;
127
+ }
128
+
129
+ - (void)testSuiteDidStart:(XCTestRun *)testRun {
130
+ [self withIndentationEnabled:^{
131
+
132
+ [self printTestSuiteHeader:testRun];
133
+ self.nestingLevel ++;
134
+
135
+ [super testSuiteDidStart:testRun];
136
+ [self printLine];
137
+
138
+ }];
139
+ }
140
+
141
+ - (void)testSuiteDidStop:(XCTestRun *)testRun {
142
+ [self withIndentationEnabled:^{
143
+
144
+ [super testSuiteDidStop:testRun];
145
+
146
+ self.nestingLevel --;
147
+ [self printTestSuiteFooter:testRun];
148
+
149
+ }];
150
+ }
151
+
152
+ - (void)testCaseDidStart:(XCTestRun *)testRun {
153
+ [self withIndentationEnabled:^{
154
+
155
+ [self printTestCaseHeader:testRun];
156
+ self.nestingLevel ++;
157
+
158
+ [super testCaseDidStart:testRun];
159
+
160
+ }];
161
+ }
162
+
163
+ - (void)testCaseDidStop:(XCTestRun *)testRun {
164
+ [self withIndentationEnabled:^{
165
+
166
+ [super testCaseDidStop:testRun];
167
+
168
+ self.nestingLevel --;
169
+ [self printTestCaseFooter:testRun];
170
+
171
+ }];
172
+ }
173
+
174
+ - (void)testLogWithFormat:(NSString *)format arguments:(va_list)arguments {
175
+ NSString * indentation = self.indentation;
176
+
177
+ NSMutableString * indentedFormat = [[NSMutableString alloc] initWithString:format];
178
+ [indentedFormat insertString:indentation atIndex:0];
179
+
180
+ NSRange replacementRange = NSMakeRange(0, [indentedFormat length]);
181
+ if ([indentedFormat hasSuffix:@"\n"]) {
182
+ replacementRange.length -= [@"\n" length];
183
+ }
184
+
185
+ [indentedFormat replaceOccurrencesOfString:@"\n"
186
+ withString:[@"\n" stringByAppendingString:indentation]
187
+ options:0
188
+ range:replacementRange];
189
+
190
+ [super testLogWithFormat:indentedFormat
191
+ arguments:arguments];
192
+ }
193
+
194
+ @end
@@ -0,0 +1,33 @@
1
+ #import <XCTest/XCTest.h>
2
+
3
+ @interface SPTReporter : XCTestLog
4
+
5
+ /*
6
+ * Returns a singleton reporter used to generate Specta's test output.
7
+ * The type of reporter can be customized by subclassing and setting the
8
+ * SPECTA_REPORTER_CLASS environment variable.
9
+ *
10
+ * Subclasses may override methods from XCTestObserver to change test output.
11
+ * Initialization shuld be performed in the -startObserving / -stopObserving methods,
12
+ * and MUST invoke the super class implementation.
13
+ */
14
+ + (instancetype)sharedReporter;
15
+
16
+ #pragma mark - Run Stack
17
+
18
+ @property (nonatomic, strong, readonly) NSArray *runStack;
19
+ @property (nonatomic, assign, readonly) NSUInteger runStackCount;
20
+
21
+ @property (nonatomic, assign, readonly) NSInteger numberOfTestCases;
22
+ @property (nonatomic, assign, readonly) NSInteger numberOfCompletedTestCases;
23
+
24
+ #pragma mark - Printing
25
+
26
+ - (void)printString:(NSString *)string;
27
+ - (void)printStringWithFormat:(NSString *)formatString, ... NS_FORMAT_FUNCTION(1,2);
28
+
29
+ - (void)printLine;
30
+ - (void)printLine:(NSString *)line;
31
+ - (void)printLineWithFormat:(NSString *)formatString, ... NS_FORMAT_FUNCTION(1,2);
32
+
33
+ @end
@@ -0,0 +1,134 @@
1
+ #import "SPTReporter.h"
2
+ #import "SPTNestedReporter.h"
3
+ #import "XCTestLog+Specta.h"
4
+
5
+ @interface SPTReporter ()
6
+
7
+ @property (nonatomic, strong, readwrite) NSArray *runStack;
8
+ @property (nonatomic, assign, readwrite) NSInteger numberOfCompletedTestCases;
9
+
10
+ @end
11
+
12
+ @implementation SPTReporter
13
+
14
+ + (instancetype)sharedReporter {
15
+ static SPTReporter * sharedReporter;
16
+ static dispatch_once_t onceToken;
17
+ dispatch_once(&onceToken, ^{
18
+ sharedReporter = [self loadSharedReporter];
19
+ });
20
+
21
+ return sharedReporter;
22
+ }
23
+
24
+ + (SPTReporter *)loadSharedReporter {
25
+ NSString * customReporterClassName = [[NSProcessInfo processInfo] environment][@"SPECTA_REPORTER_CLASS"];
26
+ if (customReporterClassName != nil) {
27
+ Class customReporterClass = NSClassFromString(customReporterClassName);
28
+ if (customReporterClass != nil) {
29
+ return [[customReporterClass alloc] init];
30
+ }
31
+ }
32
+
33
+ return [[SPTNestedReporter alloc] init];
34
+ }
35
+
36
+ #pragma mark - Run Stack
37
+
38
+ - (NSUInteger)runStackCount {
39
+ return self.runStack.count;
40
+ }
41
+
42
+ - (void)pushRunStack:(XCTestRun *)run {
43
+ [(NSMutableArray *)self.runStack addObject:run];
44
+ }
45
+
46
+ - (void)popRunStack:(XCTestRun *)run {
47
+ NSAssert(run != nil, @"Attempt to pop nil test run");
48
+
49
+ NSAssert([self.runStack lastObject] == run,
50
+ @"Attempt to pop test run (%@) out of order: %@",
51
+ run,
52
+ self.runStack);
53
+
54
+ [(NSMutableArray *)self.runStack removeLastObject];
55
+ }
56
+
57
+ - (NSInteger)numberOfTestCases {
58
+ XCTestRun * rootRun = self.runStack.firstObject;
59
+ if (rootRun) {
60
+ return rootRun.testCaseCount;
61
+ } else {
62
+ return 0;
63
+ }
64
+ }
65
+
66
+ #pragma mark - Printing
67
+
68
+ - (void)printString:(NSString *)string {
69
+ [[self logFileHandle] writeData:[string dataUsingEncoding:NSUTF8StringEncoding]];
70
+ }
71
+
72
+ - (void)printStringWithFormat:(NSString *)formatString, ... {
73
+ va_list args;
74
+ va_start(args, formatString);
75
+ NSString * formattedString = [[NSString alloc] initWithFormat:formatString arguments:args];
76
+ va_end(args);
77
+
78
+ [self printString:formattedString];
79
+ }
80
+
81
+ - (void)printLine {
82
+ [self printString:@"\n"];
83
+ }
84
+
85
+ - (void)printLine:(NSString *)line {
86
+ [self printStringWithFormat:@"%@\n", line];
87
+ }
88
+
89
+ - (void)printLineWithFormat:(NSString *)formatString, ... {
90
+ va_list args;
91
+ va_start(args, formatString);
92
+ NSString * formattedString = [[NSString alloc] initWithFormat:formatString arguments:args];
93
+ va_end(args);
94
+
95
+ [self printLine:formattedString];
96
+ }
97
+
98
+ #pragma mark - XCTestObserver
99
+
100
+ - (void)startObserving {
101
+ [super startObserving];
102
+
103
+ self.runStack = [[NSMutableArray alloc] init];
104
+ }
105
+
106
+ - (void)stopObserving {
107
+ [super stopObserving];
108
+
109
+ self.runStack = nil;
110
+ }
111
+
112
+ - (void)testSuiteDidStart:(XCTestRun *)testRun {
113
+ [super testSuiteDidStart:testRun];
114
+ [self pushRunStack:testRun];
115
+ }
116
+
117
+ - (void)testSuiteDidStop:(XCTestRun *)testRun {
118
+ [super testSuiteDidStop:testRun];
119
+ [self popRunStack:testRun];
120
+ }
121
+
122
+ - (void)testCaseDidStart:(XCTestRun *)testRun {
123
+ [super testCaseDidStart:testRun];
124
+ [self pushRunStack:testRun];
125
+ }
126
+
127
+ - (void)testCaseDidStop:(XCTestRun *)testRun {
128
+ [super testCaseDidStop:testRun];
129
+ [self popRunStack:testRun];
130
+
131
+ self.numberOfCompletedTestCases++;
132
+ }
133
+
134
+ @end
@@ -0,0 +1,17 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import "SpectaTypes.h"
3
+
4
+ @class
5
+ SPTExampleGroup
6
+ ;
7
+
8
+ @interface SPTSharedExampleGroups : NSObject
9
+
10
+ + (void)addSharedExampleGroupWithName:(NSString *)name block:(SPTDictionaryBlock)block exampleGroup:(SPTExampleGroup *)exampleGroup;
11
+ + (SPTDictionaryBlock)sharedExampleGroupWithName:(NSString *)name exampleGroup:(SPTExampleGroup *)exampleGroup;
12
+ + (void)defineSharedExampleGroups;
13
+
14
+ + (void)recordFailureWithDescription:(NSString *)description inFile:(NSString *)filename atLine:(NSUInteger)lineNumber expected:(BOOL)expected;
15
+
16
+ @end
17
+