├── .gitignore
├── .travis.yml
├── Example
├── Podfile
├── Podfile.lock
├── Tests
│ ├── Info.plist
│ └── Tests.swift
├── Vigilant.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Vigilant-Example.xcscheme
├── Vigilant.xcworkspace
│ └── contents.xcworkspacedata
└── Vigilant
│ ├── AppDelegate.swift
│ ├── Base.lproj
│ ├── LaunchScreen.xib
│ └── Main.storyboard
│ ├── Images.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Info.plist
│ └── ViewController.swift
├── LICENSE
├── README.md
├── Vigilant.podspec
└── Vigilant
└── Classes
├── Vigilant.h
└── Vigilant.m
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 | Example/Pods
25 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # references:
2 | # * http://www.objc.io/issue-6/travis-ci.html
3 | # * https://github.com/supermarin/xcpretty#usage
4 |
5 | language: objective-c
6 | # cache: cocoapods
7 | # podfile: Example/Podfile
8 | # before_install:
9 | # - gem install cocoapods # Since Travis is not always on latest version
10 | # - pod install --project-directory=Example
11 | script:
12 | - set -o pipefail && xcodebuild test -workspace Example/Vigilant.xcworkspace -scheme Vigilant-Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO | xcpretty
13 | - pod lib lint
14 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | source 'https://github.com/CocoaPods/Specs.git'
2 | use_frameworks!
3 |
4 | target 'Vigilant_Example', :exclusive => true do
5 | pod 'Vigilant', :path => '../'
6 | end
7 |
8 | target 'Vigilant_Tests', :exclusive => true do
9 | pod 'Vigilant', :path => '../'
10 |
11 | pod 'Quick'
12 | pod 'Nimble'
13 | end
14 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Nimble (4.0.0)
3 | - Quick (0.9.1)
4 | - Vigilant (1.0.0):
5 | - Nimble
6 | - Quick
7 |
8 | DEPENDENCIES:
9 | - Nimble
10 | - Quick
11 | - Vigilant (from `../`)
12 |
13 | EXTERNAL SOURCES:
14 | Vigilant:
15 | :path: ../
16 |
17 | SPEC CHECKSUMS:
18 | Nimble: 72bcc3e2f02242e6bfaaf8d9412ca7bfe3d8b417
19 | Quick: a5221fc21788b6aeda934805e68b061839bc3165
20 | Vigilant: c7c27bfd207bc691a27fa1e74aff3b52687c0eb5
21 |
22 | COCOAPODS: 0.39.0
23 |
--------------------------------------------------------------------------------
/Example/Tests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/Example/Tests/Tests.swift:
--------------------------------------------------------------------------------
1 | import Quick
2 | import Nimble
3 |
4 | class VigilantSpec: QuickSpec {
5 | override func spec() {
6 | describe("Vigilant's tiny test suite") {
7 |
8 | describe("FAILS -") {
9 | it("this should fail") { }
10 |
11 | it("this also should fail") {
12 | let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
13 | dispatch_async(dispatch_get_global_queue(priority, 0)) {
14 | expect(0) == 0
15 | }
16 | }
17 | }
18 |
19 | describe("FAILS - shouldn't be affected by nested beforeEach") {
20 | beforeEach { }
21 | it("fails") { }
22 | }
23 |
24 | it("This should pass though") {
25 | expect("Tests") == "Tests"
26 | }
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Example/Vigilant.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD51AFB9204008FA782 /* AppDelegate.swift */; };
11 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACD71AFB9204008FA782 /* ViewController.swift */; };
12 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 607FACD91AFB9204008FA782 /* Main.storyboard */; };
13 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDC1AFB9204008FA782 /* Images.xcassets */; };
14 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
15 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 607FACEB1AFB9204008FA782 /* Tests.swift */; };
16 | 9356B80908978E7DC8603626 /* Pods_Vigilant_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A5CC8C2AB7AC67194FFA9956 /* Pods_Vigilant_Tests.framework */; };
17 | EB00730BF0BDF9F4E8E58D4C /* Pods_Vigilant_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEE4D0E2121DDB63A3FBBDAC /* Pods_Vigilant_Example.framework */; };
18 | /* End PBXBuildFile section */
19 |
20 | /* Begin PBXContainerItemProxy section */
21 | 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */ = {
22 | isa = PBXContainerItemProxy;
23 | containerPortal = 607FACC81AFB9204008FA782 /* Project object */;
24 | proxyType = 1;
25 | remoteGlobalIDString = 607FACCF1AFB9204008FA782;
26 | remoteInfo = Vigilant;
27 | };
28 | /* End PBXContainerItemProxy section */
29 |
30 | /* Begin PBXFileReference section */
31 | 0147682571EA3685BE0C6C96 /* Pods-Vigilant_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Vigilant_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Vigilant_Tests/Pods-Vigilant_Tests.debug.xcconfig"; sourceTree = ""; };
32 | 17927D7E2A832D96CAC785FB /* Pods-Vigilant_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Vigilant_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Vigilant_Example/Pods-Vigilant_Example.debug.xcconfig"; sourceTree = ""; };
33 | 3ECF8E2E5FB7233CFF2B3786 /* Vigilant.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Vigilant.podspec; path = ../Vigilant.podspec; sourceTree = ""; };
34 | 46D452031610453D96134496 /* Pods-Vigilant_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Vigilant_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Vigilant_Tests/Pods-Vigilant_Tests.release.xcconfig"; sourceTree = ""; };
35 | 607FACD01AFB9204008FA782 /* Vigilant_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Vigilant_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
36 | 607FACD41AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
37 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
38 | 607FACD71AFB9204008FA782 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
39 | 607FACDA1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
40 | 607FACDC1AFB9204008FA782 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
41 | 607FACDF1AFB9204008FA782 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; };
42 | 607FACE51AFB9204008FA782 /* Vigilant_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Vigilant_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
44 | 607FACEB1AFB9204008FA782 /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; };
45 | A5CC8C2AB7AC67194FFA9956 /* Pods_Vigilant_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Vigilant_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
46 | A962B4391E078CABA8F008DB /* Pods-Vigilant_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Vigilant_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-Vigilant_Example/Pods-Vigilant_Example.release.xcconfig"; sourceTree = ""; };
47 | AEE4D0E2121DDB63A3FBBDAC /* Pods_Vigilant_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Vigilant_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
48 | C5F5B351665AA36F4E17E4A0 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; };
49 | E0F55654D409CD66B0954450 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; };
50 | /* End PBXFileReference section */
51 |
52 | /* Begin PBXFrameworksBuildPhase section */
53 | 607FACCD1AFB9204008FA782 /* Frameworks */ = {
54 | isa = PBXFrameworksBuildPhase;
55 | buildActionMask = 2147483647;
56 | files = (
57 | EB00730BF0BDF9F4E8E58D4C /* Pods_Vigilant_Example.framework in Frameworks */,
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | 607FACE21AFB9204008FA782 /* Frameworks */ = {
62 | isa = PBXFrameworksBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | 9356B80908978E7DC8603626 /* Pods_Vigilant_Tests.framework in Frameworks */,
66 | );
67 | runOnlyForDeploymentPostprocessing = 0;
68 | };
69 | /* End PBXFrameworksBuildPhase section */
70 |
71 | /* Begin PBXGroup section */
72 | 5B42CC86EBB0270490040162 /* Frameworks */ = {
73 | isa = PBXGroup;
74 | children = (
75 | AEE4D0E2121DDB63A3FBBDAC /* Pods_Vigilant_Example.framework */,
76 | A5CC8C2AB7AC67194FFA9956 /* Pods_Vigilant_Tests.framework */,
77 | );
78 | name = Frameworks;
79 | sourceTree = "";
80 | };
81 | 607FACC71AFB9204008FA782 = {
82 | isa = PBXGroup;
83 | children = (
84 | 607FACF51AFB993E008FA782 /* Podspec Metadata */,
85 | 607FACD21AFB9204008FA782 /* Example for Vigilant */,
86 | 607FACE81AFB9204008FA782 /* Tests */,
87 | 607FACD11AFB9204008FA782 /* Products */,
88 | E2F2283A03053B4C844F4F47 /* Pods */,
89 | 5B42CC86EBB0270490040162 /* Frameworks */,
90 | );
91 | sourceTree = "";
92 | };
93 | 607FACD11AFB9204008FA782 /* Products */ = {
94 | isa = PBXGroup;
95 | children = (
96 | 607FACD01AFB9204008FA782 /* Vigilant_Example.app */,
97 | 607FACE51AFB9204008FA782 /* Vigilant_Tests.xctest */,
98 | );
99 | name = Products;
100 | sourceTree = "";
101 | };
102 | 607FACD21AFB9204008FA782 /* Example for Vigilant */ = {
103 | isa = PBXGroup;
104 | children = (
105 | 607FACD51AFB9204008FA782 /* AppDelegate.swift */,
106 | 607FACD71AFB9204008FA782 /* ViewController.swift */,
107 | 607FACD91AFB9204008FA782 /* Main.storyboard */,
108 | 607FACDC1AFB9204008FA782 /* Images.xcassets */,
109 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */,
110 | 607FACD31AFB9204008FA782 /* Supporting Files */,
111 | );
112 | name = "Example for Vigilant";
113 | path = Vigilant;
114 | sourceTree = "";
115 | };
116 | 607FACD31AFB9204008FA782 /* Supporting Files */ = {
117 | isa = PBXGroup;
118 | children = (
119 | 607FACD41AFB9204008FA782 /* Info.plist */,
120 | );
121 | name = "Supporting Files";
122 | sourceTree = "";
123 | };
124 | 607FACE81AFB9204008FA782 /* Tests */ = {
125 | isa = PBXGroup;
126 | children = (
127 | 607FACEB1AFB9204008FA782 /* Tests.swift */,
128 | 607FACE91AFB9204008FA782 /* Supporting Files */,
129 | );
130 | path = Tests;
131 | sourceTree = "";
132 | };
133 | 607FACE91AFB9204008FA782 /* Supporting Files */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 607FACEA1AFB9204008FA782 /* Info.plist */,
137 | );
138 | name = "Supporting Files";
139 | sourceTree = "";
140 | };
141 | 607FACF51AFB993E008FA782 /* Podspec Metadata */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 3ECF8E2E5FB7233CFF2B3786 /* Vigilant.podspec */,
145 | E0F55654D409CD66B0954450 /* README.md */,
146 | C5F5B351665AA36F4E17E4A0 /* LICENSE */,
147 | );
148 | name = "Podspec Metadata";
149 | sourceTree = "";
150 | };
151 | E2F2283A03053B4C844F4F47 /* Pods */ = {
152 | isa = PBXGroup;
153 | children = (
154 | 17927D7E2A832D96CAC785FB /* Pods-Vigilant_Example.debug.xcconfig */,
155 | A962B4391E078CABA8F008DB /* Pods-Vigilant_Example.release.xcconfig */,
156 | 0147682571EA3685BE0C6C96 /* Pods-Vigilant_Tests.debug.xcconfig */,
157 | 46D452031610453D96134496 /* Pods-Vigilant_Tests.release.xcconfig */,
158 | );
159 | name = Pods;
160 | sourceTree = "";
161 | };
162 | /* End PBXGroup section */
163 |
164 | /* Begin PBXNativeTarget section */
165 | 607FACCF1AFB9204008FA782 /* Vigilant_Example */ = {
166 | isa = PBXNativeTarget;
167 | buildConfigurationList = 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Vigilant_Example" */;
168 | buildPhases = (
169 | 28A8D49182EA4167EAF74DFC /* Check Pods Manifest.lock */,
170 | 607FACCC1AFB9204008FA782 /* Sources */,
171 | 607FACCD1AFB9204008FA782 /* Frameworks */,
172 | 607FACCE1AFB9204008FA782 /* Resources */,
173 | EA2601FC33D4CCC256E06E21 /* Embed Pods Frameworks */,
174 | BA5AFEF248A5E09F5E6F03FF /* Copy Pods Resources */,
175 | );
176 | buildRules = (
177 | );
178 | dependencies = (
179 | );
180 | name = Vigilant_Example;
181 | productName = Vigilant;
182 | productReference = 607FACD01AFB9204008FA782 /* Vigilant_Example.app */;
183 | productType = "com.apple.product-type.application";
184 | };
185 | 607FACE41AFB9204008FA782 /* Vigilant_Tests */ = {
186 | isa = PBXNativeTarget;
187 | buildConfigurationList = 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Vigilant_Tests" */;
188 | buildPhases = (
189 | 69876C80D0FD154418737079 /* Check Pods Manifest.lock */,
190 | 607FACE11AFB9204008FA782 /* Sources */,
191 | 607FACE21AFB9204008FA782 /* Frameworks */,
192 | 607FACE31AFB9204008FA782 /* Resources */,
193 | 0773ABBDEE470C004C444273 /* Embed Pods Frameworks */,
194 | 8B3668B581091B410289C56E /* Copy Pods Resources */,
195 | );
196 | buildRules = (
197 | );
198 | dependencies = (
199 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */,
200 | );
201 | name = Vigilant_Tests;
202 | productName = Tests;
203 | productReference = 607FACE51AFB9204008FA782 /* Vigilant_Tests.xctest */;
204 | productType = "com.apple.product-type.bundle.unit-test";
205 | };
206 | /* End PBXNativeTarget section */
207 |
208 | /* Begin PBXProject section */
209 | 607FACC81AFB9204008FA782 /* Project object */ = {
210 | isa = PBXProject;
211 | attributes = {
212 | LastSwiftUpdateCheck = 0720;
213 | LastUpgradeCheck = 0720;
214 | ORGANIZATIONNAME = CocoaPods;
215 | TargetAttributes = {
216 | 607FACCF1AFB9204008FA782 = {
217 | CreatedOnToolsVersion = 6.3.1;
218 | };
219 | 607FACE41AFB9204008FA782 = {
220 | CreatedOnToolsVersion = 6.3.1;
221 | TestTargetID = 607FACCF1AFB9204008FA782;
222 | };
223 | };
224 | };
225 | buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Vigilant" */;
226 | compatibilityVersion = "Xcode 3.2";
227 | developmentRegion = English;
228 | hasScannedForEncodings = 0;
229 | knownRegions = (
230 | en,
231 | Base,
232 | );
233 | mainGroup = 607FACC71AFB9204008FA782;
234 | productRefGroup = 607FACD11AFB9204008FA782 /* Products */;
235 | projectDirPath = "";
236 | projectRoot = "";
237 | targets = (
238 | 607FACCF1AFB9204008FA782 /* Vigilant_Example */,
239 | 607FACE41AFB9204008FA782 /* Vigilant_Tests */,
240 | );
241 | };
242 | /* End PBXProject section */
243 |
244 | /* Begin PBXResourcesBuildPhase section */
245 | 607FACCE1AFB9204008FA782 /* Resources */ = {
246 | isa = PBXResourcesBuildPhase;
247 | buildActionMask = 2147483647;
248 | files = (
249 | 607FACDB1AFB9204008FA782 /* Main.storyboard in Resources */,
250 | 607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */,
251 | 607FACDD1AFB9204008FA782 /* Images.xcassets in Resources */,
252 | );
253 | runOnlyForDeploymentPostprocessing = 0;
254 | };
255 | 607FACE31AFB9204008FA782 /* Resources */ = {
256 | isa = PBXResourcesBuildPhase;
257 | buildActionMask = 2147483647;
258 | files = (
259 | );
260 | runOnlyForDeploymentPostprocessing = 0;
261 | };
262 | /* End PBXResourcesBuildPhase section */
263 |
264 | /* Begin PBXShellScriptBuildPhase section */
265 | 0773ABBDEE470C004C444273 /* Embed Pods Frameworks */ = {
266 | isa = PBXShellScriptBuildPhase;
267 | buildActionMask = 2147483647;
268 | files = (
269 | );
270 | inputPaths = (
271 | );
272 | name = "Embed Pods Frameworks";
273 | outputPaths = (
274 | );
275 | runOnlyForDeploymentPostprocessing = 0;
276 | shellPath = /bin/sh;
277 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Vigilant_Tests/Pods-Vigilant_Tests-frameworks.sh\"\n";
278 | showEnvVarsInLog = 0;
279 | };
280 | 28A8D49182EA4167EAF74DFC /* Check Pods Manifest.lock */ = {
281 | isa = PBXShellScriptBuildPhase;
282 | buildActionMask = 2147483647;
283 | files = (
284 | );
285 | inputPaths = (
286 | );
287 | name = "Check Pods Manifest.lock";
288 | outputPaths = (
289 | );
290 | runOnlyForDeploymentPostprocessing = 0;
291 | shellPath = /bin/sh;
292 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
293 | showEnvVarsInLog = 0;
294 | };
295 | 69876C80D0FD154418737079 /* Check Pods Manifest.lock */ = {
296 | isa = PBXShellScriptBuildPhase;
297 | buildActionMask = 2147483647;
298 | files = (
299 | );
300 | inputPaths = (
301 | );
302 | name = "Check Pods Manifest.lock";
303 | outputPaths = (
304 | );
305 | runOnlyForDeploymentPostprocessing = 0;
306 | shellPath = /bin/sh;
307 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
308 | showEnvVarsInLog = 0;
309 | };
310 | 8B3668B581091B410289C56E /* Copy Pods Resources */ = {
311 | isa = PBXShellScriptBuildPhase;
312 | buildActionMask = 2147483647;
313 | files = (
314 | );
315 | inputPaths = (
316 | );
317 | name = "Copy Pods Resources";
318 | outputPaths = (
319 | );
320 | runOnlyForDeploymentPostprocessing = 0;
321 | shellPath = /bin/sh;
322 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Vigilant_Tests/Pods-Vigilant_Tests-resources.sh\"\n";
323 | showEnvVarsInLog = 0;
324 | };
325 | BA5AFEF248A5E09F5E6F03FF /* Copy Pods Resources */ = {
326 | isa = PBXShellScriptBuildPhase;
327 | buildActionMask = 2147483647;
328 | files = (
329 | );
330 | inputPaths = (
331 | );
332 | name = "Copy Pods Resources";
333 | outputPaths = (
334 | );
335 | runOnlyForDeploymentPostprocessing = 0;
336 | shellPath = /bin/sh;
337 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Vigilant_Example/Pods-Vigilant_Example-resources.sh\"\n";
338 | showEnvVarsInLog = 0;
339 | };
340 | EA2601FC33D4CCC256E06E21 /* Embed Pods Frameworks */ = {
341 | isa = PBXShellScriptBuildPhase;
342 | buildActionMask = 2147483647;
343 | files = (
344 | );
345 | inputPaths = (
346 | );
347 | name = "Embed Pods Frameworks";
348 | outputPaths = (
349 | );
350 | runOnlyForDeploymentPostprocessing = 0;
351 | shellPath = /bin/sh;
352 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Vigilant_Example/Pods-Vigilant_Example-frameworks.sh\"\n";
353 | showEnvVarsInLog = 0;
354 | };
355 | /* End PBXShellScriptBuildPhase section */
356 |
357 | /* Begin PBXSourcesBuildPhase section */
358 | 607FACCC1AFB9204008FA782 /* Sources */ = {
359 | isa = PBXSourcesBuildPhase;
360 | buildActionMask = 2147483647;
361 | files = (
362 | 607FACD81AFB9204008FA782 /* ViewController.swift in Sources */,
363 | 607FACD61AFB9204008FA782 /* AppDelegate.swift in Sources */,
364 | );
365 | runOnlyForDeploymentPostprocessing = 0;
366 | };
367 | 607FACE11AFB9204008FA782 /* Sources */ = {
368 | isa = PBXSourcesBuildPhase;
369 | buildActionMask = 2147483647;
370 | files = (
371 | 607FACEC1AFB9204008FA782 /* Tests.swift in Sources */,
372 | );
373 | runOnlyForDeploymentPostprocessing = 0;
374 | };
375 | /* End PBXSourcesBuildPhase section */
376 |
377 | /* Begin PBXTargetDependency section */
378 | 607FACE71AFB9204008FA782 /* PBXTargetDependency */ = {
379 | isa = PBXTargetDependency;
380 | target = 607FACCF1AFB9204008FA782 /* Vigilant_Example */;
381 | targetProxy = 607FACE61AFB9204008FA782 /* PBXContainerItemProxy */;
382 | };
383 | /* End PBXTargetDependency section */
384 |
385 | /* Begin PBXVariantGroup section */
386 | 607FACD91AFB9204008FA782 /* Main.storyboard */ = {
387 | isa = PBXVariantGroup;
388 | children = (
389 | 607FACDA1AFB9204008FA782 /* Base */,
390 | );
391 | name = Main.storyboard;
392 | sourceTree = "";
393 | };
394 | 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */ = {
395 | isa = PBXVariantGroup;
396 | children = (
397 | 607FACDF1AFB9204008FA782 /* Base */,
398 | );
399 | name = LaunchScreen.xib;
400 | sourceTree = "";
401 | };
402 | /* End PBXVariantGroup section */
403 |
404 | /* Begin XCBuildConfiguration section */
405 | 607FACED1AFB9204008FA782 /* Debug */ = {
406 | isa = XCBuildConfiguration;
407 | buildSettings = {
408 | ALWAYS_SEARCH_USER_PATHS = NO;
409 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
410 | CLANG_CXX_LIBRARY = "libc++";
411 | CLANG_ENABLE_MODULES = YES;
412 | CLANG_ENABLE_OBJC_ARC = YES;
413 | CLANG_WARN_BOOL_CONVERSION = YES;
414 | CLANG_WARN_CONSTANT_CONVERSION = YES;
415 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
416 | CLANG_WARN_EMPTY_BODY = YES;
417 | CLANG_WARN_ENUM_CONVERSION = YES;
418 | CLANG_WARN_INT_CONVERSION = YES;
419 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
420 | CLANG_WARN_UNREACHABLE_CODE = YES;
421 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
422 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
423 | COPY_PHASE_STRIP = NO;
424 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
425 | ENABLE_STRICT_OBJC_MSGSEND = YES;
426 | ENABLE_TESTABILITY = YES;
427 | GCC_C_LANGUAGE_STANDARD = gnu99;
428 | GCC_DYNAMIC_NO_PIC = NO;
429 | GCC_NO_COMMON_BLOCKS = YES;
430 | GCC_OPTIMIZATION_LEVEL = 0;
431 | GCC_PREPROCESSOR_DEFINITIONS = (
432 | "DEBUG=1",
433 | "$(inherited)",
434 | );
435 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
436 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
437 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
438 | GCC_WARN_UNDECLARED_SELECTOR = YES;
439 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
440 | GCC_WARN_UNUSED_FUNCTION = YES;
441 | GCC_WARN_UNUSED_VARIABLE = YES;
442 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
443 | MTL_ENABLE_DEBUG_INFO = YES;
444 | ONLY_ACTIVE_ARCH = YES;
445 | SDKROOT = iphoneos;
446 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
447 | };
448 | name = Debug;
449 | };
450 | 607FACEE1AFB9204008FA782 /* Release */ = {
451 | isa = XCBuildConfiguration;
452 | buildSettings = {
453 | ALWAYS_SEARCH_USER_PATHS = NO;
454 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
455 | CLANG_CXX_LIBRARY = "libc++";
456 | CLANG_ENABLE_MODULES = YES;
457 | CLANG_ENABLE_OBJC_ARC = YES;
458 | CLANG_WARN_BOOL_CONVERSION = YES;
459 | CLANG_WARN_CONSTANT_CONVERSION = YES;
460 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
461 | CLANG_WARN_EMPTY_BODY = YES;
462 | CLANG_WARN_ENUM_CONVERSION = YES;
463 | CLANG_WARN_INT_CONVERSION = YES;
464 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
465 | CLANG_WARN_UNREACHABLE_CODE = YES;
466 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
467 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
468 | COPY_PHASE_STRIP = NO;
469 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
470 | ENABLE_NS_ASSERTIONS = NO;
471 | ENABLE_STRICT_OBJC_MSGSEND = YES;
472 | GCC_C_LANGUAGE_STANDARD = gnu99;
473 | GCC_NO_COMMON_BLOCKS = YES;
474 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
475 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
476 | GCC_WARN_UNDECLARED_SELECTOR = YES;
477 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
478 | GCC_WARN_UNUSED_FUNCTION = YES;
479 | GCC_WARN_UNUSED_VARIABLE = YES;
480 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
481 | MTL_ENABLE_DEBUG_INFO = NO;
482 | SDKROOT = iphoneos;
483 | VALIDATE_PRODUCT = YES;
484 | };
485 | name = Release;
486 | };
487 | 607FACF01AFB9204008FA782 /* Debug */ = {
488 | isa = XCBuildConfiguration;
489 | baseConfigurationReference = 17927D7E2A832D96CAC785FB /* Pods-Vigilant_Example.debug.xcconfig */;
490 | buildSettings = {
491 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
492 | INFOPLIST_FILE = Vigilant/Info.plist;
493 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
494 | MODULE_NAME = ExampleApp;
495 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
496 | PRODUCT_NAME = "$(TARGET_NAME)";
497 | };
498 | name = Debug;
499 | };
500 | 607FACF11AFB9204008FA782 /* Release */ = {
501 | isa = XCBuildConfiguration;
502 | baseConfigurationReference = A962B4391E078CABA8F008DB /* Pods-Vigilant_Example.release.xcconfig */;
503 | buildSettings = {
504 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
505 | INFOPLIST_FILE = Vigilant/Info.plist;
506 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
507 | MODULE_NAME = ExampleApp;
508 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)";
509 | PRODUCT_NAME = "$(TARGET_NAME)";
510 | };
511 | name = Release;
512 | };
513 | 607FACF31AFB9204008FA782 /* Debug */ = {
514 | isa = XCBuildConfiguration;
515 | baseConfigurationReference = 0147682571EA3685BE0C6C96 /* Pods-Vigilant_Tests.debug.xcconfig */;
516 | buildSettings = {
517 | FRAMEWORK_SEARCH_PATHS = (
518 | "$(SDKROOT)/Developer/Library/Frameworks",
519 | "$(inherited)",
520 | );
521 | GCC_PREPROCESSOR_DEFINITIONS = (
522 | "DEBUG=1",
523 | "$(inherited)",
524 | );
525 | INFOPLIST_FILE = Tests/Info.plist;
526 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
527 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
528 | PRODUCT_NAME = "$(TARGET_NAME)";
529 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Vigilant_Example.app/Vigilant_Example";
530 | };
531 | name = Debug;
532 | };
533 | 607FACF41AFB9204008FA782 /* Release */ = {
534 | isa = XCBuildConfiguration;
535 | baseConfigurationReference = 46D452031610453D96134496 /* Pods-Vigilant_Tests.release.xcconfig */;
536 | buildSettings = {
537 | FRAMEWORK_SEARCH_PATHS = (
538 | "$(SDKROOT)/Developer/Library/Frameworks",
539 | "$(inherited)",
540 | );
541 | INFOPLIST_FILE = Tests/Info.plist;
542 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
543 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.$(PRODUCT_NAME:rfc1034identifier)";
544 | PRODUCT_NAME = "$(TARGET_NAME)";
545 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Vigilant_Example.app/Vigilant_Example";
546 | };
547 | name = Release;
548 | };
549 | /* End XCBuildConfiguration section */
550 |
551 | /* Begin XCConfigurationList section */
552 | 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "Vigilant" */ = {
553 | isa = XCConfigurationList;
554 | buildConfigurations = (
555 | 607FACED1AFB9204008FA782 /* Debug */,
556 | 607FACEE1AFB9204008FA782 /* Release */,
557 | );
558 | defaultConfigurationIsVisible = 0;
559 | defaultConfigurationName = Release;
560 | };
561 | 607FACEF1AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Vigilant_Example" */ = {
562 | isa = XCConfigurationList;
563 | buildConfigurations = (
564 | 607FACF01AFB9204008FA782 /* Debug */,
565 | 607FACF11AFB9204008FA782 /* Release */,
566 | );
567 | defaultConfigurationIsVisible = 0;
568 | defaultConfigurationName = Release;
569 | };
570 | 607FACF21AFB9204008FA782 /* Build configuration list for PBXNativeTarget "Vigilant_Tests" */ = {
571 | isa = XCConfigurationList;
572 | buildConfigurations = (
573 | 607FACF31AFB9204008FA782 /* Debug */,
574 | 607FACF41AFB9204008FA782 /* Release */,
575 | );
576 | defaultConfigurationIsVisible = 0;
577 | defaultConfigurationName = Release;
578 | };
579 | /* End XCConfigurationList section */
580 | };
581 | rootObject = 607FACC81AFB9204008FA782 /* Project object */;
582 | }
583 |
--------------------------------------------------------------------------------
/Example/Vigilant.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/Vigilant.xcodeproj/xcshareddata/xcschemes/Vigilant-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
47 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
65 |
66 |
67 |
68 |
78 |
80 |
86 |
87 |
88 |
89 |
90 |
91 |
97 |
99 |
105 |
106 |
107 |
108 |
110 |
111 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/Example/Vigilant.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/Vigilant/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 |
3 | @UIApplicationMain
4 | class AppDelegate: UIResponder, UIApplicationDelegate {
5 |
6 | var window: UIWindow?
7 |
8 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
9 | return true
10 | }
11 |
12 | }
13 |
14 |
--------------------------------------------------------------------------------
/Example/Vigilant/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
20 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Example/Vigilant/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Example/Vigilant/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | }
33 | ],
34 | "info" : {
35 | "version" : 1,
36 | "author" : "xcode"
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Example/Vigilant/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Example/Vigilant/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Vigilant
4 | //
5 | // Created by Orta Therox on 04/10/2016.
6 | // Copyright (c) 2016 Orta Therox. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view, typically from a nib.
16 | }
17 |
18 | override func didReceiveMemoryWarning() {
19 | super.didReceiveMemoryWarning()
20 | // Dispose of any resources that can be recreated.
21 | }
22 |
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Orta Therox
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # be Vigilant
2 |
3 | ## Concept
4 |
5 | It's great that you can run both [Quick](https://github.com/quick/quick) and [Nimble](https://github.com/quick/nimble) separately, however that does come with a downside. One of Rspec's great features that helps me catch bugs in my tests is that it will raise an error if a test does not run any expectations.
6 |
7 | This Pod bridges Quick and Nimble, and creates a contract between the two. which enforces that you will use Nimble matchers inside every Quick test.
8 |
9 | The code is short, well commented, but a little bit esoteric. You'd probably enjoy [reading it](https://github.com/orta/vigilant/blob/master/Vigilant/Classes/Vigilant.m).
10 |
11 | ## Examples
12 |
13 | Here's a test suite with two tests:
14 |
15 | ``` swift
16 | import Quick
17 | import Nimble
18 |
19 | class VigilantSpec: QuickSpec {
20 | override func spec() {
21 |
22 | it("This test will pass") {
23 |
24 | }
25 |
26 | it("This should pass too") {
27 | expect("Tests") == "Tests"
28 | }
29 | }
30 | }
31 | ```
32 |
33 | Simply by including the Pod "Vigilant" in your Podfile, you will see a message like this in your console:
34 |
35 | ```
36 | Test Case '-[Vigilant_Tests.VigilantSpec This_test_will_pass]' started.
37 | 2016-04-10 16:07:29.026 Vigilant_Example[20344:1112445]
38 |
39 | Vigilant: Did not see any `expect`s in the test: 'This test will pass'
40 |
41 | Test Case '-[Vigilant_Tests.VigilantSpec This_test_will_pass]' passed (0.013 seconds).
42 | ```
43 |
44 | Making it easy to see what tests are running without any `expect`s being called.
45 |
46 | ## Hard mode
47 |
48 | Maybe you want to go all out and enforce that every test have expectations, well, this Pod
49 | also provides a way to do that. In your Testing AppDelegate, call the `Vigilant` class's function
50 | `startExpecting` to cause assertions instead of logs.
51 |
52 | ## Usage
53 |
54 | To run the example project, run `pod try Vigilant`.
55 |
56 | ## Installation
57 |
58 | Vigilant is available through [CocoaPods](http://cocoapods.org). To install
59 | it, simply add the following line to your Podfile in a test target:
60 |
61 | ```ruby
62 | pod "Vigilant"
63 | ```
64 |
65 | Once SwiftPM becomes useful I'll look into supporting that too.
66 |
67 | ## Author
68 |
69 | Orta Therox, orta.therox@gmail.com
70 |
71 | ## License
72 |
73 | Vigilant is available under the MIT license. See the LICENSE file for more info.
74 |
--------------------------------------------------------------------------------
/Vigilant.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "Vigilant"
3 | s.version = "1.0.0"
4 | s.summary = "Glues Quick & Nimble together. Makes sure you run an expectation on every test."
5 | s.description = <<-DESC
6 | Be Quick, be Nimble, be Vigilant. Vigilant keeps track of whether any test
7 | runs it's expectations. This makes it easier to notice when you have async code
8 | which "passes" because the expectations are not ran during the test.
9 | DESC
10 |
11 | s.ios.deployment_target = "7.0"
12 | s.osx.deployment_target = "10.9"
13 | s.tvos.deployment_target = '9.0'
14 |
15 | s.homepage = "https://github.com/orta/vigilant"
16 | s.license = 'MIT'
17 | s.author = { "Orta Therox" => "orta.therox@gmail.com" }
18 | s.source = { :git => "https://github.com/orta/vigilant.git", :tag => s.version.to_s }
19 | s.social_media_url = 'https://twitter.com/orta'
20 | s.source_files = 'Vigilant/Classes/**/*'
21 | s.frameworks = 'Foundation', 'XCTest'
22 | s.dependency 'Quick'
23 | s.dependency 'Nimble'
24 | end
25 |
--------------------------------------------------------------------------------
/Vigilant/Classes/Vigilant.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | /// By default, vigilant will log out errors, if you want to really be vigilant
4 | /// then you should call `startExpecting` which will assert instead.
5 |
6 | @interface Vigilant : NSObject
7 |
8 | /// Don't log, assert. Hard mode.
9 |
10 | + (void)startExpecting;
11 |
12 | @end
13 |
--------------------------------------------------------------------------------
/Vigilant/Classes/Vigilant.m:
--------------------------------------------------------------------------------
1 | @import Foundation;
2 | @import Quick;
3 | @import Nimble;
4 | @import ObjectiveC;
5 |
6 | #import "Vigilant.h"
7 |
8 | static BOOL ORVigilantShouldAssert = false;
9 | static BOOL ORVigilantConfigurationHasRunExpectations;
10 |
11 | @implementation Vigilant
12 |
13 | + (void)startExpecting
14 | {
15 | ORVigilantShouldAssert = true;
16 | }
17 |
18 | @end
19 |
20 | /// Creates an class which Quick will pick up to support
21 | /// adding beforeEach / afterEach blocks.
22 |
23 | @interface ORVigilantConfiguration: QuickConfiguration
24 | @end
25 |
26 | @implementation ORVigilantConfiguration
27 |
28 | + (void)configure:(Configuration *)configuration
29 | {
30 | /// For info on what's going on: see
31 | /// https://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html
32 | NSMutableDictionary *threadDict = [NSThread currentThread].threadDictionary;
33 |
34 | /// We want to dynamically create a subclass of the dictionary for the current thread
35 | Class orMutableDict = objc_allocateClassPair([threadDict class], "ORVigilantMutableDictionary", 0);
36 |
37 | /// We do this, because every time a nimble matcher is ran
38 | /// it makes changes to the "NimbleEnvironment" key
39 | Method indexOfObject = class_getInstanceMethod(NSMutableDictionary.class, @selector(setObject:forKeyedSubscript:));
40 |
41 | /// By doing this we can hook in to find out if any `expect`s have been ran.
42 | const char *types = method_getTypeEncoding(indexOfObject);
43 | class_addMethod(orMutableDict, @selector(setObject:forKeyedSubscript:), (IMP)ORVigilantCustomSetObject, types);
44 |
45 | /// So we register our new subclass in the objc runtime
46 | objc_registerClassPair(orMutableDict);
47 |
48 | /// And dynamically set the thread dict's class to the new one
49 | object_setClass(threadDict, orMutableDict);
50 |
51 | // Before any tests are ran, make sure that we've set the check to false,
52 | //
53 | [configuration beforeEach:^{
54 | ORVigilantConfigurationHasRunExpectations = NO;
55 | }];
56 |
57 | // We now look after a test to see if there were any changes to the
58 | // Nimble Environment during the test run.
59 | [configuration afterEachWithMetadata:^(ExampleMetadata * _Nonnull metadata) {
60 | if (ORVigilantConfigurationHasRunExpectations == false) {
61 | NSString *expectationName = [metadata.example name];
62 | NSString *errorString = [NSString stringWithFormat:@"Vigilant: Did not see any `expect`s in the test: '%@'", expectationName];
63 | if (ORVigilantShouldAssert) {
64 | @throw errorString;
65 | } else {
66 | NSLog(@"\n\n%@\n\n", errorString);
67 | }
68 | }
69 | }];
70 | }
71 |
72 | static void ORVigilantCustomSetObject(NSMutableDictionary *self, SEL _cmd, id anObject, idkey)
73 | {
74 | // We're overwriting setObject:forKeyedSubscript:
75 | // Which, hopefully, just calls setObject:forKey under the hood :)
76 | [self setObject:anObject forKey:key];
77 |
78 | // Check for whether the key was a change to the Nimble Environment
79 | if ([@"NimbleEnvironment" isEqual:key]) {
80 | ORVigilantConfigurationHasRunExpectations = YES;
81 | }
82 | }
83 |
84 |
85 | @end
86 |
--------------------------------------------------------------------------------