diff --git a/Carthage/Checkouts/Nimble/.gitignore b/Carthage/Checkouts/Nimble/.gitignore new file mode 100644 index 00000000..c7397e7d --- /dev/null +++ b/Carthage/Checkouts/Nimble/.gitignore @@ -0,0 +1,6 @@ +.DS_Store +xcuserdata/ +build/ +.idea +DerivedData/ +Nimble.framework.zip diff --git a/Carthage/Checkouts/Nimble/.travis.yml b/Carthage/Checkouts/Nimble/.travis.yml new file mode 100644 index 00000000..94e88a55 --- /dev/null +++ b/Carthage/Checkouts/Nimble/.travis.yml @@ -0,0 +1,9 @@ +osx_image: xcode7 +language: objective-c + +env: + matrix: + - NIMBLE_RUNTIME_IOS_SDK_VERSION=9.0 TYPE=ios + - NIMBLE_RUNTIME_OSX_SDK_VERSION=10.10 TYPE=osx + +script: ./test $TYPE diff --git a/Carthage/Checkouts/Nimble/CONTRIBUTING.md b/Carthage/Checkouts/Nimble/CONTRIBUTING.md new file mode 100644 index 00000000..3d3415c7 --- /dev/null +++ b/Carthage/Checkouts/Nimble/CONTRIBUTING.md @@ -0,0 +1,103 @@ + + + +- [Welcome to Nimble!](#welcome-to-nimble!) + - [Reporting Bugs](#reporting-bugs) + - [Building the Project](#building-the-project) + - [Pull Requests](#pull-requests) + - [Style Conventions](#style-conventions) + - [Core Members](#core-members) + - [Code of Conduct](#code-of-conduct) + + + +# Welcome to Nimble! + +We're building a testing framework for a new generation of Swift and +Objective-C developers. + +Nimble should be easy to use and easy to maintain. Let's keep things +simple and well-tested. + +**tl;dr:** If you've added a file to the project, make sure it's +included in both the OS X and iOS targets. + +## Reporting Bugs + +Nothing is off-limits. If you're having a problem, we want to hear about +it. + +- See a crash? File an issue. +- Code isn't compiling, but you don't know why? Sounds like you should + submit a new issue, bud. +- Went to the kitchen, only to forget why you went in the first place? + Better submit an issue. + +## Building the Project + +- Use `Nimble.xcproj` to work on Nimble. + +## Pull Requests + +- Nothing is trivial. Submit pull requests for anything: typos, + whitespace, you name it. +- Not all pull requests will be merged, but all will be acknowledged. If + no one has provided feedback on your request, ping one of the owners + by name. +- Make sure your pull request includes any necessary updates to the + README or other documentation. +- Be sure the unit tests for both the OS X and iOS targets of Nimble + before submitting your pull request. You can run all the OS X & iOS unit + tests using `./test`. +- If you've added a file to the project, make sure it's included in both + the OS X and iOS targets. +- To make minor updates to old versions of Nimble that support Swift + 1.1, issue a pull request against the `swift-1.1` branch. The master + branch supports Swift 1.2. Travis CI will only pass for pull requests + issued against the `swift-1.1` branch. +- If you're making a configuration change, make sure to edit both the xcode + project and the podspec file. + +### Style Conventions + +- Indent using 4 spaces. +- Keep lines 100 characters or shorter. Break long statements into + shorter ones over multiple lines. +- In Objective-C, use `#pragma mark -` to mark public, internal, + protocol, and superclass methods. + +## Core Members + +If a few of your pull requests have been merged, and you'd like a +controlling stake in the project, file an issue asking for write access +to the repository. + +### Code of Conduct + +Your conduct as a core member is your own responsibility, but here are +some "ground rules": + +- Feel free to push whatever you want to master, and (if you have + ownership permissions) to create any repositories you'd like. + + Ideally, however, all changes should be submitted as GitHub pull + requests. No one should merge their own pull request, unless no + other core members respond for at least a few days. + + If you'd like to create a new repository, it'd be nice if you created + a GitHub issue and gathered some feedback first. + +- It'd be awesome if you could review, provide feedback on, and close + issues or pull requests submitted to the project. Please provide kind, + constructive feedback. Please don't be sarcastic or snarky. + +### Creating a Release + +The process is relatively straight forward, but here's is a useful checklist for tagging: + +- Look a changes from the previously tagged release and write release notes: `git log v0.4.0...HEAD` +- Run the release script: `./script/release A.B.C release-notes-file` +- Go to [github releases](https://github.com/Quick/Nimble/releases) and mark the tagged commit as a release. + - Use the same release notes you created for the tag, but tweak up formatting for github. + - Attach the carthage release `Nimble.framework.zip` to the release. +- Announce! diff --git a/Carthage/Checkouts/Nimble/Carthage/Build b/Carthage/Checkouts/Nimble/Carthage/Build new file mode 120000 index 00000000..76f9ba24 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Carthage/Build @@ -0,0 +1 @@ +../../../../Carthage/Build \ No newline at end of file diff --git a/Carthage/Checkouts/Nimble/LICENSE.md b/Carthage/Checkouts/Nimble/LICENSE.md new file mode 100644 index 00000000..0f3eb71a --- /dev/null +++ b/Carthage/Checkouts/Nimble/LICENSE.md @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2014 Quick Team + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Carthage/Checkouts/Nimble/Nimble.podspec b/Carthage/Checkouts/Nimble/Nimble.podspec new file mode 100644 index 00000000..5fc90a70 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble.podspec @@ -0,0 +1,19 @@ +Pod::Spec.new do |s| + s.name = "Nimble" + s.version = "2.0.0-rc.3" + s.summary = "A Matcher Framework for Swift and Objective-C" + s.description = <<-DESC + Use Nimble to express the expected outcomes of Swift or Objective-C expressions. Inspired by Cedar. + DESC + s.homepage = "https://github.com/Quick/Nimble" + s.license = { :type => "Apache 2.0", :file => "LICENSE.md" } + s.author = "Quick Contributors" + s.ios.deployment_target = "7.0" + s.osx.deployment_target = "10.9" + s.source = { :git => "https://github.com/Quick/Nimble.git", :tag => "v#{s.version}" } + + s.source_files = "Nimble", "Nimble/**/*.{swift,h,m}" + s.weak_framework = "XCTest" + s.requires_arc = true + s.pod_target_xcconfig = { 'ENABLE_BITCODE' => 'NO', 'OTHER_LDFLAGS' => '-weak-lswiftXCTest', 'FRAMEWORK_SEARCH_PATHS' => '$(inherited) "$(PLATFORM_DIR)/Developer/Library/Frameworks"' } +end diff --git a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.pbxproj b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.pbxproj new file mode 100644 index 00000000..fc457ec7 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.pbxproj @@ -0,0 +1,1394 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1F0648CC19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0648CB19639F5A001F9C46 /* ObjectWithLazyProperty.swift */; }; + 1F0648CD19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0648CB19639F5A001F9C46 /* ObjectWithLazyProperty.swift */; }; + 1F0648D41963AAB2001F9C46 /* SynchronousTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0648D31963AAB2001F9C46 /* SynchronousTests.swift */; }; + 1F0648D51963AAB2001F9C46 /* SynchronousTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0648D31963AAB2001F9C46 /* SynchronousTests.swift */; }; + 1F0FEA9A1AF32DA4001E554E /* ObjCExpectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0FEA991AF32DA4001E554E /* ObjCExpectation.swift */; }; + 1F0FEA9B1AF32DA4001E554E /* ObjCExpectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F0FEA991AF32DA4001E554E /* ObjCExpectation.swift */; }; + 1F14FB64194180C5009F2A08 /* utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F14FB63194180C5009F2A08 /* utils.swift */; }; + 1F1A742F1940169200FFFC47 /* Nimble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F1A742E1940169200FFFC47 /* Nimble.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F1A74351940169200FFFC47 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F1A74291940169200FFFC47 /* Nimble.framework */; }; + 1F1B5AD41963E13900CA8BF9 /* BeAKindOfTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1B5AD31963E13900CA8BF9 /* BeAKindOfTest.swift */; }; + 1F1B5AD51963E13900CA8BF9 /* BeAKindOfTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F1B5AD31963E13900CA8BF9 /* BeAKindOfTest.swift */; }; + 1F299EAB19627B2D002641AF /* BeEmptyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F299EAA19627B2D002641AF /* BeEmptyTest.swift */; }; + 1F299EAC19627B2D002641AF /* BeEmptyTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F299EAA19627B2D002641AF /* BeEmptyTest.swift */; }; + 1F43728A1A1B343800EB80F8 /* Functional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD251968AB07008ED995 /* Functional.swift */; }; + 1F43728B1A1B343900EB80F8 /* Functional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD251968AB07008ED995 /* Functional.swift */; }; + 1F43728C1A1B343C00EB80F8 /* SourceLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD271968AB07008ED995 /* SourceLocation.swift */; }; + 1F43728D1A1B343D00EB80F8 /* SourceLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD271968AB07008ED995 /* SourceLocation.swift */; }; + 1F43728E1A1B343F00EB80F8 /* Stringers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD281968AB07008ED995 /* Stringers.swift */; }; + 1F43728F1A1B344000EB80F8 /* Stringers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD281968AB07008ED995 /* Stringers.swift */; }; + 1F4A56661A3B305F009E1637 /* ObjCAsyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56651A3B305F009E1637 /* ObjCAsyncTest.m */; }; + 1F4A56671A3B305F009E1637 /* ObjCAsyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56651A3B305F009E1637 /* ObjCAsyncTest.m */; }; + 1F4A566A1A3B3108009E1637 /* ObjCBeAnInstanceOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56691A3B3108009E1637 /* ObjCBeAnInstanceOfTest.m */; }; + 1F4A566B1A3B3108009E1637 /* ObjCBeAnInstanceOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56691A3B3108009E1637 /* ObjCBeAnInstanceOfTest.m */; }; + 1F4A566D1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A566C1A3B3159009E1637 /* ObjCBeKindOfTest.m */; }; + 1F4A566E1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A566C1A3B3159009E1637 /* ObjCBeKindOfTest.m */; }; + 1F4A56701A3B319F009E1637 /* ObjCBeCloseToTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A566F1A3B319F009E1637 /* ObjCBeCloseToTest.m */; }; + 1F4A56711A3B319F009E1637 /* ObjCBeCloseToTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A566F1A3B319F009E1637 /* ObjCBeCloseToTest.m */; }; + 1F4A56731A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56721A3B3210009E1637 /* ObjCBeginWithTest.m */; }; + 1F4A56741A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56721A3B3210009E1637 /* ObjCBeginWithTest.m */; }; + 1F4A56761A3B3253009E1637 /* ObjCBeGreaterThanTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56751A3B3253009E1637 /* ObjCBeGreaterThanTest.m */; }; + 1F4A56771A3B3253009E1637 /* ObjCBeGreaterThanTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56751A3B3253009E1637 /* ObjCBeGreaterThanTest.m */; }; + 1F4A56791A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56781A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m */; }; + 1F4A567A1A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56781A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m */; }; + 1F4A567C1A3B3311009E1637 /* ObjCBeIdenticalToTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A567B1A3B3311009E1637 /* ObjCBeIdenticalToTest.m */; }; + 1F4A567D1A3B3311009E1637 /* ObjCBeIdenticalToTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A567B1A3B3311009E1637 /* ObjCBeIdenticalToTest.m */; }; + 1F4A567F1A3B333F009E1637 /* ObjCBeLessThanTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A567E1A3B333F009E1637 /* ObjCBeLessThanTest.m */; }; + 1F4A56801A3B333F009E1637 /* ObjCBeLessThanTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A567E1A3B333F009E1637 /* ObjCBeLessThanTest.m */; }; + 1F4A56821A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56811A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m */; }; + 1F4A56831A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56811A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m */; }; + 1F4A56851A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56841A3B33A0009E1637 /* ObjCBeTruthyTest.m */; }; + 1F4A56861A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56841A3B33A0009E1637 /* ObjCBeTruthyTest.m */; }; + 1F4A56881A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56871A3B33CB009E1637 /* ObjCBeFalsyTest.m */; }; + 1F4A56891A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56871A3B33CB009E1637 /* ObjCBeFalsyTest.m */; }; + 1F4A568B1A3B3407009E1637 /* ObjCBeTrueTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A568A1A3B3407009E1637 /* ObjCBeTrueTest.m */; }; + 1F4A568C1A3B3407009E1637 /* ObjCBeTrueTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A568A1A3B3407009E1637 /* ObjCBeTrueTest.m */; }; + 1F4A568E1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A568D1A3B342B009E1637 /* ObjCBeFalseTest.m */; }; + 1F4A568F1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A568D1A3B342B009E1637 /* ObjCBeFalseTest.m */; }; + 1F4A56911A3B344A009E1637 /* ObjCBeNilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56901A3B344A009E1637 /* ObjCBeNilTest.m */; }; + 1F4A56921A3B344A009E1637 /* ObjCBeNilTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56901A3B344A009E1637 /* ObjCBeNilTest.m */; }; + 1F4A56941A3B346F009E1637 /* ObjCContainTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56931A3B346F009E1637 /* ObjCContainTest.m */; }; + 1F4A56951A3B346F009E1637 /* ObjCContainTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56931A3B346F009E1637 /* ObjCContainTest.m */; }; + 1F4A56971A3B34AA009E1637 /* ObjCEndWithTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56961A3B34AA009E1637 /* ObjCEndWithTest.m */; }; + 1F4A56981A3B34AA009E1637 /* ObjCEndWithTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56961A3B34AA009E1637 /* ObjCEndWithTest.m */; }; + 1F4A569A1A3B3539009E1637 /* ObjCEqualTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56991A3B3539009E1637 /* ObjCEqualTest.m */; }; + 1F4A569B1A3B3539009E1637 /* ObjCEqualTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A56991A3B3539009E1637 /* ObjCEqualTest.m */; }; + 1F4A569D1A3B3565009E1637 /* ObjCMatchTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A569C1A3B3565009E1637 /* ObjCMatchTest.m */; }; + 1F4A569E1A3B3565009E1637 /* ObjCMatchTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A569C1A3B3565009E1637 /* ObjCMatchTest.m */; }; + 1F4A56A01A3B359E009E1637 /* ObjCRaiseExceptionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A569F1A3B359E009E1637 /* ObjCRaiseExceptionTest.m */; }; + 1F4A56A11A3B359E009E1637 /* ObjCRaiseExceptionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F4A569F1A3B359E009E1637 /* ObjCRaiseExceptionTest.m */; }; + 1F8A37B01B7C5042001C8357 /* ObjCSyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */; }; + 1F8A37B11B7C5042001C8357 /* ObjCSyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */; }; + 1F925EB8195C0D6300ED456B /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F925EAD195C0D6300ED456B /* Nimble.framework */; }; + 1F925EC7195C0DD100ED456B /* Nimble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F1A742E1940169200FFFC47 /* Nimble.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F925EE2195C0DFD00ED456B /* utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F14FB63194180C5009F2A08 /* utils.swift */; }; + 1F925EE6195C121200ED456B /* AsynchronousTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EE5195C121200ED456B /* AsynchronousTest.swift */; }; + 1F925EE7195C121200ED456B /* AsynchronousTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EE5195C121200ED456B /* AsynchronousTest.swift */; }; + 1F925EE9195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EE8195C124400ED456B /* BeAnInstanceOfTest.swift */; }; + 1F925EEA195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EE8195C124400ED456B /* BeAnInstanceOfTest.swift */; }; + 1F925EEC195C12C800ED456B /* RaisesExceptionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EEB195C12C800ED456B /* RaisesExceptionTest.swift */; }; + 1F925EED195C12C800ED456B /* RaisesExceptionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EEB195C12C800ED456B /* RaisesExceptionTest.swift */; }; + 1F925EEF195C136500ED456B /* BeLogicalTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EEE195C136500ED456B /* BeLogicalTest.swift */; }; + 1F925EF0195C136500ED456B /* BeLogicalTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EEE195C136500ED456B /* BeLogicalTest.swift */; }; + 1F925EF6195C147800ED456B /* BeCloseToTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EF5195C147800ED456B /* BeCloseToTest.swift */; }; + 1F925EF7195C147800ED456B /* BeCloseToTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EF5195C147800ED456B /* BeCloseToTest.swift */; }; + 1F925EF9195C175000ED456B /* BeNilTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EF8195C175000ED456B /* BeNilTest.swift */; }; + 1F925EFA195C175000ED456B /* BeNilTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EF8195C175000ED456B /* BeNilTest.swift */; }; + 1F925EFC195C186800ED456B /* BeginWithTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EFB195C186800ED456B /* BeginWithTest.swift */; }; + 1F925EFD195C186800ED456B /* BeginWithTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EFB195C186800ED456B /* BeginWithTest.swift */; }; + 1F925EFF195C187600ED456B /* EndWithTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EFE195C187600ED456B /* EndWithTest.swift */; }; + 1F925F00195C187600ED456B /* EndWithTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EFE195C187600ED456B /* EndWithTest.swift */; }; + 1F925F02195C189500ED456B /* ContainTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F01195C189500ED456B /* ContainTest.swift */; }; + 1F925F03195C189500ED456B /* ContainTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F01195C189500ED456B /* ContainTest.swift */; }; + 1F925F05195C18B700ED456B /* EqualTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F04195C18B700ED456B /* EqualTest.swift */; }; + 1F925F06195C18B700ED456B /* EqualTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F04195C18B700ED456B /* EqualTest.swift */; }; + 1F925F08195C18CF00ED456B /* BeGreaterThanTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F07195C18CF00ED456B /* BeGreaterThanTest.swift */; }; + 1F925F09195C18CF00ED456B /* BeGreaterThanTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F07195C18CF00ED456B /* BeGreaterThanTest.swift */; }; + 1F925F0B195C18E100ED456B /* BeLessThanTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F0A195C18E100ED456B /* BeLessThanTest.swift */; }; + 1F925F0C195C18E100ED456B /* BeLessThanTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F0A195C18E100ED456B /* BeLessThanTest.swift */; }; + 1F925F0E195C18F500ED456B /* BeLessThanOrEqualToTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F0D195C18F500ED456B /* BeLessThanOrEqualToTest.swift */; }; + 1F925F0F195C18F500ED456B /* BeLessThanOrEqualToTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F0D195C18F500ED456B /* BeLessThanOrEqualToTest.swift */; }; + 1F925F11195C190B00ED456B /* BeGreaterThanOrEqualToTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F10195C190B00ED456B /* BeGreaterThanOrEqualToTest.swift */; }; + 1F925F12195C190B00ED456B /* BeGreaterThanOrEqualToTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925F10195C190B00ED456B /* BeGreaterThanOrEqualToTest.swift */; }; + 1F9DB8FB1A74E793002E96AD /* ObjCBeEmptyTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F9DB8FA1A74E793002E96AD /* ObjCBeEmptyTest.m */; }; + 1F9DB8FC1A74E793002E96AD /* ObjCBeEmptyTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F9DB8FA1A74E793002E96AD /* ObjCBeEmptyTest.m */; }; + 1FB90098195EC4B8001D7FAE /* BeIdenticalToTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FB90097195EC4B8001D7FAE /* BeIdenticalToTest.swift */; }; + 1FB90099195EC4B8001D7FAE /* BeIdenticalToTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FB90097195EC4B8001D7FAE /* BeIdenticalToTest.swift */; }; + 1FD8CD2E1968AB07008ED995 /* AssertionRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD051968AB07008ED995 /* AssertionRecorder.swift */; }; + 1FD8CD2F1968AB07008ED995 /* AssertionRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD051968AB07008ED995 /* AssertionRecorder.swift */; }; + 1FD8CD301968AB07008ED995 /* AdapterProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD061968AB07008ED995 /* AdapterProtocols.swift */; }; + 1FD8CD311968AB07008ED995 /* AdapterProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD061968AB07008ED995 /* AdapterProtocols.swift */; }; + 1FD8CD321968AB07008ED995 /* NimbleXCTestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD071968AB07008ED995 /* NimbleXCTestHandler.swift */; }; + 1FD8CD331968AB07008ED995 /* NimbleXCTestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD071968AB07008ED995 /* NimbleXCTestHandler.swift */; }; + 1FD8CD341968AB07008ED995 /* DSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD081968AB07008ED995 /* DSL.swift */; }; + 1FD8CD351968AB07008ED995 /* DSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD081968AB07008ED995 /* DSL.swift */; }; + 1FD8CD361968AB07008ED995 /* Expectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD091968AB07008ED995 /* Expectation.swift */; }; + 1FD8CD371968AB07008ED995 /* Expectation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD091968AB07008ED995 /* Expectation.swift */; }; + 1FD8CD381968AB07008ED995 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0A1968AB07008ED995 /* Expression.swift */; }; + 1FD8CD391968AB07008ED995 /* Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0A1968AB07008ED995 /* Expression.swift */; }; + 1FD8CD3A1968AB07008ED995 /* FailureMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0B1968AB07008ED995 /* FailureMessage.swift */; }; + 1FD8CD3B1968AB07008ED995 /* FailureMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0B1968AB07008ED995 /* FailureMessage.swift */; }; + 1FD8CD3C1968AB07008ED995 /* BeAnInstanceOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0D1968AB07008ED995 /* BeAnInstanceOf.swift */; }; + 1FD8CD3D1968AB07008ED995 /* BeAnInstanceOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0D1968AB07008ED995 /* BeAnInstanceOf.swift */; }; + 1FD8CD3E1968AB07008ED995 /* BeAKindOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0E1968AB07008ED995 /* BeAKindOf.swift */; }; + 1FD8CD3F1968AB07008ED995 /* BeAKindOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0E1968AB07008ED995 /* BeAKindOf.swift */; }; + 1FD8CD401968AB07008ED995 /* BeCloseTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0F1968AB07008ED995 /* BeCloseTo.swift */; }; + 1FD8CD411968AB07008ED995 /* BeCloseTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD0F1968AB07008ED995 /* BeCloseTo.swift */; }; + 1FD8CD421968AB07008ED995 /* BeEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD101968AB07008ED995 /* BeEmpty.swift */; }; + 1FD8CD431968AB07008ED995 /* BeEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD101968AB07008ED995 /* BeEmpty.swift */; }; + 1FD8CD441968AB07008ED995 /* BeginWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD111968AB07008ED995 /* BeginWith.swift */; }; + 1FD8CD451968AB07008ED995 /* BeginWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD111968AB07008ED995 /* BeginWith.swift */; }; + 1FD8CD461968AB07008ED995 /* BeGreaterThan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD121968AB07008ED995 /* BeGreaterThan.swift */; }; + 1FD8CD471968AB07008ED995 /* BeGreaterThan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD121968AB07008ED995 /* BeGreaterThan.swift */; }; + 1FD8CD481968AB07008ED995 /* BeGreaterThanOrEqualTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD131968AB07008ED995 /* BeGreaterThanOrEqualTo.swift */; }; + 1FD8CD491968AB07008ED995 /* BeGreaterThanOrEqualTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD131968AB07008ED995 /* BeGreaterThanOrEqualTo.swift */; }; + 1FD8CD4A1968AB07008ED995 /* BeIdenticalTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD141968AB07008ED995 /* BeIdenticalTo.swift */; }; + 1FD8CD4B1968AB07008ED995 /* BeIdenticalTo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD141968AB07008ED995 /* BeIdenticalTo.swift */; }; + 1FD8CD4C1968AB07008ED995 /* BeLessThan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD151968AB07008ED995 /* BeLessThan.swift */; }; + 1FD8CD4D1968AB07008ED995 /* BeLessThan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD151968AB07008ED995 /* BeLessThan.swift */; }; + 1FD8CD4E1968AB07008ED995 /* BeLessThanOrEqual.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD161968AB07008ED995 /* BeLessThanOrEqual.swift */; }; + 1FD8CD4F1968AB07008ED995 /* BeLessThanOrEqual.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD161968AB07008ED995 /* BeLessThanOrEqual.swift */; }; + 1FD8CD501968AB07008ED995 /* BeLogical.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD171968AB07008ED995 /* BeLogical.swift */; }; + 1FD8CD511968AB07008ED995 /* BeLogical.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD171968AB07008ED995 /* BeLogical.swift */; }; + 1FD8CD521968AB07008ED995 /* BeNil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD181968AB07008ED995 /* BeNil.swift */; }; + 1FD8CD531968AB07008ED995 /* BeNil.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD181968AB07008ED995 /* BeNil.swift */; }; + 1FD8CD561968AB07008ED995 /* Contain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1A1968AB07008ED995 /* Contain.swift */; }; + 1FD8CD571968AB07008ED995 /* Contain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1A1968AB07008ED995 /* Contain.swift */; }; + 1FD8CD581968AB07008ED995 /* EndWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1B1968AB07008ED995 /* EndWith.swift */; }; + 1FD8CD591968AB07008ED995 /* EndWith.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1B1968AB07008ED995 /* EndWith.swift */; }; + 1FD8CD5A1968AB07008ED995 /* Equal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1C1968AB07008ED995 /* Equal.swift */; }; + 1FD8CD5B1968AB07008ED995 /* Equal.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1C1968AB07008ED995 /* Equal.swift */; }; + 1FD8CD5C1968AB07008ED995 /* MatcherProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1D1968AB07008ED995 /* MatcherProtocols.swift */; }; + 1FD8CD5D1968AB07008ED995 /* MatcherProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1D1968AB07008ED995 /* MatcherProtocols.swift */; }; + 1FD8CD5E1968AB07008ED995 /* RaisesException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1E1968AB07008ED995 /* RaisesException.swift */; }; + 1FD8CD5F1968AB07008ED995 /* RaisesException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD1E1968AB07008ED995 /* RaisesException.swift */; }; + 1FD8CD601968AB07008ED995 /* DSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FD8CD201968AB07008ED995 /* DSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1FD8CD611968AB07008ED995 /* DSL.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FD8CD201968AB07008ED995 /* DSL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1FD8CD621968AB07008ED995 /* DSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD211968AB07008ED995 /* DSL.m */; }; + 1FD8CD631968AB07008ED995 /* DSL.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD211968AB07008ED995 /* DSL.m */; }; + 1FD8CD641968AB07008ED995 /* NMBExceptionCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FD8CD221968AB07008ED995 /* NMBExceptionCapture.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1FD8CD651968AB07008ED995 /* NMBExceptionCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FD8CD221968AB07008ED995 /* NMBExceptionCapture.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1FD8CD661968AB07008ED995 /* NMBExceptionCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD231968AB07008ED995 /* NMBExceptionCapture.m */; }; + 1FD8CD671968AB07008ED995 /* NMBExceptionCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD231968AB07008ED995 /* NMBExceptionCapture.m */; }; + 1FD8CD6A1968AB07008ED995 /* Poll.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD261968AB07008ED995 /* Poll.swift */; }; + 1FD8CD6B1968AB07008ED995 /* Poll.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD261968AB07008ED995 /* Poll.swift */; }; + 1FD8CD701968AB07008ED995 /* AsyncMatcherWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD2A1968AB07008ED995 /* AsyncMatcherWrapper.swift */; }; + 1FD8CD711968AB07008ED995 /* AsyncMatcherWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD2A1968AB07008ED995 /* AsyncMatcherWrapper.swift */; }; + 1FD8CD741968AB07008ED995 /* MatcherFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD2C1968AB07008ED995 /* MatcherFunc.swift */; }; + 1FD8CD751968AB07008ED995 /* MatcherFunc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD2C1968AB07008ED995 /* MatcherFunc.swift */; }; + 1FD8CD761968AB07008ED995 /* ObjCMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD2D1968AB07008ED995 /* ObjCMatcher.swift */; }; + 1FD8CD771968AB07008ED995 /* ObjCMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD2D1968AB07008ED995 /* ObjCMatcher.swift */; }; + 1FDBD8671AF8A4FF0089F27B /* AssertionDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDBD8661AF8A4FF0089F27B /* AssertionDispatcher.swift */; }; + 1FDBD8681AF8A4FF0089F27B /* AssertionDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FDBD8661AF8A4FF0089F27B /* AssertionDispatcher.swift */; }; + 29EA59631B551ED2002D767E /* ThrowErrorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29EA59621B551ED2002D767E /* ThrowErrorTest.swift */; }; + 29EA59641B551ED2002D767E /* ThrowErrorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29EA59621B551ED2002D767E /* ThrowErrorTest.swift */; }; + 29EA59661B551EE6002D767E /* ThrowError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29EA59651B551EE6002D767E /* ThrowError.swift */; }; + 29EA59671B551EE6002D767E /* ThrowError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29EA59651B551EE6002D767E /* ThrowError.swift */; }; + 965B0D091B62B8ED0005AE66 /* ObjCUserDescriptionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 965B0D081B62B8ED0005AE66 /* ObjCUserDescriptionTest.m */; }; + 965B0D0A1B62B8ED0005AE66 /* ObjCUserDescriptionTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 965B0D081B62B8ED0005AE66 /* ObjCUserDescriptionTest.m */; }; + 965B0D0C1B62C06D0005AE66 /* UserDescriptionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 965B0D0B1B62C06D0005AE66 /* UserDescriptionTest.swift */; }; + 965B0D0D1B62C06D0005AE66 /* UserDescriptionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 965B0D0B1B62C06D0005AE66 /* UserDescriptionTest.swift */; }; + DA9E8C821A414BB9002633C2 /* DSL+Wait.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9E8C811A414BB9002633C2 /* DSL+Wait.swift */; }; + DA9E8C831A414BB9002633C2 /* DSL+Wait.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA9E8C811A414BB9002633C2 /* DSL+Wait.swift */; }; + DD72EC641A93874A002F7651 /* AllPassTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD72EC631A93874A002F7651 /* AllPassTest.swift */; }; + DD72EC651A93874A002F7651 /* AllPassTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD72EC631A93874A002F7651 /* AllPassTest.swift */; }; + DD9A9A8F19CF439B00706F49 /* BeIdenticalToObjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD9A9A8D19CF413800706F49 /* BeIdenticalToObjectTest.swift */; }; + DD9A9A9019CF43AD00706F49 /* BeIdenticalToObjectTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD9A9A8D19CF413800706F49 /* BeIdenticalToObjectTest.swift */; }; + DDB1BC791A92235600F743C3 /* AllPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB1BC781A92235600F743C3 /* AllPass.swift */; }; + DDB1BC7A1A92235600F743C3 /* AllPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB1BC781A92235600F743C3 /* AllPass.swift */; }; + DDB4D5ED19FE43C200E9D9FE /* Match.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB4D5EC19FE43C200E9D9FE /* Match.swift */; }; + DDB4D5EE19FE43C200E9D9FE /* Match.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB4D5EC19FE43C200E9D9FE /* Match.swift */; }; + DDB4D5F019FE442800E9D9FE /* MatchTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB4D5EF19FE442800E9D9FE /* MatchTest.swift */; }; + DDB4D5F119FE442800E9D9FE /* MatchTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB4D5EF19FE442800E9D9FE /* MatchTest.swift */; }; + DDEFAEB41A93CBE6005CA37A /* ObjCAllPassTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DDEFAEB31A93CBE6005CA37A /* ObjCAllPassTest.m */; }; + DDEFAEB51A93CBE6005CA37A /* ObjCAllPassTest.m in Sources */ = {isa = PBXBuildFile; fileRef = DDEFAEB31A93CBE6005CA37A /* ObjCAllPassTest.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 1F1A74361940169200FFFC47 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1F1A74201940169200FFFC47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F1A74281940169200FFFC47; + remoteInfo = "Nimble-iOS"; + }; + 1F6BB82A1968BFF9009F1DBB /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1F1A74201940169200FFFC47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F1A74281940169200FFFC47; + remoteInfo = "Nimble-iOS"; + }; + 1F925EA4195C0C8500ED456B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1F1A74201940169200FFFC47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F1A74281940169200FFFC47; + remoteInfo = Nimble; + }; + 1F925EA6195C0C8500ED456B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1F1A74201940169200FFFC47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F1A74281940169200FFFC47; + remoteInfo = Nimble; + }; + 1F925EB9195C0D6300ED456B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1F1A74201940169200FFFC47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F925EAC195C0D6300ED456B; + remoteInfo = "Nimble-OSX"; + }; + 1F9B7BFD1968AD760094EB8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1F1A74201940169200FFFC47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F925EAC195C0D6300ED456B; + remoteInfo = "Nimble-OSX"; + }; + 1F9B7BFF1968AD760094EB8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1F1A74201940169200FFFC47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F925EAC195C0D6300ED456B; + remoteInfo = "Nimble-OSX"; + }; + 1F9B7C011968AD820094EB8F /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1F1A74201940169200FFFC47 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F925EAC195C0D6300ED456B; + remoteInfo = "Nimble-OSX"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 1F0648CB19639F5A001F9C46 /* ObjectWithLazyProperty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectWithLazyProperty.swift; sourceTree = ""; }; + 1F0648D31963AAB2001F9C46 /* SynchronousTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronousTests.swift; sourceTree = ""; }; + 1F0FEA991AF32DA4001E554E /* ObjCExpectation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjCExpectation.swift; sourceTree = ""; }; + 1F14FB63194180C5009F2A08 /* utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = utils.swift; sourceTree = ""; }; + 1F1A74291940169200FFFC47 /* Nimble.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F1A742D1940169200FFFC47 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1F1A742E1940169200FFFC47 /* Nimble.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Nimble.h; sourceTree = ""; }; + 1F1A74341940169200FFFC47 /* NimbleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F1A743A1940169200FFFC47 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1F1B5AD31963E13900CA8BF9 /* BeAKindOfTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeAKindOfTest.swift; sourceTree = ""; }; + 1F2752D119445B8400052A26 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; lineEnding = 0; path = README.md; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.markdown; }; + 1F299EAA19627B2D002641AF /* BeEmptyTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeEmptyTest.swift; sourceTree = ""; }; + 1F4A56651A3B305F009E1637 /* ObjCAsyncTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCAsyncTest.m; sourceTree = ""; }; + 1F4A56681A3B3074009E1637 /* NimbleSpecHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NimbleSpecHelper.h; sourceTree = ""; }; + 1F4A56691A3B3108009E1637 /* ObjCBeAnInstanceOfTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeAnInstanceOfTest.m; sourceTree = ""; }; + 1F4A566C1A3B3159009E1637 /* ObjCBeKindOfTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeKindOfTest.m; sourceTree = ""; }; + 1F4A566F1A3B319F009E1637 /* ObjCBeCloseToTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeCloseToTest.m; sourceTree = ""; }; + 1F4A56721A3B3210009E1637 /* ObjCBeginWithTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeginWithTest.m; sourceTree = ""; }; + 1F4A56751A3B3253009E1637 /* ObjCBeGreaterThanTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeGreaterThanTest.m; sourceTree = ""; }; + 1F4A56781A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeGreaterThanOrEqualToTest.m; sourceTree = ""; }; + 1F4A567B1A3B3311009E1637 /* ObjCBeIdenticalToTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeIdenticalToTest.m; sourceTree = ""; }; + 1F4A567E1A3B333F009E1637 /* ObjCBeLessThanTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeLessThanTest.m; sourceTree = ""; }; + 1F4A56811A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeLessThanOrEqualToTest.m; sourceTree = ""; }; + 1F4A56841A3B33A0009E1637 /* ObjCBeTruthyTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeTruthyTest.m; sourceTree = ""; }; + 1F4A56871A3B33CB009E1637 /* ObjCBeFalsyTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeFalsyTest.m; sourceTree = ""; }; + 1F4A568A1A3B3407009E1637 /* ObjCBeTrueTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeTrueTest.m; sourceTree = ""; }; + 1F4A568D1A3B342B009E1637 /* ObjCBeFalseTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeFalseTest.m; sourceTree = ""; }; + 1F4A56901A3B344A009E1637 /* ObjCBeNilTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeNilTest.m; sourceTree = ""; }; + 1F4A56931A3B346F009E1637 /* ObjCContainTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCContainTest.m; sourceTree = ""; }; + 1F4A56961A3B34AA009E1637 /* ObjCEndWithTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCEndWithTest.m; sourceTree = ""; }; + 1F4A56991A3B3539009E1637 /* ObjCEqualTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCEqualTest.m; sourceTree = ""; }; + 1F4A569C1A3B3565009E1637 /* ObjCMatchTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCMatchTest.m; sourceTree = ""; }; + 1F4A569F1A3B359E009E1637 /* ObjCRaiseExceptionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCRaiseExceptionTest.m; sourceTree = ""; }; + 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSyncTest.m; sourceTree = ""; }; + 1F925EAD195C0D6300ED456B /* Nimble.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F925EB7195C0D6300ED456B /* NimbleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 1F925EE5195C121200ED456B /* AsynchronousTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsynchronousTest.swift; sourceTree = ""; }; + 1F925EE8195C124400ED456B /* BeAnInstanceOfTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeAnInstanceOfTest.swift; sourceTree = ""; }; + 1F925EEB195C12C800ED456B /* RaisesExceptionTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RaisesExceptionTest.swift; sourceTree = ""; }; + 1F925EEE195C136500ED456B /* BeLogicalTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeLogicalTest.swift; sourceTree = ""; }; + 1F925EF5195C147800ED456B /* BeCloseToTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeCloseToTest.swift; sourceTree = ""; }; + 1F925EF8195C175000ED456B /* BeNilTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeNilTest.swift; sourceTree = ""; }; + 1F925EFB195C186800ED456B /* BeginWithTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeginWithTest.swift; sourceTree = ""; }; + 1F925EFE195C187600ED456B /* EndWithTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EndWithTest.swift; sourceTree = ""; }; + 1F925F01195C189500ED456B /* ContainTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainTest.swift; sourceTree = ""; }; + 1F925F04195C18B700ED456B /* EqualTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EqualTest.swift; sourceTree = ""; }; + 1F925F07195C18CF00ED456B /* BeGreaterThanTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeGreaterThanTest.swift; sourceTree = ""; }; + 1F925F0A195C18E100ED456B /* BeLessThanTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeLessThanTest.swift; sourceTree = ""; }; + 1F925F0D195C18F500ED456B /* BeLessThanOrEqualToTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeLessThanOrEqualToTest.swift; sourceTree = ""; }; + 1F925F10195C190B00ED456B /* BeGreaterThanOrEqualToTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeGreaterThanOrEqualToTest.swift; sourceTree = ""; }; + 1F9DB8FA1A74E793002E96AD /* ObjCBeEmptyTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCBeEmptyTest.m; sourceTree = ""; }; + 1FB90097195EC4B8001D7FAE /* BeIdenticalToTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeIdenticalToTest.swift; sourceTree = ""; }; + 1FD8CD051968AB07008ED995 /* AssertionRecorder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssertionRecorder.swift; sourceTree = ""; }; + 1FD8CD061968AB07008ED995 /* AdapterProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AdapterProtocols.swift; sourceTree = ""; }; + 1FD8CD071968AB07008ED995 /* NimbleXCTestHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NimbleXCTestHandler.swift; sourceTree = ""; }; + 1FD8CD081968AB07008ED995 /* DSL.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DSL.swift; sourceTree = ""; }; + 1FD8CD091968AB07008ED995 /* Expectation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Expectation.swift; sourceTree = ""; }; + 1FD8CD0A1968AB07008ED995 /* Expression.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Expression.swift; sourceTree = ""; }; + 1FD8CD0B1968AB07008ED995 /* FailureMessage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FailureMessage.swift; sourceTree = ""; }; + 1FD8CD0D1968AB07008ED995 /* BeAnInstanceOf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeAnInstanceOf.swift; sourceTree = ""; }; + 1FD8CD0E1968AB07008ED995 /* BeAKindOf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeAKindOf.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD0F1968AB07008ED995 /* BeCloseTo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeCloseTo.swift; sourceTree = ""; }; + 1FD8CD101968AB07008ED995 /* BeEmpty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeEmpty.swift; sourceTree = ""; }; + 1FD8CD111968AB07008ED995 /* BeginWith.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeginWith.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD121968AB07008ED995 /* BeGreaterThan.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeGreaterThan.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD131968AB07008ED995 /* BeGreaterThanOrEqualTo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeGreaterThanOrEqualTo.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD141968AB07008ED995 /* BeIdenticalTo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeIdenticalTo.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD151968AB07008ED995 /* BeLessThan.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeLessThan.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD161968AB07008ED995 /* BeLessThanOrEqual.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeLessThanOrEqual.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD171968AB07008ED995 /* BeLogical.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeLogical.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD181968AB07008ED995 /* BeNil.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = BeNil.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD1A1968AB07008ED995 /* Contain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Contain.swift; sourceTree = ""; }; + 1FD8CD1B1968AB07008ED995 /* EndWith.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EndWith.swift; sourceTree = ""; }; + 1FD8CD1C1968AB07008ED995 /* Equal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Equal.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD1D1968AB07008ED995 /* MatcherProtocols.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatcherProtocols.swift; sourceTree = ""; }; + 1FD8CD1E1968AB07008ED995 /* RaisesException.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = RaisesException.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + 1FD8CD201968AB07008ED995 /* DSL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DSL.h; sourceTree = ""; }; + 1FD8CD211968AB07008ED995 /* DSL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DSL.m; sourceTree = ""; }; + 1FD8CD221968AB07008ED995 /* NMBExceptionCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NMBExceptionCapture.h; sourceTree = ""; }; + 1FD8CD231968AB07008ED995 /* NMBExceptionCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NMBExceptionCapture.m; sourceTree = ""; }; + 1FD8CD251968AB07008ED995 /* Functional.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Functional.swift; sourceTree = ""; }; + 1FD8CD261968AB07008ED995 /* Poll.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Poll.swift; sourceTree = ""; }; + 1FD8CD271968AB07008ED995 /* SourceLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SourceLocation.swift; sourceTree = ""; }; + 1FD8CD281968AB07008ED995 /* Stringers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Stringers.swift; sourceTree = ""; }; + 1FD8CD2A1968AB07008ED995 /* AsyncMatcherWrapper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncMatcherWrapper.swift; sourceTree = ""; }; + 1FD8CD2C1968AB07008ED995 /* MatcherFunc.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatcherFunc.swift; sourceTree = ""; }; + 1FD8CD2D1968AB07008ED995 /* ObjCMatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjCMatcher.swift; sourceTree = ""; }; + 1FDBD8661AF8A4FF0089F27B /* AssertionDispatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssertionDispatcher.swift; sourceTree = ""; }; + 1FFD729B1963FCAB00CD29A2 /* NimbleTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NimbleTests-Bridging-Header.h"; sourceTree = ""; }; + 1FFD729C1963FCAB00CD29A2 /* Nimble-OSXTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Nimble-OSXTests-Bridging-Header.h"; sourceTree = ""; }; + 29EA59621B551ED2002D767E /* ThrowErrorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowErrorTest.swift; sourceTree = ""; }; + 29EA59651B551EE6002D767E /* ThrowError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowError.swift; sourceTree = ""; }; + 965B0D081B62B8ED0005AE66 /* ObjCUserDescriptionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCUserDescriptionTest.m; sourceTree = ""; }; + 965B0D0B1B62C06D0005AE66 /* UserDescriptionTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserDescriptionTest.swift; sourceTree = ""; }; + DA9E8C811A414BB9002633C2 /* DSL+Wait.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DSL+Wait.swift"; sourceTree = ""; }; + DD72EC631A93874A002F7651 /* AllPassTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AllPassTest.swift; sourceTree = ""; }; + DD9A9A8D19CF413800706F49 /* BeIdenticalToObjectTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeIdenticalToObjectTest.swift; sourceTree = ""; }; + DDB1BC781A92235600F743C3 /* AllPass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AllPass.swift; sourceTree = ""; }; + DDB4D5EC19FE43C200E9D9FE /* Match.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = Match.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; + DDB4D5EF19FE442800E9D9FE /* MatchTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatchTest.swift; sourceTree = ""; }; + DDEFAEB31A93CBE6005CA37A /* ObjCAllPassTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCAllPassTest.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1F1A74251940169200FFFC47 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F1A74311940169200FFFC47 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F1A74351940169200FFFC47 /* Nimble.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F925EA9195C0D6300ED456B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F925EB4195C0D6300ED456B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F925EB8195C0D6300ED456B /* Nimble.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 1F14FB61194180A7009F2A08 /* Helpers */ = { + isa = PBXGroup; + children = ( + 1F14FB63194180C5009F2A08 /* utils.swift */, + 1F0648CB19639F5A001F9C46 /* ObjectWithLazyProperty.swift */, + ); + path = Helpers; + sourceTree = ""; + }; + 1F1A741F1940169200FFFC47 = { + isa = PBXGroup; + children = ( + 1F2752D119445B8400052A26 /* README.md */, + 1F1A742B1940169200FFFC47 /* Nimble */, + 1F1A74381940169200FFFC47 /* NimbleTests */, + 1F1A742A1940169200FFFC47 /* Products */, + ); + sourceTree = ""; + }; + 1F1A742A1940169200FFFC47 /* Products */ = { + isa = PBXGroup; + children = ( + 1F1A74291940169200FFFC47 /* Nimble.framework */, + 1F1A74341940169200FFFC47 /* NimbleTests.xctest */, + 1F925EAD195C0D6300ED456B /* Nimble.framework */, + 1F925EB7195C0D6300ED456B /* NimbleTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 1F1A742B1940169200FFFC47 /* Nimble */ = { + isa = PBXGroup; + children = ( + 1FD8CD041968AB07008ED995 /* Adapters */, + 1FD8CD081968AB07008ED995 /* DSL.swift */, + DA9E8C811A414BB9002633C2 /* DSL+Wait.swift */, + 1FD8CD091968AB07008ED995 /* Expectation.swift */, + 1F0FEA991AF32DA4001E554E /* ObjCExpectation.swift */, + 1FD8CD0A1968AB07008ED995 /* Expression.swift */, + 1FD8CD0B1968AB07008ED995 /* FailureMessage.swift */, + 1FD8CD0C1968AB07008ED995 /* Matchers */, + 1F1A742E1940169200FFFC47 /* Nimble.h */, + 1FD8CD1F1968AB07008ED995 /* objc */, + 1F1A742C1940169200FFFC47 /* Supporting Files */, + 1FD8CD241968AB07008ED995 /* Utils */, + 1FD8CD291968AB07008ED995 /* Wrappers */, + ); + path = Nimble; + sourceTree = ""; + }; + 1F1A742C1940169200FFFC47 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 1F1A742D1940169200FFFC47 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1F1A74381940169200FFFC47 /* NimbleTests */ = { + isa = PBXGroup; + children = ( + 1F925EE5195C121200ED456B /* AsynchronousTest.swift */, + 1F0648D31963AAB2001F9C46 /* SynchronousTests.swift */, + 965B0D0B1B62C06D0005AE66 /* UserDescriptionTest.swift */, + 1FFD729A1963FC8200CD29A2 /* objc */, + 1F14FB61194180A7009F2A08 /* Helpers */, + 1F925EE3195C11B000ED456B /* Matchers */, + 1F1A74391940169200FFFC47 /* Supporting Files */, + ); + path = NimbleTests; + sourceTree = ""; + }; + 1F1A74391940169200FFFC47 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 1F1A743A1940169200FFFC47 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 1F925EE3195C11B000ED456B /* Matchers */ = { + isa = PBXGroup; + children = ( + DD72EC631A93874A002F7651 /* AllPassTest.swift */, + 1F1B5AD31963E13900CA8BF9 /* BeAKindOfTest.swift */, + 1F925EE8195C124400ED456B /* BeAnInstanceOfTest.swift */, + 1F925EF5195C147800ED456B /* BeCloseToTest.swift */, + 1F299EAA19627B2D002641AF /* BeEmptyTest.swift */, + 1F925EFB195C186800ED456B /* BeginWithTest.swift */, + 1F925F10195C190B00ED456B /* BeGreaterThanOrEqualToTest.swift */, + 1F925F07195C18CF00ED456B /* BeGreaterThanTest.swift */, + DD9A9A8D19CF413800706F49 /* BeIdenticalToObjectTest.swift */, + 1FB90097195EC4B8001D7FAE /* BeIdenticalToTest.swift */, + 1F925F0D195C18F500ED456B /* BeLessThanOrEqualToTest.swift */, + 1F925F0A195C18E100ED456B /* BeLessThanTest.swift */, + 1F925EEE195C136500ED456B /* BeLogicalTest.swift */, + 1F925EF8195C175000ED456B /* BeNilTest.swift */, + 1F925F01195C189500ED456B /* ContainTest.swift */, + 1F925EFE195C187600ED456B /* EndWithTest.swift */, + 1F925F04195C18B700ED456B /* EqualTest.swift */, + DDB4D5EF19FE442800E9D9FE /* MatchTest.swift */, + 1F925EEB195C12C800ED456B /* RaisesExceptionTest.swift */, + 29EA59621B551ED2002D767E /* ThrowErrorTest.swift */, + ); + path = Matchers; + sourceTree = ""; + }; + 1FD8CD041968AB07008ED995 /* Adapters */ = { + isa = PBXGroup; + children = ( + 1FD8CD051968AB07008ED995 /* AssertionRecorder.swift */, + 1FD8CD061968AB07008ED995 /* AdapterProtocols.swift */, + 1FD8CD071968AB07008ED995 /* NimbleXCTestHandler.swift */, + 1FDBD8661AF8A4FF0089F27B /* AssertionDispatcher.swift */, + ); + path = Adapters; + sourceTree = ""; + }; + 1FD8CD0C1968AB07008ED995 /* Matchers */ = { + isa = PBXGroup; + children = ( + DDB1BC781A92235600F743C3 /* AllPass.swift */, + 1FD8CD0E1968AB07008ED995 /* BeAKindOf.swift */, + 1FD8CD0D1968AB07008ED995 /* BeAnInstanceOf.swift */, + 1FD8CD0F1968AB07008ED995 /* BeCloseTo.swift */, + 1FD8CD101968AB07008ED995 /* BeEmpty.swift */, + 1FD8CD111968AB07008ED995 /* BeginWith.swift */, + 1FD8CD121968AB07008ED995 /* BeGreaterThan.swift */, + 1FD8CD131968AB07008ED995 /* BeGreaterThanOrEqualTo.swift */, + 1FD8CD141968AB07008ED995 /* BeIdenticalTo.swift */, + 1FD8CD151968AB07008ED995 /* BeLessThan.swift */, + 1FD8CD161968AB07008ED995 /* BeLessThanOrEqual.swift */, + 1FD8CD171968AB07008ED995 /* BeLogical.swift */, + 1FD8CD181968AB07008ED995 /* BeNil.swift */, + 1FD8CD1A1968AB07008ED995 /* Contain.swift */, + 1FD8CD1B1968AB07008ED995 /* EndWith.swift */, + 1FD8CD1C1968AB07008ED995 /* Equal.swift */, + DDB4D5EC19FE43C200E9D9FE /* Match.swift */, + 1FD8CD1D1968AB07008ED995 /* MatcherProtocols.swift */, + 1FD8CD1E1968AB07008ED995 /* RaisesException.swift */, + 29EA59651B551EE6002D767E /* ThrowError.swift */, + ); + path = Matchers; + sourceTree = ""; + }; + 1FD8CD1F1968AB07008ED995 /* objc */ = { + isa = PBXGroup; + children = ( + 1FD8CD201968AB07008ED995 /* DSL.h */, + 1FD8CD211968AB07008ED995 /* DSL.m */, + 1FD8CD221968AB07008ED995 /* NMBExceptionCapture.h */, + 1FD8CD231968AB07008ED995 /* NMBExceptionCapture.m */, + ); + path = objc; + sourceTree = ""; + }; + 1FD8CD241968AB07008ED995 /* Utils */ = { + isa = PBXGroup; + children = ( + 1FD8CD251968AB07008ED995 /* Functional.swift */, + 1FD8CD261968AB07008ED995 /* Poll.swift */, + 1FD8CD271968AB07008ED995 /* SourceLocation.swift */, + 1FD8CD281968AB07008ED995 /* Stringers.swift */, + ); + path = Utils; + sourceTree = ""; + }; + 1FD8CD291968AB07008ED995 /* Wrappers */ = { + isa = PBXGroup; + children = ( + 1FD8CD2A1968AB07008ED995 /* AsyncMatcherWrapper.swift */, + 1FD8CD2C1968AB07008ED995 /* MatcherFunc.swift */, + 1FD8CD2D1968AB07008ED995 /* ObjCMatcher.swift */, + ); + path = Wrappers; + sourceTree = ""; + }; + 1FFD729A1963FC8200CD29A2 /* objc */ = { + isa = PBXGroup; + children = ( + 1FFD729C1963FCAB00CD29A2 /* Nimble-OSXTests-Bridging-Header.h */, + 1F4A56681A3B3074009E1637 /* NimbleSpecHelper.h */, + 1FFD729B1963FCAB00CD29A2 /* NimbleTests-Bridging-Header.h */, + 1F4A56651A3B305F009E1637 /* ObjCAsyncTest.m */, + 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */, + 1F4A56691A3B3108009E1637 /* ObjCBeAnInstanceOfTest.m */, + 1F4A566F1A3B319F009E1637 /* ObjCBeCloseToTest.m */, + 1F9DB8FA1A74E793002E96AD /* ObjCBeEmptyTest.m */, + 1F4A568D1A3B342B009E1637 /* ObjCBeFalseTest.m */, + 1F4A56871A3B33CB009E1637 /* ObjCBeFalsyTest.m */, + 1F4A56721A3B3210009E1637 /* ObjCBeginWithTest.m */, + 1F4A56781A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m */, + 1F4A56751A3B3253009E1637 /* ObjCBeGreaterThanTest.m */, + 1F4A567B1A3B3311009E1637 /* ObjCBeIdenticalToTest.m */, + 1F4A566C1A3B3159009E1637 /* ObjCBeKindOfTest.m */, + 1F4A56811A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m */, + 1F4A567E1A3B333F009E1637 /* ObjCBeLessThanTest.m */, + 1F4A56901A3B344A009E1637 /* ObjCBeNilTest.m */, + 1F4A568A1A3B3407009E1637 /* ObjCBeTrueTest.m */, + 1F4A56841A3B33A0009E1637 /* ObjCBeTruthyTest.m */, + 1F4A56931A3B346F009E1637 /* ObjCContainTest.m */, + 1F4A56961A3B34AA009E1637 /* ObjCEndWithTest.m */, + 1F4A56991A3B3539009E1637 /* ObjCEqualTest.m */, + 1F4A569C1A3B3565009E1637 /* ObjCMatchTest.m */, + 1F4A569F1A3B359E009E1637 /* ObjCRaiseExceptionTest.m */, + 965B0D081B62B8ED0005AE66 /* ObjCUserDescriptionTest.m */, + DDEFAEB31A93CBE6005CA37A /* ObjCAllPassTest.m */, + ); + path = objc; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 1F1A74261940169200FFFC47 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1FD8CD601968AB07008ED995 /* DSL.h in Headers */, + 1FD8CD641968AB07008ED995 /* NMBExceptionCapture.h in Headers */, + 1F1A742F1940169200FFFC47 /* Nimble.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F925EAA195C0D6300ED456B /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 1FD8CD611968AB07008ED995 /* DSL.h in Headers */, + 1FD8CD651968AB07008ED995 /* NMBExceptionCapture.h in Headers */, + 1F925EC7195C0DD100ED456B /* Nimble.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 1F1A74281940169200FFFC47 /* Nimble-iOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1F1A743F1940169200FFFC47 /* Build configuration list for PBXNativeTarget "Nimble-iOS" */; + buildPhases = ( + 1F1A74241940169200FFFC47 /* Sources */, + 1F1A74251940169200FFFC47 /* Frameworks */, + 1F1A74261940169200FFFC47 /* Headers */, + 1F1A74271940169200FFFC47 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Nimble-iOS"; + productName = "Nimble-iOS"; + productReference = 1F1A74291940169200FFFC47 /* Nimble.framework */; + productType = "com.apple.product-type.framework"; + }; + 1F1A74331940169200FFFC47 /* Nimble-iOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1F1A74421940169200FFFC47 /* Build configuration list for PBXNativeTarget "Nimble-iOSTests" */; + buildPhases = ( + 1F1A74301940169200FFFC47 /* Sources */, + 1F1A74311940169200FFFC47 /* Frameworks */, + 1F1A74321940169200FFFC47 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1F1A74371940169200FFFC47 /* PBXTargetDependency */, + 1F925EA5195C0C8500ED456B /* PBXTargetDependency */, + 1F925EA7195C0C8500ED456B /* PBXTargetDependency */, + 1F6BB82B1968BFF9009F1DBB /* PBXTargetDependency */, + ); + name = "Nimble-iOSTests"; + productName = "Nimble-iOSTests"; + productReference = 1F1A74341940169200FFFC47 /* NimbleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 1F925EAC195C0D6300ED456B /* Nimble-OSX */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1F925EC0195C0D6300ED456B /* Build configuration list for PBXNativeTarget "Nimble-OSX" */; + buildPhases = ( + 1F925EA8195C0D6300ED456B /* Sources */, + 1F925EA9195C0D6300ED456B /* Frameworks */, + 1F925EAA195C0D6300ED456B /* Headers */, + 1F925EAB195C0D6300ED456B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Nimble-OSX"; + productName = "Nimble-OSX"; + productReference = 1F925EAD195C0D6300ED456B /* Nimble.framework */; + productType = "com.apple.product-type.framework"; + }; + 1F925EB6195C0D6300ED456B /* Nimble-OSXTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1F925EC3195C0D6300ED456B /* Build configuration list for PBXNativeTarget "Nimble-OSXTests" */; + buildPhases = ( + 1F925EB3195C0D6300ED456B /* Sources */, + 1F925EB4195C0D6300ED456B /* Frameworks */, + 1F925EB5195C0D6300ED456B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 1F925EBA195C0D6300ED456B /* PBXTargetDependency */, + 1F9B7BFE1968AD760094EB8F /* PBXTargetDependency */, + 1F9B7C001968AD760094EB8F /* PBXTargetDependency */, + 1F9B7C021968AD820094EB8F /* PBXTargetDependency */, + ); + name = "Nimble-OSXTests"; + productName = "Nimble-OSXTests"; + productReference = 1F925EB7195C0D6300ED456B /* NimbleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 1F1A74201940169200FFFC47 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0700; + LastUpgradeCheck = 0700; + ORGANIZATIONNAME = "Jeff Hui"; + TargetAttributes = { + 1F1A74281940169200FFFC47 = { + CreatedOnToolsVersion = 6.0; + }; + 1F1A74331940169200FFFC47 = { + CreatedOnToolsVersion = 6.0; + TestTargetID = 1F1A74281940169200FFFC47; + }; + 1F925EAC195C0D6300ED456B = { + CreatedOnToolsVersion = 6.0; + }; + 1F925EB6195C0D6300ED456B = { + CreatedOnToolsVersion = 6.0; + TestTargetID = 1F925EAC195C0D6300ED456B; + }; + }; + }; + buildConfigurationList = 1F1A74231940169200FFFC47 /* Build configuration list for PBXProject "Nimble" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 1F1A741F1940169200FFFC47; + productRefGroup = 1F1A742A1940169200FFFC47 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1F1A74281940169200FFFC47 /* Nimble-iOS */, + 1F1A74331940169200FFFC47 /* Nimble-iOSTests */, + 1F925EAC195C0D6300ED456B /* Nimble-OSX */, + 1F925EB6195C0D6300ED456B /* Nimble-OSXTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 1F1A74271940169200FFFC47 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F1A74321940169200FFFC47 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F925EAB195C0D6300ED456B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F925EB5195C0D6300ED456B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 1F1A74241940169200FFFC47 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1FD8CD401968AB07008ED995 /* BeCloseTo.swift in Sources */, + 1FD8CD741968AB07008ED995 /* MatcherFunc.swift in Sources */, + 1FD8CD361968AB07008ED995 /* Expectation.swift in Sources */, + 1FD8CD321968AB07008ED995 /* NimbleXCTestHandler.swift in Sources */, + 1F43728F1A1B344000EB80F8 /* Stringers.swift in Sources */, + 1F43728D1A1B343D00EB80F8 /* SourceLocation.swift in Sources */, + 1FD8CD4E1968AB07008ED995 /* BeLessThanOrEqual.swift in Sources */, + 1FDBD8671AF8A4FF0089F27B /* AssertionDispatcher.swift in Sources */, + 1F43728A1A1B343800EB80F8 /* Functional.swift in Sources */, + 1FD8CD3C1968AB07008ED995 /* BeAnInstanceOf.swift in Sources */, + 1FD8CD501968AB07008ED995 /* BeLogical.swift in Sources */, + 1F0FEA9A1AF32DA4001E554E /* ObjCExpectation.swift in Sources */, + 1FD8CD661968AB07008ED995 /* NMBExceptionCapture.m in Sources */, + DA9E8C821A414BB9002633C2 /* DSL+Wait.swift in Sources */, + DDB1BC791A92235600F743C3 /* AllPass.swift in Sources */, + 1FD8CD3E1968AB07008ED995 /* BeAKindOf.swift in Sources */, + DDB4D5ED19FE43C200E9D9FE /* Match.swift in Sources */, + 1FD8CD2E1968AB07008ED995 /* AssertionRecorder.swift in Sources */, + 29EA59661B551EE6002D767E /* ThrowError.swift in Sources */, + 1FD8CD5A1968AB07008ED995 /* Equal.swift in Sources */, + 1FD8CD4C1968AB07008ED995 /* BeLessThan.swift in Sources */, + 1FD8CD461968AB07008ED995 /* BeGreaterThan.swift in Sources */, + 1FD8CD301968AB07008ED995 /* AdapterProtocols.swift in Sources */, + 1FD8CD5E1968AB07008ED995 /* RaisesException.swift in Sources */, + 1FD8CD561968AB07008ED995 /* Contain.swift in Sources */, + 1FD8CD481968AB07008ED995 /* BeGreaterThanOrEqualTo.swift in Sources */, + 1FD8CD701968AB07008ED995 /* AsyncMatcherWrapper.swift in Sources */, + 1FD8CD441968AB07008ED995 /* BeginWith.swift in Sources */, + 1FD8CD4A1968AB07008ED995 /* BeIdenticalTo.swift in Sources */, + 1FD8CD621968AB07008ED995 /* DSL.m in Sources */, + 1FD8CD421968AB07008ED995 /* BeEmpty.swift in Sources */, + 1FD8CD521968AB07008ED995 /* BeNil.swift in Sources */, + 1FD8CD6A1968AB07008ED995 /* Poll.swift in Sources */, + 1FD8CD581968AB07008ED995 /* EndWith.swift in Sources */, + 1FD8CD5C1968AB07008ED995 /* MatcherProtocols.swift in Sources */, + 1FD8CD761968AB07008ED995 /* ObjCMatcher.swift in Sources */, + 1FD8CD341968AB07008ED995 /* DSL.swift in Sources */, + 1FD8CD381968AB07008ED995 /* Expression.swift in Sources */, + 1FD8CD3A1968AB07008ED995 /* FailureMessage.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F1A74301940169200FFFC47 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F4A569A1A3B3539009E1637 /* ObjCEqualTest.m in Sources */, + 1F925EEC195C12C800ED456B /* RaisesExceptionTest.swift in Sources */, + 1F925EFF195C187600ED456B /* EndWithTest.swift in Sources */, + 1F1B5AD41963E13900CA8BF9 /* BeAKindOfTest.swift in Sources */, + 1F925F0E195C18F500ED456B /* BeLessThanOrEqualToTest.swift in Sources */, + 1F4A56661A3B305F009E1637 /* ObjCAsyncTest.m in Sources */, + 1F925EFC195C186800ED456B /* BeginWithTest.swift in Sources */, + 1F14FB64194180C5009F2A08 /* utils.swift in Sources */, + DDB4D5F019FE442800E9D9FE /* MatchTest.swift in Sources */, + 1F4A56731A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */, + 1F4A56821A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */, + 1F925F02195C189500ED456B /* ContainTest.swift in Sources */, + 1F4A56881A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */, + 1F4A568E1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */, + 1F925F11195C190B00ED456B /* BeGreaterThanOrEqualToTest.swift in Sources */, + 1F925EEF195C136500ED456B /* BeLogicalTest.swift in Sources */, + 1F4A56A01A3B359E009E1637 /* ObjCRaiseExceptionTest.m in Sources */, + 1F925F0B195C18E100ED456B /* BeLessThanTest.swift in Sources */, + 1F9DB8FB1A74E793002E96AD /* ObjCBeEmptyTest.m in Sources */, + 1FB90098195EC4B8001D7FAE /* BeIdenticalToTest.swift in Sources */, + 1F4A56761A3B3253009E1637 /* ObjCBeGreaterThanTest.m in Sources */, + 1F925EF9195C175000ED456B /* BeNilTest.swift in Sources */, + 1F4A56701A3B319F009E1637 /* ObjCBeCloseToTest.m in Sources */, + 1F4A56971A3B34AA009E1637 /* ObjCEndWithTest.m in Sources */, + 1F4A567C1A3B3311009E1637 /* ObjCBeIdenticalToTest.m in Sources */, + 965B0D0C1B62C06D0005AE66 /* UserDescriptionTest.swift in Sources */, + 965B0D091B62B8ED0005AE66 /* ObjCUserDescriptionTest.m in Sources */, + 1F4A56911A3B344A009E1637 /* ObjCBeNilTest.m in Sources */, + 1F8A37B01B7C5042001C8357 /* ObjCSyncTest.m in Sources */, + 1F4A56941A3B346F009E1637 /* ObjCContainTest.m in Sources */, + 1F299EAB19627B2D002641AF /* BeEmptyTest.swift in Sources */, + 1F925EF6195C147800ED456B /* BeCloseToTest.swift in Sources */, + 1F4A56791A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m in Sources */, + 1F4A568B1A3B3407009E1637 /* ObjCBeTrueTest.m in Sources */, + DDEFAEB41A93CBE6005CA37A /* ObjCAllPassTest.m in Sources */, + 1F4A567F1A3B333F009E1637 /* ObjCBeLessThanTest.m in Sources */, + 1F925EE6195C121200ED456B /* AsynchronousTest.swift in Sources */, + 1F0648CC19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */, + 1F4A56851A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */, + DD9A9A8F19CF439B00706F49 /* BeIdenticalToObjectTest.swift in Sources */, + 1F0648D41963AAB2001F9C46 /* SynchronousTests.swift in Sources */, + 1F925F08195C18CF00ED456B /* BeGreaterThanTest.swift in Sources */, + 1F925F05195C18B700ED456B /* EqualTest.swift in Sources */, + 1F4A566D1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */, + DD72EC641A93874A002F7651 /* AllPassTest.swift in Sources */, + 1F4A569D1A3B3565009E1637 /* ObjCMatchTest.m in Sources */, + 1F925EE9195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */, + 29EA59631B551ED2002D767E /* ThrowErrorTest.swift in Sources */, + 1F4A566A1A3B3108009E1637 /* ObjCBeAnInstanceOfTest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F925EA8195C0D6300ED456B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1FD8CD411968AB07008ED995 /* BeCloseTo.swift in Sources */, + 1FD8CD751968AB07008ED995 /* MatcherFunc.swift in Sources */, + 1FD8CD371968AB07008ED995 /* Expectation.swift in Sources */, + 1FD8CD331968AB07008ED995 /* NimbleXCTestHandler.swift in Sources */, + 1F43728E1A1B343F00EB80F8 /* Stringers.swift in Sources */, + 1F43728C1A1B343C00EB80F8 /* SourceLocation.swift in Sources */, + 1FD8CD4F1968AB07008ED995 /* BeLessThanOrEqual.swift in Sources */, + 1FDBD8681AF8A4FF0089F27B /* AssertionDispatcher.swift in Sources */, + 1F43728B1A1B343900EB80F8 /* Functional.swift in Sources */, + 1FD8CD3D1968AB07008ED995 /* BeAnInstanceOf.swift in Sources */, + 1FD8CD511968AB07008ED995 /* BeLogical.swift in Sources */, + 1F0FEA9B1AF32DA4001E554E /* ObjCExpectation.swift in Sources */, + 1FD8CD671968AB07008ED995 /* NMBExceptionCapture.m in Sources */, + DA9E8C831A414BB9002633C2 /* DSL+Wait.swift in Sources */, + DDB1BC7A1A92235600F743C3 /* AllPass.swift in Sources */, + 1FD8CD3F1968AB07008ED995 /* BeAKindOf.swift in Sources */, + 1FD8CD2F1968AB07008ED995 /* AssertionRecorder.swift in Sources */, + DDB4D5EE19FE43C200E9D9FE /* Match.swift in Sources */, + 29EA59671B551EE6002D767E /* ThrowError.swift in Sources */, + 1FD8CD5B1968AB07008ED995 /* Equal.swift in Sources */, + 1FD8CD4D1968AB07008ED995 /* BeLessThan.swift in Sources */, + 1FD8CD471968AB07008ED995 /* BeGreaterThan.swift in Sources */, + 1FD8CD311968AB07008ED995 /* AdapterProtocols.swift in Sources */, + 1FD8CD5F1968AB07008ED995 /* RaisesException.swift in Sources */, + 1FD8CD571968AB07008ED995 /* Contain.swift in Sources */, + 1FD8CD491968AB07008ED995 /* BeGreaterThanOrEqualTo.swift in Sources */, + 1FD8CD711968AB07008ED995 /* AsyncMatcherWrapper.swift in Sources */, + 1FD8CD451968AB07008ED995 /* BeginWith.swift in Sources */, + 1FD8CD4B1968AB07008ED995 /* BeIdenticalTo.swift in Sources */, + 1FD8CD631968AB07008ED995 /* DSL.m in Sources */, + 1FD8CD431968AB07008ED995 /* BeEmpty.swift in Sources */, + 1FD8CD531968AB07008ED995 /* BeNil.swift in Sources */, + 1FD8CD6B1968AB07008ED995 /* Poll.swift in Sources */, + 1FD8CD591968AB07008ED995 /* EndWith.swift in Sources */, + 1FD8CD5D1968AB07008ED995 /* MatcherProtocols.swift in Sources */, + 1FD8CD771968AB07008ED995 /* ObjCMatcher.swift in Sources */, + 1FD8CD351968AB07008ED995 /* DSL.swift in Sources */, + 1FD8CD391968AB07008ED995 /* Expression.swift in Sources */, + 1FD8CD3B1968AB07008ED995 /* FailureMessage.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 1F925EB3195C0D6300ED456B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 1F4A569B1A3B3539009E1637 /* ObjCEqualTest.m in Sources */, + 1F925EED195C12C800ED456B /* RaisesExceptionTest.swift in Sources */, + 1F925F00195C187600ED456B /* EndWithTest.swift in Sources */, + 1F1B5AD51963E13900CA8BF9 /* BeAKindOfTest.swift in Sources */, + 1F925F0F195C18F500ED456B /* BeLessThanOrEqualToTest.swift in Sources */, + 1F4A56671A3B305F009E1637 /* ObjCAsyncTest.m in Sources */, + 1F925EFD195C186800ED456B /* BeginWithTest.swift in Sources */, + 1F925EE2195C0DFD00ED456B /* utils.swift in Sources */, + DDB4D5F119FE442800E9D9FE /* MatchTest.swift in Sources */, + 1F4A56741A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */, + 1F4A56831A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */, + 1F925F03195C189500ED456B /* ContainTest.swift in Sources */, + 1F4A56891A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */, + 1F4A568F1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */, + 1F925F12195C190B00ED456B /* BeGreaterThanOrEqualToTest.swift in Sources */, + 1F925EF0195C136500ED456B /* BeLogicalTest.swift in Sources */, + 1F4A56A11A3B359E009E1637 /* ObjCRaiseExceptionTest.m in Sources */, + 1F925F0C195C18E100ED456B /* BeLessThanTest.swift in Sources */, + 1F9DB8FC1A74E793002E96AD /* ObjCBeEmptyTest.m in Sources */, + 1FB90099195EC4B8001D7FAE /* BeIdenticalToTest.swift in Sources */, + 1F4A56771A3B3253009E1637 /* ObjCBeGreaterThanTest.m in Sources */, + 1F925EFA195C175000ED456B /* BeNilTest.swift in Sources */, + 1F4A56711A3B319F009E1637 /* ObjCBeCloseToTest.m in Sources */, + 1F4A56981A3B34AA009E1637 /* ObjCEndWithTest.m in Sources */, + 1F4A567D1A3B3311009E1637 /* ObjCBeIdenticalToTest.m in Sources */, + 965B0D0D1B62C06D0005AE66 /* UserDescriptionTest.swift in Sources */, + 965B0D0A1B62B8ED0005AE66 /* ObjCUserDescriptionTest.m in Sources */, + 1F4A56921A3B344A009E1637 /* ObjCBeNilTest.m in Sources */, + 1F8A37B11B7C5042001C8357 /* ObjCSyncTest.m in Sources */, + 1F4A56951A3B346F009E1637 /* ObjCContainTest.m in Sources */, + 1F299EAC19627B2D002641AF /* BeEmptyTest.swift in Sources */, + 1F925EF7195C147800ED456B /* BeCloseToTest.swift in Sources */, + 1F4A567A1A3B32E3009E1637 /* ObjCBeGreaterThanOrEqualToTest.m in Sources */, + 1F4A568C1A3B3407009E1637 /* ObjCBeTrueTest.m in Sources */, + DDEFAEB51A93CBE6005CA37A /* ObjCAllPassTest.m in Sources */, + 1F4A56801A3B333F009E1637 /* ObjCBeLessThanTest.m in Sources */, + 1F925EE7195C121200ED456B /* AsynchronousTest.swift in Sources */, + 1F0648CD19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */, + 1F4A56861A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */, + DD9A9A9019CF43AD00706F49 /* BeIdenticalToObjectTest.swift in Sources */, + 1F0648D51963AAB2001F9C46 /* SynchronousTests.swift in Sources */, + 1F925F09195C18CF00ED456B /* BeGreaterThanTest.swift in Sources */, + 1F925F06195C18B700ED456B /* EqualTest.swift in Sources */, + 1F4A566E1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */, + DD72EC651A93874A002F7651 /* AllPassTest.swift in Sources */, + 1F4A569E1A3B3565009E1637 /* ObjCMatchTest.m in Sources */, + 1F925EEA195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */, + 29EA59641B551ED2002D767E /* ThrowErrorTest.swift in Sources */, + 1F4A566B1A3B3108009E1637 /* ObjCBeAnInstanceOfTest.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 1F1A74371940169200FFFC47 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F1A74281940169200FFFC47 /* Nimble-iOS */; + targetProxy = 1F1A74361940169200FFFC47 /* PBXContainerItemProxy */; + }; + 1F6BB82B1968BFF9009F1DBB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F1A74281940169200FFFC47 /* Nimble-iOS */; + targetProxy = 1F6BB82A1968BFF9009F1DBB /* PBXContainerItemProxy */; + }; + 1F925EA5195C0C8500ED456B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F1A74281940169200FFFC47 /* Nimble-iOS */; + targetProxy = 1F925EA4195C0C8500ED456B /* PBXContainerItemProxy */; + }; + 1F925EA7195C0C8500ED456B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F1A74281940169200FFFC47 /* Nimble-iOS */; + targetProxy = 1F925EA6195C0C8500ED456B /* PBXContainerItemProxy */; + }; + 1F925EBA195C0D6300ED456B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F925EAC195C0D6300ED456B /* Nimble-OSX */; + targetProxy = 1F925EB9195C0D6300ED456B /* PBXContainerItemProxy */; + }; + 1F9B7BFE1968AD760094EB8F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F925EAC195C0D6300ED456B /* Nimble-OSX */; + targetProxy = 1F9B7BFD1968AD760094EB8F /* PBXContainerItemProxy */; + }; + 1F9B7C001968AD760094EB8F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F925EAC195C0D6300ED456B /* Nimble-OSX */; + targetProxy = 1F9B7BFF1968AD760094EB8F /* PBXContainerItemProxy */; + }; + 1F9B7C021968AD820094EB8F /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F925EAC195C0D6300ED456B /* Nimble-OSX */; + targetProxy = 1F9B7C011968AD820094EB8F /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 1F1A743D1940169200FFFC47 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_MODULES_AUTOLINK = NO; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + ENABLE_BITCODE = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + METAL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2,3"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 1F1A743E1940169200FFFC47 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_MODULES_AUTOLINK = NO; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + CURRENT_PROJECT_VERSION = 1; + ENABLE_BITCODE = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + METAL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2,3"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 1F1A74401940169200FFFC47 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + INFOPLIST_FILE = Nimble/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + ONLY_ACTIVE_ARCH = NO; + OTHER_LDFLAGS = ( + "-weak_framework", + XCTest, + "-weak-lswiftXCTest", + ); + PRODUCT_MODULE_NAME = Nimble; + PRODUCT_NAME = Nimble; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos"; + SWIFT_OBJC_BRIDGING_HEADER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 1F1A74411940169200FFFC47 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + ); + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + INFOPLIST_FILE = Nimble/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + OTHER_LDFLAGS = ( + "-weak_framework", + XCTest, + "-weak-lswiftXCTest", + ); + PRODUCT_MODULE_NAME = Nimble; + PRODUCT_NAME = Nimble; + SKIP_INSTALL = YES; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos"; + SWIFT_OBJC_BRIDGING_HEADER = ""; + }; + name = Release; + }; + 1F1A74431940169200FFFC47 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = NimbleTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + METAL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = NimbleTests; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos"; + SWIFT_OBJC_BRIDGING_HEADER = "NimbleTests/objc/NimbleTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 1F1A74441940169200FFFC47 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = NimbleTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + METAL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = NimbleTests; + SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvsimulator appletvos"; + SWIFT_OBJC_BRIDGING_HEADER = "NimbleTests/objc/NimbleTests-Bridging-Header.h"; + }; + name = Release; + }; + 1F925EC1195C0D6300ED456B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + FRAMEWORK_VERSION = A; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + INFOPLIST_FILE = Nimble/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + METAL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ( + "-weak_framework", + XCTest, + "-weak-lswiftXCTest", + ); + PRODUCT_MODULE_NAME = Nimble; + PRODUCT_NAME = Nimble; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + VALID_ARCHS = x86_64; + }; + name = Debug; + }; + 1F925EC2195C0D6300ED456B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(PLATFORM_DIR)/Developer/Library/Frameworks", + "$(DEVELOPER_FRAMEWORKS_DIR)", + ); + FRAMEWORK_VERSION = A; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + INFOPLIST_FILE = Nimble/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + METAL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ( + "-weak_framework", + XCTest, + "-weak-lswiftXCTest", + ); + PRODUCT_MODULE_NAME = Nimble; + PRODUCT_NAME = Nimble; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SWIFT_OBJC_BRIDGING_HEADER = ""; + VALID_ARCHS = x86_64; + }; + name = Release; + }; + 1F925EC4195C0D6300ED456B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = NimbleTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + METAL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = NimbleTests; + SDKROOT = macosx; + SWIFT_OBJC_BRIDGING_HEADER = "NimbleTests/objc/Nimble-OSXTests-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 1F925EC5195C0D6300ED456B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + INFOPLIST_FILE = NimbleTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.9; + METAL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = NimbleTests; + SDKROOT = macosx; + SWIFT_OBJC_BRIDGING_HEADER = "NimbleTests/objc/Nimble-OSXTests-Bridging-Header.h"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1F1A74231940169200FFFC47 /* Build configuration list for PBXProject "Nimble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1F1A743D1940169200FFFC47 /* Debug */, + 1F1A743E1940169200FFFC47 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1F1A743F1940169200FFFC47 /* Build configuration list for PBXNativeTarget "Nimble-iOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1F1A74401940169200FFFC47 /* Debug */, + 1F1A74411940169200FFFC47 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1F1A74421940169200FFFC47 /* Build configuration list for PBXNativeTarget "Nimble-iOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1F1A74431940169200FFFC47 /* Debug */, + 1F1A74441940169200FFFC47 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1F925EC0195C0D6300ED456B /* Build configuration list for PBXNativeTarget "Nimble-OSX" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1F925EC1195C0D6300ED456B /* Debug */, + 1F925EC2195C0D6300ED456B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1F925EC3195C0D6300ED456B /* Build configuration list for PBXNativeTarget "Nimble-OSXTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1F925EC4195C0D6300ED456B /* Debug */, + 1F925EC5195C0D6300ED456B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 1F1A74201940169200FFFC47 /* Project object */; +} diff --git a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..a822b747 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-OSX.xcscheme b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-OSX.xcscheme new file mode 100644 index 00000000..4e2d38bd --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-OSX.xcscheme @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-iOS.xcscheme b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-iOS.xcscheme new file mode 100644 index 00000000..79af4922 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-iOS.xcscheme @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Carthage/Checkouts/Nimble/Nimble/Adapters/AdapterProtocols.swift b/Carthage/Checkouts/Nimble/Nimble/Adapters/AdapterProtocols.swift new file mode 100644 index 00000000..306d4ce6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Adapters/AdapterProtocols.swift @@ -0,0 +1,17 @@ +import Foundation + +/// Protocol for the assertion handler that Nimble uses for all expectations. +public protocol AssertionHandler { + func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) +} + +/// Global backing interface for assertions that Nimble creates. +/// Defaults to a private test handler that passes through to XCTest. +/// +/// If XCTest is not available, you must assign your own assertion handler +/// before using any matchers, otherwise Nimble will abort the program. +/// +/// @see AssertionHandler +public var NimbleAssertionHandler: AssertionHandler = { () -> AssertionHandler in + return isXCTestAvailable() ? NimbleXCTestHandler() : NimbleXCTestUnavailableHandler() +}() diff --git a/Carthage/Checkouts/Nimble/Nimble/Adapters/AssertionDispatcher.swift b/Carthage/Checkouts/Nimble/Nimble/Adapters/AssertionDispatcher.swift new file mode 100644 index 00000000..09caf2aa --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Adapters/AssertionDispatcher.swift @@ -0,0 +1,20 @@ + +/// AssertionDispatcher allows multiple AssertionHandlers to receive +/// assertion messages. +/// +/// @warning Does not fully dispatch if one of the handlers raises an exception. +/// This is possible with XCTest-based assertion handlers. +/// +public class AssertionDispatcher: AssertionHandler { + let handlers: [AssertionHandler] + + public init(handlers: [AssertionHandler]) { + self.handlers = handlers + } + + public func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) { + for handler in handlers { + handler.assert(assertion, message: message, location: location) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Adapters/AssertionRecorder.swift b/Carthage/Checkouts/Nimble/Nimble/Adapters/AssertionRecorder.swift new file mode 100644 index 00000000..4709942d --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Adapters/AssertionRecorder.swift @@ -0,0 +1,99 @@ +import Foundation + +/// A data structure that stores information about an assertion when +/// AssertionRecorder is set as the Nimble assertion handler. +/// +/// @see AssertionRecorder +/// @see AssertionHandler +public struct AssertionRecord: CustomStringConvertible { + /// Whether the assertion succeeded or failed + public let success: Bool + /// The failure message the assertion would display on failure. + public let message: FailureMessage + /// The source location the expectation occurred on. + public let location: SourceLocation + + public var description: String { + return "AssertionRecord { success=\(success), message='\(message.stringValue)', location=\(location) }" + } +} + +/// An AssertionHandler that silently records assertions that Nimble makes. +/// This is useful for testing failure messages for matchers. +/// +/// @see AssertionHandler +public class AssertionRecorder : AssertionHandler { + /// All the assertions that were captured by this recorder + public var assertions = [AssertionRecord]() + + public init() {} + + public func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) { + assertions.append( + AssertionRecord( + success: assertion, + message: message, + location: location)) + } +} + +/// Allows you to temporarily replace the current Nimble assertion handler with +/// the one provided for the scope of the closure. +/// +/// Once the closure finishes, then the original Nimble assertion handler is restored. +/// +/// @see AssertionHandler +public func withAssertionHandler(tempAssertionHandler: AssertionHandler, closure: () throws -> Void) { + let oldRecorder = NimbleAssertionHandler + let capturer = NMBExceptionCapture(handler: nil, finally: ({ + NimbleAssertionHandler = oldRecorder + })) + NimbleAssertionHandler = tempAssertionHandler + capturer.tryBlock { + try! closure() + } +} + +/// Captures expectations that occur in the given closure. Note that all +/// expectations will still go through to the default Nimble handler. +/// +/// This can be useful if you want to gather information about expectations +/// that occur within a closure. +/// +/// @param silently expectations are no longer send to the default Nimble +/// assertion handler when this is true. Defaults to false. +/// +/// @see gatherFailingExpectations +public func gatherExpectations(silently silently: Bool = false, closure: () -> Void) -> [AssertionRecord] { + let previousRecorder = NimbleAssertionHandler + let recorder = AssertionRecorder() + let handlers: [AssertionHandler] + + if silently { + handlers = [recorder] + } else { + handlers = [recorder, previousRecorder] + } + + let dispatcher = AssertionDispatcher(handlers: handlers) + withAssertionHandler(dispatcher, closure: closure) + return recorder.assertions +} + +/// Captures failed expectations that occur in the given closure. Note that all +/// expectations will still go through to the default Nimble handler. +/// +/// This can be useful if you want to gather information about failed +/// expectations that occur within a closure. +/// +/// @param silently expectations are no longer send to the default Nimble +/// assertion handler when this is true. Defaults to false. +/// +/// @see gatherExpectations +/// @see raiseException source for an example use case. +public func gatherFailingExpectations(silently silently: Bool = false, closure: () -> Void) -> [AssertionRecord] { + let assertions = gatherExpectations(silently: silently, closure: closure) + return assertions.filter { assertion in + !assertion.success + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Adapters/NimbleXCTestHandler.swift b/Carthage/Checkouts/Nimble/Nimble/Adapters/NimbleXCTestHandler.swift new file mode 100644 index 00000000..12d19440 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Adapters/NimbleXCTestHandler.swift @@ -0,0 +1,40 @@ +import Foundation +import XCTest + +/// Default handler for Nimble. This assertion handler passes failures along to +/// XCTest. +public class NimbleXCTestHandler : AssertionHandler { + public func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) { + if !assertion { + XCTFail("\(message.stringValue)\n", file: location.file, line: location.line) + } + } +} + +/// Alternative handler for Nimble. This assertion handler passes failures along +/// to XCTest by attempting to reduce the failure message size. +public class NimbleShortXCTestHandler: AssertionHandler { + public func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) { + if !assertion { + let msg: String + if let actual = message.actualValue { + msg = "got: \(actual) \(message.postfixActual)" + } else { + msg = "expected \(message.to) \(message.postfixMessage)" + } + XCTFail("\(msg)\n", file: location.file, line: location.line) + } + } +} + +/// Fallback handler in case XCTest is unavailable. This assertion handler will abort +/// the program if it is invoked. +class NimbleXCTestUnavailableHandler : AssertionHandler { + func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) { + fatalError("XCTest is not available and no custom assertion handler was configured. Aborting.") + } +} + +func isXCTestAvailable() -> Bool { + return NSClassFromString("XCTestCase") != nil +} diff --git a/Carthage/Checkouts/Nimble/Nimble/DSL+Wait.swift b/Carthage/Checkouts/Nimble/Nimble/DSL+Wait.swift new file mode 100644 index 00000000..3f189dc7 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/DSL+Wait.swift @@ -0,0 +1,50 @@ +import Foundation + +/// Only classes, protocols, methods, properties, and subscript declarations can be +/// bridges to Objective-C via the @objc keyword. This class encapsulates callback-style +/// asynchronous waiting logic so that it may be called from Objective-C and Swift. +internal class NMBWait: NSObject { + internal class func until(timeout timeout: NSTimeInterval, file: String = __FILE__, line: UInt = __LINE__, action: (() -> Void) -> Void) -> Void { + var completed = false + var token: dispatch_once_t = 0 + let result = pollBlock(pollInterval: 0.01, timeoutInterval: timeout) { + dispatch_once(&token) { + dispatch_async(dispatch_get_main_queue()) { + action() { completed = true } + } + } + return completed + } + switch (result) { + case .Failure: + let pluralize = (timeout == 1 ? "" : "s") + fail("Waited more than \(timeout) second\(pluralize)", file: file, line: line) + case .Timeout: + fail("Stall on main thread - too much enqueued on main run loop before waitUntil executes.", file: file, line: line) + case let .ErrorThrown(error): + // Technically, we can never reach this via a public API call + fail("Unexpected error thrown: \(error)", file: file, line: line) + case .Success: + break + } + } + + @objc(untilFile:line:action:) + internal class func until(file: String = __FILE__, line: UInt = __LINE__, action: (() -> Void) -> Void) -> Void { + until(timeout: 1, file: file, line: line, action: action) + } +} + +/// Wait asynchronously until the done closure is called. +/// +/// This will advance the run loop. +public func waitUntil(timeout timeout: NSTimeInterval, file: String = __FILE__, line: UInt = __LINE__, action: (() -> Void) -> Void) -> Void { + NMBWait.until(timeout: timeout, file: file, line: line, action: action) +} + +/// Wait asynchronously until the done closure is called. +/// +/// This will advance the run loop. +public func waitUntil(file: String = __FILE__, line: UInt = __LINE__, action: (() -> Void) -> Void) -> Void { + NMBWait.until(timeout: 1, file: file, line: line, action: action) +} \ No newline at end of file diff --git a/Carthage/Checkouts/Nimble/Nimble/DSL.swift b/Carthage/Checkouts/Nimble/Nimble/DSL.swift new file mode 100644 index 00000000..98c60baa --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/DSL.swift @@ -0,0 +1,32 @@ +/// Make an expectation on a given actual value. The value given is lazily evaluated. +public func expect(@autoclosure(escaping) expression: () throws -> T?, file: String = __FILE__, line: UInt = __LINE__) -> Expectation { + return Expectation( + expression: Expression( + expression: expression, + location: SourceLocation(file: file, line: line), + isClosure: true)) +} + +/// Make an expectation on a given actual value. The closure is lazily invoked. +public func expect(file: String = __FILE__, line: UInt = __LINE__, expression: () throws -> T?) -> Expectation { + return Expectation( + expression: Expression( + expression: expression, + location: SourceLocation(file: file, line: line), + isClosure: true)) +} + +/// Always fails the test with a message and a specified location. +public func fail(message: String, location: SourceLocation) { + NimbleAssertionHandler.assert(false, message: FailureMessage(stringValue: message), location: location) +} + +/// Always fails the test with a message. +public func fail(message: String, file: String = __FILE__, line: UInt = __LINE__) { + fail(message, location: SourceLocation(file: file, line: line)) +} + +/// Always fails the test. +public func fail(file: String = __FILE__, line: UInt = __LINE__) { + fail("fail() always fails", file: file, line: line) +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Expectation.swift b/Carthage/Checkouts/Nimble/Nimble/Expectation.swift new file mode 100644 index 00000000..dcf1a92a --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Expectation.swift @@ -0,0 +1,64 @@ +import Foundation + +internal func expressionMatches(expression: Expression, matcher: U, to: String, description: String?) -> (Bool, FailureMessage) { + let msg = FailureMessage() + msg.userDescription = description + msg.to = to + do { + let pass = try matcher.matches(expression, failureMessage: msg) + if msg.actualValue == "" { + msg.actualValue = "<\(stringify(try expression.evaluate()))>" + } + return (pass, msg) + } catch let error { + msg.actualValue = "an unexpected error thrown: <\(error)>" + return (false, msg) + } +} + +internal func expressionDoesNotMatch(expression: Expression, matcher: U, toNot: String, description: String?) -> (Bool, FailureMessage) { + let msg = FailureMessage() + msg.userDescription = description + msg.to = toNot + do { + let pass = try matcher.doesNotMatch(expression, failureMessage: msg) + if msg.actualValue == "" { + msg.actualValue = "<\(stringify(try expression.evaluate()))>" + } + return (pass, msg) + } catch let error { + msg.actualValue = "an unexpected error thrown: <\(error)>" + return (false, msg) + } +} + +public struct Expectation { + let expression: Expression + + public func verify(pass: Bool, _ message: FailureMessage) { + NimbleAssertionHandler.assert(pass, message: message, location: expression.location) + } + + /// Tests the actual value using a matcher to match. + public func to(matcher: U, description: String? = nil) { + let (pass, msg) = expressionMatches(expression, matcher: matcher, to: "to", description: description) + verify(pass, msg) + } + + /// Tests the actual value using a matcher to not match. + public func toNot(matcher: U, description: String? = nil) { + let (pass, msg) = expressionDoesNotMatch(expression, matcher: matcher, toNot: "to not", description: description) + verify(pass, msg) + } + + /// Tests the actual value using a matcher to not match. + /// + /// Alias to toNot(). + public func notTo(matcher: U, description: String? = nil) { + toNot(matcher, description: description) + } + + // see: + // - AsyncMatcherWrapper for extension + // - NMBExpectation for Objective-C interface +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Expression.swift b/Carthage/Checkouts/Nimble/Nimble/Expression.swift new file mode 100644 index 00000000..f64ee245 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Expression.swift @@ -0,0 +1,90 @@ +import Foundation + +// Memoizes the given closure, only calling the passed +// closure once; even if repeat calls to the returned closure +internal func memoizedClosure(closure: () throws -> T) -> (Bool) throws -> T { + var cache: T? + return ({ withoutCaching in + if (withoutCaching || cache == nil) { + cache = try closure() + } + return cache! + }) +} + +/// Expression represents the closure of the value inside expect(...). +/// Expressions are memoized by default. This makes them safe to call +/// evaluate() multiple times without causing a re-evaluation of the underlying +/// closure. +/// +/// @warning Since the closure can be any code, Objective-C code may choose +/// to raise an exception. Currently, Expression does not memoize +/// exception raising. +/// +/// This provides a common consumable API for matchers to utilize to allow +/// Nimble to change internals to how the captured closure is managed. +public struct Expression { + internal let _expression: (Bool) throws -> T? + internal let _withoutCaching: Bool + public let location: SourceLocation + public let isClosure: Bool + + /// Creates a new expression struct. Normally, expect(...) will manage this + /// creation process. The expression is memoized. + /// + /// @param expression The closure that produces a given value. + /// @param location The source location that this closure originates from. + /// @param isClosure A bool indicating if the captured expression is a + /// closure or internally produced closure. Some matchers + /// may require closures. For example, toEventually() + /// requires an explicit closure. This gives Nimble + /// flexibility if @autoclosure behavior changes between + /// Swift versions. Nimble internals always sets this true. + public init(expression: () throws -> T?, location: SourceLocation, isClosure: Bool = true) { + self._expression = memoizedClosure(expression) + self.location = location + self._withoutCaching = false + self.isClosure = isClosure + } + + /// Creates a new expression struct. Normally, expect(...) will manage this + /// creation process. + /// + /// @param expression The closure that produces a given value. + /// @param location The source location that this closure originates from. + /// @param withoutCaching Indicates if the struct should memoize the given + /// closure's result. Subsequent evaluate() calls will + /// not call the given closure if this is true. + /// @param isClosure A bool indicating if the captured expression is a + /// closure or internally produced closure. Some matchers + /// may require closures. For example, toEventually() + /// requires an explicit closure. This gives Nimble + /// flexibility if @autoclosure behavior changes between + /// Swift versions. Nimble internals always sets this true. + public init(memoizedExpression: (Bool) throws -> T?, location: SourceLocation, withoutCaching: Bool, isClosure: Bool = true) { + self._expression = memoizedExpression + self.location = location + self._withoutCaching = withoutCaching + self.isClosure = isClosure + } + + /// Returns a new Expression from the given expression. Identical to a map() + /// on this type. This should be used only to typecast the Expression's + /// closure value. + /// + /// The returned expression will preserve location and isClosure. + /// + /// @param block The block that can cast the current Expression value to a + /// new type. + public func cast(block: (T?) throws -> U?) -> Expression { + return Expression(expression: ({ try block(self.evaluate()) }), location: self.location, isClosure: self.isClosure) + } + + public func evaluate() throws -> T? { + return try self._expression(_withoutCaching) + } + + public func withoutCaching() -> Expression { + return Expression(memoizedExpression: self._expression, location: location, withoutCaching: true, isClosure: isClosure) + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/FailureMessage.swift b/Carthage/Checkouts/Nimble/Nimble/FailureMessage.swift new file mode 100644 index 00000000..e59dacc6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/FailureMessage.swift @@ -0,0 +1,56 @@ +import Foundation + +/// Encapsulates the failure message that matchers can report to the end user. +/// +/// This is shared state between Nimble and matchers that mutate this value. +public class FailureMessage: NSObject { + public var expected: String = "expected" + public var actualValue: String? = "" // empty string -> use default; nil -> exclude + public var to: String = "to" + public var postfixMessage: String = "match" + public var postfixActual: String = "" + public var userDescription: String? = nil + + public var stringValue: String { + get { + if let value = _stringValueOverride { + return value + } else { + return computeStringValue() + } + } + set { + _stringValueOverride = newValue + } + } + + internal var _stringValueOverride: String? + + public override init() { + } + + public init(stringValue: String) { + _stringValueOverride = stringValue + } + + internal func stripNewlines(str: String) -> String { + var lines: [String] = (str as NSString).componentsSeparatedByString("\n") as [String] + let whitespace = NSCharacterSet.whitespaceAndNewlineCharacterSet() + lines = lines.map { line in line.stringByTrimmingCharactersInSet(whitespace) } + return lines.joinWithSeparator("") + } + + internal func computeStringValue() -> String { + var value = "\(expected) \(to) \(postfixMessage)" + if let actualValue = actualValue { + value = "\(expected) \(to) \(postfixMessage), got \(actualValue)\(postfixActual)" + } + value = stripNewlines(value) + + if let userDescription = userDescription { + return "\(userDescription)\n\(value)" + } + + return value + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/Nimble/Nimble/Info.plist b/Carthage/Checkouts/Nimble/Nimble/Info.plist new file mode 100644 index 00000000..dc2994cd --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + net.jeffhui.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + NSHumanReadableCopyright + Copyright © 2014 Jeff Hui. All rights reserved. + + diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/AllPass.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/AllPass.swift new file mode 100644 index 00000000..075b7ac6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/AllPass.swift @@ -0,0 +1,90 @@ +import Foundation + +public func allPass + (passFunc: (T?) -> Bool) -> NonNilMatcherFunc { + return allPass("pass a condition", passFunc) +} + +public func allPass + (passName: String, _ passFunc: (T?) -> Bool) -> NonNilMatcherFunc { + return createAllPassMatcher() { + expression, failureMessage in + failureMessage.postfixMessage = passName + return passFunc(try expression.evaluate()) + } +} + +public func allPass + (matcher: V) -> NonNilMatcherFunc { + return createAllPassMatcher() { + try matcher.matches($0, failureMessage: $1) + } +} + +private func createAllPassMatcher + (elementEvaluator:(Expression, FailureMessage) throws -> Bool) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.actualValue = nil + if let actualValue = try actualExpression.evaluate() { + for currentElement in actualValue { + let exp = Expression( + expression: {currentElement}, location: actualExpression.location) + if try !elementEvaluator(exp, failureMessage) { + failureMessage.postfixMessage = + "all \(failureMessage.postfixMessage)," + + " but failed first at element <\(stringify(currentElement))>" + + " in <\(stringify(actualValue))>" + return false + } + } + failureMessage.postfixMessage = "all \(failureMessage.postfixMessage)" + } else { + failureMessage.postfixMessage = "all pass (use beNil() to match nils)" + return false + } + + return true + } +} + +extension NMBObjCMatcher { + public class func allPassMatcher(matcher: NMBObjCMatcher) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let location = actualExpression.location + let actualValue = try! actualExpression.evaluate() + var nsObjects = [NSObject]() + + var collectionIsUsable = true + if let value = actualValue as? NSFastEnumeration { + let generator = NSFastGenerator(value) + while let obj:AnyObject = generator.next() { + if let nsObject = obj as? NSObject { + nsObjects.append(nsObject) + } else { + collectionIsUsable = false + break + } + } + } else { + collectionIsUsable = false + } + + if !collectionIsUsable { + failureMessage.postfixMessage = + "allPass only works with NSFastEnumeration (NSArray, NSSet, ...) of NSObjects" + failureMessage.expected = "" + failureMessage.to = "" + return false + } + + let expr = Expression(expression: ({ nsObjects }), location: location) + let elementEvaluator: (Expression, FailureMessage) -> Bool = { + expression, failureMessage in + return matcher.matches( + {try! expression.evaluate()}, failureMessage: failureMessage, location: expr.location) + } + return try! createAllPassMatcher(elementEvaluator).matches( + expr, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeAKindOf.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeAKindOf.swift new file mode 100644 index 00000000..b3f7338f --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeAKindOf.swift @@ -0,0 +1,34 @@ +import Foundation + +// A Nimble matcher that catches attempts to use beAKindOf with non Objective-C types +public func beAKindOf(expectedClass: Any) -> NonNilMatcherFunc { + return NonNilMatcherFunc {actualExpression, failureMessage in + failureMessage.stringValue = "beAKindOf only works on Objective-C types since" + + " the Swift compiler will automatically type check Swift-only types." + + " This expectation is redundant." + return false + } +} + +/// A Nimble matcher that succeeds when the actual value is an instance of the given class. +/// @see beAnInstanceOf if you want to match against the exact class +public func beAKindOf(expectedClass: AnyClass) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + let instance = try actualExpression.evaluate() + if let validInstance = instance { + failureMessage.actualValue = "<\(NSStringFromClass(validInstance.dynamicType)) instance>" + } else { + failureMessage.actualValue = "" + } + failureMessage.postfixMessage = "be a kind of \(NSStringFromClass(expectedClass))" + return instance != nil && instance!.isKindOfClass(expectedClass) + } +} + +extension NMBObjCMatcher { + public class func beAKindOfMatcher(expected: AnyClass) -> NMBMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + return try! beAKindOf(expected).matches(actualExpression, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeAnInstanceOf.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeAnInstanceOf.swift new file mode 100644 index 00000000..e65948b9 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeAnInstanceOf.swift @@ -0,0 +1,34 @@ +import Foundation + +// A Nimble matcher that catches attempts to use beAnInstanceOf with non Objective-C types +public func beAnInstanceOf(expectedClass: Any) -> NonNilMatcherFunc { + return NonNilMatcherFunc {actualExpression, failureMessage in + failureMessage.stringValue = "beAnInstanceOf only works on Objective-C types since" + + " the Swift compiler will automatically type check Swift-only types." + + " This expectation is redundant." + return false + } +} + +/// A Nimble matcher that succeeds when the actual value is an instance of the given class. +/// @see beAKindOf if you want to match against subclasses +public func beAnInstanceOf(expectedClass: AnyClass) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + let instance = try actualExpression.evaluate() + if let validInstance = instance { + failureMessage.actualValue = "<\(NSStringFromClass(validInstance.dynamicType)) instance>" + } else { + failureMessage.actualValue = "" + } + failureMessage.postfixMessage = "be an instance of \(NSStringFromClass(expectedClass))" + return instance != nil && instance!.isMemberOfClass(expectedClass) + } +} + +extension NMBObjCMatcher { + public class func beAnInstanceOfMatcher(expected: AnyClass) -> NMBMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + return try! beAnInstanceOf(expected).matches(actualExpression, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeCloseTo.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeCloseTo.swift new file mode 100644 index 00000000..909e0225 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeCloseTo.swift @@ -0,0 +1,121 @@ +import Foundation + +internal let DefaultDelta = 0.0001 + +internal func isCloseTo(actualValue: NMBDoubleConvertible?, expectedValue: NMBDoubleConvertible, delta: Double, failureMessage: FailureMessage) -> Bool { + failureMessage.postfixMessage = "be close to <\(stringify(expectedValue))> (within \(stringify(delta)))" + if actualValue != nil { + failureMessage.actualValue = "<\(stringify(actualValue!))>" + } else { + failureMessage.actualValue = "" + } + return actualValue != nil && abs(actualValue!.doubleValue - expectedValue.doubleValue) < delta +} + +/// A Nimble matcher that succeeds when a value is close to another. This is used for floating +/// point values which can have imprecise results when doing arithmetic on them. +/// +/// @see equal +public func beCloseTo(expectedValue: Double, within delta: Double = DefaultDelta) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + return isCloseTo(try actualExpression.evaluate(), expectedValue: expectedValue, delta: delta, failureMessage: failureMessage) + } +} + +/// A Nimble matcher that succeeds when a value is close to another. This is used for floating +/// point values which can have imprecise results when doing arithmetic on them. +/// +/// @see equal +public func beCloseTo(expectedValue: NMBDoubleConvertible, within delta: Double = DefaultDelta) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + return isCloseTo(try actualExpression.evaluate(), expectedValue: expectedValue, delta: delta, failureMessage: failureMessage) + } +} + +public class NMBObjCBeCloseToMatcher : NSObject, NMBMatcher { + var _expected: NSNumber + var _delta: CDouble + init(expected: NSNumber, within: CDouble) { + _expected = expected + _delta = within + } + + public func matches(actualExpression: () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { + let actualBlock: () -> NMBDoubleConvertible? = ({ + return actualExpression() as? NMBDoubleConvertible + }) + let expr = Expression(expression: actualBlock, location: location) + let matcher = beCloseTo(self._expected, within: self._delta) + return try! matcher.matches(expr, failureMessage: failureMessage) + } + + public func doesNotMatch(actualExpression: () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { + let actualBlock: () -> NMBDoubleConvertible? = ({ + return actualExpression() as? NMBDoubleConvertible + }) + let expr = Expression(expression: actualBlock, location: location) + let matcher = beCloseTo(self._expected, within: self._delta) + return try! matcher.doesNotMatch(expr, failureMessage: failureMessage) + } + + public var within: (CDouble) -> NMBObjCBeCloseToMatcher { + return ({ delta in + return NMBObjCBeCloseToMatcher(expected: self._expected, within: delta) + }) + } +} + +extension NMBObjCMatcher { + public class func beCloseToMatcher(expected: NSNumber, within: CDouble) -> NMBObjCBeCloseToMatcher { + return NMBObjCBeCloseToMatcher(expected: expected, within: within) + } +} + +public func beCloseTo(expectedValues: [Double], within delta: Double = DefaultDelta) -> NonNilMatcherFunc <[Double]> { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be close to <\(stringify(expectedValues))> (each within \(stringify(delta)))" + if let actual = try actualExpression.evaluate() { + if actual.count != expectedValues.count { + return false + } else { + for (index, actualItem) in actual.enumerate() { + if fabs(actualItem - expectedValues[index]) > delta { + return false + } + } + return true + } + } + return false + } +} + +// MARK: - Operators + +infix operator ≈ { + associativity none + precedence 130 +} + +public func ≈(lhs: Expectation<[Double]>, rhs: [Double]) { + lhs.to(beCloseTo(rhs)) +} + +public func ≈(lhs: Expectation, rhs: Double) { + lhs.to(beCloseTo(rhs)) +} + +public func ≈(lhs: Expectation, rhs: (expected: Double, delta: Double)) { + lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) +} + +public func ==(lhs: Expectation, rhs: (expected: Double, delta: Double)) { + lhs.to(beCloseTo(rhs.expected, within: rhs.delta)) +} + +// make this higher precedence than exponents so the Doubles either end aren't pulled in +// unexpectantly +infix operator ± { precedence 170 } +public func ±(lhs: Double, rhs: Double) -> (expected: Double, delta: Double) { + return (expected: lhs, delta: rhs) +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeEmpty.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeEmpty.swift new file mode 100644 index 00000000..67c6bed6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeEmpty.swift @@ -0,0 +1,90 @@ +import Foundation + + +/// A Nimble matcher that succeeds when a value is "empty". For collections, this +/// means the are no items in that collection. For strings, it is an empty string. +public func beEmpty() -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be empty" + let actualSeq = try actualExpression.evaluate() + if actualSeq == nil { + return true + } + var generator = actualSeq!.generate() + return generator.next() == nil + } +} + +/// A Nimble matcher that succeeds when a value is "empty". For collections, this +/// means the are no items in that collection. For strings, it is an empty string. +public func beEmpty() -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be empty" + let actualString = try actualExpression.evaluate() + return actualString == nil || (actualString! as NSString).length == 0 + } +} + +/// A Nimble matcher that succeeds when a value is "empty". For collections, this +/// means the are no items in that collection. For NSString instances, it is an empty string. +public func beEmpty() -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be empty" + let actualString = try actualExpression.evaluate() + return actualString == nil || actualString!.length == 0 + } +} + +// Without specific overrides, beEmpty() is ambiguous for NSDictionary, NSArray, +// etc, since they conform to SequenceType as well as NMBCollection. + +/// A Nimble matcher that succeeds when a value is "empty". For collections, this +/// means the are no items in that collection. For strings, it is an empty string. +public func beEmpty() -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be empty" + let actualDictionary = try actualExpression.evaluate() + return actualDictionary == nil || actualDictionary!.count == 0 + } +} + +/// A Nimble matcher that succeeds when a value is "empty". For collections, this +/// means the are no items in that collection. For strings, it is an empty string. +public func beEmpty() -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be empty" + let actualArray = try actualExpression.evaluate() + return actualArray == nil || actualArray!.count == 0 + } +} + +/// A Nimble matcher that succeeds when a value is "empty". For collections, this +/// means the are no items in that collection. For strings, it is an empty string. +public func beEmpty() -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be empty" + let actual = try actualExpression.evaluate() + return actual == nil || actual!.count == 0 + } +} + +extension NMBObjCMatcher { + public class func beEmptyMatcher() -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let location = actualExpression.location + let actualValue = try! actualExpression.evaluate() + failureMessage.postfixMessage = "be empty" + if let value = actualValue as? NMBCollection { + let expr = Expression(expression: ({ value as NMBCollection }), location: location) + return try! beEmpty().matches(expr, failureMessage: failureMessage) + } else if let value = actualValue as? NSString { + let expr = Expression(expression: ({ value as String }), location: location) + return try! beEmpty().matches(expr, failureMessage: failureMessage) + } else if let actualValue = actualValue { + failureMessage.postfixMessage = "be empty (only works for NSArrays, NSSets, NSDictionaries, NSHashTables, and NSStrings)" + failureMessage.actualValue = "\(NSStringFromClass(actualValue.dynamicType)) type" + } + return false + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeGreaterThan.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeGreaterThan.swift new file mode 100644 index 00000000..f632b332 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeGreaterThan.swift @@ -0,0 +1,37 @@ +import Foundation + + +/// A Nimble matcher that succeeds when the actual value is greater than the expected value. +public func beGreaterThan(expectedValue: T?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be greater than <\(stringify(expectedValue))>" + return try actualExpression.evaluate() > expectedValue + } +} + +/// A Nimble matcher that succeeds when the actual value is greater than the expected value. +public func beGreaterThan(expectedValue: NMBComparable?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be greater than <\(stringify(expectedValue))>" + let actualValue = try actualExpression.evaluate() + let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) == NSComparisonResult.OrderedDescending + return matches + } +} + +public func >(lhs: Expectation, rhs: T) { + lhs.to(beGreaterThan(rhs)) +} + +public func >(lhs: Expectation, rhs: NMBComparable?) { + lhs.to(beGreaterThan(rhs)) +} + +extension NMBObjCMatcher { + public class func beGreaterThanMatcher(expected: NMBComparable?) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let expr = actualExpression.cast { $0 as? NMBComparable } + return try! beGreaterThan(expected).matches(expr, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeGreaterThanOrEqualTo.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeGreaterThanOrEqualTo.swift new file mode 100644 index 00000000..20ad83d7 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeGreaterThanOrEqualTo.swift @@ -0,0 +1,39 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual value is greater than +/// or equal to the expected value. +public func beGreaterThanOrEqualTo(expectedValue: T?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be greater than or equal to <\(stringify(expectedValue))>" + let actualValue = try actualExpression.evaluate() + return actualValue >= expectedValue + } +} + +/// A Nimble matcher that succeeds when the actual value is greater than +/// or equal to the expected value. +public func beGreaterThanOrEqualTo(expectedValue: T?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be greater than or equal to <\(stringify(expectedValue))>" + let actualValue = try actualExpression.evaluate() + let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) != NSComparisonResult.OrderedAscending + return matches + } +} + +public func >=(lhs: Expectation, rhs: T) { + lhs.to(beGreaterThanOrEqualTo(rhs)) +} + +public func >=(lhs: Expectation, rhs: T) { + lhs.to(beGreaterThanOrEqualTo(rhs)) +} + +extension NMBObjCMatcher { + public class func beGreaterThanOrEqualToMatcher(expected: NMBComparable?) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let expr = actualExpression.cast { $0 as? NMBComparable } + return try! beGreaterThanOrEqualTo(expected).matches(expr, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeIdenticalTo.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeIdenticalTo.swift new file mode 100644 index 00000000..21607822 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeIdenticalTo.swift @@ -0,0 +1,28 @@ +import Foundation + + +/// A Nimble matcher that succeeds when the actual value is the same instance +/// as the expected instance. +public func beIdenticalTo(expected: T?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + let actual = try actualExpression.evaluate() + failureMessage.actualValue = "\(identityAsString(actual))" + failureMessage.postfixMessage = "be identical to \(identityAsString(expected))" + return actual === expected && actual !== nil + } +} + +public func ===(lhs: Expectation, rhs: T?) { + lhs.to(beIdenticalTo(rhs)) +} +public func !==(lhs: Expectation, rhs: T?) { + lhs.toNot(beIdenticalTo(rhs)) +} + +extension NMBObjCMatcher { + public class func beIdenticalToMatcher(expected: NSObject?) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + return try! beIdenticalTo(expected).matches(actualExpression, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLessThan.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLessThan.swift new file mode 100644 index 00000000..c93ea296 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLessThan.swift @@ -0,0 +1,36 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual value is less than the expected value. +public func beLessThan(expectedValue: T?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be less than <\(stringify(expectedValue))>" + return try actualExpression.evaluate() < expectedValue + } +} + +/// A Nimble matcher that succeeds when the actual value is less than the expected value. +public func beLessThan(expectedValue: NMBComparable?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be less than <\(stringify(expectedValue))>" + let actualValue = try actualExpression.evaluate() + let matches = actualValue != nil && actualValue!.NMB_compare(expectedValue) == NSComparisonResult.OrderedAscending + return matches + } +} + +public func <(lhs: Expectation, rhs: T) { + lhs.to(beLessThan(rhs)) +} + +public func <(lhs: Expectation, rhs: NMBComparable?) { + lhs.to(beLessThan(rhs)) +} + +extension NMBObjCMatcher { + public class func beLessThanMatcher(expected: NMBComparable?) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let expr = actualExpression.cast { $0 as! NMBComparable? } + return try! beLessThan(expected).matches(expr, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLessThanOrEqual.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLessThanOrEqual.swift new file mode 100644 index 00000000..f260ac37 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLessThanOrEqual.swift @@ -0,0 +1,37 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual value is less than +/// or equal to the expected value. +public func beLessThanOrEqualTo(expectedValue: T?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be less than or equal to <\(stringify(expectedValue))>" + return try actualExpression.evaluate() <= expectedValue + } +} + +/// A Nimble matcher that succeeds when the actual value is less than +/// or equal to the expected value. +public func beLessThanOrEqualTo(expectedValue: T?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be less than or equal to <\(stringify(expectedValue))>" + let actualValue = try actualExpression.evaluate() + return actualValue != nil && actualValue!.NMB_compare(expectedValue) != NSComparisonResult.OrderedDescending + } +} + +public func <=(lhs: Expectation, rhs: T) { + lhs.to(beLessThanOrEqualTo(rhs)) +} + +public func <=(lhs: Expectation, rhs: T) { + lhs.to(beLessThanOrEqualTo(rhs)) +} + +extension NMBObjCMatcher { + public class func beLessThanOrEqualToMatcher(expected: NMBComparable?) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil:false) { actualExpression, failureMessage in + let expr = actualExpression.cast { $0 as? NMBComparable } + return try! beLessThanOrEqualTo(expected).matches(expr, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLogical.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLogical.swift new file mode 100644 index 00000000..d6294721 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeLogical.swift @@ -0,0 +1,93 @@ +import Foundation + +internal func matcherWithFailureMessage(matcher: M, postprocessor: (FailureMessage) -> Void) -> FullMatcherFunc { + return FullMatcherFunc { actualExpression, failureMessage, isNegation in + let pass: Bool + if isNegation { + pass = try matcher.doesNotMatch(actualExpression, failureMessage: failureMessage) + } else { + pass = try matcher.matches(actualExpression, failureMessage: failureMessage) + } + postprocessor(failureMessage) + return pass + } +} + +// MARK: beTrue() / beFalse() + +/// A Nimble matcher that succeeds when the actual value is exactly true. +/// This matcher will not match against nils. +public func beTrue() -> FullMatcherFunc { + return matcherWithFailureMessage(equal(true)) { failureMessage in + failureMessage.postfixMessage = "be true" + } +} + +/// A Nimble matcher that succeeds when the actual value is exactly false. +/// This matcher will not match against nils. +public func beFalse() -> FullMatcherFunc { + return matcherWithFailureMessage(equal(false)) { failureMessage in + failureMessage.postfixMessage = "be false" + } +} + +// MARK: beTruthy() / beFalsy() + +/// A Nimble matcher that succeeds when the actual value is not logically false. +public func beTruthy() -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be truthy" + let actualValue = try actualExpression.evaluate() + if let actualValue = actualValue { + if let actualValue = actualValue as? BooleanType { + return actualValue.boolValue == true + } + } + return actualValue != nil + } +} + +/// A Nimble matcher that succeeds when the actual value is logically false. +/// This matcher will match against nils. +public func beFalsy() -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be falsy" + let actualValue = try actualExpression.evaluate() + if let actualValue = actualValue { + if let actualValue = actualValue as? BooleanType { + return actualValue.boolValue != true + } + } + return actualValue == nil + } +} + +extension NMBObjCMatcher { + public class func beTruthyMatcher() -> NMBObjCMatcher { + return NMBObjCMatcher { actualExpression, failureMessage in + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as BooleanType? } + return try! beTruthy().matches(expr, failureMessage: failureMessage) + } + } + + public class func beFalsyMatcher() -> NMBObjCMatcher { + return NMBObjCMatcher { actualExpression, failureMessage in + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as BooleanType? } + return try! beFalsy().matches(expr, failureMessage: failureMessage) + } + } + + public class func beTrueMatcher() -> NMBObjCMatcher { + return NMBObjCMatcher { actualExpression, failureMessage in + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } + return try! beTrue().matches(expr, failureMessage: failureMessage) + } + } + + public class func beFalseMatcher() -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } + return try! beFalse().matches(expr, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeNil.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeNil.swift new file mode 100644 index 00000000..42459076 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeNil.swift @@ -0,0 +1,18 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual value is nil. +public func beNil() -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be nil" + let actualValue = try actualExpression.evaluate() + return actualValue == nil + } +} + +extension NMBObjCMatcher { + public class func beNilMatcher() -> NMBObjCMatcher { + return NMBObjCMatcher { actualExpression, failureMessage in + return try! beNil().matches(actualExpression, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/BeginWith.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeginWith.swift new file mode 100644 index 00000000..9f07b12d --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/BeginWith.swift @@ -0,0 +1,53 @@ +import Foundation + + +/// A Nimble matcher that succeeds when the actual sequence's first element +/// is equal to the expected value. +public func beginWith(startingElement: T) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "begin with <\(startingElement)>" + if let actualValue = try actualExpression.evaluate() { + var actualGenerator = actualValue.generate() + return actualGenerator.next() == startingElement + } + return false + } +} + +/// A Nimble matcher that succeeds when the actual collection's first element +/// is equal to the expected object. +public func beginWith(startingElement: AnyObject) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "begin with <\(startingElement)>" + let collection = try actualExpression.evaluate() + return collection != nil && collection!.indexOfObject(startingElement) == 0 + } +} + +/// A Nimble matcher that succeeds when the actual string contains expected substring +/// where the expected substring's location is zero. +public func beginWith(startingSubstring: String) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "begin with <\(startingSubstring)>" + if let actual = try actualExpression.evaluate() { + let range = actual.rangeOfString(startingSubstring) + return range != nil && range!.startIndex == actual.startIndex + } + return false + } +} + +extension NMBObjCMatcher { + public class func beginWithMatcher(expected: AnyObject) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let actual = try! actualExpression.evaluate() + if let _ = actual as? String { + let expr = actualExpression.cast { $0 as? String } + return try! beginWith(expected as! String).matches(expr, failureMessage: failureMessage) + } else { + let expr = actualExpression.cast { $0 as? NMBOrderedCollection } + return try! beginWith(expected).matches(expr, failureMessage: failureMessage) + } + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/Contain.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/Contain.swift new file mode 100644 index 00000000..e0fe68c5 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/Contain.swift @@ -0,0 +1,91 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual sequence contains the expected value. +public func contain(items: T...) -> NonNilMatcherFunc { + return contain(items) +} + +private func contain(items: [T]) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "contain <\(arrayAsString(items))>" + if let actual = try actualExpression.evaluate() { + return all(items) { + return actual.contains($0) + } + } + return false + } +} + +/// A Nimble matcher that succeeds when the actual string contains the expected substring. +public func contain(substrings: String...) -> NonNilMatcherFunc { + return contain(substrings) +} + +private func contain(substrings: [String]) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "contain <\(arrayAsString(substrings))>" + if let actual = try actualExpression.evaluate() { + return all(substrings) { + let scanRange = Range(start: actual.startIndex, end: actual.endIndex) + let range = actual.rangeOfString($0, options: [], range: scanRange, locale: nil) + return range != nil && !range!.isEmpty + } + } + return false + } +} + +/// A Nimble matcher that succeeds when the actual string contains the expected substring. +public func contain(substrings: NSString...) -> NonNilMatcherFunc { + return contain(substrings) +} + +private func contain(substrings: [NSString]) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "contain <\(arrayAsString(substrings))>" + if let actual = try actualExpression.evaluate() { + return all(substrings) { actual.rangeOfString($0.description).length != 0 } + } + return false + } +} + +/// A Nimble matcher that succeeds when the actual collection contains the expected object. +public func contain(items: AnyObject?...) -> NonNilMatcherFunc { + return contain(items) +} + +private func contain(items: [AnyObject?]) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "contain <\(arrayAsString(items))>" + let actual = try actualExpression.evaluate() + return all(items) { item in + return actual != nil && actual!.containsObject(item) + } + } +} + +extension NMBObjCMatcher { + public class func containMatcher(expected: [NSObject]) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let location = actualExpression.location + let actualValue = try! actualExpression.evaluate() + if let value = actualValue as? NMBContainer { + let expr = Expression(expression: ({ value as NMBContainer }), location: location) + + // A straightforward cast on the array causes this to crash, so we have to cast the individual items + let expectedOptionals: [AnyObject?] = expected.map({ $0 as AnyObject? }) + return try! contain(expectedOptionals).matches(expr, failureMessage: failureMessage) + } else if let value = actualValue as? NSString { + let expr = Expression(expression: ({ value as String }), location: location) + return try! contain(expected as! [String]).matches(expr, failureMessage: failureMessage) + } else if actualValue != nil { + failureMessage.postfixMessage = "contain <\(arrayAsString(expected))> (only works for NSArrays, NSSets, NSHashTables, and NSStrings)" + } else { + failureMessage.postfixMessage = "contain <\(arrayAsString(expected))>" + } + return false + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/EndWith.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/EndWith.swift new file mode 100644 index 00000000..2f158741 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/EndWith.swift @@ -0,0 +1,63 @@ +import Foundation + + +/// A Nimble matcher that succeeds when the actual sequence's last element +/// is equal to the expected value. +public func endWith(endingElement: T) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "end with <\(endingElement)>" + + if let actualValue = try actualExpression.evaluate() { + var actualGenerator = actualValue.generate() + var lastItem: T? + var item: T? + repeat { + lastItem = item + item = actualGenerator.next() + } while(item != nil) + + return lastItem == endingElement + } + return false + } +} + +/// A Nimble matcher that succeeds when the actual collection's last element +/// is equal to the expected object. +public func endWith(endingElement: AnyObject) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "end with <\(endingElement)>" + let collection = try actualExpression.evaluate() + return collection != nil && collection!.indexOfObject(endingElement) == collection!.count - 1 + } +} + + +/// A Nimble matcher that succeeds when the actual string contains the expected substring +/// where the expected substring's location is the actual string's length minus the +/// expected substring's length. +public func endWith(endingSubstring: String) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "end with <\(endingSubstring)>" + if let collection = try actualExpression.evaluate() { + let range = collection.rangeOfString(endingSubstring) + return range != nil && range!.endIndex == collection.endIndex + } + return false + } +} + +extension NMBObjCMatcher { + public class func endWithMatcher(expected: AnyObject) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let actual = try! actualExpression.evaluate() + if let _ = actual as? String { + let expr = actualExpression.cast { $0 as? String } + return try! endWith(expected as! String).matches(expr, failureMessage: failureMessage) + } else { + let expr = actualExpression.cast { $0 as? NMBOrderedCollection } + return try! endWith(expected).matches(expr, failureMessage: failureMessage) + } + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/Equal.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/Equal.swift new file mode 100644 index 00000000..96b77051 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/Equal.swift @@ -0,0 +1,148 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual value is equal to the expected value. +/// Values can support equal by supporting the Equatable protocol. +/// +/// @see beCloseTo if you want to match imprecise types (eg - floats, doubles). +public func equal(expectedValue: T?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" + let actualValue = try actualExpression.evaluate() + let matches = actualValue == expectedValue && expectedValue != nil + if expectedValue == nil || actualValue == nil { + if expectedValue == nil { + failureMessage.postfixActual = " (use beNil() to match nils)" + } + return false + } + return matches + } +} + +/// A Nimble matcher that succeeds when the actual value is equal to the expected value. +/// Values can support equal by supporting the Equatable protocol. +/// +/// @see beCloseTo if you want to match imprecise types (eg - floats, doubles). +public func equal(expectedValue: [T: C]?) -> NonNilMatcherFunc<[T: C]> { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" + let actualValue = try actualExpression.evaluate() + if expectedValue == nil || actualValue == nil { + if expectedValue == nil { + failureMessage.postfixActual = " (use beNil() to match nils)" + } + return false + } + return expectedValue! == actualValue! + } +} + +/// A Nimble matcher that succeeds when the actual collection is equal to the expected collection. +/// Items must implement the Equatable protocol. +public func equal(expectedValue: [T]?) -> NonNilMatcherFunc<[T]> { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" + let actualValue = try actualExpression.evaluate() + if expectedValue == nil || actualValue == nil { + if expectedValue == nil { + failureMessage.postfixActual = " (use beNil() to match nils)" + } + return false + } + return expectedValue! == actualValue! + } +} + +/// A Nimble matcher that succeeds when the actual set is equal to the expected set. +public func equal(expectedValue: Set?) -> NonNilMatcherFunc> { + return equal(expectedValue, stringify: stringify) +} + +/// A Nimble matcher that succeeds when the actual set is equal to the expected set. +public func equal(expectedValue: Set?) -> NonNilMatcherFunc> { + return equal(expectedValue, stringify: { + if let set = $0 { + return stringify(Array(set).sort { $0 < $1 }) + } else { + return "nil" + } + }) +} + +private func equal(expectedValue: Set?, stringify: Set? -> String) -> NonNilMatcherFunc> { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "equal <\(stringify(expectedValue))>" + + if let expectedValue = expectedValue { + if let actualValue = try actualExpression.evaluate() { + failureMessage.actualValue = "<\(stringify(actualValue))>" + + if expectedValue == actualValue { + return true + } + + let missing = expectedValue.subtract(actualValue) + if missing.count > 0 { + failureMessage.postfixActual += ", missing <\(stringify(missing))>" + } + + let extra = actualValue.subtract(expectedValue) + if extra.count > 0 { + failureMessage.postfixActual += ", extra <\(stringify(extra))>" + } + } + } else { + failureMessage.postfixActual = " (use beNil() to match nils)" + } + + return false + } +} + +public func ==(lhs: Expectation, rhs: T?) { + lhs.to(equal(rhs)) +} + +public func !=(lhs: Expectation, rhs: T?) { + lhs.toNot(equal(rhs)) +} + +public func ==(lhs: Expectation<[T]>, rhs: [T]?) { + lhs.to(equal(rhs)) +} + +public func !=(lhs: Expectation<[T]>, rhs: [T]?) { + lhs.toNot(equal(rhs)) +} + +public func ==(lhs: Expectation>, rhs: Set?) { + lhs.to(equal(rhs)) +} + +public func !=(lhs: Expectation>, rhs: Set?) { + lhs.toNot(equal(rhs)) +} + +public func ==(lhs: Expectation>, rhs: Set?) { + lhs.to(equal(rhs)) +} + +public func !=(lhs: Expectation>, rhs: Set?) { + lhs.toNot(equal(rhs)) +} + +public func ==(lhs: Expectation<[T: C]>, rhs: [T: C]?) { + lhs.to(equal(rhs)) +} + +public func !=(lhs: Expectation<[T: C]>, rhs: [T: C]?) { + lhs.toNot(equal(rhs)) +} + +extension NMBObjCMatcher { + public class func equalMatcher(expected: NSObject) -> NMBMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + return try! equal(expected).matches(actualExpression, failureMessage: failureMessage) + } + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/Match.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/Match.swift new file mode 100644 index 00000000..058d6b1e --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/Match.swift @@ -0,0 +1,27 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual string satisfies the regular expression +/// described by the expected string. +public func match(expectedValue: String?) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "match <\(stringify(expectedValue))>" + + if let actual = try actualExpression.evaluate() { + if let regexp = expectedValue { + return actual.rangeOfString(regexp, options: .RegularExpressionSearch) != nil + } + } + + return false + } +} + +extension NMBObjCMatcher { + public class func matchMatcher(expected: NSString) -> NMBMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let actual = actualExpression.cast { $0 as? String } + return try! match(expected.description).matches(actual, failureMessage: failureMessage) + } + } +} + diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/MatcherProtocols.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/MatcherProtocols.swift new file mode 100644 index 00000000..d0076eac --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/MatcherProtocols.swift @@ -0,0 +1,98 @@ +import Foundation + +/// Implement this protocol to implement a custom matcher for Swift +public protocol Matcher { + typealias ValueType + func matches(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool + func doesNotMatch(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool +} + +/// Objective-C interface to the Swift variant of Matcher. +@objc public protocol NMBMatcher { + func matches(actualBlock: () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool + func doesNotMatch(actualBlock: () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool +} + +/// Protocol for types that support contain() matcher. +@objc public protocol NMBContainer { + func containsObject(object: AnyObject!) -> Bool +} +extension NSArray : NMBContainer {} +extension NSSet : NMBContainer {} +extension NSHashTable : NMBContainer {} + +/// Protocol for types that support only beEmpty() +@objc public protocol NMBCollection { + var count: Int { get } +} +extension NSSet : NMBCollection {} +extension NSDictionary : NMBCollection {} +extension NSHashTable : NMBCollection {} + +/// Protocol for types that support beginWith(), endWith(), beEmpty() matchers +@objc public protocol NMBOrderedCollection : NMBCollection { + func indexOfObject(object: AnyObject!) -> Int +} +extension NSArray : NMBOrderedCollection {} + +/// Protocol for types to support beCloseTo() matcher +@objc public protocol NMBDoubleConvertible { + var doubleValue: CDouble { get } +} +extension NSNumber : NMBDoubleConvertible { +} + +private let dateFormatter: NSDateFormatter = { + let formatter = NSDateFormatter() + formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSSS" + formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") + + return formatter + }() + +extension NSDate: NMBDoubleConvertible { + public var doubleValue: CDouble { + get { + return self.timeIntervalSinceReferenceDate + } + } +} + + +extension NMBDoubleConvertible { + public var stringRepresentation: String { + get { + if let date = self as? NSDate { + return dateFormatter.stringFromDate(date) + } + + if let debugStringConvertible = self as? CustomDebugStringConvertible { + return debugStringConvertible.debugDescription + } + + if let stringConvertible = self as? CustomStringConvertible { + return stringConvertible.description + } + + return "" + } + } +} + +/// Protocol for types to support beLessThan(), beLessThanOrEqualTo(), +/// beGreaterThan(), beGreaterThanOrEqualTo(), and equal() matchers. +/// +/// Types that conform to Swift's Comparable protocol will work implicitly too +@objc public protocol NMBComparable { + func NMB_compare(otherObject: NMBComparable!) -> NSComparisonResult +} +extension NSNumber : NMBComparable { + public func NMB_compare(otherObject: NMBComparable!) -> NSComparisonResult { + return compare(otherObject as! NSNumber) + } +} +extension NSString : NMBComparable { + public func NMB_compare(otherObject: NMBComparable!) -> NSComparisonResult { + return compare(otherObject as! String) + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/RaisesException.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/RaisesException.swift new file mode 100644 index 00000000..0b5754fc --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/RaisesException.swift @@ -0,0 +1,178 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual expression raises an +/// exception with the specified name, reason, and/or userInfo. +/// +/// Alternatively, you can pass a closure to do any arbitrary custom matching +/// to the raised exception. The closure only gets called when an exception +/// is raised. +/// +/// nil arguments indicates that the matcher should not attempt to match against +/// that parameter. +public func raiseException( + named named: String? = nil, + reason: String? = nil, + userInfo: NSDictionary? = nil, + closure: ((NSException) -> Void)? = nil) -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + + var exception: NSException? + let capture = NMBExceptionCapture(handler: ({ e in + exception = e + }), finally: nil) + + capture.tryBlock { + try! actualExpression.evaluate() + return + } + + setFailureMessageForException(failureMessage, exception: exception, named: named, reason: reason, userInfo: userInfo, closure: closure) + return exceptionMatchesNonNilFieldsOrClosure(exception, named: named, reason: reason, userInfo: userInfo, closure: closure) + } +} + +internal func setFailureMessageForException( + failureMessage: FailureMessage, + exception: NSException?, + named: String?, + reason: String?, + userInfo: NSDictionary?, + closure: ((NSException) -> Void)?) { + failureMessage.postfixMessage = "raise exception" + + if let named = named { + failureMessage.postfixMessage += " with name <\(named)>" + } + if let reason = reason { + failureMessage.postfixMessage += " with reason <\(reason)>" + } + if let userInfo = userInfo { + failureMessage.postfixMessage += " with userInfo <\(userInfo)>" + } + if let _ = closure { + failureMessage.postfixMessage += " that satisfies block" + } + if named == nil && reason == nil && userInfo == nil && closure == nil { + failureMessage.postfixMessage = "raise any exception" + } + + if let exception = exception { + failureMessage.actualValue = "\(NSStringFromClass(exception.dynamicType)) { name=\(exception.name), reason='\(stringify(exception.reason))', userInfo=\(stringify(exception.userInfo)) }" + } else { + failureMessage.actualValue = "no exception" + } +} + +internal func exceptionMatchesNonNilFieldsOrClosure( + exception: NSException?, + named: String?, + reason: String?, + userInfo: NSDictionary?, + closure: ((NSException) -> Void)?) -> Bool { + var matches = false + + if let exception = exception { + matches = true + + if named != nil && exception.name != named { + matches = false + } + if reason != nil && exception.reason != reason { + matches = false + } + if userInfo != nil && exception.userInfo != userInfo { + matches = false + } + if let closure = closure { + let assertions = gatherFailingExpectations { + closure(exception) + } + let messages = assertions.map { $0.message } + if messages.count > 0 { + matches = false + } + } + } + + return matches +} + +public class NMBObjCRaiseExceptionMatcher : NSObject, NMBMatcher { + internal var _name: String? + internal var _reason: String? + internal var _userInfo: NSDictionary? + internal var _block: ((NSException) -> Void)? + + internal init(name: String?, reason: String?, userInfo: NSDictionary?, block: ((NSException) -> Void)?) { + _name = name + _reason = reason + _userInfo = userInfo + _block = block + } + + public func matches(actualBlock: () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { + let block: () -> Any? = ({ actualBlock(); return nil }) + let expr = Expression(expression: block, location: location) + + return try! raiseException( + named: _name, + reason: _reason, + userInfo: _userInfo, + closure: _block + ).matches(expr, failureMessage: failureMessage) + } + + public func doesNotMatch(actualBlock: () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { + return !matches(actualBlock, failureMessage: failureMessage, location: location) + } + + public var named: (name: String) -> NMBObjCRaiseExceptionMatcher { + return ({ name in + return NMBObjCRaiseExceptionMatcher( + name: name, + reason: self._reason, + userInfo: self._userInfo, + block: self._block + ) + }) + } + + public var reason: (reason: String?) -> NMBObjCRaiseExceptionMatcher { + return ({ reason in + return NMBObjCRaiseExceptionMatcher( + name: self._name, + reason: reason, + userInfo: self._userInfo, + block: self._block + ) + }) + } + + public var userInfo: (userInfo: NSDictionary?) -> NMBObjCRaiseExceptionMatcher { + return ({ userInfo in + return NMBObjCRaiseExceptionMatcher( + name: self._name, + reason: self._reason, + userInfo: userInfo, + block: self._block + ) + }) + } + + public var satisfyingBlock: (block: ((NSException) -> Void)?) -> NMBObjCRaiseExceptionMatcher { + return ({ block in + return NMBObjCRaiseExceptionMatcher( + name: self._name, + reason: self._reason, + userInfo: self._userInfo, + block: block + ) + }) + } +} + +extension NMBObjCMatcher { + public class func raiseExceptionMatcher() -> NMBObjCRaiseExceptionMatcher { + return NMBObjCRaiseExceptionMatcher(name: nil, reason: nil, userInfo: nil, block: nil) + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Matchers/ThrowError.swift b/Carthage/Checkouts/Nimble/Nimble/Matchers/ThrowError.swift new file mode 100644 index 00000000..c12e31cc --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Matchers/ThrowError.swift @@ -0,0 +1,181 @@ +import Foundation + +/// A Nimble matcher that succeeds when the actual expression throws an +/// error of the specified type or from the specified case. +/// +/// Errors are tried to be compared by their implementation of Equatable, +/// otherwise they fallback to comparision by _domain and _code. +/// +/// Alternatively, you can pass a closure to do any arbitrary custom matching +/// to the thrown error. The closure only gets called when an error was thrown. +/// +/// nil arguments indicates that the matcher should not attempt to match against +/// that parameter. +public func throwError( + error: T? = nil, + errorType: T.Type? = nil, + closure: ((T) -> Void)? = nil) -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + + var actualError: ErrorType? + do { + try actualExpression.evaluate() + } catch let catchedError { + actualError = catchedError + } + + setFailureMessageForError(failureMessage, actualError: actualError, error: error, errorType: errorType, closure: closure) + return errorMatchesNonNilFieldsOrClosure(actualError, error: error, errorType: errorType, closure: closure) + } +} + +internal func setFailureMessageForError( + failureMessage: FailureMessage, + actualError: ErrorType?, + error: T?, + errorType: T.Type? = nil, + closure: ((T) -> Void)?) { + failureMessage.postfixMessage = "throw error" + + if let error = error { + if let error = error as? CustomDebugStringConvertible { + failureMessage.postfixMessage += " <\(error.debugDescription)>" + } else { + failureMessage.postfixMessage += " <\(error)>" + } + } else if errorType != nil || closure != nil { + failureMessage.postfixMessage += " from type <\(T.self)>" + } + if let _ = closure { + failureMessage.postfixMessage += " that satisfies block" + } + if error == nil && errorType == nil && closure == nil { + failureMessage.postfixMessage = "throw any error" + } + + if let actualError = actualError { + failureMessage.actualValue = "<\(actualError)>" + } else { + failureMessage.actualValue = "no error" + } +} + +internal func errorMatchesExpectedError( + actualError: ErrorType, + expectedError: T) -> Bool { + return actualError._domain == expectedError._domain + && actualError._code == expectedError._code +} + +internal func errorMatchesExpectedError( + actualError: ErrorType, + expectedError: T) -> Bool { + if let actualError = actualError as? T { + return actualError == expectedError + } + return false +} + +internal func errorMatchesNonNilFieldsOrClosure( + actualError: ErrorType?, + error: T?, + errorType: T.Type?, + closure: ((T) -> Void)?) -> Bool { + var matches = false + + if let actualError = actualError { + matches = true + + if let error = error { + if !errorMatchesExpectedError(actualError, expectedError: error) { + matches = false + } + } + if let actualError = actualError as? T { + if let closure = closure { + let assertions = gatherFailingExpectations { + closure(actualError as T) + } + let messages = assertions.map { $0.message } + if messages.count > 0 { + matches = false + } + } + } else if errorType != nil && closure != nil { + // The closure expects another ErrorType as argument, so this + // is _supposed_ to fail, so that it becomes more obvious. + let assertions = gatherExpectations { + expect(actualError is T).to(equal(true)) + } + precondition(assertions.map { $0.message }.count > 0) + matches = false + } + } + + return matches +} + + +/// A Nimble matcher that succeeds when the actual expression throws any +/// error or when the passed closures' arbitrary custom matching succeeds. +/// +/// This duplication to it's generic adequate is required to allow to receive +/// values of the existential type ErrorType in the closure. +/// +/// The closure only gets called when an error was thrown. +public func throwError( + closure closure: ((ErrorType) -> Void)? = nil) -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + + var actualError: ErrorType? + do { + try actualExpression.evaluate() + } catch let catchedError { + actualError = catchedError + } + + setFailureMessageForError(failureMessage, actualError: actualError, closure: closure) + return errorMatchesNonNilFieldsOrClosure(actualError, closure: closure) + } +} + +internal func setFailureMessageForError( + failureMessage: FailureMessage, + actualError: ErrorType?, + closure: ((ErrorType) -> Void)?) { + failureMessage.postfixMessage = "throw error" + + if let _ = closure { + failureMessage.postfixMessage += " that satisfies block" + } else { + failureMessage.postfixMessage = "throw any error" + } + + if let actualError = actualError { + failureMessage.actualValue = "<\(actualError)>" + } else { + failureMessage.actualValue = "no error" + } +} + +internal func errorMatchesNonNilFieldsOrClosure( + actualError: ErrorType?, + closure: ((ErrorType) -> Void)?) -> Bool { + var matches = false + + if let actualError = actualError { + matches = true + + if let closure = closure { + let assertions = gatherFailingExpectations { + closure(actualError) + } + let messages = assertions.map { $0.message } + if messages.count > 0 { + matches = false + } + } + } + + return matches +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Nimble.h b/Carthage/Checkouts/Nimble/Nimble/Nimble.h new file mode 100644 index 00000000..43362188 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Nimble.h @@ -0,0 +1,6 @@ +#import +#import +#import + +FOUNDATION_EXPORT double NimbleVersionNumber; +FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; diff --git a/Carthage/Checkouts/Nimble/Nimble/ObjCExpectation.swift b/Carthage/Checkouts/Nimble/Nimble/ObjCExpectation.swift new file mode 100644 index 00000000..d985c26b --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/ObjCExpectation.swift @@ -0,0 +1,125 @@ +internal struct ObjCMatcherWrapper : Matcher { + let matcher: NMBMatcher + + func matches(actualExpression: Expression, failureMessage: FailureMessage) -> Bool { + return matcher.matches( + ({ try! actualExpression.evaluate() }), + failureMessage: failureMessage, + location: actualExpression.location) + } + + func doesNotMatch(actualExpression: Expression, failureMessage: FailureMessage) -> Bool { + return matcher.doesNotMatch( + ({ try! actualExpression.evaluate() }), + failureMessage: failureMessage, + location: actualExpression.location) + } +} + +// Equivalent to Expectation, but for Nimble's Objective-C interface +public class NMBExpectation : NSObject { + internal let _actualBlock: () -> NSObject! + internal var _negative: Bool + internal let _file: String + internal let _line: UInt + internal var _timeout: NSTimeInterval = 1.0 + + public init(actualBlock: () -> NSObject!, negative: Bool, file: String, line: UInt) { + self._actualBlock = actualBlock + self._negative = negative + self._file = file + self._line = line + } + + private var expectValue: Expectation { + return expect(_file, line: _line){ + self._actualBlock() as NSObject? + } + } + + public var withTimeout: (NSTimeInterval) -> NMBExpectation { + return ({ timeout in self._timeout = timeout + return self + }) + } + + public var to: (NMBMatcher) -> Void { + return ({ matcher in + self.expectValue.to(ObjCMatcherWrapper(matcher: matcher)) + }) + } + + public var toWithDescription: (NMBMatcher, String) -> Void { + return ({ matcher, description in + self.expectValue.to(ObjCMatcherWrapper(matcher: matcher), description: description) + }) + } + + public var toNot: (NMBMatcher) -> Void { + return ({ matcher in + self.expectValue.toNot( + ObjCMatcherWrapper(matcher: matcher) + ) + }) + } + + public var toNotWithDescription: (NMBMatcher, String) -> Void { + return ({ matcher, description in + self.expectValue.toNot( + ObjCMatcherWrapper(matcher: matcher), description: description + ) + }) + } + + public var notTo: (NMBMatcher) -> Void { return toNot } + + public var notToWithDescription: (NMBMatcher, String) -> Void { return toNotWithDescription } + + public var toEventually: (NMBMatcher) -> Void { + return ({ matcher in + self.expectValue.toEventually( + ObjCMatcherWrapper(matcher: matcher), + timeout: self._timeout, + description: nil + ) + }) + } + + public var toEventuallyWithDescription: (NMBMatcher, String) -> Void { + return ({ matcher, description in + self.expectValue.toEventually( + ObjCMatcherWrapper(matcher: matcher), + timeout: self._timeout, + description: description + ) + }) + } + + public var toEventuallyNot: (NMBMatcher) -> Void { + return ({ matcher in + self.expectValue.toEventuallyNot( + ObjCMatcherWrapper(matcher: matcher), + timeout: self._timeout, + description: nil + ) + }) + } + + public var toEventuallyNotWithDescription: (NMBMatcher, String) -> Void { + return ({ matcher, description in + self.expectValue.toEventuallyNot( + ObjCMatcherWrapper(matcher: matcher), + timeout: self._timeout, + description: description + ) + }) + } + + public var toNotEventually: (NMBMatcher) -> Void { return toEventuallyNot } + + public var toNotEventuallyWithDescription: (NMBMatcher, String) -> Void { return toEventuallyNotWithDescription } + + public class func failWithMessage(message: String, file: String, line: UInt) { + fail(message, location: SourceLocation(file: file, line: line)) + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Utils/Functional.swift b/Carthage/Checkouts/Nimble/Nimble/Utils/Functional.swift new file mode 100644 index 00000000..647123f6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Utils/Functional.swift @@ -0,0 +1,11 @@ +import Foundation + +internal func all(array: [T], fn: (T) -> Bool) -> Bool { + for item in array { + if !fn(item) { + return false + } + } + return true +} + diff --git a/Carthage/Checkouts/Nimble/Nimble/Utils/Poll.swift b/Carthage/Checkouts/Nimble/Nimble/Utils/Poll.swift new file mode 100644 index 00000000..603d1110 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Utils/Poll.swift @@ -0,0 +1,86 @@ +import Foundation + +internal enum PollResult : BooleanType { + case Success, Failure, Timeout + case ErrorThrown(ErrorType) + + var boolValue : Bool { + switch (self) { + case .Success: + return true + default: + return false + } + } +} + +internal class RunPromise { + var token: dispatch_once_t = 0 + var didFinish = false + var didFail = false + + init() {} + + func succeed() { + dispatch_once(&self.token) { + self.didFinish = false + } + } + + func fail(block: () -> Void) { + dispatch_once(&self.token) { + self.didFail = true + block() + } + } +} + +let killQueue = dispatch_queue_create("nimble.waitUntil.queue", DISPATCH_QUEUE_SERIAL) + +internal func stopRunLoop(runLoop: NSRunLoop, delay: NSTimeInterval) -> RunPromise { + let promise = RunPromise() + let killTimeOffset = Int64(CDouble(delay) * CDouble(NSEC_PER_SEC)) + let killTime = dispatch_time(DISPATCH_TIME_NOW, killTimeOffset) + dispatch_after(killTime, killQueue) { + promise.fail { + CFRunLoopStop(runLoop.getCFRunLoop()) + } + } + return promise +} + +internal func pollBlock(pollInterval pollInterval: NSTimeInterval, timeoutInterval: NSTimeInterval, expression: () throws -> Bool) -> PollResult { + let runLoop = NSRunLoop.mainRunLoop() + + let promise = stopRunLoop(runLoop, delay: min(timeoutInterval, 0.2)) + + let startDate = NSDate() + + // trigger run loop to make sure enqueued tasks don't block our assertion polling + // the stop run loop task above will abort us if necessary + runLoop.runUntilDate(startDate) + dispatch_sync(killQueue) { + promise.succeed() + } + + if promise.didFail { + return .Timeout + } + + var pass = false + do { + repeat { + pass = try expression() + if pass { + break + } + + let runDate = NSDate().dateByAddingTimeInterval(pollInterval) + runLoop.runUntilDate(runDate) + } while(NSDate().timeIntervalSinceDate(startDate) < timeoutInterval) + } catch let error { + return .ErrorThrown(error) + } + + return pass ? .Success : .Failure +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Utils/SourceLocation.swift b/Carthage/Checkouts/Nimble/Nimble/Utils/SourceLocation.swift new file mode 100644 index 00000000..6066caa5 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Utils/SourceLocation.swift @@ -0,0 +1,21 @@ +import Foundation + + +public class SourceLocation : NSObject { + public let file: String + public let line: UInt + + override init() { + file = "Unknown File" + line = 0 + } + + init(file: String, line: UInt) { + self.file = file + self.line = line + } + + override public var description: String { + return "\(file):\(line)" + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Utils/Stringers.swift b/Carthage/Checkouts/Nimble/Nimble/Utils/Stringers.swift new file mode 100644 index 00000000..96073f32 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Utils/Stringers.swift @@ -0,0 +1,62 @@ +import Foundation + + +internal func identityAsString(value: AnyObject?) -> String { + if value == nil { + return "nil" + } + return NSString(format: "<%p>", unsafeBitCast(value!, Int.self)).description +} + +internal func arrayAsString(items: [T], joiner: String = ", ") -> String { + return items.reduce("") { accum, item in + let prefix = (accum.isEmpty ? "" : joiner) + return accum + prefix + "\(stringify(item))" + } +} + +@objc internal protocol NMBStringer { + func NMB_stringify() -> String +} + +internal func stringify(value: S) -> String { + var generator = value.generate() + var strings = [String]() + var value: S.Generator.Element? + repeat { + value = generator.next() + if value != nil { + strings.append(stringify(value)) + } + } while value != nil + let str = strings.joinWithSeparator(", ") + return "[\(str)]" +} + +extension NSArray : NMBStringer { + func NMB_stringify() -> String { + let str = self.componentsJoinedByString(", ") + return "[\(str)]" + } +} + +internal func stringify(value: T) -> String { + if let value = value as? Double { + return NSString(format: "%.4f", (value)).description + } + return String(value) +} + +internal func stringify(value: NMBDoubleConvertible) -> String { + if let value = value as? Double { + return NSString(format: "%.4f", (value)).description + } + return value.stringRepresentation +} + +internal func stringify(value: T?) -> String { + if let unboxed = value { + return stringify(unboxed) + } + return "nil" +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Wrappers/AsyncMatcherWrapper.swift b/Carthage/Checkouts/Nimble/Nimble/Wrappers/AsyncMatcherWrapper.swift new file mode 100644 index 00000000..2d1a15b1 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Wrappers/AsyncMatcherWrapper.swift @@ -0,0 +1,98 @@ +import Foundation + +internal struct AsyncMatcherWrapper: Matcher { + let fullMatcher: U + let timeoutInterval: NSTimeInterval + let pollInterval: NSTimeInterval + + init(fullMatcher: U, timeoutInterval: NSTimeInterval = 1, pollInterval: NSTimeInterval = 0.01) { + self.fullMatcher = fullMatcher + self.timeoutInterval = timeoutInterval + self.pollInterval = pollInterval + } + + func matches(actualExpression: Expression, failureMessage: FailureMessage) -> Bool { + let uncachedExpression = actualExpression.withoutCaching() + let result = pollBlock(pollInterval: pollInterval, timeoutInterval: timeoutInterval) { + try self.fullMatcher.matches(uncachedExpression, failureMessage: failureMessage) + } + switch (result) { + case .Success: return true + case .Failure: return false + case let .ErrorThrown(error): + failureMessage.actualValue = "an unexpected error thrown: <\(error)>" + return false + case .Timeout: + failureMessage.postfixMessage += " (Stall on main thread)." + return false + } + } + + func doesNotMatch(actualExpression: Expression, failureMessage: FailureMessage) -> Bool { + let uncachedExpression = actualExpression.withoutCaching() + let result = pollBlock(pollInterval: pollInterval, timeoutInterval: timeoutInterval) { + try self.fullMatcher.doesNotMatch(uncachedExpression, failureMessage: failureMessage) + } + switch (result) { + case .Success: return true + case .Failure: return false + case let .ErrorThrown(error): + failureMessage.actualValue = "an unexpected error thrown: <\(error)>" + return false + case .Timeout: + failureMessage.postfixMessage += " (Stall on main thread)." + return false + } + } +} + +private let toEventuallyRequiresClosureError = FailureMessage(stringValue: "expect(...).toEventually(...) requires an explicit closure (eg - expect { ... }.toEventually(...) )\nSwift 1.2 @autoclosure behavior has changed in an incompatible way for Nimble to function") + + +extension Expectation { + /// Tests the actual value using a matcher to match by checking continuously + /// at each pollInterval until the timeout is reached. + public func toEventually(matcher: U, timeout: NSTimeInterval = 1, pollInterval: NSTimeInterval = 0.01, description: String? = nil) { + if expression.isClosure { + let (pass, msg) = expressionMatches( + expression, + matcher: AsyncMatcherWrapper( + fullMatcher: matcher, + timeoutInterval: timeout, + pollInterval: pollInterval), + to: "to eventually", + description: description + ) + verify(pass, msg) + } else { + verify(false, toEventuallyRequiresClosureError) + } + } + + /// Tests the actual value using a matcher to not match by checking + /// continuously at each pollInterval until the timeout is reached. + public func toEventuallyNot(matcher: U, timeout: NSTimeInterval = 1, pollInterval: NSTimeInterval = 0.01, description: String? = nil) { + if expression.isClosure { + let (pass, msg) = expressionDoesNotMatch( + expression, + matcher: AsyncMatcherWrapper( + fullMatcher: matcher, + timeoutInterval: timeout, + pollInterval: pollInterval), + toNot: "to eventually not", + description: description + ) + verify(pass, msg) + } else { + verify(false, toEventuallyRequiresClosureError) + } + } + + /// Tests the actual value using a matcher to not match by checking + /// continuously at each pollInterval until the timeout is reached. + /// + /// Alias of toEventuallyNot() + public func toNotEventually(matcher: U, timeout: NSTimeInterval = 1, pollInterval: NSTimeInterval = 0.01, description: String? = nil) { + return toEventuallyNot(matcher, timeout: timeout, pollInterval: pollInterval, description: description) + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Wrappers/MatcherFunc.swift b/Carthage/Checkouts/Nimble/Nimble/Wrappers/MatcherFunc.swift new file mode 100644 index 00000000..ff9c2ee1 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Wrappers/MatcherFunc.swift @@ -0,0 +1,95 @@ +/// A convenience API to build matchers that allow full control over +/// to() and toNot() match cases. +/// +/// The final bool argument in the closure is if the match is for negation. +/// +/// You may use this when implementing your own custom matchers. +/// +/// Use the Matcher protocol instead of this type to accept custom matchers as +/// input parameters. +/// @see allPass for an example that uses accepts other matchers as input. +public struct FullMatcherFunc: Matcher { + public let matcher: (Expression, FailureMessage, Bool) throws -> Bool + + public init(_ matcher: (Expression, FailureMessage, Bool) throws -> Bool) { + self.matcher = matcher + } + + public func matches(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { + return try matcher(actualExpression, failureMessage, false) + } + + public func doesNotMatch(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { + return try matcher(actualExpression, failureMessage, true) + } +} + +/// A convenience API to build matchers that don't need special negation +/// behavior. The toNot() behavior is the negation of to(). +/// +/// @see NonNilMatcherFunc if you prefer to have this matcher fail when nil +/// values are recieved in an expectation. +/// +/// You may use this when implementing your own custom matchers. +/// +/// Use the Matcher protocol instead of this type to accept custom matchers as +/// input parameters. +/// @see allPass for an example that uses accepts other matchers as input. +public struct MatcherFunc: Matcher { + public let matcher: (Expression, FailureMessage) throws -> Bool + + public init(_ matcher: (Expression, FailureMessage) throws -> Bool) { + self.matcher = matcher + } + + public func matches(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { + return try matcher(actualExpression, failureMessage) + } + + public func doesNotMatch(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { + return try !matcher(actualExpression, failureMessage) + } +} + +/// A convenience API to build matchers that don't need special negation +/// behavior. The toNot() behavior is the negation of to(). +/// +/// Unlike MatcherFunc, this will always fail if an expectation contains nil. +/// This applies regardless of using to() or toNot(). +/// +/// You may use this when implementing your own custom matchers. +/// +/// Use the Matcher protocol instead of this type to accept custom matchers as +/// input parameters. +/// @see allPass for an example that uses accepts other matchers as input. +public struct NonNilMatcherFunc: Matcher { + public let matcher: (Expression, FailureMessage) throws -> Bool + + public init(_ matcher: (Expression, FailureMessage) throws -> Bool) { + self.matcher = matcher + } + + public func matches(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { + let pass = try matcher(actualExpression, failureMessage) + if try attachNilErrorIfNeeded(actualExpression, failureMessage: failureMessage) { + return false + } + return pass + } + + public func doesNotMatch(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { + let pass = try !matcher(actualExpression, failureMessage) + if try attachNilErrorIfNeeded(actualExpression, failureMessage: failureMessage) { + return false + } + return pass + } + + internal func attachNilErrorIfNeeded(actualExpression: Expression, failureMessage: FailureMessage) throws -> Bool { + if try actualExpression.evaluate() == nil { + failureMessage.postfixActual = " (use beNil() to match nils)" + return true + } + return false + } +} diff --git a/Carthage/Checkouts/Nimble/Nimble/Wrappers/ObjCMatcher.swift b/Carthage/Checkouts/Nimble/Nimble/Wrappers/ObjCMatcher.swift new file mode 100644 index 00000000..0c207be3 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/Wrappers/ObjCMatcher.swift @@ -0,0 +1,77 @@ +import Foundation + +public typealias MatcherBlock = (actualExpression: Expression, failureMessage: FailureMessage) -> Bool +public typealias FullMatcherBlock = (actualExpression: Expression, failureMessage: FailureMessage, shouldNotMatch: Bool) -> Bool +public class NMBObjCMatcher : NSObject, NMBMatcher { + let _match: MatcherBlock + let _doesNotMatch: MatcherBlock + let canMatchNil: Bool + + public init(canMatchNil: Bool, matcher: MatcherBlock, notMatcher: MatcherBlock) { + self.canMatchNil = canMatchNil + self._match = matcher + self._doesNotMatch = notMatcher + } + + public convenience init(matcher: MatcherBlock) { + self.init(canMatchNil: true, matcher: matcher) + } + + public convenience init(canMatchNil: Bool, matcher: MatcherBlock) { + self.init(canMatchNil: canMatchNil, matcher: matcher, notMatcher: ({ actualExpression, failureMessage in + return !matcher(actualExpression: actualExpression, failureMessage: failureMessage) + })) + } + + public convenience init(matcher: FullMatcherBlock) { + self.init(canMatchNil: true, matcher: matcher) + } + + public convenience init(canMatchNil: Bool, matcher: FullMatcherBlock) { + self.init(canMatchNil: canMatchNil, matcher: ({ actualExpression, failureMessage in + return matcher(actualExpression: actualExpression, failureMessage: failureMessage, shouldNotMatch: false) + }), notMatcher: ({ actualExpression, failureMessage in + return matcher(actualExpression: actualExpression, failureMessage: failureMessage, shouldNotMatch: true) + })) + } + + private func canMatch(actualExpression: Expression, failureMessage: FailureMessage) -> Bool { + do { + if !canMatchNil { + if try actualExpression.evaluate() == nil { + failureMessage.postfixActual = " (use beNil() to match nils)" + return false + } + } + } catch let error { + failureMessage.actualValue = "an unexpected error thrown: \(error)" + return false + } + return true + } + + public func matches(actualBlock: () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { + let expr = Expression(expression: actualBlock, location: location) + let result = _match( + actualExpression: expr, + failureMessage: failureMessage) + if self.canMatch(Expression(expression: actualBlock, location: location), failureMessage: failureMessage) { + return result + } else { + return false + } + } + + public func doesNotMatch(actualBlock: () -> NSObject!, failureMessage: FailureMessage, location: SourceLocation) -> Bool { + let expr = Expression(expression: actualBlock, location: location) + let result = _doesNotMatch( + actualExpression: expr, + failureMessage: failureMessage) + if self.canMatch(Expression(expression: actualBlock, location: location), failureMessage: failureMessage) { + return result + } else { + return false + } + } +} + diff --git a/Carthage/Checkouts/Nimble/Nimble/objc/DSL.h b/Carthage/Checkouts/Nimble/Nimble/objc/DSL.h new file mode 100644 index 00000000..551af885 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/objc/DSL.h @@ -0,0 +1,129 @@ +#import + +@class NMBExpectation; +@class NMBObjCBeCloseToMatcher; +@class NMBObjCRaiseExceptionMatcher; +@protocol NMBMatcher; + + +#define NIMBLE_EXPORT FOUNDATION_EXPORT + +#ifdef NIMBLE_DISABLE_SHORT_SYNTAX +#define NIMBLE_SHORT(PROTO, ORIGINAL) +#else +#define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); } +#endif + +NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line); +NIMBLE_EXPORT NMBExpectation *NMB_expectAction(void(^actualBlock)(), NSString *file, NSUInteger line); + +NIMBLE_EXPORT id NMB_equal(id expectedValue); +NIMBLE_SHORT(id equal(id expectedValue), + NMB_equal(expectedValue)); + +NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue); +NIMBLE_SHORT(NMBObjCBeCloseToMatcher *beCloseTo(id expectedValue), + NMB_beCloseTo(expectedValue)); + +NIMBLE_EXPORT id NMB_beAnInstanceOf(Class expectedClass); +NIMBLE_SHORT(id beAnInstanceOf(Class expectedClass), + NMB_beAnInstanceOf(expectedClass)); + +NIMBLE_EXPORT id NMB_beAKindOf(Class expectedClass); +NIMBLE_SHORT(id beAKindOf(Class expectedClass), + NMB_beAKindOf(expectedClass)); + +NIMBLE_EXPORT id NMB_beginWith(id itemElementOrSubstring); +NIMBLE_SHORT(id beginWith(id itemElementOrSubstring), + NMB_beginWith(itemElementOrSubstring)); + +NIMBLE_EXPORT id NMB_beGreaterThan(NSNumber *expectedValue); +NIMBLE_SHORT(id beGreaterThan(NSNumber *expectedValue), + NMB_beGreaterThan(expectedValue)); + +NIMBLE_EXPORT id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue); +NIMBLE_SHORT(id beGreaterThanOrEqualTo(NSNumber *expectedValue), + NMB_beGreaterThanOrEqualTo(expectedValue)); + +NIMBLE_EXPORT id NMB_beIdenticalTo(id expectedInstance); +NIMBLE_SHORT(id beIdenticalTo(id expectedInstance), + NMB_beIdenticalTo(expectedInstance)); + +NIMBLE_EXPORT id NMB_beLessThan(NSNumber *expectedValue); +NIMBLE_SHORT(id beLessThan(NSNumber *expectedValue), + NMB_beLessThan(expectedValue)); + +NIMBLE_EXPORT id NMB_beLessThanOrEqualTo(NSNumber *expectedValue); +NIMBLE_SHORT(id beLessThanOrEqualTo(NSNumber *expectedValue), + NMB_beLessThanOrEqualTo(expectedValue)); + +NIMBLE_EXPORT id NMB_beTruthy(void); +NIMBLE_SHORT(id beTruthy(void), + NMB_beTruthy()); + +NIMBLE_EXPORT id NMB_beFalsy(void); +NIMBLE_SHORT(id beFalsy(void), + NMB_beFalsy()); + +NIMBLE_EXPORT id NMB_beTrue(void); +NIMBLE_SHORT(id beTrue(void), + NMB_beTrue()); + +NIMBLE_EXPORT id NMB_beFalse(void); +NIMBLE_SHORT(id beFalse(void), + NMB_beFalse()); + +NIMBLE_EXPORT id NMB_beNil(void); +NIMBLE_SHORT(id beNil(void), + NMB_beNil()); + +NIMBLE_EXPORT id NMB_beEmpty(void); +NIMBLE_SHORT(id beEmpty(void), + NMB_beEmpty()); + +NIMBLE_EXPORT id NMB_containWithNilTermination(id itemOrSubstring, ...) NS_REQUIRES_NIL_TERMINATION; +#define NMB_contain(...) NMB_containWithNilTermination(__VA_ARGS__, nil) +#ifndef NIMBLE_DISABLE_SHORT_SYNTAX +#define contain(...) NMB_contain(__VA_ARGS__) +#endif + +NIMBLE_EXPORT id NMB_endWith(id itemElementOrSubstring); +NIMBLE_SHORT(id endWith(id itemElementOrSubstring), + NMB_endWith(itemElementOrSubstring)); + +NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException(void); +NIMBLE_SHORT(NMBObjCRaiseExceptionMatcher *raiseException(void), + NMB_raiseException()); + +NIMBLE_EXPORT id NMB_match(id expectedValue); +NIMBLE_SHORT(id match(id expectedValue), + NMB_match(expectedValue)); + +NIMBLE_EXPORT id NMB_allPass(id matcher); +NIMBLE_SHORT(id allPass(id matcher), + NMB_allPass(matcher)); + +// In order to preserve breakpoint behavior despite using macros to fill in __FILE__ and __LINE__, +// define a builder that populates __FILE__ and __LINE__, and returns a block that takes timeout +// and action arguments. See https://github.com/Quick/Quick/pull/185 for details. +typedef void (^NMBWaitUntilTimeoutBlock)(NSTimeInterval timeout, void (^action)(void (^)(void))); +typedef void (^NMBWaitUntilBlock)(void (^action)(void (^)(void))); + +NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line); +NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger line); + +NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line); + +#define NMB_waitUntilTimeout NMB_waitUntilTimeoutBuilder(@(__FILE__), __LINE__) +#define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__) + +#ifndef NIMBLE_DISABLE_SHORT_SYNTAX +#define expect(...) NMB_expect(^id{ return (__VA_ARGS__); }, @(__FILE__), __LINE__) +#define expectAction(BLOCK) NMB_expectAction((BLOCK), @(__FILE__), __LINE__) +#define failWithMessage(msg) NMB_failWithMessage(msg, @(__FILE__), __LINE__) +#define fail() failWithMessage(@"fail() always fails") + + +#define waitUntilTimeout NMB_waitUntilTimeout +#define waitUntil NMB_waitUntil +#endif diff --git a/Carthage/Checkouts/Nimble/Nimble/objc/DSL.m b/Carthage/Checkouts/Nimble/Nimble/objc/DSL.m new file mode 100644 index 00000000..5065a1a4 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/objc/DSL.m @@ -0,0 +1,138 @@ +#import +#import + +SWIFT_CLASS("_TtC6Nimble7NMBWait") +@interface NMBWait : NSObject + ++ (void)untilTimeout:(NSTimeInterval)timeout file:(NSString *)file line:(NSUInteger)line action:(void(^)())action; ++ (void)untilFile:(NSString *)file line:(NSUInteger)line action:(void(^)())action; + +@end + +NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line) { + return [[NMBExpectation alloc] initWithActualBlock:actualBlock + negative:NO + file:file + line:line]; +} + +NIMBLE_EXPORT NMBExpectation *NMB_expectAction(void(^actualBlock)(), NSString *file, NSUInteger line) { + return NMB_expect(^id{ + actualBlock(); + return nil; + }, file, line); +} + +NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger line) { + return [NMBExpectation failWithMessage:msg file:file line:line]; +} + +NIMBLE_EXPORT id NMB_beAnInstanceOf(Class expectedClass) { + return [NMBObjCMatcher beAnInstanceOfMatcher:expectedClass]; +} + +NIMBLE_EXPORT id NMB_beAKindOf(Class expectedClass) { + return [NMBObjCMatcher beAKindOfMatcher:expectedClass]; +} + +NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { + return [NMBObjCMatcher beCloseToMatcher:expectedValue within:0.001]; +} + +NIMBLE_EXPORT id NMB_beginWith(id itemElementOrSubstring) { + return [NMBObjCMatcher beginWithMatcher:itemElementOrSubstring]; +} + +NIMBLE_EXPORT id NMB_beGreaterThan(NSNumber *expectedValue) { + return [NMBObjCMatcher beGreaterThanMatcher:expectedValue]; +} + +NIMBLE_EXPORT id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { + return [NMBObjCMatcher beGreaterThanOrEqualToMatcher:expectedValue]; +} + +NIMBLE_EXPORT id NMB_beIdenticalTo(id expectedInstance) { + return [NMBObjCMatcher beIdenticalToMatcher:expectedInstance]; +} + +NIMBLE_EXPORT id NMB_beLessThan(NSNumber *expectedValue) { + return [NMBObjCMatcher beLessThanMatcher:expectedValue]; +} + +NIMBLE_EXPORT id NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { + return [NMBObjCMatcher beLessThanOrEqualToMatcher:expectedValue]; +} + +NIMBLE_EXPORT id NMB_beTruthy() { + return [NMBObjCMatcher beTruthyMatcher]; +} + +NIMBLE_EXPORT id NMB_beFalsy() { + return [NMBObjCMatcher beFalsyMatcher]; +} + +NIMBLE_EXPORT id NMB_beTrue() { + return [NMBObjCMatcher beTrueMatcher]; +} + +NIMBLE_EXPORT id NMB_beFalse() { + return [NMBObjCMatcher beFalseMatcher]; +} + +NIMBLE_EXPORT id NMB_beNil() { + return [NMBObjCMatcher beNilMatcher]; +} + +NIMBLE_EXPORT id NMB_beEmpty() { + return [NMBObjCMatcher beEmptyMatcher]; +} + +NIMBLE_EXPORT id NMB_containWithNilTermination(id itemOrSubstring, ...) { + NSMutableArray *itemOrSubstringArray = [NSMutableArray array]; + + if (itemOrSubstring) { + [itemOrSubstringArray addObject:itemOrSubstring]; + + va_list args; + va_start(args, itemOrSubstring); + id next; + while ((next = va_arg(args, id))) { + [itemOrSubstringArray addObject:next]; + } + va_end(args); + } + + return [NMBObjCMatcher containMatcher:itemOrSubstringArray]; +} + +NIMBLE_EXPORT id NMB_endWith(id itemElementOrSubstring) { + return [NMBObjCMatcher endWithMatcher:itemElementOrSubstring]; +} + +NIMBLE_EXPORT id NMB_equal(id expectedValue) { + return [NMBObjCMatcher equalMatcher:expectedValue]; +} + +NIMBLE_EXPORT id NMB_match(id expectedValue) { + return [NMBObjCMatcher matchMatcher:expectedValue]; +} + +NIMBLE_EXPORT id NMB_allPass(id expectedValue) { + return [NMBObjCMatcher allPassMatcher:expectedValue]; +} + +NIMBLE_EXPORT NMBObjCRaiseExceptionMatcher *NMB_raiseException() { + return [NMBObjCMatcher raiseExceptionMatcher]; +} + +NIMBLE_EXPORT NMBWaitUntilTimeoutBlock NMB_waitUntilTimeoutBuilder(NSString *file, NSUInteger line) { + return ^(NSTimeInterval timeout, void (^action)(void (^)(void))) { + [NMBWait untilTimeout:timeout file:file line:line action:action]; + }; +} + +NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger line) { + return ^(void (^action)(void (^)(void))) { + [NMBWait untilFile:file line:line action:action]; + }; +} diff --git a/Carthage/Checkouts/Nimble/Nimble/objc/NMBExceptionCapture.h b/Carthage/Checkouts/Nimble/Nimble/objc/NMBExceptionCapture.h new file mode 100644 index 00000000..8be4a5a6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/objc/NMBExceptionCapture.h @@ -0,0 +1,8 @@ +#import + +@interface NMBExceptionCapture : NSObject + +- (id)initWithHandler:(void(^)(NSException *))handler finally:(void(^)())finally; +- (void)tryBlock:(void(^)())unsafeBlock; + +@end diff --git a/Carthage/Checkouts/Nimble/Nimble/objc/NMBExceptionCapture.m b/Carthage/Checkouts/Nimble/Nimble/objc/NMBExceptionCapture.m new file mode 100644 index 00000000..d19d5d97 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Nimble/objc/NMBExceptionCapture.m @@ -0,0 +1,35 @@ +#import "NMBExceptionCapture.h" + +@interface NMBExceptionCapture () +@property (nonatomic, copy) void(^handler)(NSException *exception); +@property (nonatomic, copy) void(^finally)(); +@end + +@implementation NMBExceptionCapture + +- (id)initWithHandler:(void(^)(NSException *))handler finally:(void(^)())finally { + self = [super init]; + if (self) { + self.handler = handler; + self.finally = finally; + } + return self; +} + +- (void)tryBlock:(void(^)())unsafeBlock { + @try { + unsafeBlock(); + } + @catch (NSException *exception) { + if (self.handler) { + self.handler(exception); + } + } + @finally { + if (self.finally) { + self.finally(); + } + } +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/AsynchronousTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/AsynchronousTest.swift new file mode 100644 index 00000000..75463663 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/AsynchronousTest.swift @@ -0,0 +1,84 @@ +import XCTest +import Nimble +import Swift + +class AsyncTest: XCTestCase { + let errorToThrow = NSError(domain: NSInternalInconsistencyException, code: 42, userInfo: nil) + + private func doThrowError() throws -> Int { + throw errorToThrow + } + + func testAsyncTestingViaEventuallyPositiveMatches() { + var value = 0 + deferToMainQueue { value = 1 } + expect { value }.toEventually(equal(1)) + + deferToMainQueue { value = 0 } + expect { value }.toEventuallyNot(equal(1)) + } + + func testAsyncTestingViaEventuallyNegativeMatches() { + let value = 0 + failsWithErrorMessage("expected to eventually not equal <0>, got <0>") { + expect { value }.toEventuallyNot(equal(0)) + } + failsWithErrorMessage("expected to eventually equal <1>, got <0>") { + expect { value }.toEventually(equal(1)) + } + failsWithErrorMessage("expected to eventually equal <1>, got an unexpected error thrown: <\(errorToThrow)>") { + expect { try self.doThrowError() }.toEventually(equal(1)) + } + failsWithErrorMessage("expected to eventually not equal <0>, got an unexpected error thrown: <\(errorToThrow)>") { + expect { try self.doThrowError() }.toEventuallyNot(equal(0)) + } + } + + func testAsyncTestingViaWaitUntilPositiveMatches() { + waitUntil { done in + done() + } + waitUntil { done in + deferToMainQueue { + done() + } + } + } + + func testAsyncTestingViaWaitUntilNegativeMatches() { + failsWithErrorMessage("Waited more than 1.0 second") { + waitUntil(timeout: 1) { done in return } + } + failsWithErrorMessage("Waited more than 0.01 seconds") { + waitUntil(timeout: 0.01) { done in + NSThread.sleepForTimeInterval(0.1) + done() + } + } + + failsWithErrorMessage("expected to equal <2>, got <1>") { + waitUntil { done in + NSThread.sleepForTimeInterval(0.1) + expect(1).to(equal(2)) + done() + } + } + // "clear" runloop to ensure this test doesn't poison other tests + NSRunLoop.mainRunLoop().runUntilDate(NSDate().dateByAddingTimeInterval(0.2)) + } + + func testWaitUntilDetectsStalledMainThreadActivity() { + dispatch_async(dispatch_get_main_queue()) { + NSThread.sleepForTimeInterval(2.0) + } + + failsWithErrorMessage("Stall on main thread - too much enqueued on main run loop before waitUntil executes.") { + waitUntil { done in + done() + } + } + + // "clear" runloop to ensure this test doesn't poison other tests + NSRunLoop.mainRunLoop().runUntilDate(NSDate().dateByAddingTimeInterval(2.0)) + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Helpers/ObjectWithLazyProperty.swift b/Carthage/Checkouts/Nimble/NimbleTests/Helpers/ObjectWithLazyProperty.swift new file mode 100644 index 00000000..26e5a981 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Helpers/ObjectWithLazyProperty.swift @@ -0,0 +1,7 @@ +import Foundation + +class ObjectWithLazyProperty { + init() {} + lazy var value: String = "hello" + lazy var anotherValue: String = { return "world" }() +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Helpers/utils.swift b/Carthage/Checkouts/Nimble/NimbleTests/Helpers/utils.swift new file mode 100644 index 00000000..5ea394ef --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Helpers/utils.swift @@ -0,0 +1,87 @@ +import Foundation +import Nimble +import XCTest + +func failsWithErrorMessage(messages: [String], file: String = __FILE__, line: UInt = __LINE__, preferOriginalSourceLocation: Bool = false, closure: () throws -> Void) { + var filePath = file + var lineNumber = line + + let recorder = AssertionRecorder() + withAssertionHandler(recorder, closure: closure) + + for msg in messages { + var lastFailure: AssertionRecord? + var foundFailureMessage = false + + for assertion in recorder.assertions { + lastFailure = assertion + if assertion.message.stringValue == msg { + foundFailureMessage = true + break + } + } + + if foundFailureMessage { + continue + } + + if preferOriginalSourceLocation { + if let failure = lastFailure { + filePath = failure.location.file + lineNumber = failure.location.line + } + } + + if let lastFailure = lastFailure { + let msg = "Got failure message: \"\(lastFailure.message.stringValue)\", but expected \"\(msg)\"" + XCTFail(msg, file: filePath, line: lineNumber) + } else { + XCTFail("expected failure message, but got none", file: filePath, line: lineNumber) + } + } +} + +func failsWithErrorMessage(message: String, file: String = __FILE__, line: UInt = __LINE__, preferOriginalSourceLocation: Bool = false, closure: () -> Void) { + return failsWithErrorMessage( + [message], + file: file, + line: line, + preferOriginalSourceLocation: preferOriginalSourceLocation, + closure: closure + ) +} + +func failsWithErrorMessageForNil(message: String, file: String = __FILE__, line: UInt = __LINE__, preferOriginalSourceLocation: Bool = false, closure: () -> Void) { + failsWithErrorMessage("\(message) (use beNil() to match nils)", file: file, line: line, preferOriginalSourceLocation: preferOriginalSourceLocation, closure: closure) +} + +func deferToMainQueue(action: () -> Void) { + dispatch_async(dispatch_get_main_queue()) { + NSThread.sleepForTimeInterval(0.01) + action() + } +} + +public class NimbleHelper : NSObject { + class func expectFailureMessage(message: NSString, block: () -> Void, file: String, line: UInt) { + failsWithErrorMessage(message as String, file: file, line: line, preferOriginalSourceLocation: true, closure: block) + } + + class func expectFailureMessages(messages: [NSString], block: () -> Void, file: String, line: UInt) { + failsWithErrorMessage(messages as! [String], file: file, line: line, preferOriginalSourceLocation: true, closure: block) + } + + class func expectFailureMessageForNil(message: NSString, block: () -> Void, file: String, line: UInt) { + failsWithErrorMessageForNil(message as String, file: file, line: line, preferOriginalSourceLocation: true, closure: block) + } +} + +extension NSDate { + convenience init(dateTimeString:String) { + let dateFormatter = NSDateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" + dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") + let date = dateFormatter.dateFromString(dateTimeString)! + self.init(timeInterval:0, sinceDate:date) + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Info.plist b/Carthage/Checkouts/Nimble/NimbleTests/Info.plist new file mode 100644 index 00000000..6f6b8a6b --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + net.jeffhui.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/AllPassTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/AllPassTest.swift new file mode 100644 index 00000000..14cb87f3 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/AllPassTest.swift @@ -0,0 +1,74 @@ +import XCTest +import Nimble + +class AllPassTest: XCTestCase { + func testAllPassArray() { + expect([1,2,3,4]).to(allPass({$0 < 5})) + expect([1,2,3,4]).toNot(allPass({$0 > 5})) + + failsWithErrorMessage( + "expected to all pass a condition, but failed first at element <3> in <[1, 2, 3, 4]>") { + expect([1,2,3,4]).to(allPass({$0 < 3})) + } + failsWithErrorMessage("expected to not all pass a condition") { + expect([1,2,3,4]).toNot(allPass({$0 < 5})) + } + failsWithErrorMessage( + "expected to all be something, but failed first at element <3> in <[1, 2, 3, 4]>") { + expect([1,2,3,4]).to(allPass("be something", {$0 < 3})) + } + failsWithErrorMessage("expected to not all be something") { + expect([1,2,3,4]).toNot(allPass("be something", {$0 < 5})) + } + } + + func testAllPassMatcher() { + expect([1,2,3,4]).to(allPass(beLessThan(5))) + expect([1,2,3,4]).toNot(allPass(beGreaterThan(5))) + + failsWithErrorMessage( + "expected to all be less than <3>, but failed first at element <3> in <[1, 2, 3, 4]>") { + expect([1,2,3,4]).to(allPass(beLessThan(3))) + } + failsWithErrorMessage("expected to not all be less than <5>") { + expect([1,2,3,4]).toNot(allPass(beLessThan(5))) + } + } + + func testAllPassCollectionsWithOptionalsDontWork() { + failsWithErrorMessage("expected to all be nil, but failed first at element in <[nil, nil, nil]>") { + expect([nil, nil, nil] as [Int?]).to(allPass(beNil())) + } + failsWithErrorMessage("expected to all pass a condition, but failed first at element in <[nil, nil, nil]>") { + expect([nil, nil, nil] as [Int?]).to(allPass({$0 == nil})) + } + } + + func testAllPassCollectionsWithOptionalsUnwrappingOneOptionalLayer() { + expect([nil, nil, nil] as [Int?]).to(allPass({$0! == nil})) + expect([nil, 1, nil] as [Int?]).toNot(allPass({$0! == nil})) + expect([1, 1, 1] as [Int?]).to(allPass({$0! == 1})) + expect([1, 1, nil] as [Int?]).toNot(allPass({$0! == 1})) + expect([1, 2, 3] as [Int?]).to(allPass({$0! < 4})) + expect([1, 2, 3] as [Int?]).toNot(allPass({$0! < 3})) + expect([1, 2, nil] as [Int?]).to(allPass({$0! < 3})) + } + + func testAllPassSet() { + expect(Set([1,2,3,4])).to(allPass({$0 < 5})) + expect(Set([1,2,3,4])).toNot(allPass({$0 > 5})) + + failsWithErrorMessage("expected to not all pass a condition") { + expect(Set([1,2,3,4])).toNot(allPass({$0 < 5})) + } + failsWithErrorMessage("expected to not all be something") { + expect(Set([1,2,3,4])).toNot(allPass("be something", {$0 < 5})) + } + } + + func testAllPassWithNilAsExpectedValue() { + failsWithErrorMessageForNil("expected to all pass") { + expect(nil as [Int]?).to(allPass(beLessThan(5))) + } + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeAKindOfTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeAKindOfTest.swift new file mode 100644 index 00000000..fcd928ae --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeAKindOfTest.swift @@ -0,0 +1,45 @@ +import XCTest +import Nimble + +class TestNull : NSNull {} + +class BeAKindOfTest: XCTestCase { + func testPositiveMatch() { + expect(TestNull()).to(beAKindOf(NSNull)) + expect(NSObject()).to(beAKindOf(NSObject)) + expect(NSNumber(integer:1)).toNot(beAKindOf(NSDate)) + } + + func testFailureMessages() { + failsWithErrorMessageForNil("expected to not be a kind of NSNull, got ") { + expect(nil as NSNull?).toNot(beAKindOf(NSNull)) + } + failsWithErrorMessageForNil("expected to be a kind of NSString, got ") { + expect(nil as NSString?).to(beAKindOf(NSString)) + } + failsWithErrorMessage("expected to be a kind of NSString, got <__NSCFNumber instance>") { + expect(NSNumber(integer:1)).to(beAKindOf(NSString)) + } + failsWithErrorMessage("expected to not be a kind of NSNumber, got <__NSCFNumber instance>") { + expect(NSNumber(integer:1)).toNot(beAKindOf(NSNumber)) + } + } + + func testSwiftTypesFailureMessages() { + enum TestEnum { + case One, Two + } + failsWithErrorMessage("beAKindOf only works on Objective-C types since the Swift compiler" + + " will automatically type check Swift-only types. This expectation is redundant.") { + expect(1).to(beAKindOf(Int)) + } + failsWithErrorMessage("beAKindOf only works on Objective-C types since the Swift compiler" + + " will automatically type check Swift-only types. This expectation is redundant.") { + expect("test").to(beAKindOf(String)) + } + failsWithErrorMessage("beAKindOf only works on Objective-C types since the Swift compiler" + + " will automatically type check Swift-only types. This expectation is redundant.") { + expect(TestEnum.One).to(beAKindOf(TestEnum)) + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeAnInstanceOfTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeAnInstanceOfTest.swift new file mode 100644 index 00000000..ccca989b --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeAnInstanceOfTest.swift @@ -0,0 +1,44 @@ +import XCTest +import Nimble + +class BeAnInstanceOfTest: XCTestCase { + func testPositiveMatch() { + expect(NSNull()).to(beAnInstanceOf(NSNull)) + expect(NSNumber(integer:1)).toNot(beAnInstanceOf(NSDate)) + } + + func testFailureMessages() { + failsWithErrorMessageForNil("expected to not be an instance of NSNull, got ") { + expect(nil as NSNull?).toNot(beAnInstanceOf(NSNull)) + } + failsWithErrorMessageForNil("expected to be an instance of NSString, got ") { + expect(nil as NSString?).to(beAnInstanceOf(NSString)) + } + failsWithErrorMessage("expected to be an instance of NSString, got <__NSCFNumber instance>") { + expect(NSNumber(integer:1)).to(beAnInstanceOf(NSString)) + } + failsWithErrorMessage("expected to not be an instance of NSNumber, got <__NSCFNumber instance>") { + expect(NSNumber(integer:1)).toNot(beAnInstanceOf(NSNumber)) + } + } + + func testSwiftTypesFailureMessages() { + enum TestEnum { + case One, Two + } + + failsWithErrorMessage("beAnInstanceOf only works on Objective-C types since the Swift compiler" + + " will automatically type check Swift-only types. This expectation is redundant.") { + expect(1).to(beAnInstanceOf(Int)) + } + failsWithErrorMessage("beAnInstanceOf only works on Objective-C types since the Swift compiler" + + " will automatically type check Swift-only types. This expectation is redundant.") { + expect("test").to(beAnInstanceOf(String)) + } + failsWithErrorMessage("beAnInstanceOf only works on Objective-C types since the Swift compiler" + + " will automatically type check Swift-only types. This expectation is redundant.") { + expect(TestEnum.One).to(beAnInstanceOf(TestEnum)) + } + } + +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeCloseToTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeCloseToTest.swift new file mode 100644 index 00000000..002accbb --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeCloseToTest.swift @@ -0,0 +1,87 @@ +import XCTest +import Nimble + +class BeCloseToTest: XCTestCase { + func testBeCloseTo() { + expect(1.2).to(beCloseTo(1.2001)) + expect(1.2 as CDouble).to(beCloseTo(1.2001)) + expect(1.2 as Float).to(beCloseTo(1.2001)) + + failsWithErrorMessage("expected to not be close to <1.2001> (within 0.0001), got <1.2000>") { + expect(1.2).toNot(beCloseTo(1.2001)) + } + } + + func testBeCloseToWithin() { + expect(1.2).to(beCloseTo(9.300, within: 10)) + + failsWithErrorMessage("expected to not be close to <1.2001> (within 1.0000), got <1.2000>") { + expect(1.2).toNot(beCloseTo(1.2001, within: 1.0)) + } + } + + func testBeCloseToWithNSNumber() { + expect(NSNumber(double:1.2)).to(beCloseTo(9.300, within: 10)) + expect(NSNumber(double:1.2)).to(beCloseTo(NSNumber(double:9.300), within: 10)) + expect(1.2).to(beCloseTo(NSNumber(double:9.300), within: 10)) + + failsWithErrorMessage("expected to not be close to <1.2001> (within 1.0000), got <1.2000>") { + expect(NSNumber(double:1.2)).toNot(beCloseTo(1.2001, within: 1.0)) + } + } + + func testBeCloseToWithNSDate() { + expect(NSDate(dateTimeString: "2015-08-26 11:43:00")).to(beCloseTo(NSDate(dateTimeString: "2015-08-26 11:43:05"), within: 10)) + + failsWithErrorMessage("expected to not be close to <2015-08-26 11:43:00.0050> (within 0.0040), got <2015-08-26 11:43:00.0000>") { + + let expectedDate = NSDate(dateTimeString: "2015-08-26 11:43:00").dateByAddingTimeInterval(0.005) + expect(NSDate(dateTimeString: "2015-08-26 11:43:00")).toNot(beCloseTo(expectedDate, within: 0.004)) + } + } + + func testBeCloseToOperator() { + expect(1.2) ≈ 1.2001 + expect(1.2 as CDouble) ≈ 1.2001 + + failsWithErrorMessage("expected to be close to <1.2002> (within 0.0001), got <1.2000>") { + expect(1.2) ≈ 1.2002 + } + } + + func testBeCloseToWithinOperator() { + expect(1.2) ≈ (9.300, 10) + expect(1.2) == (9.300, 10) + + failsWithErrorMessage("expected to be close to <1.0000> (within 0.1000), got <1.2000>") { + expect(1.2) ≈ (1.0, 0.1) + } + failsWithErrorMessage("expected to be close to <1.0000> (within 0.1000), got <1.2000>") { + expect(1.2) == (1.0, 0.1) + } + } + + func testPlusMinusOperator() { + expect(1.2) ≈ 9.300 ± 10 + expect(1.2) == 9.300 ± 10 + + failsWithErrorMessage("expected to be close to <1.0000> (within 0.1000), got <1.2000>") { + expect(1.2) ≈ 1.0 ± 0.1 + } + failsWithErrorMessage("expected to be close to <1.0000> (within 0.1000), got <1.2000>") { + expect(1.2) == 1.0 ± 0.1 + } + } + + func testBeCloseToArray() { + expect([0.0, 1.1, 2.2]) ≈ [0.0001, 1.1001, 2.2001] + expect([0.0, 1.1, 2.2]).to(beCloseTo([0.1, 1.2, 2.3], within: 0.1)) + + failsWithErrorMessage("expected to be close to <[0.0000, 1.0000]> (each within 0.0001), got <[0.0, 1.1]>") { + expect([0.0, 1.1]) ≈ [0.0, 1.0] + } + failsWithErrorMessage("expected to be close to <[0.2000, 1.2000]> (each within 0.1000), got <[0.0, 1.1]>") { + expect([0.0, 1.1]).to(beCloseTo([0.2, 1.2], within: 0.1)) + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeEmptyTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeEmptyTest.swift new file mode 100644 index 00000000..e064a070 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeEmptyTest.swift @@ -0,0 +1,53 @@ +import XCTest +import Nimble + +class BeEmptyTest: XCTestCase { + func testBeEmptyPositive() { + expect([] as [Int]).to(beEmpty()) + expect([1]).toNot(beEmpty()) + + expect([] as [CInt]).to(beEmpty()) + expect([1] as [CInt]).toNot(beEmpty()) + + expect(NSDictionary() as? [Int:Int]).to(beEmpty()) + expect(NSDictionary(object: 1, forKey: 1) as? [Int:Int]).toNot(beEmpty()) + + expect(Dictionary()).to(beEmpty()) + expect(["hi": 1]).toNot(beEmpty()) + + expect(NSArray() as? [Int]).to(beEmpty()) + expect(NSArray(array: [1]) as? [Int]).toNot(beEmpty()) + + expect(NSSet()).to(beEmpty()) + expect(NSSet(array: [1])).toNot(beEmpty()) + + expect(NSString()).to(beEmpty()) + expect(NSString(string: "hello")).toNot(beEmpty()) + + expect("").to(beEmpty()) + expect("foo").toNot(beEmpty()) + } + + func testBeEmptyNegative() { + failsWithErrorMessageForNil("expected to be empty, got ") { + expect(nil as NSString?).to(beEmpty()) + } + failsWithErrorMessageForNil("expected to not be empty, got ") { + expect(nil as [CInt]?).toNot(beEmpty()) + } + + failsWithErrorMessage("expected to not be empty, got <()>") { + expect([]).toNot(beEmpty()) + } + failsWithErrorMessage("expected to be empty, got <[1]>") { + expect([1]).to(beEmpty()) + } + + failsWithErrorMessage("expected to not be empty, got <>") { + expect("").toNot(beEmpty()) + } + failsWithErrorMessage("expected to be empty, got ") { + expect("foo").to(beEmpty()) + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeGreaterThanOrEqualToTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeGreaterThanOrEqualToTest.swift new file mode 100644 index 00000000..90aa2422 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeGreaterThanOrEqualToTest.swift @@ -0,0 +1,41 @@ +import XCTest +import Nimble + +class BeGreaterThanOrEqualToTest: XCTestCase { + + func testGreaterThanOrEqualTo() { + expect(10).to(beGreaterThanOrEqualTo(10)) + expect(10).to(beGreaterThanOrEqualTo(2)) + expect(1).toNot(beGreaterThanOrEqualTo(2)) + expect(NSNumber(int:1)).toNot(beGreaterThanOrEqualTo(2)) + expect(NSNumber(int:2)).to(beGreaterThanOrEqualTo(NSNumber(int:2))) + expect(1).to(beGreaterThanOrEqualTo(NSNumber(int:0))) + + failsWithErrorMessage("expected to be greater than or equal to <2>, got <0>") { + expect(0).to(beGreaterThanOrEqualTo(2)) + return + } + failsWithErrorMessage("expected to not be greater than or equal to <1>, got <1>") { + expect(1).toNot(beGreaterThanOrEqualTo(1)) + return + } + failsWithErrorMessageForNil("expected to be greater than or equal to <-2>, got ") { + expect(nil as Int?).to(beGreaterThanOrEqualTo(-2)) + } + failsWithErrorMessageForNil("expected to not be greater than or equal to <1>, got ") { + expect(nil as Int?).toNot(beGreaterThanOrEqualTo(1)) + } + } + + func testGreaterThanOrEqualToOperator() { + expect(0) >= 0 + expect(1) >= 0 + expect(NSNumber(int:1)) >= 1 + expect(NSNumber(int:1)) >= NSNumber(int:1) + + failsWithErrorMessage("expected to be greater than or equal to <2>, got <1>") { + expect(1) >= 2 + return + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeGreaterThanTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeGreaterThanTest.swift new file mode 100644 index 00000000..7a62e633 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeGreaterThanTest.swift @@ -0,0 +1,35 @@ +import XCTest +import Nimble + +class BeGreaterThanTest: XCTestCase { + func testGreaterThan() { + expect(10).to(beGreaterThan(2)) + expect(1).toNot(beGreaterThan(2)) + expect(NSNumber(int:3)).to(beGreaterThan(2)) + expect(NSNumber(int:1)).toNot(beGreaterThan(NSNumber(int:2))) + + failsWithErrorMessage("expected to be greater than <2>, got <0>") { + expect(0).to(beGreaterThan(2)) + } + failsWithErrorMessage("expected to not be greater than <0>, got <1>") { + expect(1).toNot(beGreaterThan(0)) + } + failsWithErrorMessageForNil("expected to be greater than <-2>, got ") { + expect(nil as Int?).to(beGreaterThan(-2)) + } + failsWithErrorMessageForNil("expected to not be greater than <0>, got ") { + expect(nil as Int?).toNot(beGreaterThan(0)) + } + } + + func testGreaterThanOperator() { + expect(1) > 0 + expect(NSNumber(int:1)) > NSNumber(int:0) + expect(NSNumber(int:1)) > 0 + + failsWithErrorMessage("expected to be greater than <2.0000>, got <1.0000>") { + expect(1) > 2 + return + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeIdenticalToObjectTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeIdenticalToObjectTest.swift new file mode 100644 index 00000000..90180af3 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeIdenticalToObjectTest.swift @@ -0,0 +1,52 @@ +import XCTest +import Nimble + +class BeIdenticalToObjectTest: XCTestCase { + private class BeIdenticalToObjectTester {} + private let testObjectA = BeIdenticalToObjectTester() + private let testObjectB = BeIdenticalToObjectTester() + + func testBeIdenticalToPositive() { + expect(self.testObjectA).to(beIdenticalTo(testObjectA)) + } + + func testBeIdenticalToNegative() { + expect(self.testObjectA).toNot(beIdenticalTo(testObjectB)) + } + + func testBeIdenticalToPositiveMessage() { + let message = String(format: "expected to be identical to <%p>, got <%p>", + unsafeBitCast(testObjectB, Int.self), unsafeBitCast(testObjectA, Int.self)) + failsWithErrorMessage(message) { + expect(self.testObjectA).to(beIdenticalTo(self.testObjectB)) + } + } + + func testBeIdenticalToNegativeMessage() { + let message = String(format: "expected to not be identical to <%p>, got <%p>", + unsafeBitCast(testObjectA, Int.self), unsafeBitCast(testObjectA, Int.self)) + failsWithErrorMessage(message) { + expect(self.testObjectA).toNot(beIdenticalTo(self.testObjectA)) + } + } + + func testFailsOnNils() { + let message1 = String(format: "expected to be identical to <%p>, got nil", + unsafeBitCast(testObjectA, Int.self)) + failsWithErrorMessageForNil(message1) { + expect(nil as BeIdenticalToObjectTester?).to(beIdenticalTo(self.testObjectA)) + } + + let message2 = String(format: "expected to not be identical to <%p>, got nil", + unsafeBitCast(testObjectA, Int.self)) + failsWithErrorMessageForNil(message2) { + expect(nil as BeIdenticalToObjectTester?).toNot(beIdenticalTo(self.testObjectA)) + } + } + + func testOperators() { + expect(self.testObjectA) === testObjectA + expect(self.testObjectA) !== testObjectB + } + +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeIdenticalToTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeIdenticalToTest.swift new file mode 100644 index 00000000..bca3cc39 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeIdenticalToTest.swift @@ -0,0 +1,36 @@ +import XCTest +import Nimble + +class BeIdenticalToTest: XCTestCase { + func testBeIdenticalToPositive() { + expect(NSNumber(integer:1)).to(beIdenticalTo(NSNumber(integer:1))) + } + + func testBeIdenticalToNegative() { + expect(NSNumber(integer:1)).toNot(beIdenticalTo("yo")) + expect([1]).toNot(beIdenticalTo([1])) + } + + func testBeIdenticalToPositiveMessage() { + let num1 = NSNumber(integer:1) + let num2 = NSNumber(integer:2) + let message = NSString(format: "expected to be identical to <%p>, got <%p>", num2, num1) + failsWithErrorMessage(message.description) { + expect(num1).to(beIdenticalTo(num2)) + } + } + + func testBeIdenticalToNegativeMessage() { + let value1 = NSArray(array: []) + let value2 = NSArray(array: []) + let message = NSString(format: "expected to not be identical to <%p>, got <%p>", value2, value1) + failsWithErrorMessage(message.description) { + expect(value1).toNot(beIdenticalTo(value2)) + } + } + + func testOperators() { + expect(NSNumber(integer:1)) === NSNumber(integer:1) + expect(NSNumber(integer:1)) !== NSNumber(integer:2) + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLessThanOrEqualToTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLessThanOrEqualToTest.swift new file mode 100644 index 00000000..889ecbc4 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLessThanOrEqualToTest.swift @@ -0,0 +1,42 @@ +import XCTest +import Nimble + +class BeLessThanOrEqualToTest: XCTestCase { + func testLessThanOrEqualTo() { + expect(10).to(beLessThanOrEqualTo(10)) + expect(2).to(beLessThanOrEqualTo(10)) + expect(2).toNot(beLessThanOrEqualTo(1)) + + expect(NSNumber(int:2)).to(beLessThanOrEqualTo(10)) + expect(NSNumber(int:2)).toNot(beLessThanOrEqualTo(1)) + expect(2).to(beLessThanOrEqualTo(NSNumber(int:10))) + expect(2).toNot(beLessThanOrEqualTo(NSNumber(int:1))) + + failsWithErrorMessage("expected to be less than or equal to <0>, got <2>") { + expect(2).to(beLessThanOrEqualTo(0)) + return + } + failsWithErrorMessage("expected to not be less than or equal to <0>, got <0>") { + expect(0).toNot(beLessThanOrEqualTo(0)) + return + } + failsWithErrorMessageForNil("expected to be less than or equal to <2>, got ") { + expect(nil as Int?).to(beLessThanOrEqualTo(2)) + return + } + failsWithErrorMessageForNil("expected to not be less than or equal to <-2>, got ") { + expect(nil as Int?).toNot(beLessThanOrEqualTo(-2)) + return + } + } + + func testLessThanOrEqualToOperator() { + expect(0) <= 1 + expect(1) <= 1 + + failsWithErrorMessage("expected to be less than or equal to <1>, got <2>") { + expect(2) <= 1 + return + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLessThanTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLessThanTest.swift new file mode 100644 index 00000000..602f6dfd --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLessThanTest.swift @@ -0,0 +1,39 @@ +import XCTest +import Nimble + +class BeLessThanTest: XCTestCase { + + func testLessThan() { + expect(2).to(beLessThan(10)) + expect(2).toNot(beLessThan(1)) + expect(NSNumber(integer:2)).to(beLessThan(10)) + expect(NSNumber(integer:2)).toNot(beLessThan(1)) + + expect(2).to(beLessThan(NSNumber(integer:10))) + expect(2).toNot(beLessThan(NSNumber(integer:1))) + + failsWithErrorMessage("expected to be less than <0>, got <2>") { + expect(2).to(beLessThan(0)) + } + failsWithErrorMessage("expected to not be less than <1>, got <0>") { + expect(0).toNot(beLessThan(1)) + } + + failsWithErrorMessageForNil("expected to be less than <2>, got ") { + expect(nil as Int?).to(beLessThan(2)) + } + failsWithErrorMessageForNil("expected to not be less than <-1>, got ") { + expect(nil as Int?).toNot(beLessThan(-1)) + } + } + + func testLessThanOperator() { + expect(0) < 1 + expect(NSNumber(int:0)) < 1 + + failsWithErrorMessage("expected to be less than <1.0000>, got <2.0000>") { + expect(2) < 1 + return + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLogicalTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLogicalTest.swift new file mode 100644 index 00000000..b34cc15d --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeLogicalTest.swift @@ -0,0 +1,166 @@ +import XCTest +import Nimble + +enum ConvertsToBool : BooleanType, CustomStringConvertible { + case TrueLike, FalseLike + + var boolValue : Bool { + switch self { + case .TrueLike: return true + case .FalseLike: return false + } + } + + var description : String { + switch self { + case .TrueLike: return "TrueLike" + case .FalseLike: return "FalseLike" + } + } +} + +class BeTruthyTest : XCTestCase { + func testShouldMatchNonNilTypes() { + expect(true as Bool?).to(beTruthy()) + expect(1 as Int?).to(beTruthy()) + } + + func testShouldMatchTrue() { + expect(true).to(beTruthy()) + + failsWithErrorMessage("expected to not be truthy, got ") { + expect(true).toNot(beTruthy()) + } + } + + func testShouldNotMatchNilTypes() { + expect(false as Bool?).toNot(beTruthy()) + expect(nil as Bool?).toNot(beTruthy()) + expect(nil as Int?).toNot(beTruthy()) + } + + func testShouldNotMatchFalse() { + expect(false).toNot(beTruthy()) + + failsWithErrorMessage("expected to be truthy, got ") { + expect(false).to(beTruthy()) + } + } + + func testShouldNotMatchNilBools() { + expect(nil as Bool?).toNot(beTruthy()) + + failsWithErrorMessage("expected to be truthy, got ") { + expect(nil as Bool?).to(beTruthy()) + } + } + + func testShouldMatchBoolConvertibleTypesThatConvertToTrue() { + expect(ConvertsToBool.TrueLike).to(beTruthy()) + + failsWithErrorMessage("expected to not be truthy, got ") { + expect(ConvertsToBool.TrueLike).toNot(beTruthy()) + } + } + + func testShouldNotMatchBoolConvertibleTypesThatConvertToFalse() { + expect(ConvertsToBool.FalseLike).toNot(beTruthy()) + + failsWithErrorMessage("expected to be truthy, got ") { + expect(ConvertsToBool.FalseLike).to(beTruthy()) + } + } +} + +class BeTrueTest : XCTestCase { + func testShouldMatchTrue() { + expect(true).to(beTrue()) + + failsWithErrorMessage("expected to not be true, got ") { + expect(true).toNot(beTrue()) + } + } + + func testShouldNotMatchFalse() { + expect(false).toNot(beTrue()) + + failsWithErrorMessage("expected to be true, got ") { + expect(false).to(beTrue()) + } + } + + func testShouldNotMatchNilBools() { + failsWithErrorMessageForNil("expected to not be true, got ") { + expect(nil as Bool?).toNot(beTrue()) + } + + failsWithErrorMessageForNil("expected to be true, got ") { + expect(nil as Bool?).to(beTrue()) + } + } +} + +class BeFalsyTest : XCTestCase { + func testShouldMatchNilTypes() { + expect(false as Bool?).to(beFalsy()) + expect(nil as Bool?).to(beFalsy()) + expect(nil as Int?).to(beFalsy()) + } + + func testShouldNotMatchTrue() { + expect(true).toNot(beFalsy()) + + failsWithErrorMessage("expected to be falsy, got ") { + expect(true).to(beFalsy()) + } + } + + func testShouldNotMatchNonNilTypes() { + expect(true as Bool?).toNot(beFalsy()) + expect(1 as Int?).toNot(beFalsy()) + } + + func testShouldMatchFalse() { + expect(false).to(beFalsy()) + + failsWithErrorMessage("expected to not be falsy, got ") { + expect(false).toNot(beFalsy()) + } + } + + func testShouldMatchNilBools() { + expect(nil as Bool?).to(beFalsy()) + + failsWithErrorMessage("expected to not be falsy, got ") { + expect(nil as Bool?).toNot(beFalsy()) + } + } +} + +class BeFalseTest : XCTestCase { + func testShouldNotMatchTrue() { + expect(true).toNot(beFalse()) + + failsWithErrorMessage("expected to be false, got ") { + expect(true).to(beFalse()) + } + } + + func testShouldMatchFalse() { + expect(false).to(beFalse()) + + failsWithErrorMessage("expected to not be false, got ") { + expect(false).toNot(beFalse()) + } + } + + func testShouldNotMatchNilBools() { + failsWithErrorMessageForNil("expected to be false, got ") { + expect(nil as Bool?).to(beFalse()) + } + + failsWithErrorMessageForNil("expected to not be false, got ") { + expect(nil as Bool?).toNot(beFalse()) + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeNilTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeNilTest.swift new file mode 100644 index 00000000..1f27bdfd --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeNilTest.swift @@ -0,0 +1,22 @@ +import XCTest +import Nimble + +class BeNilTest: XCTestCase { + func producesNil() -> Array? { + return nil + } + + func testBeNil() { + expect(nil as Int?).to(beNil()) + expect(1 as Int?).toNot(beNil()) + expect(self.producesNil()).to(beNil()) + + failsWithErrorMessage("expected to not be nil, got ") { + expect(nil as Int?).toNot(beNil()) + } + + failsWithErrorMessage("expected to be nil, got <1>") { + expect(1 as Int?).to(beNil()) + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeginWithTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeginWithTest.swift new file mode 100644 index 00000000..f2453f59 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/BeginWithTest.swift @@ -0,0 +1,42 @@ +import XCTest +import Nimble + +class BeginWithTest: XCTestCase { + + func testPositiveMatches() { + expect([1, 2, 3]).to(beginWith(1)) + expect([1, 2, 3]).toNot(beginWith(2)) + + expect("foobar").to(beginWith("foo")) + expect("foobar").toNot(beginWith("oo")) + + expect(NSString(string: "foobar").description).to(beginWith("foo")) + expect(NSString(string: "foobar").description).toNot(beginWith("oo")) + + expect(NSArray(array: ["a", "b"])).to(beginWith("a")) + expect(NSArray(array: ["a", "b"])).toNot(beginWith("b")) + } + + func testNegativeMatches() { + failsWithErrorMessageForNil("expected to begin with , got ") { + expect(nil as NSArray?).to(beginWith("b")) + } + failsWithErrorMessageForNil("expected to not begin with , got ") { + expect(nil as NSArray?).toNot(beginWith("b")) + } + + failsWithErrorMessage("expected to begin with <2>, got <[1, 2, 3]>") { + expect([1, 2, 3]).to(beginWith(2)) + } + failsWithErrorMessage("expected to not begin with <1>, got <[1, 2, 3]>") { + expect([1, 2, 3]).toNot(beginWith(1)) + } + failsWithErrorMessage("expected to begin with , got ") { + expect("batman").to(beginWith("atm")) + } + failsWithErrorMessage("expected to not begin with , got ") { + expect("batman").toNot(beginWith("bat")) + } + } + +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/ContainTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/ContainTest.swift new file mode 100644 index 00000000..e2d6952a --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/ContainTest.swift @@ -0,0 +1,65 @@ +import XCTest +import Nimble + +class ContainTest: XCTestCase { + func testContain() { + expect([1, 2, 3]).to(contain(1)) + expect([1, 2, 3] as [CInt]).to(contain(1 as CInt)) + expect([1, 2, 3] as Array).to(contain(1 as CInt)) + expect(["foo", "bar", "baz"]).to(contain("baz")) + expect([1, 2, 3]).toNot(contain(4)) + expect(["foo", "bar", "baz"]).toNot(contain("ba")) + expect(NSArray(array: ["a"])).to(contain("a")) + expect(NSArray(array: ["a"])).toNot(contain("b")) + expect(NSArray(object: 1) as NSArray?).to(contain(1)) + + failsWithErrorMessage("expected to contain , got <[\"a\", \"b\", \"c\"]>") { + expect(["a", "b", "c"]).to(contain("bar")) + } + failsWithErrorMessage("expected to not contain , got <[\"a\", \"b\", \"c\"]>") { + expect(["a", "b", "c"]).toNot(contain("b")) + } + + failsWithErrorMessageForNil("expected to contain , got ") { + expect(nil as [String]?).to(contain("bar")) + } + failsWithErrorMessageForNil("expected to not contain , got ") { + expect(nil as [String]?).toNot(contain("b")) + } + } + + func testContainSubstring() { + expect("foo").to(contain("o")) + expect("foo").to(contain("oo")) + expect("foo").toNot(contain("z")) + expect("foo").toNot(contain("zz")) + + failsWithErrorMessage("expected to contain , got ") { + expect("foo").to(contain("bar")) + } + failsWithErrorMessage("expected to not contain , got ") { + expect("foo").toNot(contain("oo")) + } + } + + func testContainObjCSubstring() { + let str = NSString(string: "foo") + expect(str).to(contain(NSString(string: "o"))) + expect(str).to(contain(NSString(string: "oo"))) + expect(str).toNot(contain(NSString(string: "z"))) + expect(str).toNot(contain(NSString(string: "zz"))) + } + + func testVariadicArguments() { + expect([1, 2, 3]).to(contain(1, 2)) + expect([1, 2, 3]).toNot(contain(1, 4)) + + failsWithErrorMessage("expected to contain , got <[\"a\", \"b\", \"c\"]>") { + expect(["a", "b", "c"]).to(contain("a", "bar")) + } + + failsWithErrorMessage("expected to not contain , got <[\"a\", \"b\", \"c\"]>") { + expect(["a", "b", "c"]).toNot(contain("bar", "b")) + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/EndWithTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/EndWithTest.swift new file mode 100644 index 00000000..ab3378b8 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/EndWithTest.swift @@ -0,0 +1,42 @@ +import XCTest +import Nimble + +class EndWithTest: XCTestCase { + + func testEndWithPositives() { + expect([1, 2, 3]).to(endWith(3)) + expect([1, 2, 3]).toNot(endWith(2)) + + expect("foobar").to(endWith("bar")) + expect("foobar").toNot(endWith("oo")) + + expect(NSString(string: "foobar").description).to(endWith("bar")) + expect(NSString(string: "foobar").description).toNot(endWith("oo")) + + expect(NSArray(array: ["a", "b"])).to(endWith("b")) + expect(NSArray(array: ["a", "b"])).toNot(endWith("a")) + } + + func testEndWithNegatives() { + failsWithErrorMessageForNil("expected to end with <2>, got ") { + expect(nil as [Int]?).to(endWith(2)) + } + failsWithErrorMessageForNil("expected to not end with <2>, got ") { + expect(nil as [Int]?).toNot(endWith(2)) + } + + failsWithErrorMessage("expected to end with <2>, got <[1, 2, 3]>") { + expect([1, 2, 3]).to(endWith(2)) + } + failsWithErrorMessage("expected to not end with <3>, got <[1, 2, 3]>") { + expect([1, 2, 3]).toNot(endWith(3)) + } + failsWithErrorMessage("expected to end with , got ") { + expect("batman").to(endWith("atm")) + } + failsWithErrorMessage("expected to not end with , got ") { + expect("batman").toNot(endWith("man")) + } + } + +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/EqualTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/EqualTest.swift new file mode 100644 index 00000000..decdb1da --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/EqualTest.swift @@ -0,0 +1,201 @@ +import XCTest +import Nimble + +class EqualTest: XCTestCase { + func testEquality() { + expect(1 as CInt).to(equal(1 as CInt)) + expect(1 as CInt).to(equal(1)) + expect(1).to(equal(1)) + expect("hello").to(equal("hello")) + expect("hello").toNot(equal("world")) + + expect { + 1 + }.to(equal(1)) + + failsWithErrorMessage("expected to equal , got ") { + expect("hello").to(equal("world")) + } + failsWithErrorMessage("expected to not equal , got ") { + expect("hello").toNot(equal("hello")) + } + } + + func testArrayEquality() { + expect([1, 2, 3]).to(equal([1, 2, 3])) + expect([1, 2, 3]).toNot(equal([1, 2])) + expect([1, 2, 3]).toNot(equal([1, 2, 4])) + + let array1: Array = [1, 2, 3] + let array2: Array = [1, 2, 3] + expect(array1).to(equal(array2)) + expect(array1).to(equal([1, 2, 3])) + expect(array1).toNot(equal([1, 2] as Array)) + + expect(NSArray(array: [1, 2, 3])).to(equal(NSArray(array: [1, 2, 3]))) + + failsWithErrorMessage("expected to equal <[1, 2]>, got <[1, 2, 3]>") { + expect([1, 2, 3]).to(equal([1, 2])) + } + } + + func testSetEquality() { + expect(Set([1, 2])).to(equal(Set([1, 2]))) + expect(Set()).to(equal(Set())) + expect(Set()) == Set() + expect(Set([1, 2])) != Set() + + failsWithErrorMessageForNil("expected to equal <[1, 2]>, got ") { + expect(nil as Set?).to(equal(Set([1, 2]))) + } + + failsWithErrorMessage("expected to equal <[1, 2, 3]>, got <[2, 3]>, missing <[1]>") { + expect(Set([2, 3])).to(equal(Set([1, 2, 3]))) + } + + failsWithErrorMessage("expected to equal <[1, 2, 3]>, got <[1, 2, 3, 4]>, extra <[4]>") { + expect(Set([1, 2, 3, 4])).to(equal(Set([1, 2, 3]))) + } + + failsWithErrorMessage("expected to equal <[1, 2, 3]>, got <[2, 3, 4]>, missing <[1]>, extra <[4]>") { + expect(Set([2, 3, 4])).to(equal(Set([1, 2, 3]))) + } + + failsWithErrorMessage("expected to equal <[1, 2, 3]>, got <[2, 3, 4]>, missing <[1]>, extra <[4]>") { + expect(Set([2, 3, 4])) == Set([1, 2, 3]) + } + + failsWithErrorMessage("expected to not equal <[1, 2, 3]>, got <[1, 2, 3]>") { + expect(Set([1, 2, 3])) != Set([1, 2, 3]) + } + } + + func testDoesNotMatchNils() { + failsWithErrorMessageForNil("expected to equal , got ") { + expect(nil as String?).to(equal(nil as String?)) + } + failsWithErrorMessageForNil("expected to not equal , got ") { + expect("foo").toNot(equal(nil as String?)) + } + failsWithErrorMessageForNil("expected to not equal , got ") { + expect(nil as String?).toNot(equal("bar")) + } + + failsWithErrorMessageForNil("expected to equal , got ") { + expect(nil as [Int]?).to(equal(nil as [Int]?)) + } + failsWithErrorMessageForNil("expected to not equal <[1]>, got ") { + expect(nil as [Int]?).toNot(equal([1])) + } + failsWithErrorMessageForNil("expected to not equal , got <[1]>") { + expect([1]).toNot(equal(nil as [Int]?)) + } + + failsWithErrorMessageForNil("expected to equal , got ") { + expect(nil as [Int: Int]?).to(equal(nil as [Int: Int]?)) + } + failsWithErrorMessageForNil("expected to not equal <[1: 1]>, got ") { + expect(nil as [Int: Int]?).toNot(equal([1: 1])) + } + failsWithErrorMessageForNil("expected to not equal , got <[1: 1]>") { + expect([1: 1]).toNot(equal(nil as [Int: Int]?)) + } + } + + func testDictionaryEquality() { + expect(["foo": "bar"]).to(equal(["foo": "bar"])) + expect(["foo": "bar"]).toNot(equal(["foo": "baz"])) + + let actual = ["foo": "bar"] + let expected = ["foo": "bar"] + let unexpected = ["foo": "baz"] + expect(actual).to(equal(expected)) + expect(actual).toNot(equal(unexpected)) + + expect(NSDictionary(object: "bar", forKey: "foo")).to(equal(["foo": "bar"])) + expect(NSDictionary(object: "bar", forKey: "foo")).to(equal(expected)) + } + + func testNSObjectEquality() { + expect(NSNumber(integer:1)).to(equal(NSNumber(integer:1))) + expect(NSNumber(integer:1)) == NSNumber(integer:1) + expect(NSNumber(integer:1)) != NSNumber(integer:2) + expect { NSNumber(integer:1) }.to(equal(1)) + } + + func testOperatorEquality() { + expect("foo") == "foo" + expect("foo") != "bar" + + failsWithErrorMessage("expected to equal , got ") { + expect("hello") == "world" + return + } + failsWithErrorMessage("expected to not equal , got ") { + expect("hello") != "hello" + return + } + } + + func testOperatorEqualityWithArrays() { + let array1: Array = [1, 2, 3] + let array2: Array = [1, 2, 3] + let array3: Array = [1, 2] + expect(array1) == array2 + expect(array1) != array3 + } + + func testOperatorEqualityWithDictionaries() { + let dict1 = ["foo": "bar"] + let dict2 = ["foo": "bar"] + let dict3 = ["foo": "baz"] + expect(dict1) == dict2 + expect(dict1) != dict3 + } + + func testOptionalEquality() { + expect(1 as CInt?).to(equal(1)) + expect(1 as CInt?).to(equal(1 as CInt?)) + + expect(1).toNot(equal(nil)) + } + + func testDictionariesWithDifferentSequences() { + // see: https://github.com/Quick/Nimble/issues/61 + // these dictionaries generate different orderings of sequences. + let result = ["how":1, "think":1, "didnt":2, "because":1, + "interesting":1, "always":1, "right":1, "such":1, + "to":3, "say":1, "cool":1, "you":1, + "weather":3, "be":1, "went":1, "was":2, + "sometimes":1, "and":3, "mind":1, "rain":1, + "whole":1, "everything":1, "weather.":1, "down":1, + "kind":1, "mood.":1, "it":2, "everyday":1, "might":1, + "more":1, "have":2, "person":1, "could":1, "tenth":2, + "night":1, "write":1, "Youd":1, "affects":1, "of":3, + "Who":1, "us":1, "an":1, "I":4, "my":1, "much":2, + "wrong.":1, "peacefully.":1, "amazing":3, "would":4, + "just":1, "grade.":1, "Its":2, "The":2, "had":1, "that":1, + "the":5, "best":1, "but":1, "essay":1, "for":1, "summer":2, + "your":1, "grade":1, "vary":1, "pretty":1, "at":1, "rain.":1, + "about":1, "allow":1, "thought":1, "in":1, "sleep":1, "a":1, + "hot":1, "really":1, "beach":1, "life.":1, "we":1, "although":1] + + let storyCount = ["The":2, "summer":2, "of":3, "tenth":2, "grade":1, + "was":2, "the":5, "best":1, "my":1, "life.":1, "I":4, + "went":1, "to":3, "beach":1, "everyday":1, "and":3, + "we":1, "had":1, "amazing":3, "weather.":1, "weather":3, + "didnt":2, "really":1, "vary":1, "much":2, "always":1, + "pretty":1, "hot":1, "although":1, "sometimes":1, "at":1, + "night":1, "it":2, "would":4, "rain.":1, "mind":1, "rain":1, + "because":1, "cool":1, "everything":1, "down":1, "allow":1, + "us":1, "sleep":1, "peacefully.":1, "Its":2, "how":1, + "affects":1, "your":1, "mood.":1, "Who":1, "have":2, + "thought":1, "that":1, "could":1, "write":1, "a":1, + "whole":1, "essay":1, "just":1, "about":1, "in":1, + "grade.":1, "kind":1, "right":1, "Youd":1, "think":1, + "for":1, "such":1, "an":1, "interesting":1, "person":1, + "might":1, "more":1, "say":1, "but":1, "you":1, "be":1, "wrong.":1] + + expect(result).to(equal(storyCount)) + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/MatchTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/MatchTest.swift new file mode 100644 index 00000000..b13c6d1f --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/MatchTest.swift @@ -0,0 +1,36 @@ +import XCTest +import Nimble + +class MatchTest:XCTestCase { + func testMatchPositive() { + expect("11:14").to(match("\\d{2}:\\d{2}")) + } + + func testMatchNegative() { + expect("hello").toNot(match("\\d{2}:\\d{2}")) + } + + func testMatchPositiveMessage() { + let message = "expected to match <\\d{2}:\\d{2}>, got " + failsWithErrorMessage(message) { + expect("hello").to(match("\\d{2}:\\d{2}")) + } + } + + func testMatchNegativeMessage() { + let message = "expected to not match <\\d{2}:\\d{2}>, got <11:14>" + failsWithErrorMessage(message) { + expect("11:14").toNot(match("\\d{2}:\\d{2}")) + } + } + + func testMatchNils() { + failsWithErrorMessageForNil("expected to match <\\d{2}:\\d{2}>, got ") { + expect(nil as String?).to(match("\\d{2}:\\d{2}")) + } + + failsWithErrorMessageForNil("expected to not match <\\d{2}:\\d{2}>, got ") { + expect(nil as String?).toNot(match("\\d{2}:\\d{2}")) + } + } +} \ No newline at end of file diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/RaisesExceptionTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/RaisesExceptionTest.swift new file mode 100644 index 00000000..9d9cc5fd --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/RaisesExceptionTest.swift @@ -0,0 +1,153 @@ +import XCTest +import Nimble + +class RaisesExceptionTest: XCTestCase { + var anException = NSException(name: "laugh", reason: "Lulz", userInfo: ["key": "value"]) + + func testPositiveMatches() { + expect { self.anException.raise() }.to(raiseException()) + expect { self.anException.raise() }.to(raiseException(named: "laugh")) + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz")) + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz", userInfo: ["key": "value"])) + } + + func testPositiveMatchesWithClosures() { + expect { self.anException.raise() }.to(raiseException { (exception: NSException) in + expect(exception.name).to(equal("laugh")) + }) + expect { self.anException.raise() }.to(raiseException(named: "laugh") { (exception: NSException) in + expect(exception.name).to(beginWith("lau")) + }) + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz") { (exception: NSException) in + expect(exception.name).to(beginWith("lau")) + }) + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz", userInfo: ["key": "value"]) { (exception: NSException) in + expect(exception.name).to(beginWith("lau")) + }) + + expect { self.anException.raise() }.to(raiseException(named: "laugh") { (exception: NSException) in + expect(exception.name).toNot(beginWith("as")) + }) + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz") { (exception: NSException) in + expect(exception.name).toNot(beginWith("df")) + }) + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz", userInfo: ["key": "value"]) { (exception: NSException) in + expect(exception.name).toNot(beginWith("as")) + }) + } + + func testNegativeMatches() { + failsWithErrorMessage("expected to raise exception with name , got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.to(raiseException(named: "foo")) + } + + failsWithErrorMessage("expected to raise exception with name with reason , got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "bar")) + } + + failsWithErrorMessage( + "expected to raise exception with name with reason with userInfo <{k = v;}>, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz", userInfo: ["k": "v"])) + } + + failsWithErrorMessage("expected to raise any exception, got no exception") { + expect { self.anException }.to(raiseException()) + } + failsWithErrorMessage("expected to not raise any exception, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.toNot(raiseException()) + } + failsWithErrorMessage("expected to raise exception with name with reason , got no exception") { + expect { self.anException }.to(raiseException(named: "laugh", reason: "Lulz")) + } + + failsWithErrorMessage("expected to raise exception with name with reason , got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.to(raiseException(named: "bar", reason: "Lulz")) + } + failsWithErrorMessage("expected to not raise exception with name , got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.toNot(raiseException(named: "laugh")) + } + failsWithErrorMessage("expected to not raise exception with name with reason , got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.toNot(raiseException(named: "laugh", reason: "Lulz")) + } + + failsWithErrorMessage("expected to not raise exception with name with reason with userInfo <{key = value;}>, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.toNot(raiseException(named: "laugh", reason: "Lulz", userInfo: ["key": "value"])) + } + } + + func testNegativeMatchesDoNotCallClosureWithoutException() { + failsWithErrorMessage("expected to raise exception that satisfies block, got no exception") { + expect { self.anException }.to(raiseException { (exception: NSException) in + expect(exception.name).to(equal("foo")) + }) + } + + failsWithErrorMessage("expected to raise exception with name that satisfies block, got no exception") { + expect { self.anException }.to(raiseException(named: "foo") { (exception: NSException) in + expect(exception.name).to(equal("foo")) + }) + } + + failsWithErrorMessage("expected to raise exception with name with reason that satisfies block, got no exception") { + expect { self.anException }.to(raiseException(named: "foo", reason: "ha") { (exception: NSException) in + expect(exception.name).to(equal("foo")) + }) + } + + failsWithErrorMessage("expected to raise exception with name with reason with userInfo <{}> that satisfies block, got no exception") { + expect { self.anException }.to(raiseException(named: "foo", reason: "Lulz", userInfo: [:]) { (exception: NSException) in + expect(exception.name).to(equal("foo")) + }) + } + + failsWithErrorMessage("expected to not raise any exception, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.toNot(raiseException()) + } + } + + func testNegativeMatchesWithClosure() { + failsWithErrorMessage("expected to raise exception that satisfies block, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }") { + expect { self.anException.raise() }.to(raiseException { (exception: NSException) in + expect(exception.name).to(equal("foo")) + }) + } + + let innerFailureMessage = "expected to begin with , got " + + failsWithErrorMessage([innerFailureMessage, "expected to raise exception with name that satisfies block, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }"]) { + expect { self.anException.raise() }.to(raiseException(named: "laugh") { (exception: NSException) in + expect(exception.name).to(beginWith("fo")) + }) + } + + failsWithErrorMessage([innerFailureMessage, "expected to raise exception with name that satisfies block, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }"]) { + expect { self.anException.raise() }.to(raiseException(named: "lol") { (exception: NSException) in + expect(exception.name).to(beginWith("fo")) + }) + } + + failsWithErrorMessage([innerFailureMessage, "expected to raise exception with name with reason that satisfies block, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }"]) { + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz") { (exception: NSException) in + expect(exception.name).to(beginWith("fo")) + }) + } + + failsWithErrorMessage([innerFailureMessage, "expected to raise exception with name with reason that satisfies block, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }"]) { + expect { self.anException.raise() }.to(raiseException(named: "lol", reason: "wrong") { (exception: NSException) in + expect(exception.name).to(beginWith("fo")) + }) + } + + failsWithErrorMessage([innerFailureMessage, "expected to raise exception with name with reason with userInfo <{key = value;}> that satisfies block, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }"]) { + expect { self.anException.raise() }.to(raiseException(named: "laugh", reason: "Lulz", userInfo: ["key": "value"]) { (exception: NSException) in + expect(exception.name).to(beginWith("fo")) + }) + } + + failsWithErrorMessage([innerFailureMessage, "expected to raise exception with name with reason with userInfo <{}> that satisfies block, got NSException { name=laugh, reason='Lulz', userInfo=[key: value] }"]) { + expect { self.anException.raise() }.to(raiseException(named: "lol", reason: "Lulz", userInfo: [:]) { (exception: NSException) in + expect(exception.name).to(beginWith("fo")) + }) + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/Matchers/ThrowErrorTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/ThrowErrorTest.swift new file mode 100644 index 00000000..7bbbf698 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/Matchers/ThrowErrorTest.swift @@ -0,0 +1,137 @@ +import XCTest +import Nimble + +enum Error : ErrorType { + case Laugh + case Cry +} + +enum EquatableError : ErrorType { + case Parameterized(x: Int) +} + +extension EquatableError : Equatable { +} + +func ==(lhs: EquatableError, rhs: EquatableError) -> Bool { + switch (lhs, rhs) { + case (.Parameterized(let l), .Parameterized(let r)): + return l == r + } +} + +enum CustomDebugStringConvertibleError : ErrorType { + case A + case B +} + +extension CustomDebugStringConvertibleError : CustomDebugStringConvertible { + var debugDescription : String { + return "code=\(_code)" + } +} + +class ThrowErrorTest: XCTestCase { + func testPositiveMatches() { + expect { throw Error.Laugh }.to(throwError()) + expect { throw Error.Laugh }.to(throwError(Error.Laugh)) + expect { throw Error.Laugh }.to(throwError(errorType: Error.self)) + expect { throw EquatableError.Parameterized(x: 1) }.to(throwError(EquatableError.Parameterized(x: 1))) + } + + func testPositiveMatchesWithClosures() { + // Generic typed closure + expect { throw EquatableError.Parameterized(x: 42) }.to(throwError { error in + guard case EquatableError.Parameterized(let x) = error else { fail(); return } + expect(x) >= 1 + }) + // Explicit typed closure + expect { throw EquatableError.Parameterized(x: 42) }.to(throwError { (error: EquatableError) in + guard case .Parameterized(let x) = error else { fail(); return } + expect(x) >= 1 + }) + // Typed closure over errorType argument + expect { throw EquatableError.Parameterized(x: 42) }.to(throwError(errorType: EquatableError.self) { error in + guard case .Parameterized(let x) = error else { fail(); return } + expect(x) >= 1 + }) + // Typed closure over error argument + expect { throw Error.Laugh }.to(throwError(Error.Laugh) { (error: Error) in + expect(error._domain).to(beginWith("Nim")) + }) + // Typed closure over error argument + expect { throw Error.Laugh }.to(throwError(Error.Laugh) { (error: Error) in + expect(error._domain).toNot(beginWith("as")) + }) + } + + func testNegativeMatches() { + // Same case, different arguments + failsWithErrorMessage("expected to throw error , got ") { + expect { throw EquatableError.Parameterized(x: 1) }.to(throwError(EquatableError.Parameterized(x: 2))) + } + // Same case, different arguments + failsWithErrorMessage("expected to throw error , got ") { + expect { throw EquatableError.Parameterized(x: 1) }.to(throwError(EquatableError.Parameterized(x: 2))) + } + // Different case + failsWithErrorMessage("expected to throw error , got ") { + expect { throw Error.Laugh }.to(throwError(Error.Cry)) + } + // Different case with closure + failsWithErrorMessage("expected to throw error that satisfies block, got ") { + expect { throw Error.Laugh }.to(throwError(Error.Cry) { _ in return }) + } + // Different case, implementing CustomDebugStringConvertible + failsWithErrorMessage("expected to throw error , got ") { + expect { throw CustomDebugStringConvertibleError.A }.to(throwError(CustomDebugStringConvertibleError.B)) + } + } + + func testPositiveNegatedMatches() { + // No error at all + expect { return }.toNot(throwError()) + // Different case + expect { throw Error.Laugh }.toNot(throwError(Error.Cry)) + } + + func testNegativeNegatedMatches() { + // No error at all + failsWithErrorMessage("expected to not throw any error, got ") { + expect { throw Error.Laugh }.toNot(throwError()) + } + // Different error + failsWithErrorMessage("expected to not throw error , got ") { + expect { throw Error.Laugh }.toNot(throwError(Error.Laugh)) + } + } + + func testNegativeMatchesDoNotCallClosureWithoutError() { + failsWithErrorMessage("expected to throw error that satisfies block, got no error") { + expect { return }.to(throwError { error in + fail() + }) + } + + failsWithErrorMessage("expected to throw error that satisfies block, got no error") { + expect { return }.to(throwError(Error.Laugh) { error in + fail() + }) + } + } + + func testNegativeMatchesWithClosure() { + let innerFailureMessage = "expected to equal , got " + let closure = { (error: Error) in + expect(error._domain).to(equal("foo")) + } + + failsWithErrorMessage([innerFailureMessage, "expected to throw error from type that satisfies block, got "]) { + expect { throw Error.Laugh }.to(throwError(closure: closure)) + } + + failsWithErrorMessage([innerFailureMessage, "expected to throw error that satisfies block, got "]) { + expect { throw Error.Laugh }.to(throwError(Error.Laugh, closure: closure)) + } + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/SynchronousTests.swift b/Carthage/Checkouts/Nimble/NimbleTests/SynchronousTests.swift new file mode 100644 index 00000000..59d5b813 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/SynchronousTests.swift @@ -0,0 +1,108 @@ +import XCTest +import Nimble + +class SynchronousTest: XCTestCase { + let errorToThrow = NSError(domain: NSInternalInconsistencyException, code: 42, userInfo: nil) + private func doThrowError() throws -> Int { + throw errorToThrow + } + + func testFailAlwaysFails() { + failsWithErrorMessage("My error message") { + fail("My error message") + } + failsWithErrorMessage("fail() always fails") { + fail() + } + } + + func testUnexpectedErrorsThrownFails() { + failsWithErrorMessage("expected to equal <1>, got an unexpected error thrown: <\(errorToThrow)>") { + expect { try self.doThrowError() }.to(equal(1)) + } + failsWithErrorMessage("expected to not equal <1>, got an unexpected error thrown: <\(errorToThrow)>") { + expect { try self.doThrowError() }.toNot(equal(1)) + } + } + + func testToMatchesIfMatcherReturnsTrue() { + expect(1).to(MatcherFunc { expr, failure in true }) + expect{1}.to(MatcherFunc { expr, failure in true }) + } + + func testToProvidesActualValueExpression() { + var value: Int? + expect(1).to(MatcherFunc { expr, failure in value = try expr.evaluate(); return true }) + expect(value).to(equal(1)) + } + + func testToProvidesAMemoizedActualValueExpression() { + var callCount = 0 + expect{ callCount++ }.to(MatcherFunc { expr, failure in + try expr.evaluate() + try expr.evaluate() + return true + }) + expect(callCount).to(equal(1)) + } + + func testToProvidesAMemoizedActualValueExpressionIsEvaluatedAtMatcherControl() { + var callCount = 0 + expect{ callCount++ }.to(MatcherFunc { expr, failure in + expect(callCount).to(equal(0)) + try expr.evaluate() + return true + }) + expect(callCount).to(equal(1)) + } + + func testToMatchAgainstLazyProperties() { + expect(ObjectWithLazyProperty().value).to(equal("hello")) + expect(ObjectWithLazyProperty().value).toNot(equal("world")) + expect(ObjectWithLazyProperty().anotherValue).to(equal("world")) + expect(ObjectWithLazyProperty().anotherValue).toNot(equal("hello")) + } + + // repeated tests from to() for toNot() + func testToNotMatchesIfMatcherReturnsTrue() { + expect(1).toNot(MatcherFunc { expr, failure in false }) + expect{1}.toNot(MatcherFunc { expr, failure in false }) + } + + func testToNotProvidesActualValueExpression() { + var value: Int? + expect(1).toNot(MatcherFunc { expr, failure in value = try expr.evaluate(); return false }) + expect(value).to(equal(1)) + } + + func testToNotProvidesAMemoizedActualValueExpression() { + var callCount = 0 + expect{ callCount++ }.toNot(MatcherFunc { expr, failure in + try expr.evaluate() + try expr.evaluate() + return false + }) + expect(callCount).to(equal(1)) + } + + func testToNotProvidesAMemoizedActualValueExpressionIsEvaluatedAtMatcherControl() { + var callCount = 0 + expect{ callCount++ }.toNot(MatcherFunc { expr, failure in + expect(callCount).to(equal(0)) + try expr.evaluate() + return false + }) + expect(callCount).to(equal(1)) + } + + func testToNotNegativeMatches() { + failsWithErrorMessage("expected to not match, got <1>") { + expect(1).toNot(MatcherFunc { expr, failure in true }) + } + } + + + func testNotToMatchesLikeToNot() { + expect(1).notTo(MatcherFunc { expr, failure in false }) + } +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/UserDescriptionTest.swift b/Carthage/Checkouts/Nimble/NimbleTests/UserDescriptionTest.swift new file mode 100644 index 00000000..835819a2 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/UserDescriptionTest.swift @@ -0,0 +1,54 @@ +import XCTest +import Nimble + +class UserDescriptionTest: XCTestCase { + + func testToMatcher_CustomFailureMessage() { + failsWithErrorMessage( + "These aren't equal!\n" + + "expected to match, got <1>") { + expect(1).to(MatcherFunc { expr, failure in false }, description: "These aren't equal!") + } + } + + func testNotToMatcher_CustomFailureMessage() { + failsWithErrorMessage( + "These aren't equal!\n" + + "expected to not match, got <1>") { + expect(1).notTo(MatcherFunc { expr, failure in true }, description: "These aren't equal!") + } + } + + func testToNotMatcher_CustomFailureMessage() { + failsWithErrorMessage( + "These aren't equal!\n" + + "expected to not match, got <1>") { + expect(1).toNot(MatcherFunc { expr, failure in true }, description: "These aren't equal!") + } + } + + func testToEventuallyMatch_CustomFailureMessage() { + failsWithErrorMessage( + "These aren't eventually equal!\n" + + "expected to eventually equal <1>, got <0>") { + expect { 0 }.toEventually(equal(1), description: "These aren't eventually equal!") + } + } + + func testToEventuallyNotMatch_CustomFailureMessage() { + failsWithErrorMessage( + "These are eventually equal!\n" + + "expected to eventually not equal <1>, got <1>") { + expect { 1 }.toEventuallyNot(equal(1), description: "These are eventually equal!") + } + } + + func testToNotEventuallyMatch_CustomFailureMessage() { + failsWithErrorMessage( + "These are eventually equal!\n" + + "expected to eventually not equal <1>, got <1>") { + expect { 1 }.toEventuallyNot(equal(1), description: "These are eventually equal!") + } + } + +} diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/Nimble-OSXTests-Bridging-Header.h b/Carthage/Checkouts/Nimble/NimbleTests/objc/Nimble-OSXTests-Bridging-Header.h new file mode 100644 index 00000000..1b2cb5d6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/Nimble-OSXTests-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/NimbleSpecHelper.h b/Carthage/Checkouts/Nimble/NimbleTests/objc/NimbleSpecHelper.h new file mode 100644 index 00000000..282993d3 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/NimbleSpecHelper.h @@ -0,0 +1,15 @@ +@import Nimble; +#import "NimbleTests-Swift.h" + +// Use this when you want to verify the failure message for when an expectation fails +#define expectFailureMessage(MSG, BLOCK) \ +[NimbleHelper expectFailureMessage:(MSG) block:(BLOCK) file:@(__FILE__) line:__LINE__]; + +#define expectFailureMessages(MSGS, BLOCK) \ +[NimbleHelper expectFailureMessages:(MSGS) block:(BLOCK) file:@(__FILE__) line:__LINE__]; + + +// Use this when you want to verify the failure message with the nil message postfixed +// to it: " (use beNil() to match nils)" +#define expectNilFailureMessage(MSG, BLOCK) \ +[NimbleHelper expectFailureMessageForNil:(MSG) block:(BLOCK) file:@(__FILE__) line:__LINE__]; diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/NimbleTests-Bridging-Header.h b/Carthage/Checkouts/Nimble/NimbleTests/objc/NimbleTests-Bridging-Header.h new file mode 100644 index 00000000..1b2cb5d6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/NimbleTests-Bridging-Header.h @@ -0,0 +1,4 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCAllPassTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCAllPassTest.m new file mode 100644 index 00000000..013071df --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCAllPassTest.m @@ -0,0 +1,38 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCAllPassTest : XCTestCase + +@end + +@implementation ObjCAllPassTest + +- (void)testPositiveMatches { + expect(@[@1, @2, @3,@4]).to(allPass(beLessThan(@5))); + expect(@[@1, @2, @3,@4]).toNot(allPass(beGreaterThan(@5))); + + expect([NSSet setWithArray:@[@1, @2, @3,@4]]).to(allPass(beLessThan(@5))); + expect([NSSet setWithArray:@[@1, @2, @3,@4]]).toNot(allPass(beGreaterThan(@5))); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to all be less than <3.0000>, but failed first at element" + " <3.0000> in <[1.0000, 2.0000, 3.0000, 4.0000]>", ^{ + expect(@[@1, @2, @3,@4]).to(allPass(beLessThan(@3))); + }); + expectFailureMessage(@"expected to not all be less than <5.0000>", ^{ + expect(@[@1, @2, @3,@4]).toNot(allPass(beLessThan(@5))); + }); + expectFailureMessage(@"expected to not all be less than <5.0000>", ^{ + expect([NSSet setWithArray:@[@1, @2, @3,@4]]).toNot(allPass(beLessThan(@5))); + }); + expectFailureMessage(@"allPass only works with NSFastEnumeration" + " (NSArray, NSSet, ...) of NSObjects, got <3.0000>", ^{ + expect(@3).to(allPass(beLessThan(@5))); + }); + expectFailureMessage(@"allPass only works with NSFastEnumeration" + " (NSArray, NSSet, ...) of NSObjects, got <3.0000>", ^{ + expect(@3).toNot(allPass(beLessThan(@5))); + }); +} +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCAsyncTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCAsyncTest.m new file mode 100644 index 00000000..ea95b250 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCAsyncTest.m @@ -0,0 +1,53 @@ +#import +#import +#import "NimbleSpecHelper.h" + +@interface ObjCAsyncTest : XCTestCase + +@end + +@implementation ObjCAsyncTest + +- (void)testAsync { + __block id obj = @1; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + obj = nil; + }); + expect(obj).toEventually(beNil()); +} + + +- (void)testAsyncWithCustomTimeout { + __block id obj = nil; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + obj = @1; + }); + expect(obj).withTimeout(5).toEventuallyNot(beNil()); +} + +- (void)testAsyncCallback { + waitUntil(^(void (^done)(void)){ + done(); + }); + + expectFailureMessage(@"Waited more than 1.0 second", ^{ + waitUntil(^(void (^done)(void)){ /* ... */ }); + }); + + expectFailureMessage(@"Waited more than 0.01 seconds", ^{ + waitUntilTimeout(0.01, ^(void (^done)(void)){ + [NSThread sleepForTimeInterval:0.1]; + done(); + }); + }); + + expectFailureMessage(@"expected to equal , got ", ^{ + waitUntil(^(void (^done)(void)){ + [NSThread sleepForTimeInterval:0.1]; + expect(@"hello").to(equal(@"goodbye")); + done(); + }); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeAnInstanceOfTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeAnInstanceOfTest.m new file mode 100644 index 00000000..f5fca2d8 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeAnInstanceOfTest.m @@ -0,0 +1,34 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeAnInstanceOfTest : XCTestCase +@end + +@implementation ObjCBeAnInstanceOfTest + +- (void)testPositiveMatches { + NSNull *obj = [NSNull null]; + expect(obj).to(beAnInstanceOf([NSNull class])); + expect(@1).toNot(beAnInstanceOf([NSNull class])); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be an instance of NSNull, got <__NSCFNumber instance>", ^{ + expect(@1).to(beAnInstanceOf([NSNull class])); + }); + expectFailureMessage(@"expected to not be an instance of NSNull, got ", ^{ + expect([NSNull null]).toNot(beAnInstanceOf([NSNull class])); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to be an instance of NSNull, got ", ^{ + expect(nil).to(beAnInstanceOf([NSNull class])); + }); + + expectNilFailureMessage(@"expected to not be an instance of NSNull, got ", ^{ + expect(nil).toNot(beAnInstanceOf([NSNull class])); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeCloseToTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeCloseToTest.m new file mode 100644 index 00000000..d624ef4f --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeCloseToTest.m @@ -0,0 +1,36 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeCloseToTest : XCTestCase + +@end + +@implementation ObjCBeCloseToTest + +- (void)testPositiveMatches { + expect(@1.2).to(beCloseTo(@1.2001)); + expect(@1.2).to(beCloseTo(@2).within(10)); + expect(@2).toNot(beCloseTo(@1)); + expect(@1.00001).toNot(beCloseTo(@1).within(0.00000001)); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be close to <0.0000> (within 0.0010), got <1.0000>", ^{ + expect(@1).to(beCloseTo(@0)); + }); + expectFailureMessage(@"expected to not be close to <0.0000> (within 0.0010), got <0.0001>", ^{ + expect(@(0.0001)).toNot(beCloseTo(@0)); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to be close to <0.0000> (within 0.0010), got ", ^{ + expect(nil).to(beCloseTo(@0)); + }); + expectNilFailureMessage(@"expected to not be close to <0.0000> (within 0.0010), got ", ^{ + expect(nil).toNot(beCloseTo(@0)); + }); +} + + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeEmptyTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeEmptyTest.m new file mode 100644 index 00000000..856eb60c --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeEmptyTest.m @@ -0,0 +1,81 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeEmptyTest : XCTestCase +@end + +@implementation ObjCBeEmptyTest + +- (void)testPositiveMatches { + expect(@[]).to(beEmpty()); + expect(@"").to(beEmpty()); + expect(@{}).to(beEmpty()); + expect([NSSet set]).to(beEmpty()); + expect([NSHashTable hashTableWithOptions:NSPointerFunctionsWeakMemory]).to(beEmpty()); + + expect(@[@1, @2]).toNot(beEmpty()); + expect(@"a").toNot(beEmpty()); + expect(@{@"key": @"value"}).toNot(beEmpty()); + expect([NSSet setWithObject:@1]).toNot(beEmpty()); + + NSHashTable *table = [NSHashTable hashTableWithOptions:NSPointerFunctionsStrongMemory]; + [table addObject:@1]; + expect(table).toNot(beEmpty()); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be empty, got ", ^{ + expect(@"foo").to(beEmpty()); + }); + expectFailureMessage(@"expected to be empty, got <(1)>", ^{ + expect(@[@1]).to(beEmpty()); + }); + expectFailureMessage(@"expected to be empty, got <{key = value;}>", ^{ + expect(@{@"key": @"value"}).to(beEmpty()); + }); + expectFailureMessage(@"expected to be empty, got <{(1)}>", ^{ + expect([NSSet setWithObject:@1]).to(beEmpty()); + }); + NSHashTable *table = [NSHashTable hashTableWithOptions:NSPointerFunctionsStrongMemory]; + [table addObject:@1]; + NSString *tableString = [[table description] stringByReplacingOccurrencesOfString:@"\n" withString:@""]; + expectFailureMessage(([NSString stringWithFormat:@"expected to be empty, got <%@>", tableString]), ^{ + expect(table).to(beEmpty()); + }); + + expectFailureMessage(@"expected to not be empty, got <>", ^{ + expect(@"").toNot(beEmpty()); + }); + expectFailureMessage(@"expected to not be empty, got <()>", ^{ + expect(@[]).toNot(beEmpty()); + }); + expectFailureMessage(@"expected to not be empty, got <{}>", ^{ + expect(@{}).toNot(beEmpty()); + }); + expectFailureMessage(@"expected to not be empty, got <{(1)}>", ^{ + expect([NSSet setWithObject:@1]).toNot(beEmpty()); + }); + expectFailureMessage(@"expected to not be empty, got ", ^{ + expect([NSHashTable hashTableWithOptions:NSPointerFunctionsStrongMemory]).toNot(beEmpty()); + }); +} + +- (void)testItDoesNotMatchNil { + expectNilFailureMessage(@"expected to be empty, got ", ^{ + expect(nil).to(beEmpty()); + }); + expectNilFailureMessage(@"expected to not be empty, got ", ^{ + expect(nil).toNot(beEmpty()); + }); +} + +- (void)testItReportsTypesItMatchesAgainst { + expectFailureMessage(@"expected to be empty (only works for NSArrays, NSSets, NSDictionaries, NSHashTables, and NSStrings), got __NSCFNumber type", ^{ + expect(@1).to(beEmpty()); + }); + expectFailureMessage(@"expected to not be empty (only works for NSArrays, NSSets, NSDictionaries, NSHashTables, and NSStrings), got __NSCFNumber type", ^{ + expect(@1).toNot(beEmpty()); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeFalseTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeFalseTest.m new file mode 100644 index 00000000..5b99842d --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeFalseTest.m @@ -0,0 +1,24 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeFalseTest : XCTestCase + +@end + +@implementation ObjCBeFalseTest + +- (void)testPositiveMatches { + expect(@NO).to(beFalse()); + expect(@YES).toNot(beFalse()); +} + +- (void)testNegativeMatches { + expectNilFailureMessage(@"expected to be false, got ", ^{ + expect(nil).to(beFalse()); + }); + expectNilFailureMessage(@"expected to not be false, got ", ^{ + expect(nil).toNot(beFalse()); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeFalsyTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeFalsyTest.m new file mode 100644 index 00000000..00581126 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeFalsyTest.m @@ -0,0 +1,28 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeFalsyTest : XCTestCase + +@end + +@implementation ObjCBeFalsyTest + +- (void)testPositiveMatches { + expect(@NO).to(beFalsy()); + expect(@YES).toNot(beFalsy()); + expect(nil).to(beFalsy()); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to not be falsy, got ", ^{ + expect(nil).toNot(beFalsy()); + }); + expectFailureMessage(@"expected to be falsy, got <1.0000>", ^{ + expect(@1).to(beFalsy()); + }); + expectFailureMessage(@"expected to be truthy, got <0.0000>", ^{ + expect(@NO).to(beTruthy()); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m new file mode 100644 index 00000000..745ff441 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m @@ -0,0 +1,33 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeGreaterThanOrEqualToTest : XCTestCase + +@end + +@implementation ObjCBeGreaterThanOrEqualToTest + +- (void)testPositiveMatches { + expect(@2).to(beGreaterThanOrEqualTo(@2)); + expect(@2).toNot(beGreaterThanOrEqualTo(@3)); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be greater than or equal to <0.0000>, got <-1.0000>", ^{ + expect(@(-1)).to(beGreaterThanOrEqualTo(@0)); + }); + expectFailureMessage(@"expected to not be greater than or equal to <1.0000>, got <2.0000>", ^{ + expect(@2).toNot(beGreaterThanOrEqualTo(@(1))); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to be greater than or equal to <-1.0000>, got ", ^{ + expect(nil).to(beGreaterThanOrEqualTo(@(-1))); + }); + expectNilFailureMessage(@"expected to not be greater than or equal to <1.0000>, got ", ^{ + expect(nil).toNot(beGreaterThanOrEqualTo(@(1))); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeGreaterThanTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeGreaterThanTest.m new file mode 100644 index 00000000..1832ffc2 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeGreaterThanTest.m @@ -0,0 +1,33 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeGreaterThanTest : XCTestCase + +@end + +@implementation ObjCBeGreaterThanTest + +- (void)testPositiveMatches { + expect(@2).to(beGreaterThan(@1)); + expect(@2).toNot(beGreaterThan(@2)); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be greater than <0.0000>, got <-1.0000>", ^{ + expect(@(-1)).to(beGreaterThan(@(0))); + }); + expectFailureMessage(@"expected to not be greater than <1.0000>, got <0.0000>", ^{ + expect(@0).toNot(beGreaterThan(@(1))); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to be greater than <-1.0000>, got ", ^{ + expect(nil).to(beGreaterThan(@(-1))); + }); + expectNilFailureMessage(@"expected to not be greater than <1.0000>, got ", ^{ + expect(nil).toNot(beGreaterThan(@(1))); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeIdenticalToTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeIdenticalToTest.m new file mode 100644 index 00000000..7cfe4acb --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeIdenticalToTest.m @@ -0,0 +1,36 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeIdenticalToTest : XCTestCase + +@end + +@implementation ObjCBeIdenticalToTest + +- (void)testPositiveMatches { + NSNull *obj = [NSNull null]; + expect(obj).to(beIdenticalTo([NSNull null])); + expect(@2).toNot(beIdenticalTo(@3)); +} + +- (void)testNegativeMatches { + NSNull *obj = [NSNull null]; + expectFailureMessage(([NSString stringWithFormat:@"expected to be identical to <%p>, got <%p>", obj, @2]), ^{ + expect(@2).to(beIdenticalTo(obj)); + }); + expectFailureMessage(([NSString stringWithFormat:@"expected to not be identical to <%p>, got <%p>", obj, obj]), ^{ + expect(obj).toNot(beIdenticalTo(obj)); + }); +} + +- (void)testNilMatches { + NSNull *obj = [NSNull null]; + expectNilFailureMessage(@"expected to be identical to nil, got nil", ^{ + expect(nil).to(beIdenticalTo(nil)); + }); + expectNilFailureMessage(([NSString stringWithFormat:@"expected to not be identical to <%p>, got nil", obj]), ^{ + expect(nil).toNot(beIdenticalTo(obj)); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeKindOfTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeKindOfTest.m new file mode 100644 index 00000000..7eee2617 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeKindOfTest.m @@ -0,0 +1,34 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeKindOfTest : XCTestCase + +@end + +@implementation ObjCBeKindOfTest + +- (void)testPositiveMatches { + NSMutableArray *array = [NSMutableArray array]; + expect(array).to(beAKindOf([NSArray class])); + expect(@1).toNot(beAKindOf([NSNull class])); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be a kind of NSNull, got <__NSCFNumber instance>", ^{ + expect(@1).to(beAKindOf([NSNull class])); + }); + expectFailureMessage(@"expected to not be a kind of NSNull, got ", ^{ + expect([NSNull null]).toNot(beAKindOf([NSNull class])); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to be a kind of NSNull, got ", ^{ + expect(nil).to(beAKindOf([NSNull class])); + }); + expectNilFailureMessage(@"expected to not be a kind of NSNull, got ", ^{ + expect(nil).toNot(beAKindOf([NSNull class])); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m new file mode 100644 index 00000000..1aef1616 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m @@ -0,0 +1,33 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeLessThanOrEqualToTest : XCTestCase + +@end + +@implementation ObjCBeLessThanOrEqualToTest + +- (void)testPositiveMatches { + expect(@2).to(beLessThanOrEqualTo(@2)); + expect(@2).toNot(beLessThanOrEqualTo(@1)); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be less than or equal to <1.0000>, got <2.0000>", ^{ + expect(@2).to(beLessThanOrEqualTo(@1)); + }); + expectFailureMessage(@"expected to not be less than or equal to <1.0000>, got <1.0000>", ^{ + expect(@1).toNot(beLessThanOrEqualTo(@1)); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to be less than or equal to <1.0000>, got ", ^{ + expect(nil).to(beLessThanOrEqualTo(@1)); + }); + expectNilFailureMessage(@"expected to not be less than or equal to <-1.0000>, got ", ^{ + expect(nil).toNot(beLessThanOrEqualTo(@(-1))); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeLessThanTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeLessThanTest.m new file mode 100644 index 00000000..e517fa6f --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeLessThanTest.m @@ -0,0 +1,33 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeLessThanTest : XCTestCase + +@end + +@implementation ObjCBeLessThanTest + +- (void)testPositiveMatches { + expect(@2).to(beLessThan(@3)); + expect(@2).toNot(beLessThan(@2)); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be less than <0.0000>, got <-1.0000>", ^{ + expect(@(-1)).to(beLessThan(@0)); + }); + expectFailureMessage(@"expected to not be less than <1.0000>, got <0.0000>", ^{ + expect(@0).toNot(beLessThan(@1)); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to be less than <-1.0000>, got ", ^{ + expect(nil).to(beLessThan(@(-1))); + }); + expectNilFailureMessage(@"expected to not be less than <1.0000>, got ", ^{ + expect(nil).toNot(beLessThan(@1)); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeNilTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeNilTest.m new file mode 100644 index 00000000..905156e3 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeNilTest.m @@ -0,0 +1,24 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeNilTest : XCTestCase + +@end + +@implementation ObjCBeNilTest + +- (void)testPositiveMatches { + expect(nil).to(beNil()); + expect(@NO).toNot(beNil()); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be nil, got <1.0000>", ^{ + expect(@1).to(beNil()); + }); + expectFailureMessage(@"expected to not be nil, got ", ^{ + expect(nil).toNot(beNil()); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeTrueTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeTrueTest.m new file mode 100644 index 00000000..c078097b --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeTrueTest.m @@ -0,0 +1,25 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeTrueTest : XCTestCase + +@end + +@implementation ObjCBeTrueTest + +- (void)testPositiveMatches { + expect(@YES).to(beTrue()); + expect(@NO).toNot(beTrue()); + expect(nil).toNot(beTrue()); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be true, got <0.0000>", ^{ + expect(@NO).to(beTrue()); + }); + expectFailureMessage(@"expected to be true, got ", ^{ + expect(nil).to(beTrue()); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeTruthyTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeTruthyTest.m new file mode 100644 index 00000000..fea00154 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeTruthyTest.m @@ -0,0 +1,28 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeTruthyTest : XCTestCase + +@end + +@implementation ObjCBeTruthyTest + +- (void)testPositiveMatches { + expect(@YES).to(beTruthy()); + expect(@NO).toNot(beTruthy()); + expect(nil).toNot(beTruthy()); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to be truthy, got ", ^{ + expect(nil).to(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <1.0000>", ^{ + expect(@1).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to be truthy, got <0.0000>", ^{ + expect(@NO).to(beTruthy()); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeginWithTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeginWithTest.m new file mode 100644 index 00000000..5ca7be45 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCBeginWithTest.m @@ -0,0 +1,37 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCBeginWithTest : XCTestCase + +@end + +@implementation ObjCBeginWithTest + +- (void)testPositiveMatches { + expect(@"hello world!").to(beginWith(@"hello")); + expect(@"hello world!").toNot(beginWith(@"world")); + + NSArray *array = @[@1, @2]; + expect(array).to(beginWith(@1)); + expect(array).toNot(beginWith(@2)); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to begin with , got ", ^{ + expect(@"foo").to(beginWith(@"bar")); + }); + expectFailureMessage(@"expected to not begin with , got ", ^{ + expect(@"foo").toNot(beginWith(@"foo")); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to begin with <1>, got ", ^{ + expect(nil).to(beginWith(@1)); + }); + expectNilFailureMessage(@"expected to not begin with <1>, got ", ^{ + expect(nil).toNot(beginWith(@1)); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCContainTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCContainTest.m new file mode 100644 index 00000000..4370625e --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCContainTest.m @@ -0,0 +1,67 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCContainTest : XCTestCase + +@end + +@implementation ObjCContainTest + +- (void)testPositiveMatches { + NSArray *array = @[@1, @2]; + expect(array).to(contain(@1)); + expect(array).toNot(contain(@"HI")); + expect(@"String").to(contain(@"Str")); + expect(@"Other").toNot(contain(@"Str")); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to contain , got <(1,2)>", ^{ + expect((@[@1, @2])).to(contain(@3)); + }); + expectFailureMessage(@"expected to not contain , got <(1,2)>", ^{ + expect((@[@1, @2])).toNot(contain(@2)); + }); + + expectFailureMessage(@"expected to contain , got ", ^{ + expect(@"la").to(contain(@"hi")); + }); + expectFailureMessage(@"expected to not contain , got ", ^{ + expect(@"hihihi").toNot(contain(@"hi")); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to contain <3.0000>, got ", ^{ + expect(nil).to(contain(@3)); + }); + expectNilFailureMessage(@"expected to not contain <3.0000>, got ", ^{ + expect(nil).toNot(contain(@3)); + }); + + expectNilFailureMessage(@"expected to contain , got ", ^{ + expect(nil).to(contain(@"hi")); + }); + expectNilFailureMessage(@"expected to not contain , got ", ^{ + expect(nil).toNot(contain(@"hi")); + }); +} + +- (void)testVariadicArguments { + NSArray *array = @[@1, @2]; + expect(array).to(contain(@1, @2)); + expect(array).toNot(contain(@"HI", @"whale")); + expect(@"String").to(contain(@"Str", @"ng")); + expect(@"Other").toNot(contain(@"Str", @"Oth")); + + + expectFailureMessage(@"expected to contain , got <(a,b,c)>", ^{ + expect(@[@"a", @"b", @"c"]).to(contain(@"a", @"bar")); + }); + + expectFailureMessage(@"expected to not contain , got <(a,b,c)>", ^{ + expect(@[@"a", @"b", @"c"]).toNot(contain(@"bar", @"b")); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCEndWithTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCEndWithTest.m new file mode 100644 index 00000000..b960f01b --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCEndWithTest.m @@ -0,0 +1,37 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCEndWithTest : XCTestCase + +@end + +@implementation ObjCEndWithTest + +- (void)testPositiveMatches { + NSArray *array = @[@1, @2]; + expect(@"hello world!").to(endWith(@"world!")); + expect(@"hello world!").toNot(endWith(@"hello")); + expect(array).to(endWith(@2)); + expect(array).toNot(endWith(@1)); + expect(@1).toNot(contain(@"foo")); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to end with , got ", ^{ + expect(@"hello world!").to(endWith(@"?")); + }); + expectFailureMessage(@"expected to not end with , got ", ^{ + expect(@"hello world!").toNot(endWith(@"!")); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to end with <1>, got ", ^{ + expect(nil).to(endWith(@1)); + }); + expectNilFailureMessage(@"expected to not end with <1>, got ", ^{ + expect(nil).toNot(endWith(@1)); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCEqualTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCEqualTest.m new file mode 100644 index 00000000..2378a32d --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCEqualTest.m @@ -0,0 +1,35 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCEqualTest : XCTestCase + +@end + +@implementation ObjCEqualTest + +- (void)testPositiveMatches { + expect(@1).to(equal(@1)); + expect(@1).toNot(equal(@2)); + expect(@1).notTo(equal(@2)); + expect(@"hello").to(equal(@"hello")); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to equal <2.0000>, got <1.0000>", ^{ + expect(@1).to(equal(@2)); + }); + expectFailureMessage(@"expected to not equal <1.0000>, got <1.0000>", ^{ + expect(@1).toNot(equal(@1)); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to equal , got ", ^{ + expect(nil).to(equal(nil)); + }); + expectNilFailureMessage(@"expected to not equal , got ", ^{ + expect(nil).toNot(equal(nil)); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCMatchTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCMatchTest.m new file mode 100644 index 00000000..2342ae48 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCMatchTest.m @@ -0,0 +1,33 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCMatchTest : XCTestCase + +@end + +@implementation ObjCMatchTest + +- (void)testPositiveMatches { + expect(@"11:14").to(match(@"\\d{2}:\\d{2}")); + expect(@"hello").toNot(match(@"\\d{2}:\\d{2}")); +} + +- (void)testNegativeMatches { + expectFailureMessage(@"expected to match <\\d{2}:\\d{2}>, got ", ^{ + expect(@"hello").to(match(@"\\d{2}:\\d{2}")); + }); + expectFailureMessage(@"expected to not match <\\d{2}:\\d{2}>, got <11:22>", ^{ + expect(@"11:22").toNot(match(@"\\d{2}:\\d{2}")); + }); +} + +- (void)testNilMatches { + expectNilFailureMessage(@"expected to match <\\d{2}:\\d{2}>, got ", ^{ + expect(nil).to(match(@"\\d{2}:\\d{2}")); + }); + expectNilFailureMessage(@"expected to not match <\\d{2}:\\d{2}>, got ", ^{ + expect(nil).toNot(match(@"\\d{2}:\\d{2}")); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCRaiseExceptionTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCRaiseExceptionTest.m new file mode 100644 index 00000000..31793880 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCRaiseExceptionTest.m @@ -0,0 +1,178 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCRaiseExceptionTest : XCTestCase + +@end + +@implementation ObjCRaiseExceptionTest + +- (void)testPositiveMatches { + __block NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException + reason:@"No food" + userInfo:@{@"key": @"value"}]; + expectAction(^{ @throw exception; }).to(raiseException()); + expectAction(^{ [exception raise]; }).to(raiseException()); + expectAction(^{ [exception raise]; }).to(raiseException().named(NSInvalidArgumentException)); + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"No food")); + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"No food"). + userInfo(@{@"key": @"value"})); + + expectAction(^{ }).toNot(raiseException()); +} + +- (void)testPositiveMatchesWithBlocks { + __block NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException + reason:@"No food" + userInfo:@{@"key": @"value"}]; + expectAction(^{ [exception raise]; }).to(raiseException(). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(NSInvalidArgumentException)); + })); + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(NSInvalidArgumentException)); + })); + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"No food"). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(NSInvalidArgumentException)); + })); + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"No food"). + userInfo(@{@"key": @"value"}). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(NSInvalidArgumentException)); + })); +} + +- (void)testNegativeMatches { + __block NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException + reason:@"No food" + userInfo:@{@"key": @"value"}]; + + expectFailureMessage(@"expected to raise any exception, got no exception", ^{ + expectAction(^{ }).to(raiseException()); + }); + + expectFailureMessage(@"expected to raise exception with name , got no exception", ^{ + expectAction(^{ }).to(raiseException(). + named(@"foo")); + }); + + expectFailureMessage(@"expected to raise exception with name with reason , got no exception", ^{ + expectAction(^{ }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"cakes")); + }); + + expectFailureMessage(@"expected to raise exception with name with reason with userInfo <{k = v;}>, got no exception", ^{ + expectAction(^{ }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"No food"). + userInfo(@{@"k": @"v"})); + }); + + expectFailureMessage(@"expected to not raise any exception, got NSException { name=NSInvalidArgumentException, reason='No food', userInfo=[key: value] }", ^{ + expectAction(^{ [exception raise]; }).toNot(raiseException()); + }); +} + +- (void)testNegativeMatchesWithPassingBlocks { + __block NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException + reason:@"No food" + userInfo:@{@"key": @"value"}]; + expectFailureMessage(@"expected to raise exception that satisfies block, got no exception", ^{ + expect(exception).to(raiseException(). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(@"LOL")); + })); + }); + + NSString *outerFailureMessage = @"expected to raise exception that satisfies block, got NSException { name=NSInvalidArgumentException, reason='No food', userInfo=[key: value] }"; + expectFailureMessages((@[outerFailureMessage]), ^{ + expectAction(^{ [exception raise]; }).to(raiseException(). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(NSInvalidArgumentException)); + })); + }); + + outerFailureMessage = @"expected to raise exception with name that satisfies block, got NSException { name=NSInvalidArgumentException, reason='No food', userInfo=[key: value] }"; + expectFailureMessages((@[outerFailureMessage]), ^{ + expectAction(^{ [exception raise]; }).to(raiseException(). + named(@"foo"). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(NSInvalidArgumentException)); + })); + }); + + outerFailureMessage = @"expected to raise exception with name with reason that satisfies block, got NSException { name=NSInvalidArgumentException, reason='No food', userInfo=[key: value] }"; + expectFailureMessages((@[outerFailureMessage]), ^{ + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"bar"). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(NSInvalidArgumentException)); + })); + }); + + outerFailureMessage = @"expected to raise exception with name with reason with userInfo <{}> that satisfies block, got NSException { name=NSInvalidArgumentException, reason='No food', userInfo=[key: value] }"; + expectFailureMessages((@[outerFailureMessage]), ^{ + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"No food"). + userInfo(@{}). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(NSInvalidArgumentException)); + })); + }); +} + +- (void)testNegativeMatchesWithNegativeBlocks { + __block NSException *exception = [NSException exceptionWithName:NSInvalidArgumentException + reason:@"No food" + userInfo:@{@"key": @"value"}]; + NSString *outerFailureMessage; + + NSString const *innerFailureMessage = @"expected to equal , got "; + outerFailureMessage = @"expected to raise exception with name that satisfies block, got NSException { name=NSInvalidArgumentException, reason='No food', userInfo=[key: value] }"; + expectFailureMessages((@[outerFailureMessage, innerFailureMessage]), ^{ + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(@"foo")); + })); + }); + + + outerFailureMessage = @"expected to raise exception with name with reason that satisfies block, got NSException { name=NSInvalidArgumentException, reason='No food', userInfo=[key: value] }"; + expectFailureMessages((@[outerFailureMessage, innerFailureMessage]), ^{ + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"No food"). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(@"foo")); + })); + }); + + + outerFailureMessage = @"expected to raise exception with name with reason with userInfo <{key = value;}> that satisfies block, got NSException { name=NSInvalidArgumentException, reason='No food', userInfo=[key: value] }"; + expectFailureMessages((@[outerFailureMessage, innerFailureMessage]), ^{ + expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInvalidArgumentException). + reason(@"No food"). + userInfo(@{@"key": @"value"}). + satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(equal(@"foo")); + })); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCSyncTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCSyncTest.m new file mode 100644 index 00000000..2aae8168 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCSyncTest.m @@ -0,0 +1,21 @@ +#import +#import +#import "NimbleSpecHelper.h" + +@interface ObjCSyncTest : XCTestCase + +@end + +@implementation ObjCSyncTest + +- (void)testFailureExpectation { + expectFailureMessage(@"fail() always fails", ^{ + fail(); + }); + + expectFailureMessage(@"This always fails", ^{ + failWithMessage(@"This always fails"); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCUserDescriptionTest.m b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCUserDescriptionTest.m new file mode 100644 index 00000000..72bb2be6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/NimbleTests/objc/ObjCUserDescriptionTest.m @@ -0,0 +1,52 @@ +#import +#import "NimbleSpecHelper.h" + +@interface ObjCUserDescriptionTest : XCTestCase + +@end + +@implementation ObjCUserDescriptionTest + +- (void)testToWithDescription { + expectFailureMessage(@"These are equal!\n" + "expected to equal <2.0000>, got <1.0000>", ^{ + expect(@1).toWithDescription(equal(@2), @"These are equal!"); + }); +} + +- (void)testToNotWithDescription { + expectFailureMessage(@"These aren't equal!\n" + "expected to not equal <1.0000>, got <1.0000>", ^{ + expect(@1).toNotWithDescription(equal(@1), @"These aren't equal!"); + }); +} + +- (void)testNotToWithDescription { + expectFailureMessage(@"These aren't equal!\n" + "expected to not equal <1.0000>, got <1.0000>", ^{ + expect(@1).notToWithDescription(equal(@1), @"These aren't equal!"); + }); +} + +- (void)testToEventuallyWithDescription { + expectFailureMessage(@"These are equal!\n" + "expected to eventually equal <2.0000>, got <1.0000>", ^{ + expect(@1).toEventuallyWithDescription(equal(@2), @"These are equal!"); + }); +} + +- (void)testToEventuallyNotWithDescription { + expectFailureMessage(@"These aren't equal!\n" + "expected to eventually not equal <1.0000>, got <1.0000>", ^{ + expect(@1).toEventuallyNotWithDescription(equal(@1), @"These aren't equal!"); + }); +} + +- (void)testToNotEventuallyWithDescription { + expectFailureMessage(@"These aren't equal!\n" + "expected to eventually not equal <1.0000>, got <1.0000>", ^{ + expect(@1).toNotEventuallyWithDescription(equal(@1), @"These aren't equal!"); + }); +} + +@end diff --git a/Carthage/Checkouts/Nimble/README.md b/Carthage/Checkouts/Nimble/README.md new file mode 100644 index 00000000..dd42435e --- /dev/null +++ b/Carthage/Checkouts/Nimble/README.md @@ -0,0 +1,1149 @@ +# Nimble + +Use Nimble to express the expected outcomes of Swift +or Objective-C expressions. Inspired by +[Cedar](https://github.com/pivotal/cedar). + +```swift +// Swift + +expect(1 + 1).to(equal(2)) +expect(1.2).to(beCloseTo(1.1, within: 0.1)) +expect(3) > 2 +expect("seahorse").to(contain("sea")) +expect(["Atlantic", "Pacific"]).toNot(contain("Mississippi")) +expect(ocean.isClean).toEventually(beTruthy()) +``` + +# How to Use Nimble + + + + +- [Some Background: Expressing Outcomes Using Assertions in XCTest](#some-background-expressing-outcomes-using-assertions-in-xctest) +- [Nimble: Expectations Using `expect(...).to`](#nimble-expectations-using-expectto) + - [Type Checking](#type-checking) + - [Operator Overloads](#operator-overloads) + - [Lazily Computed Values](#lazily-computed-values) + - [C Primitives](#c-primitives) + - [Asynchronous Expectations](#asynchronous-expectations) + - [Objective-C Support](#objective-c-support) + - [Disabling Objective-C Shorthand](#disabling-objective-c-shorthand) +- [Built-in Matcher Functions](#built-in-matcher-functions) + - [Equivalence](#equivalence) + - [Identity](#identity) + - [Comparisons](#comparisons) + - [Types/Classes](#typesclasses) + - [Truthiness](#truthiness) + - [Exceptions](#exceptions) + - [Collection Membership](#collection-membership) + - [Strings](#strings) + - [Checking if all elements of a collection pass a condition](#checking-if-all-elements-of-a-collection-pass-a-condition) +- [Writing Your Own Matchers](#writing-your-own-matchers) + - [Lazy Evaluation](#lazy-evaluation) + - [Type Checking via Swift Generics](#type-checking-via-swift-generics) + - [Customizing Failure Messages](#customizing-failure-messages) + - [Supporting Objective-C](#supporting-objective-c) + - [Properly Handling `nil` in Objective-C Matchers](#properly-handling-nil-in-objective-c-matchers) +- [Installing Nimble](#installing-nimble) + - [Installing Nimble as a Submodule](#installing-nimble-as-a-submodule) + - [Installing Nimble via CocoaPods](#installing-nimble-via-cocoapods) + - [Using Nimble without XCTest](#using-nimble-without-xctest) + + + +# Some Background: Expressing Outcomes Using Assertions in XCTest + +Apple's Xcode includes the XCTest framework, which provides +assertion macros to test whether code behaves properly. +For example, to assert that `1 + 1 = 2`, XCTest has you write: + +```swift +// Swift + +XCTAssertEqual(1 + 1, 2, "expected one plus one to equal two") +``` + +Or, in Objective-C: + +```objc +// Objective-C + +XCTAssertEqual(1 + 1, 2, @"expected one plus one to equal two"); +``` + +XCTest assertions have a couple of drawbacks: + +1. **Not enough macros.** There's no easy way to assert that a string + contains a particular substring, or that a number is less than or + equal to another. +2. **It's hard to write asynchronous tests.** XCTest forces you to write + a lot of boilerplate code. + +Nimble addresses these concerns. + +# Nimble: Expectations Using `expect(...).to` + +Nimble allows you to express expectations using a natural, +easily understood language: + +```swift +// Swift + +import Nimble + +expect(seagull.squawk).to(equal("Squee!")) +``` + +```objc +// Objective-C + +@import Nimble; + +expect(seagull.squawk).to(equal(@"Squee!")); +``` + +> The `expect` function autocompletes to include `file:` and `line:`, + but these parameters are optional. Use the default values to have + Xcode highlight the correct line when an expectation is not met. + +To perform the opposite expectation--to assert something is *not* +equal--use `toNot` or `notTo`: + +```swift +// Swift + +import Nimble + +expect(seagull.squawk).toNot(equal("Oh, hello there!")) +expect(seagull.squawk).notTo(equal("Oh, hello there!")) +``` + +```objc +// Objective-C + +@import Nimble; + +expect(seagull.squawk).toNot(equal(@"Oh, hello there!")); +expect(seagull.squawk).notTo(equal(@"Oh, hello there!")); +``` + +## Custom Failure Messages + +Would you like to add more information to the test's failure messages? Use the `description` optional argument to add your own text: + +```swift +// Swift + +expect(1 + 1).to(equal(3)) +// failed - expected to equal <3>, got <2> + +expect(1 + 1).to(equal(3), description: "Make sure libKindergartenMath is loaded") +// failed - Make sure libKindergartenMath is loaded +// expected to equal <3>, got <2> +``` + +Or the *WithDescription version in Objective-C: + +```objc +// Objective-C + +@import Nimble; + +expect(@(1+1)).to(equal(@3)); +// failed - expected to equal <3.0000>, got <2.0000> + +expect(@(1+1)).toWithDescription(equal(@3), @"Make sure libKindergartenMath is loaded"); +// failed - Make sure libKindergartenMath is loaded +// expected to equal <3.0000>, got <2.0000> +``` + +## Type Checking + +Nimble makes sure you don't compare two types that don't match: + +```swift +// Swift + +// Does not compile: +expect(1 + 1).to(equal("Squee!")) +``` + +> Nimble uses generics--only available in Swift--to ensure + type correctness. That means type checking is + not available when using Nimble in Objective-C. :sob: + +## Operator Overloads + +Tired of so much typing? With Nimble, you can use overloaded operators +like `==` for equivalence, or `>` for comparisons: + +```swift +// Swift + +// Passes if squawk does not equal "Hi!": +expect(seagull.squawk) != "Hi!" + +// Passes if 10 is greater than 2: +expect(10) > 2 +``` + +> Operator overloads are only available in Swift, so you won't be able + to use this syntax in Objective-C. :broken_heart: + +## Lazily Computed Values + +The `expect` function doesn't evalaute the value it's given until it's +time to match. So Nimble can test whether an expression raises an +exception once evaluated: + +```swift +// Swift + +// Note: Swift currently doesn't have exceptions. +// Only Objective-C code can raise exceptions +// that Nimble will catch. +let exception = NSException( + name: NSInternalInconsistencyException, + reason: "Not enough fish in the sea.", + userInfo: ["something": "is fishy"]) +expect { exception.raise() }.to(raiseException()) + +// Also, you can customize raiseException to be more specific +expect { exception.raise() }.to(raiseException(named: NSInternalInconsistencyException)) +expect { exception.raise() }.to(raiseException( + named: NSInternalInconsistencyException, + reason: "Not enough fish in the sea")) +expect { exception.raise() }.to(raiseException( + named: NSInternalInconsistencyException, + reason: "Not enough fish in the sea", + userInfo: ["something": "is fishy"])) +``` + +Objective-C works the same way, but you must use the `expectAction` +macro when making an expectation on an expression that has no return +value: + +```objc +// Objective-C + +NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException + reason:@"Not enough fish in the sea." + userInfo:nil]; +expectAction(^{ [exception raise]; }).to(raiseException()); + +// Use the property-block syntax to be more specific. +expectAction(^{ [exception raise]; }).to(raiseException().named(NSInternalInconsistencyException)); +expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInternalInconsistencyException). + reason("Not enough fish in the sea")); +expectAction(^{ [exception raise]; }).to(raiseException(). + named(NSInternalInconsistencyException). + reason("Not enough fish in the sea"). + userInfo(@{@"something": @"is fishy"})); + +// You can also pass a block for custom matching of the raised exception +expectAction(exception.raise()).to(raiseException().satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(beginWith(NSInternalInconsistencyException)); +})); +``` + +## C Primitives + +Some testing frameworks make it hard to test primitive C values. +In Nimble, it just works: + +```swift +// Swift + +let actual: CInt = 1 +let expectedValue: CInt = 1 +expect(actual).to(equal(expectedValue)) +``` + +In fact, Nimble uses type inference, so you can write the above +without explicitly specifying both types: + +```swift +// Swift + +expect(1 as CInt).to(equal(1)) +``` + +> In Objective-C, Nimble only supports Objective-C objects. To + make expectations on primitive C values, wrap then in an object + literal: + + ```objc + expect(@(1 + 1)).to(equal(@2)); + ``` + +## Asynchronous Expectations + +In Nimble, it's easy to make expectations on values that are updated +asynchronously. Just use `toEventually` or `toEventuallyNot`: + +```swift +// Swift + +dispatch_async(dispatch_get_main_queue()) { + ocean.add("dolphins") + ocean.add("whales") +} +expect(ocean).toEventually(contain("dolphins", "whales")) +``` + + +```objc +// Objective-C +dispatch_async(dispatch_get_main_queue(), ^{ + [ocean add:@"dolphins"]; + [ocean add:@"whales"]; +}); +expect(ocean).toEventually(contain(@"dolphins", @"whales")); +``` + +In the above example, `ocean` is constantly re-evaluated. If it ever +contains dolphins and whales, the expectation passes. If `ocean` still +doesn't contain them, even after being continuously re-evaluated for one +whole second, the expectation fails. + +Sometimes it takes more than a second for a value to update. In those +cases, use the `timeout` parameter: + +```swift +// Swift + +// Waits three seconds for ocean to contain "starfish": +expect(ocean).toEventually(contain("starfish"), timeout: 3) +``` + +```objc +// Objective-C + +// Waits three seconds for ocean to contain "starfish": +expect(ocean).withTimeout(3).toEventually(contain(@"starfish")); +``` + +You can also provide a callback by using the `waitUntil` function: + +```swift +// Swift + +waitUntil { done in + // do some stuff that takes a while... + NSThread.sleepForTimeInterval(0.5) + done() +} +``` + +```objc +// Objective-C + +waitUntil(^(void (^done)(void)){ + // do some stuff that takes a while... + [NSThread sleepForTimeInterval:0.5]; + done(); +}); +``` + +`waitUntil` also optionally takes a timeout parameter: + +```swift +// Swift + +waitUntil(timeout: 10) { done in + // do some stuff that takes a while... + NSThread.sleepForTimeInterval(1) + done() +} +``` + +```objc +// Objective-C + +waitUntilTimeout(10, ^(void (^done)(void)){ + // do some stuff that takes a while... + [NSThread sleepForTimeInterval:1]; + done(); +}); +``` + +## Objective-C Support + +Nimble has full support for Objective-C. However, there are two things +to keep in mind when using Nimble in Objective-C: + +1. All parameters passed to the `expect` function, as well as matcher + functions like `equal`, must be Objective-C objects: + + ```objc + // Objective-C + + @import Nimble; + + expect(@(1 + 1)).to(equal(@2)); + expect(@"Hello world").to(contain(@"world")); + ``` + +2. To make an expectation on an expression that does not return a value, + such as `-[NSException raise]`, use `expectAction` instead of + `expect`: + + ```objc + // Objective-C + + expectAction(^{ [exception raise]; }).to(raiseException()); + ``` + +## Disabling Objective-C Shorthand + +Nimble provides a shorthand for expressing expectations using the +`expect` function. To disable this shorthand in Objective-C, define the +`NIMBLE_DISABLE_SHORT_SYNTAX` macro somewhere in your code before +importing Nimble: + +```objc +#define NIMBLE_DISABLE_SHORT_SYNTAX 1 + +@import Nimble; + +NMB_expect(^{ return seagull.squawk; }, __FILE__, __LINE__).to(NMB_equal(@"Squee!")); +``` + +> Disabling the shorthand is useful if you're testing functions with + names that conflict with Nimble functions, such as `expect` or + `equal`. If that's not the case, there's no point in disabling the + shorthand. + +# Built-in Matcher Functions + +Nimble includes a wide variety of matcher functions. + +## Equivalence + +```swift +// Swift + +// Passes if actual is equivalent to expected: +expect(actual).to(equal(expected)) +expect(actual) == expected + +// Passes if actual is not equivalent to expected: +expect(actual).toNot(equal(expected)) +expect(actual) != expected +``` + +```objc +// Objective-C + +// Passes if actual is equivalent to expected: +expect(actual).to(equal(expected)) + +// Passes if actual is not equivalent to expected: +expect(actual).toNot(equal(expected)) +``` + +Values must be `Equatable`, `Comparable`, or subclasses of `NSObject`. +`equal` will always fail when used to compare one or more `nil` values. + +## Identity + +```swift +// Swift + +// Passes if actual has the same pointer address as expected: +expect(actual).to(beIdenticalTo(expected)) +expect(actual) === expected + +// Passes if actual does not have the same pointer address as expected: +expect(actual).toNot(beIdenticalTo(expected)) +expect(actual) !== expected +``` + +```objc +// Objective-C + +// Passes if actual has the same pointer address as expected: +expect(actual).to(beIdenticalTo(expected)); + +// Passes if actual does not have the same pointer address as expected: +expect(actual).toNot(beIdenticalTo(expected)); +``` + +> `beIdenticalTo` only supports Objective-C objects: subclasses + of `NSObject`, or Swift objects bridged to Objective-C with the + `@objc` prefix. + +## Comparisons + +```swift +// Swift + +expect(actual).to(beLessThan(expected)) +expect(actual) < expected + +expect(actual).to(beLessThanOrEqualTo(expected)) +expect(actual) <= expected + +expect(actual).to(beGreaterThan(expected)) +expect(actual) > expected + +expect(actual).to(beGreaterThanOrEqualTo(expected)) +expect(actual) >= expected +``` + +```objc +// Objective-C + +expect(actual).to(beLessThan(expected)); +expect(actual).to(beLessThanOrEqualTo(expected)); +expect(actual).to(beGreaterThan(expected)); +expect(actual).to(beGreaterThanOrEqualTo(expected)); +``` + +> Values given to the comparison matchers above must implement + `Comparable`. + +Because of how computers represent floating point numbers, assertions +that two floating point numbers be equal will sometimes fail. To express +that two numbers should be close to one another within a certain margin +of error, use `beCloseTo`: + +```swift +// Swift + +expect(actual).to(beCloseTo(expected, within: delta)) +``` + +```objc +// Objective-C + +expect(actual).to(beCloseTo(expected).within(delta)); +``` + +For example, to assert that `10.01` is close to `10`, you can write: + +```swift +// Swift + +expect(10.01).to(beCloseTo(10, within: 0.1)) +``` + +```objc +// Objective-C + +expect(@(10.01)).to(beCloseTo(@10).within(0.1)); +``` + +There is also an operator shortcut available in Swift: + +```swift +// Swift + +expect(actual) ≈ expected +expect(actual) ≈ (expected, delta) + +``` +(Type Option-x to get ≈ on a U.S. keyboard) + +The former version uses the default delta of 0.0001. Here is yet another way to do this: + +```swift +// Swift + +expect(actual) ≈ expected ± delta +expect(actual) == expected ± delta + +``` +(Type Option-Shift-= to get ± on a U.S. keyboard) + +If you are comparing arrays of floating point numbers, you'll find the following useful: + +```swift +// Swift + +expect([0.0, 2.0]) ≈ [0.0001, 2.0001] +expect([0.0, 2.0]).to(beCloseTo([0.1, 2.1], within: 0.1)) + +``` + +> Values given to the `beCloseTo` matcher must be coercable into a + `Double`. + +## Types/Classes + +```swift +// Swift + +// Passes if instance is an instance of aClass: +expect(instance).to(beAnInstanceOf(aClass)) + +// Passes if instance is an instance of aClass or any of its subclasses: +expect(instance).to(beAKindOf(aClass)) +``` + +```objc +// Objective-C + +// Passes if instance is an instance of aClass: +expect(instance).to(beAnInstanceOf(aClass)); + +// Passes if instance is an instance of aClass or any of its subclasses: +expect(instance).to(beAKindOf(aClass)); +``` + +> Instances must be Objective-C objects: subclasses of `NSObject`, + or Swift objects bridged to Objective-C with the `@objc` prefix. + +For example, to assert that `dolphin` is a kind of `Mammal`: + +```swift +// Swift + +expect(dolphin).to(beAKindOf(Mammal)) +``` + +```objc +// Objective-C + +expect(dolphin).to(beAKindOf([Mammal class])); +``` + +> `beAnInstanceOf` uses the `-[NSObject isMemberOfClass:]` method to + test membership. `beAKindOf` uses `-[NSObject isKindOfClass:]`. + +## Truthiness + +```swift +// Passes if actual is not nil, false, or an object with a boolean value of false: +expect(actual).to(beTruthy()) + +// Passes if actual is only true (not nil or an object conforming to BooleanType true): +expect(actual).to(beTrue()) + +// Passes if actual is nil, false, or an object with a boolean value of false: +expect(actual).to(beFalsy()) + +// Passes if actual is only false (not nil or an object conforming to BooleanType false): +expect(actual).to(beFalse()) + +// Passes if actual is nil: +expect(actual).to(beNil()) +``` + +```objc +// Objective-C + +// Passes if actual is not nil, false, or an object with a boolean value of false: +expect(actual).to(beTruthy()); + +// Passes if actual is only true (not nil or an object conforming to BooleanType true): +expect(actual).to(beTrue()); + +// Passes if actual is nil, false, or an object with a boolean value of false: +expect(actual).to(beFalsy()); + +// Passes if actual is only false (not nil or an object conforming to BooleanType false): +expect(actual).to(beFalse()); + +// Passes if actual is nil: +expect(actual).to(beNil()); +``` + +## Swift Error Handling + +If you're using Swift 2.0+, you can use the `throwError` matcher to check if an error is thrown. + +```swift +// Swift + +// Passes if somethingThatThrows() throws an ErrorType: +expect{ try somethingThatThrows() }.to(throwError()) + +// Passes if somethingThatThrows() throws an error with a given domain: +expect{ try somethingThatThrows() }.to(throwError { (error: ErrorType) in + expect(error._domain).to(equal(NSCocoaErrorDomain)) +}) + +// Passes if somethingThatThrows() throws an error with a given case: +expect{ try somethingThatThrows() }.to(throwError(NSCocoaError.PropertyListReadCorruptError)) + +// Passes if somethingThatThrows() throws an error with a given type: +expect{ try somethingThatThrows() }.to(throwError(errorType: MyError.self)) +``` + +Note: This feature is only available in Swift. + +## Exceptions + +```swift +// Swift + +// Passes if actual, when evaluated, raises an exception: +expect(actual).to(raiseException()) + +// Passes if actual raises an exception with the given name: +expect(actual).to(raiseException(named: name)) + +// Passes if actual raises an exception with the given name and reason: +expect(actual).to(raiseException(named: name, reason: reason)) + +// Passes if actual raises an exception and it passes expectations in the block +// (in this case, if name begins with 'a r') +expect { exception.raise() }.to(raiseException { (exception: NSException) in + expect(exception.name).to(beginWith("a r")) +}) +``` + +```objc +// Objective-C + +// Passes if actual, when evaluated, raises an exception: +expect(actual).to(raiseException()) + +// Passes if actual raises an exception with the given name +expect(actual).to(raiseException().named(name)) + +// Passes if actual raises an exception with the given name and reason: +expect(actual).to(raiseException().named(name).reason(reason)) + +// Passes if actual raises an exception and it passes expectations in the block +// (in this case, if name begins with 'a r') +expect(actual).to(raiseException().satisfyingBlock(^(NSException *exception) { + expect(exception.name).to(beginWith(@"a r")); +})); +``` + +Note: Swift currently doesn't have exceptions. Only Objective-C code can raise +exceptions that Nimble will catch. + +## Collection Membership + +```swift +// Swift + +// Passes if all of the expected values are members of actual: +expect(actual).to(contain(expected...)) + +// Passes if actual is an empty collection (it contains no elements): +expect(actual).to(beEmpty()) +``` + +```objc +// Objective-C + +// Passes if expected is a member of actual: +expect(actual).to(contain(expected)); + +// Passes if actual is an empty collection (it contains no elements): +expect(actual).to(beEmpty()); +``` + +> In Swift `contain` takes any number of arguments. The expectation + passes if all of them are members of the collection. In Objective-C, + `contain` only takes one argument [for now](https://github.com/Quick/Nimble/issues/27). + +For example, to assert that a list of sea creature names contains +"dolphin" and "starfish": + +```swift +// Swift + +expect(["whale", "dolphin", "starfish"]).to(contain("dolphin", "starfish")) +``` + +```objc +// Objective-C + +expect(@[@"whale", @"dolphin", @"starfish"]).to(contain(@"dolphin")); +expect(@[@"whale", @"dolphin", @"starfish"]).to(contain(@"starfish")); +``` + +> `contain` and `beEmpty` expect collections to be instances of + `NSArray`, `NSSet`, or a Swift collection composed of `Equatable` elements. + +To test whether a set of elements is present at the beginning or end of +an ordered collection, use `beginWith` and `endWith`: + +```swift +// Swift + +// Passes if the elements in expected appear at the beginning of actual: +expect(actual).to(beginWith(expected...)) + +// Passes if the the elements in expected come at the end of actual: +expect(actual).to(endWith(expected...)) +``` + +```objc +// Objective-C + +// Passes if the elements in expected appear at the beginning of actual: +expect(actual).to(beginWith(expected)); + +// Passes if the the elements in expected come at the end of actual: +expect(actual).to(endWith(expected)); +``` + +> `beginWith` and `endWith` expect collections to be instances of + `NSArray`, or ordered Swift collections composed of `Equatable` + elements. + + Like `contain`, in Objective-C `beginWith` and `endWith` only support + a single argument [for now](https://github.com/Quick/Nimble/issues/27). + +## Strings + +```swift +// Swift + +// Passes if actual contains substring expected: +expect(actual).to(contain(expected)) + +// Passes if actual begins with substring: +expect(actual).to(beginWith(expected)) + +// Passes if actual ends with substring: +expect(actual).to(endWith(expected)) + +// Passes if actual is an empty string, "": +expect(actual).to(beEmpty()) + +// Passes if actual matches the regular expression defined in expected: +expect(actual).to(match(expected)) +``` + +```objc +// Objective-C + +// Passes if actual contains substring expected: +expect(actual).to(contain(expected)); + +// Passes if actual begins with substring: +expect(actual).to(beginWith(expected)); + +// Passes if actual ends with substring: +expect(actual).to(endWith(expected)); + +// Passes if actual is an empty string, "": +expect(actual).to(beEmpty()); + +// Passes if actual matches the regular expression defined in expected: +expect(actual).to(match(expected)) +``` + +## Checking if all elements of a collection pass a condition + +```swift +// Swift + +// with a custom function: +expect([1,2,3,4]).to(allPass({$0 < 5})) + +// with another matcher: +expect([1,2,3,4]).to(allPass(beLessThan(5))) +``` + +```objc +// Objective-C + +expect(@[@1, @2, @3,@4]).to(allPass(beLessThan(@5))); +``` + +For Swift the actual value has to be a SequenceType, e.g. an array, a set or a custom seqence type. + +For Objective-C the actual value has to be a NSFastEnumeration, e.g. NSArray and NSSet, of NSObjects and only the variant which +uses another matcher is available here. + +# Writing Your Own Matchers + +In Nimble, matchers are Swift functions that take an expected +value and return a `MatcherFunc` closure. Take `equal`, for example: + +```swift +// Swift + +public func equal(expectedValue: T?) -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "equal <\(expectedValue)>" + return actualExpression.evaluate() == expectedValue + } +} +``` + +The return value of a `MatcherFunc` closure is a `Bool` that indicates +whether the actual value matches the expectation: `true` if it does, or +`false` if it doesn't. + +> The actual `equal` matcher function does not match when either + `actual` or `expected` are nil; the example above has been edited for + brevity. + +Since matchers are just Swift functions, you can define them anywhere: +at the top of your test file, in a file shared by all of your tests, or +in an Xcode project you distribute to others. + +> If you write a matcher you think everyone can use, consider adding it + to Nimble's built-in set of matchers by sending a pull request! Or + distribute it yourself via GitHub. + +For examples of how to write your own matchers, just check out the +[`Matchers` directory](https://github.com/Quick/Nimble/tree/master/Nimble/Matchers) +to see how Nimble's built-in set of matchers are implemented. You can +also check out the tips below. + +## Lazy Evaluation + +`actualExpression` is a lazy, memoized closure around the value provided to the +`expect` function. The expression can either be a closure or a value directly +passed to `expect(...)`. In order to determine whether that value matches, +custom matchers should call `actualExpression.evaluate()`: + +```swift +// Swift + +public func beNil() -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "be nil" + return actualExpression.evaluate() == nil + } +} +``` + +In the above example, `actualExpression` is not `nil`--it is a closure +that returns a value. The value it returns, which is accessed via the +`evaluate()` method, may be `nil`. If that value is `nil`, the `beNil` +matcher function returns `true`, indicating that the expectation passed. + +Use `expression.isClosure` to determine if the expression will be invoking +a closure to produce its value. + +## Type Checking via Swift Generics + +Using Swift's generics, matchers can constrain the type of the actual value +passed to the `expect` function by modifying the return type. + +For example, the following matcher, `haveDescription`, only accepts actual +values that implement the `Printable` protocol. It checks their `description` +against the one provided to the matcher function, and passes if they are the same: + +```swift +// Swift + +public func haveDescription(description: String) -> MatcherFunc { + return MatcherFunc { actual, failureMessage in + return actual.evaluate().description == description + } +} +``` + +## Customizing Failure Messages + +By default, Nimble outputs the following failure message when an +expectation fails: + +``` +expected to match, got <\(actual)> +``` + +You can customize this message by modifying the `failureMessage` struct +from within your `MatcherFunc` closure. To change the verb "match" to +something else, update the `postfixMessage` property: + +```swift +// Swift + +// Outputs: expected to be under the sea, got <\(actual)> +failureMessage.postfixMessage = "be under the sea" +``` + +You can change how the `actual` value is displayed by updating +`failureMessage.actualValue`. Or, to remove it altogether, set it to +`nil`: + +```swift +// Swift + +// Outputs: expected to be under the sea +failureMessage.actualValue = nil +failureMessage.postfixMessage = "be under the sea" +``` + +## Supporting Objective-C + +To use a custom matcher written in Swift from Objective-C, you'll have +to extend the `NMBObjCMatcher` class, adding a new class method for your +custom matcher. The example below defines the class method +`+[NMBObjCMatcher beNilMatcher]`: + +```swift +// Swift + +extension NMBObjCMatcher { + public class func beNilMatcher() -> NMBObjCMatcher { + return NMBObjCMatcher { actualBlock, failureMessage, location in + let block = ({ actualBlock() as NSObject? }) + let expr = Expression(expression: block, location: location) + return beNil().matches(expr, failureMessage: failureMessage) + } + } +} +``` + +The above allows you to use the matcher from Objective-C: + +```objc +// Objective-C + +expect(actual).to([NMBObjCMatcher beNilMatcher]()); +``` + +To make the syntax easier to use, define a C function that calls the +class method: + +```objc +// Objective-C + +FOUNDATION_EXPORT id beNil() { + return [NMBObjCMatcher beNilMatcher]; +} +``` + +### Properly Handling `nil` in Objective-C Matchers + +When supporting Objective-C, make sure you handle `nil` appropriately. +Like [Cedar](https://github.com/pivotal/cedar/issues/100), +**most matchers do not match with nil**. This is to bring prevent test +writers from being surprised by `nil` values where they did not expect +them. + +Nimble provides the `beNil` matcher function for test writer that want +to make expectations on `nil` objects: + +```objc +// Objective-C + +expect(nil).to(equal(nil)); // fails +expect(nil).to(beNil()); // passes +``` + +If your matcher does not want to match with nil, you use `NonNilMatcherFunc` +and the `canMatchNil` constructor on `NMBObjCMatcher`. Using both types will +automatically generate expected value failure messages when they're nil. + +```swift + +public func beginWith(startingElement: T) -> NonNilMatcherFunc { + return NonNilMatcherFunc { actualExpression, failureMessage in + failureMessage.postfixMessage = "begin with <\(startingElement)>" + if let actualValue = actualExpression.evaluate() { + var actualGenerator = actualValue.generate() + return actualGenerator.next() == startingElement + } + return false + } +} + +extension NMBObjCMatcher { + public class func beginWithMatcher(expected: AnyObject) -> NMBObjCMatcher { + return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in + let actual = actualExpression.evaluate() + let expr = actualExpression.cast { $0 as? NMBOrderedCollection } + return beginWith(expected).matches(expr, failureMessage: failureMessage) + } + } +} +``` + +# Installing Nimble + +> Nimble can be used on its own, or in conjunction with its sister + project, [Quick](https://github.com/Quick/Quick). To install both + Quick and Nimble, follow [the installation instructions in the Quick + README](https://github.com/Quick/Quick#how-to-install-quick). + +Nimble can currently be installed in one of two ways: using CocoaPods, or with +git submodules. + +- The `swift-2.0` branch support Swift 2.0. +- The `master` branch of Nimble supports Swift 1.2. +- For Swift 1.1 support, use the `swift-1.1` branch. + +## Installing Nimble as a Submodule + +To use Nimble as a submodule to test your iOS or OS X applications, follow these +4 easy steps: + +1. Clone the Nimble repository +2. Add Nimble.xcodeproj to the Xcode workspace for your project +3. Link Nimble.framework to your test target +4. Start writing expectations! + +For more detailed instructions on each of these steps, +read [How to Install Quick](https://github.com/Quick/Quick#how-to-install-quick). +Ignore the steps involving adding Quick to your project in order to +install just Nimble. + +## Installing Nimble via CocoaPods + +To use Nimble in CocoaPods to test your iOS or OS X applications, add Nimble to +your podfile and add the ```use_frameworks!``` line to enable Swift support for +Cocoapods. + +```ruby +platform :ios, '8.0' + +source 'https://github.com/CocoaPods/Specs.git' + +# Whatever pods you need for your app go here + +target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do + use_frameworks! + # If you're using Swift 2.0 (Xcode 7), use this: + pod 'Nimble', '2.0.0-rc.2' + # If you're using Swift 1.2 (Xcode 6), use this: + pod 'Nimble', '~> 1.0.0' + # Otherwise, use this commented out line for Swift 1.1 (Xcode 6.2): + # pod 'Nimble', '~> 0.3.0' +end +``` + +Finally run `pod install`. + +## Using Nimble without XCTest + +Nimble is integrated with XCTest to allow it work well when used in Xcode test +bundles, however it can also be used in a standalone app. After installing +Nimble using one of the above methods, there are two additional steps required +to make this work. + +1. Create a custom assertion handler and assign an instance of it to the + global `NimbleAssertionHandler` variable. For example: + +```swift +class MyAssertionHandler : AssertionHandler { + func assert(assertion: Bool, message: FailureMessage, location: SourceLocation) { + if (!assertion) { + print("Expectation failed: \(message.stringValue)") + } + } +} +``` +```swift +// Somewhere before you use any assertions +NimbleAssertionHandler = MyAssertionHandler() +``` + +2. Add a post-build action to fix an issue with the Swift XCTest support + library being unnecessarily copied into your app + * Edit your scheme in Xcode, and navigate to Build -> Post-actions + * Click the "+" icon and select "New Run Script Action" + * Open the "Provide build settings from" dropdown and select your target + * Enter the following script contents: +``` +rm "${SWIFT_STDLIB_TOOL_DESTINATION_DIR}/libswiftXCTest.dylib" +``` + +You can now use Nimble assertions in your code and handle failures as you see +fit. diff --git a/Carthage/Checkouts/Nimble/circle.yml b/Carthage/Checkouts/Nimble/circle.yml new file mode 100644 index 00000000..0b527c1b --- /dev/null +++ b/Carthage/Checkouts/Nimble/circle.yml @@ -0,0 +1,42 @@ +machine: + xcode: + version: "6.3.1" + +general: + branches: + ignore: + - swift-2.0 # Circle CI doesn't support Xcode 7/Swift 2.0 yet. + +# despite what circle ci says, xctool 0.2.3 cannot run +# ios simulator tests on iOS frameworks for whatever reason. +# +# See: https://github.com/facebook/xctool/issues/415 +test: + override: + - set -o pipefail && + xcodebuild + -scheme "Nimble-iOS" + -sdk iphonesimulator + -destination 'platform=iOS Simulator,OS=8.1,name=iPhone 6' + -project Nimble.xcodeproj + -configuration Debug + CODE_SIGNING_REQUIRED=NO + CODE_SIGN_IDENTITY= + PROVISIONING_PROFILE= + clean test | + tee $CIRCLE_ARTIFACTS/xcode_raw_ios.log | + xcpretty --color --report junit --output $CIRCLE_TEST_REPORTS/xcode/ios-results.xml + - set -o pipefail && + xcodebuild + -scheme "Nimble-OSX" + -sdk macosx + -project Nimble.xcodeproj + -configuration Debug + CODE_SIGNING_REQUIRED=NO + CODE_SIGN_IDENTITY= + PROVISIONING_PROFILE= + clean test | + tee $CIRCLE_ARTIFACTS/xcode_raw_osx.log | + xcpretty --color --report junit --output $CIRCLE_TEST_REPORTS/xcode/osx-results.xml + + diff --git a/Carthage/Checkouts/Nimble/script/release b/Carthage/Checkouts/Nimble/script/release new file mode 100755 index 00000000..0a964217 --- /dev/null +++ b/Carthage/Checkouts/Nimble/script/release @@ -0,0 +1,178 @@ +#!/usr/bin/env sh +REMOTE_BRANCH=swift-2.0 +POD_NAME=Nimble +PODSPEC=Nimble.podspec +GITHUB_TAGS_URL=https://github.com/Quick/Nimble/tags +CARTHAGE_FRAMEWORK_NAME=Nimble + +CARTHAGE=${CARTHAGE:-carthage} +POD=${COCOAPODS:-pod} + +function help { + echo "Usage: release VERSION RELEASE_NOTES [-f]" + echo + echo "VERSION should be the version to release, should not include the 'v' prefix" + echo "RELEASE_NOTES should be a file that lists all the release notes for this version" + echo + echo "FLAGS" + echo " -f Forces override of tag" + echo + echo " Example: ./release 1.0.0-rc.2 ./release-notes.txt" + echo + echo "HINT: use 'git diff ...HEAD' to build the release notes" + echo + exit 2 +} + +function die { + echo "[ERROR] $@" + echo + exit 1 +} + +if [ $# -lt 2 ]; then + help +fi + +VERSION=$1 +RELEASE_NOTES=$2 +FORCE_TAG=$3 + +VERSION_TAG="v$VERSION" + +echo "-> Verifying Local Directory for Release" + +if [ -z "`which $CARTHAGE`" ]; then + die "Carthage is required to produce a release. Aborting." +fi +echo " > Carthage is installed" + +if [ -z "`which $POD`" ]; then + die "Cocoapods is required to produce a release. Aborting." +fi +echo " > Cocoapods is installed" + +echo " > Is this a reasonable tag?" + +echo $VERSION_TAG | grep -q "^vv" +if [ $? -eq 0 ]; then + die "This tag ($VERSION) is an incorrect format. You should remove the 'v' prefix." +fi + +echo $VERSION_TAG | grep -q -E "^v\d+\.\d+\.\d+(-\w+(\.\d)?)?\$" +if [ $? -ne 0 ]; then + die "This tag ($VERSION) is an incorrect format. It should be in 'v{MAJOR}.{MINOR}.{PATCH}(-{PRERELEASE_NAME}.{PRERELEASE_VERSION})' form." +fi + +echo " > Is this version ($VERSION) unique?" +git describe --exact-match "$VERSION_TAG" 2>&1 > /dev/null +if [ $? -eq 0 ]; then + if [ -z "$FORCE_TAG" ]; then + die "This tag ($VERSION) already exists. Aborting. Append '-f' to override" + else + echo " > NO, but force was specified." + fi +else + echo " > Yes, tag is unique" +fi + +if [ ! -f "$RELEASE_NOTES" ]; then + die "Failed to find $RELEASE_NOTES. Aborting." +fi +echo " > Release notes: $RELEASE_NOTES" + +if [ ! -f "$PODSPEC" ]; then + die "Cannot find podspec: $PODSPEC. Aborting." +fi +echo " > Podspec exists" + +git config --get user.signingkey > /dev/null || { + echo "[ERROR] No PGP found to sign tag. Aborting." + echo + echo " Creating a release requires signing the tag for security purposes. This allows users to verify the git cloned tree is from a trusted source." + echo " From a security perspective, it is not considered safe to trust the commits (including Author & Signed-off fields). It is easy for any" + echo " intermediate between you and the end-users to modify the git repository." + echo + echo " While not all users may choose to verify the PGP key for tagged releases. It is a good measure to ensure 'this is an official release'" + echo " from the official maintainers." + echo + echo " If you're creating your PGP key for the first time, use RSA with at least 4096 bits." + echo + echo "Related resources:" + echo " - Configuring your system for PGP: https://git-scm.com/book/tr/v2/Git-Tools-Signing-Your-Work" + echo " - Why: http://programmers.stackexchange.com/questions/212192/what-are-the-advantages-and-disadvantages-of-cryptographically-signing-commits-a" + echo + exit 2 +} +echo " > Found PGP key for git" + +# Verify cocoapods trunk ownership +pod trunk me | grep -q "$POD_NAME" || die "You do not have access to pod repository $POD_NAME. Aborting." +echo " > Verified ownership to $POD_NAME pod" + + +echo "--- Releasing version $VERSION (tag: $VERSION_TAG)..." + +function restore_podspec { + if [ -f 'Nimble.podspec.backup' ]; then + mv -f Nimble.podspec{.backup,} + fi +} + +echo "-> Ensuring no differences to origin/$REMOTE_BRANCH" +git fetch origin || die "Failed to fetch origin" +git diff --quiet HEAD "origin/$REMOTE_BRANCH" || die "HEAD is not aligned to origin/$REMOTE_BRANCH. Cannot update version safely" + +echo "-> Building Carthage release" +$CARTHAGE build --no-skip-current || die "Failed to build framework for carthage" + +echo "-> Setting podspec version" +cat "$PODSPEC" | grep 's.version' | grep -q "\"$VERSION\"" +if [ $? -eq 0 ]; then + echo " > Podspec already set to $VERSION. Skipping." +else + sed -i.backup "s/s.version *= *\".*\"/s.version = \"$VERSION\"/g" "$PODSPEC" || { + restore_podspec + die "Failed to update version in podspec" + } + + git add Nimble.podspec || { restore_podspec; die "Failed to add Nimble.podspec to INDEX"; } + git commit -m "Bumping version to $VERSION" || { restore_podspec; die "Failed to push updated version: $VERSION"; } + git push origin "$REMOTE_BRANCH" || die "Failed to push to origin" + echo " > Pushed version to origin" +fi + +if [ -z "$FORCE_TAG" ]; then + echo "-> Tagging version" + git tag -s "$VERSION_TAG" -F "$RELEASE_NOTES" || die "Failed to tag version" + echo "-> Pushing tag to origin" + git push origin "$VERSION_TAG" || die "Failed to push tag '$VERSION_TAG' to origin" +else + echo "-> Tagging version (force)" + git tag -f -s "$VERSION_TAG" -F "$RELEASE_NOTES" || die "Failed to tag version" + echo "-> Pushing tag to origin (force)" + git push origin "$VERSION_TAG" -f || die "Failed to push tag '$VERSION_TAG' to origin" +fi + +echo +echo "---------------- Released as $VERSION_TAG ----------------" +echo +echo "Archiving carthage release..." + +$CARTHAGE archive "$CARTHAGE_FRAMEWORK_NAME" || die "Failed to archive framework for carthage" + +echo +echo "Pushing to pod trunk..." + +$POD trunk push "$PODSPEC" + +echo +echo "================ Finalizing the Release ================" +echo +echo " - Go to $GITHUB_TAGS_URL and mark this as a release." +echo " - Paste the contents of $RELEASE_NOTES into the release notes. Tweak for Github styling." +echo " - Attach ${CARTHAGE_FRAMEWORK_NAME}.framework.zip to it." +echo " - Announce!" + +rm Nimble.podspec.backup + diff --git a/Carthage/Checkouts/Nimble/test b/Carthage/Checkouts/Nimble/test new file mode 100755 index 00000000..83fdc8d8 --- /dev/null +++ b/Carthage/Checkouts/Nimble/test @@ -0,0 +1,100 @@ +#!/bin/sh + +BUILD_DIR=`pwd`/build +LATEST_IOS_SDK_VERSION=`xcodebuild -showsdks | grep iphonesimulator | cut -d ' ' -f 4 | ruby -e 'puts STDIN.read.chomp.split("\n").last'` +LATEST_OSX_SDK_VERSION=`xcodebuild -showsdks | grep 'macosx' | cut -d ' ' -f 3 | ruby -e 'puts STDIN.read.chomp.split("\n").last'` +BUILD_IOS_SDK_VERSION=${NIMBLE_BUILD_IOS_SDK_VERSION:-$LATEST_IOS_SDK_VERSION} +RUNTIME_IOS_SDK_VERSION=${NIMBLE_RUNTIME_IOS_SDK_VERSION:-$LATEST_IOS_SDK_VERSION} +BUILD_OSX_SDK_VERSION=${NIMBLE_BUILD_OSX_SDK_VERSION:-$LATEST_OSX_SDK_VERSION} + +set -e + +GREEN="\x1B[01;92m" +CLEAR="\x1B[0m" + +function color_if_overridden { + local actual=$1 + local env_var=$2 + if [ -z "$env_var" ]; then + printf "$actual" + else + printf "$GREEN$actual$CLEAR" + fi +} + +function print_env { + echo "=== Environment ===" + echo " iOS:" + echo " Latest iOS SDK: $LATEST_IOS_SDK_VERSION" + echo " Building with iOS SDK: `color_if_overridden $BUILD_IOS_SDK_VERSION $NIMBLE_BUILD_IOS_SDK_VERSION`" + echo " Running with iOS SDK: `color_if_overridden $RUNTIME_IOS_SDK_VERSION $NIMBLE_RUNTIME_IOS_SDK_VERSION`" + echo + echo " Mac OS X:" + echo " Latest OS X SDK: $LATEST_OSX_SDK_VERSION" + echo " Building with OS X SDK: `color_if_overridden $BUILD_OSX_SDK_VERSION $NIMBLE_BUILD_OSX_SDK_VERSION`" + echo + echo "======= END =======" + echo +} + +function run { + echo "$GREEN==>$CLEAR $@" + "$@" +} + +function test_ios { + run osascript -e 'tell app "iOS Simulator" to quit' + run xcodebuild -project Nimble.xcodeproj -scheme "Nimble-iOS" -configuration "Debug" -sdk "iphonesimulator$BUILD_IOS_SDK_VERSION" -destination "name=iPad Air,OS=$RUNTIME_IOS_SDK_VERSION" build test + + run osascript -e 'tell app "iOS Simulator" to quit' + run xcodebuild -project Nimble.xcodeproj -scheme "Nimble-iOS" -configuration "Debug" -sdk "iphonesimulator$BUILD_IOS_SDK_VERSION" -destination "name=iPhone 5s,OS=$RUNTIME_IOS_SDK_VERSION" build test +} + +function test_osx { + run xcodebuild -project Nimble.xcodeproj -scheme "Nimble-OSX" -configuration "Debug" -sdk "macosx$BUILD_OSX_SDK_VERSION" build test +} + +function test() { + test_ios + test_osx +} + +function clean { + run rm -rf ~/Library/Developer/Xcode/DerivedData\; true +} + +function help { + echo "Usage: $0 COMMANDS" + echo + echo "COMMANDS:" + echo " clean - Cleans the derived data directory of Xcode. Assumes default location" + echo " ios - Runs the tests as an iOS device" + echo " osx - Runs the tests on Mac OS X 10.10 (Yosemite and newer only)" + echo " all - Runs both ios and osx tests" + echo " help - Displays this help" + echo + exit 1 +} + +function main { + print_env + for arg in $@ + do + case "$arg" in + clean) clean ;; + ios) test_ios ;; + osx) test_osx ;; + test) test ;; + all) test ;; + help) help ;; + esac + done + + if [ $# -eq 0 ]; then + clean + test + fi +} + +main $@ +