├── .gitignore
├── README.md
├── Supporting Files
└── Info.plist
├── XCTestPlayground.swift
├── XCTestPlayground.xcodeproj
├── project.pbxproj
└── xcshareddata
│ └── xcschemes
│ └── XCTestPlayground.xcscheme
├── XCTestPlayground.xcworkspace
└── contents.xcworkspacedata
├── XCTestPlaygroundExample.playground
├── Contents.swift
└── contents.xcplayground
└── screenshot.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xcuserstate
23 |
24 | ## Obj-C/Swift specific
25 | *.hmap
26 | *.ipa
27 | *.dSYM.zip
28 | *.dSYM
29 |
30 | ## Playgrounds
31 | timeline.xctimeline
32 | playground.xcworkspace
33 |
34 | # Swift Package Manager
35 | #
36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
37 | # Packages/
38 | .build/
39 |
40 | # CocoaPods
41 | #
42 | # We recommend against adding the Pods directory to your .gitignore. However
43 | # you should judge for yourself, the pros and cons are mentioned at:
44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
45 | #
46 | # Pods/
47 |
48 | # Carthage
49 | #
50 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
51 | # Carthage/Checkouts
52 |
53 | Carthage/Build
54 |
55 | # fastlane
56 | #
57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
58 | # screenshots whenever they are needed.
59 | # For more information about the recommended setup visit:
60 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
61 |
62 | fastlane/report.xml
63 | fastlane/Preview.html
64 | fastlane/screenshots
65 | fastlane/test_output
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # XCTestPlayground
2 |
3 | This repository contains a simple implementation of most `XCTAssert` macros to use in a Playground.
4 |
5 | With the Playground feature that display the result of an executed line, it will show the assert result like this:
6 | 
7 |
8 | I use this to do TDD directly inside a Playground and then move the code as-is inside my test files.
9 |
10 | It contains a `XCTestCase` base class that, when instantiated, will run all methods with names beginning with "test", to mimic XCTestCase behaviour and make moving the code to your Xcode project easier.
11 |
12 | ## How to install it in an existing playground
13 |
14 | Simply add the `XCTestPlayground.swift` file to your Playground `Sources` folder.
15 |
16 | ## Using it directly
17 |
18 | The repo contains a fully configured Xcode workspace containing a playground importing `XCTestPlayground`.
19 | All you have to do is:
20 |
21 | 1. clone the repo
22 | 2. build the framework on a 64-bit target (e.g. iPhone 5s simulator)
23 | 3. go and play in the `XCTestPlaygroundExample` playground! 🎉
24 |
25 | ## Swift version
26 |
27 | Xcode 9 has been released and since the playgrounds in this version uses swift 4 tools intended to be used inside them should use this version.
28 | Nevertheless, if you want to use `XCTestPlayground` with previous versions of Xcode, you can still checkout the last commit using the Swift 2.2 version: af05981c214a3a5ac1fa7b298787d517100db868
29 |
--------------------------------------------------------------------------------
/Supporting Files/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 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/XCTestPlayground.swift:
--------------------------------------------------------------------------------
1 | // Playground Tests
2 |
3 | import Foundation
4 |
5 | public let defaultMessage = ""
6 |
7 | /// Emits a test failure if the general `Boolean` expression passed
8 | /// to it evaluates to `false`.
9 | ///
10 | /// - Requires: This and all other XCTAssert* functions must be called from
11 | /// within a test method, as passed to `XCTMain`.
12 | /// Assertion failures that occur outside of a test method will *not* be
13 | /// reported as failures.
14 | ///
15 | /// - Parameter expression: A boolean test. If it evaluates to `false`, the
16 | /// assertion fails and emits a test failure.
17 | /// - Parameter message: An optional message to use in the failure if the
18 | /// assertion fails. If no message is supplied a default message is used.
19 | ///
20 | /// For example
21 | ///
22 | /// ```swift
23 | /// class TestCase: XCTestCase {
24 | /// func testAssertions() {
25 | /// XCTAssertEqual(1, 2)
26 | /// XCTAssertEqual([1, 2], [2, 3])
27 | /// XCTAssertGreaterThanOrEqual(1, 2)
28 | /// XCTAssertTrue(true)
29 | /// }
30 | /// }
31 | /// ```
32 | ///
33 | public func XCTAssert(
34 | _ expression: @autoclosure () -> Bool,
35 | _ message: String = defaultMessage
36 | ) -> String {
37 | return returnTestResult(expression(), message: message)
38 | }
39 |
40 | public func XCTAssertEqual(
41 | _ expression1: @autoclosure () -> T?,
42 | _ expression2: @autoclosure () -> T?,
43 | _ message: String = defaultMessage
44 | ) -> String {
45 | return returnTestResult(
46 | expression1() == expression2(),
47 | message: "\(message) - expected: \(expression2() as Optional), actual: \(expression1() as Optional)")
48 | }
49 |
50 | public func XCTAssertEqual(
51 | _ expression1: @autoclosure () -> ArraySlice,
52 | _ expression2: @autoclosure () -> ArraySlice,
53 | _ message: String = defaultMessage
54 | ) -> String {
55 | return returnTestResult(
56 | expression1() == expression2(),
57 | message: "\(message) - expected: \(expression2()), actual: \(expression1())")
58 | }
59 |
60 | public func XCTAssertEqual(
61 | _ expression1: @autoclosure () -> ContiguousArray,
62 | _ expression2: @autoclosure () -> ContiguousArray,
63 | _ message: String = defaultMessage
64 | ) -> String {
65 | return returnTestResult(
66 | expression1() == expression2(),
67 | message: "\(message) - expected: \(expression2()), actual: \(expression1())")
68 | }
69 |
70 | public func XCTAssertEqual(
71 | _ expression1: @autoclosure () -> [T],
72 | _ expression2: @autoclosure () -> [T],
73 | _ message: String = defaultMessage
74 | ) -> String {
75 | return returnTestResult(
76 | expression1() == expression2(),
77 | message: "\(message) - expected: \(expression2()), actual: \(expression1())")
78 | }
79 |
80 | public func XCTAssertEqual(
81 | _ expression1: @autoclosure () -> [T : U],
82 | _ expression2: @autoclosure () -> [T : U],
83 | _ message: String = defaultMessage
84 | ) -> String {
85 | return returnTestResult(
86 | expression1() == expression2(),
87 | message: "\(message) - expected: \(expression2()), actual: \(expression1())")
88 | }
89 |
90 | public func XCTAssertFalse(
91 | _ expression: @autoclosure () -> Bool,
92 | _ message: String = defaultMessage
93 | ) -> String {
94 | return returnTestResult(!expression(), message: message)
95 | }
96 |
97 | public func XCTAssertGreaterThan(
98 | _ expression1: @autoclosure () -> T,
99 | _ expression2: @autoclosure () -> T,
100 | _ message: String = defaultMessage
101 | ) -> String {
102 | return returnTestResult(
103 | expression1() > expression2(),
104 | message: "\(message) - actual: \(expression1()) > \(expression2())")
105 | }
106 |
107 | public func XCTAssertGreaterThanOrEqual(
108 | _ expression1: @autoclosure () -> T,
109 | _ expression2: @autoclosure () -> T,
110 | _ message: String = defaultMessage
111 | ) -> String {
112 | return returnTestResult(
113 | expression1() >= expression2(),
114 | message: "\(message) - actual: \(expression1()) >= \(expression2())")
115 | }
116 |
117 | public func XCTAssertLessThan(
118 | _ expression1: @autoclosure () -> T,
119 | _ expression2: @autoclosure () -> T,
120 | _ message: String = defaultMessage
121 | ) -> String {
122 | return returnTestResult(
123 | expression1() < expression2(),
124 | message: "\(message) - actual: \(expression1()) < \(expression2())")
125 | }
126 |
127 | public func XCTAssertLessThanOrEqual(
128 | _ expression1: @autoclosure () -> T,
129 | _ expression2: @autoclosure () -> T,
130 | _ message: String = defaultMessage
131 | ) -> String {
132 | return returnTestResult(
133 | expression1() <= expression2(),
134 | message: "\(message) - actual: \(expression1()) <= \(expression2())")
135 | }
136 |
137 | public func XCTAssertNil(
138 | _ expression: @autoclosure () -> Any?,
139 | _ message: String = ""
140 | ) -> String {
141 | var result = true
142 | if let _ = expression() { result = false }
143 | return returnTestResult(
144 | result,
145 | message: "\(message) - expected: nil, actual: \(expression() as Optional)")
146 | }
147 |
148 | public func XCTAssertNotEqual(
149 | _ expression1: @autoclosure () -> T?,
150 | _ expression2: @autoclosure () -> T?,
151 | _ message: String = defaultMessage
152 | ) -> String {
153 | return returnTestResult(
154 | expression1() != expression2(),
155 | message: "\(message) - expected: \(expression1() as Optional) =! \(expression2() as Optional)")
156 | }
157 |
158 | public func XCTAssertNotEqual(
159 | _ expression1: @autoclosure () -> ContiguousArray,
160 | _ expression2: @autoclosure () -> ContiguousArray,
161 | _ message: String = defaultMessage
162 | ) -> String {
163 | return returnTestResult(
164 | expression1() != expression2(),
165 | message: "\(message) - expected: \(expression1()) != \(expression2())")
166 | }
167 |
168 | public func XCTAssertNotEqual(
169 | _ expression1: @autoclosure () -> ArraySlice,
170 | _ expression2: @autoclosure () -> ArraySlice,
171 | _ message: String = defaultMessage
172 | ) -> String {
173 | return returnTestResult(
174 | expression1() != expression2(),
175 | message: "\(message) - expected: \(expression1()) != \(expression2())")
176 | }
177 |
178 | public func XCTAssertNotEqual(
179 | _ expression1: @autoclosure () -> [T],
180 | _ expression2: @autoclosure () -> [T],
181 | _ message: String = defaultMessage
182 | ) -> String {
183 | return returnTestResult(
184 | expression1() != expression2(),
185 | message: "\(message) - expected: \(expression1()) != \(expression2())")
186 | }
187 |
188 | public func XCTAssertNotEqual(
189 | _ expression1: @autoclosure () -> [T : U],
190 | _ expression2: @autoclosure () -> [T : U],
191 | _ message: String = defaultMessage
192 | ) -> String {
193 | return returnTestResult(
194 | expression1() != expression2(),
195 | message: "\(message) - expected: \(expression1()) != \(expression2())")
196 | }
197 |
198 | public func XCTAssertNotNil(
199 | _ expression: @autoclosure () -> Any?,
200 | _ message: String = ""
201 | ) -> String {
202 | var result = false
203 | if let _ = expression() { result = true }
204 | return returnTestResult(result, message: message)
205 | }
206 |
207 | public func XCTAssertTrue(
208 | _ expression: @autoclosure () -> Bool,
209 | _ message: String = defaultMessage
210 | ) -> String {
211 | return returnTestResult(expression(), message: message)
212 | }
213 |
214 | public func XCTFail(_ message: String = "") -> String {
215 | return failMessage(message)
216 | }
217 |
218 | func returnTestResult(_ result: Bool, message: String) -> String {
219 | return result ? okMessage() : failMessage(message)
220 | }
221 |
222 | func okMessage() -> String { return "✅" }
223 |
224 | func failMessage(_ message: String) -> String { return "❌" + message }
225 |
226 | // This class was based on GitHub gist:
227 | // https://gist.github.com/croath/a9358dac0530d91e9e2b
228 |
229 | open class XCTestCase: NSObject {
230 |
231 | public override init(){
232 | super.init()
233 | self.runTestMethods()
234 | }
235 |
236 | open class func setUp() {}
237 | open func setUp() {}
238 |
239 | open class func tearDown() {}
240 | open func tearDown() {}
241 |
242 | override open var description: String { return "" }
243 |
244 | private func runTestMethods() {
245 | type(of:self).setUp()
246 | defer {
247 | type(of:self).tearDown()
248 | }
249 | var mc: CUnsignedInt = 0
250 |
251 | guard var mlist = class_copyMethodList(type(of:self).classForCoder(), &mc) else {
252 | return
253 | }
254 | (0 ..< mc).forEach { _ in
255 | let m = method_getName(mlist.pointee)
256 | if String(describing: m).hasPrefix("test") {
257 | self.setUp()
258 | self.performSelector(
259 | onMainThread: m,
260 | with: nil,
261 | waitUntilDone: true)
262 | self.tearDown()
263 | }
264 | mlist = mlist.successor()
265 | }
266 | }
267 | }
268 |
--------------------------------------------------------------------------------
/XCTestPlayground.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | FE3CAD201CEE59DE0058C6B4 /* XCTestPlayground.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE3CAD1F1CEE59DE0058C6B4 /* XCTestPlayground.swift */; };
11 | /* End PBXBuildFile section */
12 |
13 | /* Begin PBXFileReference section */
14 | FE3CAD141CEE59530058C6B4 /* XCTestPlayground.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = XCTestPlayground.framework; sourceTree = BUILT_PRODUCTS_DIR; };
15 | FE3CAD191CEE59530058C6B4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = "../Supporting Files/Info.plist"; sourceTree = ""; };
16 | FE3CAD1F1CEE59DE0058C6B4 /* XCTestPlayground.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XCTestPlayground.swift; sourceTree = ""; };
17 | /* End PBXFileReference section */
18 |
19 | /* Begin PBXFrameworksBuildPhase section */
20 | FE3CAD101CEE59530058C6B4 /* Frameworks */ = {
21 | isa = PBXFrameworksBuildPhase;
22 | buildActionMask = 2147483647;
23 | files = (
24 | );
25 | runOnlyForDeploymentPostprocessing = 0;
26 | };
27 | /* End PBXFrameworksBuildPhase section */
28 |
29 | /* Begin PBXGroup section */
30 | FE3CAD0A1CEE59530058C6B4 = {
31 | isa = PBXGroup;
32 | children = (
33 | FE3CAD1F1CEE59DE0058C6B4 /* XCTestPlayground.swift */,
34 | FE3CAD161CEE59530058C6B4 /* Supporting FIles */,
35 | FE3CAD151CEE59530058C6B4 /* Products */,
36 | );
37 | sourceTree = "";
38 | };
39 | FE3CAD151CEE59530058C6B4 /* Products */ = {
40 | isa = PBXGroup;
41 | children = (
42 | FE3CAD141CEE59530058C6B4 /* XCTestPlayground.framework */,
43 | );
44 | name = Products;
45 | sourceTree = "";
46 | };
47 | FE3CAD161CEE59530058C6B4 /* Supporting FIles */ = {
48 | isa = PBXGroup;
49 | children = (
50 | FE3CAD191CEE59530058C6B4 /* Info.plist */,
51 | );
52 | name = "Supporting FIles";
53 | path = "Supporting Files";
54 | sourceTree = "";
55 | };
56 | /* End PBXGroup section */
57 |
58 | /* Begin PBXHeadersBuildPhase section */
59 | FE3CAD111CEE59530058C6B4 /* Headers */ = {
60 | isa = PBXHeadersBuildPhase;
61 | buildActionMask = 2147483647;
62 | files = (
63 | );
64 | runOnlyForDeploymentPostprocessing = 0;
65 | };
66 | /* End PBXHeadersBuildPhase section */
67 |
68 | /* Begin PBXNativeTarget section */
69 | FE3CAD131CEE59530058C6B4 /* XCTestPlayground */ = {
70 | isa = PBXNativeTarget;
71 | buildConfigurationList = FE3CAD1C1CEE59530058C6B4 /* Build configuration list for PBXNativeTarget "XCTestPlayground" */;
72 | buildPhases = (
73 | FE3CAD0F1CEE59530058C6B4 /* Sources */,
74 | FE3CAD101CEE59530058C6B4 /* Frameworks */,
75 | FE3CAD111CEE59530058C6B4 /* Headers */,
76 | FE3CAD121CEE59530058C6B4 /* Resources */,
77 | );
78 | buildRules = (
79 | );
80 | dependencies = (
81 | );
82 | name = XCTestPlayground;
83 | productName = XCTestPlayground;
84 | productReference = FE3CAD141CEE59530058C6B4 /* XCTestPlayground.framework */;
85 | productType = "com.apple.product-type.framework";
86 | };
87 | /* End PBXNativeTarget section */
88 |
89 | /* Begin PBXProject section */
90 | FE3CAD0B1CEE59530058C6B4 /* Project object */ = {
91 | isa = PBXProject;
92 | attributes = {
93 | LastUpgradeCheck = 0910;
94 | ORGANIZATIONNAME = Liquidsoul;
95 | TargetAttributes = {
96 | FE3CAD131CEE59530058C6B4 = {
97 | CreatedOnToolsVersion = 7.3.1;
98 | LastSwiftMigration = 0900;
99 | };
100 | };
101 | };
102 | buildConfigurationList = FE3CAD0E1CEE59530058C6B4 /* Build configuration list for PBXProject "XCTestPlayground" */;
103 | compatibilityVersion = "Xcode 3.2";
104 | developmentRegion = English;
105 | hasScannedForEncodings = 0;
106 | knownRegions = (
107 | en,
108 | );
109 | mainGroup = FE3CAD0A1CEE59530058C6B4;
110 | productRefGroup = FE3CAD151CEE59530058C6B4 /* Products */;
111 | projectDirPath = "";
112 | projectRoot = "";
113 | targets = (
114 | FE3CAD131CEE59530058C6B4 /* XCTestPlayground */,
115 | );
116 | };
117 | /* End PBXProject section */
118 |
119 | /* Begin PBXResourcesBuildPhase section */
120 | FE3CAD121CEE59530058C6B4 /* Resources */ = {
121 | isa = PBXResourcesBuildPhase;
122 | buildActionMask = 2147483647;
123 | files = (
124 | );
125 | runOnlyForDeploymentPostprocessing = 0;
126 | };
127 | /* End PBXResourcesBuildPhase section */
128 |
129 | /* Begin PBXSourcesBuildPhase section */
130 | FE3CAD0F1CEE59530058C6B4 /* Sources */ = {
131 | isa = PBXSourcesBuildPhase;
132 | buildActionMask = 2147483647;
133 | files = (
134 | FE3CAD201CEE59DE0058C6B4 /* XCTestPlayground.swift in Sources */,
135 | );
136 | runOnlyForDeploymentPostprocessing = 0;
137 | };
138 | /* End PBXSourcesBuildPhase section */
139 |
140 | /* Begin XCBuildConfiguration section */
141 | FE3CAD1A1CEE59530058C6B4 /* Debug */ = {
142 | isa = XCBuildConfiguration;
143 | buildSettings = {
144 | ALWAYS_SEARCH_USER_PATHS = NO;
145 | CLANG_ANALYZER_NONNULL = YES;
146 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
147 | CLANG_CXX_LIBRARY = "libc++";
148 | CLANG_ENABLE_MODULES = YES;
149 | CLANG_ENABLE_OBJC_ARC = YES;
150 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
151 | CLANG_WARN_BOOL_CONVERSION = YES;
152 | CLANG_WARN_COMMA = YES;
153 | CLANG_WARN_CONSTANT_CONVERSION = YES;
154 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
155 | CLANG_WARN_EMPTY_BODY = YES;
156 | CLANG_WARN_ENUM_CONVERSION = YES;
157 | CLANG_WARN_INFINITE_RECURSION = YES;
158 | CLANG_WARN_INT_CONVERSION = YES;
159 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
160 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
161 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
162 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
163 | CLANG_WARN_STRICT_PROTOTYPES = YES;
164 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
165 | CLANG_WARN_UNREACHABLE_CODE = YES;
166 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
167 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
168 | COPY_PHASE_STRIP = NO;
169 | CURRENT_PROJECT_VERSION = 1;
170 | DEBUG_INFORMATION_FORMAT = dwarf;
171 | ENABLE_STRICT_OBJC_MSGSEND = YES;
172 | ENABLE_TESTABILITY = YES;
173 | GCC_C_LANGUAGE_STANDARD = gnu99;
174 | GCC_DYNAMIC_NO_PIC = NO;
175 | GCC_NO_COMMON_BLOCKS = YES;
176 | GCC_OPTIMIZATION_LEVEL = 0;
177 | GCC_PREPROCESSOR_DEFINITIONS = (
178 | "DEBUG=1",
179 | "$(inherited)",
180 | );
181 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
182 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
183 | GCC_WARN_UNDECLARED_SELECTOR = YES;
184 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
185 | GCC_WARN_UNUSED_FUNCTION = YES;
186 | GCC_WARN_UNUSED_VARIABLE = YES;
187 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
188 | MTL_ENABLE_DEBUG_INFO = YES;
189 | ONLY_ACTIVE_ARCH = YES;
190 | SDKROOT = iphoneos;
191 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
192 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
193 | TARGETED_DEVICE_FAMILY = "1,2";
194 | VERSIONING_SYSTEM = "apple-generic";
195 | VERSION_INFO_PREFIX = "";
196 | };
197 | name = Debug;
198 | };
199 | FE3CAD1B1CEE59530058C6B4 /* Release */ = {
200 | isa = XCBuildConfiguration;
201 | buildSettings = {
202 | ALWAYS_SEARCH_USER_PATHS = NO;
203 | CLANG_ANALYZER_NONNULL = YES;
204 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
205 | CLANG_CXX_LIBRARY = "libc++";
206 | CLANG_ENABLE_MODULES = YES;
207 | CLANG_ENABLE_OBJC_ARC = YES;
208 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
209 | CLANG_WARN_BOOL_CONVERSION = YES;
210 | CLANG_WARN_COMMA = YES;
211 | CLANG_WARN_CONSTANT_CONVERSION = YES;
212 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
213 | CLANG_WARN_EMPTY_BODY = YES;
214 | CLANG_WARN_ENUM_CONVERSION = YES;
215 | CLANG_WARN_INFINITE_RECURSION = YES;
216 | CLANG_WARN_INT_CONVERSION = YES;
217 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
218 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
219 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
220 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
221 | CLANG_WARN_STRICT_PROTOTYPES = YES;
222 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
223 | CLANG_WARN_UNREACHABLE_CODE = YES;
224 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
225 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
226 | COPY_PHASE_STRIP = NO;
227 | CURRENT_PROJECT_VERSION = 1;
228 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
229 | ENABLE_NS_ASSERTIONS = NO;
230 | ENABLE_STRICT_OBJC_MSGSEND = YES;
231 | GCC_C_LANGUAGE_STANDARD = gnu99;
232 | GCC_NO_COMMON_BLOCKS = YES;
233 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
234 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
235 | GCC_WARN_UNDECLARED_SELECTOR = YES;
236 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
237 | GCC_WARN_UNUSED_FUNCTION = YES;
238 | GCC_WARN_UNUSED_VARIABLE = YES;
239 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
240 | MTL_ENABLE_DEBUG_INFO = NO;
241 | SDKROOT = iphoneos;
242 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
243 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
244 | TARGETED_DEVICE_FAMILY = "1,2";
245 | VALIDATE_PRODUCT = YES;
246 | VERSIONING_SYSTEM = "apple-generic";
247 | VERSION_INFO_PREFIX = "";
248 | };
249 | name = Release;
250 | };
251 | FE3CAD1D1CEE59530058C6B4 /* Debug */ = {
252 | isa = XCBuildConfiguration;
253 | buildSettings = {
254 | CLANG_ENABLE_MODULES = YES;
255 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
256 | DEFINES_MODULE = YES;
257 | DYLIB_COMPATIBILITY_VERSION = 1;
258 | DYLIB_CURRENT_VERSION = 1;
259 | DYLIB_INSTALL_NAME_BASE = "@rpath";
260 | INFOPLIST_FILE = "Supporting FIles/Info.plist";
261 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
262 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
263 | PRODUCT_BUNDLE_IDENTIFIER = fr.liquidsoul.XCTestPlayground;
264 | PRODUCT_NAME = "$(TARGET_NAME)";
265 | SKIP_INSTALL = YES;
266 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
267 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
268 | SWIFT_VERSION = 4.0;
269 | };
270 | name = Debug;
271 | };
272 | FE3CAD1E1CEE59530058C6B4 /* Release */ = {
273 | isa = XCBuildConfiguration;
274 | buildSettings = {
275 | CLANG_ENABLE_MODULES = YES;
276 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
277 | DEFINES_MODULE = YES;
278 | DYLIB_COMPATIBILITY_VERSION = 1;
279 | DYLIB_CURRENT_VERSION = 1;
280 | DYLIB_INSTALL_NAME_BASE = "@rpath";
281 | INFOPLIST_FILE = "Supporting FIles/Info.plist";
282 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
283 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
284 | PRODUCT_BUNDLE_IDENTIFIER = fr.liquidsoul.XCTestPlayground;
285 | PRODUCT_NAME = "$(TARGET_NAME)";
286 | SKIP_INSTALL = YES;
287 | SWIFT_SWIFT3_OBJC_INFERENCE = Default;
288 | SWIFT_VERSION = 4.0;
289 | };
290 | name = Release;
291 | };
292 | /* End XCBuildConfiguration section */
293 |
294 | /* Begin XCConfigurationList section */
295 | FE3CAD0E1CEE59530058C6B4 /* Build configuration list for PBXProject "XCTestPlayground" */ = {
296 | isa = XCConfigurationList;
297 | buildConfigurations = (
298 | FE3CAD1A1CEE59530058C6B4 /* Debug */,
299 | FE3CAD1B1CEE59530058C6B4 /* Release */,
300 | );
301 | defaultConfigurationIsVisible = 0;
302 | defaultConfigurationName = Release;
303 | };
304 | FE3CAD1C1CEE59530058C6B4 /* Build configuration list for PBXNativeTarget "XCTestPlayground" */ = {
305 | isa = XCConfigurationList;
306 | buildConfigurations = (
307 | FE3CAD1D1CEE59530058C6B4 /* Debug */,
308 | FE3CAD1E1CEE59530058C6B4 /* Release */,
309 | );
310 | defaultConfigurationIsVisible = 0;
311 | defaultConfigurationName = Release;
312 | };
313 | /* End XCConfigurationList section */
314 | };
315 | rootObject = FE3CAD0B1CEE59530058C6B4 /* Project object */;
316 | }
317 |
--------------------------------------------------------------------------------
/XCTestPlayground.xcodeproj/xcshareddata/xcschemes/XCTestPlayground.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
31 |
32 |
33 |
34 |
35 |
36 |
47 |
48 |
54 |
55 |
56 |
57 |
58 |
59 |
65 |
66 |
72 |
73 |
74 |
75 |
77 |
78 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/XCTestPlayground.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/XCTestPlaygroundExample.playground/Contents.swift:
--------------------------------------------------------------------------------
1 | //: A simple example on how to use `XCTestPlayground`.
2 | //:
3 | //: Note that you **need** to build the framework first using a 64-bit target (iPhone 5s and above) before you can use it here.
4 |
5 | import Foundation
6 | import XCTestPlayground
7 |
8 | class TestCase: XCTestCase {
9 | @objc func testAssertions() {
10 | XCTAssertEqual(1, 2)
11 | XCTAssertEqual([1, 2], [2, 3])
12 | XCTAssertGreaterThanOrEqual(1, 2)
13 | XCTAssertTrue(true)
14 | }
15 | }
16 |
17 | TestCase()
18 |
--------------------------------------------------------------------------------
/XCTestPlaygroundExample.playground/contents.xcplayground:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Liquidsoul/XCTestPlayground/a2eb3620a62a99f443c82b3b84500ef3ee322dd0/screenshot.png
--------------------------------------------------------------------------------