From ee05caaf4f0999fd0c1b74452c82ad844455bb50 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Tue, 25 Oct 2016 14:48:13 +0200 Subject: [PATCH 01/23] Updated podspec --- SwinjectAutoregistration.podspec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SwinjectAutoregistration.podspec b/SwinjectAutoregistration.podspec index bd4f066..ce21ed3 100644 --- a/SwinjectAutoregistration.podspec +++ b/SwinjectAutoregistration.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'SwinjectAutoregistration' - s.version = '1.0.0' + s.version = '2.0.0' s.summary = 'Autoregistration for Swinject' s.description = <<-DESC SwinjectAutoregistration is an extension of Swinject to automatically inject dependency into registered services. @@ -15,5 +15,5 @@ SwinjectAutoregistration is an extension of Swinject to automatically inject dep s.source_files = 'SwinjectAutoregistration/Classes/**/*' - s.dependency 'Swinject', '1.1.5' + s.dependency 'Swinject', '~> 2.0.0-beta.2' end From 6206eda4a6ebf4cdc6189976a4bf4bb442dcd125 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Tue, 25 Oct 2016 14:54:34 +0200 Subject: [PATCH 02/23] Changed podspec to project structure --- SwinjectAutoregistration.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SwinjectAutoregistration.podspec b/SwinjectAutoregistration.podspec index ce21ed3..68c2da3 100644 --- a/SwinjectAutoregistration.podspec +++ b/SwinjectAutoregistration.podspec @@ -13,7 +13,7 @@ SwinjectAutoregistration is an extension of Swinject to automatically inject dep s.ios.deployment_target = '8.0' - s.source_files = 'SwinjectAutoregistration/Classes/**/*' + s.source_files = 'Sources/**/*' s.dependency 'Swinject', '~> 2.0.0-beta.2' end From c859a7860481bc03a8e11b1a40227dcff37cbf27 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Tue, 25 Oct 2016 15:33:32 +0200 Subject: [PATCH 03/23] Updated to newest Swinject --- Cartfile | 2 +- Cartfile.resolved | 4 +- Carthage/Checkouts/Nimble/.gitignore | 4 +- Carthage/Checkouts/Nimble/.travis.yml | 6 +- Carthage/Checkouts/Nimble/CONTRIBUTING.md | 8 + Carthage/Checkouts/Nimble/Gemfile | 2 +- Carthage/Checkouts/Nimble/Gemfile.lock | 54 +- Carthage/Checkouts/Nimble/Nimble.podspec | 34 +- .../Nimble/Nimble.xcodeproj/project.pbxproj | 134 ++++- .../xcschemes/Nimble-tvOS.xcscheme | 4 +- Carthage/Checkouts/Nimble/Package.swift | 3 +- Carthage/Checkouts/Nimble/README.md | 86 ++- .../CwlCatchException/.gitignore | 3 + .../CwlCatchException/CwlCatchException.h | 30 + .../CwlCatchException/CwlCatchException.m | 35 ++ .../CwlCatchException/CwlCatchException.swift | 32 ++ .../CwlCatchException/Info.plist | 28 + .../CwlBadInstructionException.swift | 76 +++ .../CwlCatchBadInstruction.h | 61 ++ .../CwlCatchBadInstruction.m | 50 ++ .../CwlCatchBadInstruction.swift | 194 +++++++ .../CwlCatchBadInstructionPOSIX.swift | 100 ++++ .../CwlDarwinDefinitions.swift | 63 ++ .../CwlPreconditionTesting/Info.plist | 28 + .../CwlPreconditionTesting/mach_excServer.c | 537 ++++++++++++++++++ .../CwlPreconditionTesting/mach_excServer.h | 298 ++++++++++ .../Lib/CwlPreconditionTesting/README.md | 80 +++ .../Nimble/Adapters/NimbleEnvironment.swift | 4 +- .../Nimble/Sources/Nimble/DSL+Wait.swift | 9 +- .../Nimble/Matchers/AsyncMatcherWrapper.swift | 6 +- .../Sources/Nimble/Matchers/BeLessThan.swift | 2 +- .../Sources/Nimble/Matchers/BeLogical.swift | 8 +- .../Sources/Nimble/Matchers/Match.swift | 4 +- .../Nimble/Matchers/ThrowAssertion.swift | 55 ++ .../Checkouts/Nimble/Sources/Nimble/Nimble.h | 7 + .../Nimble/Sources/Nimble/Utils/Async.swift | 29 +- .../Nimble/Sources/Nimble/Utils/Errors.swift | 17 +- .../Nimble/Sources/NimbleObjectiveC/DSL.h | 294 +++++++++- .../Nimble/Sources/NimbleObjectiveC/DSL.m | 22 +- .../Checkouts/Nimble/Tests/LinuxMain.swift | 4 +- .../Tests/NimbleTests/AsynchronousTest.swift | 10 +- .../Tests/NimbleTests/Helpers/utils.swift | 3 +- .../NimbleTests/Matchers/MatchErrorTest.swift | 5 + .../NimbleTests/Matchers/MatchTest.swift | 3 - .../Matchers/ThrowAssertionTest.swift | 62 ++ .../NimbleTests/Matchers/ThrowErrorTest.swift | 1 - .../Tests/NimbleTests/SynchronousTests.swift | 6 +- .../NimbleTests/UserDescriptionTest.swift | 6 - .../NimbleTests/objc/ObjCBeCloseToTest.m | 11 + .../Tests/NimbleTests/objc/ObjCBeFalseTest.m | 22 + .../Tests/NimbleTests/objc/ObjCBeFalsyTest.m | 34 +- .../objc/ObjCBeGreaterThanOrEqualToTest.m | 9 + .../NimbleTests/objc/ObjCBeGreaterThanTest.m | 8 + .../NimbleTests/objc/ObjCBeIdenticalToTest.m | 6 + .../objc/ObjCBeLessThanOrEqualToTest.m | 10 + .../NimbleTests/objc/ObjCBeLessThanTest.m | 9 + .../Tests/NimbleTests/objc/ObjCBeTrueTest.m | 22 + .../Tests/NimbleTests/objc/ObjCBeTruthyTest.m | 27 + .../Tests/NimbleTests/objc/ObjCEqualTest.m | 59 ++ .../Tests/NimbleTests/objc/ObjCHaveCount.m | 71 ++- Carthage/Checkouts/Swinject/.swiftlint.yml | 2 +- Carthage/Checkouts/Swinject/.travis.yml | 6 +- .../Documentation/CircularDependencies.md | 23 + .../Documentation/ContainerHierarchy.md | 2 +- .../Swinject/Documentation/Properties.md | 140 ----- .../Swinject/Documentation/README.md | 15 +- .../Swinject/Documentation/Storyboard.md | 175 ------ .../Swinject/Documentation/ThreadSafety.md | 4 +- Carthage/Checkouts/Swinject/README.md | 59 +- .../Sample-iOS.playground/Contents.swift | 28 +- .../Swinject/Sources/Assembler.swift | 2 +- .../Swinject/Sources/AssemblyType.swift | 4 +- .../Swinject/Sources/Container.Arguments.erb | 8 +- .../Sources/Container.Arguments.swift | 56 +- .../Swinject/Sources/Container.Logging.swift | 24 + .../Swinject/Sources/Container.swift | 55 +- .../Swinject/Sources/DebugHelper.swift | 54 ++ .../Swinject/Sources/ResolutionPool.swift | 12 +- .../{ResolverType.erb => Resolver.erb} | 8 +- .../{ResolverType.swift => Resolver.swift} | 8 +- .../Swinject/Sources/ServiceEntry.swift | 18 +- .../SynchronizedResolver.Arguments.erb | 2 +- .../SynchronizedResolver.Arguments.swift | 2 +- .../Sources/SynchronizedResolver.swift | 4 +- .../{_ResolverType.swift => _Resolver.swift} | 6 +- .../Swinject.xcodeproj/project.pbxproj | 78 ++- .../Swinject/Tests/Circularity.swift | 14 +- .../Tests/ContainerSpec.Circularity.swift | 23 - .../Tests/ContainerSpec.DebugHelper.swift | 69 +++ .../Swinject/Tests/ContainerSpec.swift | 14 +- .../Swinject/Tests/LoadAwareAssembly.swift | 6 +- .../Swinject/Tests/ServiceKeySpec.swift | 32 +- Carthage/Checkouts/Swinject/script/gencode | 2 +- 93 files changed, 3069 insertions(+), 687 deletions(-) create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/README.md create mode 100644 Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift create mode 100644 Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift delete mode 100644 Carthage/Checkouts/Swinject/Documentation/Properties.md delete mode 100644 Carthage/Checkouts/Swinject/Documentation/Storyboard.md create mode 100644 Carthage/Checkouts/Swinject/Sources/Container.Logging.swift create mode 100644 Carthage/Checkouts/Swinject/Sources/DebugHelper.swift rename Carthage/Checkouts/Swinject/Sources/{ResolverType.erb => Resolver.erb} (91%) rename Carthage/Checkouts/Swinject/Sources/{ResolverType.swift => Resolver.swift} (98%) rename Carthage/Checkouts/Swinject/Sources/{_ResolverType.swift => _Resolver.swift} (86%) create mode 100644 Carthage/Checkouts/Swinject/Tests/ContainerSpec.DebugHelper.swift diff --git a/Cartfile b/Cartfile index 2d27e43..505d442 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "Swinject/Swinject" "2.0.0-beta.2" +github "Swinject/Swinject" "master" diff --git a/Cartfile.resolved b/Cartfile.resolved index c637c7b..2b4858d 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,4 +1,4 @@ -github "Quick/Nimble" "v5.0.0" +github "Quick/Nimble" "v5.1.0" github "Quick/Quick" "v0.10.0" -github "Swinject/Swinject" "2.0.0-beta.2" +github "Swinject/Swinject" "3083fe424d782a026590b4a53e6499dbb242d4b7" github "jspahrsummers/xcconfigs" "0.10" diff --git a/Carthage/Checkouts/Nimble/.gitignore b/Carthage/Checkouts/Nimble/.gitignore index b067294..e50906d 100644 --- a/Carthage/Checkouts/Nimble/.gitignore +++ b/Carthage/Checkouts/Nimble/.gitignore @@ -1,5 +1,7 @@ .DS_Store -xcuserdata/ +**/xcuserdata/* +**/*.xccheckout +**/*.xcscmblueprint build/ .idea DerivedData/ diff --git a/Carthage/Checkouts/Nimble/.travis.yml b/Carthage/Checkouts/Nimble/.travis.yml index 977a75b..3e2f896 100644 --- a/Carthage/Checkouts/Nimble/.travis.yml +++ b/Carthage/Checkouts/Nimble/.travis.yml @@ -2,9 +2,9 @@ osx_image: xcode8 language: generic matrix: include: - # - os: osx - # sudo: required - # env: TYPE=podspec + - os: osx + sudo: required + env: TYPE=podspec - os: osx env: TYPE=ios NIMBLE_RUNTIME_IOS_SDK_VERSION=10.0 - os: osx diff --git a/Carthage/Checkouts/Nimble/CONTRIBUTING.md b/Carthage/Checkouts/Nimble/CONTRIBUTING.md index a97114f..d9c4ba6 100644 --- a/Carthage/Checkouts/Nimble/CONTRIBUTING.md +++ b/Carthage/Checkouts/Nimble/CONTRIBUTING.md @@ -46,6 +46,14 @@ Be sure to include in your issue: - Use `Nimble.xcodeproj` to work on Nimble. +## Running the Swift Package Manager tests + +1. Install `swiftenv` by running a line from the build script (`.travis.yml`): + + eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/02090c7ede5a637b76e6df1710e83cd0bbe7dcdf/swiftenv-install.sh)" + +2. Run `./test swiftpm` + ## Pull Requests - Nothing is trivial. Submit pull requests for anything: typos, diff --git a/Carthage/Checkouts/Nimble/Gemfile b/Carthage/Checkouts/Nimble/Gemfile index 66d7eff..a6dc312 100644 --- a/Carthage/Checkouts/Nimble/Gemfile +++ b/Carthage/Checkouts/Nimble/Gemfile @@ -1,4 +1,4 @@ # A sample Gemfile source "https://rubygems.org" -gem 'cocoapods' +gem 'cocoapods', '1.1.0.rc.3' diff --git a/Carthage/Checkouts/Nimble/Gemfile.lock b/Carthage/Checkouts/Nimble/Gemfile.lock index 374561e..87dc02b 100644 --- a/Carthage/Checkouts/Nimble/Gemfile.lock +++ b/Carthage/Checkouts/Nimble/Gemfile.lock @@ -1,67 +1,69 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.2.6) + activesupport (4.2.7.1) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - claide (1.0.0) - cocoapods (1.0.1) - activesupport (>= 4.0.2) - claide (>= 1.0.0, < 2.0) - cocoapods-core (= 1.0.1) - cocoapods-deintegrate (>= 1.0.0, < 2.0) - cocoapods-downloader (>= 1.0.0, < 2.0) + claide (1.0.1) + cocoapods (1.1.0.rc.3) + activesupport (>= 4.0.2, < 5) + claide (>= 1.0.1, < 2.0) + cocoapods-core (= 1.1.0.rc.3) + cocoapods-deintegrate (>= 1.0.1, < 2.0) + cocoapods-downloader (>= 1.1.1, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.0.0, < 2.0) - cocoapods-try (>= 1.0.0, < 2.0) + cocoapods-trunk (= 1.1.0.beta.1) + cocoapods-try (>= 1.1.0, < 2.0) colored (~> 1.2) escape (~> 0.0.4) - fourflusher (~> 0.3.0) - molinillo (~> 0.4.5) + fourflusher (~> 2.0) + gh_inspector (~> 1.0) + molinillo (~> 0.5.1) nap (~> 1.0) - xcodeproj (>= 1.1.0, < 2.0) - cocoapods-core (1.0.1) - activesupport (>= 4.0.2) + xcodeproj (>= 1.3.2, < 2.0) + cocoapods-core (1.1.0.rc.3) + activesupport (>= 4.0.2, < 5) fuzzy_match (~> 2.0.4) nap (~> 1.0) - cocoapods-deintegrate (1.0.0) - cocoapods-downloader (1.0.1) + cocoapods-deintegrate (1.0.1) + cocoapods-downloader (1.1.1) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.0) cocoapods-stats (1.0.0) - cocoapods-trunk (1.0.0) + cocoapods-trunk (1.1.0.beta.1) nap (>= 0.8, < 2.0) netrc (= 0.7.8) - cocoapods-try (1.0.0) + cocoapods-try (1.1.0) colored (1.2) escape (0.0.4) - fourflusher (0.3.2) + fourflusher (2.0.1) fuzzy_match (2.0.4) + gh_inspector (1.0.2) i18n (0.7.0) json (1.8.3) - minitest (5.9.0) - molinillo (0.4.5) + minitest (5.9.1) + molinillo (0.5.1) nap (1.1.0) netrc (0.7.8) thread_safe (0.3.5) tzinfo (1.2.2) thread_safe (~> 0.1) - xcodeproj (1.1.0) + xcodeproj (1.3.2) activesupport (>= 3) - claide (>= 1.0.0, < 2.0) + claide (>= 1.0.1, < 2.0) colored (~> 1.2) PLATFORMS ruby DEPENDENCIES - cocoapods + cocoapods (= 1.1.0.rc.3) BUNDLED WITH - 1.12.3 + 1.13.1 diff --git a/Carthage/Checkouts/Nimble/Nimble.podspec b/Carthage/Checkouts/Nimble/Nimble.podspec index 5fa0974..bcc2d4a 100644 --- a/Carthage/Checkouts/Nimble/Nimble.podspec +++ b/Carthage/Checkouts/Nimble/Nimble.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Nimble" - s.version = "5.0.0" + s.version = "5.1.0" 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. @@ -11,12 +11,38 @@ Pod::Spec.new do |s| s.ios.deployment_target = "8.0" s.osx.deployment_target = "10.10" s.tvos.deployment_target = "9.0" - s.source = { :git => "https://github.com/Quick/Nimble.git", :tag => "v#{s.version}" } + s.source = { :git => "https://github.com/Quick/Nimble.git", + :tag => "v#{s.version}" } + + s.source_files = "Sources/**/*.{swift,h,m,c}" + + s.osx.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift", + ] + s.ios.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift", + ] + s.tvos.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.{h,c}", + "Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException.swift", + "Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException.m", + ] - s.source_files = "Sources/**/**/*.{swift,h,m}" s.private_header_files = "Sources/NimbleObjectiveC/CurrentTestCaseTracker.h" + s.osx.private_header_files = "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h" + s.tvos.private_header_files = "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h" + s.exclude_files = "Sources/Nimble/Adapters/NonObjectiveC/*.swift" 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"' } + s.compiler_flags = '-DPRODUCT_NAME=Nimble/Nimble' + 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 index c6fe033..14378e7 100644 --- a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.pbxproj +++ b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.pbxproj @@ -48,6 +48,8 @@ 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 */; }; + 1F2D175B1DB618ED00EE9C7A /* mach_excServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0261C6D0BB0000693EE /* mach_excServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F2D175C1DB618F000EE9C7A /* mach_excServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0221C6D0B82000693EE /* mach_excServer.c */; }; 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 */; }; @@ -94,6 +96,14 @@ 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 */; }; + 1F4BB8A41DAC9DC90048464B /* CwlCatchBadInstructionPOSIX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */; }; + 1F4BB8AB1DAC9DE50048464B /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F4BB8AE1DAC9DED0048464B /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F4BB8B61DACA0E30048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8B71DACA0E40048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8B81DACAACF0048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8BA1DACBFCF0048464B /* CwlCatchBadInstruction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */; }; + 1F4BB8BB1DACBFD00048464B /* CwlCatchBadInstruction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */; }; 1F5DF15F1BDCA0CE00C3A531 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F5DF1551BDCA0CE00C3A531 /* Nimble.framework */; }; 1F5DF16C1BDCA0F500C3A531 /* AssertionRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD051968AB07008ED995 /* AssertionRecorder.swift */; }; 1F5DF16D1BDCA0F500C3A531 /* AdapterProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD061968AB07008ED995 /* AdapterProtocols.swift */; }; @@ -282,11 +292,25 @@ 7B5358BE1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; 7B5358BF1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; 7B5358C01C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; - 7B5358C51C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */; }; - 7B5358C61C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */; }; - 8DF1C3F71C94FC75004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; - 8DF1C3F81C94FC75004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; - 8DF1C3F91C94FD0C004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; + 9630C00D1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C00E1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C0131C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */; }; + 9630C0141C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */; }; + 9630C0191C6D0B2F000693EE /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C01A1C6D0B2F000693EE /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C01C1C6D0B2F000693EE /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0171C6D0B2F000693EE /* CwlCatchException.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 9630C01D1C6D0B2F000693EE /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0171C6D0B2F000693EE /* CwlCatchException.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 9630C01F1C6D0B2F000693EE /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */; }; + 9630C0201C6D0B2F000693EE /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */; }; + 9630C0231C6D0B82000693EE /* mach_excServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0221C6D0B82000693EE /* mach_excServer.c */; }; + 9630C0271C6D0BB0000693EE /* mach_excServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0261C6D0BB0000693EE /* mach_excServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C02C1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */; }; + 9630C02D1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */; }; + 9630C0301C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */; }; + 9630C0311C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */; }; + 964CFEFD1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; + 964CFEFE1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; + 964CFEFF1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.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 */; }; @@ -455,6 +479,8 @@ 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 = ""; }; + 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchBadInstructionPOSIX.swift; path = CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift; sourceTree = ""; }; + 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowAssertionTest.swift; sourceTree = ""; }; 1F5DF1551BDCA0CE00C3A531 /* Nimble.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1F5DF15E1BDCA0CE00C3A531 /* NimbleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSyncTest.m; sourceTree = ""; }; @@ -521,6 +547,17 @@ 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SatisfyAnyOf.swift; sourceTree = ""; }; 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSatisfyAnyOfTest.m; sourceTree = ""; }; 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjcStringersTest.m; sourceTree = ""; }; + 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CwlCatchBadInstruction.h; path = CwlPreconditionTesting/CwlCatchBadInstruction.h; sourceTree = ""; }; + 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CwlCatchBadInstruction.m; path = CwlPreconditionTesting/CwlCatchBadInstruction.m; sourceTree = ""; }; + 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchBadInstruction.swift; path = CwlPreconditionTesting/CwlCatchBadInstruction.swift; sourceTree = ""; }; + 9630C0161C6D0B2F000693EE /* CwlCatchException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CwlCatchException.h; path = CwlCatchException/CwlCatchException/CwlCatchException.h; sourceTree = ""; }; + 9630C0171C6D0B2F000693EE /* CwlCatchException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CwlCatchException.m; path = CwlCatchException/CwlCatchException/CwlCatchException.m; sourceTree = ""; }; + 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchException.swift; path = CwlCatchException/CwlCatchException/CwlCatchException.swift; sourceTree = ""; }; + 9630C0221C6D0B82000693EE /* mach_excServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mach_excServer.c; path = CwlPreconditionTesting/mach_excServer.c; sourceTree = ""; }; + 9630C0261C6D0BB0000693EE /* mach_excServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mach_excServer.h; path = CwlPreconditionTesting/mach_excServer.h; sourceTree = ""; }; + 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlBadInstructionException.swift; path = CwlPreconditionTesting/CwlBadInstructionException.swift; sourceTree = ""; }; + 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlDarwinDefinitions.swift; path = CwlPreconditionTesting/CwlDarwinDefinitions.swift; sourceTree = ""; }; + 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowAssertion.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 = ""; }; AE4BA9AC1C88DDB500B73906 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; @@ -627,6 +664,7 @@ 1F1A742B1940169200FFFC47 /* Nimble */, 1F1871B91CA89E1B00A34BF2 /* NimbleObjectiveC */, 1F1A74381940169200FFFC47 /* NimbleTests */, + 9630C0081C6D0AB3000693EE /* Lib */, 1F1A742A1940169200FFFC47 /* Products */, ); indentWidth = 4; @@ -717,6 +755,7 @@ 7B5358B91C3846C900A23FAA /* SatisfyAnyOfTest.swift */, 1FCF914E1C61C85A00B15DCB /* PostNotificationTest.swift */, AE7ADE481C80C00D00B94CD3 /* MatchErrorTest.swift */, + 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */, ); path = Matchers; sourceTree = ""; @@ -764,6 +803,7 @@ AE7ADE441C80BF8000B94CD3 /* MatchError.swift */, 1FCF91521C61C8A400B15DCB /* PostNotification.swift */, 1FD8CD1E1968AB07008ED995 /* RaisesException.swift */, + 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */, 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */, 29EA59651B551EE6002D767E /* ThrowError.swift */, ); @@ -817,6 +857,33 @@ path = objc; sourceTree = ""; }; + 9630C0081C6D0AB3000693EE /* Lib */ = { + isa = PBXGroup; + children = ( + 9630C0091C6D0ABA000693EE /* CwlPreconditionTesting */, + ); + name = Lib; + path = Sources/Lib; + sourceTree = ""; + }; + 9630C0091C6D0ABA000693EE /* CwlPreconditionTesting */ = { + isa = PBXGroup; + children = ( + 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */, + 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */, + 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */, + 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */, + 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */, + 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */, + 9630C0161C6D0B2F000693EE /* CwlCatchException.h */, + 9630C0171C6D0B2F000693EE /* CwlCatchException.m */, + 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */, + 9630C0261C6D0BB0000693EE /* mach_excServer.h */, + 9630C0221C6D0B82000693EE /* mach_excServer.c */, + ); + path = CwlPreconditionTesting; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -824,10 +891,13 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 9630C00D1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */, + 9630C0191C6D0B2F000693EE /* CwlCatchException.h in Headers */, 1F1871C91CA89EDB00A34BF2 /* NMBStringify.h in Headers */, 1F1871C51CA89EDB00A34BF2 /* DSL.h in Headers */, 1F1871C71CA89EDB00A34BF2 /* NMBExceptionCapture.h in Headers */, 1F1A742F1940169200FFFC47 /* Nimble.h in Headers */, + 9630C0271C6D0BB0000693EE /* mach_excServer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -835,9 +905,11 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1F4BB8AE1DAC9DED0048464B /* CwlCatchException.h in Headers */, 1F1871E21CA89EF600A34BF2 /* NMBStringify.h in Headers */, 1F1871E01CA89EF600A34BF2 /* DSL.h in Headers */, 1F1871E11CA89EF600A34BF2 /* NMBExceptionCapture.h in Headers */, + 1F4BB8AB1DAC9DE50048464B /* CwlCatchBadInstruction.h in Headers */, 1F5DF1AE1BDCA17600C3A531 /* Nimble.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -846,6 +918,9 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 9630C00E1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */, + 9630C01A1C6D0B2F000693EE /* CwlCatchException.h in Headers */, + 1F2D175B1DB618ED00EE9C7A /* mach_excServer.h in Headers */, 1F1871DF1CA89EF500A34BF2 /* NMBStringify.h in Headers */, 1F1871DD1CA89EF500A34BF2 /* DSL.h in Headers */, 1F1871DE1CA89EF500A34BF2 /* NMBExceptionCapture.h in Headers */, @@ -1109,6 +1184,7 @@ 1F1871C61CA89EDB00A34BF2 /* DSL.m in Sources */, 1FD8CD301968AB07008ED995 /* AdapterProtocols.swift in Sources */, AE7ADE451C80BF8000B94CD3 /* MatchError.swift in Sources */, + 1F4BB8BA1DACBFCF0048464B /* CwlCatchBadInstruction.m in Sources */, 1FC494AA1C29CBA40010975C /* NimbleEnvironment.swift in Sources */, 1FD8CD5E1968AB07008ED995 /* RaisesException.swift in Sources */, 1FD8CD561968AB07008ED995 /* Contain.swift in Sources */, @@ -1128,6 +1204,13 @@ 1FD8CD381968AB07008ED995 /* Expression.swift in Sources */, 1FD8CD3A1968AB07008ED995 /* FailureMessage.swift in Sources */, 472FD1351B9E085700C7B8DA /* HaveCount.swift in Sources */, + 9630C0301C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */, + 9630C0231C6D0B82000693EE /* mach_excServer.c in Sources */, + 9630C01F1C6D0B2F000693EE /* CwlCatchException.swift in Sources */, + 9630C0131C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */, + 9630C01C1C6D0B2F000693EE /* CwlCatchException.m in Sources */, + 9630C02C1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */, + 964CFEFD1C4FF48900513336 /* ThrowAssertion.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1146,7 +1229,6 @@ DDB4D5F019FE442800E9D9FE /* MatchTest.swift in Sources */, 1F4A56731A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */, 1F4A56821A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */, - 8DF1C3F71C94FC75004B2D36 /* ObjcStringersTest.m in Sources */, 1F925F02195C189500ED456B /* ContainTest.swift in Sources */, 1F4A56881A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */, 1F4A568E1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */, @@ -1179,6 +1261,7 @@ 1F0648CC19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */, 1F4A56851A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */, DD9A9A8F19CF439B00706F49 /* BeIdenticalToObjectTest.swift in Sources */, + 1F4BB8B71DACA0E40048464B /* ThrowAssertionTest.swift in Sources */, 1F0648D41963AAB2001F9C46 /* SynchronousTests.swift in Sources */, 347155CA1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 4793854D1BA0BB2500296F85 /* ObjCHaveCount.m in Sources */, @@ -1187,7 +1270,6 @@ 1F925F05195C18B700ED456B /* EqualTest.swift in Sources */, 1F4A566D1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */, DD72EC641A93874A002F7651 /* AllPassTest.swift in Sources */, - 7B5358C51C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */, 1F4A569D1A3B3565009E1637 /* ObjCMatchTest.m in Sources */, 1F925EE9195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */, 29EA59631B551ED2002D767E /* ThrowErrorTest.swift in Sources */, @@ -1220,6 +1302,7 @@ 1F5DF1781BDCA0F500C3A531 /* BeAnInstanceOf.swift in Sources */, 1F5DF1771BDCA0F500C3A531 /* BeAKindOf.swift in Sources */, 1F5DF17F1BDCA0F500C3A531 /* BeLessThan.swift in Sources */, + 1F4BB8A41DAC9DC90048464B /* CwlCatchBadInstructionPOSIX.swift in Sources */, 1F5DF17C1BDCA0F500C3A531 /* BeGreaterThan.swift in Sources */, 1F91DD331C74BF61002C309F /* BeVoid.swift in Sources */, 1FCF91551C61C8A400B15DCB /* PostNotification.swift in Sources */, @@ -1242,6 +1325,7 @@ 1F1871D81CA89EEF00A34BF2 /* NMBStringify.m in Sources */, 1F5DF1821BDCA0F500C3A531 /* BeNil.swift in Sources */, 1F5DF16F1BDCA0F500C3A531 /* AssertionDispatcher.swift in Sources */, + 964CFEFF1C4FF48900513336 /* ThrowAssertion.swift in Sources */, 1F5DF1841BDCA0F500C3A531 /* EndWith.swift in Sources */, 1F5DF18D1BDCA0F500C3A531 /* SourceLocation.swift in Sources */, 1F5DF1701BDCA0F500C3A531 /* DSL.swift in Sources */, @@ -1301,13 +1385,13 @@ CD79C9A51D2CC848004B6F9A /* ObjCBeginWithTest.m in Sources */, 347155CC1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 1F5DF1AA1BDCA10200C3A531 /* RaisesExceptionTest.swift in Sources */, - 8DF1C3F91C94FD0C004B2D36 /* ObjcStringersTest.m in Sources */, 1F5DF1941BDCA10200C3A531 /* UserDescriptionTest.swift in Sources */, CD79C9AF1D2CC848004B6F9A /* ObjCContainTest.m in Sources */, 1F5DF19F1BDCA10200C3A531 /* BeIdenticalToObjectTest.swift in Sources */, CD79C99E1D2CC832004B6F9A /* ObjCAsyncTest.m in Sources */, 1F91DD2F1C74BF36002C309F /* BeVoidTest.swift in Sources */, 6CAEDD0C1CAEA86F003F1584 /* LinuxSupport.swift in Sources */, + 1F4BB8B81DACAACF0048464B /* ThrowAssertionTest.swift in Sources */, CD79C9B71D2CC848004B6F9A /* ObjCSatisfyAnyOfTest.m in Sources */, 1F5DF1991BDCA10200C3A531 /* BeAnInstanceOfTest.swift in Sources */, CD79C9B11D2CC848004B6F9A /* ObjCEqualTest.m in Sources */, @@ -1350,7 +1434,9 @@ F8A1BE301CB3710900031679 /* XCTestObservationCenter+Register.m in Sources */, 1F1871DA1CA89EF100A34BF2 /* NMBObjCMatcher.swift in Sources */, 1FD8CD311968AB07008ED995 /* AdapterProtocols.swift in Sources */, + 1F2D175C1DB618F000EE9C7A /* mach_excServer.c in Sources */, 1F1871D21CA89EEE00A34BF2 /* DSL.m in Sources */, + 1F4BB8BB1DACBFD00048464B /* CwlCatchBadInstruction.m in Sources */, AE7ADE461C80BF8000B94CD3 /* MatchError.swift in Sources */, 1FC494AB1C29CBA40010975C /* NimbleEnvironment.swift in Sources */, 1FD8CD5F1968AB07008ED995 /* RaisesException.swift in Sources */, @@ -1363,6 +1449,7 @@ 1F1871D41CA89EEE00A34BF2 /* NMBStringify.m in Sources */, 1FD8CD531968AB07008ED995 /* BeNil.swift in Sources */, 1FD8CD6B1968AB07008ED995 /* Async.swift in Sources */, + 964CFEFE1C4FF48900513336 /* ThrowAssertion.swift in Sources */, 1FD8CD591968AB07008ED995 /* EndWith.swift in Sources */, 1FD8CD5D1968AB07008ED995 /* MatcherProtocols.swift in Sources */, 1FD8CD351968AB07008ED995 /* DSL.swift in Sources */, @@ -1370,6 +1457,11 @@ 1FD8CD391968AB07008ED995 /* Expression.swift in Sources */, 1FD8CD3B1968AB07008ED995 /* FailureMessage.swift in Sources */, 472FD1391B9E0A9700C7B8DA /* HaveCount.swift in Sources */, + 9630C0311C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */, + 9630C0201C6D0B2F000693EE /* CwlCatchException.swift in Sources */, + 9630C0141C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */, + 9630C01D1C6D0B2F000693EE /* CwlCatchException.m in Sources */, + 9630C02D1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1388,7 +1480,6 @@ DDB4D5F119FE442800E9D9FE /* MatchTest.swift in Sources */, 1F4A56741A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */, 1F4A56831A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */, - 8DF1C3F81C94FC75004B2D36 /* ObjcStringersTest.m in Sources */, 1F925F03195C189500ED456B /* ContainTest.swift in Sources */, 1F4A56891A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */, 1F4A568F1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */, @@ -1421,6 +1512,7 @@ 1F0648CD19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */, 1F4A56861A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */, DD9A9A9019CF43AD00706F49 /* BeIdenticalToObjectTest.swift in Sources */, + 1F4BB8B61DACA0E30048464B /* ThrowAssertionTest.swift in Sources */, 1F0648D51963AAB2001F9C46 /* SynchronousTests.swift in Sources */, 347155CB1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 4793854E1BA0BB2500296F85 /* ObjCHaveCount.m in Sources */, @@ -1429,7 +1521,6 @@ 1F925F06195C18B700ED456B /* EqualTest.swift in Sources */, 1F4A566E1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */, DD72EC651A93874A002F7651 /* AllPassTest.swift in Sources */, - 7B5358C61C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */, 1F4A569E1A3B3565009E1637 /* ObjCMatchTest.m in Sources */, 1F925EEA195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */, 29EA59641B551ED2002D767E /* ThrowErrorTest.swift in Sources */, @@ -1607,6 +1698,11 @@ "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(DEVELOPER_FRAMEWORKS_DIR)", ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1638,6 +1734,10 @@ "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(DEVELOPER_FRAMEWORKS_DIR)", ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1709,6 +1809,11 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1742,6 +1847,10 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1818,6 +1927,7 @@ FRAMEWORK_VERSION = A; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", "$(inherited)", ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; @@ -1853,6 +1963,10 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); FRAMEWORK_VERSION = A; + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; diff --git a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme index c1c4ade..2309132 100644 --- a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme +++ b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme @@ -24,8 +24,8 @@ Void in fatalError() }.to(throwAssertion()) +expect { precondition(false) }.to(throwAssertion()) + +// Passes if throwing a NSError is not equal to throwing an assertion: +expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion()) + +// Passes if the post assertion code is not run: +var reachedPoint1 = false +var reachedPoint2 = false +expect { + reachedPoint1 = true + precondition(false, "condition message") + reachedPoint2 = true +}.to(throwAssertion()) + +expect(reachedPoint1) == true +expect(reachedPoint2) == false +``` + +Notes: + +* This feature is only available in Swift. +* It is only supported for `x86_64` binaries, meaning _you cannot run this matcher on iOS devices, only simulators_. +* The tvOS simulator is supported, but using a different mechanism, requiring you to turn off the `Debug executable` scheme setting for your tvOS scheme's Test configuration. + ## Swift Error Handling If you're using Swift 2.0+, you can use the `throwError` matcher to check if an error is thrown. @@ -975,10 +1047,10 @@ expect(actual).to(satisfyAnyOf(beLessThan(@10), beGreaterThan(@20))) expect(@6).to(satisfyAnyOf(equal(@2), equal(@3), equal(@4), equal(@5), equal(@6), equal(@7))) ``` -Note: This matcher allows you to chain any number of matchers together. This provides flexibility, - but if you find yourself chaining many matchers together in one test, consider whether you - could instead refactor that single test into multiple, more precisely focused tests for - better coverage. +Note: This matcher allows you to chain any number of matchers together. This provides flexibility, + but if you find yourself chaining many matchers together in one test, consider whether you + could instead refactor that single test into multiple, more precisely focused tests for + better coverage. # Writing Your Own Matchers @@ -1189,7 +1261,7 @@ extension NMBObjCMatcher { > 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). + Documentation](https://github.com/Quick/Quick/blob/master/Documentation/en-us/InstallingQuick.md). Nimble can currently be installed in one of two ways: using CocoaPods, or with git submodules. @@ -1224,7 +1296,7 @@ source 'https://github.com/CocoaPods/Specs.git' target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do use_frameworks! - pod 'Nimble', '~> 4.0.0' + pod 'Nimble', '~> 5.0.0' end ``` diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore new file mode 100644 index 0000000..5b05d7e --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +project.xcworkspace/ +xcuserdata/ diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h new file mode 100644 index 0000000..6ec6a29 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h @@ -0,0 +1,30 @@ +// +// CwlCatchException.h +// CwlCatchException +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import + +//! Project version number for CwlCatchException. +FOUNDATION_EXPORT double CwlCatchExceptionVersionNumber; + +//! Project version string for CwlCatchException. +FOUNDATION_EXPORT const unsigned char CwlCatchExceptionVersionString[]; + +__attribute__((visibility("hidden"))) +NSException* __nullable catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)()); diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m new file mode 100644 index 0000000..4f9772c --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m @@ -0,0 +1,35 @@ +// +// CwlCatchException.m +// CwlAssertionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import "CwlCatchException.h" + +__attribute__((visibility("hidden"))) +NSException* catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)()) { + @try { + inBlock(); + } @catch (NSException *exception) { + if ([exception isKindOfClass:type]) { + return exception; + } else { + @throw; + } + } + return nil; +} diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift new file mode 100644 index 0000000..b44a232 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift @@ -0,0 +1,32 @@ +// +// CwlCatchException.swift +// CwlAssertionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +// We can't simply cast to Self? in the catchInBlock method so we need this generic function wrapper to do the conversion for us. Mildly annoying. +private func catchReturnTypeConverter(_ type: T.Type, block: () -> Void) -> T? { + return catchExceptionOfKind(type, block) as? T +} + +extension NSException { + public static func catchException(in block: () -> Void) -> Self? { + return catchReturnTypeConverter(self, block: block) + } +} diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist new file mode 100644 index 0000000..f14cf1e --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2016 Matt Gallagher. All rights reserved. + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift new file mode 100644 index 0000000..2fa67c9 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift @@ -0,0 +1,76 @@ +// +// CwlBadInstructionException.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +private func raiseBadInstructionException() { + BadInstructionException().raise() +} + +/// A simple NSException subclass. It's not required to subclass NSException (since the exception type is represented in the name) but this helps for identifying the exception through runtime type. +@objc public class BadInstructionException: NSException { + static var name: String = "com.cocoawithlove.BadInstruction" + + init() { + super.init(name: NSExceptionName(rawValue: BadInstructionException.name), reason: nil, userInfo: nil) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + /// An Objective-C callable function, invoked from the `mach_exc_server` callback function `catch_mach_exception_raise_state` to push the `raiseBadInstructionException` function onto the stack. + public class func catch_mach_exception_raise_state(_ exception_port: mach_port_t, exception: exception_type_t, code: UnsafePointer, codeCnt: mach_msg_type_number_t, flavor: UnsafeMutablePointer, old_state: UnsafePointer, old_stateCnt: mach_msg_type_number_t, new_state: thread_state_t, new_stateCnt: UnsafeMutablePointer) -> kern_return_t { + + #if arch(x86_64) + // Make sure we've been given enough memory + if old_stateCnt != x86_THREAD_STATE64_COUNT || new_stateCnt.pointee < x86_THREAD_STATE64_COUNT { + return KERN_INVALID_ARGUMENT + } + + // Read the old thread state + var state = old_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { return $0.pointee } + + // 1. Decrement the stack pointer + state.__rsp -= __uint64_t(MemoryLayout.size) + + // 2. Save the old Instruction Pointer to the stack. + if let pointer = UnsafeMutablePointer<__uint64_t>(bitPattern: UInt(state.__rsp)) { + pointer.pointee = state.__rip + } else { + return KERN_INVALID_ARGUMENT + } + + // 3. Set the Instruction Pointer to the new function's address + var f: @convention(c) () -> Void = raiseBadInstructionException + withUnsafePointer(to: &f) { + state.__rip = $0.withMemoryRebound(to: __uint64_t.self, capacity: 1) { return $0.pointee } + } + + // Write the new thread state + new_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { $0.pointee = state } + new_stateCnt.pointee = x86_THREAD_STATE64_COUNT + + return KERN_SUCCESS + #else + fatalError("Unavailable for this CPU architecture") + #endif + } +} diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h new file mode 100644 index 0000000..0333ed2 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h @@ -0,0 +1,61 @@ +// +// CwlCatchBadInstruction.h +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if defined(__x86_64__) + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +// The request_mach_exception_raise_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. +typedef struct +{ + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; +} request_mach_exception_raise_t; + +// The reply_mach_exception_raise_state_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. +typedef struct +{ + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; +} reply_mach_exception_raise_state_t; + +extern boolean_t mach_exc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +NS_ASSUME_NONNULL_END + +#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m new file mode 100644 index 0000000..22c1377 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m @@ -0,0 +1,50 @@ +// +// CwlCatchBadInstruction.m +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if defined(__x86_64__) + +#import "CwlCatchBadInstruction.h" + +// Assuming the "PRODUCT_NAME" macro is defined, this will create the name of the Swift generated header file +#define STRINGIZE_NO_EXPANSION(A) #A +#define STRINGIZE_WITH_EXPANSION(A) STRINGIZE_NO_EXPANSION(A) +#define SWIFT_INCLUDE STRINGIZE_WITH_EXPANSION(PRODUCT_NAME-Swift.h) + +// Include the Swift generated header file +#import SWIFT_INCLUDE + +/// A basic function that receives callbacks from mach_exc_server and relays them to the Swift implemented BadInstructionException.catch_mach_exception_raise_state. +kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, const thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { + return [BadInstructionException catch_mach_exception_raise_state:exception_port exception:exception code:code codeCnt:codeCnt flavor:flavor old_state:old_state old_stateCnt:old_stateCnt new_state:new_state new_stateCnt:new_stateCnt]; +} + +// The mach port should be configured so that this function is never used. +kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) { + assert(false); + return KERN_FAILURE; +} + +// The mach port should be configured so that this function is never used. +kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { + assert(false); + return KERN_FAILURE; +} + +#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift new file mode 100644 index 0000000..ab460b3 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift @@ -0,0 +1,194 @@ +// +// CwlCatchBadInstruction.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +#if arch(x86_64) + + private enum PthreadError: Error { case code(Int32) } + private enum MachExcServer: Error { case code(kern_return_t) } + + /// A quick function for converting Mach error results into Swift errors + private func kernCheck(_ f: () -> Int32) throws { + let r = f() + guard r == KERN_SUCCESS else { + throw NSError(domain: NSMachErrorDomain, code: Int(r), userInfo: nil) + } + } + + extension execTypesCountTuple { + mutating func pointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: T.self, capacity: EXC_TYPES_COUNT) { ptr -> R in + return block(ptr) + } + } + } + } + + extension request_mach_exception_raise_t { + mutating func withMsgHeaderPointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: mach_msg_header_t.self, capacity: 1) { ptr -> R in + return block(ptr) + } + } + } + } + + extension reply_mach_exception_raise_state_t { + mutating func withMsgHeaderPointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: mach_msg_header_t.self, capacity: 1) { ptr -> R in + return block(ptr) + } + } + } + } + + /// A structure used to store context associated with the Mach message port + private struct MachContext { + var masks = execTypesCountTuple() + var count: mach_msg_type_number_t = 0 + var ports = execTypesCountTuple() + var behaviors = execTypesCountTuple() + var flavors = execTypesCountTuple() + var currentExceptionPort: mach_port_t = 0 + var handlerThread: pthread_t? = nil + + mutating func withUnsafeMutablePointers(in block: (UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer) -> R) -> R { + return masks.pointer { masksPtr in + return ports.pointer { portsPtr in + return behaviors.pointer { behaviorsPtr in + return flavors.pointer { flavorsPtr in + return block(masksPtr, portsPtr, behaviorsPtr, flavorsPtr) + } + } + } + } + } + } + + /// A function for receiving mach messages and parsing the first with mach_exc_server (and if any others are received, throwing them away). + private func machMessageHandler(_ arg: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { + let context = arg.assumingMemoryBound(to: MachContext.self).pointee + var request = request_mach_exception_raise_t() + var reply = reply_mach_exception_raise_state_t() + + var handledfirstException = false + repeat { do { + // Request the next mach message from the port + request.Head.msgh_local_port = context.currentExceptionPort + request.Head.msgh_size = UInt32(MemoryLayout.size) + try kernCheck { request.withMsgHeaderPointer { requestPtr in + mach_msg(requestPtr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0, request.Head.msgh_size, context.currentExceptionPort, 0, UInt32(MACH_PORT_NULL)) + } } + + // Prepare the reply structure + reply.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request.Head.msgh_bits), 0) + reply.Head.msgh_local_port = UInt32(MACH_PORT_NULL) + reply.Head.msgh_remote_port = request.Head.msgh_remote_port + reply.Head.msgh_size = UInt32(MemoryLayout.size) + reply.NDR = NDR_record + + if !handledfirstException { + // Use the MiG generated server to invoke our handler for the request and fill in the rest of the reply structure + guard request.withMsgHeaderPointer(in: { requestPtr in reply.withMsgHeaderPointer { replyPtr in + mach_exc_server(requestPtr, replyPtr) + } }) != 0 else { throw MachExcServer.code(reply.RetCode) } + + handledfirstException = true + } else { + // If multiple fatal errors occur, don't handle subsquent errors (let the program crash) + reply.RetCode = KERN_FAILURE + } + + // Send the reply + try kernCheck { reply.withMsgHeaderPointer { replyPtr in + mach_msg(replyPtr, MACH_SEND_MSG, reply.Head.msgh_size, 0, UInt32(MACH_PORT_NULL), 0, UInt32(MACH_PORT_NULL)) + } } + } catch let error as NSError where (error.domain == NSMachErrorDomain && (error.code == Int(MACH_RCV_PORT_CHANGED) || error.code == Int(MACH_RCV_INVALID_NAME))) { + // Port was already closed before we started or closed while we were listening. + // This means the controlling thread shut down. + return nil + } catch { + // Should never be reached but this is testing code, don't try to recover, just abort + fatalError("Mach message error: \(error)") + } } while true + } + + /// Run the provided block. If a mach "BAD_INSTRUCTION" exception is raised, catch it and return a BadInstructionException (which captures stack information about the throw site, if desired). Otherwise return nil. + /// NOTE: This function is only intended for use in test harnesses – use in a distributed build is almost certainly a bad choice. If a "BAD_INSTRUCTION" exception is raised, the block will be exited before completion via Objective-C exception. The risks associated with an Objective-C exception apply here: most Swift/Objective-C functions are *not* exception-safe. Memory may be leaked and the program will not necessarily be left in a safe state. + /// - parameter block: a function without parameters that will be run + /// - returns: if an EXC_BAD_INSTRUCTION is raised during the execution of `block` then a BadInstructionException will be returned, otherwise `nil`. + public func catchBadInstruction(in block: () -> Void) -> BadInstructionException? { + var context = MachContext() + var result: BadInstructionException? = nil + do { + var handlerThread: pthread_t? = nil + defer { + // 8. Wait for the thread to terminate *if* we actually made it to the creation point + // The mach port should be destroyed *before* calling pthread_join to avoid a deadlock. + if handlerThread != nil { + pthread_join(handlerThread!, nil) + } + } + + try kernCheck { + // 1. Create the mach port + mach_port_allocate(mach_task_self_, MACH_PORT_RIGHT_RECEIVE, &context.currentExceptionPort) + } + defer { + // 7. Cleanup the mach port + mach_port_destroy(mach_task_self_, context.currentExceptionPort) + } + + try kernCheck { + // 2. Configure the mach port + mach_port_insert_right(mach_task_self_, context.currentExceptionPort, context.currentExceptionPort, MACH_MSG_TYPE_MAKE_SEND) + } + + try kernCheck { context.withUnsafeMutablePointers { masksPtr, portsPtr, behaviorsPtr, flavorsPtr in + // 3. Apply the mach port as the handler for this thread + thread_swap_exception_ports(mach_thread_self(), EXC_MASK_BAD_INSTRUCTION, context.currentExceptionPort, Int32(bitPattern: UInt32(EXCEPTION_STATE) | MACH_EXCEPTION_CODES), x86_THREAD_STATE64, masksPtr, &context.count, portsPtr, behaviorsPtr, flavorsPtr) + } } + + defer { context.withUnsafeMutablePointers { masksPtr, portsPtr, behaviorsPtr, flavorsPtr in + // 6. Unapply the mach port + _ = thread_swap_exception_ports(mach_thread_self(), EXC_MASK_BAD_INSTRUCTION, 0, EXCEPTION_DEFAULT, THREAD_STATE_NONE, masksPtr, &context.count, portsPtr, behaviorsPtr, flavorsPtr) + } } + + try withUnsafeMutablePointer(to: &context) { c throws in + // 4. Create the thread + let e = pthread_create(&handlerThread, nil, machMessageHandler, c) + guard e == 0 else { throw PthreadError.code(e) } + + // 5. Run the block + result = BadInstructionException.catchException(in: block) + } + } catch { + // Should never be reached but this is testing code, don't try to recover, just abort + fatalError("Mach port error: \(error)") + } + return result + } + +#endif + diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift new file mode 100644 index 0000000..b3afb12 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift @@ -0,0 +1,100 @@ +// +// CwlCatchBadInstructionPOSIX.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 8/02/2016. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +#if arch(x86_64) + +// This file is an alternative implementation to CwlCatchBadInstruction.swift that uses a SIGILL signal action and setenv/longjmp instead of a Mach exception handler and Objective-C exception raising. +// +// WARNING: +// This code is quick and dirty. It's a proof of concept for using a SIGILL handler and setjmp/longjmp where Mach exceptions and the Obj-C runtime aren't available. I ran the automated tests when I first wrote this code but I don't personally use it at all so by the time you're reading this comment, it probably broke and I didn't notice. +// Obvious limitations: +// * It doesn't work when debugging with lldb. +// * It doesn't scope correctly to the thread (it's global) +// * In violation of rules for signal handlers, it writes to the "red zone" on the stack +// * It isn't re-entrant +// * Plus all of the same caveats as the Mach exceptions version (doesn't play well with other handlers, probably leaks ARC memory, etc) +// Treat it like a loaded shotgun. Don't point it at your face. + +private var env = jmp_buf(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0) + +private func triggerLongJmp() { + longjmp(&env.0, 1) +} + +private func sigIllHandler(code: Int32, info: UnsafeMutablePointer<__siginfo>?, uap: UnsafeMutableRawPointer?) -> Void { + guard let context = uap?.assumingMemoryBound(to: ucontext64_t.self) else { return } + + // 1. Decrement the stack pointer + context.pointee.uc_mcontext64.pointee.__ss.__rsp -= __uint64_t(MemoryLayout.size) + + // 2. Save the old Instruction Pointer to the stack. + let rsp = context.pointee.uc_mcontext64.pointee.__ss.__rsp + if let ump = UnsafeMutablePointer<__uint64_t>(bitPattern: UInt(rsp)) { + ump.pointee = rsp + } + + // 3. Set the Instruction Pointer to the new function's address + var f: @convention(c) () -> Void = triggerLongJmp + withUnsafePointer(to: &f) { $0.withMemoryRebound(to: __uint64_t.self, capacity: 1) { ptr in + context.pointee.uc_mcontext64.pointee.__ss.__rip = ptr.pointee + } } +} + +/// Without Mach exceptions or the Objective-C runtime, there's nothing to put in the exception object. It's really just a boolean – either a SIGILL was caught or not. +public class BadInstructionException { +} + +/// Run the provided block. If a POSIX SIGILL is received, handle it and return a BadInstructionException (which is just an empty object in this POSIX signal version). Otherwise return nil. +/// NOTE: This function is only intended for use in test harnesses – use in a distributed build is almost certainly a bad choice. If a SIGILL is received, the block will be interrupted using a C `longjmp`. The risks associated with abrupt jumps apply here: most Swift functions are *not* interrupt-safe. Memory may be leaked and the program will not necessarily be left in a safe state. +/// - parameter block: a function without parameters that will be run +/// - returns: if an SIGILL is raised during the execution of `block` then a BadInstructionException will be returned, otherwise `nil`. +public func catchBadInstruction( block: () -> Void) -> BadInstructionException? { + // Construct the signal action + var sigActionPrev = sigaction() + let action = __sigaction_u(__sa_sigaction: sigIllHandler) + var sigActionNew = sigaction(__sigaction_u: action, sa_mask: sigset_t(), sa_flags: SA_SIGINFO) + + // Install the signal action + if sigaction(SIGILL, &sigActionNew, &sigActionPrev) != 0 { + fatalError("Sigaction error: \(errno)") + } + + defer { + // Restore the previous signal action + if sigaction(SIGILL, &sigActionPrev, nil) != 0 { + fatalError("Sigaction error: \(errno)") + } + } + + // Prepare the jump point + if setjmp(&env.0) != 0 { + // Handle jump received + return BadInstructionException() + } + + // Run the block + block() + + return nil +} + +#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift new file mode 100644 index 0000000..12a6b9f --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift @@ -0,0 +1,63 @@ +// +// CwlDarwinDefinitions.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Darwin + +#if arch(x86_64) + +// From /usr/include/mach/port.h +// #define MACH_PORT_RIGHT_RECEIVE ((mach_port_right_t) 1) +let MACH_PORT_RIGHT_RECEIVE: mach_port_right_t = 1 + +// From /usr/include/mach/message.h +// #define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */ +// #define MACH_MSGH_BITS_REMOTE(bits) \ +// ((bits) & MACH_MSGH_BITS_REMOTE_MASK) +// #define MACH_MSGH_BITS(remote, local) /* legacy */ \ +// ((remote) | ((local) << 8)) +let MACH_MSG_TYPE_MAKE_SEND: UInt32 = 20 +func MACH_MSGH_BITS_REMOTE(_ bits: UInt32) -> UInt32 { return bits & UInt32(MACH_MSGH_BITS_REMOTE_MASK) } +func MACH_MSGH_BITS(_ remote: UInt32, _ local: UInt32) -> UInt32 { return ((remote) | ((local) << 8)) } + +// From /usr/include/mach/exception_types.h +// #define EXC_BAD_INSTRUCTION 2 /* Instruction failed */ +// #define EXC_MASK_BAD_INSTRUCTION (1 << EXC_BAD_INSTRUCTION) +// #define EXCEPTION_DEFAULT 1 +let EXC_BAD_INSTRUCTION: UInt32 = 2 +let EXC_MASK_BAD_INSTRUCTION: UInt32 = 1 << EXC_BAD_INSTRUCTION +let EXCEPTION_DEFAULT: Int32 = 1 + +// From /usr/include/mach/i386/thread_status.h +// #define THREAD_STATE_NONE 13 +// #define x86_THREAD_STATE64_COUNT ((mach_msg_type_number_t) \ +// ( sizeof (x86_thread_state64_t) / sizeof (int) )) +let THREAD_STATE_NONE: Int32 = 13 +let x86_THREAD_STATE64_COUNT = UInt32(MemoryLayout.size / MemoryLayout.size) + +let EXC_TYPES_COUNT = 14 +struct execTypesCountTuple { + // From /usr/include/mach/i386/exception.h + // #define EXC_TYPES_COUNT 14 /* incl. illegal exception 0 */ + var value: (T,T,T,T,T,T,T,T,T,T,T,T,T,T) = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + init() { + } +} + +#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist new file mode 100644 index 0000000..f14cf1e --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2016 Matt Gallagher. All rights reserved. + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c new file mode 100644 index 0000000..2334538 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c @@ -0,0 +1,537 @@ +/* + * IDENTIFICATION: + * stub generated Mon Jan 11 00:24:26 2016 + * with a MiG generated by bootstrap_cmds-93 + * OPTIONS: + */ + +/* Module mach_exc */ + +#if defined(__x86_64__) + +#define __MIG_check__Request__mach_exc_subsystem__ 1 + +#include "mach_excServer.h" + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __DeclareRcvRpc +#define __DeclareRcvRpc(_NUM_, _NAME_) +#endif /* __DeclareRcvRpc */ + +#ifndef __BeforeRcvRpc +#define __BeforeRcvRpc(_NUM_, _NAME_) +#endif /* __BeforeRcvRpc */ + +#ifndef __AfterRcvRpc +#define __AfterRcvRpc(_NUM_, _NAME_) +#endif /* __AfterRcvRpc */ + +#ifndef __DeclareRcvSimple +#define __DeclareRcvSimple(_NUM_, _NAME_) +#endif /* __DeclareRcvSimple */ + +#ifndef __BeforeRcvSimple +#define __BeforeRcvSimple(_NUM_, _NAME_) +#endif /* __BeforeRcvSimple */ + +#ifndef __AfterRcvSimple +#define __AfterRcvSimple(_NUM_, _NAME_) +#endif /* __AfterRcvSimple */ + +#define novalue void + +#define msgh_request_port msgh_local_port +#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) +#define msgh_reply_port msgh_remote_port +#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) + +#define MIG_RETURN_ERROR(X, code) {\ + ((mig_reply_error_t *)X)->RetCode = code;\ + ((mig_reply_error_t *)X)->NDR = NDR_record;\ + return;\ + } + +/* Forward Declarations */ + + +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_t__defined) +#define __MIG_check__Request__mach_exception_raise_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) +{ + + typedef __Request__mach_exception_raise_t __Request; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 16)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 16)) / 8 < In0P->codeCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 16) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise */ +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_t __Request; + typedef __Reply__mach_exception_raise_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_t__defined */ + + __DeclareRcvRpc(2405, "mach_exception_raise") + __BeforeRcvRpc(2405, "mach_exception_raise") + +#if defined(__MIG_check__Request__mach_exception_raise_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_t((__Request *)In0P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ + + OutP->RetCode = catch_mach_exception_raise(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); + + OutP->NDR = NDR_record; + + + __AfterRcvRpc(2405, "mach_exception_raise") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state */ +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_t __Request; + typedef __Reply__mach_exception_raise_state_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ + + __DeclareRcvRpc(2406, "mach_exception_raise_state") + __BeforeRcvRpc(2406, "mach_exception_raise_state") + +#if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2406, "mach_exception_raise_state") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_identity_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_identity_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state_identity */ +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_identity_t __Request; + typedef __Reply__mach_exception_raise_state_identity_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ + + __DeclareRcvRpc(2407, "mach_exception_raise_state_identity") + __BeforeRcvRpc(2407, "mach_exception_raise_state_identity") + +#if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_identity_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state_identity(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2407, "mach_exception_raise_state_identity") +} + + + +/* Description of this subsystem, for use in direct RPC */ +const struct catch_mach_exc_subsystem catch_mach_exc_subsystem = { + mach_exc_server_routine, + 2405, + 2408, + (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), + (vm_address_t)0, + { + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state_identity, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, + } +}; + +mig_external boolean_t mach_exc_server + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + register mig_routine_t routine; + + OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); + OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; + /* Minimal size: routine() will update it if different */ + OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); + OutHeadP->msgh_local_port = MACH_PORT_NULL; + OutHeadP->msgh_id = InHeadP->msgh_id + 100; + + if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || + ((routine = catch_mach_exc_subsystem.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) { + ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; + ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; + return FALSE; + } + (*routine) (InHeadP, OutHeadP); + return TRUE; +} + +mig_external mig_routine_t mach_exc_server_routine + (mach_msg_header_t *InHeadP) +{ + register int msgh_id; + + msgh_id = InHeadP->msgh_id - 2405; + + if ((msgh_id > 2) || (msgh_id < 0)) + return 0; + + return catch_mach_exc_subsystem.routine[msgh_id].stub_routine; +} + +#endif + diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h new file mode 100644 index 0000000..766ba11 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h @@ -0,0 +1,298 @@ +#ifndef _mach_exc_server_ +#define _mach_exc_server_ + +/* Module mach_exc */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN VOUCHER CODE */ + +#ifndef KERNEL +#if defined(__has_include) +#if __has_include() +#ifndef USING_VOUCHERS +#define USING_VOUCHERS +#endif +#ifndef __VOUCHER_FORWARD_TYPE_DECLS__ +#define __VOUCHER_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif // __VOUCHER_FORWARD_TYPE_DECLS__ +#endif // __has_include() +#endif // __has_include +#endif // !KERNEL + +/* END VOUCHER CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_exc_MSG_COUNT +#define mach_exc_MSG_COUNT 3 +#endif /* mach_exc_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigServerHeader +__BeforeMigServerHeader +#endif /* __BeforeMigServerHeader */ + + +/* Routine mach_exception_raise */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine mach_exception_raise_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state_identity */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state_identity +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +boolean_t mach_exc_server( + mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +mig_routine_t mach_exc_server_routine( + mach_msg_header_t *InHeadP); + + +/* Description of this subsystem, for use in direct RPC */ +extern const struct catch_mach_exc_subsystem { + mig_server_routine_t server; /* Server routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + unsigned int maxsize; /* Max msg size */ + vm_address_t reserved; /* Reserved */ + struct routine_descriptor /*Array of routine descriptors */ + routine[3]; +} catch_mach_exc_subsystem; + +/* typedefs for all requests */ + +#ifndef __Request__mach_exc_subsystem__defined +#define __Request__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } __Request__mach_exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_exc_subsystem__defined */ + + +/* union of all requests */ + +#ifndef __RequestUnion__catch_mach_exc_subsystem__defined +#define __RequestUnion__catch_mach_exc_subsystem__defined +union __RequestUnion__catch_mach_exc_subsystem { + __Request__mach_exception_raise_t Request_mach_exception_raise; + __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; + __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_exc_subsystem__defined +#define __Reply__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_exc_subsystem__defined */ + + +/* union of all replies */ + +#ifndef __ReplyUnion__catch_mach_exc_subsystem__defined +#define __ReplyUnion__catch_mach_exc_subsystem__defined +union __ReplyUnion__catch_mach_exc_subsystem { + __Reply__mach_exception_raise_t Reply_mach_exception_raise; + __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; + __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_exc +#define subsystem_to_name_map_mach_exc \ + { "mach_exception_raise", 2405 },\ + { "mach_exception_raise_state", 2406 },\ + { "mach_exception_raise_state_identity", 2407 } +#endif + +#ifdef __AfterMigServerHeader +__AfterMigServerHeader +#endif /* __AfterMigServerHeader */ + +#endif /* _mach_exc_server_ */ diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/README.md b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/README.md new file mode 100644 index 0000000..a1a9a70 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/README.md @@ -0,0 +1,80 @@ +# CwlPreconditionTesting + +A Mach exception handler, written in Swift and Objective-C, that allows `EXC_BAD_INSTRUCTION` (as raised by Swift's `assertionFailure`/`preconditionFailure`/`fatalError`) to be caught and tested. + +For an extended discussion of this code, please see the Cocoa with Love article: + +[Partial functions in Swift, Part 2: Catching precondition failures](http://cocoawithlove.com/blog/2016/02/02/partial-functions-part-two-catching-precondition-failures.html) + +## Usage + +The short version is: + +1. `git clone https://github.com/mattgallagher/CwlPreconditionTesting.git` +2. drag the "CwlPreconditionTesting.xcodeproj" file into your project's file tree in Xcode +3. go to your testing target's Build Phase settings and under "Target Dependencies" press the "+" button and select the relevant "CwlPreconditionTesting" target ("_iOS" or "_OSX", depending on your testing target's SDK) +4. write `import CwlPreconditionTesting` at the top of any test file where you want to use `catchBadInstruction` (Swift should handle the linkage automatically when you do this) +5. use the `catchBadInstruction` function as shown in the [CwlCatchBadInstructionTests.swift tests file](https://github.com/mattgallagher/CwlPreconditionTesting/blob/master/CwlPreconditionTestingTests/CwlCatchBadInstructionTests.swift?ts=4) + +### Project details + +The "CwlPreconditionTesting.xcodeproj" contains two targets: + +* CwlPreconditionTesting_OSX +* CwlPreconditionTesting_iOS + +both build a framework named "CwlPreconditionTesting.framework". If you're linking manually, be certain to select the "CwlPreconditionTesting.framework" from the appropriate target. + +Remember: the iOS build is useful only in the simulator. All Mach exception handling code will be conditionally excluded in any device build. + +### Static inclusion + +Due to the complications associated with needing to call into and out of Objective-C, static inclusion in other projects is not a single file nor a quick drag and drop. There's at least 7 files and you'll need to add some project settings. + +All of the following files: + +* CwlCatchBadInstruction.swift +* CwlCatchBadInstruction.h +* CwlCatchBadInstruction.m +* CwlCatchException.swift +* CwlCatchException.h +* CwlCatchException.m + +and either: + +* $(SDKROOT)/usr/include/mach/mach_exc.defs +* mach_excServer.c + +need to be added to the testing target for OS X projects or iOS projects, respectively. + +Your target will also need to have the following macros defined in the "Apple LLVM - Preprocessing" → "Preprocessor Macros" build setting: + + PRODUCT_NAME=$(PRODUCT_NAME) + +This lets the Objective-C file generate the include directive for the autogenerated Swift header so it can call back into Swift during the Mach exception handler callbacks. This macro should stay in sync if you change the target name but if you do anything else in your project that changes the name of the autogenerated Swift header independent of the target name (or you want to add spaces or other command-line complications to the target name), you'll want to update "CwlCatchBadInstruction.m" directly with the correct include directive. + +Additionally, you'll need a standard Objective-C "Bridging header" for your testing target and it will need to include the following import statements: + +``` +#if defined(__x86_64__) +#import +#endif + +#import +``` + +### Using POSIX signals and setjmp/longjmp + +For comparison or for anyone running this code on a platform without Mach exceptions or the Objective-C runtime, I've added a proof-of-concept implementation of `catchBadInstruction` that uses a POSIX SIGILL `sigaction` and `setjmp`/`longjmp` to perform the throw. + +In Xcode, you can simply select the CwlPreconditionTesting_POSIX target (instead of the OSX or iOS targets). If you're building without Xcode: all you need is the CwlCatchBadInstructionPOSIX.swift file (compared to the Mach exception handler, the code is tiny doesn't have any weird Objective-C/MiG file dependencies). + +**Warning No. 1**: on OS X, this approach can't be used when lldb is attached since lldb's Mach exception handler blocks the SIGILL from ever occurring (I've disabled the "Debug Executable" setting for the tests in Xcode - re-enable it to witness the problem). + +**Warning No. 2**: if you're switching between the CwlPreconditionTesting_OSX and CwlPreconditionTesting_POSIX targets, Xcode (as of Xcode 7.2.1) will not detect the change and will not remove the old framework correctly so you'll need to *clean your project* otherwise the old framework will hang around. + +Additional problems in decreasing severity include: + +* the signal handler is whole process (rather than correctly scoped to the thread where the "catch" occurs) +* the signal handler doesn't deal with re-entrancy whereas the mach exception handler remains deterministic in the face of multiple fatal errors +* the signal handler overwrites the "[red zone](https://en.wikipedia.org/wiki/Red_zone_(computing))" which is technically frowned upon in signal handlers (although unlikely to cause problems here) diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift index 5434aaf..a55cb27 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift @@ -1,3 +1,4 @@ +import Dispatch import Foundation /// "Global" state of Nimble is stored here. Only DSL functions should access / be aware of this @@ -25,7 +26,7 @@ internal class NimbleEnvironment { set { NimbleAssertionHandler = newValue } } -#if _runtime(_ObjC) + var suppressTVOSAssertionWarning: Bool = false var awaiter: Awaiter init() { @@ -41,5 +42,4 @@ internal class NimbleEnvironment { asyncQueue: .main, timeoutQueue: timeoutQueue) } -#endif } diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/DSL+Wait.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/DSL+Wait.swift index fa5a10f..619b6dc 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/DSL+Wait.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/DSL+Wait.swift @@ -1,6 +1,6 @@ +import Dispatch import Foundation -#if _runtime(_ObjC) private enum ErrorResult { case exception(NSException) case error(Error) @@ -70,10 +70,16 @@ internal class NMBWait: NSObject { } } + #if _runtime(_ObjC) @objc(untilFile:line:action:) internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) -> Void { until(timeout: 1, file: file, line: line, action: action) } + #else + internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) -> Void { + until(timeout: 1, file: file, line: line, action: action) + } + #endif } internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: TimeInterval) -> String { @@ -90,4 +96,3 @@ internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: TimeInterv public func waitUntil(timeout: TimeInterval = 1, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) -> Void { NMBWait.until(timeout: timeout, file: file, line: line, action: action) } -#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift index c028f5a..6b89c76 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift @@ -1,7 +1,7 @@ import Foundation -#if _runtime(_ObjC) - +/// If you are running on a slower machine, it could be useful to increase the default timeout value +/// or slow down poll interval. Default timeout interval is 1, and poll interval is 0.01. public struct AsyncDefaults { public static var Timeout: TimeInterval = 1 public static var PollInterval: TimeInterval = 0.01 @@ -144,5 +144,3 @@ extension Expectation { return toEventuallyNot(matcher, timeout: timeout, pollInterval: pollInterval, description: description) } } - -#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLessThan.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLessThan.swift index 4cd1a05..fbcd7c7 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLessThan.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLessThan.swift @@ -33,7 +33,7 @@ public func <(lhs: Expectation, rhs: NMBComparable?) { extension NMBObjCMatcher { public class func beLessThanMatcher(_ expected: NMBComparable?) -> NMBObjCMatcher { return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in - let expr = actualExpression.cast { $0 as! NMBComparable? } + let expr = actualExpression.cast { $0 as? NMBComparable } return try! beLessThan(expected).matches(expr, failureMessage: failureMessage) } } diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLogical.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLogical.swift index ee62928..49272a3 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLogical.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLogical.swift @@ -144,28 +144,28 @@ public func beFalsy() -> MatcherFunc extension NMBObjCMatcher { public class func beTruthyMatcher() -> NMBObjCMatcher { return NMBObjCMatcher { actualExpression, failureMessage in - let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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 Bool? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } return try! beFalse().matches(expr, failureMessage: failureMessage) } } diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/Match.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/Match.swift index c225f88..3ad5fb5 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/Match.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/Match.swift @@ -1,7 +1,5 @@ import Foundation -#if _runtime(_ObjC) - /// A Nimble matcher that succeeds when the actual string satisfies the regular expression /// described by the expected string. public func match(_ expectedValue: String?) -> NonNilMatcherFunc { @@ -18,6 +16,8 @@ public func match(_ expectedValue: String?) -> NonNilMatcherFunc { } } +#if _runtime(_ObjC) + extension NMBObjCMatcher { public class func matchMatcher(_ expected: NSString) -> NMBMatcher { return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift new file mode 100644 index 0000000..67f9cf6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift @@ -0,0 +1,55 @@ +import Foundation + +public func throwAssertion() -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + #if arch(x86_64) && _runtime(_ObjC) && !SWIFT_PACKAGE + failureMessage.postfixMessage = "throw an assertion" + failureMessage.actualValue = nil + + var succeeded = true + + let caughtException: BadInstructionException? = catchBadInstruction { + #if os(tvOS) + if (!NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning) { + print() + print("[Nimble Warning]: If you're getting stuck on a debugger breakpoint for a " + + "fatal error while using throwAssertion(), please disable 'Debug Executable' " + + "in your scheme. Go to 'Edit Scheme > Test > Info' and uncheck " + + "'Debug Executable'. If you've already done that, suppress this warning " + + "by setting `NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true`. " + + "This is required because the standard methods of catching assertions " + + "(mach APIs) are unavailable for tvOS. Instead, the same mechanism the " + + "debugger uses is the fallback method for tvOS." + ) + print() + NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true + } + #endif + do { + try actualExpression.evaluate() + } catch let error { + succeeded = false + failureMessage.postfixMessage += "; threw error instead <\(error)>" + } + } + + if !succeeded { + return false + } + + if caughtException == nil { + return false + } + + return true + #elseif SWIFT_PACKAGE + fatalError("The throwAssertion Nimble matcher does not currently support Swift CLI." + + " You can silence this error by placing the test case inside an #if !SWIFT_PACKAGE" + + " conditional statement") + #else + fatalError("The throwAssertion Nimble matcher can only run on x86_64 platforms with " + + "Objective-C (e.g. Mac, iPhone 5s or later simulators). You can silence this error " + + "by placing the test case inside an #if arch(x86_64) or _runtime(_ObjC) conditional statement") + #endif + } +} diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Nimble.h b/Carthage/Checkouts/Nimble/Sources/Nimble/Nimble.h index 1eab61a..7885a53 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Nimble.h +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Nimble.h @@ -3,5 +3,12 @@ #import "NMBStringify.h" #import "DSL.h" +#import "CwlCatchException.h" +#import "CwlCatchBadInstruction.h" + +#if TARGET_OS_IPHONE && !TARGET_OS_TV + #import "mach_excServer.h" +#endif + FOUNDATION_EXPORT double NimbleVersionNumber; FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Async.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Async.swift index a78a147..c902692 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Async.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Async.swift @@ -1,10 +1,13 @@ +import CoreFoundation +import Dispatch import Foundation -#if _runtime(_ObjC) -import Dispatch +#if !_runtime(_ObjC) + import CDispatch +#endif -private let timeoutLeeway = DispatchTimeInterval.nanoseconds(Int(NSEC_PER_MSEC)) -private let pollLeeway = DispatchTimeInterval.nanoseconds(Int(NSEC_PER_MSEC)) +private let timeoutLeeway = DispatchTimeInterval.milliseconds(1) +private let pollLeeway = DispatchTimeInterval.milliseconds(1) /// Stores debugging information about callers internal struct WaitingInfo: CustomStringConvertible { @@ -29,8 +32,13 @@ internal class AssertionWaitLock: WaitLock { func acquireWaitingLock(_ fnName: String, file: FileString, line: UInt) { let info = WaitingInfo(name: fnName, file: file, lineNumber: line) + #if _runtime(_ObjC) + let isMainThread = Thread.isMainThread + #else + let isMainThread = _CFIsMainThread() + #endif nimblePrecondition( - Thread.isMainThread, + isMainThread, "InvalidNimbleAPIUsage", "\(fnName) can only run on the main thread." ) @@ -177,7 +185,12 @@ internal class AwaitPromiseBuilder { let semTimedOutOrBlocked = DispatchSemaphore(value: 0) semTimedOutOrBlocked.signal() let runLoop = CFRunLoopGetMain() - CFRunLoopPerformBlock(runLoop, CFRunLoopMode.defaultMode.rawValue) { + #if _runtime(_ObjC) + let runLoopMode = CFRunLoopMode.defaultMode.rawValue + #else + let runLoopMode = kCFRunLoopDefaultMode + #endif + CFRunLoopPerformBlock(runLoop, runLoopMode) { if semTimedOutOrBlocked.wait(timeout: .now()) == .success { timedOutSem.signal() semTimedOutOrBlocked.signal() @@ -237,7 +250,7 @@ internal class AwaitPromiseBuilder { self.trigger.timeoutSource.resume() while self.promise.asyncResult.isIncomplete() { // Stopping the run loop does not work unless we run only 1 mode - RunLoop.current.run(mode: .defaultRunLoopMode, before: .distantFuture) + _ = RunLoop.current.run(mode: .defaultRunLoopMode, before: .distantFuture) } self.trigger.timeoutSource.suspend() self.trigger.timeoutSource.cancel() @@ -346,5 +359,3 @@ internal func pollBlock( return result } - -#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Errors.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Errors.swift index 54bed92..d424c98 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Errors.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Errors.swift @@ -77,14 +77,21 @@ internal func errorMatchesNonNilFieldsOrClosure( matches = false } } - } else if errorType != nil && closure != nil { + } else if errorType != nil { + matches = (actualError is T) // The closure expects another ErrorProtocol as argument, so this // is _supposed_ to fail, so that it becomes more obvious. - let assertions = gatherExpectations { - expect(actualError is T).to(equal(true)) + if let closure = closure { + let assertions = gatherExpectations { + if let actual = actualError as? T { + closure(actual) + } + } + let messages = assertions.map { $0.message } + if messages.count > 0 { + matches = false + } } - precondition(assertions.map { $0.message }.count > 0) - matches = false } } diff --git a/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.h b/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.h index a499059..54677ee 100644 --- a/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.h +++ b/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.h @@ -6,48 +6,222 @@ @protocol NMBMatcher; +NS_ASSUME_NONNULL_BEGIN + + +#define NIMBLE_OVERLOADABLE __attribute__((overloadable)) #define NIMBLE_EXPORT FOUNDATION_EXPORT +#define NIMBLE_EXPORT_INLINE FOUNDATION_STATIC_INLINE + +#define NIMBLE_VALUE_OF(VAL) ({ \ + __typeof__((VAL)) val = (VAL); \ + [NSValue valueWithBytes:&val objCType:@encode(__typeof__((VAL)))]; \ +}) #ifdef NIMBLE_DISABLE_SHORT_SYNTAX #define NIMBLE_SHORT(PROTO, ORIGINAL) +#define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) #else #define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); } +#define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE NIMBLE_OVERLOADABLE PROTO { return (ORIGINAL); } #endif -NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line); + + +#define DEFINE_NMB_EXPECT_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBExpectation *NMB_expect(TYPE(^actualBlock)(), NSString *file, NSUInteger line) { \ + return NMB_expect(^id { return EXPR; }, file, line); \ + } + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line); + + // overloaded dispatch for nils - expect(nil) + DEFINE_NMB_EXPECT_OVERLOAD(void*, nil) + DEFINE_NMB_EXPECT_OVERLOAD(NSRange, NIMBLE_VALUE_OF(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(int, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned int, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(float, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(double, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(long long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned long long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(char, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned char, @(actualBlock())) + // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow + // the compiler to dispatch to bool. + DEFINE_NMB_EXPECT_OVERLOAD(BOOL, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(char *, @(actualBlock())) + + +#undef DEFINE_NMB_EXPECT_OVERLOAD + + + 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 id NMB_haveCount(id expectedValue); -NIMBLE_SHORT(id haveCount(id expectedValue), - NMB_haveCount(expectedValue)); -NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue); -NIMBLE_SHORT(NMBObjCBeCloseToMatcher *beCloseTo(id expectedValue), - NMB_beCloseTo(expectedValue)); +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_equal(TYPE expectedValue) { \ + return NMB_equal((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id equal(TYPE expectedValue), NMB_equal(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_equal(__nullable id expectedValue); + + NIMBLE_SHORT_OVERLOADED(id equal(__nullable id expectedValue), + NMB_equal(expectedValue)); + + // overloaded dispatch for nils - expect(nil) + DEFINE_OVERLOAD(void*__nullable, (id)nil) + DEFINE_OVERLOAD(NSRange, NIMBLE_VALUE_OF(expectedValue)) + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow + // the compiler to dispatch to bool. + DEFINE_OVERLOAD(BOOL, @(expectedValue)) + DEFINE_OVERLOAD(char *, @(expectedValue)) + +#undef DEFINE_OVERLOAD + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_haveCount(TYPE expectedValue) { \ + return NMB_haveCount((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id haveCount(TYPE expectedValue), \ + NMB_haveCount(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_haveCount(id expectedValue); + + NIMBLE_SHORT_OVERLOADED(id haveCount(id expectedValue), + NMB_haveCount(expectedValue)); + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBObjCBeCloseToMatcher *NMB_beCloseTo(TYPE expectedValue) { \ + return NMB_beCloseTo((NSNumber *)(EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToMatcher *beCloseTo(TYPE expectedValue), \ + NMB_beCloseTo(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue); + NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToMatcher *beCloseTo(NSNumber *expectedValue), + NMB_beCloseTo(expectedValue)); + + // it would be better to only overload float & double, but zero becomes ambigious + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beAnInstanceOf(Class expectedClass); -NIMBLE_SHORT(id beAnInstanceOf(Class expectedClass), - NMB_beAnInstanceOf(expectedClass)); +NIMBLE_EXPORT_INLINE id beAnInstanceOf(Class expectedClass) { + return NMB_beAnInstanceOf(expectedClass); +} NIMBLE_EXPORT id NMB_beAKindOf(Class expectedClass); -NIMBLE_SHORT(id beAKindOf(Class expectedClass), - NMB_beAKindOf(expectedClass)); +NIMBLE_EXPORT_INLINE id beAKindOf(Class expectedClass) { + return 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_INLINE id beginWith(id itemElementOrSubstring) { + return NMB_beginWith(itemElementOrSubstring); +} + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beGreaterThan(TYPE expectedValue) { \ + return NMB_beGreaterThan((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beGreaterThan(TYPE expectedValue), NMB_beGreaterThan(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beGreaterThan(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beGreaterThan(NSNumber *expectedValue) { + return NMB_beGreaterThan(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beGreaterThanOrEqualTo(TYPE expectedValue) { \ + return NMB_beGreaterThanOrEqualTo((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beGreaterThanOrEqualTo(TYPE expectedValue), \ + NMB_beGreaterThanOrEqualTo(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beGreaterThanOrEqualTo(NSNumber *expectedValue) { + return NMB_beGreaterThanOrEqualTo(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beIdenticalTo(id expectedInstance); NIMBLE_SHORT(id beIdenticalTo(id expectedInstance), @@ -57,13 +231,66 @@ NIMBLE_EXPORT id NMB_be(id expectedInstance); NIMBLE_SHORT(id be(id expectedInstance), NMB_be(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)); +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beLessThan(TYPE expectedValue) { \ + return NMB_beLessThan((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beLessThan(TYPE expectedValue), \ + NMB_beLessThan(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beLessThan(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beLessThan(NSNumber *expectedValue) { + return NMB_beLessThan(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beLessThanOrEqualTo(TYPE expectedValue) { \ + return NMB_beLessThanOrEqualTo((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beLessThanOrEqualTo(TYPE expectedValue), \ + NMB_beLessThanOrEqualTo(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beLessThanOrEqualTo(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beLessThanOrEqualTo(NSNumber *expectedValue) { + return NMB_beLessThanOrEqualTo(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beTruthy(void); NIMBLE_SHORT(id beTruthy(void), @@ -134,7 +361,7 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger #define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__) #ifndef NIMBLE_DISABLE_SHORT_SYNTAX -#define expect(...) NMB_expect(^id{ return (__VA_ARGS__); }, @(__FILE__), __LINE__) +#define expect(...) NMB_expect(^{ 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") @@ -142,4 +369,9 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger #define waitUntilTimeout NMB_waitUntilTimeout #define waitUntil NMB_waitUntil + +#undef NIMBLE_VALUE_OF + #endif + +NS_ASSUME_NONNULL_END diff --git a/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.m b/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.m index 2170238..cd93ddd 100644 --- a/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.m +++ b/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.m @@ -9,7 +9,11 @@ + (void)untilFile:(NSString *)file line:(NSUInteger)line action:(void(^)())actio @end -NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line) { + +NS_ASSUME_NONNULL_BEGIN + + +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBExpectation *__nonnull NMB_expect(id __nullable(^actualBlock)(), NSString *__nonnull file, NSUInteger line) { return [[NMBExpectation alloc] initWithActualBlock:actualBlock negative:NO file:file @@ -35,7 +39,7 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beAKindOfMatcher:expectedClass]; } -NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { return [NMBObjCMatcher beCloseToMatcher:expectedValue within:0.001]; } @@ -43,11 +47,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beginWithMatcher:itemElementOrSubstring]; } -NIMBLE_EXPORT id NMB_beGreaterThan(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beGreaterThan(NSNumber *expectedValue) { return [NMBObjCMatcher beGreaterThanMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { return [NMBObjCMatcher beGreaterThanOrEqualToMatcher:expectedValue]; } @@ -59,11 +63,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beIdenticalToMatcher:expectedInstance]; } -NIMBLE_EXPORT id NMB_beLessThan(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beLessThan(NSNumber *expectedValue) { return [NMBObjCMatcher beLessThanMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { return [NMBObjCMatcher beLessThanOrEqualToMatcher:expectedValue]; } @@ -113,11 +117,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher endWithMatcher:itemElementOrSubstring]; } -NIMBLE_EXPORT id NMB_equal(id expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_equal(__nullable id expectedValue) { return [NMBObjCMatcher equalMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_haveCount(id expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_haveCount(id expectedValue) { return [NMBObjCMatcher haveCountMatcher:expectedValue]; } @@ -148,3 +152,5 @@ NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger [NMBWait untilFile:file line:line action:action]; }; } + +NS_ASSUME_NONNULL_END diff --git a/Carthage/Checkouts/Nimble/Tests/LinuxMain.swift b/Carthage/Checkouts/Nimble/Tests/LinuxMain.swift index 6cae8ca..4210ef0 100644 --- a/Carthage/Checkouts/Nimble/Tests/LinuxMain.swift +++ b/Carthage/Checkouts/Nimble/Tests/LinuxMain.swift @@ -4,7 +4,7 @@ import XCTest // This is the entry point for NimbleTests on Linux XCTMain([ - // testCase(AsynchronousTests.allTests), + testCase(AsyncTest.allTests), testCase(SynchronousTest.allTests), testCase(UserDescriptionTest.allTests), @@ -29,7 +29,7 @@ XCTMain([ testCase(EndWithTest.allTests), testCase(EqualTest.allTests), testCase(HaveCountTest.allTests), - // testCase(MatchTest.allTests), + testCase(MatchTest.allTests), // testCase(RaisesExceptionTest.allTests), testCase(ThrowErrorTest.allTests), testCase(SatisfyAnyOfTest.allTests), diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/AsynchronousTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/AsynchronousTest.swift index 0ccd220..ff78d47 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/AsynchronousTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/AsynchronousTest.swift @@ -1,11 +1,8 @@ +import Dispatch import Foundation import XCTest import Nimble -// These tests require the ObjC runtimes do not currently have the GCD and run loop facilities -// required for working with Nimble's async matchers -#if _runtime(_ObjC) - final class AsyncTest: XCTestCase, XCTestCaseProvider { static var allTests: [(String, (AsyncTest) -> () throws -> Void)] { return [ @@ -24,7 +21,8 @@ final class AsyncTest: XCTestCase, XCTestCaseProvider { ] } - let errorToThrow = NSError(domain: NSExceptionName.internalInconsistencyException.rawValue, code: 42, userInfo: nil) + class Error: Swift.Error {} + let errorToThrow = Error() private func doThrowError() throws -> Int { throw errorToThrow @@ -222,5 +220,3 @@ final class AsyncTest: XCTestCase, XCTestCaseProvider { #endif } } -#endif - diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Helpers/utils.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Helpers/utils.swift index 7962ae4..0b33ea6 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Helpers/utils.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Helpers/utils.swift @@ -1,3 +1,4 @@ +import Dispatch import Foundation @testable import Nimble import XCTest @@ -58,14 +59,12 @@ func failsWithErrorMessageForNil(_ message: String, file: FileString = #file, li failsWithErrorMessage("\(message) (use beNil() to match nils)", file: file, line: line, preferOriginalSourceLocation: preferOriginalSourceLocation, closure: closure) } -#if _runtime(_ObjC) func deferToMainQueue(action: @escaping () -> Void) { DispatchQueue.main.async { Thread.sleep(forTimeInterval: 0.01) action() } } -#endif public class NimbleHelper : NSObject { public class func expectFailureMessage(_ message: NSString, block: @escaping () -> Void, file: FileString, line: UInt) { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift index 7bd3e4c..940a214 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift @@ -26,6 +26,7 @@ final class MatchErrorTest: XCTestCase, XCTestCaseProvider { func testMatchErrorNegative() { expect(NimbleError.laugh).toNot(matchError(NimbleError.cry)) expect(NimbleError.laugh as Error).toNot(matchError(NimbleError.cry)) + expect(NimbleError.laugh).toNot(matchError(EquatableError.self)) } func testMatchNSErrorPositive() { @@ -64,6 +65,10 @@ final class MatchErrorTest: XCTestCase, XCTestCaseProvider { failsWithErrorMessage("expected to not match error , got ") { expect(NimbleError.laugh).toNot(matchError(NimbleError.laugh)) } + + failsWithErrorMessage("expected to match error from type , got ") { + expect(NimbleError.laugh).to(matchError(EquatableError.self)) + } } func testDoesNotMatchNils() { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift index 24257ba..5b6d77f 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift @@ -1,8 +1,6 @@ import XCTest import Nimble -#if _runtime(_ObjC) - final class MatchTest:XCTestCase, XCTestCaseProvider { static var allTests: [(String, (MatchTest) -> () throws -> Void)] { return [ @@ -46,4 +44,3 @@ final class MatchTest:XCTestCase, XCTestCaseProvider { } } } -#endif diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift new file mode 100644 index 0000000..c227b1b --- /dev/null +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift @@ -0,0 +1,62 @@ +import Foundation +import XCTest +import Nimble + +#if _runtime(_ObjC) && !SWIFT_PACKAGE + +final class ThrowAssertionTest: XCTestCase, XCTestCaseProvider { + static var allTests: [(String, (ThrowAssertionTest) -> () throws -> Void)] { + return [ + ("testPositiveMatch", testPositiveMatch), + ("testErrorThrown", testErrorThrown), + ("testPostAssertionCodeNotRun", testPostAssertionCodeNotRun), + ("testNegativeMatch", testNegativeMatch), + ("testPositiveMessage", testPositiveMessage), + ("testNegativeMessage", testNegativeMessage), + ] + } + + func testPositiveMatch() { + expect { () -> Void in fatalError() }.to(throwAssertion()) + } + + func testErrorThrown() { + expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion()) + } + + func testPostAssertionCodeNotRun() { + var reachedPoint1 = false + var reachedPoint2 = false + + expect { + reachedPoint1 = true + precondition(false, "condition message") + reachedPoint2 = true + }.to(throwAssertion()) + + expect(reachedPoint1) == true + expect(reachedPoint2) == false + } + + func testNegativeMatch() { + var reachedPoint1 = false + + expect { reachedPoint1 = true }.toNot(throwAssertion()) + + expect(reachedPoint1) == true + } + + func testPositiveMessage() { + failsWithErrorMessage("expected to throw an assertion") { + expect { () -> Void? in return }.to(throwAssertion()) + } + } + + func testNegativeMessage() { + failsWithErrorMessage("expected to not throw an assertion") { + expect { () -> Void in fatalError() }.toNot(throwAssertion()) + } + } +} + +#endif diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift index 8fd5baf..d7cd312 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift @@ -136,7 +136,6 @@ final class ThrowErrorTest: XCTestCase, XCTestCaseProvider { let moduleName = "NimbleTests" let innerFailureMessage = "expected to equal , got <\(moduleName).NimbleError>" let closure = { (error: Error) in - print("** In closure! With domain \(error._domain)") expect(error._domain).to(equal("foo")) } diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/SynchronousTests.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/SynchronousTests.swift index b50e19b..6234932 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/SynchronousTests.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/SynchronousTests.swift @@ -21,7 +21,9 @@ final class SynchronousTest: XCTestCase, XCTestCaseProvider { ] } - let errorToThrow = NSError(domain: NSCocoaErrorDomain, code: 42, userInfo: nil) + class Error: Swift.Error {} + let errorToThrow = Error() + private func doThrowError() throws -> Int { throw errorToThrow } @@ -36,14 +38,12 @@ final class SynchronousTest: XCTestCase, XCTestCaseProvider { } func testUnexpectedErrorsThrownFails() { -#if _runtime(_ObjC) // This test triggers a weird segfault on Linux currently 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)) } -#endif } func testToMatchesIfMatcherReturnsTrue() { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/UserDescriptionTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/UserDescriptionTest.swift index ef754ec..e22d64e 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/UserDescriptionTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/UserDescriptionTest.swift @@ -38,33 +38,27 @@ final class UserDescriptionTest: XCTestCase, XCTestCaseProvider { } func testToEventuallyMatch_CustomFailureMessage() { -#if _runtime(_ObjC) 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!") } -#endif } func testToEventuallyNotMatch_CustomFailureMessage() { -#if _runtime(_ObjC) failsWithErrorMessage( "These are eventually equal!\n" + "expected to eventually not equal <1>, got <1>") { expect { 1 }.toEventuallyNot(equal(1), description: "These are eventually equal!") } -#endif } func testToNotEventuallyMatch_CustomFailureMessage() { -#if _runtime(_ObjC) failsWithErrorMessage( "These are eventually equal!\n" + "expected to eventually not equal <1>, got <1>") { expect { 1 }.toEventuallyNot(equal(1), description: "These are eventually equal!") } -#endif } } diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m index c3f5639..c33d643 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m @@ -12,6 +12,11 @@ - (void)testPositiveMatches { expect(@1.2).to(beCloseTo(@2).within(10)); expect(@2).toNot(beCloseTo(@1)); expect(@1.00001).toNot(beCloseTo(@1).within(0.00000001)); + + 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 { @@ -21,6 +26,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be close to <0> (within 0.001), got <0.0001>", ^{ expect(@(0.0001)).toNot(beCloseTo(@0)); }); + expectFailureMessage(@"expected to be close to <0> (within 0.001), got <1>", ^{ + expect(1).to(beCloseTo(0)); + }); + expectFailureMessage(@"expected to not be close to <0> (within 0.001), got <0.0001>", ^{ + expect(0.0001).toNot(beCloseTo(0)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m index 5b99842..5a5bce8 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m @@ -10,6 +10,14 @@ @implementation ObjCBeFalseTest - (void)testPositiveMatches { expect(@NO).to(beFalse()); expect(@YES).toNot(beFalse()); + + expect(false).to(beFalse()); + expect(true).toNot(beFalse()); + + expect(NO).to(beFalse()); + expect(YES).toNot(beFalse()); + + expect(10).toNot(beFalse()); } - (void)testNegativeMatches { @@ -19,6 +27,20 @@ - (void)testNegativeMatches { expectNilFailureMessage(@"expected to not be false, got ", ^{ expect(nil).toNot(beFalse()); }); + + expectFailureMessage(@"expected to be false, got <1>", ^{ + expect(true).to(beFalse()); + }); + expectFailureMessage(@"expected to not be false, got <0>", ^{ + expect(false).toNot(beFalse()); + }); + + expectFailureMessage(@"expected to be false, got <1>", ^{ + expect(YES).to(beFalse()); + }); + expectFailureMessage(@"expected to not be false, got <0>", ^{ + expect(NO).toNot(beFalse()); + }); } @end diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m index 4b6281e..f3f5c98 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m @@ -11,6 +11,15 @@ - (void)testPositiveMatches { expect(@NO).to(beFalsy()); expect(@YES).toNot(beFalsy()); expect(nil).to(beFalsy()); + + expect(true).toNot(beFalsy()); + expect(false).to(beFalsy()); + + expect(YES).toNot(beFalsy()); + expect(NO).to(beFalsy()); + + expect(10).toNot(beFalsy()); + expect(0).to(beFalsy()); } - (void)testNegativeMatches { @@ -20,8 +29,29 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be falsy, got <1>", ^{ expect(@1).to(beFalsy()); }); - expectFailureMessage(@"expected to be truthy, got <0>", ^{ - expect(@NO).to(beTruthy()); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(@NO).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <1>", ^{ + expect(true).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(false).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <1>", ^{ + expect(YES).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(NO).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <10>", ^{ + expect(10).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(0).toNot(beFalsy()); }); } diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m index cec26c7..22cab3a 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeGreaterThanOrEqualToTest - (void)testPositiveMatches { expect(@2).to(beGreaterThanOrEqualTo(@2)); expect(@2).toNot(beGreaterThanOrEqualTo(@3)); + expect(2).to(beGreaterThanOrEqualTo(0)); + expect(2).to(beGreaterThanOrEqualTo(2)); + expect(2).toNot(beGreaterThanOrEqualTo(3)); } - (void)testNegativeMatches { @@ -19,6 +22,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be greater than or equal to <1>, got <2>", ^{ expect(@2).toNot(beGreaterThanOrEqualTo(@(1))); }); + expectFailureMessage(@"expected to be greater than or equal to <0>, got <-1>", ^{ + expect(-1).to(beGreaterThanOrEqualTo(0)); + }); + expectFailureMessage(@"expected to not be greater than or equal to <1>, got <2>", ^{ + expect(2).toNot(beGreaterThanOrEqualTo(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m index 5ad3087..13336d5 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m @@ -10,6 +10,8 @@ @implementation ObjCBeGreaterThanTest - (void)testPositiveMatches { expect(@2).to(beGreaterThan(@1)); expect(@2).toNot(beGreaterThan(@2)); + expect(@2).to(beGreaterThan(0)); + expect(@2).toNot(beGreaterThan(2)); } - (void)testNegativeMatches { @@ -19,6 +21,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be greater than <1>, got <0>", ^{ expect(@0).toNot(beGreaterThan(@(1))); }); + expectFailureMessage(@"expected to be greater than <0>, got <-1>", ^{ + expect(-1).to(beGreaterThan(0)); + }); + expectFailureMessage(@"expected to not be greater than <1>, got <0>", ^{ + expect(0).toNot(beGreaterThan(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m index ab60a81..a9d9d51 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m @@ -25,9 +25,12 @@ - (void)testNegativeMatches { - (void)testNilMatches { NSNull *obj = [NSNull null]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" expectNilFailureMessage(@"expected to be identical to nil, got nil", ^{ expect(nil).to(beIdenticalTo(nil)); }); +#pragma clang diagnostic pop expectNilFailureMessage(([NSString stringWithFormat:@"expected to not be identical to <%p>, got nil", obj]), ^{ expect(nil).toNot(beIdenticalTo(obj)); }); @@ -51,9 +54,12 @@ - (void)testAliasNegativeMatches { - (void)testAliasNilMatches { NSNull *obj = [NSNull null]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" expectNilFailureMessage(@"expected to be identical to nil, got nil", ^{ expect(nil).to(be(nil)); }); +#pragma clang diagnostic pop expectNilFailureMessage(([NSString stringWithFormat:@"expected to not be identical to <%p>, got nil", obj]), ^{ expect(nil).toNot(be(obj)); }); diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m index dbd2062..4a738ec 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeLessThanOrEqualToTest - (void)testPositiveMatches { expect(@2).to(beLessThanOrEqualTo(@2)); expect(@2).toNot(beLessThanOrEqualTo(@1)); + expect(2).to(beLessThanOrEqualTo(2)); + expect(2).toNot(beLessThanOrEqualTo(1)); + expect(2).toNot(beLessThanOrEqualTo(0)); } - (void)testNegativeMatches { @@ -19,6 +22,13 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be less than or equal to <1>, got <1>", ^{ expect(@1).toNot(beLessThanOrEqualTo(@1)); }); + + expectFailureMessage(@"expected to be less than or equal to <1>, got <2>", ^{ + expect(2).to(beLessThanOrEqualTo(1)); + }); + expectFailureMessage(@"expected to not be less than or equal to <1>, got <1>", ^{ + expect(1).toNot(beLessThanOrEqualTo(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m index 4d9da72..7ba38b2 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeLessThanTest - (void)testPositiveMatches { expect(@2).to(beLessThan(@3)); expect(@2).toNot(beLessThan(@2)); + expect(2).to(beLessThan(3)); + expect(2).toNot(beLessThan(2)); + expect(2).toNot(beLessThan(0)); } - (void)testNegativeMatches { @@ -19,6 +22,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be less than <1>, got <0>", ^{ expect(@0).toNot(beLessThan(@1)); }); + expectFailureMessage(@"expected to be less than <0>, got <-1>", ^{ + expect(-1).to(beLessThan(0)); + }); + expectFailureMessage(@"expected to not be less than <1>, got <0>", ^{ + expect(0).toNot(beLessThan(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m index 3f10ce3..c669475 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m @@ -11,6 +11,12 @@ - (void)testPositiveMatches { expect(@YES).to(beTrue()); expect(@NO).toNot(beTrue()); expect(nil).toNot(beTrue()); + + expect(true).to(beTrue()); + expect(false).toNot(beTrue()); + + expect(YES).to(beTrue()); + expect(NO).toNot(beTrue()); } - (void)testNegativeMatches { @@ -20,6 +26,22 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be true, got ", ^{ expect(nil).to(beTrue()); }); + + expectFailureMessage(@"expected to be true, got <0>", ^{ + expect(false).to(beTrue()); + }); + + expectFailureMessage(@"expected to not be true, got <1>", ^{ + expect(true).toNot(beTrue()); + }); + + expectFailureMessage(@"expected to be true, got <0>", ^{ + expect(NO).to(beTrue()); + }); + + expectFailureMessage(@"expected to not be true, got <1>", ^{ + expect(YES).toNot(beTrue()); + }); } @end diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m index 93180a2..1ad7913 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m @@ -11,6 +11,15 @@ - (void)testPositiveMatches { expect(@YES).to(beTruthy()); expect(@NO).toNot(beTruthy()); expect(nil).toNot(beTruthy()); + + expect(true).to(beTruthy()); + expect(false).toNot(beTruthy()); + + expect(YES).to(beTruthy()); + expect(NO).toNot(beTruthy()); + + expect(10).to(beTruthy()); + expect(0).toNot(beTruthy()); } - (void)testNegativeMatches { @@ -23,6 +32,24 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be truthy, got <0>", ^{ expect(@NO).to(beTruthy()); }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(false).to(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <1>", ^{ + expect(true).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(NO).to(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <1>", ^{ + expect(YES).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <10>", ^{ + expect(10).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(0).to(beTruthy()); + }); } @end diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m index e5a2be0..6c20809 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m @@ -12,6 +12,31 @@ - (void)testPositiveMatches { expect(@1).toNot(equal(@2)); expect(@1).notTo(equal(@2)); expect(@"hello").to(equal(@"hello")); + expect("hello").to(equal("hello")); + expect(NSMakeRange(0, 10)).to(equal(NSMakeRange(0, 10))); + expect(NSMakeRange(0, 10)).toNot(equal(NSMakeRange(0, 5))); + expect((NSInteger)1).to(equal((NSInteger)1)); + expect((NSInteger)1).toNot(equal((NSInteger)2)); + expect((NSUInteger)1).to(equal((NSUInteger)1)); + expect((NSUInteger)1).toNot(equal((NSUInteger)2)); + expect(0).to(equal(0)); + expect(1).to(equal(1)); + expect(1).toNot(equal(2)); + expect(1.0).to(equal(1.0)); // Note: not recommended, use beCloseTo() instead + expect(1.0).toNot(equal(2.0)); // Note: not recommended, use beCloseTo() instead + expect((float)1.0).to(equal((float)1.0)); // Note: not recommended, use beCloseTo() instead + expect((float)1.0).toNot(equal((float)2.0)); // Note: not recommended, use beCloseTo() instead + expect((double)1.0).to(equal((double)1.0)); // Note: not recommended, use beCloseTo() instead + expect((double)1.0).toNot(equal((double)2.0)); // Note: not recommended, use beCloseTo() instead + expect((long long)1).to(equal((long long)1)); + expect((long long)1).toNot(equal((long long)2)); + expect((unsigned long long)1).to(equal((unsigned long long)1)); + expect((unsigned long long)1).toNot(equal((unsigned long long)2)); +} + +- (void)testNimbleCurrentlyBoxesNumbersWhichAllowsImplicitTypeConversions { + expect(1).to(equal(1.0)); + expect((long long)1).to(equal((unsigned long long)1)); } - (void)testNegativeMatches { @@ -21,9 +46,43 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not equal <1>, got <1>", ^{ expect(@1).toNot(equal(@1)); }); + expectFailureMessage(@"expected to not equal , got ", ^{ + expect("bar").toNot(equal("foo")); + }); + expectFailureMessage(@"expected to equal , got ", ^{ + expect(NSMakeRange(0, 10)).to(equal(NSMakeRange(0, 5))); + }); + + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((NSInteger)1).to(equal((NSInteger)2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((NSUInteger)1).to(equal((NSUInteger)2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect(1).to(equal(2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect(1.0).to(equal(2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((float)1.0).to(equal((float)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((double)1.0).to(equal((double)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((long long)1.0).to(equal((long long)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((unsigned long long)1.0).to(equal((unsigned long long)2.0)); + }); } - (void)testNilMatches { + expectNilFailureMessage(@"expected to equal , got ", ^{ + expect(NULL).to(equal(NULL)); + }); expectNilFailureMessage(@"expected to equal , got ", ^{ expect(nil).to(equal(nil)); }); diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m index d5fdf4f..31053c8 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m @@ -14,6 +14,12 @@ - (void)testHaveCountForNSArray { expect(@[]).to(haveCount(@0)); expect(@[@1]).notTo(haveCount(@0)); + expect(@[@1, @2, @3]).to(haveCount(3)); + expect(@[@1, @2, @3]).notTo(haveCount(1)); + + expect(@[]).to(haveCount(0)); + expect(@[@1]).notTo(haveCount(0)); + expectFailureMessage(@"expected to have NSArray with count 1, got 3\nActual Value: (1, 2, 3)", ^{ expect(@[@1, @2, @3]).to(haveCount(@1)); }); @@ -22,12 +28,22 @@ - (void)testHaveCountForNSArray { expect(@[@1, @2, @3]).notTo(haveCount(@3)); }); + expectFailureMessage(@"expected to have NSArray with count 1, got 3\nActual Value: (1, 2, 3)", ^{ + expect(@[@1, @2, @3]).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSArray with count 3, got 3\nActual Value: (1, 2, 3)", ^{ + expect(@[@1, @2, @3]).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSDictionary { expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(@3)); expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(@1)); + expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(3)); + expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(1)); + expectFailureMessage(@"expected to have NSDictionary with count 1, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(@1)); }); @@ -35,6 +51,14 @@ - (void)testHaveCountForNSDictionary { expectFailureMessage(@"expected to not have NSDictionary with count 3, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSDictionary with count 1, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ + expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSDictionary with count 3, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ + expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSHashtable { @@ -46,6 +70,9 @@ - (void)testHaveCountForNSHashtable { expect(table).to(haveCount(@3)); expect(table).notTo(haveCount(@1)); + expect(table).to(haveCount(3)); + expect(table).notTo(haveCount(1)); + NSString *msg = [NSString stringWithFormat: @"expected to have NSHashTable {[2] 2[12] 1[13] 3}with count 1, got 3\nActual Value: %@", [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; @@ -53,13 +80,27 @@ - (void)testHaveCountForNSHashtable { expect(table).to(haveCount(@1)); }); - msg = [NSString stringWithFormat: @"expected to not have NSHashTable {[2] 2[12] 1[13] 3}with count 3, got 3\nActual Value: %@", [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; expectFailureMessage(msg, ^{ expect(table).notTo(haveCount(@3)); }); + + + msg = [NSString stringWithFormat: + @"expected to have NSHashTable {[2] 2[12] 1[13] 3}with count 1, got 3\nActual Value: %@", + [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; + expectFailureMessage(msg, ^{ + expect(table).to(haveCount(1)); + }); + + msg = [NSString stringWithFormat: + @"expected to not have NSHashTable {[2] 2[12] 1[13] 3}with count 3, got 3\nActual Value: %@", + [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; + expectFailureMessage(msg, ^{ + expect(table).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSSet { @@ -67,6 +108,8 @@ - (void)testHaveCountForNSSet { expect(set).to(haveCount(@3)); expect(set).notTo(haveCount(@1)); + expect(set).to(haveCount(3)); + expect(set).notTo(haveCount(1)); expectFailureMessage(@"expected to have NSSet with count 1, got 3\nActual Value: {(3,1,2)}", ^{ expect(set).to(haveCount(@1)); @@ -75,6 +118,14 @@ - (void)testHaveCountForNSSet { expectFailureMessage(@"expected to not have NSSet with count 3, got 3\nActual Value: {(3,1,2)}", ^{ expect(set).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSSet with count 1, got 3\nActual Value: {(3,1,2)}", ^{ + expect(set).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSSet with count 3, got 3\nActual Value: {(3,1,2)}", ^{ + expect(set).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSIndexSet { @@ -82,6 +133,8 @@ - (void)testHaveCountForNSIndexSet { expect(set).to(haveCount(@3)); expect(set).notTo(haveCount(@1)); + expect(set).to(haveCount(3)); + expect(set).notTo(haveCount(1)); expectFailureMessage(@"expected to have NSIndexSet with count 1, got 3\nActual Value: (1, 2, 3)", ^{ expect(set).to(haveCount(@1)); @@ -90,6 +143,14 @@ - (void)testHaveCountForNSIndexSet { expectFailureMessage(@"expected to not have NSIndexSet with count 3, got 3\nActual Value: (1, 2, 3)", ^{ expect(set).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSIndexSet with count 1, got 3\nActual Value: (1, 2, 3)", ^{ + expect(set).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSIndexSet with count 3, got 3\nActual Value: (1, 2, 3)", ^{ + expect(set).notTo(haveCount(3)); + }); } - (void)testHaveCountForUnsupportedTypes { @@ -100,6 +161,14 @@ - (void)testHaveCountForUnsupportedTypes { expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFNumber", ^{ expect(@1).to(haveCount(@6)); }); + + expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFConstantString", ^{ + expect(@"string").to(haveCount(6)); + }); + + expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFNumber", ^{ + expect(@1).to(haveCount(6)); + }); } @end diff --git a/Carthage/Checkouts/Swinject/.swiftlint.yml b/Carthage/Checkouts/Swinject/.swiftlint.yml index 6233474..3c049ca 100644 --- a/Carthage/Checkouts/Swinject/.swiftlint.yml +++ b/Carthage/Checkouts/Swinject/.swiftlint.yml @@ -9,7 +9,7 @@ disabled_rules: excluded: - Sources/Container.Arguments.swift - Sources/SynchronizedResolver.Arguments.swift - - Sources/ResolverType.swift + - Sources/Resolver.swift - Tests - Sample-iOS.playground - Carthage diff --git a/Carthage/Checkouts/Swinject/.travis.yml b/Carthage/Checkouts/Swinject/.travis.yml index 7a68a6a..b34e6bc 100644 --- a/Carthage/Checkouts/Swinject/.travis.yml +++ b/Carthage/Checkouts/Swinject/.travis.yml @@ -23,15 +23,13 @@ env: - DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="Swinject-watchOS" SDK="$WATCHOS_SDK" PLATFORM="watchOS" POD_LINT="NO" ACTION="build" - DESTINATION="OS=3.0,name=Apple Watch - 42mm" SCHEME="Swinject-watchOS" SDK="$WATCHOS_SDK" PLATFORM="watchOS" POD_LINT="NO" ACTION="build" before_install: - - curl -L -O https://github.com/Carthage/Carthage/releases/download/0.17.2/Carthage.pkg - - sudo installer -pkg Carthage.pkg -target / - - carthage bootstrap --verbose --no-build --use-submodules + - git submodule update --recursive script: - set -o pipefail - xcodebuild -version - open -b com.apple.iphonesimulator # Workaround https://github.com/travis-ci/travis-ci/issues/3040 - xcodebuild -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" - -configuration Release ENABLE_TESTABILITY=YES ONLY_ACTIVE_ARCH=NO $ACTION + -configuration Release ENABLE_TESTABILITY=YES ONLY_ACTIVE_ARCH=NO $ACTION | xcpretty - if [ $POD_LINT == "YES" ]; then pod lib lint --quick; fi diff --git a/Carthage/Checkouts/Swinject/Documentation/CircularDependencies.md b/Carthage/Checkouts/Swinject/Documentation/CircularDependencies.md index b8bc3fb..dc3f441 100644 --- a/Carthage/Checkouts/Swinject/Documentation/CircularDependencies.md +++ b/Carthage/Checkouts/Swinject/Documentation/CircularDependencies.md @@ -78,6 +78,29 @@ Here both or either of the depending properties must be specified in the `initCo _Not supported._ This type of dependency causes infinite recursion. +## Remark + +When resolving circular dependencies one of the factory methods (one containing resolution of circular dependency) migth be invoked twice. Only one of the resulting instances will be used in the final object graph but in some cases this can be problematic - particularly when there are side effects of factory invocation, such as +- time consuming operations +- interactions with resolved dependencies + +You can avoid duplicate invocation by resolving both parts of the dependency cycle inside `initCompleted` closures, for example refactoring +```swift +container.register(ParentType.self) { r in + let parent = Parent() + parent.child = r.resolve(ChildType.self)! + return parent +} +``` +to +```swift +container.register(ParentType.self) { _ in Parent() } + .initCompleted { r, p in + let parent = p as! Parent + parent.child = r.resolve(ChildType.self)! + } +``` + _[Next page: Object Scopes](ObjectScopes.md)_ _[Table of Contents](README.md)_ diff --git a/Carthage/Checkouts/Swinject/Documentation/ContainerHierarchy.md b/Carthage/Checkouts/Swinject/Documentation/ContainerHierarchy.md index 35daacc..f6705bb 100644 --- a/Carthage/Checkouts/Swinject/Documentation/ContainerHierarchy.md +++ b/Carthage/Checkouts/Swinject/Documentation/ContainerHierarchy.md @@ -22,6 +22,6 @@ let cat = parentContainer.resolve(AnimalType.self) print(cat == nil) // prints "true" ``` -_[Next page: Properties](Properties.md)_ +_[Next page: Properties](Assembler.md)_ _[Table of Contents](README.md)_ diff --git a/Carthage/Checkouts/Swinject/Documentation/Properties.md b/Carthage/Checkouts/Swinject/Documentation/Properties.md deleted file mode 100644 index 108b8dc..0000000 --- a/Carthage/Checkouts/Swinject/Documentation/Properties.md +++ /dev/null @@ -1,140 +0,0 @@ -# Properties - -Properties are values that can be loaded from resources that are bundled with your application/framework. -Properties can then be used when assembling definitions in your container. - -There are 2 types of support property formats: - - - JSON (`JsonPropertyLoader`) - - Plist (`PlistPropertyLoader`) - -Each format supports the types specified by the format itself. If JSON format is used -then your basic types: `Bool`, `Int`, `Double`, `String`, `Array` and `Dictionary` are -supported. For Plist, all types supported by the Plist are supported which include all -JSON types plus `NSDate` and `NSData`. - -JSON property files also support comments which allow you to provide more context to -your properties besides your property key names. For example: - -```js -{ - // Comment type 1 - "foo": "bar", - - /* Comment type 2 */ - "baz": 100, - - /** - Comment type 3 - */ - "boo": 30.50 -} -``` - -Loading properties into the container is as simple as: - -```swift -let container = Container() - -// will load "properties.json" from the main app bundle -let loader = JsonPropertyLoader(bundle: .mainBundle(), name: "properties") - -try! container.applyPropertyLoader(loader) -``` - -Now you can inject properties into definitions registered into the container. - -Consider the following definition: - -```swift -class Person { - var name: String! - var count: Int? - var team: String = "" -} -``` - -And let's say our `properties.json` file contains: - -```json -{ - "name": "Mike", - "count": 100, - "team": "Giants" -} -``` - -Then we can register this Service type with properties like so: - -```swift -container.register(Person.self) { r in - let person = Person() - person.name = r.property("name") - person.count = r.property("count") - person.team = r.property("team")! -} -``` - -This will resolve the person as: - -```swift -let person = container.resolve(Person.self)! -person.name // "Mike" -person.count // 100 -person.team // "Giants" -``` - -Properties are available on a per-container basis. Multiple property loaders can be -applied to a single container. Properties are merged in the order in which they -are applied to a container. For example, let's say you have 2 property files: - -```json -{ - "message": "hello from A", - "count": 10 -} -``` - -And: - -```json -{ - "message": "hello from B", - "timeout": 4 -} -``` - -If we apply property file A, then property file B to the container, the resulting -property key-value pairs would be: - -```swift -message = "hello from B" -count = 10 -timeout = 4 -``` - -As you can see the `message` property was overridden. This only works for first-level -properties which means `Dictionary` and `Array` are not merged. For example: - -```json -{ - "items": [ - "hello from A" - ] -} -``` -And: - -```json -{ - "items": [ - "hello from B" - ] -} -``` - -The resulting value for `items` would be: `[ "hello from B" ]` - -_[Next page: Modularizing Service Registration](Assembler.md)_ - -_[Table of Contents](README.md)_ diff --git a/Carthage/Checkouts/Swinject/Documentation/README.md b/Carthage/Checkouts/Swinject/Documentation/README.md index 0ae9f42..e663739 100644 --- a/Carthage/Checkouts/Swinject/Documentation/README.md +++ b/Carthage/Checkouts/Swinject/Documentation/README.md @@ -1,5 +1,7 @@ # Documentation +This is documentation for Swinject v2.x series. Documentation for v1.x is [here](https://github.com/Swinject/Swinject/tree/v1/Documentation). + Swinject is a lightweight dependency injection framework for Swift apps. It allows you to split your app into loosely-coupled components, which can then be maintained and tested more easily. Swinject supports pure Swift types, and is powered by the Swift generic type system and [first class functions](https://en.wikipedia.org/wiki/First-class_function). This makes it syntactically elegant and simple to define the object dependencies for your app. ## Table of Contents @@ -15,14 +17,11 @@ Swinject is a lightweight dependency injection framework for Swift apps. It allo ### Advanced Features 1. [Container Hierarchy](ContainerHierarchy.md) -2. [Properties](Properties.md) -3. [Modularizing Service Registration](Assembler.md) -4. [Thread Safety](ThreadSafety.md) - -### UI Features - -1. [Storyboard](Storyboard.md) +2. [Modularizing Service Registration (Assembly)](Assembler.md) +3. [Thread Safety](ThreadSafety.md) ### Extensions -1. [Swinject-CodeGen](https://github.com/Swinject/Swinject-CodeGen) +1. [SwinjectPropertyLoader](https://github.com/Swinject/SwinjectPropertyLoader): Loading property values from resources +2. [SwinjectStoryboard](https://github.com/Swinject/SwinjectStoryboard): Automatic dependency injection via Storyboard +3. [Swinject-CodeGen](https://github.com/Swinject/Swinject-CodeGen): Type-safe code generation of `Container` from a CSV/YAML file defining dependencies diff --git a/Carthage/Checkouts/Swinject/Documentation/Storyboard.md b/Carthage/Checkouts/Swinject/Documentation/Storyboard.md deleted file mode 100644 index 53c5282..0000000 --- a/Carthage/Checkouts/Swinject/Documentation/Storyboard.md +++ /dev/null @@ -1,175 +0,0 @@ -# Storyboard - -Swinject supports automatic dependency injection to view controllers instantiated by `SwinjectStoryboard`. This class inherits `UIStoryboard` (or `NSStoryboard` in case of OS X). To register dependencies of a view controller, use `registerForStoryboard` method. In the same way as a registration of a service type, a view controller can be registered with or without a name. - -**NOTE**: Do NOT explicitly resolve the view controllers registered by `registerForStoryboard` method. The view controllers are intended to be resolved by `SwinjectStoryboard` implicitly. - -## Registration - -### Registration without Name - -Here is a simple example to register a dependency of a view controller without a registration name: - -```swift -let container = Container() -container.registerForStoryboard(AnimalViewController.self) { r, c in - c.animal = r.resolve(AnimalType.self) -} -container.register(AnimalType.self) { _ in Cat(name: "Mimi") } -``` - -Next, we create an instance of `SwinjectStoryboard` with the container specified. If the container is not specified, `SwinjectStoryboard.defaultContainer` is used instead. `instantiateViewControllerWithIdentifier` method creates an instance of the view controller with its dependencies injected: - -```swift -let sb = SwinjectStoryboard.create( - name: "Animals", bundle: nil, container: container) -let controller = sb.instantiateViewControllerWithIdentifier("Animal") - as! AnimalViewController -print(controller.animal! is Cat) // prints "true" -print(controller.animal!.name) // prints "Mimi" -``` - -Where the classes and protocol are: - -```swift -class AnimalViewController: UIViewController { - var animal: AnimalType? - - required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - } -} - -protocol AnimalType { - var name: String { get set } -} - -class Cat: AnimalType { - var name: String - - init(name: String) { - self.name = name - } -} -``` - -and the storyboard named `Animals.storyboard` has `AnimalViewController` with storyboard ID `Animal`. - -![AnimalViewController in Animals.storyboard](./Assets/AnimalViewControllerScreenshot1.png) - -### Registration with Name - -If a storyboard has more than one view controller with the same type, dependencies should be registered with registration names. - -```swift -let container = Container() -container.registerForStoryboard(AnimalViewController.self, name: "cat") { - r, c in c.animal = r.resolve(AnimalType.self, name: "mimi") -} -container.registerForStoryboard(AnimalViewController.self, name: "dog") { - r, c in c.animal = r.resolve(AnimalType.self, name: "hachi") -} -container.register(AnimalType.self, name: "mimi") { - _ in Cat(name: "Mimi") -} -container.register(AnimalType.self, name: "hachi") { - _ in Dog(name: "Hachi") -} -``` - -Then view controllers are instantiated with storyboard IDs similarly to the case without registration names: - -```swift -let sb = SwinjectStoryboard.create( - name: "Animals", bundle: nil, container: container) -let catController = sb.instantiateViewControllerWithIdentifier("Cat") - as! AnimalViewController -let dogController = sb.instantiateViewControllerWithIdentifier("Dog") - as! AnimalViewController -print(catController.animal!.name) // prints "Mimi" -print(dogController.animal!.name) // prints "Hachi" -``` - -Where `Dog` class is: - -```swift -class Dog: AnimalType { - var name: String - - init(name: String) { - self.name = name - } -} -``` - -and the storyboard named `Animals.storyboard` has `AnimalViewController`s with storyboard IDs `Cat` and `Dog`. In addition to the storyboard IDs, user defined runtime attributes are specified as `cat` and `dog` for the key `swinjectRegistrationName`, respectively. - -![AnimalViewControllers with user defined runtime attribute in Animals.storyboard](./Assets/AnimalViewControllerScreenshot2.png) - -## UIWindow and Root View Controller Instantiation - -### Implicit Instantiation from "Main" Storyboard - -If you implicitly instantiate `UIWindow` and its root view controller from "Main" storyboard, implement `setup` class method as an extension of `SwinjectStoryboard` to register dependencies to `defaultContainer`. When the root view controller (initial view controller) is instantiated by runtime, dependencies registered to `defaultContainer` are injected. - -```swift -extension SwinjectStoryboard { - class func setup() { - defaultContainer.registerForStoryboard(AnimalViewController.self) { r, c in - c.animal = r.resolve(AnimalType.self) - } - defaultContainer.register(AnimalType.self) { _ in Cat(name: "Mimi") } - } -} -``` - -### Explicit Instantiation in AppDelegate - -If you prefer explicit instantiation of UIWindow and its root view controller, instantiate `SwinjectStoryboard` with a container in `application:didFinishLaunchingWithOptions:` method. - -```swift -@UIApplicationMain -class AppDelegate: UIResponder, UIApplicationDelegate { - var window: UIWindow? - var container: Container = { - let container = Container() - container.registerForStoryboard(AnimalViewController.self) { r, c in - c.animal = r.resolve(AnimalType.self) - } - container.register(AnimalType.self) { _ in Cat(name: "Mimi") } - return container - }() - - func application( - application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool - { - let window = UIWindow(frame: UIScreen.mainScreen().bounds) - window.makeKeyAndVisible() - self.window = window - - let storyboard = SwinjectStoryboard.create(name: "Main", bundle: nil, container: container) - window.rootViewController = storyboard.instantiateInitialViewController() - - return true - } -} -``` - -Notice that you should delete the `Main storyboard file base name` item (or `UIMainStoryboardFile` item if you are displaying raw keys/values) in `Info.plist` of your app. - -## Storyboard References - -Storyboard Reference introduced with Xcode 7 is supported by `SwinjectStoryboard`. To enable dependency injection when an instance is created from a referenced storyboard, register dependencies to `defaultContainer` static property of `SwinjectStoryboard`. - -```swift -let container = SwinjectStoryboard.defaultContainer -container.registerForStoryboard(AnimalViewController.self) { r, c in - c.animal = r.resolve(AnimalType.self) -} -container.register(AnimalType.self) { _ in Cat(name: "Mimi") } -``` - -If you implicitly instantiate `UIWindow` and its root view controller, the registrations setup for "Main" storyboard can be shared with the referenced storyboard since `defaultContainer` is configured in `setup` method. - -_[Table of Contents](README.md)_ diff --git a/Carthage/Checkouts/Swinject/Documentation/ThreadSafety.md b/Carthage/Checkouts/Swinject/Documentation/ThreadSafety.md index e8e5e65..14b5635 100644 --- a/Carthage/Checkouts/Swinject/Documentation/ThreadSafety.md +++ b/Carthage/Checkouts/Swinject/Documentation/ThreadSafety.md @@ -74,8 +74,6 @@ dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)) { let viewController = storyboard.instantiateInitialViewController() ``` -Refer to [Storyboard Documentation](Storyboard.md) for more details about `SwinjectStoryboard` itself. - -_[Next page: Storyboard](Storyboard.md)_ +Refer to [Storyboard README](https://github.com/Swinject/SwinjectStoryboard) for more details about `SwinjectStoryboard` itself. _[Table of Contents](README.md)_ diff --git a/Carthage/Checkouts/Swinject/README.md b/Carthage/Checkouts/Swinject/README.md index 4500893..0d14c4c 100644 --- a/Carthage/Checkouts/Swinject/README.md +++ b/Carthage/Checkouts/Swinject/README.md @@ -10,8 +10,7 @@ Swinject [![CocoaPods Version](https://img.shields.io/cocoapods/v/Swinject.svg?style=flat)](http://cocoapods.org/pods/Swinject) [![License](https://img.shields.io/cocoapods/l/Swinject.svg?style=flat)](http://cocoapods.org/pods/Swinject) [![Platform](https://img.shields.io/cocoapods/p/Swinject.svg?style=flat)](http://cocoapods.org/pods/Swinject) -[![Swift Version](https://img.shields.io/badge/Swift-2.2-F16D39.svg?style=flat)](https://developer.apple.com/swift) -[![Swift Version](https://img.shields.io/badge/Swift-3.0-F16D39.svg?style=flat)](https://developer.apple.com/swift) +[![Swift Version](https://img.shields.io/badge/Swift-2.2--3.0-F16D39.svg?style=flat)](https://developer.apple.com/swift) Swinject is a lightweight [dependency injection](https://en.wikipedia.org/wiki/Dependency_injection) framework for Swift. @@ -28,19 +27,24 @@ Dependency injection (DI) is a software design pattern that implements Inversion - [x] Support of both Reference and [Value Types](./Documentation/Misc.md#value-types) - [x] [Self-registration (Self-binding)](./Documentation/Misc.md#self-registration-self-binding) - [x] [Container Hierarchy](./Documentation/ContainerHierarchy.md) -- [x] [Property Injection from Resource files](./Documentation/Properties.md) - [x] [Thread Safety](./Documentation/ThreadSafety.md) - [x] [Modular Components](./Documentation/Assembler.md) -- [x] [Storyboard](./Documentation/Storyboard.md) ## Extensions +- **[SwinjectPropertyLoader](https://github.com/Swinject/SwinjectPropertyLoader)**: Loading property values from resources. +- **[SwinjectStoryboard](https://github.com/Swinject/SwinjectStoryboard)**: Automatic dependency injection via Storyboard. - **[Swinject-CodeGen](https://github.com/Swinject/Swinject-CodeGen)**: Type-safe code generation of `Container` from a CSV/YAML file defining dependencies. ## Requirements - iOS 8.0+ / Mac OS X 10.10+ / watchOS 2.0+ / tvOS 9.0+ -- Xcode 7.0+ +- Swift 2.2 or 2.3 + - Xcode 7.0+ +- Swift 3 + - Xcode 8.0+ +- Carthage 0.18+ (if you use) +- CocoaPods 1.1.1+ (if you use) ## Installation @@ -50,8 +54,20 @@ Swinject is available through [Carthage](https://github.com/Carthage/Carthage) o To install Swinject with Carthage, add the following line to your `Cartfile`. - github "Swinject/Swinject" ~> 1.1.0 +#### Swift 2.2 or 2.3 +``` +github "Swinject/Swinject" ~> 1.1.4 +``` + +#### Swift 3.0 + +``` +github "Swinject/Swinject" "2.0.0-beta.2" + +# Uncomment if you use SwinjectStoryboard +# github "Swinject/SwinjectStoryboard" "1.0.0-beta.2" +``` Then run `carthage update --no-use-binaries` command or just `carthage update`. For details of the installation and usage of Carthage, visit [its project page](https://github.com/Carthage/Carthage). @@ -60,12 +76,27 @@ Then run `carthage update --no-use-binaries` command or just `carthage update`. To install Swinject with CocoaPods, add the following lines to your `Podfile`. +#### Swift 2.2 or 2.3 + ```ruby source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' # or platform :osx, '10.10' if your target is OS X. use_frameworks! -pod 'Swinject', '~> 1.1.0' +pod 'Swinject', '~> 1.1.4' +``` + +#### Swift 3.0 + +```ruby +source 'https://github.com/CocoaPods/Specs.git' +platform :ios, '8.0' # or platform :osx, '10.10' if your target is OS X. +use_frameworks! + +pod 'Swinject', '2.0.0-beta.2' + +# Uncomment if you use SwinjectStoryboard +# pod 'SwinjectStoryboard', '1.0.0-beta.2' ``` Then run `pod install` command. For details of the installation and usage of CocoaPods, visit [its official website](https://cocoapods.org). @@ -147,7 +178,14 @@ class PersonViewController: UIViewController { ### With SwinjectStoryboard -Services should be registered in an extension of `SwinjectStoryboard` if you use `SwinjectStoryboard`. Refer to [the document of SwinjectStoryboard](./Documentation/Storyboard.md) for its details. +Import SwinjectStoryboard at the top of your swift source file if you use Swinject v2 in Swift 3. + +```swift +// Only Swinject v2 in Swift 3. +import SwinjectStoryboard +``` + +Services should be registered in an extension of `SwinjectStoryboard` if you use `SwinjectStoryboard`. Refer to [the project page of SwinjectStoryboard](https://github.com/Swinject/SwinjectStoryboard) for its details. ```swift extension SwinjectStoryboard { @@ -242,11 +280,6 @@ and highly inspired by: - [Funq](http://funq.codeplex.com) - [Daniel Cazzulino](http://www.codeplex.com/site/users/view/dcazzulino) and [the project team](http://funq.codeplex.com/team/view). -SwinjectStoryboard is inspired by: - -- [Typhoon](http://typhoonframework.org) - [Jasper Blues](https://github.com/jasperblues), [Aleksey Garbarev](https://github.com/alexgarbarev) and [contributors](https://github.com/appsquickly/Typhoon/graphs/contributors). -- [BlindsidedStoryboard](https://github.com/briancroom/BlindsidedStoryboard) - [Brian Croom](https://github.com/briancroom). - ## License MIT license. See the [LICENSE file](LICENSE.txt) for details. diff --git a/Carthage/Checkouts/Swinject/Sample-iOS.playground/Contents.swift b/Carthage/Checkouts/Swinject/Sample-iOS.playground/Contents.swift index 68e02ce..0e3d796 100644 --- a/Carthage/Checkouts/Swinject/Sample-iOS.playground/Contents.swift +++ b/Carthage/Checkouts/Swinject/Sample-iOS.playground/Contents.swift @@ -108,7 +108,7 @@ class InjectablePerson: PersonType { log = "Injected by initializer." } - func setPet(pet: AnimalType) { + func setPet(_ pet: AnimalType) { self.pet = pet log = "Injected by method." } @@ -308,12 +308,12 @@ class B { class C { } -//: ### ObjectScope.None (aka Transient) +//: ### ObjectScope.none (aka Transient) // New instatnces are created every time. let container1 = Container() container1.register(C.self) { _ in C() } - .inObjectScope(.None) + .inObjectScope(.none) let c1 = container1.resolve(C.self) let c2 = container1.resolve(C.self) @@ -326,30 +326,30 @@ container1.register(B.self) { r in B(c: r.resolve(C.self)!) } let a1 = container1.resolve(A.self)! print(a1.b.c !== a1.c) -//: ### ObjectScope.Graph +//: ### ObjectScope.graph -// New instances are created like ObjectScope.None. +// New instances are created like ObjectScope.none. let container2 = Container() container2.register(C.self) { _ in C() } - .inObjectScope(.Graph) // This is the default scope. + .inObjectScope(.graph) // This is the default scope. let c3 = container2.resolve(C.self) let c4 = container2.resolve(C.self) print(c3 !== c4) -// But unlike ObjectScope.None, the same instance is resolved in the object graph. +// But unlike ObjectScope.none, the same instance is resolved in the object graph. container2.register(A.self) { r in A(b: r.resolve(B.self)!, c: r.resolve(C.self)!) } container2.register(B.self) { r in B(c: r.resolve(C.self)!) } let a2 = container2.resolve(A.self)! print(a2.b.c === a2.c) -//: ### ObjectScope.Container (aka Singleton) +//: ### ObjectScope.container (aka Singleton) // The same instance is shared in the container. let container3 = Container() container3.register(C.self) { _ in C() } - .inObjectScope(.Container) + .inObjectScope(.container) let c5 = container3.resolve(C.self) let c6 = container3.resolve(C.self) @@ -360,18 +360,18 @@ let childOfContainer3 = Container(parent: container3) let c7 = childOfContainer3.resolve(C.self) print(c5 !== c7) -//: ### ObjectScope.Hierarchy (aka Singleton in the Hierarchy) +//: ### ObjectScope.hierarchy (aka Singleton in the Hierarchy) -// The same instance is shared in the container like ObjectScope.Container. +// The same instance is shared in the container like ObjectScope.container. let container4 = Container() container4.register(C.self) { _ in C() } - .inObjectScope(.Hierarchy) + .inObjectScope(.hierarchy) let c8 = container4.resolve(C.self) let c9 = container4.resolve(C.self) print(c8 === c9) -// Unlike ObjectScope.Container, the instance in the parent container is shared to its child container. +// Unlike ObjectScope.container, the instance in the parent container is shared to its child container. let childOfContainer4 = Container(parent: container4) let c10 = childOfContainer4.resolve(C.self) print(c8 === c10) @@ -396,7 +396,7 @@ struct Turtle: AnimalType { // The object scope is ignored because a value type always creates a new instance. let container5 = Container() container5.register(AnimalType.self) { _ in Turtle(name: "Reo") } - .inObjectScope(.Container) + .inObjectScope(.container) var turtle1 = container5.resolve(AnimalType.self)! var turtle2 = container5.resolve(AnimalType.self)! diff --git a/Carthage/Checkouts/Swinject/Sources/Assembler.swift b/Carthage/Checkouts/Swinject/Sources/Assembler.swift index ded86ea..a52dbbd 100644 --- a/Carthage/Checkouts/Swinject/Sources/Assembler.swift +++ b/Carthage/Checkouts/Swinject/Sources/Assembler.swift @@ -14,7 +14,7 @@ public class Assembler { private let container: Container /// expose the container as a resolver so `Service` registration only happens within an assembly - public var resolver: ResolverType { + public var resolver: Resolver { return container } diff --git a/Carthage/Checkouts/Swinject/Sources/AssemblyType.swift b/Carthage/Checkouts/Swinject/Sources/AssemblyType.swift index 4a041c5..104f27d 100644 --- a/Carthage/Checkouts/Swinject/Sources/AssemblyType.swift +++ b/Carthage/Checkouts/Swinject/Sources/AssemblyType.swift @@ -23,11 +23,11 @@ public protocol AssemblyType { /// /// - parameter resolver: the resolver that can resolve instances from the built container /// - func loaded(resolver: ResolverType) + func loaded(resolver: Resolver) } public extension AssemblyType { - func loaded(resolver: ResolverType) { + func loaded(resolver: Resolver) { // no-op } } diff --git a/Carthage/Checkouts/Swinject/Sources/Container.Arguments.erb b/Carthage/Checkouts/Swinject/Sources/Container.Arguments.erb index c11d7a3..36bca6a 100644 --- a/Carthage/Checkouts/Swinject/Sources/Container.Arguments.erb +++ b/Carthage/Checkouts/Swinject/Sources/Container.Arguments.erb @@ -31,7 +31,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and <%= arg_description %> to inject dependencies to the instance, + /// It takes a `Resolver` instance and <%= arg_description %> to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -39,7 +39,7 @@ extension Container { public func register>( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, <%= arg_types %>) -> Service) -> ServiceEntry + factory: (Resolver, <%= arg_types %>) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -47,7 +47,7 @@ extension Container { <% end %> } -// MARK: - ResolverType with Arguments +// MARK: - Resolver with Arguments extension Container { <% (1..arg_count).each do |i| %> <% arg_types = (1..i).map { |n| "Arg#{n}" }.join(", ") %> @@ -85,7 +85,7 @@ extension Container { name: String?, <%= arg_param_def %>) -> Service? { - typealias FactoryType = (ResolverType, <%= arg_types %>) -> Service + typealias FactoryType = (Resolver, <%= arg_types %>) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, <%= arg_param_call %>) } } diff --git a/Carthage/Checkouts/Swinject/Sources/Container.Arguments.swift b/Carthage/Checkouts/Swinject/Sources/Container.Arguments.swift index b5b7b3a..8e731b1 100644 --- a/Carthage/Checkouts/Swinject/Sources/Container.Arguments.swift +++ b/Carthage/Checkouts/Swinject/Sources/Container.Arguments.swift @@ -27,7 +27,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 1 argument to inject dependencies to the instance, + /// It takes a `Resolver` instance and 1 argument to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -35,7 +35,7 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1) -> Service) -> ServiceEntry + factory: (Resolver, Arg1) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -48,7 +48,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 2 arguments to inject dependencies to the instance, + /// It takes a `Resolver` instance and 2 arguments to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -56,7 +56,7 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1, Arg2) -> Service) -> ServiceEntry + factory: (Resolver, Arg1, Arg2) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -69,7 +69,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 3 arguments to inject dependencies to the instance, + /// It takes a `Resolver` instance and 3 arguments to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -77,7 +77,7 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1, Arg2, Arg3) -> Service) -> ServiceEntry + factory: (Resolver, Arg1, Arg2, Arg3) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -90,7 +90,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 4 arguments to inject dependencies to the instance, + /// It takes a `Resolver` instance and 4 arguments to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -98,7 +98,7 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1, Arg2, Arg3, Arg4) -> Service) -> ServiceEntry + factory: (Resolver, Arg1, Arg2, Arg3, Arg4) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -111,7 +111,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 5 arguments to inject dependencies to the instance, + /// It takes a `Resolver` instance and 5 arguments to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -119,7 +119,7 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5) -> Service) -> ServiceEntry + factory: (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -132,7 +132,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 6 arguments to inject dependencies to the instance, + /// It takes a `Resolver` instance and 6 arguments to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -140,7 +140,7 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> Service) -> ServiceEntry + factory: (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -153,7 +153,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 7 arguments to inject dependencies to the instance, + /// It takes a `Resolver` instance and 7 arguments to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -161,7 +161,7 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) -> Service) -> ServiceEntry + factory: (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -174,7 +174,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 8 arguments to inject dependencies to the instance, + /// It takes a `Resolver` instance and 8 arguments to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -182,7 +182,7 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) -> Service) -> ServiceEntry + factory: (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -195,7 +195,7 @@ extension Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` instance and 9 arguments to inject dependencies to the instance, + /// It takes a `Resolver` instance and 9 arguments to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -203,14 +203,14 @@ extension Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) -> Service) -> ServiceEntry + factory: (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } } -// MARK: - ResolverType with Arguments +// MARK: - Resolver with Arguments extension Container { /// Retrieves the instance with the specified service type and 1 argument to the factory closure. /// @@ -241,7 +241,7 @@ extension Container { name: String?, argument: Arg1) -> Service? { - typealias FactoryType = (ResolverType, Arg1) -> Service + typealias FactoryType = (Resolver, Arg1) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, argument) } } @@ -274,7 +274,7 @@ extension Container { name: String?, arguments arg1: Arg1, _ arg2: Arg2) -> Service? { - typealias FactoryType = (ResolverType, Arg1, Arg2) -> Service + typealias FactoryType = (Resolver, Arg1, Arg2) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, arg1, arg2) } } @@ -307,7 +307,7 @@ extension Container { name: String?, arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3) -> Service? { - typealias FactoryType = (ResolverType, Arg1, Arg2, Arg3) -> Service + typealias FactoryType = (Resolver, Arg1, Arg2, Arg3) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, arg1, arg2, arg3) } } @@ -340,7 +340,7 @@ extension Container { name: String?, arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4) -> Service? { - typealias FactoryType = (ResolverType, Arg1, Arg2, Arg3, Arg4) -> Service + typealias FactoryType = (Resolver, Arg1, Arg2, Arg3, Arg4) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, arg1, arg2, arg3, arg4) } } @@ -373,7 +373,7 @@ extension Container { name: String?, arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5) -> Service? { - typealias FactoryType = (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5) -> Service + typealias FactoryType = (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, arg1, arg2, arg3, arg4, arg5) } } @@ -406,7 +406,7 @@ extension Container { name: String?, arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5, _ arg6: Arg6) -> Service? { - typealias FactoryType = (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> Service + typealias FactoryType = (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, arg1, arg2, arg3, arg4, arg5, arg6) } } @@ -439,7 +439,7 @@ extension Container { name: String?, arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5, _ arg6: Arg6, _ arg7: Arg7) -> Service? { - typealias FactoryType = (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) -> Service + typealias FactoryType = (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7) } } @@ -472,7 +472,7 @@ extension Container { name: String?, arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5, _ arg6: Arg6, _ arg7: Arg7, _ arg8: Arg8) -> Service? { - typealias FactoryType = (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) -> Service + typealias FactoryType = (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) } } @@ -505,7 +505,7 @@ extension Container { name: String?, arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3, _ arg4: Arg4, _ arg5: Arg5, _ arg6: Arg6, _ arg7: Arg7, _ arg8: Arg8, _ arg9: Arg9) -> Service? { - typealias FactoryType = (ResolverType, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) -> Service + typealias FactoryType = (Resolver, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) } } diff --git a/Carthage/Checkouts/Swinject/Sources/Container.Logging.swift b/Carthage/Checkouts/Swinject/Sources/Container.Logging.swift new file mode 100644 index 0000000..5012105 --- /dev/null +++ b/Carthage/Checkouts/Swinject/Sources/Container.Logging.swift @@ -0,0 +1,24 @@ +// +// Container.Logging.swift +// Swinject +// +// Created by Jakub Vaňo on 30/09/16. +// Copyright © 2016 Swinject Contributors. All rights reserved. +// + +public typealias LoggingFunctionType = (String) -> Void + +public extension Container { + /// Function to be used for logging debugging data. + /// Default implementation writes to standard output. + public static var logingFunction: LoggingFunctionType? { + get { return _logingFunction } + set { _logingFunction = newValue } + } + + internal static func log(_ message: String) { + _logingFunction?(message) + } +} + +private var _logingFunction: LoggingFunctionType? = { print($0) } diff --git a/Carthage/Checkouts/Swinject/Sources/Container.swift b/Carthage/Checkouts/Swinject/Sources/Container.swift index 8d1f129..fef9a27 100644 --- a/Carthage/Checkouts/Swinject/Sources/Container.swift +++ b/Carthage/Checkouts/Swinject/Sources/Container.swift @@ -27,14 +27,20 @@ public final class Container { fileprivate var services = [ServiceKey: ServiceEntryType]() fileprivate let parent: Container? fileprivate var resolutionPool = ResolutionPool() + fileprivate let debugHelper: DebugHelper internal let lock: SpinLock // Used by SynchronizedResolver. + + internal init(parent: Container? = nil, debugHelper: DebugHelper) { + self.parent = parent + self.debugHelper = debugHelper + self.lock = parent.map { $0.lock } ?? SpinLock() + } /// Instantiates a `Container` with its parent `Container`. The parent is optional. /// /// - Parameter parent: The optional parent `Container`. - public init(parent: Container? = nil) { - self.parent = parent - self.lock = parent.map { $0.lock } ?? SpinLock() + public convenience init(parent: Container? = nil) { + self.init(parent: parent, debugHelper: LoggingDebugHelper()) } /// Instantiates a `Container` with its parent `Container` and a closure registering services. The parent is optional. @@ -60,7 +66,7 @@ public final class Container { /// that have the same service and factory types. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` to inject dependencies to the instance, + /// It takes a `Resolver` to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// /// - Returns: A registered `ServiceEntry` to configure more settings with method chaining. @@ -68,7 +74,7 @@ public final class Container { public func register( _ serviceType: Service.Type, name: String? = nil, - factory: (ResolverType) -> Service) -> ServiceEntry + factory: (Resolver) -> Service) -> ServiceEntry { return _register(serviceType, factory: factory, name: name) } @@ -80,7 +86,7 @@ public final class Container { /// - serviceType: The service type to register. /// - factory: The closure to specify how the service type is resolved with the dependencies of the type. /// It is invoked when the `Container` needs to instantiate the instance. - /// It takes a `ResolverType` to inject dependencies to the instance, + /// It takes a `Resolver` to inject dependencies to the instance, /// and returns the instance of the component type for the service. /// - name: A registration name. /// - option: A service key option for an extension/plugin. @@ -100,16 +106,16 @@ public final class Container { } /// Returns a synchronized view of the container for thread safety. - /// The returned container is `ResolverType` type. Call this method after you finish all service registrations to the original container. + /// The returned container is `Resolver` type. Call this method after you finish all service registrations to the original container. /// - /// - Returns: A synchronized container as `ResolverType`. - public func synchronize() -> ResolverType { + /// - Returns: A synchronized container as `Resolver`. + public func synchronize() -> Resolver { return SynchronizedResolver(container: self) } } -// MARK: - _ResolverType -extension Container: _ResolverType { +// MARK: - _Resolver +extension Container: _Resolver { public func _resolve(name: String?, option: ServiceKeyOptionType? = nil, invoker: (Factory) -> Service) -> Service? { resolutionPool.incrementDepth() defer { resolutionPool.decrementDepth() } @@ -140,12 +146,27 @@ extension Container: _ResolverType { resolvedInstance = entry.instance as? Service } } + + if resolvedInstance == nil { + debugHelper.resolutionFailed( + serviceType: Service.self, + key: key, + availableRegistrations: getRegistrations() + ) + } + return resolvedInstance } + + private func getRegistrations() -> [ServiceKey: ServiceEntryType] { + var registrations = parent?.getRegistrations() ?? [:] + services.forEach { key, value in registrations[key] = value } + return registrations + } } -// MARK: - ResolverType -extension Container: ResolverType { +// MARK: - Resolver +extension Container: Resolver { /// Retrieves the instance with the specified service type. /// /// - Parameter serviceType: The service type to resolve. @@ -170,7 +191,7 @@ extension Container: ResolverType { _ serviceType: Service.Type, name: String?) -> Service? { - typealias FactoryType = (ResolverType) -> Service + typealias FactoryType = (Resolver) -> Service return _resolve(name: name) { (factory: FactoryType) in factory(self) } } @@ -200,9 +221,9 @@ extension Container: ResolverType { } resolutionPool[key] = resolvedInstance as Any } - - if let completed = entry.initCompleted as? (ResolverType, Service) -> () { - resolutionPool.appendPendingCompletion({completed(self, resolvedInstance)}) + + if let completed = entry.initCompleted as? (Resolver, Service) -> () { + completed(self, resolvedInstance) } return resolvedInstance } diff --git a/Carthage/Checkouts/Swinject/Sources/DebugHelper.swift b/Carthage/Checkouts/Swinject/Sources/DebugHelper.swift new file mode 100644 index 0000000..81428a4 --- /dev/null +++ b/Carthage/Checkouts/Swinject/Sources/DebugHelper.swift @@ -0,0 +1,54 @@ +// +// DebugHelper.swift +// Swinject +// +// Created by Jakub Vaňo on 26/09/16. +// Copyright © 2016 Swinject Contributors. All rights reserved. +// + +internal protocol DebugHelper { + func resolutionFailed( + serviceType: Service.Type, + key: ServiceKey, + availableRegistrations: [ServiceKey: ServiceEntryType] + ) +} + +internal final class LoggingDebugHelper: DebugHelper { + + func resolutionFailed( + serviceType: Service.Type, + key: ServiceKey, + availableRegistrations: [ServiceKey: ServiceEntryType] + ) { + var output = [ + "Swinject: Resolution failed. Expected registration:", + "\t{ \(description(serviceType: serviceType, serviceKey: key)) }", + "Available registrations:", + ] + output += availableRegistrations + .filter { $0.1 is ServiceEntry } + .map { "\t{ " + $0.1.describeWithKey($0.0) + " }" } + + Container.log(output.joined(separator: "\n")) + } +} + +internal func description( + serviceType: Service.Type, + serviceKey: ServiceKey, + objectScope: ObjectScope? = nil, + initCompleted: FunctionType? = nil +) -> String { + // The protocol order in "protocol<>" is non-deterministic. + let nameDescription = serviceKey.name.map { ", Name: \"\($0)\"" } ?? "" + let optionDescription = serviceKey.option.map { ", \($0)" } ?? "" + let initCompletedDescription = initCompleted.map { _ in ", InitCompleted: Specified" } ?? "" + let objectScopeDescription = objectScope.map { ", ObjectScope: \($0)" } ?? "" + return "Service: \(serviceType)" + + nameDescription + + optionDescription + + ", Factory: \(serviceKey.factoryType)" + + objectScopeDescription + + initCompletedDescription +} diff --git a/Carthage/Checkouts/Swinject/Sources/ResolutionPool.swift b/Carthage/Checkouts/Swinject/Sources/ResolutionPool.swift index 9bd7654..131f78f 100644 --- a/Carthage/Checkouts/Swinject/Sources/ResolutionPool.swift +++ b/Carthage/Checkouts/Swinject/Sources/ResolutionPool.swift @@ -13,7 +13,6 @@ internal struct ResolutionPool { private var pool = [ServiceKey: Any]() private var depth: Int = 0 - private var pendingCompletions: [()->()] = [] internal subscript(key: ServiceKey) -> Any? { get { return pool[key] } @@ -31,16 +30,9 @@ internal struct ResolutionPool { internal mutating func decrementDepth() { assert(depth > 0, "The depth cannot be negative.") - if depth == 1 { - while let pendingCompletion = pendingCompletions.popLast() { - pendingCompletion() // Must be invoked decrementing depth counter. - } + depth -= 1 + if depth == 0 { pool = [:] } - depth -= 1 - } - - internal mutating func appendPendingCompletion(_ completion: @escaping ()->()) { - pendingCompletions.append(completion) } } diff --git a/Carthage/Checkouts/Swinject/Sources/ResolverType.erb b/Carthage/Checkouts/Swinject/Sources/Resolver.erb similarity index 91% rename from Carthage/Checkouts/Swinject/Sources/ResolverType.erb rename to Carthage/Checkouts/Swinject/Sources/Resolver.erb index 7c4ca0b..0eeb036 100644 --- a/Carthage/Checkouts/Swinject/Sources/ResolverType.erb +++ b/Carthage/Checkouts/Swinject/Sources/Resolver.erb @@ -1,5 +1,5 @@ // -// ResolverType.swift +// Resolver.swift // Swinject // // Created by Yoichi Tagaya on 8/18/15. @@ -9,14 +9,14 @@ // // NOTICE: // -// ResolverType.swift is generated from ResolverType.erb by ERB. +// Resolver.swift is generated from Resolver.erb by ERB. // Do NOT modify Container.Arguments.swift directly. -// Instead, modify ResolverType.erb and run `script/gencode` at the project root directory to generate the code. +// Instead, modify Resolver.erb and run `script/gencode` at the project root directory to generate the code. // <% arg_count = 9 %> -public protocol ResolverType { +public protocol Resolver { /// Retrieves the instance with the specified service type. /// /// - Parameter serviceType: The service type to resolve. diff --git a/Carthage/Checkouts/Swinject/Sources/ResolverType.swift b/Carthage/Checkouts/Swinject/Sources/Resolver.swift similarity index 98% rename from Carthage/Checkouts/Swinject/Sources/ResolverType.swift rename to Carthage/Checkouts/Swinject/Sources/Resolver.swift index 74b7069..cf56060 100644 --- a/Carthage/Checkouts/Swinject/Sources/ResolverType.swift +++ b/Carthage/Checkouts/Swinject/Sources/Resolver.swift @@ -1,5 +1,5 @@ // -// ResolverType.swift +// Resolver.swift // Swinject // // Created by Yoichi Tagaya on 8/18/15. @@ -9,13 +9,13 @@ // // NOTICE: // -// ResolverType.swift is generated from ResolverType.erb by ERB. +// Resolver.swift is generated from Resolver.erb by ERB. // Do NOT modify Container.Arguments.swift directly. -// Instead, modify ResolverType.erb and run `script/gencode` at the project root directory to generate the code. +// Instead, modify Resolver.erb and run `script/gencode` at the project root directory to generate the code. // -public protocol ResolverType { +public protocol Resolver { /// Retrieves the instance with the specified service type. /// /// - Parameter serviceType: The service type to resolve. diff --git a/Carthage/Checkouts/Swinject/Sources/ServiceEntry.swift b/Carthage/Checkouts/Swinject/Sources/ServiceEntry.swift index a0fadcf..e025c20 100644 --- a/Carthage/Checkouts/Swinject/Sources/ServiceEntry.swift +++ b/Carthage/Checkouts/Swinject/Sources/ServiceEntry.swift @@ -54,7 +54,7 @@ public final class ServiceEntry { /// /// - Returns: `self` to add another configuration fluently. @discardableResult - public func initCompleted(_ completed: @escaping (ResolverType, Service) -> ()) -> Self { + public func initCompleted(_ completed: @escaping (Resolver, Service) -> ()) -> Self { initCompleted = completed return self } @@ -62,15 +62,11 @@ public final class ServiceEntry { extension ServiceEntry: ServiceEntryType { internal func describeWithKey(_ serviceKey: ServiceKey) -> String { - // The protocol order in "protocol<>" is non-deterministic. - let nameDescription = serviceKey.name.map { ", Name: \"\($0)\"" } ?? "" - let optionDescription = serviceKey.option.map { ", \($0)" } ?? "" - let initCompletedDescription = initCompleted.map { _ in ", InitCompleted: Specified" } ?? "" - return "Service: \(serviceType)" - + nameDescription - + optionDescription - + ", Factory: \(type(of: factory))" - + ", ObjectScope: \(objectScope)" - + initCompletedDescription + return description( + serviceType: serviceType, + serviceKey: serviceKey, + objectScope: objectScope, + initCompleted: initCompleted + ) } } diff --git a/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.Arguments.erb b/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.Arguments.erb index e7c1e4c..840aa80 100644 --- a/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.Arguments.erb +++ b/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.Arguments.erb @@ -16,7 +16,7 @@ <% arg_count = 9 %> -// MARK: - ResolverType with Arguments +// MARK: - Resolver with Arguments extension SynchronizedResolver { <% (1..arg_count).each do |i| %> <% arg_types = (1..i).map { |n| "Arg#{n}" }.join(", ") %> diff --git a/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.Arguments.swift b/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.Arguments.swift index 49164af..0f43575 100644 --- a/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.Arguments.swift +++ b/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.Arguments.swift @@ -15,7 +15,7 @@ // -// MARK: - ResolverType with Arguments +// MARK: - Resolver with Arguments extension SynchronizedResolver { internal func resolve( _ serviceType: Service.Type, diff --git a/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.swift b/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.swift index 3eb0af5..18f8c55 100644 --- a/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.swift +++ b/Carthage/Checkouts/Swinject/Sources/SynchronizedResolver.swift @@ -14,7 +14,7 @@ internal final class SynchronizedResolver { } } -extension SynchronizedResolver: _ResolverType { +extension SynchronizedResolver: _Resolver { internal func _resolve(name: String?, option: ServiceKeyOptionType?, invoker: (Factory) -> Service) -> Service? { return container.lock.sync { return self.container._resolve(name: name, option: option, invoker: invoker) @@ -22,7 +22,7 @@ extension SynchronizedResolver: _ResolverType { } } -extension SynchronizedResolver: ResolverType { +extension SynchronizedResolver: Resolver { internal func resolve(_ serviceType: Service.Type) -> Service? { return container.lock.sync { return self.container.resolve(serviceType) diff --git a/Carthage/Checkouts/Swinject/Sources/_ResolverType.swift b/Carthage/Checkouts/Swinject/Sources/_Resolver.swift similarity index 86% rename from Carthage/Checkouts/Swinject/Sources/_ResolverType.swift rename to Carthage/Checkouts/Swinject/Sources/_Resolver.swift index a993b93..66aa82a 100644 --- a/Carthage/Checkouts/Swinject/Sources/_ResolverType.swift +++ b/Carthage/Checkouts/Swinject/Sources/_Resolver.swift @@ -1,5 +1,5 @@ // -// _ResolverType.swift +// _Resolver.swift // Swinject // // Created by Yoichi Tagaya on 5/4/16. @@ -9,8 +9,8 @@ /// This protocol is designed for the use to extend Swinject functionality. /// Do NOT use this protocol unless you intend to write an extension or plugin to Swinject framework. /// -/// A type conforming ResolverType protocol must conform _ResolverType protocol too. -public protocol _ResolverType { +/// A type conforming Resolver protocol must conform _Resolver protocol too. +public protocol _Resolver { /// This method is designed for the use to extend Swinject functionality. /// Do NOT use this method unless you intend to write an extension or plugin to Swinject framework. /// diff --git a/Carthage/Checkouts/Swinject/Swinject.xcodeproj/project.pbxproj b/Carthage/Checkouts/Swinject/Swinject.xcodeproj/project.pbxproj index 4facd6d..1fc1840 100644 --- a/Carthage/Checkouts/Swinject/Swinject.xcodeproj/project.pbxproj +++ b/Carthage/Checkouts/Swinject/Swinject.xcodeproj/project.pbxproj @@ -61,10 +61,10 @@ 984775011C034C5C0092A757 /* SynchronizedResolverSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984774FE1C034C5C0092A757 /* SynchronizedResolverSpec.swift */; }; 9848611C1B6F9B7000C07072 /* ContainerSpec.Arguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9848611B1B6F9B7000C07072 /* ContainerSpec.Arguments.swift */; }; 9848611D1B6F9B7000C07072 /* ContainerSpec.Arguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9848611B1B6F9B7000C07072 /* ContainerSpec.Arguments.swift */; }; - 984BE3131CDA3FCF00BCF2AC /* _ResolverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BE3121CDA3FCF00BCF2AC /* _ResolverType.swift */; }; - 984BE3141CDA3FCF00BCF2AC /* _ResolverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BE3121CDA3FCF00BCF2AC /* _ResolverType.swift */; }; - 984BE3151CDA3FCF00BCF2AC /* _ResolverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BE3121CDA3FCF00BCF2AC /* _ResolverType.swift */; }; - 984BE3161CDA3FCF00BCF2AC /* _ResolverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BE3121CDA3FCF00BCF2AC /* _ResolverType.swift */; }; + 984BE3131CDA3FCF00BCF2AC /* _Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BE3121CDA3FCF00BCF2AC /* _Resolver.swift */; }; + 984BE3141CDA3FCF00BCF2AC /* _Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BE3121CDA3FCF00BCF2AC /* _Resolver.swift */; }; + 984BE3151CDA3FCF00BCF2AC /* _Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BE3121CDA3FCF00BCF2AC /* _Resolver.swift */; }; + 984BE3161CDA3FCF00BCF2AC /* _Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BE3121CDA3FCF00BCF2AC /* _Resolver.swift */; }; 984E8A521C317AC90039943D /* Swinject.h in Headers */ = {isa = PBXBuildFile; fileRef = 984E8A511C317AC90039943D /* Swinject.h */; settings = {ATTRIBUTES = (Public, ); }; }; 984E8A531C317AC90039943D /* Swinject.h in Headers */ = {isa = PBXBuildFile; fileRef = 984E8A511C317AC90039943D /* Swinject.h */; settings = {ATTRIBUTES = (Public, ); }; }; 984E8A541C317AC90039943D /* Swinject.h in Headers */ = {isa = PBXBuildFile; fileRef = 984E8A511C317AC90039943D /* Swinject.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -75,7 +75,7 @@ 985011211BBE7E8900A2CCFC /* ResolutionPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 981577F31B676BF700BF686B /* ResolutionPool.swift */; }; 985011221BBE7E8900A2CCFC /* ObjectScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9819701E1B6145D600EEB942 /* ObjectScope.swift */; }; 985011241BBE7E8900A2CCFC /* Container.Arguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012B71B82D67300053A32 /* Container.Arguments.swift */; }; - 985011251BBE7E8900A2CCFC /* ResolverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012BE1B82F68E00053A32 /* ResolverType.swift */; }; + 985011251BBE7E8900A2CCFC /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012BE1B82F68E00053A32 /* Resolver.swift */; }; 9855C5BF1B686F5900DADB0B /* ContainerSpec.Circularity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9855C5BE1B686F5900DADB0B /* ContainerSpec.Circularity.swift */; }; 9855C5C01B686F5900DADB0B /* ContainerSpec.Circularity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9855C5BE1B686F5900DADB0B /* ContainerSpec.Circularity.swift */; }; 9855C5C21B68721800DADB0B /* ResolutionPoolSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9855C5C11B68721800DADB0B /* ResolutionPoolSpec.swift */; }; @@ -92,7 +92,7 @@ 98689C9C1BBFC7EB0005C6D3 /* ResolutionPool.swift in Sources */ = {isa = PBXBuildFile; fileRef = 981577F31B676BF700BF686B /* ResolutionPool.swift */; }; 98689C9D1BBFC7EB0005C6D3 /* ObjectScope.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9819701E1B6145D600EEB942 /* ObjectScope.swift */; }; 98689C9F1BBFC7EB0005C6D3 /* Container.Arguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012B71B82D67300053A32 /* Container.Arguments.swift */; }; - 98689CA01BBFC7EB0005C6D3 /* ResolverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012BE1B82F68E00053A32 /* ResolverType.swift */; }; + 98689CA01BBFC7EB0005C6D3 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012BE1B82F68E00053A32 /* Resolver.swift */; }; 98689CB61BBFD5110005C6D3 /* PersonType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9878C63B1B65CA8700CBEFEF /* PersonType.swift */; }; 98689CB71BBFD5110005C6D3 /* AnimalType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9878C6371B65C9E000CBEFEF /* AnimalType.swift */; }; 98689CB81BBFD5110005C6D3 /* FoodType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9855C5C41B689B7B00DADB0B /* FoodType.swift */; }; @@ -118,8 +118,19 @@ 9884E2AB1B60C51C00120259 /* ServiceKeySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9884E2A91B60C51C00120259 /* ServiceKeySpec.swift */; }; 98B012B81B82D67300053A32 /* Container.Arguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012B71B82D67300053A32 /* Container.Arguments.swift */; }; 98B012B91B82D67300053A32 /* Container.Arguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012B71B82D67300053A32 /* Container.Arguments.swift */; }; - 98B012BF1B82F68E00053A32 /* ResolverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012BE1B82F68E00053A32 /* ResolverType.swift */; }; - 98B012C01B82F68E00053A32 /* ResolverType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012BE1B82F68E00053A32 /* ResolverType.swift */; }; + 98B012BF1B82F68E00053A32 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012BE1B82F68E00053A32 /* Resolver.swift */; }; + 98B012C01B82F68E00053A32 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 98B012BE1B82F68E00053A32 /* Resolver.swift */; }; + CD3C2CDF1D98E47000863421 /* DebugHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C2CDE1D98E47000863421 /* DebugHelper.swift */; }; + CD3C2CE01D98E47000863421 /* DebugHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C2CDE1D98E47000863421 /* DebugHelper.swift */; }; + CD3C2CE11D98E47000863421 /* DebugHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C2CDE1D98E47000863421 /* DebugHelper.swift */; }; + CD3C2CE21D98E47000863421 /* DebugHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C2CDE1D98E47000863421 /* DebugHelper.swift */; }; + CD3C2CF21D98EF4A00863421 /* ContainerSpec.DebugHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C2CF11D98EF4A00863421 /* ContainerSpec.DebugHelper.swift */; }; + CD3C2CF31D98EF4A00863421 /* ContainerSpec.DebugHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C2CF11D98EF4A00863421 /* ContainerSpec.DebugHelper.swift */; }; + CD3C2CF41D98EF4A00863421 /* ContainerSpec.DebugHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD3C2CF11D98EF4A00863421 /* ContainerSpec.DebugHelper.swift */; }; + CDBBACF61D9EAD60002F5EF9 /* Container.Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDBBACF51D9EAD60002F5EF9 /* Container.Logging.swift */; }; + CDBBACF71D9EAD60002F5EF9 /* Container.Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDBBACF51D9EAD60002F5EF9 /* Container.Logging.swift */; }; + CDBBACF81D9EAD60002F5EF9 /* Container.Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDBBACF51D9EAD60002F5EF9 /* Container.Logging.swift */; }; + CDBBACF91D9EAD60002F5EF9 /* Container.Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDBBACF51D9EAD60002F5EF9 /* Container.Logging.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -321,13 +332,13 @@ 984774FE1C034C5C0092A757 /* SynchronizedResolverSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronizedResolverSpec.swift; sourceTree = ""; }; 9848611A1B6F21EC00C07072 /* Sample-iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = "Sample-iOS.playground"; sourceTree = ""; }; 9848611B1B6F9B7000C07072 /* ContainerSpec.Arguments.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainerSpec.Arguments.swift; sourceTree = ""; }; - 984BE3121CDA3FCF00BCF2AC /* _ResolverType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = _ResolverType.swift; sourceTree = ""; }; + 984BE3121CDA3FCF00BCF2AC /* _Resolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = _Resolver.swift; sourceTree = ""; }; 984E8A511C317AC90039943D /* Swinject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Swinject.h; sourceTree = ""; }; 985010BD1BBE76AB00A2CCFC /* watchOS-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Application.xcconfig"; sourceTree = ""; }; 985010BE1BBE76AB00A2CCFC /* watchOS-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Base.xcconfig"; sourceTree = ""; }; 985010BF1BBE76AB00A2CCFC /* watchOS-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Framework.xcconfig"; sourceTree = ""; }; 985010C01BBE76AB00A2CCFC /* watchOS-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-StaticLibrary.xcconfig"; sourceTree = ""; }; - 985010C61BBE76D400A2CCFC /* Swinject.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Swinject.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 985010C61BBE76D400A2CCFC /* .framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = .framework; path = Swinject.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 9855C5BE1B686F5900DADB0B /* ContainerSpec.Circularity.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainerSpec.Circularity.swift; sourceTree = ""; }; 9855C5C11B68721800DADB0B /* ResolutionPoolSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResolutionPoolSpec.swift; sourceTree = ""; }; 9855C5C41B689B7B00DADB0B /* FoodType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoodType.swift; sourceTree = ""; }; @@ -363,8 +374,11 @@ 98AA745A1BB70CBB00E2F48A /* Mac-StaticLibrary.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Mac-StaticLibrary.xcconfig"; sourceTree = ""; }; 98B012B71B82D67300053A32 /* Container.Arguments.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Container.Arguments.swift; sourceTree = ""; }; 98B012BA1B82D6A400053A32 /* Container.Arguments.erb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Container.Arguments.erb; sourceTree = ""; }; - 98B012BE1B82F68E00053A32 /* ResolverType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResolverType.swift; sourceTree = ""; }; - 98B012C11B82F70A00053A32 /* ResolverType.erb */ = {isa = PBXFileReference; lastKnownFileType = text; path = ResolverType.erb; sourceTree = ""; }; + 98B012BE1B82F68E00053A32 /* Resolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Resolver.swift; sourceTree = ""; }; + 98B012C11B82F70A00053A32 /* Resolver.erb */ = {isa = PBXFileReference; lastKnownFileType = text; path = Resolver.erb; sourceTree = ""; }; + CD3C2CDE1D98E47000863421 /* DebugHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugHelper.swift; sourceTree = ""; }; + CD3C2CF11D98EF4A00863421 /* ContainerSpec.DebugHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContainerSpec.DebugHelper.swift; sourceTree = ""; }; + CDBBACF51D9EAD60002F5EF9 /* Container.Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Container.Logging.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -461,7 +475,7 @@ 981ABE8B1B5FC9DF00294975 /* SwinjectTests.xctest */, 981899BC1B5FE63F00C702D0 /* Swinject.framework */, 981899C51B5FE63F00C702D0 /* SwinjectTests.xctest */, - 985010C61BBE76D400A2CCFC /* Swinject.framework */, + 985010C61BBE76D400A2CCFC /* .framework */, 98689C7F1BBFC7A50005C6D3 /* Swinject.framework */, 98689C881BBFC7A60005C6D3 /* SwinjectTests.xctest */, ); @@ -475,6 +489,8 @@ 90B029741C18599200A6A521 /* AssemblyType.swift */, 981899E31B5FFE5800C702D0 /* Container.swift */, 98B012BA1B82D6A400053A32 /* Container.Arguments.erb */, + CD3C2CDE1D98E47000863421 /* DebugHelper.swift */, + CDBBACF51D9EAD60002F5EF9 /* Container.Logging.swift */, 984774EF1C02F25D0092A757 /* SynchronizedResolver.swift */, 984774F41C02F4EA0092A757 /* SynchronizedResolver.Arguments.erb */, 9880E70D1C09EE2800ED5293 /* FunctionType.swift */, @@ -482,8 +498,8 @@ 985BAFA81B625E0F0055F998 /* ServiceEntry.swift */, 981577F31B676BF700BF686B /* ResolutionPool.swift */, 9819701E1B6145D600EEB942 /* ObjectScope.swift */, - 984BE3121CDA3FCF00BCF2AC /* _ResolverType.swift */, - 98B012C11B82F70A00053A32 /* ResolverType.erb */, + 984BE3121CDA3FCF00BCF2AC /* _Resolver.swift */, + 98B012C11B82F70A00053A32 /* Resolver.erb */, 983B98301C06ECB2006A23D4 /* SpinLock.swift */, 98B012BD1B82D6B000053A32 /* GeneratedCode */, 984E8A511C317AC90039943D /* Swinject.h */, @@ -500,6 +516,7 @@ 981899E01B5FF88800C702D0 /* ContainerSpec.swift */, 9848611B1B6F9B7000C07072 /* ContainerSpec.Arguments.swift */, 9855C5BE1B686F5900DADB0B /* ContainerSpec.Circularity.swift */, + CD3C2CF11D98EF4A00863421 /* ContainerSpec.DebugHelper.swift */, 984774FE1C034C5C0092A757 /* SynchronizedResolverSpec.swift */, 9884E2A91B60C51C00120259 /* ServiceKeySpec.swift */, 9855C5C71B689D9000DADB0B /* ServiceEntrySpec.swift */, @@ -649,7 +666,7 @@ children = ( 98B012B71B82D67300053A32 /* Container.Arguments.swift */, 984774F91C02F5A50092A757 /* SynchronizedResolver.Arguments.swift */, - 98B012BE1B82F68E00053A32 /* ResolverType.swift */, + 98B012BE1B82F68E00053A32 /* Resolver.swift */, ); name = GeneratedCode; sourceTree = ""; @@ -785,7 +802,7 @@ ); name = "Swinject-watchOS"; productName = "Swinject-watchOS"; - productReference = 985010C61BBE76D400A2CCFC /* Swinject.framework */; + productReference = 985010C61BBE76D400A2CCFC /* .framework */; productType = "com.apple.product-type.framework"; }; 98689C7E1BBFC7A50005C6D3 /* Swinject-tvOS */ = { @@ -1094,15 +1111,17 @@ 985BAFAA1B625E0F0055F998 /* ServiceEntry.swift in Sources */, 981577F51B676BF700BF686B /* ResolutionPool.swift in Sources */, 9880E70F1C09EE2900ED5293 /* FunctionType.swift in Sources */, - 98B012C01B82F68E00053A32 /* ResolverType.swift in Sources */, + 98B012C01B82F68E00053A32 /* Resolver.swift in Sources */, + CD3C2CE01D98E47000863421 /* DebugHelper.swift in Sources */, 90B0297A1C185B1600A6A521 /* Assembler.swift in Sources */, 90B029761C18599200A6A521 /* AssemblyType.swift in Sources */, 984774F11C02F25D0092A757 /* SynchronizedResolver.swift in Sources */, 981899E51B5FFE5800C702D0 /* Container.swift in Sources */, 98B012B91B82D67300053A32 /* Container.Arguments.swift in Sources */, 9884E2A81B60B77400120259 /* ServiceKey.swift in Sources */, - 984BE3141CDA3FCF00BCF2AC /* _ResolverType.swift in Sources */, + 984BE3141CDA3FCF00BCF2AC /* _Resolver.swift in Sources */, 981970201B6145D600EEB942 /* ObjectScope.swift in Sources */, + CDBBACF71D9EAD60002F5EF9 /* Container.Logging.swift in Sources */, 984774FB1C02F5A50092A757 /* SynchronizedResolver.Arguments.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1114,6 +1133,7 @@ 90B029841C18670000A6A521 /* BasicAssembly.swift in Sources */, 9855C5C61B689B7B00DADB0B /* FoodType.swift in Sources */, 9855C5C91B689D9000DADB0B /* ServiceEntrySpec.swift in Sources */, + CD3C2CF31D98EF4A00863421 /* ContainerSpec.DebugHelper.swift in Sources */, 984775001C034C5C0092A757 /* SynchronizedResolverSpec.swift in Sources */, 9848611D1B6F9B7000C07072 /* ContainerSpec.Arguments.swift in Sources */, 9878C63D1B65CA8700CBEFEF /* PersonType.swift in Sources */, @@ -1137,14 +1157,16 @@ 9880E70E1C09EE2900ED5293 /* FunctionType.swift in Sources */, 985BAFA91B625E0F0055F998 /* ServiceEntry.swift in Sources */, 984774F01C02F25D0092A757 /* SynchronizedResolver.swift in Sources */, + CD3C2CDF1D98E47000863421 /* DebugHelper.swift in Sources */, 981577F41B676BF700BF686B /* ResolutionPool.swift in Sources */, - 98B012BF1B82F68E00053A32 /* ResolverType.swift in Sources */, + 98B012BF1B82F68E00053A32 /* Resolver.swift in Sources */, 981899E41B5FFE5800C702D0 /* Container.swift in Sources */, 98B012B81B82D67300053A32 /* Container.Arguments.swift in Sources */, 9884E2A71B60B77400120259 /* ServiceKey.swift in Sources */, 9819701F1B6145D600EEB942 /* ObjectScope.swift in Sources */, - 984BE3131CDA3FCF00BCF2AC /* _ResolverType.swift in Sources */, + 984BE3131CDA3FCF00BCF2AC /* _Resolver.swift in Sources */, 984774FA1C02F5A50092A757 /* SynchronizedResolver.Arguments.swift in Sources */, + CDBBACF61D9EAD60002F5EF9 /* Container.Logging.swift in Sources */, 90B029751C18599200A6A521 /* AssemblyType.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1156,6 +1178,7 @@ 9855C5C51B689B7B00DADB0B /* FoodType.swift in Sources */, 9855C5C81B689D9000DADB0B /* ServiceEntrySpec.swift in Sources */, 9878C63C1B65CA8700CBEFEF /* PersonType.swift in Sources */, + CD3C2CF21D98EF4A00863421 /* ContainerSpec.DebugHelper.swift in Sources */, 90B0298B1C186D5300A6A521 /* LoadAwareAssembly.swift in Sources */, 9848611C1B6F9B7000C07072 /* ContainerSpec.Arguments.swift in Sources */, 90B0297F1C18666200A6A521 /* AssemblerSpec.swift in Sources */, @@ -1177,16 +1200,18 @@ 983B98331C06ECB2006A23D4 /* SpinLock.swift in Sources */, 9880E7101C09EE2900ED5293 /* FunctionType.swift in Sources */, 985011221BBE7E8900A2CCFC /* ObjectScope.swift in Sources */, - 985011251BBE7E8900A2CCFC /* ResolverType.swift in Sources */, + 985011251BBE7E8900A2CCFC /* Resolver.swift in Sources */, 9850111E1BBE7E8900A2CCFC /* Container.swift in Sources */, + CD3C2CE11D98E47000863421 /* DebugHelper.swift in Sources */, 985011211BBE7E8900A2CCFC /* ResolutionPool.swift in Sources */, 9850111F1BBE7E8900A2CCFC /* ServiceKey.swift in Sources */, 90B0297B1C185B1600A6A521 /* Assembler.swift in Sources */, 985011201BBE7E8900A2CCFC /* ServiceEntry.swift in Sources */, - 984BE3151CDA3FCF00BCF2AC /* _ResolverType.swift in Sources */, + 984BE3151CDA3FCF00BCF2AC /* _Resolver.swift in Sources */, 985011241BBE7E8900A2CCFC /* Container.Arguments.swift in Sources */, 984774F21C02F25D0092A757 /* SynchronizedResolver.swift in Sources */, 90B029771C18599200A6A521 /* AssemblyType.swift in Sources */, + CDBBACF81D9EAD60002F5EF9 /* Container.Logging.swift in Sources */, 984774FC1C02F5A50092A757 /* SynchronizedResolver.Arguments.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1200,14 +1225,16 @@ 9880E7111C09EE2900ED5293 /* FunctionType.swift in Sources */, 98689C9D1BBFC7EB0005C6D3 /* ObjectScope.swift in Sources */, 984774F31C02F25D0092A757 /* SynchronizedResolver.swift in Sources */, - 98689CA01BBFC7EB0005C6D3 /* ResolverType.swift in Sources */, + CD3C2CE21D98E47000863421 /* DebugHelper.swift in Sources */, + 98689CA01BBFC7EB0005C6D3 /* Resolver.swift in Sources */, 98689C991BBFC7EB0005C6D3 /* Container.swift in Sources */, 98689C9C1BBFC7EB0005C6D3 /* ResolutionPool.swift in Sources */, 98689C9A1BBFC7EB0005C6D3 /* ServiceKey.swift in Sources */, 90B0297C1C185B1600A6A521 /* Assembler.swift in Sources */, 98689C9B1BBFC7EB0005C6D3 /* ServiceEntry.swift in Sources */, - 984BE3161CDA3FCF00BCF2AC /* _ResolverType.swift in Sources */, + 984BE3161CDA3FCF00BCF2AC /* _Resolver.swift in Sources */, 98689C9F1BBFC7EB0005C6D3 /* Container.Arguments.swift in Sources */, + CDBBACF91D9EAD60002F5EF9 /* Container.Logging.swift in Sources */, 984774FD1C02F5A50092A757 /* SynchronizedResolver.Arguments.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1219,6 +1246,7 @@ 98689CBB1BBFD5110005C6D3 /* ContainerSpec.Arguments.swift in Sources */, 98689CBE1BBFD5110005C6D3 /* ServiceEntrySpec.swift in Sources */, 98689CBC1BBFD5110005C6D3 /* ContainerSpec.Circularity.swift in Sources */, + CD3C2CF41D98EF4A00863421 /* ContainerSpec.DebugHelper.swift in Sources */, 98689CB61BBFD5110005C6D3 /* PersonType.swift in Sources */, 90B0298D1C186D5300A6A521 /* LoadAwareAssembly.swift in Sources */, 98689CBA1BBFD5110005C6D3 /* ContainerSpec.swift in Sources */, diff --git a/Carthage/Checkouts/Swinject/Tests/Circularity.swift b/Carthage/Checkouts/Swinject/Tests/Circularity.swift index 194f171..cf6bbdc 100644 --- a/Carthage/Checkouts/Swinject/Tests/Circularity.swift +++ b/Carthage/Checkouts/Swinject/Tests/Circularity.swift @@ -9,32 +9,22 @@ import Foundation // MARK: Circular dependency of two objects -internal protocol ParentType: AnyObject {} -internal protocol ChildType: AnyObject {} +internal protocol ParentType: AnyObject { } +internal protocol ChildType: AnyObject { } internal class Parent: ParentType { - internal static var numberOfInstances: Int = 0 - var child: ChildType? init() { - Parent.numberOfInstances += 1 } init(child: ChildType) { self.child = child - Parent.numberOfInstances += 1 } } internal class Child: ChildType { - internal static var numberOfInstances: Int = 0 - weak var parent: ParentType? - - init() { - Child.numberOfInstances += 1 - } } // MARK: - Circular dependency of more than two objects diff --git a/Carthage/Checkouts/Swinject/Tests/ContainerSpec.Circularity.swift b/Carthage/Checkouts/Swinject/Tests/ContainerSpec.Circularity.swift index a27283a..6fc5000 100644 --- a/Carthage/Checkouts/Swinject/Tests/ContainerSpec.Circularity.swift +++ b/Carthage/Checkouts/Swinject/Tests/ContainerSpec.Circularity.swift @@ -64,29 +64,6 @@ class ContainerSpec_Circularity: QuickSpec { runInObjectScope(.container) runInObjectScope(.hierarchy) } - it("resolves circular dependency while intantiating each singleton object only once.") { - let runInObjectScope: (ObjectScope) -> Void = { scope in - container.removeAll() - Parent.numberOfInstances = 0 - Child.numberOfInstances = 0 - container.register(ParentType.self) { r in Parent(child: r.resolve(ChildType.self)!) } - .inObjectScope(scope) - container.register(ChildType.self) { _ in Child() } - .initCompleted { r, s in - let child = s as! Child - child.parent = r.resolve(ParentType.self) - } - .inObjectScope(scope) - - let _ = container.resolve(ParentType.self) - let _ = container.resolve(ChildType.self) - expect(Parent.numberOfInstances) == 1 - expect(Child.numberOfInstances) == 1 - } - - runInObjectScope(.container) - runInObjectScope(.hierarchy) - } } describe("More than two objects") { it("resolves circular dependency on properties.") { diff --git a/Carthage/Checkouts/Swinject/Tests/ContainerSpec.DebugHelper.swift b/Carthage/Checkouts/Swinject/Tests/ContainerSpec.DebugHelper.swift new file mode 100644 index 0000000..c9150a3 --- /dev/null +++ b/Carthage/Checkouts/Swinject/Tests/ContainerSpec.DebugHelper.swift @@ -0,0 +1,69 @@ +// +// ContainerSpec.DebugHelper.swift +// Swinject +// +// Created by Jakub Vaňo on 26/09/16. +// Copyright © 2016 Swinject Contributors. All rights reserved. +// + +import Quick +import Nimble +@testable import Swinject + +class ContainerSpec_DebugHelper: QuickSpec { + override func spec() { + var spy: DebugHelperSpy! + beforeEach { spy = DebugHelperSpy() } + + describe("resolution fails") { + it("should call debug helper with failing service and key") { + let container = Container(debugHelper: spy) + + let _ = container._resolve(name: "name") { (a: Int, b: Int) in return 1 as Double } + + expect("\(spy.serviceType)") == "Double" + expect(spy.key) == ServiceKey(factoryType: (Int, Int).self, name: "name", option: nil) + } + + it("should call helper with all registrations") { + let container = Container(debugHelper: spy) + container.register(Int.self) { _ in 0 } + container.register(Double.self) { _ in 0} + + let _ = container.resolve(String.self) + + expect(spy.availableRegistrations?.count) == 2 + } + + context("has parent container") { + it("should call helper with parent registrations") { + let parent = Container() + parent.register(Int.self) { _ in 0 } + let container = Container(parent: parent, debugHelper: spy) + container.register(Double.self) { _ in 0 } + + let _ = container.resolve(String.self) + + expect(spy.availableRegistrations?.count) == 2 + } + } + } + } +} + +private class DebugHelperSpy: DebugHelper { + + var serviceType: Any = "" + var key: ServiceKey? + var availableRegistrations: [ServiceKey : ServiceEntryType]? + + func resolutionFailed( + serviceType: Service.Type, + key: ServiceKey, + availableRegistrations: [ServiceKey : ServiceEntryType] + ) { + self.serviceType = serviceType + self.key = key + self.availableRegistrations = availableRegistrations + } +} diff --git a/Carthage/Checkouts/Swinject/Tests/ContainerSpec.swift b/Carthage/Checkouts/Swinject/Tests/ContainerSpec.swift index 601bc1e..780cdca 100644 --- a/Carthage/Checkouts/Swinject/Tests/ContainerSpec.swift +++ b/Carthage/Checkouts/Swinject/Tests/ContainerSpec.swift @@ -367,7 +367,7 @@ class ContainerSpec: QuickSpec { expect(container.description) == "[\n" - + " { Service: AnimalType, Factory: (ResolverType) -> AnimalType, ObjectScope: graph }\n" + + " { Service: AnimalType, Factory: (Resolver) -> AnimalType, ObjectScope: graph }\n" + "]" } it("describes a registration with name.") { @@ -375,7 +375,7 @@ class ContainerSpec: QuickSpec { expect(container.description) == "[\n" - + " { Service: AnimalType, Name: \"My Cat\", Factory: (ResolverType) -> AnimalType, ObjectScope: graph }\n" + + " { Service: AnimalType, Name: \"My Cat\", Factory: (Resolver) -> AnimalType, ObjectScope: graph }\n" + "]" } it("describes a registration with arguments.") { @@ -383,7 +383,7 @@ class ContainerSpec: QuickSpec { expect(container.description) == "[\n" - + " { Service: AnimalType, Factory: ((ResolverType, String, Bool)) -> AnimalType, ObjectScope: graph }\n" + + " { Service: AnimalType, Factory: ((Resolver, String, Bool)) -> AnimalType, ObjectScope: graph }\n" + "]" } it("describes a registration with a specified object scope.") { @@ -392,7 +392,7 @@ class ContainerSpec: QuickSpec { expect(container.description) == "[\n" - + " { Service: AnimalType, Factory: (ResolverType) -> AnimalType, ObjectScope: container }\n" + + " { Service: AnimalType, Factory: (Resolver) -> AnimalType, ObjectScope: container }\n" + "]" } it("describes a registration with initCompleted.") { @@ -401,7 +401,7 @@ class ContainerSpec: QuickSpec { expect(container.description) == "[\n" - + " { Service: AnimalType, Factory: (ResolverType) -> AnimalType, ObjectScope: graph, InitCompleted: Specified }\n" + + " { Service: AnimalType, Factory: (Resolver) -> AnimalType, ObjectScope: graph, InitCompleted: Specified }\n" + "]" } it("describes multiple registrations.") { @@ -410,8 +410,8 @@ class ContainerSpec: QuickSpec { expect(container.description) == "[\n" - + " { Service: AnimalType, Name: \"1\", Factory: (ResolverType) -> AnimalType, ObjectScope: graph },\n" - + " { Service: AnimalType, Name: \"2\", Factory: (ResolverType) -> AnimalType, ObjectScope: graph }\n" + + " { Service: AnimalType, Name: \"1\", Factory: (Resolver) -> AnimalType, ObjectScope: graph },\n" + + " { Service: AnimalType, Name: \"2\", Factory: (Resolver) -> AnimalType, ObjectScope: graph }\n" + "]" } } diff --git a/Carthage/Checkouts/Swinject/Tests/LoadAwareAssembly.swift b/Carthage/Checkouts/Swinject/Tests/LoadAwareAssembly.swift index 9094637..2d77b90 100644 --- a/Carthage/Checkouts/Swinject/Tests/LoadAwareAssembly.swift +++ b/Carthage/Checkouts/Swinject/Tests/LoadAwareAssembly.swift @@ -10,10 +10,10 @@ import Swinject class LoadAwareAssembly: AssemblyType { - var onLoad: (ResolverType) -> Void + var onLoad: (Resolver) -> Void var loaded = false - init(onLoad: @escaping (ResolverType) -> Void) { + init(onLoad: @escaping (Resolver) -> Void) { self.onLoad = onLoad } @@ -23,7 +23,7 @@ class LoadAwareAssembly: AssemblyType { } } - func loaded(resolver: ResolverType) { + func loaded(resolver: Resolver) { onLoad(resolver) loaded = true } diff --git a/Carthage/Checkouts/Swinject/Tests/ServiceKeySpec.swift b/Carthage/Checkouts/Swinject/Tests/ServiceKeySpec.swift index 593d9f5..db9d9d9 100644 --- a/Carthage/Checkouts/Swinject/Tests/ServiceKeySpec.swift +++ b/Carthage/Checkouts/Swinject/Tests/ServiceKeySpec.swift @@ -36,36 +36,36 @@ class ServiceKeySpec: QuickSpec { override func spec() { describe("Without name") { it("equals with the same factory type.") { - typealias FactoryType0Args = (ResolverType) -> AnimalType + typealias FactoryType0Args = (Resolver) -> AnimalType let key1 = ServiceKey(factoryType: FactoryType0Args.self) let key2 = ServiceKey(factoryType: FactoryType0Args.self) expect(key1) == key2 expect(key1.hashValue) == key2.hashValue - typealias FactoryType2Args = (ResolverType, String, Bool) -> AnimalType + typealias FactoryType2Args = (Resolver, String, Bool) -> AnimalType let key3 = ServiceKey(factoryType: FactoryType2Args.self) let key4 = ServiceKey(factoryType: FactoryType2Args.self) expect(key3) == key4 expect(key3.hashValue) == key4.hashValue } it("does not equal with different service types in factory types.") { - typealias PersonFactoryType = (ResolverType) -> PersonType - typealias AnimalFactoryType = (ResolverType) -> AnimalType + typealias PersonFactoryType = (Resolver) -> PersonType + typealias AnimalFactoryType = (Resolver) -> AnimalType let key1 = ServiceKey(factoryType: PersonFactoryType.self) let key2 = ServiceKey(factoryType: AnimalFactoryType.self) expect(key1) != key2 expect(key1.hashValue) != key2.hashValue } it("does not equal with different arg types in factory types.") { - typealias FactoryType1Arg = (ResolverType, String) -> AnimalType - typealias FactoryType2Args = (ResolverType, String, Bool) -> AnimalType + typealias FactoryType1Arg = (Resolver, String) -> AnimalType + typealias FactoryType2Args = (Resolver, String, Bool) -> AnimalType let key1 = ServiceKey(factoryType: FactoryType1Arg.self) let key2 = ServiceKey(factoryType: FactoryType2Args.self) expect(key1) != key2 expect(key1.hashValue) != key2.hashValue - typealias FactoryTypeStringBoolArgs = (ResolverType, String, Bool) -> AnimalType - typealias FactoryTypeStringIntArgs = (ResolverType, String, Int) -> AnimalType + typealias FactoryTypeStringBoolArgs = (Resolver, String, Bool) -> AnimalType + typealias FactoryTypeStringIntArgs = (Resolver, String, Int) -> AnimalType let key3 = ServiceKey(factoryType: FactoryTypeStringBoolArgs.self) let key4 = ServiceKey(factoryType: FactoryTypeStringIntArgs.self) expect(key3) != key4 @@ -74,26 +74,26 @@ class ServiceKeySpec: QuickSpec { } describe("With name") { it("equals with the same name.") { - typealias FactoryType0Args = (ResolverType) -> AnimalType + typealias FactoryType0Args = (Resolver) -> AnimalType let key1 = ServiceKey(factoryType: FactoryType0Args.self, name: "my factory") let key2 = ServiceKey(factoryType: FactoryType0Args.self, name: "my factory") expect(key1) == key2 expect(key1.hashValue) == key2.hashValue - typealias FactoryType2Args = (ResolverType, String, Bool) -> AnimalType + typealias FactoryType2Args = (Resolver, String, Bool) -> AnimalType let key3 = ServiceKey(factoryType: FactoryType2Args.self, name: "my factory") let key4 = ServiceKey(factoryType: FactoryType2Args.self, name: "my factory") expect(key3) == key4 expect(key3.hashValue) == key4.hashValue } it("does not equal with different names.") { - typealias FactoryType0Args = (ResolverType) -> AnimalType + typealias FactoryType0Args = (Resolver) -> AnimalType let key1 = ServiceKey(factoryType: FactoryType0Args.self, name: "my factory") let key2 = ServiceKey(factoryType: FactoryType0Args.self, name: "your factory") expect(key1) != key2 expect(key1.hashValue) != key2.hashValue - typealias FactoryType2Args = (ResolverType, String, Bool) -> AnimalType + typealias FactoryType2Args = (Resolver, String, Bool) -> AnimalType let key3 = ServiceKey(factoryType: FactoryType2Args.self, name: "my factory") let key4 = ServiceKey(factoryType: FactoryType2Args.self, name: "your factory") expect(key3) != key4 @@ -102,26 +102,26 @@ class ServiceKeySpec: QuickSpec { } describe("With option") { it("equals with the same option.") { - typealias FactoryType0Args = (ResolverType) -> AnimalType + typealias FactoryType0Args = (Resolver) -> AnimalType let key1 = ServiceKey(factoryType: FactoryType0Args.self, option: Option(option: 1)) let key2 = ServiceKey(factoryType: FactoryType0Args.self, option: Option(option: 1)) expect(key1) == key2 expect(key1.hashValue) == key2.hashValue - typealias FactoryType2Args = (ResolverType, String, Bool) -> AnimalType + typealias FactoryType2Args = (Resolver, String, Bool) -> AnimalType let key3 = ServiceKey(factoryType: FactoryType2Args.self, option: Option(option: 1)) let key4 = ServiceKey(factoryType: FactoryType2Args.self, option: Option(option: 1)) expect(key3) == key4 expect(key3.hashValue) == key4.hashValue } it("does not equal with different options.") { - typealias FactoryType0Args = (ResolverType) -> AnimalType + typealias FactoryType0Args = (Resolver) -> AnimalType let key1 = ServiceKey(factoryType: FactoryType0Args.self, option: Option(option: 1)) let key2 = ServiceKey(factoryType: FactoryType0Args.self, option: Option(option: 2)) expect(key1) != key2 expect(key1.hashValue) != key2.hashValue - typealias FactoryType2Args = (ResolverType, String, Bool) -> AnimalType + typealias FactoryType2Args = (Resolver, String, Bool) -> AnimalType let key3 = ServiceKey(factoryType: FactoryType2Args.self, option: Option(option: 1)) let key4 = ServiceKey(factoryType: FactoryType2Args.self, option: Option(option: 2)) expect(key3) != key4 diff --git a/Carthage/Checkouts/Swinject/script/gencode b/Carthage/Checkouts/Swinject/script/gencode index cb06a51..b7224f0 100755 --- a/Carthage/Checkouts/Swinject/script/gencode +++ b/Carthage/Checkouts/Swinject/script/gencode @@ -1,6 +1,6 @@ #!/bin/sh -files="Sources/Container.Arguments Sources/SynchronizedResolver.Arguments Sources/ResolverType" +files="Sources/Container.Arguments Sources/SynchronizedResolver.Arguments Sources/Resolver" for file in $files; do echo "Generating code to $file.swift" From 1af3d7c5a549019285ce5d773fb18844f63c3c7c Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Tue, 25 Oct 2016 15:34:00 +0200 Subject: [PATCH 04/23] Updated ResolverType to Resolver --- Sources/AutoRegistration.swift | 70 +++++++++++++++++----------------- Sources/Operators.swift | 18 ++++----- bin/generate | 4 +- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/Sources/AutoRegistration.swift b/Sources/AutoRegistration.swift index 1871a73..9c3693d 100644 --- a/Sources/AutoRegistration.swift +++ b/Sources/AutoRegistration.swift @@ -26,7 +26,7 @@ extension Container { public func autoregister(_ service: Service.Type, name: String? = nil, initializer: @escaping () -> Service) -> ServiceEntry { return self.register(service.self, name: name, factory: { r in initializer() - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -46,7 +46,7 @@ public func autoregister(_ service: Service.Type, name: String? = ni let a: A? = r.resolve() checkResolved(initializer: initializer, services: a) return initializer(a!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -66,7 +66,7 @@ public func autoregister(_ service: Service.Type, name: String? = let arg1: Arg1? = arg1 checkResolved(initializer: initializer, services: arg1) return initializer(arg1!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -86,7 +86,7 @@ public func autoregister(_ service: Service.Type, name: String? = let a: A? = r.resolve(); let b: B? = r.resolve() checkResolved(initializer: initializer, services: a, b) return initializer(a!, b!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -106,7 +106,7 @@ public func autoregister(_ service: Service.Type, name: Str let a: A? = r.resolve(argument: arg1); let b: B? = r.resolve(argument: arg1) checkResolved(initializer: initializer, services: a, b) return initializer(a!, b!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -126,7 +126,7 @@ public func autoregister(_ service: Service.Type, nam let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b) return initializer(a!, b!) - } as (ResolverType, Arg1, Arg2) -> Service) + } as (Resolver, Arg1, Arg2) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -146,7 +146,7 @@ public func autoregister(_ service: Service.Type, name: String let a: A? = r.resolve(); let b: B? = r.resolve(); let c: C? = r.resolve() checkResolved(initializer: initializer, services: a, b, c) return initializer(a!, b!, c!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -166,7 +166,7 @@ public func autoregister(_ service: Service.Type, name: let a: A? = r.resolve(argument: arg1); let b: B? = r.resolve(argument: arg1); let c: C? = r.resolve(argument: arg1) checkResolved(initializer: initializer, services: a, b, c) return initializer(a!, b!, c!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -186,7 +186,7 @@ public func autoregister(_ service: Service.Type, let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c) return initializer(a!, b!, c!) - } as (ResolverType, Arg1, Arg2) -> Service) + } as (Resolver, Arg1, Arg2) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -206,7 +206,7 @@ public func autoregister(_ service: Service. let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c) return initializer(a!, b!, c!) - } as (ResolverType, Arg1, Arg2, Arg3) -> Service) + } as (Resolver, Arg1, Arg2, Arg3) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -226,7 +226,7 @@ public func autoregister(_ service: Service.Type, name: Str let a: A? = r.resolve(); let b: B? = r.resolve(); let c: C? = r.resolve(); let d: D? = r.resolve() checkResolved(initializer: initializer, services: a, b, c, d) return initializer(a!, b!, c!, d!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -246,7 +246,7 @@ public func autoregister(_ service: Service.Type, nam let a: A? = r.resolve(argument: arg1); let b: B? = r.resolve(argument: arg1); let c: C? = r.resolve(argument: arg1); let d: D? = r.resolve(argument: arg1) checkResolved(initializer: initializer, services: a, b, c, d) return initializer(a!, b!, c!, d!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -266,7 +266,7 @@ public func autoregister(_ service: Service.Typ let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d) return initializer(a!, b!, c!, d!) - } as (ResolverType, Arg1, Arg2) -> Service) + } as (Resolver, Arg1, Arg2) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -286,7 +286,7 @@ public func autoregister(_ service: Servi let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d) return initializer(a!, b!, c!, d!) - } as (ResolverType, Arg1, Arg2, Arg3) -> Service) + } as (Resolver, Arg1, Arg2, Arg3) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -306,7 +306,7 @@ public func autoregister(_ service: Service.Type, name: let a: A? = r.resolve(); let b: B? = r.resolve(); let c: C? = r.resolve(); let d: D? = r.resolve(); let e: E? = r.resolve() checkResolved(initializer: initializer, services: a, b, c, d, e) return initializer(a!, b!, c!, d!, e!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -326,7 +326,7 @@ public func autoregister(_ service: Service.Type, let a: A? = r.resolve(argument: arg1); let b: B? = r.resolve(argument: arg1); let c: C? = r.resolve(argument: arg1); let d: D? = r.resolve(argument: arg1); let e: E? = r.resolve(argument: arg1) checkResolved(initializer: initializer, services: a, b, c, d, e) return initializer(a!, b!, c!, d!, e!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -346,7 +346,7 @@ public func autoregister(_ service: Service. let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e) return initializer(a!, b!, c!, d!, e!) - } as (ResolverType, Arg1, Arg2) -> Service) + } as (Resolver, Arg1, Arg2) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -366,7 +366,7 @@ public func autoregister(_ service: Se let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e) return initializer(a!, b!, c!, d!, e!) - } as (ResolverType, Arg1, Arg2, Arg3) -> Service) + } as (Resolver, Arg1, Arg2, Arg3) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -386,7 +386,7 @@ public func autoregister(_ service: Service.Type, nam let a: A? = r.resolve(); let b: B? = r.resolve(); let c: C? = r.resolve(); let d: D? = r.resolve(); let e: E? = r.resolve(); let f: F? = r.resolve() checkResolved(initializer: initializer, services: a, b, c, d, e, f) return initializer(a!, b!, c!, d!, e!, f!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -406,7 +406,7 @@ public func autoregister(_ service: Service.Typ let a: A? = r.resolve(argument: arg1); let b: B? = r.resolve(argument: arg1); let c: C? = r.resolve(argument: arg1); let d: D? = r.resolve(argument: arg1); let e: E? = r.resolve(argument: arg1); let f: F? = r.resolve(argument: arg1) checkResolved(initializer: initializer, services: a, b, c, d, e, f) return initializer(a!, b!, c!, d!, e!, f!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -426,7 +426,7 @@ public func autoregister(_ service: Servi let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f) return initializer(a!, b!, c!, d!, e!, f!) - } as (ResolverType, Arg1, Arg2) -> Service) + } as (Resolver, Arg1, Arg2) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -446,7 +446,7 @@ public func autoregister(_ service: let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f) return initializer(a!, b!, c!, d!, e!, f!) - } as (ResolverType, Arg1, Arg2, Arg3) -> Service) + } as (Resolver, Arg1, Arg2, Arg3) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -466,7 +466,7 @@ public func autoregister(_ service: Service.Type, let a: A? = r.resolve(); let b: B? = r.resolve(); let c: C? = r.resolve(); let d: D? = r.resolve(); let e: E? = r.resolve(); let f: F? = r.resolve(); let g: G? = r.resolve() checkResolved(initializer: initializer, services: a, b, c, d, e, f, g) return initializer(a!, b!, c!, d!, e!, f!, g!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -486,7 +486,7 @@ public func autoregister(_ service: Service. let a: A? = r.resolve(argument: arg1); let b: B? = r.resolve(argument: arg1); let c: C? = r.resolve(argument: arg1); let d: D? = r.resolve(argument: arg1); let e: E? = r.resolve(argument: arg1); let f: F? = r.resolve(argument: arg1); let g: G? = r.resolve(argument: arg1) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g) return initializer(a!, b!, c!, d!, e!, f!, g!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -506,7 +506,7 @@ public func autoregister(_ service: Se let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g) return initializer(a!, b!, c!, d!, e!, f!, g!) - } as (ResolverType, Arg1, Arg2) -> Service) + } as (Resolver, Arg1, Arg2) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -526,7 +526,7 @@ public func autoregister(_ servi let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g) return initializer(a!, b!, c!, d!, e!, f!, g!) - } as (ResolverType, Arg1, Arg2, Arg3) -> Service) + } as (Resolver, Arg1, Arg2, Arg3) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -546,7 +546,7 @@ public func autoregister(_ service: Service.Typ let a: A? = r.resolve(); let b: B? = r.resolve(); let c: C? = r.resolve(); let d: D? = r.resolve(); let e: E? = r.resolve(); let f: F? = r.resolve(); let g: G? = r.resolve(); let h: H? = r.resolve() checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h) return initializer(a!, b!, c!, d!, e!, f!, g!, h!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -566,7 +566,7 @@ public func autoregister(_ service: Servi let a: A? = r.resolve(argument: arg1); let b: B? = r.resolve(argument: arg1); let c: C? = r.resolve(argument: arg1); let d: D? = r.resolve(argument: arg1); let e: E? = r.resolve(argument: arg1); let f: F? = r.resolve(argument: arg1); let g: G? = r.resolve(argument: arg1); let h: H? = r.resolve(argument: arg1) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h) return initializer(a!, b!, c!, d!, e!, f!, g!, h!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -586,7 +586,7 @@ public func autoregister(_ service: let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2); let h: H? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h) return initializer(a!, b!, c!, d!, e!, f!, g!, h!) - } as (ResolverType, Arg1, Arg2) -> Service) + } as (Resolver, Arg1, Arg2) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -606,7 +606,7 @@ public func autoregister(_ se let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3); let h: H? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h) return initializer(a!, b!, c!, d!, e!, f!, g!, h!) - } as (ResolverType, Arg1, Arg2, Arg3) -> Service) + } as (Resolver, Arg1, Arg2, Arg3) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -626,7 +626,7 @@ public func autoregister(_ service: Service. let a: A? = r.resolve(); let b: B? = r.resolve(); let c: C? = r.resolve(); let d: D? = r.resolve(); let e: E? = r.resolve(); let f: F? = r.resolve(); let g: G? = r.resolve(); let h: H? = r.resolve(); let i: I? = r.resolve() checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h, i) return initializer(a!, b!, c!, d!, e!, f!, g!, h!, i!) - } as (ResolverType) -> Service) + } as (Resolver) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -646,7 +646,7 @@ public func autoregister(_ service: Se let a: A? = r.resolve(argument: arg1); let b: B? = r.resolve(argument: arg1); let c: C? = r.resolve(argument: arg1); let d: D? = r.resolve(argument: arg1); let e: E? = r.resolve(argument: arg1); let f: F? = r.resolve(argument: arg1); let g: G? = r.resolve(argument: arg1); let h: H? = r.resolve(argument: arg1); let i: I? = r.resolve(argument: arg1) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h, i) return initializer(a!, b!, c!, d!, e!, f!, g!, h!, i!) - } as (ResolverType, Arg1) -> Service) + } as (Resolver, Arg1) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -666,7 +666,7 @@ public func autoregister(_ servi let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2); let h: H? = r.resolve(arguments: arg1, arg2); let i: I? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h, i) return initializer(a!, b!, c!, d!, e!, f!, g!, h!, i!) - } as (ResolverType, Arg1, Arg2) -> Service) + } as (Resolver, Arg1, Arg2) -> Service) } /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -686,12 +686,12 @@ public func autoregister(_ let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3); let h: H? = r.resolve(arguments: arg1, arg2, arg3); let i: I? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h, i) return initializer(a!, b!, c!, d!, e!, f!, g!, h!, i!) - } as (ResolverType, Arg1, Arg2, Arg3) -> Service) + } as (Resolver, Arg1, Arg2, Arg3) -> Service) } } -public extension ResolverType { +public extension Resolver { fileprivate func resolve() -> Service? { diff --git a/Sources/Operators.swift b/Sources/Operators.swift index ab4ad4e..9fbc026 100644 --- a/Sources/Operators.swift +++ b/Sources/Operators.swift @@ -20,7 +20,7 @@ postfix operator ~> - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public postfix func ~> (r: ResolverType) -> Service { +public postfix func ~> (r: Resolver) -> Service { return r.resolve(Service.self)! } @@ -34,7 +34,7 @@ public postfix func ~> (r: ResolverType) -> Service { - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public func ~> (r: ResolverType, service: Service.Type) -> Service { +public func ~> (r: Resolver, service: Service.Type) -> Service { return r.resolve(service)! } @@ -48,7 +48,7 @@ public func ~> (r: ResolverType, service: Service.Type) -> Service { - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public func ~> (r: ResolverType, o: (service: Service.Type, name: String)) -> Service { +public func ~> (r: Resolver, o: (service: Service.Type, name: String)) -> Service { return r.resolve(o.service, name: o.name)! } @@ -63,7 +63,7 @@ public func ~> (r: ResolverType, o: (service: Service.Type, name: Strin - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public func ~> (r: ResolverType, o: (service: Service.Type, argument: Arg1) ) -> Service { +public func ~> (r: Resolver, o: (service: Service.Type, argument: Arg1) ) -> Service { return r.resolve(o.service, argument: o.argument)! } @@ -78,7 +78,7 @@ public func ~> (r: ResolverType, o: (service: Service.Type, argum - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public func ~> (r: ResolverType, o: (service: Service.Type, name: String, argument: Arg1) ) -> Service { +public func ~> (r: Resolver, o: (service: Service.Type, name: String, argument: Arg1) ) -> Service { return r.resolve(o.service, name: o.name, argument: o.argument)! } @@ -93,7 +93,7 @@ public func ~> (r: ResolverType, o: (service: Service.Type, name: - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public func ~> (r: ResolverType, o: (Service.Type, arguments: Arg1, Arg2) ) -> Service { +public func ~> (r: Resolver, o: (Service.Type, arguments: Arg1, Arg2) ) -> Service { return r.resolve(o.0, arguments: 0.1, 0.2)! } @@ -109,7 +109,7 @@ public func ~> (r: ResolverType, o: (Service.Type, argument - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public func ~> (r: ResolverType, o: (Service.Type, name: String, arguments: Arg1, Arg2) ) -> Service { +public func ~> (r: Resolver, o: (Service.Type, name: String, arguments: Arg1, Arg2) ) -> Service { return r.resolve(o.0, name: o.1, arguments: o.2, o.3)! } @@ -125,7 +125,7 @@ public func ~> (r: ResolverType, o: (Service.Type, name: St - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public func ~> (r: ResolverType, o: (Service.Type, arguments: Arg1, Arg2, Arg3) ) -> Service { +public func ~> (r: Resolver, o: (Service.Type, arguments: Arg1, Arg2, Arg3) ) -> Service { return r.resolve(o.0, arguments: o.1, o.2, o.3)! } @@ -140,6 +140,6 @@ public func ~> (r: ResolverType, o: (Service.Type, ar - Returns: The resolved service type instance. - Important: Fails on unresolvable service. */ -public func ~> (r: ResolverType, o: (Service.Type, name: String, arguments: Arg1, Arg2, Arg3) ) -> Service { +public func ~> (r: Resolver, o: (Service.Type, name: String, arguments: Arg1, Arg2, Arg3) ) -> Service { return r.resolve(o.0, name: o.1, arguments: o.2, o.3, o.4)! } diff --git a/bin/generate b/bin/generate index 66a78a0..d5b22c2 100755 --- a/bin/generate +++ b/bin/generate @@ -99,7 +99,7 @@ func registerGenerator(_ dependenciesCount: Int, argumentsCount: Int, breakIntoV "public func autoregister<\(genericsDefinition)>(_ service: Service.Type, name: String? = nil\(argumentsDefinition), initializer: @escaping (\(concatenatedParameters)) -> Service) -> ServiceEntry {", " return self.register(service.self, name: name, factory: { \(closureParameters) in ", initializer, - " } as (\(commaConcat(["ResolverType"] + genericArguments))) -> Service)", + " } as (\(commaConcat(["Resolver"] + genericArguments))) -> Service)", "}" ] @@ -183,7 +183,7 @@ var output = [ "extension Container {\n", registers.joined(separator: "\n\n"), "\n\n}", - "public extension ResolverType {\n\n", + "public extension Resolver {\n\n", resolvers.joined(separator: "\n\n"), "}\n\n", checks.joined(separator: "\n\n") From c963bc4d92d061faed32a44fc0a262000cd7d77a Mon Sep 17 00:00:00 2001 From: Nikolay Kostyurin Date: Wed, 18 Jan 2017 20:52:18 +0200 Subject: [PATCH 05/23] swift pm support --- Package.swift | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 Package.swift diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..6aebe29 --- /dev/null +++ b/Package.swift @@ -0,0 +1,8 @@ +import PackageDescription + +let package = Package( + name: "SwinjectAutoregistration", + dependencies: [ + .Package(url: "https://github.com/Swinject/Swinject.git", majorVersion: 2) + ] +) \ No newline at end of file From c3708981163bc03aabaa0cfa6f5c42bb074c818d Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Wed, 18 Jan 2017 23:55:47 +0100 Subject: [PATCH 06/23] Added message when trying to resolve Optional dependency. Refactored into separated files --- Sources/AutoRegistration.swift | 126 +------------- Sources/CheckResolved.swift | 155 ++++++++++++++++++ Sources/Helpers.swift | 20 +++ Sources/Resolver.swift | 32 ++++ .../project.pbxproj | 38 +++++ Tests/OptionalTests.swift | 70 ++++++++ Tests/Tests.swift | 10 +- bin/generate | 86 ++++++---- 8 files changed, 382 insertions(+), 155 deletions(-) create mode 100644 Sources/CheckResolved.swift create mode 100644 Sources/Helpers.swift create mode 100644 Sources/Resolver.swift create mode 100644 Tests/OptionalTests.swift diff --git a/Sources/AutoRegistration.swift b/Sources/AutoRegistration.swift index 1871a73..e322d0e 100644 --- a/Sources/AutoRegistration.swift +++ b/Sources/AutoRegistration.swift @@ -1,15 +1,16 @@ // // Sources/AutoRegistration.swift -// Swinject +// SwinjectAutoregistration // -// Generated using Swinject AutoRegistration generator. +// Generated by Swinject AutoRegistration generator. +// Copyright © 2017 Swinject Contributors. All rights reserved. // import Swinject -extension Container { +public extension Container { /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. @@ -690,123 +691,4 @@ public func autoregister(_ } -} -public extension ResolverType { - - - fileprivate func resolve() -> Service? { - return self.resolve(Service.self) - } - - fileprivate func resolve(argument arg1: Arg1) -> Service? { - return (arg1 as? Service) ?? self.resolve(Service.self) - } - - fileprivate func resolve(arguments arg1: Arg1, _ arg2: Arg2) -> Service? { - return (arg1 as? Service) ?? (arg2 as? Service) ?? self.resolve(Service.self) - } - - fileprivate func resolve(arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3) -> Service? { - return (arg1 as? Service) ?? (arg2 as? Service) ?? (arg3 as? Service) ?? self.resolve(Service.self) - } -} - - -fileprivate func unresolvedService(_ a: A?) -> String? { - return ( a == nil ? "\(A.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A) -> Service, services a: A?){ - let unresolved = ( [a] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a)!), initializer: (\(A.self)) -> \(Service.self)") - } -} - -fileprivate func unresolvedService(_ a: A?, _ b: B?) -> String? { - return unresolvedService(a) ?? ( b == nil ? "\(B.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A, B) -> Service, services a: A?, _ b: B?){ - let unresolved = ( [a, b] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a, b)!), initializer: (\(A.self), \(B.self)) -> \(Service.self)") - } -} - -fileprivate func unresolvedService(_ a: A?, _ b: B?, _ c: C?) -> String? { - return unresolvedService(a, b) ?? ( c == nil ? "\(C.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A, B, C) -> Service, services a: A?, _ b: B?, _ c: C?){ - let unresolved = ( [a, b, c] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a, b, c)!), initializer: (\(A.self), \(B.self), \(C.self)) -> \(Service.self)") - } -} - -fileprivate func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?) -> String? { - return unresolvedService(a, b, c) ?? ( d == nil ? "\(D.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A, B, C, D) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?){ - let unresolved = ( [a, b, c, d] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a, b, c, d)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self)) -> \(Service.self)") - } -} - -fileprivate func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?) -> String? { - return unresolvedService(a, b, c, d) ?? ( e == nil ? "\(E.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A, B, C, D, E) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?){ - let unresolved = ( [a, b, c, d, e] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a, b, c, d, e)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self)) -> \(Service.self)") - } -} - -fileprivate func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?) -> String? { - return unresolvedService(a, b, c, d, e) ?? ( f == nil ? "\(F.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A, B, C, D, E, F) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?){ - let unresolved = ( [a, b, c, d, e, f] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a, b, c, d, e, f)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self)) -> \(Service.self)") - } -} - -fileprivate func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?) -> String? { - return unresolvedService(a, b, c, d, e, f) ?? ( g == nil ? "\(G.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A, B, C, D, E, F, G) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?){ - let unresolved = ( [a, b, c, d, e, f, g] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a, b, c, d, e, f, g)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self)) -> \(Service.self)") - } -} - -fileprivate func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?) -> String? { - return unresolvedService(a, b, c, d, e, f, g) ?? ( h == nil ? "\(H.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A, B, C, D, E, F, G, H) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?){ - let unresolved = ( [a, b, c, d, e, f, g, h] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a, b, c, d, e, f, g, h)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self)) -> \(Service.self)") - } -} - -fileprivate func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?, _ i: I?) -> String? { - return unresolvedService(a, b, c, d, e, f, g, h) ?? ( i == nil ? "\(I.self)" : nil ) -} - -fileprivate func checkResolved(initializer: (A, B, C, D, E, F, G, H, I) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?, _ i: I?){ - let unresolved = ( [a, b, c, d, e, f, g, h, i] as [Any?] ).filter { $0 == nil } - if unresolved.count > 0 { - fatalError("Failed to resolve \(unresolvedService(a, b, c, d, e, f, g, h, i)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self), \(I.self)) -> \(Service.self)") - } } \ No newline at end of file diff --git a/Sources/CheckResolved.swift b/Sources/CheckResolved.swift new file mode 100644 index 0000000..b596578 --- /dev/null +++ b/Sources/CheckResolved.swift @@ -0,0 +1,155 @@ +// +// Sources/CheckResolved.swift +// SwinjectAutoregistration +// +// Generated by Swinject AutoRegistration generator. +// Copyright © 2017 Swinject Contributors. All rights reserved. +// + + + import Swinject + + +func unresolvedService(_ a: A?) -> String? { + return ( a == nil ? "\(A.self)" : nil ) +} + +func optionalService(_ a: A?) -> String? { + return (isOptional(A.self) ? "\(A.self)" : nil ) +} + +func checkResolved(initializer: (A) -> Service, services a: A?){ + let unresolved = ( [a] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a))!), initializer: (\(A.self)) -> \(Service.self)") + } +} + +func unresolvedService(_ a: A?, _ b: B?) -> String? { + return unresolvedService(a) ?? ( b == nil ? "\(B.self)" : nil ) +} + +func optionalService(_ a: A?, _ b: B?) -> String? { + return optionalService(a) ?? (isOptional(B.self) ? "\(B.self)" : nil ) +} + +func checkResolved(initializer: (A, B) -> Service, services a: A?, _ b: B?){ + let unresolved = ( [a, b] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a, b).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a, b))!), initializer: (\(A.self), \(B.self)) -> \(Service.self)") + } +} + +func unresolvedService(_ a: A?, _ b: B?, _ c: C?) -> String? { + return unresolvedService(a, b) ?? ( c == nil ? "\(C.self)" : nil ) +} + +func optionalService(_ a: A?, _ b: B?, _ c: C?) -> String? { + return optionalService(a, b) ?? (isOptional(C.self) ? "\(C.self)" : nil ) +} + +func checkResolved(initializer: (A, B, C) -> Service, services a: A?, _ b: B?, _ c: C?){ + let unresolved = ( [a, b, c] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a, b, c).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c))!), initializer: (\(A.self), \(B.self), \(C.self)) -> \(Service.self)") + } +} + +func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?) -> String? { + return unresolvedService(a, b, c) ?? ( d == nil ? "\(D.self)" : nil ) +} + +func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?) -> String? { + return optionalService(a, b, c) ?? (isOptional(D.self) ? "\(D.self)" : nil ) +} + +func checkResolved(initializer: (A, B, C, D) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?){ + let unresolved = ( [a, b, c, d] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a, b, c, d).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self)) -> \(Service.self)") + } +} + +func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?) -> String? { + return unresolvedService(a, b, c, d) ?? ( e == nil ? "\(E.self)" : nil ) +} + +func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?) -> String? { + return optionalService(a, b, c, d) ?? (isOptional(E.self) ? "\(E.self)" : nil ) +} + +func checkResolved(initializer: (A, B, C, D, E) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?){ + let unresolved = ( [a, b, c, d, e] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a, b, c, d, e).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self)) -> \(Service.self)") + } +} + +func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?) -> String? { + return unresolvedService(a, b, c, d, e) ?? ( f == nil ? "\(F.self)" : nil ) +} + +func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?) -> String? { + return optionalService(a, b, c, d, e) ?? (isOptional(F.self) ? "\(F.self)" : nil ) +} + +func checkResolved(initializer: (A, B, C, D, E, F) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?){ + let unresolved = ( [a, b, c, d, e, f] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a, b, c, d, e, f).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e, f))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self)) -> \(Service.self)") + } +} + +func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?) -> String? { + return unresolvedService(a, b, c, d, e, f) ?? ( g == nil ? "\(G.self)" : nil ) +} + +func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?) -> String? { + return optionalService(a, b, c, d, e, f) ?? (isOptional(G.self) ? "\(G.self)" : nil ) +} + +func checkResolved(initializer: (A, B, C, D, E, F, G) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?){ + let unresolved = ( [a, b, c, d, e, f, g] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a, b, c, d, e, f, g).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self)) -> \(Service.self)") + } +} + +func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?) -> String? { + return unresolvedService(a, b, c, d, e, f, g) ?? ( h == nil ? "\(H.self)" : nil ) +} + +func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?) -> String? { + return optionalService(a, b, c, d, e, f, g) ?? (isOptional(H.self) ? "\(H.self)" : nil ) +} + +func checkResolved(initializer: (A, B, C, D, E, F, G, H) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?){ + let unresolved = ( [a, b, c, d, e, f, g, h] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a, b, c, d, e, f, g, h).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g, h))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self)) -> \(Service.self)") + } +} + +func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?, _ i: I?) -> String? { + return unresolvedService(a, b, c, d, e, f, g, h) ?? ( i == nil ? "\(I.self)" : nil ) +} + +func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?, _ i: I?) -> String? { + return optionalService(a, b, c, d, e, f, g, h) ?? (isOptional(I.self) ? "\(I.self)" : nil ) +} + +func checkResolved(initializer: (A, B, C, D, E, F, G, H, I) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?, _ i: I?){ + let unresolved = ( [a, b, c, d, e, f, g, h, i] as [Any?] ).filter { $0 == nil } + if unresolved.count > 0 { + let optional = optionalService(a, b, c, d, e, f, g, h, i).flatMap { optionalMessage($0) } ?? "" + fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g, h, i))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self), \(I.self)) -> \(Service.self)") + } +} \ No newline at end of file diff --git a/Sources/Helpers.swift b/Sources/Helpers.swift new file mode 100644 index 0000000..c30ea0d --- /dev/null +++ b/Sources/Helpers.swift @@ -0,0 +1,20 @@ +// +// Helpers.swift +// SwinjectAutoregistration +// +// Created by Tomas Kohout on 18/01/2017. +// Copyright © 2017 Swinject Contributors. All rights reserved. +// + +import Foundation + +var optionalCheckRegex = try! NSRegularExpression(pattern: "^Optional<.*>$", options: []) + +var optionalMessage:(String)->String = { _ in "AutoRegistration for services with optional dependencies is not supported. Split to multiple initializers or use regular `register` method. " } + +//Check whether a type is optional by converting it to a string and matching it with regular expression + +func isOptional(_ service: Any) -> Bool { + let serviceType = String(describing: service.self) + return optionalCheckRegex.firstMatch(in: serviceType, options: [], range: NSMakeRange(0, serviceType.characters.count)) != nil +} diff --git a/Sources/Resolver.swift b/Sources/Resolver.swift new file mode 100644 index 0000000..6518740 --- /dev/null +++ b/Sources/Resolver.swift @@ -0,0 +1,32 @@ +// +// Sources/Resolver.swift +// SwinjectAutoregistration +// +// Generated by Swinject AutoRegistration generator. +// Copyright © 2017 Swinject Contributors. All rights reserved. +// + + + import Swinject + + +extension ResolverType { + + + func resolve() -> Service? { + return self.resolve(Service.self) + } + + func resolve(argument arg1: Arg1) -> Service? { + return (arg1 as? Service) ?? self.resolve(Service.self) + } + + func resolve(arguments arg1: Arg1, _ arg2: Arg2) -> Service? { + return (arg1 as? Service) ?? (arg2 as? Service) ?? self.resolve(Service.self) + } + + func resolve(arguments arg1: Arg1, _ arg2: Arg2, _ arg3: Arg3) -> Service? { + return (arg1 as? Service) ?? (arg2 as? Service) ?? (arg3 as? Service) ?? self.resolve(Service.self) + } +} + diff --git a/SwinjectAutoregistration.xcodeproj/project.pbxproj b/SwinjectAutoregistration.xcodeproj/project.pbxproj index a8d7c62..0e3c1ef 100644 --- a/SwinjectAutoregistration.xcodeproj/project.pbxproj +++ b/SwinjectAutoregistration.xcodeproj/project.pbxproj @@ -7,6 +7,21 @@ objects = { /* Begin PBXBuildFile section */ + AC11910A1E301CD200B112D9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Helpers.swift */; }; + AC1191191E301E3A00B112D9 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191171E301E3A00B112D9 /* Resolver.swift */; }; + AC11911A1E301E3A00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; + AC11911B1E30210200B112D9 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191171E301E3A00B112D9 /* Resolver.swift */; }; + AC11911C1E30210500B112D9 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191171E301E3A00B112D9 /* Resolver.swift */; }; + AC11911D1E30210500B112D9 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191171E301E3A00B112D9 /* Resolver.swift */; }; + AC11911E1E30210A00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; + AC11911F1E30210B00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; + AC1191201E30210C00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; + AC1191211E30211300B112D9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Helpers.swift */; }; + AC1191221E30211400B112D9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Helpers.swift */; }; + AC1191231E30211500B112D9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Helpers.swift */; }; + AC6A0E251E2FF6DD00EF441C /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */; }; + AC6A0E321E2FF81F00EF441C /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */; }; + AC6A0E331E2FF82000EF441C /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */; }; CD5B9ECB1D832D5A007ED05F /* SwinjectAutoregistration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9EC01D832D5A007ED05F /* SwinjectAutoregistration.framework */; }; CD5B9EDF1D832E32007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; CD5B9EE01D833088007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; @@ -286,6 +301,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + AC1191091E301CD200B112D9 /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; + AC1191171E301E3A00B112D9 /* Resolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Resolver.swift; sourceTree = ""; }; + AC1191181E301E3A00B112D9 /* CheckResolved.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckResolved.swift; sourceTree = ""; }; + AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalTests.swift; sourceTree = ""; }; CD5B9E231D832A4F007ED05F /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; CD5B9E251D832A4F007ED05F /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; CD5B9E261D832A4F007ED05F /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = ""; }; @@ -535,8 +554,11 @@ CD5B9E8B1D832BF9007ED05F /* Sources */ = { isa = PBXGroup; children = ( + AC1191171E301E3A00B112D9 /* Resolver.swift */, + AC1191181E301E3A00B112D9 /* CheckResolved.swift */, CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */, CD5B9E8D1D832BF9007ED05F /* Operators.swift */, + AC1191091E301CD200B112D9 /* Helpers.swift */, CD5B9ED81D832E18007ED05F /* Info.plist */, CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */, ); @@ -548,6 +570,7 @@ children = ( CD5B9E8F1D832BF9007ED05F /* Tests.swift */, CD5B9EDD1D832E2E007ED05F /* Info.plist */, + AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */, ); path = Tests; sourceTree = ""; @@ -1039,7 +1062,10 @@ buildActionMask = 2147483647; files = ( CD5B9EE01D833088007ED05F /* AutoRegistration.swift in Sources */, + AC11910A1E301CD200B112D9 /* Helpers.swift in Sources */, + AC11911A1E301E3A00B112D9 /* CheckResolved.swift in Sources */, CD5B9EE11D833088007ED05F /* Operators.swift in Sources */, + AC1191191E301E3A00B112D9 /* Resolver.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1048,6 +1074,7 @@ buildActionMask = 2147483647; files = ( CD5B9EE21D83308B007ED05F /* Tests.swift in Sources */, + AC6A0E251E2FF6DD00EF441C /* OptionalTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1055,7 +1082,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AC11911E1E30210A00B112D9 /* CheckResolved.swift in Sources */, + AC11911C1E30210500B112D9 /* Resolver.swift in Sources */, CD5B9EF81D8333A9007ED05F /* AutoRegistration.swift in Sources */, + AC1191211E30211300B112D9 /* Helpers.swift in Sources */, CD5B9EF91D8333A9007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1064,7 +1094,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AC11911F1E30210B00B112D9 /* CheckResolved.swift in Sources */, + AC11911D1E30210500B112D9 /* Resolver.swift in Sources */, CD5B9F201D833697007ED05F /* AutoRegistration.swift in Sources */, + AC1191221E30211400B112D9 /* Helpers.swift in Sources */, CD5B9F211D833697007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1074,6 +1107,7 @@ buildActionMask = 2147483647; files = ( CD5B9F221D83369A007ED05F /* Tests.swift in Sources */, + AC6A0E321E2FF81F00EF441C /* OptionalTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1081,7 +1115,10 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AC1191201E30210C00B112D9 /* CheckResolved.swift in Sources */, + AC11911B1E30210200B112D9 /* Resolver.swift in Sources */, CD5B9F701D8338FC007ED05F /* AutoRegistration.swift in Sources */, + AC1191231E30211500B112D9 /* Helpers.swift in Sources */, CD5B9F711D8338FC007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1091,6 +1128,7 @@ buildActionMask = 2147483647; files = ( CD5B9F731D83390C007ED05F /* Tests.swift in Sources */, + AC6A0E331E2FF82000EF441C /* OptionalTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tests/OptionalTests.swift b/Tests/OptionalTests.swift new file mode 100644 index 0000000..3b1b964 --- /dev/null +++ b/Tests/OptionalTests.swift @@ -0,0 +1,70 @@ +import Quick +import Nimble +import Swinject + +@testable import SwinjectAutoregistration +class OptionalSpec: QuickSpec { + + override func spec() { + describe("optional helper") { + + it("does recognize explicit optional"){ + let c = Optional.self + let result = isOptional(c.self) + expect(result) == true + } + + it("does recognize questionmark optional"){ + let c: String? = "" + let result = isOptional(type(of:c)) + expect(result) == true + } + + it("does not recognize nested optional"){ + let c = [Int?].self + let result = isOptional(c) + expect(result) == false + } + + it("does recognize optional tuple"){ + let c: (String, String)? = ("a", "b") + let result = isOptional(type(of: c)) + expect(result) == true + } + + it("does not recognize tuple with optional elements"){ + let c: (String?, String?) = ("a", "b") + let result = isOptional(type(of: c)) + expect(result) == false + } + } + + class Dependency { + init(second: Int, _ b: Double, _ c: String?, _ d: Float){} + init(first: Int?, _ b: Double?, _ c: String, _ d: Float){} + } + + func optionalServiceGenericsStub(initializer: (A, B, C, D) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?) -> String? { + return optionalService(a, b, c, d) + } + + + describe("optional checker") { + it("does found optional service"){ + let optional = optionalServiceGenericsStub(initializer: Dependency.init, services: 0, 2.0, "", 5) + expect(optional) == "Optional" + } + + it("does found optional service with nil"){ + let optional = optionalServiceGenericsStub(initializer: Dependency.init, services: 0, 2.0, nil, 5) + expect(optional) == "Optional" + } + + it("does found optional in first to last order"){ + let optional = optionalServiceGenericsStub(initializer: Dependency.init, services: nil, nil, "C", 5) + expect(optional) == "Optional" + } + } + } + +} diff --git a/Tests/Tests.swift b/Tests/Tests.swift index ca46123..ee5c8bf 100644 --- a/Tests/Tests.swift +++ b/Tests/Tests.swift @@ -135,11 +135,11 @@ class AutoregistrationSpec: QuickSpec { //TODO: Find a way how to test that assertion was thrown //This should fail because we generate register functions only for 10 dependencies -// it("registers service with ten dependencies") { -// container.register(initializer: Service10.init, service: Service10.self) -// let service = container.resolve(Service10.self) -// expect(service).notTo(beNil()) -// } + xit("registers service with ten dependencies") { + container.autoregister(Service10.self, initializer: Service10.init) + let service = container.resolve(Service10.self) + expect(service).notTo(beNil()) + } } } } diff --git a/bin/generate b/bin/generate index 66a78a0..172db2f 100755 --- a/bin/generate +++ b/bin/generate @@ -8,14 +8,17 @@ let genericServices = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L let genericArgumentPrefix = "Arg" -let outputPath = "Sources/AutoRegistration.swift" +let autoregistrationPath = "Sources/AutoRegistration.swift" +let checksPath = "Sources/CheckResolved.swift" +let resolverPath = "Sources/Resolver.swift" func headers(_ fileName: String) -> String { return ["//", "// \(fileName)", - "// Swinject", + "// SwinjectAutoregistration", "//", - "// Generated using Swinject AutoRegistration generator.", + "// Generated by Swinject AutoRegistration generator.", + "// Copyright © 2017 Swinject Contributors. All rights reserved.", "//"].joined(separator: "\n") } @@ -125,7 +128,7 @@ func resolverGenerator(_ arguments: Int) -> String { let implementation = "return \(argumentsTests)self.resolve(Service.self)" let resolver = [ - " fileprivate func resolve<\(genericsDefinition)>(\(argumentsDefinition)) -> Service? {", + " func resolve<\(genericsDefinition)>(\(argumentsDefinition)) -> Service? {", " \(implementation)", " }" ] @@ -138,16 +141,24 @@ func checkGenerator(_ dependencies: Int) -> String { let generics = commaConcat(genericParameters) let servicesDefinition = dependencies == 0 ? "" : "\(commaConcat(genericParameters.enumerated().map{ "\($0 >= 1 ? "_" : "") \($1.lowercased()): \($1)?" }))" - let recursiveCall = dependencies > 1 ? "unresolvedService(\(commaConcat(genericParameters.dropLast().map { $0.lowercased() }))) ?? " : "" + let recursiveUnresolvedCall = dependencies > 1 ? "unresolvedService(\(commaConcat(genericParameters.dropLast().map { $0.lowercased() }))) ?? " : "" + let recursiveOptionalCall = dependencies > 1 ? "optionalService(\(commaConcat(genericParameters.dropLast().map { $0.lowercased() }))) ?? " : "" + let lowercasedServicesString = commaConcat(genericParameters.map{ $0.lowercased() }) + let check = [ - "fileprivate func unresolvedService<\(generics)>(_\(servicesDefinition)) -> String? {", - " return \(recursiveCall)( \(genericParameters.last!.lowercased()) == nil ? \"\\(\(genericParameters.last!).self)\" : nil )", + "func unresolvedService<\(generics)>(_\(servicesDefinition)) -> String? {", + " return \(recursiveUnresolvedCall)( \(genericParameters.last!.lowercased()) == nil ? \"\\(\(genericParameters.last!).self)\" : nil )", + "}", + "", + "func optionalService<\(generics)>(_\(servicesDefinition)) -> String? {", + " return \(recursiveOptionalCall)(isOptional(\(genericParameters.last!).self) ? \"\\(\(genericParameters.last!).self)\" : nil )", "}", "", - "fileprivate func checkResolved(initializer: (\(generics)) -> Service, services\(servicesDefinition)){", - " let unresolved = ( [\(commaConcat(genericParameters.map{ $0.lowercased() }))] as [Any?] ).filter { $0 == nil }", + "func checkResolved(initializer: (\(generics)) -> Service, services\(servicesDefinition)){", + " let unresolved = ( [\(lowercasedServicesString)] as [Any?] ).filter { $0 == nil }", " if unresolved.count > 0 {", - " fatalError(\"Failed to resolve \\(unresolvedService(\(commaConcat(genericParameters.map{ $0.lowercased() })))!), initializer: (\(commaConcat(genericParameters.map{ "\\(\($0).self)" }))) -> \\(Service.self)\")", + " let optional = optionalService(\(lowercasedServicesString)).flatMap { optionalMessage($0) } ?? \"\"", + " fatalError(\"\\(optional)Failed to resolve \\(unresolvedService(\(lowercasedServicesString)))!), initializer: (\(commaConcat(genericParameters.map{ "\\(\($0).self)" }))) -> \\(Service.self)\")", " }", "}" ] @@ -156,6 +167,20 @@ func checkGenerator(_ dependencies: Int) -> String { } +func write(to outputPath: String, lines: [String]) throws{ + let output = ([ + headers(outputPath), + "\n\n import Swinject \n\n", + ] + + lines) + .joined(separator: "\n") + + let currentPath = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) + let swinjectPath = currentPath.appendingPathComponent(outputPath) + + try output.write(to: swinjectPath, atomically: true, encoding: String.Encoding.utf8) +} + print("Generating 💬") @@ -163,9 +188,6 @@ let dependenciesCount = Int(CommandLine.arguments[safe: 1] ?? "9")! let argumentsCount = Int(CommandLine.arguments[safe: 2] ?? "3")! let breakCount = Int(CommandLine.arguments[safe: 3] ?? "0")! -let resolvers = (0...argumentsCount).map { arg in - resolverGenerator(arg) -} let registers = (0...dependenciesCount).map { dep in (0...argumentsCount).filter{ dep >= $0 }.map { arg in @@ -173,28 +195,36 @@ let registers = (0...dependenciesCount).map { dep in } }.reduce([]){ $0 + $1} + +var autoregistrationOutput = [ + "public extension Container {\n", + registers.joined(separator: "\n\n"), + "\n\n}", +] + +let resolvers = (0...argumentsCount).map { arg in + resolverGenerator(arg) +} + +let resolverOutput = [ + "extension ResolverType {\n\n", + resolvers.joined(separator: "\n\n"), + "}\n\n" +] + let checks = (1...dependenciesCount).map { dep in checkGenerator(dep) } -var output = [ - headers(outputPath), - "\n\n import Swinject \n\n", - "extension Container {\n", - registers.joined(separator: "\n\n"), - "\n\n}", - "public extension ResolverType {\n\n", - resolvers.joined(separator: "\n\n"), - "}\n\n", - checks.joined(separator: "\n\n") -].joined(separator: "\n") +let checksOutput = [checks.joined(separator: "\n\n")] -let currentPath = URL(fileURLWithPath: FileManager.default.currentDirectoryPath) -let swinjectPath = currentPath.appendingPathComponent(outputPath) do { - try output.write(to: swinjectPath, atomically: true, encoding: String.Encoding.utf8) - print("Done, swinject functions files written at \(outputPath) 👍") + try write(to: autoregistrationPath, lines: autoregistrationOutput) + try write(to: resolverPath, lines: resolverOutput) + try write(to: checksPath, lines: checksOutput) + + print("Done, swinject functions files written at \(autoregistrationPath), \(resolverPath), \(checksPath) 👍") } catch let e as NSError { print("An error occurred while saving the generated functions. Error: \(e)") } From e5e71fbfe8861c1e114acda7f2e5207a9911d147 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 22 Jan 2017 18:05:59 +0100 Subject: [PATCH 07/23] Added useful warnings when resolution fails --- Sources/AutoRegistration.swift | 4 + Sources/CheckResolved.swift | 72 ++----- Sources/Helpers.swift | 20 -- Sources/Type.swift | 70 +++++++ Sources/TypeParser.swift | 179 ++++++++++++++++++ Sources/Warning.swift | 65 +++++++ .../project.pbxproj | 74 ++++++-- ...OptionalTests.swift => OptionalSpec.swift} | 2 +- Tests/Tests.swift | 22 ++- Tests/TypeParserTests.swift | 169 +++++++++++++++++ Tests/WarningsSpec.swift | 140 ++++++++++++++ bin/generate | 13 +- 12 files changed, 729 insertions(+), 101 deletions(-) delete mode 100644 Sources/Helpers.swift create mode 100644 Sources/Type.swift create mode 100644 Sources/TypeParser.swift create mode 100644 Sources/Warning.swift rename Tests/{OptionalTests.swift => OptionalSpec.swift} (99%) create mode 100644 Tests/TypeParserTests.swift create mode 100644 Tests/WarningsSpec.swift diff --git a/Sources/AutoRegistration.swift b/Sources/AutoRegistration.swift index e322d0e..1690e2d 100644 --- a/Sources/AutoRegistration.swift +++ b/Sources/AutoRegistration.swift @@ -10,6 +10,10 @@ import Swinject +let maxDependencies = 9 +let maxArguments = 3 + + public extension Container { /** Registers a factory that resolves the Service based on dependencies infered from the Service initializer. diff --git a/Sources/CheckResolved.swift b/Sources/CheckResolved.swift index b596578..5efd580 100644 --- a/Sources/CheckResolved.swift +++ b/Sources/CheckResolved.swift @@ -14,15 +14,11 @@ func unresolvedService(_ a: A?) -> String? { return ( a == nil ? "\(A.self)" : nil ) } -func optionalService(_ a: A?) -> String? { - return (isOptional(A.self) ? "\(A.self)" : nil ) -} - func checkResolved(initializer: (A) -> Service, services a: A?){ let unresolved = ( [a] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a))!), initializer: (\(A.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a)!), initializer: (\(A.self)) -> \(Service.self)") } } @@ -30,15 +26,11 @@ func unresolvedService(_ a: A?, _ b: B?) -> String? { return unresolvedService(a) ?? ( b == nil ? "\(B.self)" : nil ) } -func optionalService(_ a: A?, _ b: B?) -> String? { - return optionalService(a) ?? (isOptional(B.self) ? "\(B.self)" : nil ) -} - func checkResolved(initializer: (A, B) -> Service, services a: A?, _ b: B?){ let unresolved = ( [a, b] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a, b).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a, b))!), initializer: (\(A.self), \(B.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a, b)!), initializer: (\(A.self), \(B.self)) -> \(Service.self)") } } @@ -46,15 +38,11 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?) -> String? { return unresolvedService(a, b) ?? ( c == nil ? "\(C.self)" : nil ) } -func optionalService(_ a: A?, _ b: B?, _ c: C?) -> String? { - return optionalService(a, b) ?? (isOptional(C.self) ? "\(C.self)" : nil ) -} - func checkResolved(initializer: (A, B, C) -> Service, services a: A?, _ b: B?, _ c: C?){ let unresolved = ( [a, b, c] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a, b, c).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c))!), initializer: (\(A.self), \(B.self), \(C.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a, b, c)!), initializer: (\(A.self), \(B.self), \(C.self)) -> \(Service.self)") } } @@ -62,15 +50,11 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?) -> String return unresolvedService(a, b, c) ?? ( d == nil ? "\(D.self)" : nil ) } -func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?) -> String? { - return optionalService(a, b, c) ?? (isOptional(D.self) ? "\(D.self)" : nil ) -} - func checkResolved(initializer: (A, B, C, D) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?){ let unresolved = ( [a, b, c, d] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a, b, c, d).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a, b, c, d)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self)) -> \(Service.self)") } } @@ -78,15 +62,11 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E return unresolvedService(a, b, c, d) ?? ( e == nil ? "\(E.self)" : nil ) } -func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?) -> String? { - return optionalService(a, b, c, d) ?? (isOptional(E.self) ? "\(E.self)" : nil ) -} - func checkResolved(initializer: (A, B, C, D, E) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?){ let unresolved = ( [a, b, c, d, e] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a, b, c, d, e).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a, b, c, d, e)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self)) -> \(Service.self)") } } @@ -94,15 +74,11 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e return unresolvedService(a, b, c, d, e) ?? ( f == nil ? "\(F.self)" : nil ) } -func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?) -> String? { - return optionalService(a, b, c, d, e) ?? (isOptional(F.self) ? "\(F.self)" : nil ) -} - func checkResolved(initializer: (A, B, C, D, E, F) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?){ let unresolved = ( [a, b, c, d, e, f] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a, b, c, d, e, f).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e, f))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a, b, c, d, e, f)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self)) -> \(Service.self)") } } @@ -110,15 +86,11 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, return unresolvedService(a, b, c, d, e, f) ?? ( g == nil ? "\(G.self)" : nil ) } -func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?) -> String? { - return optionalService(a, b, c, d, e, f) ?? (isOptional(G.self) ? "\(G.self)" : nil ) -} - func checkResolved(initializer: (A, B, C, D, E, F, G) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?){ let unresolved = ( [a, b, c, d, e, f, g] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a, b, c, d, e, f, g).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self)) -> \(Service.self)") } } @@ -126,15 +98,11 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D return unresolvedService(a, b, c, d, e, f, g) ?? ( h == nil ? "\(H.self)" : nil ) } -func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?) -> String? { - return optionalService(a, b, c, d, e, f, g) ?? (isOptional(H.self) ? "\(H.self)" : nil ) -} - func checkResolved(initializer: (A, B, C, D, E, F, G, H) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?){ let unresolved = ( [a, b, c, d, e, f, g, h] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a, b, c, d, e, f, g, h).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g, h))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g, h)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self)) -> \(Service.self)") } } @@ -142,14 +110,10 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d return unresolvedService(a, b, c, d, e, f, g, h) ?? ( i == nil ? "\(I.self)" : nil ) } -func optionalService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?, _ i: I?) -> String? { - return optionalService(a, b, c, d, e, f, g, h) ?? (isOptional(I.self) ? "\(I.self)" : nil ) -} - func checkResolved(initializer: (A, B, C, D, E, F, G, H, I) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?, _ i: I?){ let unresolved = ( [a, b, c, d, e, f, g, h, i] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let optional = optionalService(a, b, c, d, e, f, g, h, i).flatMap { optionalMessage($0) } ?? "" - fatalError("\(optional)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g, h, i))!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self), \(I.self)) -> \(Service.self)") + let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: "\n") + fatalError("\(warningsMessage)Failed to resolve \(unresolvedService(a, b, c, d, e, f, g, h, i)!), initializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self), \(I.self)) -> \(Service.self)") } } \ No newline at end of file diff --git a/Sources/Helpers.swift b/Sources/Helpers.swift deleted file mode 100644 index c30ea0d..0000000 --- a/Sources/Helpers.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// Helpers.swift -// SwinjectAutoregistration -// -// Created by Tomas Kohout on 18/01/2017. -// Copyright © 2017 Swinject Contributors. All rights reserved. -// - -import Foundation - -var optionalCheckRegex = try! NSRegularExpression(pattern: "^Optional<.*>$", options: []) - -var optionalMessage:(String)->String = { _ in "AutoRegistration for services with optional dependencies is not supported. Split to multiple initializers or use regular `register` method. " } - -//Check whether a type is optional by converting it to a string and matching it with regular expression - -func isOptional(_ service: Any) -> Bool { - let serviceType = String(describing: service.self) - return optionalCheckRegex.firstMatch(in: serviceType, options: [], range: NSMakeRange(0, serviceType.characters.count)) != nil -} diff --git a/Sources/Type.swift b/Sources/Type.swift new file mode 100644 index 0000000..fd22e1e --- /dev/null +++ b/Sources/Type.swift @@ -0,0 +1,70 @@ +// +// Type.swift +// SwinjectAutoregistration +// +// Created by Tomas Kohout on 21/01/2017. +// Copyright © 2017 Swinject Contributors. All rights reserved. +// + +import Foundation + +class TypeIdentifier: CustomStringConvertible { + var name: String + var genericTypes: [Type] + var subTypeIdentifier: TypeIdentifier? + + init(name: String, genericTypes: [Type] = [], subTypeIdentifier: TypeIdentifier? = nil){ + self.name = name + self.genericTypes = genericTypes + self.subTypeIdentifier = subTypeIdentifier + } + + var description: String { + let generics = genericTypes.count > 0 ? "<\(genericTypes.map { "\($0)" }.joined(separator: ", "))>" : "" + let subType = subTypeIdentifier.flatMap { ".\($0)" } ?? "" + return "\(name)" + generics + subType + } +} + +extension TypeIdentifier: Equatable { + static func ==(lhs: TypeIdentifier, rhs: TypeIdentifier) -> Bool { + return lhs.name == rhs.name && lhs.genericTypes == rhs.genericTypes && lhs.subTypeIdentifier == rhs.subTypeIdentifier + } +} + +indirect enum Type: CustomStringConvertible { + case closure(parameters:[Type], returnType: Type, throws: Bool) + case identifier(TypeIdentifier) + case tuple([Type]) + case protocolComposition([TypeIdentifier]) + + var description: String { + switch self { + case .closure(let parameters, let returnType, let `throws`): + return "(\(parameters.map { "\($0)" }.joined(separator: ", "))) \(`throws` ? "throws " : "")-> \(returnType)" + case .identifier(let identifier): + return "\(identifier)" + case .tuple(let types): + return "(\(types.map { "\($0)" }.joined(separator: ", ")))" + case .protocolComposition(let types): + return types.map { "\($0)" }.joined(separator: " & ") + } + } +} + +extension Type: Equatable { + static func ==(lhs: Type, rhs: Type) -> Bool { + switch (lhs, rhs) { + case (.closure(let lparams, let lreturn, let lthrows), .closure(let rparams, let rreturn, let rthrows)): + return lparams == rparams && lreturn == rreturn && lthrows == rthrows + case (.identifier(let lidentifier), .identifier(let ridentifier)): + return lidentifier == ridentifier + case (.tuple(let ltuple), .tuple(let rtuple)): + return ltuple == rtuple + case (.protocolComposition(let lprotocols), .protocolComposition(let rprotocols)): + return lprotocols == rprotocols + default: + return false + } + } +} diff --git a/Sources/TypeParser.swift b/Sources/TypeParser.swift new file mode 100644 index 0000000..0aef2fa --- /dev/null +++ b/Sources/TypeParser.swift @@ -0,0 +1,179 @@ +// +// Parser.swift +// SwinjectAutoregistration +// +// Created by Tomas Kohout on 21/01/2017. +// Copyright © 2017 Swinject Contributors. All rights reserved. +// + +import Foundation + +private func ..<(start: Int, end: Int) -> NSRange { + return NSRange(location: start, length: end - start + 1) +} + +/// Simple top-down parser for type description based on swift grammatic: +/// See https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Types.html +/// +/// type → +/// [-] array-type­ - Printed as Array<...> +/// [-] dictionary-type­ - Printed as Dictionary<...> +/// [x] function-type­ `tuple-type throws? -> type` +/// [x] type-identifier­ `identifier ­generic-argument-clause? .­ type-identifier?­` +/// [x] tuple-type­ `type,? type ...` +/// [-] optional-type­ - Printed as Optional<...> +/// [-] implicitly-unwrapped-optional-type­ - Printed as ImplicitlyUnwrappedOptional<...> +/// [x] protocol-composition-type­ `identifier & identifier ...` +/// [-] metatype-type­ - recognized by type identifier +/// [-] Any, Self - recognized by type identifier +/// +/// [x] identifier → identifier-head ­identifier-characters?­ +/// [-] identifier → `­identifier-head­identifier-characters­?`­ - backticks are not printed +/// [-] identifier → implicit-parameter-name­ - e.g. $0, $1 - not needed in type +/// [x] identifier-list → identifier­ | identifier­,­identifier-list + +class TypeParser { + + let scanner: Scanner + + init(string: String){ + scanner = Scanner(string: string) + scanner.charactersToBeSkipped = CharacterSet.whitespacesAndNewlines + } + + func parseType() -> Type? { + if let function = parseFunctionType() { + return Type.closure(parameters: function.parameters, returnType: function.returnType, throws: function.throws) + } else if let protocolComposition = parseProtocolCompositionClause() { + return Type.protocolComposition(protocolComposition) + } else if let typeIdentifier = parseTypeIdentifier() { + return Type.identifier(typeIdentifier) + } else if let tupleType = parseTupleType() { + return Type.tuple(tupleType) + } + + return nil + } + + func parseTypeIdentifier() -> TypeIdentifier? { + guard let typeName = parseIdentifier() else { return nil } + + let genericTypes = parseGenericArgumentClause() ?? [] + var subTypeIdentifier: TypeIdentifier? = nil + + if scanner.scanString(".", into: nil), let typeIdentifier = parseTypeIdentifier() { + subTypeIdentifier = typeIdentifier + } + + return TypeIdentifier(name: typeName, genericTypes: genericTypes, subTypeIdentifier: subTypeIdentifier) + + } + + func parseGenericArgumentClause() -> [Type]? { + guard scanner.scanString("<", into: nil) else { return nil } + guard let type = parseType() else { return nil } + + var types: [Type] = [type] + + while scanner.scanString(",", into: nil), let type = parseType(){ + types.append(type) + } + + guard scanner.scanString(">", into: nil) else { return nil } + return types + } + + func parseProtocolCompositionClause() -> [TypeIdentifier]? { + let originalLocation = scanner.scanLocation + + guard let protocolType = parseTypeIdentifier() else { return nil } + + var protocolTypes: [TypeIdentifier] = [protocolType] + + while scanner.scanString("&", into: nil), let protocolType = parseTypeIdentifier() { + protocolTypes.append(protocolType) + } + + guard protocolTypes.count > 1 else { scanner.scanLocation = originalLocation; return nil; } + + return protocolTypes + } + + func parseTupleType() -> [Type]? { + guard scanner.scanString("(", into: nil) else { return nil } + + var types: [Type] = [] + + if let type = parseType() { types.append(type) } + + while scanner.scanString(",", into: nil), let type = parseType() { + types.append(type) + } + + guard scanner.scanString(")", into: nil) else { return nil } + + return types + } + + func parseFunctionType() -> (parameters: [Type], returnType: Type, throws: Bool)? { + let originalLocation = scanner.scanLocation + + guard let parameters = parseTupleType() else { return nil } + + let `throws` = scanner.scanString("throws", into: nil) + // - rethrows is not allowed for closures + + guard scanner.scanString("->", into: nil) else { scanner.scanLocation = originalLocation; return nil } + + guard let returnType = parseType() else { scanner.scanLocation = originalLocation; return nil } + + return (parameters: parameters, returnType: returnType, throws: `throws`) + + } + + func parseIdentifier() -> String? { + + let head = NSMutableCharacterSet() + + // See https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-head + + //Identifier head + head.formUnion(with: CharacterSet.letters) + head.addCharacters(in: "_") + + let ranges = [ + 0x00A8 ..< 0x00A8, 0x00AA ..< 0x00AA, 0x00AD ..< 0x00AD, 0x00AF ..< 0x00AF, 0x00B2..<0x00B5, 0x00B7..<0x00BA, + 0x00BC..<0x00BE, 0x00C0..<0x00D6, 0x00D8..<0x00F6, 0x00F8..<0x00FF, + 0x0100..<0x02FF, 0x0370..<0x167F, 0x1681..<0x180D, 0x180F..<0x1DBF, + 0x1E00..<0x1FFF, + 0x200B..<0x200D, 0x202A..<0x202E, 0x203F..<0x2040, 0x2054..<0x2054, 0x2060..<0x206F, + 0x2070..<0x20CF, 0x2100..<0x218F, 0x2460..<0x24FF, 0x2776..<0x2793, + 0x2C00..<0x2DFF, 0x2E80..<0x2FFF, + 0x3004..<0x3007, 0x3021..<0x302F, 0x3031..<0x303F, 0x3040..<0xD7FF, + 0xF900..<0xFD3D, 0xFD40..<0xFDCF, 0xFDF0..<0xFE1F, 0xFE30..<0xFE44, + 0xFE47..<0xFFFD, + //Emoticons + 0x10000..<0x1FFFD, 0x20000..<0x2FFFD, 0x30000..<0x3FFFD, 0x40000..<0x4FFFD, + 0x50000..<0x5FFFD, 0x60000..<0x6FFFD, 0x70000..<0x7FFFD, 0x80000..<0x8FFFD, + 0x90000..<0x9FFFD, 0xA0000..<0xAFFFD, 0xB0000..<0xBFFFD, 0xC0000..<0xCFFFD, + 0xD0000..<0xDFFFD, 0xE0000..<0xEFFFD] + + ranges.forEach { head.addCharacters(in: $0) } + + //Identifier characters + let characters = head.copy() as! NSMutableCharacterSet + characters.addCharacters(in: "0123456789") + + let charactersRanges = [0x0300..<0x036F, 0x1DC0..<0x1DFF, 0x20D0..<0x20FF, 0xFE20..<0xFE2F] + charactersRanges.forEach { characters.addCharacters(in: $0) } + + var headString: NSString? + var charactersString: NSString? + + guard scanner.scanCharacters(from: head as CharacterSet, into: &headString) else { return nil } + + scanner.scanCharacters(from: characters as CharacterSet, into: &charactersString) + return "\(headString!)\(charactersString ?? "")" + } + +} diff --git a/Sources/Warning.swift b/Sources/Warning.swift new file mode 100644 index 0000000..2e022b1 --- /dev/null +++ b/Sources/Warning.swift @@ -0,0 +1,65 @@ +// +// Warnings.swift +// SwinjectAutoregistration +// +// Created by Tomas Kohout on 18/01/2017. +// Copyright © 2017 Swinject Contributors. All rights reserved. +// + +import Foundation + +enum Warning { + case optional(String) + case implicitlyUnwrappedOptional(String) + case tooManyDependencies(Int) + + var message: String { + switch self { + case .optional(let name): + return "⚠ AutoRegistration of optional dependency (\(name))? is not supported. Split to multiple initializers or use regular `register` method. " + case .implicitlyUnwrappedOptional(let name): + return "⚠ AutoRegistration of implicitly unwrapped optional dependency (\(name))! is not supported. Use regular `register` method. " + case .tooManyDependencies(let dependencyCount): + return "⚠ AutoRegistration is limited to maximum of \(maxDependencies) dependencies, tried to resolve \(dependencyCount). Use regular `register` method instead. " + } + } +} + +/// Shows warnings based on information parsed from initializers description + +func warnings(forInitializer initializer: (Parameters) -> Service) -> [Warning] { + let parser = TypeParser(string: String(describing: Parameters.self)) + guard let type = parser.parseType() else { return [] } + + let dependencies: [Type] + + //Multiple arguments + if case .tuple(let types) = type { + dependencies = types + //Single argument + } else if case .identifier(_) = type { + dependencies = [type] + } else { + return [] + } + + var warnings: [Warning] = [] + + + if dependencies.count > maxDependencies { + warnings.append(.tooManyDependencies(dependencies.count)) + } + + for dependency in dependencies { + if case .identifier(let dependencyType) = dependency, let generic = dependencyType.genericTypes.first { + if dependencyType.name == "Optional" { + warnings.append(.optional("\(generic)")) + } else if dependencyType.name == "ImplicitlyUnwrappedOptional" { + warnings.append(.implicitlyUnwrappedOptional("\(generic)")) + } + } + } + + return warnings +} + diff --git a/SwinjectAutoregistration.xcodeproj/project.pbxproj b/SwinjectAutoregistration.xcodeproj/project.pbxproj index 0e3c1ef..56659cc 100644 --- a/SwinjectAutoregistration.xcodeproj/project.pbxproj +++ b/SwinjectAutoregistration.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - AC11910A1E301CD200B112D9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Helpers.swift */; }; + AC11910A1E301CD200B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; AC1191191E301E3A00B112D9 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191171E301E3A00B112D9 /* Resolver.swift */; }; AC11911A1E301E3A00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; AC11911B1E30210200B112D9 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191171E301E3A00B112D9 /* Resolver.swift */; }; @@ -16,12 +16,23 @@ AC11911E1E30210A00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; AC11911F1E30210B00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; AC1191201E30210C00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; - AC1191211E30211300B112D9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Helpers.swift */; }; - AC1191221E30211400B112D9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Helpers.swift */; }; - AC1191231E30211500B112D9 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Helpers.swift */; }; - AC6A0E251E2FF6DD00EF441C /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */; }; - AC6A0E321E2FF81F00EF441C /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */; }; - AC6A0E331E2FF82000EF441C /* OptionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */; }; + AC1191211E30211300B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; + AC1191221E30211400B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; + AC1191231E30211500B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; + AC4AC9081E32964C00E6355A /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9071E32964C00E6355A /* TypeParserTests.swift */; }; + AC4AC9171E3297E000E6355A /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9071E32964C00E6355A /* TypeParserTests.swift */; }; + AC4AC9181E3297E100E6355A /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9071E32964C00E6355A /* TypeParserTests.swift */; }; + AC4AC9491E33C71D00E6355A /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9481E33C71D00E6355A /* TypeParser.swift */; }; + AC4AC94B1E33C75200E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; + AC4AC94C1E33CB9100E6355A /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9481E33C71D00E6355A /* TypeParser.swift */; }; + AC4AC94D1E33CB9100E6355A /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9481E33C71D00E6355A /* TypeParser.swift */; }; + AC4AC94E1E33CB9200E6355A /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9481E33C71D00E6355A /* TypeParser.swift */; }; + AC4AC94F1E33CB9600E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; + AC4AC9501E33CB9700E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; + AC4AC9511E33CB9700E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; + AC4AC9531E33CF0600E6355A /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */; }; + AC4AC9541E33D04C00E6355A /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */; }; + AC4AC9551E33D04D00E6355A /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */; }; CD5B9ECB1D832D5A007ED05F /* SwinjectAutoregistration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9EC01D832D5A007ED05F /* SwinjectAutoregistration.framework */; }; CD5B9EDF1D832E32007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; CD5B9EE01D833088007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; @@ -301,10 +312,14 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - AC1191091E301CD200B112D9 /* Helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; + AC1191091E301CD200B112D9 /* Warning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Warning.swift; sourceTree = ""; }; AC1191171E301E3A00B112D9 /* Resolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Resolver.swift; sourceTree = ""; }; AC1191181E301E3A00B112D9 /* CheckResolved.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckResolved.swift; sourceTree = ""; }; - AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalTests.swift; sourceTree = ""; }; + AC4AC9071E32964C00E6355A /* TypeParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParserTests.swift; sourceTree = ""; }; + AC4AC9481E33C71D00E6355A /* TypeParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParser.swift; sourceTree = ""; }; + AC4AC94A1E33C75200E6355A /* Type.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Type.swift; sourceTree = ""; }; + AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WarningsSpec.swift; sourceTree = ""; }; + AC6A0E241E2FF6DD00EF441C /* OptionalSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalSpec.swift; sourceTree = ""; }; CD5B9E231D832A4F007ED05F /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; CD5B9E251D832A4F007ED05F /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; CD5B9E261D832A4F007ED05F /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = ""; }; @@ -414,6 +429,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + AC4AC9471E33C70900E6355A /* Parser */ = { + isa = PBXGroup; + children = ( + AC4AC9481E33C71D00E6355A /* TypeParser.swift */, + AC4AC94A1E33C75200E6355A /* Type.swift */, + ); + name = Parser; + sourceTree = ""; + }; CD5B9E151D832813007ED05F = { isa = PBXGroup; children = ( @@ -554,11 +578,12 @@ CD5B9E8B1D832BF9007ED05F /* Sources */ = { isa = PBXGroup; children = ( + AC4AC9471E33C70900E6355A /* Parser */, AC1191171E301E3A00B112D9 /* Resolver.swift */, AC1191181E301E3A00B112D9 /* CheckResolved.swift */, CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */, CD5B9E8D1D832BF9007ED05F /* Operators.swift */, - AC1191091E301CD200B112D9 /* Helpers.swift */, + AC1191091E301CD200B112D9 /* Warning.swift */, CD5B9ED81D832E18007ED05F /* Info.plist */, CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */, ); @@ -570,7 +595,9 @@ children = ( CD5B9E8F1D832BF9007ED05F /* Tests.swift */, CD5B9EDD1D832E2E007ED05F /* Info.plist */, - AC6A0E241E2FF6DD00EF441C /* OptionalTests.swift */, + AC6A0E241E2FF6DD00EF441C /* OptionalSpec.swift */, + AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */, + AC4AC9071E32964C00E6355A /* TypeParserTests.swift */, ); path = Tests; sourceTree = ""; @@ -1062,10 +1089,12 @@ buildActionMask = 2147483647; files = ( CD5B9EE01D833088007ED05F /* AutoRegistration.swift in Sources */, - AC11910A1E301CD200B112D9 /* Helpers.swift in Sources */, + AC11910A1E301CD200B112D9 /* Warning.swift in Sources */, AC11911A1E301E3A00B112D9 /* CheckResolved.swift in Sources */, CD5B9EE11D833088007ED05F /* Operators.swift in Sources */, AC1191191E301E3A00B112D9 /* Resolver.swift in Sources */, + AC4AC9491E33C71D00E6355A /* TypeParser.swift in Sources */, + AC4AC94B1E33C75200E6355A /* Type.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1073,8 +1102,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AC4AC9081E32964C00E6355A /* TypeParserTests.swift in Sources */, CD5B9EE21D83308B007ED05F /* Tests.swift in Sources */, - AC6A0E251E2FF6DD00EF441C /* OptionalTests.swift in Sources */, + AC4AC9531E33CF0600E6355A /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1084,8 +1114,10 @@ files = ( AC11911E1E30210A00B112D9 /* CheckResolved.swift in Sources */, AC11911C1E30210500B112D9 /* Resolver.swift in Sources */, + AC4AC94C1E33CB9100E6355A /* TypeParser.swift in Sources */, CD5B9EF81D8333A9007ED05F /* AutoRegistration.swift in Sources */, - AC1191211E30211300B112D9 /* Helpers.swift in Sources */, + AC4AC94F1E33CB9600E6355A /* Type.swift in Sources */, + AC1191211E30211300B112D9 /* Warning.swift in Sources */, CD5B9EF91D8333A9007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1096,8 +1128,10 @@ files = ( AC11911F1E30210B00B112D9 /* CheckResolved.swift in Sources */, AC11911D1E30210500B112D9 /* Resolver.swift in Sources */, + AC4AC94D1E33CB9100E6355A /* TypeParser.swift in Sources */, CD5B9F201D833697007ED05F /* AutoRegistration.swift in Sources */, - AC1191221E30211400B112D9 /* Helpers.swift in Sources */, + AC4AC9501E33CB9700E6355A /* Type.swift in Sources */, + AC1191221E30211400B112D9 /* Warning.swift in Sources */, CD5B9F211D833697007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1106,8 +1140,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AC4AC9171E3297E000E6355A /* TypeParserTests.swift in Sources */, CD5B9F221D83369A007ED05F /* Tests.swift in Sources */, - AC6A0E321E2FF81F00EF441C /* OptionalTests.swift in Sources */, + AC4AC9541E33D04C00E6355A /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1117,8 +1152,10 @@ files = ( AC1191201E30210C00B112D9 /* CheckResolved.swift in Sources */, AC11911B1E30210200B112D9 /* Resolver.swift in Sources */, + AC4AC94E1E33CB9200E6355A /* TypeParser.swift in Sources */, CD5B9F701D8338FC007ED05F /* AutoRegistration.swift in Sources */, - AC1191231E30211500B112D9 /* Helpers.swift in Sources */, + AC4AC9511E33CB9700E6355A /* Type.swift in Sources */, + AC1191231E30211500B112D9 /* Warning.swift in Sources */, CD5B9F711D8338FC007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1127,8 +1164,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + AC4AC9181E3297E100E6355A /* TypeParserTests.swift in Sources */, CD5B9F731D83390C007ED05F /* Tests.swift in Sources */, - AC6A0E331E2FF82000EF441C /* OptionalTests.swift in Sources */, + AC4AC9551E33D04D00E6355A /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tests/OptionalTests.swift b/Tests/OptionalSpec.swift similarity index 99% rename from Tests/OptionalTests.swift rename to Tests/OptionalSpec.swift index 3b1b964..5775175 100644 --- a/Tests/OptionalTests.swift +++ b/Tests/OptionalSpec.swift @@ -65,6 +65,6 @@ class OptionalSpec: QuickSpec { expect(optional) == "Optional" } } - } + } } diff --git a/Tests/Tests.swift b/Tests/Tests.swift index ee5c8bf..a6561e7 100644 --- a/Tests/Tests.swift +++ b/Tests/Tests.swift @@ -58,6 +58,14 @@ class AutoregistrationSpec: QuickSpec { init(a: DependencyA, b: DependencyB, c: DependencyC, d: DependencyD, e: DependencyE, f: DependencyF, g: DependencyG, h: DependencyH, i: DependencyI, j: DependencyJ){} } + class OptionalService { + init(a: DependencyA?){} + } + + class UnwrappedService { + init(a: DependencyA!){} + } + override func spec() { describe("autoregistration") { @@ -135,11 +143,23 @@ class AutoregistrationSpec: QuickSpec { //TODO: Find a way how to test that assertion was thrown //This should fail because we generate register functions only for 10 dependencies - xit("registers service with ten dependencies") { + xit("fails to register service with ten dependencies") { container.autoregister(Service10.self, initializer: Service10.init) let service = container.resolve(Service10.self) expect(service).notTo(beNil()) } + + xit("fails to register service with optional dependency") { + container.autoregister(OptionalService.self, initializer: OptionalService.init) + let service = container.resolve(OptionalService.self) + expect(service).notTo(beNil()) + } + + xit("fails to register service with unwrapped dependency") { + container.autoregister(UnwrappedService.self, initializer: UnwrappedService.init) + let service = container.resolve(UnwrappedService.self) + expect(service).notTo(beNil()) + } } } } diff --git a/Tests/TypeParserTests.swift b/Tests/TypeParserTests.swift new file mode 100644 index 0000000..637fd6a --- /dev/null +++ b/Tests/TypeParserTests.swift @@ -0,0 +1,169 @@ +// +// ScannerTests.swift +// SwinjectAutoregistration +// +// Created by Tomas Kohout on 20/01/2017. +// Copyright © 2017 Swinject Contributors. All rights reserved. +// + +import XCTest + +protocol ProtocolA{} +protocol ProtocolB{} + +class ClassA{ + class Nested{} +} + +class _x0😪name²〡yﷰ {} + +class `protocol` {} + +@testable import SwinjectAutoregistration + +class TypeParserTests: XCTestCase { + + //Helpers + func identifier(_ name: String, generics: [Type] = []) -> Type { + return Type.identifier(TypeIdentifier(name: name, genericTypes: generics)) + } + + func generic_identifier(_ name: String, generics: [String]) -> Type { + return Type.identifier(TypeIdentifier(name: name, genericTypes: generics.map { identifier($0) })) + } + + + func testScansTypeIdentifier() { + let string = "\(_x0😪name²〡yﷰ.self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, identifier(string)) + } + + func testDoesntScanNonTypeIdentifier() { + let string = "1Array" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, nil) + } + + + func testScanSubTypeIdentifier() { + let string = "\(ClassA.Nested.self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, identifier("Nested")) + } + + func testScansArrayType() { + let string = "\([String].self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, generic_identifier("Array", generics: ["String"])) + } + + func testScansGenericTypeWithMultipleArguments() { + let string = "\([Int: String].self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, generic_identifier("Dictionary", generics: ["Int", "String"])) + } + + func testScansTupleType() { + let string = "\((name: String, count: Int).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.tuple([identifier("String"), identifier("Int")])) + } + + func testScansTupleOfTuples() { + let string = "\(((String, Int, Double), [String]).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.tuple([Type.tuple([identifier("String"), identifier("Int"), identifier("Double")]), generic_identifier("Array", generics: ["String"])])) + } + + func testScansClosureType() { + let string = "\(((String, Int) -> String).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.closure(parameters: [Type.tuple([identifier("String"), identifier("Int")])], returnType: identifier("String"), throws: false)) + } + + func testScansNestedFunctionType() { + let string = "\((((String) -> String, Int) -> String).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + //Type print adds one unneccessary tuple to the output + XCTAssertEqual(type, Type.closure(parameters: [Type.tuple([Type.closure(parameters: [identifier("String")], returnType: identifier("String"), throws: false), identifier("Int")])], returnType: identifier("String"), throws: false)) + } + + func testScansNoParameterFunctionType() { + let string = "\(((Void) -> Void).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + let void = Type.tuple([]) // Void is empty tuple + XCTAssertEqual(type, Type.closure(parameters: [void], returnType: void, throws: false)) + } + + func testScansThrowingFunctionType() { + let string = "\(((Void) throws -> Void).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + let void = Type.tuple([]) // Void is empty tuple + XCTAssertEqual(type, Type.closure(parameters: [void], returnType: void, throws: true)) + } + + func testScansImplicitlyUnwrappedOptional() { + let string = "\((String!).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, generic_identifier("ImplicitlyUnwrappedOptional", generics: ["String"])) + } + + func testScansOptional() { + let string = "\((Int?).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, generic_identifier("Optional", generics: ["Int"])) + } + + func testScansProtocolCompositionType() { + let string = "\((ProtocolA & ProtocolB).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.protocolComposition([TypeIdentifier(name: "ProtocolA"), TypeIdentifier(name: "ProtocolB")])) + } + + func testScansMetatypes() { + let string = "\((ProtocolA.Type.Type).self)" // Very meta + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.identifier(TypeIdentifier(name: "ProtocolA", subTypeIdentifier: TypeIdentifier(name: "Type", subTypeIdentifier: TypeIdentifier(name: "Type"))))) + } + + func testScansBacktickedType() { + let string = "\((`protocol`).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, identifier(string)) + } + + +} diff --git a/Tests/WarningsSpec.swift b/Tests/WarningsSpec.swift new file mode 100644 index 0000000..c4a78ca --- /dev/null +++ b/Tests/WarningsSpec.swift @@ -0,0 +1,140 @@ +import Quick +import Nimble + +@testable import SwinjectAutoregistration + +extension Warning: Equatable {} + +public func ==(lhs: Warning, rhs: Warning) -> Bool { + switch (lhs, rhs){ + case (.optional(let lname), .optional(let rname)): + return lname == rname + case (.implicitlyUnwrappedOptional(let lname), .implicitlyUnwrappedOptional(let rname)): + return lname == rname + case (.tooManyDependencies(let ldependencyCount), .tooManyDependencies(let rdependencyCount)): + return ldependencyCount == rdependencyCount + default: + return false + } +} + +class WarningsSpec: QuickSpec { + + class DependencyA {} + class DependencyB {} + class DependencyC {} + class DependencyD {} + class DependencyE {} + class DependencyF {} + class DependencyG {} + class DependencyH {} + class DependencyI {} + class DependencyJ {} + + class Service1 { + init(a: DependencyA){} + } + + class Service2 { + init(a: DependencyA, b: DependencyB){} + } + + class Service3 { + init(a: DependencyA, b: DependencyB, c: DependencyC){} + } + + class Service9 { + init(a: DependencyA, b: DependencyB, c: DependencyC, d: DependencyD, e: DependencyE, f: DependencyF, g: DependencyG, h: DependencyH, i: DependencyI){} + } + + class Service10 { + init(a: DependencyA, b: DependencyB, c: DependencyC, d: DependencyD, e: DependencyE, f: DependencyF, g: DependencyG, h: DependencyH, i: DependencyI, j: DependencyJ){} + } + + class OptionalService { + init(a: DependencyB?){} + } + + class UnwrappedService { + init(a: DependencyA!, b: DependencyB){} + } + + class BadService { + init(a: DependencyA, b: DependencyB, c: DependencyC!, d: DependencyD?, e: DependencyE!, f: DependencyF, g: DependencyG, h: DependencyH?, i: DependencyI, j: DependencyJ){} + } + + class OptionalSingleTupleService { + init(tuple: (a: DependencyA?, b: DependencyB?, c: DependencyC?)){} + } + + class OptionalMutipleTupleService { + init(tupleA: (a: DependencyA?, b: DependencyB?, c: DependencyC?), tupleB: (a: DependencyA?, b: DependencyB?)){} + } + + class NestedClosureService { + init(closure: (((String) -> String)?) -> String){} + } + + class OptionalNestedClosureService { + init(closure: ((((String) -> String)?) -> String)?){} + } + + + override func spec() { + describe("warnings checker") { + it("does show warning for service with more than 9 dependencies"){ + let w = warnings(forInitializer: Service10.init) + expect(w.first) == Warning.tooManyDependencies(10) + } + + it("doesnt show warning for single dependency"){ + let w = warnings(forInitializer: Service1.init) + expect(w.count) == 0 + } + + it("doesnt show warning for service with 9 dependencies"){ + let w = warnings(forInitializer: Service9.init) + expect(w.count) == 0 + } + + it("does show warning for service with optional dependency"){ + let w = warnings(forInitializer: OptionalService.init) + expect(w.first) == Warning.optional("DependencyB") + } + + it("does show warning for service with implicitly unwrapped dependency"){ + let w = warnings(forInitializer: UnwrappedService.init) + expect(w.first) == Warning.implicitlyUnwrappedOptional("DependencyA") + } + + it("does show multiple warnings"){ + let w = warnings(forInitializer: BadService.init) + expect(w.count) == 5 + } + + // This fails + // Single argument tuple looks exactly the same as multiple arguments when printed + xit("doesnt show warning for single argument tuple of optionals"){ + let w = warnings(forInitializer: OptionalSingleTupleService.init) + expect(w.count) == 0 + } + + it("doesnt show warning for mutiple argument tuples of optionals"){ + let w = warnings(forInitializer: OptionalMutipleTupleService.init) + expect(w.count) == 0 + } + + it("doesnt show warning for nested closures"){ + let w = warnings(forInitializer: NestedClosureService.init) + expect(w.count) == 0 + } + + it("does show warning for optional closure"){ + let w = warnings(forInitializer: OptionalNestedClosureService.init) + expect(w.count) == 1 + } + + } + } + +} diff --git a/bin/generate b/bin/generate index 172db2f..eb4df28 100755 --- a/bin/generate +++ b/bin/generate @@ -142,23 +142,19 @@ func checkGenerator(_ dependencies: Int) -> String { let servicesDefinition = dependencies == 0 ? "" : "\(commaConcat(genericParameters.enumerated().map{ "\($0 >= 1 ? "_" : "") \($1.lowercased()): \($1)?" }))" let recursiveUnresolvedCall = dependencies > 1 ? "unresolvedService(\(commaConcat(genericParameters.dropLast().map { $0.lowercased() }))) ?? " : "" - let recursiveOptionalCall = dependencies > 1 ? "optionalService(\(commaConcat(genericParameters.dropLast().map { $0.lowercased() }))) ?? " : "" let lowercasedServicesString = commaConcat(genericParameters.map{ $0.lowercased() }) + let check = [ "func unresolvedService<\(generics)>(_\(servicesDefinition)) -> String? {", " return \(recursiveUnresolvedCall)( \(genericParameters.last!.lowercased()) == nil ? \"\\(\(genericParameters.last!).self)\" : nil )", "}", "", - "func optionalService<\(generics)>(_\(servicesDefinition)) -> String? {", - " return \(recursiveOptionalCall)(isOptional(\(genericParameters.last!).self) ? \"\\(\(genericParameters.last!).self)\" : nil )", - "}", - "", "func checkResolved(initializer: (\(generics)) -> Service, services\(servicesDefinition)){", " let unresolved = ( [\(lowercasedServicesString)] as [Any?] ).filter { $0 == nil }", " if unresolved.count > 0 {", - " let optional = optionalService(\(lowercasedServicesString)).flatMap { optionalMessage($0) } ?? \"\"", - " fatalError(\"\\(optional)Failed to resolve \\(unresolvedService(\(lowercasedServicesString)))!), initializer: (\(commaConcat(genericParameters.map{ "\\(\($0).self)" }))) -> \\(Service.self)\")", + " let warningsMessage = warnings(forInitializer: initializer).map { $0.message }.joined(separator: \"\\n\")", + " fatalError(\"\\(warningsMessage)Failed to resolve \\(unresolvedService(\(lowercasedServicesString))!), initializer: (\(commaConcat(genericParameters.map{ "\\(\($0).self)" }))) -> \\(Service.self)\")", " }", "}" ] @@ -197,6 +193,9 @@ let registers = (0...dependenciesCount).map { dep in var autoregistrationOutput = [ + "let maxDependencies = \(dependenciesCount)", + "let maxArguments = \(argumentsCount)", + "\n", "public extension Container {\n", registers.joined(separator: "\n\n"), "\n\n}", From 44d7ac5709859356f78ce368d76f175794fbc125 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 22 Jan 2017 18:08:03 +0100 Subject: [PATCH 08/23] Clean up --- .../project.pbxproj | 18 +++-- ...Tests.swift => AutoregistrationSpec.swift} | 0 Tests/OptionalSpec.swift | 70 ------------------- 3 files changed, 8 insertions(+), 80 deletions(-) rename Tests/{Tests.swift => AutoregistrationSpec.swift} (100%) delete mode 100644 Tests/OptionalSpec.swift diff --git a/SwinjectAutoregistration.xcodeproj/project.pbxproj b/SwinjectAutoregistration.xcodeproj/project.pbxproj index 56659cc..ed214b0 100644 --- a/SwinjectAutoregistration.xcodeproj/project.pbxproj +++ b/SwinjectAutoregistration.xcodeproj/project.pbxproj @@ -37,7 +37,7 @@ CD5B9EDF1D832E32007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; CD5B9EE01D833088007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; CD5B9EE11D833088007ED05F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8D1D832BF9007ED05F /* Operators.swift */; }; - CD5B9EE21D83308B007ED05F /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* Tests.swift */; }; + CD5B9EE21D83308B007ED05F /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */; }; CD5B9EF81D8333A9007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; CD5B9EF91D8333A9007ED05F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8D1D832BF9007ED05F /* Operators.swift */; }; CD5B9EFA1D8333A9007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -45,7 +45,7 @@ CD5B9F1F1D83368E007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; CD5B9F201D833697007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; CD5B9F211D833697007ED05F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8D1D832BF9007ED05F /* Operators.swift */; }; - CD5B9F221D83369A007ED05F /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* Tests.swift */; }; + CD5B9F221D83369A007ED05F /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */; }; CD5B9F5B1D833772007ED05F /* Swinject.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9E7D1D832A84007ED05F /* Swinject.framework */; }; CD5B9F5C1D83377C007ED05F /* Swinject.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9E851D832A84007ED05F /* Swinject.framework */; }; CD5B9F5F1D8337B4007ED05F /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9E6A1D832A84007ED05F /* Quick.framework */; }; @@ -58,7 +58,7 @@ CD5B9F701D8338FC007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; CD5B9F711D8338FC007ED05F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8D1D832BF9007ED05F /* Operators.swift */; }; CD5B9F721D833900007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CD5B9F731D83390C007ED05F /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* Tests.swift */; }; + CD5B9F731D83390C007ED05F /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */; }; CD5B9F761D833A15007ED05F /* SwinjectAutoregistration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9F281D833711007ED05F /* SwinjectAutoregistration.framework */; }; CD5B9F781D833A27007ED05F /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9E641D832A84007ED05F /* Quick.framework */; }; /* End PBXBuildFile section */ @@ -319,7 +319,6 @@ AC4AC9481E33C71D00E6355A /* TypeParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParser.swift; sourceTree = ""; }; AC4AC94A1E33C75200E6355A /* Type.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Type.swift; sourceTree = ""; }; AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WarningsSpec.swift; sourceTree = ""; }; - AC6A0E241E2FF6DD00EF441C /* OptionalSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalSpec.swift; sourceTree = ""; }; CD5B9E231D832A4F007ED05F /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; CD5B9E251D832A4F007ED05F /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; CD5B9E261D832A4F007ED05F /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = ""; }; @@ -346,7 +345,7 @@ CD5B9E551D832A84007ED05F /* Swinject.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Swinject.xcodeproj; path = Carthage/Checkouts/Swinject/Swinject.xcodeproj; sourceTree = ""; }; CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoRegistration.swift; sourceTree = ""; }; CD5B9E8D1D832BF9007ED05F /* Operators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; - CD5B9E8F1D832BF9007ED05F /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoregistrationSpec.swift; sourceTree = ""; }; CD5B9EB21D832C81007ED05F /* watchOS-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Application.xcconfig"; sourceTree = ""; }; CD5B9EB31D832C81007ED05F /* watchOS-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Base.xcconfig"; sourceTree = ""; }; CD5B9EB41D832C81007ED05F /* watchOS-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Framework.xcconfig"; sourceTree = ""; }; @@ -593,9 +592,8 @@ CD5B9E8E1D832BF9007ED05F /* Tests */ = { isa = PBXGroup; children = ( - CD5B9E8F1D832BF9007ED05F /* Tests.swift */, + CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */, CD5B9EDD1D832E2E007ED05F /* Info.plist */, - AC6A0E241E2FF6DD00EF441C /* OptionalSpec.swift */, AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */, AC4AC9071E32964C00E6355A /* TypeParserTests.swift */, ); @@ -1103,7 +1101,7 @@ buildActionMask = 2147483647; files = ( AC4AC9081E32964C00E6355A /* TypeParserTests.swift in Sources */, - CD5B9EE21D83308B007ED05F /* Tests.swift in Sources */, + CD5B9EE21D83308B007ED05F /* AutoregistrationSpec.swift in Sources */, AC4AC9531E33CF0600E6355A /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1141,7 +1139,7 @@ buildActionMask = 2147483647; files = ( AC4AC9171E3297E000E6355A /* TypeParserTests.swift in Sources */, - CD5B9F221D83369A007ED05F /* Tests.swift in Sources */, + CD5B9F221D83369A007ED05F /* AutoregistrationSpec.swift in Sources */, AC4AC9541E33D04C00E6355A /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1165,7 +1163,7 @@ buildActionMask = 2147483647; files = ( AC4AC9181E3297E100E6355A /* TypeParserTests.swift in Sources */, - CD5B9F731D83390C007ED05F /* Tests.swift in Sources */, + CD5B9F731D83390C007ED05F /* AutoregistrationSpec.swift in Sources */, AC4AC9551E33D04D00E6355A /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Tests/Tests.swift b/Tests/AutoregistrationSpec.swift similarity index 100% rename from Tests/Tests.swift rename to Tests/AutoregistrationSpec.swift diff --git a/Tests/OptionalSpec.swift b/Tests/OptionalSpec.swift deleted file mode 100644 index 5775175..0000000 --- a/Tests/OptionalSpec.swift +++ /dev/null @@ -1,70 +0,0 @@ -import Quick -import Nimble -import Swinject - -@testable import SwinjectAutoregistration -class OptionalSpec: QuickSpec { - - override func spec() { - describe("optional helper") { - - it("does recognize explicit optional"){ - let c = Optional.self - let result = isOptional(c.self) - expect(result) == true - } - - it("does recognize questionmark optional"){ - let c: String? = "" - let result = isOptional(type(of:c)) - expect(result) == true - } - - it("does not recognize nested optional"){ - let c = [Int?].self - let result = isOptional(c) - expect(result) == false - } - - it("does recognize optional tuple"){ - let c: (String, String)? = ("a", "b") - let result = isOptional(type(of: c)) - expect(result) == true - } - - it("does not recognize tuple with optional elements"){ - let c: (String?, String?) = ("a", "b") - let result = isOptional(type(of: c)) - expect(result) == false - } - } - - class Dependency { - init(second: Int, _ b: Double, _ c: String?, _ d: Float){} - init(first: Int?, _ b: Double?, _ c: String, _ d: Float){} - } - - func optionalServiceGenericsStub(initializer: (A, B, C, D) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?) -> String? { - return optionalService(a, b, c, d) - } - - - describe("optional checker") { - it("does found optional service"){ - let optional = optionalServiceGenericsStub(initializer: Dependency.init, services: 0, 2.0, "", 5) - expect(optional) == "Optional" - } - - it("does found optional service with nil"){ - let optional = optionalServiceGenericsStub(initializer: Dependency.init, services: 0, 2.0, nil, 5) - expect(optional) == "Optional" - } - - it("does found optional in first to last order"){ - let optional = optionalServiceGenericsStub(initializer: Dependency.init, services: nil, nil, "C", 5) - expect(optional) == "Optional" - } - } - } - -} From 4ff8813f377b26306d422216bcaf15c11914ad46 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 22 Jan 2017 19:19:48 +0100 Subject: [PATCH 09/23] Added fatalError for same type dynamic arguments --- Sources/AutoRegistration.swift | 15 ++++++++++++ Sources/Warning.swift | 12 +++++++++- Tests/AutoregistrationSpec.swift | 39 +++++++++++++++++++++++++++++++- bin/generate | 9 +++++++- 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/Sources/AutoRegistration.swift b/Sources/AutoRegistration.swift index 1690e2d..1824bcb 100644 --- a/Sources/AutoRegistration.swift +++ b/Sources/AutoRegistration.swift @@ -127,6 +127,7 @@ public func autoregister(_ service: Service.Type, name: Str */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b) @@ -187,6 +188,7 @@ public func autoregister(_ service: Service.Type, name: */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c) @@ -207,6 +209,7 @@ public func autoregister(_ service: Service.Type, */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c) @@ -267,6 +270,7 @@ public func autoregister(_ service: Service.Type, nam */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d) @@ -287,6 +291,7 @@ public func autoregister(_ service: Service.Typ */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d) @@ -347,6 +352,7 @@ public func autoregister(_ service: Service.Type, */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e) @@ -367,6 +373,7 @@ public func autoregister(_ service: Service. */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e) @@ -427,6 +434,7 @@ public func autoregister(_ service: Service.Typ */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E, F) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f) @@ -447,6 +455,7 @@ public func autoregister(_ service: Servi */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E, F) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f) @@ -507,6 +516,7 @@ public func autoregister(_ service: Service. */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E, F, G) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g) @@ -527,6 +537,7 @@ public func autoregister(_ service: Se */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E, F, G) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g) @@ -587,6 +598,7 @@ public func autoregister(_ service: Servi */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E, F, G, H) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2); let h: H? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h) @@ -607,6 +619,7 @@ public func autoregister(_ service: */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E, F, G, H) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3); let h: H? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h) @@ -667,6 +680,7 @@ public func autoregister(_ service: Se */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E, F, G, H, I) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2); let h: H? = r.resolve(arguments: arg1, arg2); let i: I? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h, i) @@ -687,6 +701,7 @@ public func autoregister(_ servi */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E, F, G, H, I) -> Service) -> ServiceEntry { + if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3); let h: H? = r.resolve(arguments: arg1, arg2, arg3); let i: I? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h, i) diff --git a/Sources/Warning.swift b/Sources/Warning.swift index 2e022b1..a555981 100644 --- a/Sources/Warning.swift +++ b/Sources/Warning.swift @@ -12,7 +12,7 @@ enum Warning { case optional(String) case implicitlyUnwrappedOptional(String) case tooManyDependencies(Int) - + case sameTypeDynamicArguments([String]) var message: String { switch self { case .optional(let name): @@ -21,6 +21,8 @@ enum Warning { return "⚠ AutoRegistration of implicitly unwrapped optional dependency (\(name))! is not supported. Use regular `register` method. " case .tooManyDependencies(let dependencyCount): return "⚠ AutoRegistration is limited to maximum of \(maxDependencies) dependencies, tried to resolve \(dependencyCount). Use regular `register` method instead. " + case .sameTypeDynamicArguments(let args): + return "⚠ AutoRegistration of service with same type arguments (\(args.joined(separator: ", "))) is not supported)" } } } @@ -63,3 +65,11 @@ func warnings(forInitializer initializer: (Parameters) -> S return warnings } +func hasUnique(arguments: [Any.Type]) -> Bool { + for (index, arg) in arguments.enumerated() { + if (arguments.enumerated().filter { index != $0 && arg == $1 }).count > 0 { + return false + } + } + return true +} diff --git a/Tests/AutoregistrationSpec.swift b/Tests/AutoregistrationSpec.swift index a6561e7..a418519 100644 --- a/Tests/AutoregistrationSpec.swift +++ b/Tests/AutoregistrationSpec.swift @@ -66,6 +66,12 @@ class AutoregistrationSpec: QuickSpec { init(a: DependencyA!){} } + class SameArgumentsService { + let nameA: String; let nameB: String + init(a: DependencyA, nameA: String, age: Int, nameB: String){ + self.nameA = nameA; self.nameB = nameB + } + } override func spec() { describe("autoregistration") { @@ -140,7 +146,38 @@ class AutoregistrationSpec: QuickSpec { let service = container.resolve(Service9.self) expect(service).notTo(beNil()) } - + + it("registers service with one dynamic argument") { + container.autoregister(Service2.self, argument: DependencyB.self, initializer: Service2.init) + let service = container.resolve(Service2.self, argument: DependencyB()) + expect(service).notTo(beNil()) + } + + it("registers service with two dynamic arguments") { + container.autoregister(Service3.self, arguments: DependencyB.self, DependencyC.self, initializer: Service3.init) + let service = container.resolve(Service3.self, arguments: DependencyB(), DependencyC()) + expect(service).notTo(beNil()) + } + + it("registers service with three dynamic arguments") { + container.autoregister(Service4.self, arguments: DependencyB.self, DependencyC.self, DependencyD.self, initializer: Service4.init) + let service = container.resolve(Service4.self, arguments: DependencyB(), DependencyC(), DependencyD()) + expect(service).notTo(beNil()) + } + + it("registers with arguments interchangeably") { + container.autoregister(Service4.self, arguments: DependencyC.self, DependencyD.self, DependencyB.self, initializer: Service4.init) + let service = container.resolve(Service4.self, arguments: DependencyC(), DependencyD(), DependencyB()) + expect(service).notTo(beNil()) + } + + xit("fails to pass arguments of the same type") { + container.autoregister(SameArgumentsService.self, arguments: String.self, Int.self, String.self, initializer: SameArgumentsService.init) + let service = container.resolve(SameArgumentsService.self, arguments: "NameA", 15, "NameB") + expect(service?.nameA) == "NameA" + expect(service?.nameB) == "NameB" + } + //TODO: Find a way how to test that assertion was thrown //This should fail because we generate register functions only for 10 dependencies xit("fails to register service with ten dependencies") { diff --git a/bin/generate b/bin/generate index eb4df28..c6c1227 100755 --- a/bin/generate +++ b/bin/generate @@ -96,10 +96,17 @@ func registerGenerator(_ dependenciesCount: Int, argumentsCount: Int, breakIntoV let closureParameters = commaConcat(["r"] + genericArgumentsVars) - let register = [ + var register = [ registerComment(dependenciesCount, arguments: argumentsCount), "@discardableResult", "public func autoregister<\(genericsDefinition)>(_ service: Service.Type, name: String? = nil\(argumentsDefinition), initializer: @escaping (\(concatenatedParameters)) -> Service) -> ServiceEntry {", + ] + + if argumentsCount > 1 { + register += [" if !hasUnique(arguments: [\(commaConcat(genericArgumentsVars))]) { fatalError(\"AutoRegistration of service with same type arguments (\(commaConcat(genericArgumentsVars.map{ "\\(\($0))" }))) is not supported)\") }"] + } + + register += [ " return self.register(service.self, name: name, factory: { \(closureParameters) in ", initializer, " } as (\(commaConcat(["ResolverType"] + genericArguments))) -> Service)", From 50c40ba26052f0d5e87633805a2cbdec846e0b29 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 22 Jan 2017 19:43:46 +0100 Subject: [PATCH 10/23] Updated quick and nimble, added assertion tests --- Cartfile.resolved | 4 +- Carthage/Checkouts/Nimble/.gitignore | 4 +- Carthage/Checkouts/Nimble/.travis.yml | 6 +- Carthage/Checkouts/Nimble/CONTRIBUTING.md | 8 + Carthage/Checkouts/Nimble/Gemfile | 2 +- Carthage/Checkouts/Nimble/Gemfile.lock | 54 ++- Carthage/Checkouts/Nimble/Nimble.podspec | 33 +- .../Nimble/Nimble.xcodeproj/project.pbxproj | 138 +++++- .../xcschemes/Nimble-tvOS.xcscheme | 4 +- Carthage/Checkouts/Nimble/Package.swift | 3 +- Carthage/Checkouts/Nimble/README.md | 86 +++- .../Nimble/Adapters/NimbleEnvironment.swift | 4 +- .../Nimble/Sources/Nimble/DSL+Wait.swift | 9 +- .../Nimble/Matchers/AsyncMatcherWrapper.swift | 6 +- .../Sources/Nimble/Matchers/BeLessThan.swift | 2 +- .../Sources/Nimble/Matchers/BeLogical.swift | 8 +- .../Sources/Nimble/Matchers/Match.swift | 4 +- .../Checkouts/Nimble/Sources/Nimble/Nimble.h | 7 + .../Nimble/Sources/Nimble/Utils/Async.swift | 29 +- .../Nimble/Sources/Nimble/Utils/Errors.swift | 17 +- .../Nimble/Sources/NimbleObjectiveC/DSL.h | 294 ++++++++++-- .../Nimble/Sources/NimbleObjectiveC/DSL.m | 22 +- .../Checkouts/Nimble/Tests/LinuxMain.swift | 4 +- .../Tests/NimbleTests/AsynchronousTest.swift | 10 +- .../Tests/NimbleTests/Helpers/utils.swift | 3 +- .../NimbleTests/Matchers/MatchErrorTest.swift | 5 + .../NimbleTests/Matchers/MatchTest.swift | 3 - .../NimbleTests/Matchers/ThrowErrorTest.swift | 1 - .../Tests/NimbleTests/SynchronousTests.swift | 6 +- .../NimbleTests/UserDescriptionTest.swift | 6 - .../NimbleTests/objc/ObjCBeCloseToTest.m | 11 + .../Tests/NimbleTests/objc/ObjCBeFalseTest.m | 22 + .../Tests/NimbleTests/objc/ObjCBeFalsyTest.m | 34 +- .../objc/ObjCBeGreaterThanOrEqualToTest.m | 9 + .../NimbleTests/objc/ObjCBeGreaterThanTest.m | 8 + .../NimbleTests/objc/ObjCBeIdenticalToTest.m | 6 + .../objc/ObjCBeLessThanOrEqualToTest.m | 10 + .../NimbleTests/objc/ObjCBeLessThanTest.m | 9 + .../Tests/NimbleTests/objc/ObjCBeTrueTest.m | 22 + .../Tests/NimbleTests/objc/ObjCBeTruthyTest.m | 27 ++ .../Tests/NimbleTests/objc/ObjCEqualTest.m | 59 +++ .../Tests/NimbleTests/objc/ObjCHaveCount.m | 71 ++- Carthage/Checkouts/Quick/.travis.yml | 6 +- .../Checkouts/Quick/Documentation/README.md | 1 + .../Documentation/en-us/InstallingQuick.md | 19 +- .../en-us/SettingUpYourXcodeProject.md | 9 +- .../Documentation/en-us/SharedExamples.md | 2 +- .../en-us/TestUsingTestDoubles.md | 68 +-- .../Quick/Documentation/zh-cn/README.md | 1 + .../Quick/Externals/Nimble/.gitignore | 4 +- .../Quick/Externals/Nimble/.travis.yml | 6 +- .../Quick/Externals/Nimble/CONTRIBUTING.md | 8 + .../Checkouts/Quick/Externals/Nimble/Gemfile | 2 +- .../Quick/Externals/Nimble/Gemfile.lock | 54 ++- .../Quick/Externals/Nimble/Nimble.podspec | 33 +- .../Nimble/Nimble.xcodeproj/project.pbxproj | 138 +++++- .../xcschemes/Nimble-tvOS.xcscheme | 4 +- .../Quick/Externals/Nimble/Package.swift | 3 +- .../Quick/Externals/Nimble/README.md | 86 +++- .../Nimble/Adapters/NimbleEnvironment.swift | 4 +- .../Nimble/Sources/Nimble/DSL+Wait.swift | 9 +- .../Nimble/Matchers/AsyncMatcherWrapper.swift | 6 +- .../Sources/Nimble/Matchers/BeLessThan.swift | 2 +- .../Sources/Nimble/Matchers/BeLogical.swift | 8 +- .../Sources/Nimble/Matchers/Match.swift | 4 +- .../Externals/Nimble/Sources/Nimble/Nimble.h | 7 + .../Nimble/Sources/Nimble/Utils/Async.swift | 29 +- .../Nimble/Sources/Nimble/Utils/Errors.swift | 17 +- .../Nimble/Sources/NimbleObjectiveC/DSL.h | 294 ++++++++++-- .../Nimble/Sources/NimbleObjectiveC/DSL.m | 22 +- .../Externals/Nimble/Tests/LinuxMain.swift | 4 +- .../Tests/NimbleTests/AsynchronousTest.swift | 10 +- .../Tests/NimbleTests/Helpers/utils.swift | 3 +- .../NimbleTests/Matchers/MatchErrorTest.swift | 5 + .../NimbleTests/Matchers/MatchTest.swift | 3 - .../NimbleTests/Matchers/ThrowErrorTest.swift | 1 - .../Tests/NimbleTests/SynchronousTests.swift | 6 +- .../NimbleTests/UserDescriptionTest.swift | 6 - .../NimbleTests/objc/ObjCBeCloseToTest.m | 11 + .../Tests/NimbleTests/objc/ObjCBeFalseTest.m | 22 + .../Tests/NimbleTests/objc/ObjCBeFalsyTest.m | 34 +- .../objc/ObjCBeGreaterThanOrEqualToTest.m | 9 + .../NimbleTests/objc/ObjCBeGreaterThanTest.m | 8 + .../NimbleTests/objc/ObjCBeIdenticalToTest.m | 6 + .../objc/ObjCBeLessThanOrEqualToTest.m | 10 + .../NimbleTests/objc/ObjCBeLessThanTest.m | 9 + .../Tests/NimbleTests/objc/ObjCBeTrueTest.m | 22 + .../Tests/NimbleTests/objc/ObjCBeTruthyTest.m | 27 ++ .../Tests/NimbleTests/objc/ObjCEqualTest.m | 59 +++ .../Tests/NimbleTests/objc/ObjCHaveCount.m | 71 ++- Carthage/Checkouts/Quick/Package.swift | 7 +- Carthage/Checkouts/Quick/Quick.podspec | 2 +- .../Quick/Quick.xcodeproj/project.pbxproj | 444 +++++++++++++++++- .../xcshareddata/xcschemes/Quick-iOS.xcscheme | 12 +- .../xcschemes/Quick-macOS.xcscheme | 12 +- .../xcschemes/Quick-tvOS.xcscheme | 12 +- Carthage/Checkouts/Quick/README.md | 16 + Carthage/Checkouts/Quick/Rakefile | 2 + .../Quick/Sources/Quick/Callsite.swift | 2 +- .../Quick/Configuration/Configuration.swift | 4 +- .../Quick/Sources/Quick/Example.swift | 4 +- .../Quick/Sources/Quick/ExampleGroup.swift | 2 +- .../Sources/Quick/Hooks/ExampleHooks.swift | 2 +- .../Quick/QuickSelectedTestSuiteBuilder.swift | 3 +- .../Quick/Sources/Quick/QuickSpec.swift | 2 +- .../Quick/Sources/Quick/String+FileName.swift | 12 - .../Checkouts/Quick/Sources/Quick/World.swift | 8 +- .../Checkouts/Quick/Tests/LinuxMain.swift | 4 +- .../QuickFocusedTests/FocusedTests.swift | 1 - .../QuickTests/QuickTestHelpers/TestRun.swift | 1 - .../QuickTestHelpers/XCTestCaseProvider.swift | 2 +- ...s_SharedExamplesTests_SharedExamples.swift | 2 +- .../FunctionalTests/AfterEachTests.swift | 10 +- .../FunctionalTests/AfterSuiteTests.swift | 45 -- .../FunctionalTests/BeforeEachTests.swift | 10 +- .../QuickTests/FunctionalTests/ItTests.swift | 20 +- .../ObjC/AfterSuiteTests+ObjC.m | 42 -- .../Helpers/QuickTestsBridgingHeader.h | 2 +- Sources/AutoRegistration.swift | 30 +- .../project.pbxproj | 45 ++ Tests/AutoregistrationSpec.swift | 42 +- bin/generate | 2 +- 122 files changed, 2466 insertions(+), 580 deletions(-) delete mode 100644 Carthage/Checkouts/Quick/Sources/Quick/String+FileName.swift delete mode 100644 Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/AfterSuiteTests.swift delete mode 100644 Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/ObjC/AfterSuiteTests+ObjC.m diff --git a/Cartfile.resolved b/Cartfile.resolved index c637c7b..e509607 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,4 +1,4 @@ -github "Quick/Nimble" "v5.0.0" -github "Quick/Quick" "v0.10.0" +github "Quick/Nimble" "v5.1.1" +github "Quick/Quick" "v1.0.0" github "Swinject/Swinject" "2.0.0-beta.2" github "jspahrsummers/xcconfigs" "0.10" diff --git a/Carthage/Checkouts/Nimble/.gitignore b/Carthage/Checkouts/Nimble/.gitignore index b067294..e50906d 100644 --- a/Carthage/Checkouts/Nimble/.gitignore +++ b/Carthage/Checkouts/Nimble/.gitignore @@ -1,5 +1,7 @@ .DS_Store -xcuserdata/ +**/xcuserdata/* +**/*.xccheckout +**/*.xcscmblueprint build/ .idea DerivedData/ diff --git a/Carthage/Checkouts/Nimble/.travis.yml b/Carthage/Checkouts/Nimble/.travis.yml index 977a75b..3e2f896 100644 --- a/Carthage/Checkouts/Nimble/.travis.yml +++ b/Carthage/Checkouts/Nimble/.travis.yml @@ -2,9 +2,9 @@ osx_image: xcode8 language: generic matrix: include: - # - os: osx - # sudo: required - # env: TYPE=podspec + - os: osx + sudo: required + env: TYPE=podspec - os: osx env: TYPE=ios NIMBLE_RUNTIME_IOS_SDK_VERSION=10.0 - os: osx diff --git a/Carthage/Checkouts/Nimble/CONTRIBUTING.md b/Carthage/Checkouts/Nimble/CONTRIBUTING.md index a97114f..d9c4ba6 100644 --- a/Carthage/Checkouts/Nimble/CONTRIBUTING.md +++ b/Carthage/Checkouts/Nimble/CONTRIBUTING.md @@ -46,6 +46,14 @@ Be sure to include in your issue: - Use `Nimble.xcodeproj` to work on Nimble. +## Running the Swift Package Manager tests + +1. Install `swiftenv` by running a line from the build script (`.travis.yml`): + + eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/02090c7ede5a637b76e6df1710e83cd0bbe7dcdf/swiftenv-install.sh)" + +2. Run `./test swiftpm` + ## Pull Requests - Nothing is trivial. Submit pull requests for anything: typos, diff --git a/Carthage/Checkouts/Nimble/Gemfile b/Carthage/Checkouts/Nimble/Gemfile index 66d7eff..a6dc312 100644 --- a/Carthage/Checkouts/Nimble/Gemfile +++ b/Carthage/Checkouts/Nimble/Gemfile @@ -1,4 +1,4 @@ # A sample Gemfile source "https://rubygems.org" -gem 'cocoapods' +gem 'cocoapods', '1.1.0.rc.3' diff --git a/Carthage/Checkouts/Nimble/Gemfile.lock b/Carthage/Checkouts/Nimble/Gemfile.lock index 374561e..87dc02b 100644 --- a/Carthage/Checkouts/Nimble/Gemfile.lock +++ b/Carthage/Checkouts/Nimble/Gemfile.lock @@ -1,67 +1,69 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.2.6) + activesupport (4.2.7.1) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - claide (1.0.0) - cocoapods (1.0.1) - activesupport (>= 4.0.2) - claide (>= 1.0.0, < 2.0) - cocoapods-core (= 1.0.1) - cocoapods-deintegrate (>= 1.0.0, < 2.0) - cocoapods-downloader (>= 1.0.0, < 2.0) + claide (1.0.1) + cocoapods (1.1.0.rc.3) + activesupport (>= 4.0.2, < 5) + claide (>= 1.0.1, < 2.0) + cocoapods-core (= 1.1.0.rc.3) + cocoapods-deintegrate (>= 1.0.1, < 2.0) + cocoapods-downloader (>= 1.1.1, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.0.0, < 2.0) - cocoapods-try (>= 1.0.0, < 2.0) + cocoapods-trunk (= 1.1.0.beta.1) + cocoapods-try (>= 1.1.0, < 2.0) colored (~> 1.2) escape (~> 0.0.4) - fourflusher (~> 0.3.0) - molinillo (~> 0.4.5) + fourflusher (~> 2.0) + gh_inspector (~> 1.0) + molinillo (~> 0.5.1) nap (~> 1.0) - xcodeproj (>= 1.1.0, < 2.0) - cocoapods-core (1.0.1) - activesupport (>= 4.0.2) + xcodeproj (>= 1.3.2, < 2.0) + cocoapods-core (1.1.0.rc.3) + activesupport (>= 4.0.2, < 5) fuzzy_match (~> 2.0.4) nap (~> 1.0) - cocoapods-deintegrate (1.0.0) - cocoapods-downloader (1.0.1) + cocoapods-deintegrate (1.0.1) + cocoapods-downloader (1.1.1) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.0) cocoapods-stats (1.0.0) - cocoapods-trunk (1.0.0) + cocoapods-trunk (1.1.0.beta.1) nap (>= 0.8, < 2.0) netrc (= 0.7.8) - cocoapods-try (1.0.0) + cocoapods-try (1.1.0) colored (1.2) escape (0.0.4) - fourflusher (0.3.2) + fourflusher (2.0.1) fuzzy_match (2.0.4) + gh_inspector (1.0.2) i18n (0.7.0) json (1.8.3) - minitest (5.9.0) - molinillo (0.4.5) + minitest (5.9.1) + molinillo (0.5.1) nap (1.1.0) netrc (0.7.8) thread_safe (0.3.5) tzinfo (1.2.2) thread_safe (~> 0.1) - xcodeproj (1.1.0) + xcodeproj (1.3.2) activesupport (>= 3) - claide (>= 1.0.0, < 2.0) + claide (>= 1.0.1, < 2.0) colored (~> 1.2) PLATFORMS ruby DEPENDENCIES - cocoapods + cocoapods (= 1.1.0.rc.3) BUNDLED WITH - 1.12.3 + 1.13.1 diff --git a/Carthage/Checkouts/Nimble/Nimble.podspec b/Carthage/Checkouts/Nimble/Nimble.podspec index 5fa0974..8ca36a1 100644 --- a/Carthage/Checkouts/Nimble/Nimble.podspec +++ b/Carthage/Checkouts/Nimble/Nimble.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Nimble" - s.version = "5.0.0" + s.version = "5.1.1" 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. @@ -11,12 +11,37 @@ Pod::Spec.new do |s| s.ios.deployment_target = "8.0" s.osx.deployment_target = "10.10" s.tvos.deployment_target = "9.0" - s.source = { :git => "https://github.com/Quick/Nimble.git", :tag => "v#{s.version}" } + s.source = { :git => "https://github.com/Quick/Nimble.git", + :tag => "v#{s.version}" } + + s.source_files = "Sources/**/*.{swift,h,m,c}" + + s.osx.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift", + ] + s.ios.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift", + ] + s.tvos.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.{h,c}", + "Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException.swift", + "Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException.m", + ] - s.source_files = "Sources/**/**/*.{swift,h,m}" s.private_header_files = "Sources/NimbleObjectiveC/CurrentTestCaseTracker.h" + s.tvos.private_header_files = "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h" + s.exclude_files = "Sources/Nimble/Adapters/NonObjectiveC/*.swift" 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"' } + s.compiler_flags = '-DPRODUCT_NAME=Nimble/Nimble' + 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 index c6fe033..7c2c084 100644 --- a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.pbxproj +++ b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/project.pbxproj @@ -48,12 +48,15 @@ 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 */; }; + 1F2D175B1DB618ED00EE9C7A /* mach_excServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0261C6D0BB0000693EE /* mach_excServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F2D175C1DB618F000EE9C7A /* mach_excServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0221C6D0B82000693EE /* mach_excServer.c */; }; 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 */; }; + 1F4999A61DBF2DD100BF8877 /* Nimble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F1A742E1940169200FFFC47 /* Nimble.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; @@ -94,6 +97,14 @@ 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 */; }; + 1F4BB8A41DAC9DC90048464B /* CwlCatchBadInstructionPOSIX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */; }; + 1F4BB8AB1DAC9DE50048464B /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F4BB8AE1DAC9DED0048464B /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F4BB8B61DACA0E30048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8B71DACA0E40048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8B81DACAACF0048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8BA1DACBFCF0048464B /* CwlCatchBadInstruction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */; }; + 1F4BB8BB1DACBFD00048464B /* CwlCatchBadInstruction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */; }; 1F5DF15F1BDCA0CE00C3A531 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F5DF1551BDCA0CE00C3A531 /* Nimble.framework */; }; 1F5DF16C1BDCA0F500C3A531 /* AssertionRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD051968AB07008ED995 /* AssertionRecorder.swift */; }; 1F5DF16D1BDCA0F500C3A531 /* AdapterProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD061968AB07008ED995 /* AdapterProtocols.swift */; }; @@ -155,7 +166,6 @@ 1F5DF1A91BDCA10200C3A531 /* MatchTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB4D5EF19FE442800E9D9FE /* MatchTest.swift */; }; 1F5DF1AA1BDCA10200C3A531 /* RaisesExceptionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EEB195C12C800ED456B /* RaisesExceptionTest.swift */; }; 1F5DF1AB1BDCA10200C3A531 /* ThrowErrorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29EA59621B551ED2002D767E /* ThrowErrorTest.swift */; }; - 1F5DF1AE1BDCA17600C3A531 /* Nimble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F1A742E1940169200FFFC47 /* Nimble.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1F8A37B01B7C5042001C8357 /* ObjCSyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */; }; 1F8A37B11B7C5042001C8357 /* ObjCSyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */; }; 1F91DD2D1C74BF36002C309F /* BeVoidTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F91DD2C1C74BF36002C309F /* BeVoidTest.swift */; }; @@ -282,11 +292,25 @@ 7B5358BE1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; 7B5358BF1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; 7B5358C01C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; - 7B5358C51C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */; }; - 7B5358C61C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */; }; - 8DF1C3F71C94FC75004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; - 8DF1C3F81C94FC75004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; - 8DF1C3F91C94FD0C004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; + 9630C00D1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C00E1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C0131C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */; }; + 9630C0141C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */; }; + 9630C0191C6D0B2F000693EE /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C01A1C6D0B2F000693EE /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C01C1C6D0B2F000693EE /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0171C6D0B2F000693EE /* CwlCatchException.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 9630C01D1C6D0B2F000693EE /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0171C6D0B2F000693EE /* CwlCatchException.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 9630C01F1C6D0B2F000693EE /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */; }; + 9630C0201C6D0B2F000693EE /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */; }; + 9630C0231C6D0B82000693EE /* mach_excServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0221C6D0B82000693EE /* mach_excServer.c */; }; + 9630C0271C6D0BB0000693EE /* mach_excServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0261C6D0BB0000693EE /* mach_excServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C02C1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */; }; + 9630C02D1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */; }; + 9630C0301C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */; }; + 9630C0311C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */; }; + 964CFEFD1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; + 964CFEFE1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; + 964CFEFF1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.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 */; }; @@ -455,6 +479,8 @@ 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 = ""; }; + 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchBadInstructionPOSIX.swift; path = CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift; sourceTree = ""; }; + 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowAssertionTest.swift; sourceTree = ""; }; 1F5DF1551BDCA0CE00C3A531 /* Nimble.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1F5DF15E1BDCA0CE00C3A531 /* NimbleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSyncTest.m; sourceTree = ""; }; @@ -521,6 +547,17 @@ 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SatisfyAnyOf.swift; sourceTree = ""; }; 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSatisfyAnyOfTest.m; sourceTree = ""; }; 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjcStringersTest.m; sourceTree = ""; }; + 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CwlCatchBadInstruction.h; path = CwlPreconditionTesting/CwlCatchBadInstruction.h; sourceTree = ""; }; + 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CwlCatchBadInstruction.m; path = CwlPreconditionTesting/CwlCatchBadInstruction.m; sourceTree = ""; }; + 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchBadInstruction.swift; path = CwlPreconditionTesting/CwlCatchBadInstruction.swift; sourceTree = ""; }; + 9630C0161C6D0B2F000693EE /* CwlCatchException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CwlCatchException.h; path = CwlCatchException/CwlCatchException/CwlCatchException.h; sourceTree = ""; }; + 9630C0171C6D0B2F000693EE /* CwlCatchException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CwlCatchException.m; path = CwlCatchException/CwlCatchException/CwlCatchException.m; sourceTree = ""; }; + 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchException.swift; path = CwlCatchException/CwlCatchException/CwlCatchException.swift; sourceTree = ""; }; + 9630C0221C6D0B82000693EE /* mach_excServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mach_excServer.c; path = CwlPreconditionTesting/mach_excServer.c; sourceTree = ""; }; + 9630C0261C6D0BB0000693EE /* mach_excServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mach_excServer.h; path = CwlPreconditionTesting/mach_excServer.h; sourceTree = ""; }; + 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlBadInstructionException.swift; path = CwlPreconditionTesting/CwlBadInstructionException.swift; sourceTree = ""; }; + 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlDarwinDefinitions.swift; path = CwlPreconditionTesting/CwlDarwinDefinitions.swift; sourceTree = ""; }; + 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowAssertion.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 = ""; }; AE4BA9AC1C88DDB500B73906 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; @@ -627,6 +664,7 @@ 1F1A742B1940169200FFFC47 /* Nimble */, 1F1871B91CA89E1B00A34BF2 /* NimbleObjectiveC */, 1F1A74381940169200FFFC47 /* NimbleTests */, + 9630C0081C6D0AB3000693EE /* Lib */, 1F1A742A1940169200FFFC47 /* Products */, ); indentWidth = 4; @@ -717,6 +755,7 @@ 7B5358B91C3846C900A23FAA /* SatisfyAnyOfTest.swift */, 1FCF914E1C61C85A00B15DCB /* PostNotificationTest.swift */, AE7ADE481C80C00D00B94CD3 /* MatchErrorTest.swift */, + 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */, ); path = Matchers; sourceTree = ""; @@ -764,6 +803,7 @@ AE7ADE441C80BF8000B94CD3 /* MatchError.swift */, 1FCF91521C61C8A400B15DCB /* PostNotification.swift */, 1FD8CD1E1968AB07008ED995 /* RaisesException.swift */, + 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */, 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */, 29EA59651B551EE6002D767E /* ThrowError.swift */, ); @@ -817,6 +857,33 @@ path = objc; sourceTree = ""; }; + 9630C0081C6D0AB3000693EE /* Lib */ = { + isa = PBXGroup; + children = ( + 9630C0091C6D0ABA000693EE /* CwlPreconditionTesting */, + ); + name = Lib; + path = Sources/Lib; + sourceTree = ""; + }; + 9630C0091C6D0ABA000693EE /* CwlPreconditionTesting */ = { + isa = PBXGroup; + children = ( + 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */, + 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */, + 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */, + 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */, + 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */, + 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */, + 9630C0161C6D0B2F000693EE /* CwlCatchException.h */, + 9630C0171C6D0B2F000693EE /* CwlCatchException.m */, + 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */, + 9630C0261C6D0BB0000693EE /* mach_excServer.h */, + 9630C0221C6D0B82000693EE /* mach_excServer.c */, + ); + path = CwlPreconditionTesting; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -824,10 +891,13 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 9630C00D1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */, + 9630C0191C6D0B2F000693EE /* CwlCatchException.h in Headers */, 1F1871C91CA89EDB00A34BF2 /* NMBStringify.h in Headers */, 1F1871C51CA89EDB00A34BF2 /* DSL.h in Headers */, 1F1871C71CA89EDB00A34BF2 /* NMBExceptionCapture.h in Headers */, 1F1A742F1940169200FFFC47 /* Nimble.h in Headers */, + 9630C0271C6D0BB0000693EE /* mach_excServer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -835,10 +905,12 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1F4BB8AE1DAC9DED0048464B /* CwlCatchException.h in Headers */, 1F1871E21CA89EF600A34BF2 /* NMBStringify.h in Headers */, 1F1871E01CA89EF600A34BF2 /* DSL.h in Headers */, 1F1871E11CA89EF600A34BF2 /* NMBExceptionCapture.h in Headers */, - 1F5DF1AE1BDCA17600C3A531 /* Nimble.h in Headers */, + 1F4BB8AB1DAC9DE50048464B /* CwlCatchBadInstruction.h in Headers */, + 1F4999A61DBF2DD100BF8877 /* Nimble.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -846,6 +918,9 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 9630C00E1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */, + 9630C01A1C6D0B2F000693EE /* CwlCatchException.h in Headers */, + 1F2D175B1DB618ED00EE9C7A /* mach_excServer.h in Headers */, 1F1871DF1CA89EF500A34BF2 /* NMBStringify.h in Headers */, 1F1871DD1CA89EF500A34BF2 /* DSL.h in Headers */, 1F1871DE1CA89EF500A34BF2 /* NMBExceptionCapture.h in Headers */, @@ -1109,6 +1184,7 @@ 1F1871C61CA89EDB00A34BF2 /* DSL.m in Sources */, 1FD8CD301968AB07008ED995 /* AdapterProtocols.swift in Sources */, AE7ADE451C80BF8000B94CD3 /* MatchError.swift in Sources */, + 1F4BB8BA1DACBFCF0048464B /* CwlCatchBadInstruction.m in Sources */, 1FC494AA1C29CBA40010975C /* NimbleEnvironment.swift in Sources */, 1FD8CD5E1968AB07008ED995 /* RaisesException.swift in Sources */, 1FD8CD561968AB07008ED995 /* Contain.swift in Sources */, @@ -1128,6 +1204,13 @@ 1FD8CD381968AB07008ED995 /* Expression.swift in Sources */, 1FD8CD3A1968AB07008ED995 /* FailureMessage.swift in Sources */, 472FD1351B9E085700C7B8DA /* HaveCount.swift in Sources */, + 9630C0301C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */, + 9630C0231C6D0B82000693EE /* mach_excServer.c in Sources */, + 9630C01F1C6D0B2F000693EE /* CwlCatchException.swift in Sources */, + 9630C0131C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */, + 9630C01C1C6D0B2F000693EE /* CwlCatchException.m in Sources */, + 9630C02C1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */, + 964CFEFD1C4FF48900513336 /* ThrowAssertion.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1146,7 +1229,6 @@ DDB4D5F019FE442800E9D9FE /* MatchTest.swift in Sources */, 1F4A56731A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */, 1F4A56821A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */, - 8DF1C3F71C94FC75004B2D36 /* ObjcStringersTest.m in Sources */, 1F925F02195C189500ED456B /* ContainTest.swift in Sources */, 1F4A56881A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */, 1F4A568E1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */, @@ -1179,6 +1261,7 @@ 1F0648CC19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */, 1F4A56851A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */, DD9A9A8F19CF439B00706F49 /* BeIdenticalToObjectTest.swift in Sources */, + 1F4BB8B71DACA0E40048464B /* ThrowAssertionTest.swift in Sources */, 1F0648D41963AAB2001F9C46 /* SynchronousTests.swift in Sources */, 347155CA1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 4793854D1BA0BB2500296F85 /* ObjCHaveCount.m in Sources */, @@ -1187,7 +1270,6 @@ 1F925F05195C18B700ED456B /* EqualTest.swift in Sources */, 1F4A566D1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */, DD72EC641A93874A002F7651 /* AllPassTest.swift in Sources */, - 7B5358C51C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */, 1F4A569D1A3B3565009E1637 /* ObjCMatchTest.m in Sources */, 1F925EE9195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */, 29EA59631B551ED2002D767E /* ThrowErrorTest.swift in Sources */, @@ -1220,6 +1302,7 @@ 1F5DF1781BDCA0F500C3A531 /* BeAnInstanceOf.swift in Sources */, 1F5DF1771BDCA0F500C3A531 /* BeAKindOf.swift in Sources */, 1F5DF17F1BDCA0F500C3A531 /* BeLessThan.swift in Sources */, + 1F4BB8A41DAC9DC90048464B /* CwlCatchBadInstructionPOSIX.swift in Sources */, 1F5DF17C1BDCA0F500C3A531 /* BeGreaterThan.swift in Sources */, 1F91DD331C74BF61002C309F /* BeVoid.swift in Sources */, 1FCF91551C61C8A400B15DCB /* PostNotification.swift in Sources */, @@ -1242,6 +1325,7 @@ 1F1871D81CA89EEF00A34BF2 /* NMBStringify.m in Sources */, 1F5DF1821BDCA0F500C3A531 /* BeNil.swift in Sources */, 1F5DF16F1BDCA0F500C3A531 /* AssertionDispatcher.swift in Sources */, + 964CFEFF1C4FF48900513336 /* ThrowAssertion.swift in Sources */, 1F5DF1841BDCA0F500C3A531 /* EndWith.swift in Sources */, 1F5DF18D1BDCA0F500C3A531 /* SourceLocation.swift in Sources */, 1F5DF1701BDCA0F500C3A531 /* DSL.swift in Sources */, @@ -1301,13 +1385,13 @@ CD79C9A51D2CC848004B6F9A /* ObjCBeginWithTest.m in Sources */, 347155CC1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 1F5DF1AA1BDCA10200C3A531 /* RaisesExceptionTest.swift in Sources */, - 8DF1C3F91C94FD0C004B2D36 /* ObjcStringersTest.m in Sources */, 1F5DF1941BDCA10200C3A531 /* UserDescriptionTest.swift in Sources */, CD79C9AF1D2CC848004B6F9A /* ObjCContainTest.m in Sources */, 1F5DF19F1BDCA10200C3A531 /* BeIdenticalToObjectTest.swift in Sources */, CD79C99E1D2CC832004B6F9A /* ObjCAsyncTest.m in Sources */, 1F91DD2F1C74BF36002C309F /* BeVoidTest.swift in Sources */, 6CAEDD0C1CAEA86F003F1584 /* LinuxSupport.swift in Sources */, + 1F4BB8B81DACAACF0048464B /* ThrowAssertionTest.swift in Sources */, CD79C9B71D2CC848004B6F9A /* ObjCSatisfyAnyOfTest.m in Sources */, 1F5DF1991BDCA10200C3A531 /* BeAnInstanceOfTest.swift in Sources */, CD79C9B11D2CC848004B6F9A /* ObjCEqualTest.m in Sources */, @@ -1350,7 +1434,9 @@ F8A1BE301CB3710900031679 /* XCTestObservationCenter+Register.m in Sources */, 1F1871DA1CA89EF100A34BF2 /* NMBObjCMatcher.swift in Sources */, 1FD8CD311968AB07008ED995 /* AdapterProtocols.swift in Sources */, + 1F2D175C1DB618F000EE9C7A /* mach_excServer.c in Sources */, 1F1871D21CA89EEE00A34BF2 /* DSL.m in Sources */, + 1F4BB8BB1DACBFD00048464B /* CwlCatchBadInstruction.m in Sources */, AE7ADE461C80BF8000B94CD3 /* MatchError.swift in Sources */, 1FC494AB1C29CBA40010975C /* NimbleEnvironment.swift in Sources */, 1FD8CD5F1968AB07008ED995 /* RaisesException.swift in Sources */, @@ -1363,6 +1449,7 @@ 1F1871D41CA89EEE00A34BF2 /* NMBStringify.m in Sources */, 1FD8CD531968AB07008ED995 /* BeNil.swift in Sources */, 1FD8CD6B1968AB07008ED995 /* Async.swift in Sources */, + 964CFEFE1C4FF48900513336 /* ThrowAssertion.swift in Sources */, 1FD8CD591968AB07008ED995 /* EndWith.swift in Sources */, 1FD8CD5D1968AB07008ED995 /* MatcherProtocols.swift in Sources */, 1FD8CD351968AB07008ED995 /* DSL.swift in Sources */, @@ -1370,6 +1457,11 @@ 1FD8CD391968AB07008ED995 /* Expression.swift in Sources */, 1FD8CD3B1968AB07008ED995 /* FailureMessage.swift in Sources */, 472FD1391B9E0A9700C7B8DA /* HaveCount.swift in Sources */, + 9630C0311C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */, + 9630C0201C6D0B2F000693EE /* CwlCatchException.swift in Sources */, + 9630C0141C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */, + 9630C01D1C6D0B2F000693EE /* CwlCatchException.m in Sources */, + 9630C02D1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1388,7 +1480,6 @@ DDB4D5F119FE442800E9D9FE /* MatchTest.swift in Sources */, 1F4A56741A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */, 1F4A56831A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */, - 8DF1C3F81C94FC75004B2D36 /* ObjcStringersTest.m in Sources */, 1F925F03195C189500ED456B /* ContainTest.swift in Sources */, 1F4A56891A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */, 1F4A568F1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */, @@ -1421,6 +1512,7 @@ 1F0648CD19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */, 1F4A56861A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */, DD9A9A9019CF43AD00706F49 /* BeIdenticalToObjectTest.swift in Sources */, + 1F4BB8B61DACA0E30048464B /* ThrowAssertionTest.swift in Sources */, 1F0648D51963AAB2001F9C46 /* SynchronousTests.swift in Sources */, 347155CB1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 4793854E1BA0BB2500296F85 /* ObjCHaveCount.m in Sources */, @@ -1429,7 +1521,6 @@ 1F925F06195C18B700ED456B /* EqualTest.swift in Sources */, 1F4A566E1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */, DD72EC651A93874A002F7651 /* AllPassTest.swift in Sources */, - 7B5358C61C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */, 1F4A569E1A3B3565009E1637 /* ObjCMatchTest.m in Sources */, 1F925EEA195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */, 29EA59641B551ED2002D767E /* ThrowErrorTest.swift in Sources */, @@ -1607,6 +1698,11 @@ "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(DEVELOPER_FRAMEWORKS_DIR)", ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1638,6 +1734,10 @@ "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(DEVELOPER_FRAMEWORKS_DIR)", ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1709,6 +1809,11 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1742,6 +1847,10 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1818,6 +1927,7 @@ FRAMEWORK_VERSION = A; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", "$(inherited)", ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; @@ -1853,6 +1963,10 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); FRAMEWORK_VERSION = A; + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; diff --git a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme index c1c4ade..2309132 100644 --- a/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme +++ b/Carthage/Checkouts/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme @@ -24,8 +24,8 @@ Void in fatalError() }.to(throwAssertion()) +expect { precondition(false) }.to(throwAssertion()) + +// Passes if throwing a NSError is not equal to throwing an assertion: +expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion()) + +// Passes if the post assertion code is not run: +var reachedPoint1 = false +var reachedPoint2 = false +expect { + reachedPoint1 = true + precondition(false, "condition message") + reachedPoint2 = true +}.to(throwAssertion()) + +expect(reachedPoint1) == true +expect(reachedPoint2) == false +``` + +Notes: + +* This feature is only available in Swift. +* It is only supported for `x86_64` binaries, meaning _you cannot run this matcher on iOS devices, only simulators_. +* The tvOS simulator is supported, but using a different mechanism, requiring you to turn off the `Debug executable` scheme setting for your tvOS scheme's Test configuration. + ## Swift Error Handling If you're using Swift 2.0+, you can use the `throwError` matcher to check if an error is thrown. @@ -975,10 +1047,10 @@ expect(actual).to(satisfyAnyOf(beLessThan(@10), beGreaterThan(@20))) expect(@6).to(satisfyAnyOf(equal(@2), equal(@3), equal(@4), equal(@5), equal(@6), equal(@7))) ``` -Note: This matcher allows you to chain any number of matchers together. This provides flexibility, - but if you find yourself chaining many matchers together in one test, consider whether you - could instead refactor that single test into multiple, more precisely focused tests for - better coverage. +Note: This matcher allows you to chain any number of matchers together. This provides flexibility, + but if you find yourself chaining many matchers together in one test, consider whether you + could instead refactor that single test into multiple, more precisely focused tests for + better coverage. # Writing Your Own Matchers @@ -1189,7 +1261,7 @@ extension NMBObjCMatcher { > 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). + Documentation](https://github.com/Quick/Quick/blob/master/Documentation/en-us/InstallingQuick.md). Nimble can currently be installed in one of two ways: using CocoaPods, or with git submodules. @@ -1224,7 +1296,7 @@ source 'https://github.com/CocoaPods/Specs.git' target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do use_frameworks! - pod 'Nimble', '~> 4.0.0' + pod 'Nimble', '~> 5.0.0' end ``` diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift index 5434aaf..a55cb27 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift @@ -1,3 +1,4 @@ +import Dispatch import Foundation /// "Global" state of Nimble is stored here. Only DSL functions should access / be aware of this @@ -25,7 +26,7 @@ internal class NimbleEnvironment { set { NimbleAssertionHandler = newValue } } -#if _runtime(_ObjC) + var suppressTVOSAssertionWarning: Bool = false var awaiter: Awaiter init() { @@ -41,5 +42,4 @@ internal class NimbleEnvironment { asyncQueue: .main, timeoutQueue: timeoutQueue) } -#endif } diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/DSL+Wait.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/DSL+Wait.swift index fa5a10f..619b6dc 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/DSL+Wait.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/DSL+Wait.swift @@ -1,6 +1,6 @@ +import Dispatch import Foundation -#if _runtime(_ObjC) private enum ErrorResult { case exception(NSException) case error(Error) @@ -70,10 +70,16 @@ internal class NMBWait: NSObject { } } + #if _runtime(_ObjC) @objc(untilFile:line:action:) internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) -> Void { until(timeout: 1, file: file, line: line, action: action) } + #else + internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) -> Void { + until(timeout: 1, file: file, line: line, action: action) + } + #endif } internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: TimeInterval) -> String { @@ -90,4 +96,3 @@ internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: TimeInterv public func waitUntil(timeout: TimeInterval = 1, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) -> Void { NMBWait.until(timeout: timeout, file: file, line: line, action: action) } -#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift index c028f5a..6b89c76 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift @@ -1,7 +1,7 @@ import Foundation -#if _runtime(_ObjC) - +/// If you are running on a slower machine, it could be useful to increase the default timeout value +/// or slow down poll interval. Default timeout interval is 1, and poll interval is 0.01. public struct AsyncDefaults { public static var Timeout: TimeInterval = 1 public static var PollInterval: TimeInterval = 0.01 @@ -144,5 +144,3 @@ extension Expectation { return toEventuallyNot(matcher, timeout: timeout, pollInterval: pollInterval, description: description) } } - -#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLessThan.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLessThan.swift index 4cd1a05..fbcd7c7 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLessThan.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLessThan.swift @@ -33,7 +33,7 @@ public func <(lhs: Expectation, rhs: NMBComparable?) { extension NMBObjCMatcher { public class func beLessThanMatcher(_ expected: NMBComparable?) -> NMBObjCMatcher { return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in - let expr = actualExpression.cast { $0 as! NMBComparable? } + let expr = actualExpression.cast { $0 as? NMBComparable } return try! beLessThan(expected).matches(expr, failureMessage: failureMessage) } } diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLogical.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLogical.swift index ee62928..49272a3 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLogical.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/BeLogical.swift @@ -144,28 +144,28 @@ public func beFalsy() -> MatcherFunc extension NMBObjCMatcher { public class func beTruthyMatcher() -> NMBObjCMatcher { return NMBObjCMatcher { actualExpression, failureMessage in - let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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 Bool? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } return try! beFalse().matches(expr, failureMessage: failureMessage) } } diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/Match.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/Match.swift index c225f88..3ad5fb5 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/Match.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/Match.swift @@ -1,7 +1,5 @@ import Foundation -#if _runtime(_ObjC) - /// A Nimble matcher that succeeds when the actual string satisfies the regular expression /// described by the expected string. public func match(_ expectedValue: String?) -> NonNilMatcherFunc { @@ -18,6 +16,8 @@ public func match(_ expectedValue: String?) -> NonNilMatcherFunc { } } +#if _runtime(_ObjC) + extension NMBObjCMatcher { public class func matchMatcher(_ expected: NSString) -> NMBMatcher { return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Nimble.h b/Carthage/Checkouts/Nimble/Sources/Nimble/Nimble.h index 1eab61a..790d16d 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Nimble.h +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Nimble.h @@ -3,5 +3,12 @@ #import "NMBStringify.h" #import "DSL.h" +#import "CwlCatchException.h" +#import "CwlCatchBadInstruction.h" + +#if !TARGET_OS_TV + #import "mach_excServer.h" +#endif + FOUNDATION_EXPORT double NimbleVersionNumber; FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Async.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Async.swift index a78a147..c902692 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Async.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Async.swift @@ -1,10 +1,13 @@ +import CoreFoundation +import Dispatch import Foundation -#if _runtime(_ObjC) -import Dispatch +#if !_runtime(_ObjC) + import CDispatch +#endif -private let timeoutLeeway = DispatchTimeInterval.nanoseconds(Int(NSEC_PER_MSEC)) -private let pollLeeway = DispatchTimeInterval.nanoseconds(Int(NSEC_PER_MSEC)) +private let timeoutLeeway = DispatchTimeInterval.milliseconds(1) +private let pollLeeway = DispatchTimeInterval.milliseconds(1) /// Stores debugging information about callers internal struct WaitingInfo: CustomStringConvertible { @@ -29,8 +32,13 @@ internal class AssertionWaitLock: WaitLock { func acquireWaitingLock(_ fnName: String, file: FileString, line: UInt) { let info = WaitingInfo(name: fnName, file: file, lineNumber: line) + #if _runtime(_ObjC) + let isMainThread = Thread.isMainThread + #else + let isMainThread = _CFIsMainThread() + #endif nimblePrecondition( - Thread.isMainThread, + isMainThread, "InvalidNimbleAPIUsage", "\(fnName) can only run on the main thread." ) @@ -177,7 +185,12 @@ internal class AwaitPromiseBuilder { let semTimedOutOrBlocked = DispatchSemaphore(value: 0) semTimedOutOrBlocked.signal() let runLoop = CFRunLoopGetMain() - CFRunLoopPerformBlock(runLoop, CFRunLoopMode.defaultMode.rawValue) { + #if _runtime(_ObjC) + let runLoopMode = CFRunLoopMode.defaultMode.rawValue + #else + let runLoopMode = kCFRunLoopDefaultMode + #endif + CFRunLoopPerformBlock(runLoop, runLoopMode) { if semTimedOutOrBlocked.wait(timeout: .now()) == .success { timedOutSem.signal() semTimedOutOrBlocked.signal() @@ -237,7 +250,7 @@ internal class AwaitPromiseBuilder { self.trigger.timeoutSource.resume() while self.promise.asyncResult.isIncomplete() { // Stopping the run loop does not work unless we run only 1 mode - RunLoop.current.run(mode: .defaultRunLoopMode, before: .distantFuture) + _ = RunLoop.current.run(mode: .defaultRunLoopMode, before: .distantFuture) } self.trigger.timeoutSource.suspend() self.trigger.timeoutSource.cancel() @@ -346,5 +359,3 @@ internal func pollBlock( return result } - -#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Errors.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Errors.swift index 54bed92..d424c98 100644 --- a/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Errors.swift +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Utils/Errors.swift @@ -77,14 +77,21 @@ internal func errorMatchesNonNilFieldsOrClosure( matches = false } } - } else if errorType != nil && closure != nil { + } else if errorType != nil { + matches = (actualError is T) // The closure expects another ErrorProtocol as argument, so this // is _supposed_ to fail, so that it becomes more obvious. - let assertions = gatherExpectations { - expect(actualError is T).to(equal(true)) + if let closure = closure { + let assertions = gatherExpectations { + if let actual = actualError as? T { + closure(actual) + } + } + let messages = assertions.map { $0.message } + if messages.count > 0 { + matches = false + } } - precondition(assertions.map { $0.message }.count > 0) - matches = false } } diff --git a/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.h b/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.h index a499059..54677ee 100644 --- a/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.h +++ b/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.h @@ -6,48 +6,222 @@ @protocol NMBMatcher; +NS_ASSUME_NONNULL_BEGIN + + +#define NIMBLE_OVERLOADABLE __attribute__((overloadable)) #define NIMBLE_EXPORT FOUNDATION_EXPORT +#define NIMBLE_EXPORT_INLINE FOUNDATION_STATIC_INLINE + +#define NIMBLE_VALUE_OF(VAL) ({ \ + __typeof__((VAL)) val = (VAL); \ + [NSValue valueWithBytes:&val objCType:@encode(__typeof__((VAL)))]; \ +}) #ifdef NIMBLE_DISABLE_SHORT_SYNTAX #define NIMBLE_SHORT(PROTO, ORIGINAL) +#define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) #else #define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); } +#define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE NIMBLE_OVERLOADABLE PROTO { return (ORIGINAL); } #endif -NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line); + + +#define DEFINE_NMB_EXPECT_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBExpectation *NMB_expect(TYPE(^actualBlock)(), NSString *file, NSUInteger line) { \ + return NMB_expect(^id { return EXPR; }, file, line); \ + } + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line); + + // overloaded dispatch for nils - expect(nil) + DEFINE_NMB_EXPECT_OVERLOAD(void*, nil) + DEFINE_NMB_EXPECT_OVERLOAD(NSRange, NIMBLE_VALUE_OF(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(int, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned int, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(float, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(double, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(long long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned long long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(char, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned char, @(actualBlock())) + // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow + // the compiler to dispatch to bool. + DEFINE_NMB_EXPECT_OVERLOAD(BOOL, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(char *, @(actualBlock())) + + +#undef DEFINE_NMB_EXPECT_OVERLOAD + + + 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 id NMB_haveCount(id expectedValue); -NIMBLE_SHORT(id haveCount(id expectedValue), - NMB_haveCount(expectedValue)); -NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue); -NIMBLE_SHORT(NMBObjCBeCloseToMatcher *beCloseTo(id expectedValue), - NMB_beCloseTo(expectedValue)); +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_equal(TYPE expectedValue) { \ + return NMB_equal((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id equal(TYPE expectedValue), NMB_equal(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_equal(__nullable id expectedValue); + + NIMBLE_SHORT_OVERLOADED(id equal(__nullable id expectedValue), + NMB_equal(expectedValue)); + + // overloaded dispatch for nils - expect(nil) + DEFINE_OVERLOAD(void*__nullable, (id)nil) + DEFINE_OVERLOAD(NSRange, NIMBLE_VALUE_OF(expectedValue)) + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow + // the compiler to dispatch to bool. + DEFINE_OVERLOAD(BOOL, @(expectedValue)) + DEFINE_OVERLOAD(char *, @(expectedValue)) + +#undef DEFINE_OVERLOAD + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_haveCount(TYPE expectedValue) { \ + return NMB_haveCount((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id haveCount(TYPE expectedValue), \ + NMB_haveCount(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_haveCount(id expectedValue); + + NIMBLE_SHORT_OVERLOADED(id haveCount(id expectedValue), + NMB_haveCount(expectedValue)); + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBObjCBeCloseToMatcher *NMB_beCloseTo(TYPE expectedValue) { \ + return NMB_beCloseTo((NSNumber *)(EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToMatcher *beCloseTo(TYPE expectedValue), \ + NMB_beCloseTo(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue); + NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToMatcher *beCloseTo(NSNumber *expectedValue), + NMB_beCloseTo(expectedValue)); + + // it would be better to only overload float & double, but zero becomes ambigious + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beAnInstanceOf(Class expectedClass); -NIMBLE_SHORT(id beAnInstanceOf(Class expectedClass), - NMB_beAnInstanceOf(expectedClass)); +NIMBLE_EXPORT_INLINE id beAnInstanceOf(Class expectedClass) { + return NMB_beAnInstanceOf(expectedClass); +} NIMBLE_EXPORT id NMB_beAKindOf(Class expectedClass); -NIMBLE_SHORT(id beAKindOf(Class expectedClass), - NMB_beAKindOf(expectedClass)); +NIMBLE_EXPORT_INLINE id beAKindOf(Class expectedClass) { + return 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_INLINE id beginWith(id itemElementOrSubstring) { + return NMB_beginWith(itemElementOrSubstring); +} + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beGreaterThan(TYPE expectedValue) { \ + return NMB_beGreaterThan((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beGreaterThan(TYPE expectedValue), NMB_beGreaterThan(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beGreaterThan(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beGreaterThan(NSNumber *expectedValue) { + return NMB_beGreaterThan(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beGreaterThanOrEqualTo(TYPE expectedValue) { \ + return NMB_beGreaterThanOrEqualTo((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beGreaterThanOrEqualTo(TYPE expectedValue), \ + NMB_beGreaterThanOrEqualTo(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beGreaterThanOrEqualTo(NSNumber *expectedValue) { + return NMB_beGreaterThanOrEqualTo(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beIdenticalTo(id expectedInstance); NIMBLE_SHORT(id beIdenticalTo(id expectedInstance), @@ -57,13 +231,66 @@ NIMBLE_EXPORT id NMB_be(id expectedInstance); NIMBLE_SHORT(id be(id expectedInstance), NMB_be(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)); +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beLessThan(TYPE expectedValue) { \ + return NMB_beLessThan((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beLessThan(TYPE expectedValue), \ + NMB_beLessThan(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beLessThan(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beLessThan(NSNumber *expectedValue) { + return NMB_beLessThan(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beLessThanOrEqualTo(TYPE expectedValue) { \ + return NMB_beLessThanOrEqualTo((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beLessThanOrEqualTo(TYPE expectedValue), \ + NMB_beLessThanOrEqualTo(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beLessThanOrEqualTo(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beLessThanOrEqualTo(NSNumber *expectedValue) { + return NMB_beLessThanOrEqualTo(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beTruthy(void); NIMBLE_SHORT(id beTruthy(void), @@ -134,7 +361,7 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger #define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__) #ifndef NIMBLE_DISABLE_SHORT_SYNTAX -#define expect(...) NMB_expect(^id{ return (__VA_ARGS__); }, @(__FILE__), __LINE__) +#define expect(...) NMB_expect(^{ 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") @@ -142,4 +369,9 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger #define waitUntilTimeout NMB_waitUntilTimeout #define waitUntil NMB_waitUntil + +#undef NIMBLE_VALUE_OF + #endif + +NS_ASSUME_NONNULL_END diff --git a/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.m b/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.m index 2170238..cd93ddd 100644 --- a/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.m +++ b/Carthage/Checkouts/Nimble/Sources/NimbleObjectiveC/DSL.m @@ -9,7 +9,11 @@ + (void)untilFile:(NSString *)file line:(NSUInteger)line action:(void(^)())actio @end -NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line) { + +NS_ASSUME_NONNULL_BEGIN + + +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBExpectation *__nonnull NMB_expect(id __nullable(^actualBlock)(), NSString *__nonnull file, NSUInteger line) { return [[NMBExpectation alloc] initWithActualBlock:actualBlock negative:NO file:file @@ -35,7 +39,7 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beAKindOfMatcher:expectedClass]; } -NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { return [NMBObjCMatcher beCloseToMatcher:expectedValue within:0.001]; } @@ -43,11 +47,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beginWithMatcher:itemElementOrSubstring]; } -NIMBLE_EXPORT id NMB_beGreaterThan(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beGreaterThan(NSNumber *expectedValue) { return [NMBObjCMatcher beGreaterThanMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { return [NMBObjCMatcher beGreaterThanOrEqualToMatcher:expectedValue]; } @@ -59,11 +63,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beIdenticalToMatcher:expectedInstance]; } -NIMBLE_EXPORT id NMB_beLessThan(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beLessThan(NSNumber *expectedValue) { return [NMBObjCMatcher beLessThanMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { return [NMBObjCMatcher beLessThanOrEqualToMatcher:expectedValue]; } @@ -113,11 +117,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher endWithMatcher:itemElementOrSubstring]; } -NIMBLE_EXPORT id NMB_equal(id expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_equal(__nullable id expectedValue) { return [NMBObjCMatcher equalMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_haveCount(id expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_haveCount(id expectedValue) { return [NMBObjCMatcher haveCountMatcher:expectedValue]; } @@ -148,3 +152,5 @@ NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger [NMBWait untilFile:file line:line action:action]; }; } + +NS_ASSUME_NONNULL_END diff --git a/Carthage/Checkouts/Nimble/Tests/LinuxMain.swift b/Carthage/Checkouts/Nimble/Tests/LinuxMain.swift index 6cae8ca..4210ef0 100644 --- a/Carthage/Checkouts/Nimble/Tests/LinuxMain.swift +++ b/Carthage/Checkouts/Nimble/Tests/LinuxMain.swift @@ -4,7 +4,7 @@ import XCTest // This is the entry point for NimbleTests on Linux XCTMain([ - // testCase(AsynchronousTests.allTests), + testCase(AsyncTest.allTests), testCase(SynchronousTest.allTests), testCase(UserDescriptionTest.allTests), @@ -29,7 +29,7 @@ XCTMain([ testCase(EndWithTest.allTests), testCase(EqualTest.allTests), testCase(HaveCountTest.allTests), - // testCase(MatchTest.allTests), + testCase(MatchTest.allTests), // testCase(RaisesExceptionTest.allTests), testCase(ThrowErrorTest.allTests), testCase(SatisfyAnyOfTest.allTests), diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/AsynchronousTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/AsynchronousTest.swift index 0ccd220..ff78d47 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/AsynchronousTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/AsynchronousTest.swift @@ -1,11 +1,8 @@ +import Dispatch import Foundation import XCTest import Nimble -// These tests require the ObjC runtimes do not currently have the GCD and run loop facilities -// required for working with Nimble's async matchers -#if _runtime(_ObjC) - final class AsyncTest: XCTestCase, XCTestCaseProvider { static var allTests: [(String, (AsyncTest) -> () throws -> Void)] { return [ @@ -24,7 +21,8 @@ final class AsyncTest: XCTestCase, XCTestCaseProvider { ] } - let errorToThrow = NSError(domain: NSExceptionName.internalInconsistencyException.rawValue, code: 42, userInfo: nil) + class Error: Swift.Error {} + let errorToThrow = Error() private func doThrowError() throws -> Int { throw errorToThrow @@ -222,5 +220,3 @@ final class AsyncTest: XCTestCase, XCTestCaseProvider { #endif } } -#endif - diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Helpers/utils.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Helpers/utils.swift index 7962ae4..0b33ea6 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Helpers/utils.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Helpers/utils.swift @@ -1,3 +1,4 @@ +import Dispatch import Foundation @testable import Nimble import XCTest @@ -58,14 +59,12 @@ func failsWithErrorMessageForNil(_ message: String, file: FileString = #file, li failsWithErrorMessage("\(message) (use beNil() to match nils)", file: file, line: line, preferOriginalSourceLocation: preferOriginalSourceLocation, closure: closure) } -#if _runtime(_ObjC) func deferToMainQueue(action: @escaping () -> Void) { DispatchQueue.main.async { Thread.sleep(forTimeInterval: 0.01) action() } } -#endif public class NimbleHelper : NSObject { public class func expectFailureMessage(_ message: NSString, block: @escaping () -> Void, file: FileString, line: UInt) { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift index 7bd3e4c..940a214 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift @@ -26,6 +26,7 @@ final class MatchErrorTest: XCTestCase, XCTestCaseProvider { func testMatchErrorNegative() { expect(NimbleError.laugh).toNot(matchError(NimbleError.cry)) expect(NimbleError.laugh as Error).toNot(matchError(NimbleError.cry)) + expect(NimbleError.laugh).toNot(matchError(EquatableError.self)) } func testMatchNSErrorPositive() { @@ -64,6 +65,10 @@ final class MatchErrorTest: XCTestCase, XCTestCaseProvider { failsWithErrorMessage("expected to not match error , got ") { expect(NimbleError.laugh).toNot(matchError(NimbleError.laugh)) } + + failsWithErrorMessage("expected to match error from type , got ") { + expect(NimbleError.laugh).to(matchError(EquatableError.self)) + } } func testDoesNotMatchNils() { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift index 24257ba..5b6d77f 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift @@ -1,8 +1,6 @@ import XCTest import Nimble -#if _runtime(_ObjC) - final class MatchTest:XCTestCase, XCTestCaseProvider { static var allTests: [(String, (MatchTest) -> () throws -> Void)] { return [ @@ -46,4 +44,3 @@ final class MatchTest:XCTestCase, XCTestCaseProvider { } } } -#endif diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift index 8fd5baf..d7cd312 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift @@ -136,7 +136,6 @@ final class ThrowErrorTest: XCTestCase, XCTestCaseProvider { let moduleName = "NimbleTests" let innerFailureMessage = "expected to equal , got <\(moduleName).NimbleError>" let closure = { (error: Error) in - print("** In closure! With domain \(error._domain)") expect(error._domain).to(equal("foo")) } diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/SynchronousTests.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/SynchronousTests.swift index b50e19b..6234932 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/SynchronousTests.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/SynchronousTests.swift @@ -21,7 +21,9 @@ final class SynchronousTest: XCTestCase, XCTestCaseProvider { ] } - let errorToThrow = NSError(domain: NSCocoaErrorDomain, code: 42, userInfo: nil) + class Error: Swift.Error {} + let errorToThrow = Error() + private func doThrowError() throws -> Int { throw errorToThrow } @@ -36,14 +38,12 @@ final class SynchronousTest: XCTestCase, XCTestCaseProvider { } func testUnexpectedErrorsThrownFails() { -#if _runtime(_ObjC) // This test triggers a weird segfault on Linux currently 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)) } -#endif } func testToMatchesIfMatcherReturnsTrue() { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/UserDescriptionTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/UserDescriptionTest.swift index ef754ec..e22d64e 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/UserDescriptionTest.swift +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/UserDescriptionTest.swift @@ -38,33 +38,27 @@ final class UserDescriptionTest: XCTestCase, XCTestCaseProvider { } func testToEventuallyMatch_CustomFailureMessage() { -#if _runtime(_ObjC) 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!") } -#endif } func testToEventuallyNotMatch_CustomFailureMessage() { -#if _runtime(_ObjC) failsWithErrorMessage( "These are eventually equal!\n" + "expected to eventually not equal <1>, got <1>") { expect { 1 }.toEventuallyNot(equal(1), description: "These are eventually equal!") } -#endif } func testToNotEventuallyMatch_CustomFailureMessage() { -#if _runtime(_ObjC) failsWithErrorMessage( "These are eventually equal!\n" + "expected to eventually not equal <1>, got <1>") { expect { 1 }.toEventuallyNot(equal(1), description: "These are eventually equal!") } -#endif } } diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m index c3f5639..c33d643 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m @@ -12,6 +12,11 @@ - (void)testPositiveMatches { expect(@1.2).to(beCloseTo(@2).within(10)); expect(@2).toNot(beCloseTo(@1)); expect(@1.00001).toNot(beCloseTo(@1).within(0.00000001)); + + 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 { @@ -21,6 +26,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be close to <0> (within 0.001), got <0.0001>", ^{ expect(@(0.0001)).toNot(beCloseTo(@0)); }); + expectFailureMessage(@"expected to be close to <0> (within 0.001), got <1>", ^{ + expect(1).to(beCloseTo(0)); + }); + expectFailureMessage(@"expected to not be close to <0> (within 0.001), got <0.0001>", ^{ + expect(0.0001).toNot(beCloseTo(0)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m index 5b99842..5a5bce8 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m @@ -10,6 +10,14 @@ @implementation ObjCBeFalseTest - (void)testPositiveMatches { expect(@NO).to(beFalse()); expect(@YES).toNot(beFalse()); + + expect(false).to(beFalse()); + expect(true).toNot(beFalse()); + + expect(NO).to(beFalse()); + expect(YES).toNot(beFalse()); + + expect(10).toNot(beFalse()); } - (void)testNegativeMatches { @@ -19,6 +27,20 @@ - (void)testNegativeMatches { expectNilFailureMessage(@"expected to not be false, got ", ^{ expect(nil).toNot(beFalse()); }); + + expectFailureMessage(@"expected to be false, got <1>", ^{ + expect(true).to(beFalse()); + }); + expectFailureMessage(@"expected to not be false, got <0>", ^{ + expect(false).toNot(beFalse()); + }); + + expectFailureMessage(@"expected to be false, got <1>", ^{ + expect(YES).to(beFalse()); + }); + expectFailureMessage(@"expected to not be false, got <0>", ^{ + expect(NO).toNot(beFalse()); + }); } @end diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m index 4b6281e..f3f5c98 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m @@ -11,6 +11,15 @@ - (void)testPositiveMatches { expect(@NO).to(beFalsy()); expect(@YES).toNot(beFalsy()); expect(nil).to(beFalsy()); + + expect(true).toNot(beFalsy()); + expect(false).to(beFalsy()); + + expect(YES).toNot(beFalsy()); + expect(NO).to(beFalsy()); + + expect(10).toNot(beFalsy()); + expect(0).to(beFalsy()); } - (void)testNegativeMatches { @@ -20,8 +29,29 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be falsy, got <1>", ^{ expect(@1).to(beFalsy()); }); - expectFailureMessage(@"expected to be truthy, got <0>", ^{ - expect(@NO).to(beTruthy()); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(@NO).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <1>", ^{ + expect(true).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(false).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <1>", ^{ + expect(YES).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(NO).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <10>", ^{ + expect(10).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(0).toNot(beFalsy()); }); } diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m index cec26c7..22cab3a 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeGreaterThanOrEqualToTest - (void)testPositiveMatches { expect(@2).to(beGreaterThanOrEqualTo(@2)); expect(@2).toNot(beGreaterThanOrEqualTo(@3)); + expect(2).to(beGreaterThanOrEqualTo(0)); + expect(2).to(beGreaterThanOrEqualTo(2)); + expect(2).toNot(beGreaterThanOrEqualTo(3)); } - (void)testNegativeMatches { @@ -19,6 +22,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be greater than or equal to <1>, got <2>", ^{ expect(@2).toNot(beGreaterThanOrEqualTo(@(1))); }); + expectFailureMessage(@"expected to be greater than or equal to <0>, got <-1>", ^{ + expect(-1).to(beGreaterThanOrEqualTo(0)); + }); + expectFailureMessage(@"expected to not be greater than or equal to <1>, got <2>", ^{ + expect(2).toNot(beGreaterThanOrEqualTo(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m index 5ad3087..13336d5 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m @@ -10,6 +10,8 @@ @implementation ObjCBeGreaterThanTest - (void)testPositiveMatches { expect(@2).to(beGreaterThan(@1)); expect(@2).toNot(beGreaterThan(@2)); + expect(@2).to(beGreaterThan(0)); + expect(@2).toNot(beGreaterThan(2)); } - (void)testNegativeMatches { @@ -19,6 +21,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be greater than <1>, got <0>", ^{ expect(@0).toNot(beGreaterThan(@(1))); }); + expectFailureMessage(@"expected to be greater than <0>, got <-1>", ^{ + expect(-1).to(beGreaterThan(0)); + }); + expectFailureMessage(@"expected to not be greater than <1>, got <0>", ^{ + expect(0).toNot(beGreaterThan(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m index ab60a81..a9d9d51 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m @@ -25,9 +25,12 @@ - (void)testNegativeMatches { - (void)testNilMatches { NSNull *obj = [NSNull null]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" expectNilFailureMessage(@"expected to be identical to nil, got nil", ^{ expect(nil).to(beIdenticalTo(nil)); }); +#pragma clang diagnostic pop expectNilFailureMessage(([NSString stringWithFormat:@"expected to not be identical to <%p>, got nil", obj]), ^{ expect(nil).toNot(beIdenticalTo(obj)); }); @@ -51,9 +54,12 @@ - (void)testAliasNegativeMatches { - (void)testAliasNilMatches { NSNull *obj = [NSNull null]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" expectNilFailureMessage(@"expected to be identical to nil, got nil", ^{ expect(nil).to(be(nil)); }); +#pragma clang diagnostic pop expectNilFailureMessage(([NSString stringWithFormat:@"expected to not be identical to <%p>, got nil", obj]), ^{ expect(nil).toNot(be(obj)); }); diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m index dbd2062..4a738ec 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeLessThanOrEqualToTest - (void)testPositiveMatches { expect(@2).to(beLessThanOrEqualTo(@2)); expect(@2).toNot(beLessThanOrEqualTo(@1)); + expect(2).to(beLessThanOrEqualTo(2)); + expect(2).toNot(beLessThanOrEqualTo(1)); + expect(2).toNot(beLessThanOrEqualTo(0)); } - (void)testNegativeMatches { @@ -19,6 +22,13 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be less than or equal to <1>, got <1>", ^{ expect(@1).toNot(beLessThanOrEqualTo(@1)); }); + + expectFailureMessage(@"expected to be less than or equal to <1>, got <2>", ^{ + expect(2).to(beLessThanOrEqualTo(1)); + }); + expectFailureMessage(@"expected to not be less than or equal to <1>, got <1>", ^{ + expect(1).toNot(beLessThanOrEqualTo(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m index 4d9da72..7ba38b2 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeLessThanTest - (void)testPositiveMatches { expect(@2).to(beLessThan(@3)); expect(@2).toNot(beLessThan(@2)); + expect(2).to(beLessThan(3)); + expect(2).toNot(beLessThan(2)); + expect(2).toNot(beLessThan(0)); } - (void)testNegativeMatches { @@ -19,6 +22,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be less than <1>, got <0>", ^{ expect(@0).toNot(beLessThan(@1)); }); + expectFailureMessage(@"expected to be less than <0>, got <-1>", ^{ + expect(-1).to(beLessThan(0)); + }); + expectFailureMessage(@"expected to not be less than <1>, got <0>", ^{ + expect(0).toNot(beLessThan(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m index 3f10ce3..c669475 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m @@ -11,6 +11,12 @@ - (void)testPositiveMatches { expect(@YES).to(beTrue()); expect(@NO).toNot(beTrue()); expect(nil).toNot(beTrue()); + + expect(true).to(beTrue()); + expect(false).toNot(beTrue()); + + expect(YES).to(beTrue()); + expect(NO).toNot(beTrue()); } - (void)testNegativeMatches { @@ -20,6 +26,22 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be true, got ", ^{ expect(nil).to(beTrue()); }); + + expectFailureMessage(@"expected to be true, got <0>", ^{ + expect(false).to(beTrue()); + }); + + expectFailureMessage(@"expected to not be true, got <1>", ^{ + expect(true).toNot(beTrue()); + }); + + expectFailureMessage(@"expected to be true, got <0>", ^{ + expect(NO).to(beTrue()); + }); + + expectFailureMessage(@"expected to not be true, got <1>", ^{ + expect(YES).toNot(beTrue()); + }); } @end diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m index 93180a2..1ad7913 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m @@ -11,6 +11,15 @@ - (void)testPositiveMatches { expect(@YES).to(beTruthy()); expect(@NO).toNot(beTruthy()); expect(nil).toNot(beTruthy()); + + expect(true).to(beTruthy()); + expect(false).toNot(beTruthy()); + + expect(YES).to(beTruthy()); + expect(NO).toNot(beTruthy()); + + expect(10).to(beTruthy()); + expect(0).toNot(beTruthy()); } - (void)testNegativeMatches { @@ -23,6 +32,24 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be truthy, got <0>", ^{ expect(@NO).to(beTruthy()); }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(false).to(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <1>", ^{ + expect(true).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(NO).to(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <1>", ^{ + expect(YES).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <10>", ^{ + expect(10).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(0).to(beTruthy()); + }); } @end diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m index e5a2be0..6c20809 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m @@ -12,6 +12,31 @@ - (void)testPositiveMatches { expect(@1).toNot(equal(@2)); expect(@1).notTo(equal(@2)); expect(@"hello").to(equal(@"hello")); + expect("hello").to(equal("hello")); + expect(NSMakeRange(0, 10)).to(equal(NSMakeRange(0, 10))); + expect(NSMakeRange(0, 10)).toNot(equal(NSMakeRange(0, 5))); + expect((NSInteger)1).to(equal((NSInteger)1)); + expect((NSInteger)1).toNot(equal((NSInteger)2)); + expect((NSUInteger)1).to(equal((NSUInteger)1)); + expect((NSUInteger)1).toNot(equal((NSUInteger)2)); + expect(0).to(equal(0)); + expect(1).to(equal(1)); + expect(1).toNot(equal(2)); + expect(1.0).to(equal(1.0)); // Note: not recommended, use beCloseTo() instead + expect(1.0).toNot(equal(2.0)); // Note: not recommended, use beCloseTo() instead + expect((float)1.0).to(equal((float)1.0)); // Note: not recommended, use beCloseTo() instead + expect((float)1.0).toNot(equal((float)2.0)); // Note: not recommended, use beCloseTo() instead + expect((double)1.0).to(equal((double)1.0)); // Note: not recommended, use beCloseTo() instead + expect((double)1.0).toNot(equal((double)2.0)); // Note: not recommended, use beCloseTo() instead + expect((long long)1).to(equal((long long)1)); + expect((long long)1).toNot(equal((long long)2)); + expect((unsigned long long)1).to(equal((unsigned long long)1)); + expect((unsigned long long)1).toNot(equal((unsigned long long)2)); +} + +- (void)testNimbleCurrentlyBoxesNumbersWhichAllowsImplicitTypeConversions { + expect(1).to(equal(1.0)); + expect((long long)1).to(equal((unsigned long long)1)); } - (void)testNegativeMatches { @@ -21,9 +46,43 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not equal <1>, got <1>", ^{ expect(@1).toNot(equal(@1)); }); + expectFailureMessage(@"expected to not equal , got ", ^{ + expect("bar").toNot(equal("foo")); + }); + expectFailureMessage(@"expected to equal , got ", ^{ + expect(NSMakeRange(0, 10)).to(equal(NSMakeRange(0, 5))); + }); + + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((NSInteger)1).to(equal((NSInteger)2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((NSUInteger)1).to(equal((NSUInteger)2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect(1).to(equal(2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect(1.0).to(equal(2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((float)1.0).to(equal((float)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((double)1.0).to(equal((double)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((long long)1.0).to(equal((long long)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((unsigned long long)1.0).to(equal((unsigned long long)2.0)); + }); } - (void)testNilMatches { + expectNilFailureMessage(@"expected to equal , got ", ^{ + expect(NULL).to(equal(NULL)); + }); expectNilFailureMessage(@"expected to equal , got ", ^{ expect(nil).to(equal(nil)); }); diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m index d5fdf4f..31053c8 100644 --- a/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m @@ -14,6 +14,12 @@ - (void)testHaveCountForNSArray { expect(@[]).to(haveCount(@0)); expect(@[@1]).notTo(haveCount(@0)); + expect(@[@1, @2, @3]).to(haveCount(3)); + expect(@[@1, @2, @3]).notTo(haveCount(1)); + + expect(@[]).to(haveCount(0)); + expect(@[@1]).notTo(haveCount(0)); + expectFailureMessage(@"expected to have NSArray with count 1, got 3\nActual Value: (1, 2, 3)", ^{ expect(@[@1, @2, @3]).to(haveCount(@1)); }); @@ -22,12 +28,22 @@ - (void)testHaveCountForNSArray { expect(@[@1, @2, @3]).notTo(haveCount(@3)); }); + expectFailureMessage(@"expected to have NSArray with count 1, got 3\nActual Value: (1, 2, 3)", ^{ + expect(@[@1, @2, @3]).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSArray with count 3, got 3\nActual Value: (1, 2, 3)", ^{ + expect(@[@1, @2, @3]).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSDictionary { expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(@3)); expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(@1)); + expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(3)); + expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(1)); + expectFailureMessage(@"expected to have NSDictionary with count 1, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(@1)); }); @@ -35,6 +51,14 @@ - (void)testHaveCountForNSDictionary { expectFailureMessage(@"expected to not have NSDictionary with count 3, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSDictionary with count 1, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ + expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSDictionary with count 3, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ + expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSHashtable { @@ -46,6 +70,9 @@ - (void)testHaveCountForNSHashtable { expect(table).to(haveCount(@3)); expect(table).notTo(haveCount(@1)); + expect(table).to(haveCount(3)); + expect(table).notTo(haveCount(1)); + NSString *msg = [NSString stringWithFormat: @"expected to have NSHashTable {[2] 2[12] 1[13] 3}with count 1, got 3\nActual Value: %@", [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; @@ -53,13 +80,27 @@ - (void)testHaveCountForNSHashtable { expect(table).to(haveCount(@1)); }); - msg = [NSString stringWithFormat: @"expected to not have NSHashTable {[2] 2[12] 1[13] 3}with count 3, got 3\nActual Value: %@", [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; expectFailureMessage(msg, ^{ expect(table).notTo(haveCount(@3)); }); + + + msg = [NSString stringWithFormat: + @"expected to have NSHashTable {[2] 2[12] 1[13] 3}with count 1, got 3\nActual Value: %@", + [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; + expectFailureMessage(msg, ^{ + expect(table).to(haveCount(1)); + }); + + msg = [NSString stringWithFormat: + @"expected to not have NSHashTable {[2] 2[12] 1[13] 3}with count 3, got 3\nActual Value: %@", + [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; + expectFailureMessage(msg, ^{ + expect(table).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSSet { @@ -67,6 +108,8 @@ - (void)testHaveCountForNSSet { expect(set).to(haveCount(@3)); expect(set).notTo(haveCount(@1)); + expect(set).to(haveCount(3)); + expect(set).notTo(haveCount(1)); expectFailureMessage(@"expected to have NSSet with count 1, got 3\nActual Value: {(3,1,2)}", ^{ expect(set).to(haveCount(@1)); @@ -75,6 +118,14 @@ - (void)testHaveCountForNSSet { expectFailureMessage(@"expected to not have NSSet with count 3, got 3\nActual Value: {(3,1,2)}", ^{ expect(set).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSSet with count 1, got 3\nActual Value: {(3,1,2)}", ^{ + expect(set).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSSet with count 3, got 3\nActual Value: {(3,1,2)}", ^{ + expect(set).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSIndexSet { @@ -82,6 +133,8 @@ - (void)testHaveCountForNSIndexSet { expect(set).to(haveCount(@3)); expect(set).notTo(haveCount(@1)); + expect(set).to(haveCount(3)); + expect(set).notTo(haveCount(1)); expectFailureMessage(@"expected to have NSIndexSet with count 1, got 3\nActual Value: (1, 2, 3)", ^{ expect(set).to(haveCount(@1)); @@ -90,6 +143,14 @@ - (void)testHaveCountForNSIndexSet { expectFailureMessage(@"expected to not have NSIndexSet with count 3, got 3\nActual Value: (1, 2, 3)", ^{ expect(set).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSIndexSet with count 1, got 3\nActual Value: (1, 2, 3)", ^{ + expect(set).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSIndexSet with count 3, got 3\nActual Value: (1, 2, 3)", ^{ + expect(set).notTo(haveCount(3)); + }); } - (void)testHaveCountForUnsupportedTypes { @@ -100,6 +161,14 @@ - (void)testHaveCountForUnsupportedTypes { expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFNumber", ^{ expect(@1).to(haveCount(@6)); }); + + expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFConstantString", ^{ + expect(@"string").to(haveCount(6)); + }); + + expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFNumber", ^{ + expect(@1).to(haveCount(6)); + }); } @end diff --git a/Carthage/Checkouts/Quick/.travis.yml b/Carthage/Checkouts/Quick/.travis.yml index fb9ecc5..4c57144 100644 --- a/Carthage/Checkouts/Quick/.travis.yml +++ b/Carthage/Checkouts/Quick/.travis.yml @@ -19,14 +19,12 @@ matrix: env: - PODSPEC=1 - os: linux - env: - - PLATFORM=linux sudo: required dist: trusty install: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./script/travis-install-macos; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./script/travis-install-macos; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./script/travis-install-linux; fi - if [[ "$PODSPEC" ]]; then rvm system; sudo gem install bundler; bundle install; fi script: - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./script/travis-script-macos; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./script/travis-script-macos; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./script/travis-script-linux; fi diff --git a/Carthage/Checkouts/Quick/Documentation/README.md b/Carthage/Checkouts/Quick/Documentation/README.md index 457a0e3..08fb556 100644 --- a/Carthage/Checkouts/Quick/Documentation/README.md +++ b/Carthage/Checkouts/Quick/Documentation/README.md @@ -3,3 +3,4 @@ - [English](en-us/README.md) - [日本語](ja/README.md) - [中文](zh-cn/README.md) +- [pt-br](pt-br/README.md) diff --git a/Carthage/Checkouts/Quick/Documentation/en-us/InstallingQuick.md b/Carthage/Checkouts/Quick/Documentation/en-us/InstallingQuick.md index 6267c04..258956f 100644 --- a/Carthage/Checkouts/Quick/Documentation/en-us/InstallingQuick.md +++ b/Carthage/Checkouts/Quick/Documentation/en-us/InstallingQuick.md @@ -1,9 +1,6 @@ # Installing Quick -> **If you're using Xcode 7.1,** use the latest version of Quick--`v0.9.0` at the time of writing. -> New releases are developed on the `swift-2.0` branch. - - +>Before starting, check [here](../../README.md#swift-version) which versions of Quick and Nimble are compatible with your version of Swift. Quick provides the syntax to define examples and example groups. Nimble provides the `expect(...).to` assertion syntax. You may use either one, @@ -115,20 +112,6 @@ Finally, download and link Quick and Nimble to your tests: pod install ``` -### Using Swift 1.2? - -The latest release of Quick (0.4.0) is for Swift 2 (Xcode 7), but the latest Nimble (1.0.0) is for Swift 1.2 (Xcode 6). - -If you want Xcode 6 do: - -```sh -target 'MyTests' do - use_frameworks! - pod 'Quick', '~>0.3.0' - pod 'Nimble', '~>1.0.0' -end -``` - ## [Carthage](https://github.com/Carthage/Carthage) As test targets do not have the "Embedded Binaries" section, the frameworks must diff --git a/Carthage/Checkouts/Quick/Documentation/en-us/SettingUpYourXcodeProject.md b/Carthage/Checkouts/Quick/Documentation/en-us/SettingUpYourXcodeProject.md index b2ba8e1..dd49355 100644 --- a/Carthage/Checkouts/Quick/Documentation/en-us/SettingUpYourXcodeProject.md +++ b/Carthage/Checkouts/Quick/Documentation/en-us/SettingUpYourXcodeProject.md @@ -2,15 +2,18 @@ With the exception of the Command Line Tool project type, when you create a new project in Xcode 7, a unit test target is included by default. [See specific instructions for a Command Line Tool Project](#setting-up-a-test-target-for-a-command-line-tool-project). To write unit tests, you'll need to be able to use your main -target's code from within your test target. +target's code from within your test target. ## Testing Swift Code Using Swift In order to test code written in Swift, you'll need to do two things: -1. Set "defines module" in your `.xcodeproj` to `YES`. +1. Set "Defines Module" in your `.xcodeproj` to `YES`. - * To do this in Xcode: Choose your project, then "Build Settings" header, then "Defines Modules" line, then select "Yes". + * To do this in Xcode: Choose your project, then "Build Settings", then "Packaging" header, + then "Defines Module" line, then select "Yes". Note: you may have + to choose "All" (Build Settings) instead of "Basic" to see the + "Packaging" section. 2. `@testable import YourAppModuleName` in your unit tests. This will expose Any `public` and `internal` (the default) symbols to your tests. `private` symbols are still unavailable. diff --git a/Carthage/Checkouts/Quick/Documentation/en-us/SharedExamples.md b/Carthage/Checkouts/Quick/Documentation/en-us/SharedExamples.md index 1e3e7dd..3e67cb5 100644 --- a/Carthage/Checkouts/Quick/Documentation/en-us/SharedExamples.md +++ b/Carthage/Checkouts/Quick/Documentation/en-us/SharedExamples.md @@ -17,7 +17,7 @@ import Quick import Nimble class EdibleSharedExamplesConfiguration: QuickConfiguration { - override class func configure(configuration: Configuration) { + override class func configure(_ configuration: Configuration) { sharedExamples("something edible") { (sharedExampleContext: SharedExampleContext) in it("makes dolphins happy") { let dolphin = Dolphin(happy: false) diff --git a/Carthage/Checkouts/Quick/Documentation/en-us/TestUsingTestDoubles.md b/Carthage/Checkouts/Quick/Documentation/en-us/TestUsingTestDoubles.md index d69235e..fc4f3f9 100644 --- a/Carthage/Checkouts/Quick/Documentation/en-us/TestUsingTestDoubles.md +++ b/Carthage/Checkouts/Quick/Documentation/en-us/TestUsingTestDoubles.md @@ -1,39 +1,45 @@ -# Testing with Mock +# Testing with Mocks ## Test doubles -The following problem occurs frequently when writing tests. In example, `Car` depends on/uses `Tire`. +Dependencies between objects can cause problems when writing tests. For example, say you have a `Car` class that depends on/uses `Tire`. ![](https://github.com/Quick/Assets/blob/master/Screenshots/TestUsingMock_BusesA.png) -`CarTests` test `Car` which calls `Tire`. Now bugs in `Tire` could cause `CarTests` to fail (even though `Car` is okay). +`CarTests` tests `Car`, which calls `Tire`. Now bugs in `Tire` could cause `CarTests` to fail (even though `Car` is okay). It can be hard to answer the question: "What's broken?". -It can be hard to answer the question: "What's broken?". To avoid this problem, one can use a stand-in object for `Tire` in `CarTests`. In this case, we'll create a stand-in object for `Tire` called `PerfectTire`. +To avoid this problem, you can use a stand-in object for `Tire` in `CarTests`. In this case, we'll create a stand-in object for `Tire` called `PerfectTire`. ![](https://github.com/Quick/Assets/blob/master/Screenshots/TestUsingMock_BusesAmock.png) -`PerfectTire` would have all of the same functions and properties as `Tire`. However, the implementation of those functions and properties may differ. +`PerfectTire` will have all of the same public functions and properties as `Tire`. However, the implementation of some or all of those functions and properties will differ. -Objects like `PerfectTire` are called "test doubles". Test doubles are used as "stand-in objects" for testing functionality of related objects in isolation. There are several kinds of test doubles: +Objects like `PerfectTire` are called "test doubles". Test doubles are used as "stand-in objects" for testing the functionality of related objects in isolation. There are several kinds of test doubles: - Mock object: Used for receiving output from a test class. - Stub object: Used for providing input to a test class. -- Fake object: Behaves similar to the original class. +- Fake object: Behaves similarly to the original class, but in a simplified way. Let's start with how to use mock objects. ## Mock -A mock object focuses on fully specifying what the correct interaction is supposed to be with other objects and detecting when something goes awry. The mock object should know (in advance) what is supposed to happen during the test and how the mock object is supposed to react. +A mock object focuses on fully specifying the correct interaction with other objects and detecting when something goes awry. The mock object should know (in advance) the methods that should be called on it during the test and what values the mock object should return. -### Writing test with Mock in Swift +Mock objects are great because you can: + +- Run tests a lot quicker. +- Run tests even if you're not connected to the Internet. +- Focus on testing classes in isolation from their dependencies. + +### Writing Tests with Mock Objects in Swift #### Sample app -For example, we will provide an app which retrieves data from the internet. +For example, let's create an app which retrieves data from the Internet: -* Displays the data from the internet in `ViewController`. -* Custom class implements `DataProviderProtocol`, which is responsible for fetching data. +* Data from the Internet will be displayed in `ViewController`. +* A custom class will implement the `DataProviderProtocol`, which specifies methods for fetching data. `DataProviderProtocol` is defined as follows: @@ -43,26 +49,26 @@ protocol DataProviderProtocol: class { } ``` -`fetch()` gets data from the internet and returns it using a `callback` closure. +`fetch()` gets data from the Internet and returns it using a `callback` closure. -Here is `DataProvider` which implements the `DataProviderProtocol` protocol. +Here is the `DataProvider` class, which conforms to the `DataProviderProtocol` protocol. ```swift class DataProvider: NSObject, DataProviderProtocol { func fetch(callback: (data: String) -> Void) { - let url = NSURL(string: "http://example.com/")! - let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration()) - let task = session.dataTaskWithURL(url, completionHandler: { + let url = URL(string: "http://example.com/")! + let session = URLSession(configuration: .default) + let task = session.dataTask(with: url) { (data, resp, err) in - let string = NSString(data:data!, encoding:NSUTF8StringEncoding) as! String + let string = String(data: data!, encoding: .utf8) callback(data: string) - }) + } task.resume() } } ``` -In our scenario, `fetch()` is called in `viewDidLoad()` of `ViewController`. +In our scenario, `fetch()` is called in the `viewDidLoad()` method of `ViewController`. ```swift class ViewController: UIViewController { @@ -86,13 +92,7 @@ class ViewController: UIViewController { #### Testing using a Mock of `DataProviderProtocol` -`ViewController` depends on `DataProviderProtocol`. Create a mock object which conforms to `DataProviderProtocol` in order to test the view controller. - -Mock objects are great because you can: - -- Run tests a lot quicker. -- Run tests even if you're not connected to the internet. -- Focus on testing `ViewController` in isolation. +`ViewController` depends on `DataProviderProtocol`. In order to test the view controller in isolation, you can create a mock object which conforms to `DataProviderProtocol`. ```swift class MockDataProvider: NSObject, DataProviderProtocol { @@ -104,26 +104,26 @@ class MockDataProvider: NSObject, DataProviderProtocol { } ``` -The `fetchCalled` property is set to `true` when `fetch()` is called. This helps the test determine if the object is ready to test. +The `fetchCalled` property is set to `true` when `fetch()` is called, so that the test can confirm that it was called. -The following test verifies that when `ViewController` is loaded, the view controller should call `dataProvider.fetch()`. +The following test verifies that when `ViewController` is loaded, the view controller calls `dataProvider.fetch()`. ```swift override func spec() { describe("view controller") { it("fetch data with data provider") { - let mockProvier = MockDataProvider() + let mockProvider = MockDataProvider() let viewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as! ViewController - viewController.dataProvier = mockProvier + viewController.dataProvider = mockProvider - expect(mockProvier.fetchCalled).to(equal(false)) + expect(mockProvider.fetchCalled).to(beFalse()) let _ = viewController.view - expect(mockProvier.fetchCalled).to(equal(true)) + expect(mockProvider.fetchCalled).to(beTrue()) } } } ``` -If you're interested in learning more about writing tests, continue on to https://realm.io/news/testing-in-swift/. +If you're interested in learning more about writing tests, continue on to . diff --git a/Carthage/Checkouts/Quick/Documentation/zh-cn/README.md b/Carthage/Checkouts/Quick/Documentation/zh-cn/README.md index cf3051f..2c48f4c 100644 --- a/Carthage/Checkouts/Quick/Documentation/zh-cn/README.md +++ b/Carthage/Checkouts/Quick/Documentation/zh-cn/README.md @@ -9,6 +9,7 @@ Quick 能够帮助你验证你的 Swift 和 Objective-C 程序的行为。然而 - **[不要测试代码,而应该测试行为](BehavioralTesting.md)**:通过这份指南你能学习到哪些是好的测试,哪些是不好的测试。 - **[测试 OS X 和 iOS 应用](TestingApps.md)**:了解如何为使用 AppKit 和 UIKit 框架的代码编写测试。 - **[使用测试替身进行测试](TestUsingTestDoubles.md)**:阅读这份指南来了解什么是测试替身,以及如何使用它们。 +- **[使用 Shared Assertion 来复用测试模板代码](SharedExamples.md)**:学习如何在测试中共享测试代码。 - **[配置 Quick 的行为](ConfiguringQuick.md)**:阅读这份指南来了解如何在运行测试代码时改变 Quick 的行为。 - **[在 Objective-C 中使用 Quick](QuickInObjectiveC.md)**:如果你在 Objective-C 项目使用 Quick 的过程中遇到了困难,请阅读这份指南。 - **[安装 Quick](InstallingQuick.md)**:通过这份指南了解在项目中添加 Quick 的方法:Git submodules,CocoaPods,Carthage 和 Swift Package Manager 。 diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/.gitignore b/Carthage/Checkouts/Quick/Externals/Nimble/.gitignore index b067294..e50906d 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/.gitignore +++ b/Carthage/Checkouts/Quick/Externals/Nimble/.gitignore @@ -1,5 +1,7 @@ .DS_Store -xcuserdata/ +**/xcuserdata/* +**/*.xccheckout +**/*.xcscmblueprint build/ .idea DerivedData/ diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/.travis.yml b/Carthage/Checkouts/Quick/Externals/Nimble/.travis.yml index 977a75b..3e2f896 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/.travis.yml +++ b/Carthage/Checkouts/Quick/Externals/Nimble/.travis.yml @@ -2,9 +2,9 @@ osx_image: xcode8 language: generic matrix: include: - # - os: osx - # sudo: required - # env: TYPE=podspec + - os: osx + sudo: required + env: TYPE=podspec - os: osx env: TYPE=ios NIMBLE_RUNTIME_IOS_SDK_VERSION=10.0 - os: osx diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/CONTRIBUTING.md b/Carthage/Checkouts/Quick/Externals/Nimble/CONTRIBUTING.md index a97114f..d9c4ba6 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/CONTRIBUTING.md +++ b/Carthage/Checkouts/Quick/Externals/Nimble/CONTRIBUTING.md @@ -46,6 +46,14 @@ Be sure to include in your issue: - Use `Nimble.xcodeproj` to work on Nimble. +## Running the Swift Package Manager tests + +1. Install `swiftenv` by running a line from the build script (`.travis.yml`): + + eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/02090c7ede5a637b76e6df1710e83cd0bbe7dcdf/swiftenv-install.sh)" + +2. Run `./test swiftpm` + ## Pull Requests - Nothing is trivial. Submit pull requests for anything: typos, diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Gemfile b/Carthage/Checkouts/Quick/Externals/Nimble/Gemfile index 66d7eff..a6dc312 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Gemfile +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Gemfile @@ -1,4 +1,4 @@ # A sample Gemfile source "https://rubygems.org" -gem 'cocoapods' +gem 'cocoapods', '1.1.0.rc.3' diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Gemfile.lock b/Carthage/Checkouts/Quick/Externals/Nimble/Gemfile.lock index 374561e..87dc02b 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Gemfile.lock +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Gemfile.lock @@ -1,67 +1,69 @@ GEM remote: https://rubygems.org/ specs: - activesupport (4.2.6) + activesupport (4.2.7.1) i18n (~> 0.7) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - claide (1.0.0) - cocoapods (1.0.1) - activesupport (>= 4.0.2) - claide (>= 1.0.0, < 2.0) - cocoapods-core (= 1.0.1) - cocoapods-deintegrate (>= 1.0.0, < 2.0) - cocoapods-downloader (>= 1.0.0, < 2.0) + claide (1.0.1) + cocoapods (1.1.0.rc.3) + activesupport (>= 4.0.2, < 5) + claide (>= 1.0.1, < 2.0) + cocoapods-core (= 1.1.0.rc.3) + cocoapods-deintegrate (>= 1.0.1, < 2.0) + cocoapods-downloader (>= 1.1.1, < 2.0) cocoapods-plugins (>= 1.0.0, < 2.0) cocoapods-search (>= 1.0.0, < 2.0) cocoapods-stats (>= 1.0.0, < 2.0) - cocoapods-trunk (>= 1.0.0, < 2.0) - cocoapods-try (>= 1.0.0, < 2.0) + cocoapods-trunk (= 1.1.0.beta.1) + cocoapods-try (>= 1.1.0, < 2.0) colored (~> 1.2) escape (~> 0.0.4) - fourflusher (~> 0.3.0) - molinillo (~> 0.4.5) + fourflusher (~> 2.0) + gh_inspector (~> 1.0) + molinillo (~> 0.5.1) nap (~> 1.0) - xcodeproj (>= 1.1.0, < 2.0) - cocoapods-core (1.0.1) - activesupport (>= 4.0.2) + xcodeproj (>= 1.3.2, < 2.0) + cocoapods-core (1.1.0.rc.3) + activesupport (>= 4.0.2, < 5) fuzzy_match (~> 2.0.4) nap (~> 1.0) - cocoapods-deintegrate (1.0.0) - cocoapods-downloader (1.0.1) + cocoapods-deintegrate (1.0.1) + cocoapods-downloader (1.1.1) cocoapods-plugins (1.0.0) nap cocoapods-search (1.0.0) cocoapods-stats (1.0.0) - cocoapods-trunk (1.0.0) + cocoapods-trunk (1.1.0.beta.1) nap (>= 0.8, < 2.0) netrc (= 0.7.8) - cocoapods-try (1.0.0) + cocoapods-try (1.1.0) colored (1.2) escape (0.0.4) - fourflusher (0.3.2) + fourflusher (2.0.1) fuzzy_match (2.0.4) + gh_inspector (1.0.2) i18n (0.7.0) json (1.8.3) - minitest (5.9.0) - molinillo (0.4.5) + minitest (5.9.1) + molinillo (0.5.1) nap (1.1.0) netrc (0.7.8) thread_safe (0.3.5) tzinfo (1.2.2) thread_safe (~> 0.1) - xcodeproj (1.1.0) + xcodeproj (1.3.2) activesupport (>= 3) - claide (>= 1.0.0, < 2.0) + claide (>= 1.0.1, < 2.0) colored (~> 1.2) PLATFORMS ruby DEPENDENCIES - cocoapods + cocoapods (= 1.1.0.rc.3) BUNDLED WITH - 1.12.3 + 1.13.1 diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.podspec b/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.podspec index 5fa0974..8ca36a1 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.podspec +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Nimble" - s.version = "5.0.0" + s.version = "5.1.1" 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. @@ -11,12 +11,37 @@ Pod::Spec.new do |s| s.ios.deployment_target = "8.0" s.osx.deployment_target = "10.10" s.tvos.deployment_target = "9.0" - s.source = { :git => "https://github.com/Quick/Nimble.git", :tag => "v#{s.version}" } + s.source = { :git => "https://github.com/Quick/Nimble.git", + :tag => "v#{s.version}" } + + s.source_files = "Sources/**/*.{swift,h,m,c}" + + s.osx.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift", + ] + s.ios.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift", + ] + s.tvos.exclude_files = [ + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift", + "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.{h,c}", + "Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException.swift", + "Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException.m", + ] - s.source_files = "Sources/**/**/*.{swift,h,m}" s.private_header_files = "Sources/NimbleObjectiveC/CurrentTestCaseTracker.h" + s.tvos.private_header_files = "Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h" + s.exclude_files = "Sources/Nimble/Adapters/NonObjectiveC/*.swift" 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"' } + s.compiler_flags = '-DPRODUCT_NAME=Nimble/Nimble' + 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/Quick/Externals/Nimble/Nimble.xcodeproj/project.pbxproj b/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.xcodeproj/project.pbxproj index c6fe033..7c2c084 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.xcodeproj/project.pbxproj +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.xcodeproj/project.pbxproj @@ -48,12 +48,15 @@ 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 */; }; + 1F2D175B1DB618ED00EE9C7A /* mach_excServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0261C6D0BB0000693EE /* mach_excServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F2D175C1DB618F000EE9C7A /* mach_excServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0221C6D0B82000693EE /* mach_excServer.c */; }; 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 */; }; + 1F4999A61DBF2DD100BF8877 /* Nimble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F1A742E1940169200FFFC47 /* Nimble.h */; settings = {ATTRIBUTES = (Public, ); }; }; 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 */; }; @@ -94,6 +97,14 @@ 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 */; }; + 1F4BB8A41DAC9DC90048464B /* CwlCatchBadInstructionPOSIX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */; }; + 1F4BB8AB1DAC9DE50048464B /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F4BB8AE1DAC9DED0048464B /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1F4BB8B61DACA0E30048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8B71DACA0E40048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8B81DACAACF0048464B /* ThrowAssertionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */; }; + 1F4BB8BA1DACBFCF0048464B /* CwlCatchBadInstruction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */; }; + 1F4BB8BB1DACBFD00048464B /* CwlCatchBadInstruction.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */; }; 1F5DF15F1BDCA0CE00C3A531 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F5DF1551BDCA0CE00C3A531 /* Nimble.framework */; }; 1F5DF16C1BDCA0F500C3A531 /* AssertionRecorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD051968AB07008ED995 /* AssertionRecorder.swift */; }; 1F5DF16D1BDCA0F500C3A531 /* AdapterProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1FD8CD061968AB07008ED995 /* AdapterProtocols.swift */; }; @@ -155,7 +166,6 @@ 1F5DF1A91BDCA10200C3A531 /* MatchTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDB4D5EF19FE442800E9D9FE /* MatchTest.swift */; }; 1F5DF1AA1BDCA10200C3A531 /* RaisesExceptionTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F925EEB195C12C800ED456B /* RaisesExceptionTest.swift */; }; 1F5DF1AB1BDCA10200C3A531 /* ThrowErrorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29EA59621B551ED2002D767E /* ThrowErrorTest.swift */; }; - 1F5DF1AE1BDCA17600C3A531 /* Nimble.h in Headers */ = {isa = PBXBuildFile; fileRef = 1F1A742E1940169200FFFC47 /* Nimble.h */; settings = {ATTRIBUTES = (Public, ); }; }; 1F8A37B01B7C5042001C8357 /* ObjCSyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */; }; 1F8A37B11B7C5042001C8357 /* ObjCSyncTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */; }; 1F91DD2D1C74BF36002C309F /* BeVoidTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1F91DD2C1C74BF36002C309F /* BeVoidTest.swift */; }; @@ -282,11 +292,25 @@ 7B5358BE1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; 7B5358BF1C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; 7B5358C01C38479700A23FAA /* SatisfyAnyOf.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */; }; - 7B5358C51C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */; }; - 7B5358C61C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */; }; - 8DF1C3F71C94FC75004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; - 8DF1C3F81C94FC75004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; - 8DF1C3F91C94FD0C004B2D36 /* ObjcStringersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */; }; + 9630C00D1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C00E1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C0131C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */; }; + 9630C0141C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */; }; + 9630C0191C6D0B2F000693EE /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C01A1C6D0B2F000693EE /* CwlCatchException.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0161C6D0B2F000693EE /* CwlCatchException.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C01C1C6D0B2F000693EE /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0171C6D0B2F000693EE /* CwlCatchException.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 9630C01D1C6D0B2F000693EE /* CwlCatchException.m in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0171C6D0B2F000693EE /* CwlCatchException.m */; settings = {COMPILER_FLAGS = "-fobjc-arc"; }; }; + 9630C01F1C6D0B2F000693EE /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */; }; + 9630C0201C6D0B2F000693EE /* CwlCatchException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */; }; + 9630C0231C6D0B82000693EE /* mach_excServer.c in Sources */ = {isa = PBXBuildFile; fileRef = 9630C0221C6D0B82000693EE /* mach_excServer.c */; }; + 9630C0271C6D0BB0000693EE /* mach_excServer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9630C0261C6D0BB0000693EE /* mach_excServer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9630C02C1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */; }; + 9630C02D1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */; }; + 9630C0301C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */; }; + 9630C0311C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */; }; + 964CFEFD1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; + 964CFEFE1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */; }; + 964CFEFF1C4FF48900513336 /* ThrowAssertion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 964CFEFC1C4FF48900513336 /* ThrowAssertion.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 */; }; @@ -455,6 +479,8 @@ 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 = ""; }; + 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchBadInstructionPOSIX.swift; path = CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift; sourceTree = ""; }; + 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowAssertionTest.swift; sourceTree = ""; }; 1F5DF1551BDCA0CE00C3A531 /* Nimble.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Nimble.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 1F5DF15E1BDCA0CE00C3A531 /* NimbleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = NimbleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 1F8A37AF1B7C5042001C8357 /* ObjCSyncTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSyncTest.m; sourceTree = ""; }; @@ -521,6 +547,17 @@ 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SatisfyAnyOf.swift; sourceTree = ""; }; 7B5358C11C39155600A23FAA /* ObjCSatisfyAnyOfTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjCSatisfyAnyOfTest.m; sourceTree = ""; }; 8DF1C3F61C94FC75004B2D36 /* ObjcStringersTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ObjcStringersTest.m; sourceTree = ""; }; + 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CwlCatchBadInstruction.h; path = CwlPreconditionTesting/CwlCatchBadInstruction.h; sourceTree = ""; }; + 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CwlCatchBadInstruction.m; path = CwlPreconditionTesting/CwlCatchBadInstruction.m; sourceTree = ""; }; + 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchBadInstruction.swift; path = CwlPreconditionTesting/CwlCatchBadInstruction.swift; sourceTree = ""; }; + 9630C0161C6D0B2F000693EE /* CwlCatchException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CwlCatchException.h; path = CwlCatchException/CwlCatchException/CwlCatchException.h; sourceTree = ""; }; + 9630C0171C6D0B2F000693EE /* CwlCatchException.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CwlCatchException.m; path = CwlCatchException/CwlCatchException/CwlCatchException.m; sourceTree = ""; }; + 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlCatchException.swift; path = CwlCatchException/CwlCatchException/CwlCatchException.swift; sourceTree = ""; }; + 9630C0221C6D0B82000693EE /* mach_excServer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mach_excServer.c; path = CwlPreconditionTesting/mach_excServer.c; sourceTree = ""; }; + 9630C0261C6D0BB0000693EE /* mach_excServer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mach_excServer.h; path = CwlPreconditionTesting/mach_excServer.h; sourceTree = ""; }; + 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlBadInstructionException.swift; path = CwlPreconditionTesting/CwlBadInstructionException.swift; sourceTree = ""; }; + 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CwlDarwinDefinitions.swift; path = CwlPreconditionTesting/CwlDarwinDefinitions.swift; sourceTree = ""; }; + 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ThrowAssertion.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 = ""; }; AE4BA9AC1C88DDB500B73906 /* Errors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; @@ -627,6 +664,7 @@ 1F1A742B1940169200FFFC47 /* Nimble */, 1F1871B91CA89E1B00A34BF2 /* NimbleObjectiveC */, 1F1A74381940169200FFFC47 /* NimbleTests */, + 9630C0081C6D0AB3000693EE /* Lib */, 1F1A742A1940169200FFFC47 /* Products */, ); indentWidth = 4; @@ -717,6 +755,7 @@ 7B5358B91C3846C900A23FAA /* SatisfyAnyOfTest.swift */, 1FCF914E1C61C85A00B15DCB /* PostNotificationTest.swift */, AE7ADE481C80C00D00B94CD3 /* MatchErrorTest.swift */, + 1F4BB8B31DACA0D00048464B /* ThrowAssertionTest.swift */, ); path = Matchers; sourceTree = ""; @@ -764,6 +803,7 @@ AE7ADE441C80BF8000B94CD3 /* MatchError.swift */, 1FCF91521C61C8A400B15DCB /* PostNotification.swift */, 1FD8CD1E1968AB07008ED995 /* RaisesException.swift */, + 964CFEFC1C4FF48900513336 /* ThrowAssertion.swift */, 7B5358BD1C38479700A23FAA /* SatisfyAnyOf.swift */, 29EA59651B551EE6002D767E /* ThrowError.swift */, ); @@ -817,6 +857,33 @@ path = objc; sourceTree = ""; }; + 9630C0081C6D0AB3000693EE /* Lib */ = { + isa = PBXGroup; + children = ( + 9630C0091C6D0ABA000693EE /* CwlPreconditionTesting */, + ); + name = Lib; + path = Sources/Lib; + sourceTree = ""; + }; + 9630C0091C6D0ABA000693EE /* CwlPreconditionTesting */ = { + isa = PBXGroup; + children = ( + 1F4BB89D1DAC9D930048464B /* CwlCatchBadInstructionPOSIX.swift */, + 9630C02B1C6D125F000693EE /* CwlBadInstructionException.swift */, + 9630C00C1C6D0B18000693EE /* CwlCatchBadInstruction.swift */, + 9630C00A1C6D0B18000693EE /* CwlCatchBadInstruction.h */, + 9630C00B1C6D0B18000693EE /* CwlCatchBadInstruction.m */, + 9630C0181C6D0B2F000693EE /* CwlCatchException.swift */, + 9630C0161C6D0B2F000693EE /* CwlCatchException.h */, + 9630C0171C6D0B2F000693EE /* CwlCatchException.m */, + 9630C02F1C6D139F000693EE /* CwlDarwinDefinitions.swift */, + 9630C0261C6D0BB0000693EE /* mach_excServer.h */, + 9630C0221C6D0B82000693EE /* mach_excServer.c */, + ); + path = CwlPreconditionTesting; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -824,10 +891,13 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 9630C00D1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */, + 9630C0191C6D0B2F000693EE /* CwlCatchException.h in Headers */, 1F1871C91CA89EDB00A34BF2 /* NMBStringify.h in Headers */, 1F1871C51CA89EDB00A34BF2 /* DSL.h in Headers */, 1F1871C71CA89EDB00A34BF2 /* NMBExceptionCapture.h in Headers */, 1F1A742F1940169200FFFC47 /* Nimble.h in Headers */, + 9630C0271C6D0BB0000693EE /* mach_excServer.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -835,10 +905,12 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 1F4BB8AE1DAC9DED0048464B /* CwlCatchException.h in Headers */, 1F1871E21CA89EF600A34BF2 /* NMBStringify.h in Headers */, 1F1871E01CA89EF600A34BF2 /* DSL.h in Headers */, 1F1871E11CA89EF600A34BF2 /* NMBExceptionCapture.h in Headers */, - 1F5DF1AE1BDCA17600C3A531 /* Nimble.h in Headers */, + 1F4BB8AB1DAC9DE50048464B /* CwlCatchBadInstruction.h in Headers */, + 1F4999A61DBF2DD100BF8877 /* Nimble.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -846,6 +918,9 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 9630C00E1C6D0B18000693EE /* CwlCatchBadInstruction.h in Headers */, + 9630C01A1C6D0B2F000693EE /* CwlCatchException.h in Headers */, + 1F2D175B1DB618ED00EE9C7A /* mach_excServer.h in Headers */, 1F1871DF1CA89EF500A34BF2 /* NMBStringify.h in Headers */, 1F1871DD1CA89EF500A34BF2 /* DSL.h in Headers */, 1F1871DE1CA89EF500A34BF2 /* NMBExceptionCapture.h in Headers */, @@ -1109,6 +1184,7 @@ 1F1871C61CA89EDB00A34BF2 /* DSL.m in Sources */, 1FD8CD301968AB07008ED995 /* AdapterProtocols.swift in Sources */, AE7ADE451C80BF8000B94CD3 /* MatchError.swift in Sources */, + 1F4BB8BA1DACBFCF0048464B /* CwlCatchBadInstruction.m in Sources */, 1FC494AA1C29CBA40010975C /* NimbleEnvironment.swift in Sources */, 1FD8CD5E1968AB07008ED995 /* RaisesException.swift in Sources */, 1FD8CD561968AB07008ED995 /* Contain.swift in Sources */, @@ -1128,6 +1204,13 @@ 1FD8CD381968AB07008ED995 /* Expression.swift in Sources */, 1FD8CD3A1968AB07008ED995 /* FailureMessage.swift in Sources */, 472FD1351B9E085700C7B8DA /* HaveCount.swift in Sources */, + 9630C0301C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */, + 9630C0231C6D0B82000693EE /* mach_excServer.c in Sources */, + 9630C01F1C6D0B2F000693EE /* CwlCatchException.swift in Sources */, + 9630C0131C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */, + 9630C01C1C6D0B2F000693EE /* CwlCatchException.m in Sources */, + 9630C02C1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */, + 964CFEFD1C4FF48900513336 /* ThrowAssertion.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1146,7 +1229,6 @@ DDB4D5F019FE442800E9D9FE /* MatchTest.swift in Sources */, 1F4A56731A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */, 1F4A56821A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */, - 8DF1C3F71C94FC75004B2D36 /* ObjcStringersTest.m in Sources */, 1F925F02195C189500ED456B /* ContainTest.swift in Sources */, 1F4A56881A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */, 1F4A568E1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */, @@ -1179,6 +1261,7 @@ 1F0648CC19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */, 1F4A56851A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */, DD9A9A8F19CF439B00706F49 /* BeIdenticalToObjectTest.swift in Sources */, + 1F4BB8B71DACA0E40048464B /* ThrowAssertionTest.swift in Sources */, 1F0648D41963AAB2001F9C46 /* SynchronousTests.swift in Sources */, 347155CA1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 4793854D1BA0BB2500296F85 /* ObjCHaveCount.m in Sources */, @@ -1187,7 +1270,6 @@ 1F925F05195C18B700ED456B /* EqualTest.swift in Sources */, 1F4A566D1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */, DD72EC641A93874A002F7651 /* AllPassTest.swift in Sources */, - 7B5358C51C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */, 1F4A569D1A3B3565009E1637 /* ObjCMatchTest.m in Sources */, 1F925EE9195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */, 29EA59631B551ED2002D767E /* ThrowErrorTest.swift in Sources */, @@ -1220,6 +1302,7 @@ 1F5DF1781BDCA0F500C3A531 /* BeAnInstanceOf.swift in Sources */, 1F5DF1771BDCA0F500C3A531 /* BeAKindOf.swift in Sources */, 1F5DF17F1BDCA0F500C3A531 /* BeLessThan.swift in Sources */, + 1F4BB8A41DAC9DC90048464B /* CwlCatchBadInstructionPOSIX.swift in Sources */, 1F5DF17C1BDCA0F500C3A531 /* BeGreaterThan.swift in Sources */, 1F91DD331C74BF61002C309F /* BeVoid.swift in Sources */, 1FCF91551C61C8A400B15DCB /* PostNotification.swift in Sources */, @@ -1242,6 +1325,7 @@ 1F1871D81CA89EEF00A34BF2 /* NMBStringify.m in Sources */, 1F5DF1821BDCA0F500C3A531 /* BeNil.swift in Sources */, 1F5DF16F1BDCA0F500C3A531 /* AssertionDispatcher.swift in Sources */, + 964CFEFF1C4FF48900513336 /* ThrowAssertion.swift in Sources */, 1F5DF1841BDCA0F500C3A531 /* EndWith.swift in Sources */, 1F5DF18D1BDCA0F500C3A531 /* SourceLocation.swift in Sources */, 1F5DF1701BDCA0F500C3A531 /* DSL.swift in Sources */, @@ -1301,13 +1385,13 @@ CD79C9A51D2CC848004B6F9A /* ObjCBeginWithTest.m in Sources */, 347155CC1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 1F5DF1AA1BDCA10200C3A531 /* RaisesExceptionTest.swift in Sources */, - 8DF1C3F91C94FD0C004B2D36 /* ObjcStringersTest.m in Sources */, 1F5DF1941BDCA10200C3A531 /* UserDescriptionTest.swift in Sources */, CD79C9AF1D2CC848004B6F9A /* ObjCContainTest.m in Sources */, 1F5DF19F1BDCA10200C3A531 /* BeIdenticalToObjectTest.swift in Sources */, CD79C99E1D2CC832004B6F9A /* ObjCAsyncTest.m in Sources */, 1F91DD2F1C74BF36002C309F /* BeVoidTest.swift in Sources */, 6CAEDD0C1CAEA86F003F1584 /* LinuxSupport.swift in Sources */, + 1F4BB8B81DACAACF0048464B /* ThrowAssertionTest.swift in Sources */, CD79C9B71D2CC848004B6F9A /* ObjCSatisfyAnyOfTest.m in Sources */, 1F5DF1991BDCA10200C3A531 /* BeAnInstanceOfTest.swift in Sources */, CD79C9B11D2CC848004B6F9A /* ObjCEqualTest.m in Sources */, @@ -1350,7 +1434,9 @@ F8A1BE301CB3710900031679 /* XCTestObservationCenter+Register.m in Sources */, 1F1871DA1CA89EF100A34BF2 /* NMBObjCMatcher.swift in Sources */, 1FD8CD311968AB07008ED995 /* AdapterProtocols.swift in Sources */, + 1F2D175C1DB618F000EE9C7A /* mach_excServer.c in Sources */, 1F1871D21CA89EEE00A34BF2 /* DSL.m in Sources */, + 1F4BB8BB1DACBFD00048464B /* CwlCatchBadInstruction.m in Sources */, AE7ADE461C80BF8000B94CD3 /* MatchError.swift in Sources */, 1FC494AB1C29CBA40010975C /* NimbleEnvironment.swift in Sources */, 1FD8CD5F1968AB07008ED995 /* RaisesException.swift in Sources */, @@ -1363,6 +1449,7 @@ 1F1871D41CA89EEE00A34BF2 /* NMBStringify.m in Sources */, 1FD8CD531968AB07008ED995 /* BeNil.swift in Sources */, 1FD8CD6B1968AB07008ED995 /* Async.swift in Sources */, + 964CFEFE1C4FF48900513336 /* ThrowAssertion.swift in Sources */, 1FD8CD591968AB07008ED995 /* EndWith.swift in Sources */, 1FD8CD5D1968AB07008ED995 /* MatcherProtocols.swift in Sources */, 1FD8CD351968AB07008ED995 /* DSL.swift in Sources */, @@ -1370,6 +1457,11 @@ 1FD8CD391968AB07008ED995 /* Expression.swift in Sources */, 1FD8CD3B1968AB07008ED995 /* FailureMessage.swift in Sources */, 472FD1391B9E0A9700C7B8DA /* HaveCount.swift in Sources */, + 9630C0311C6D139F000693EE /* CwlDarwinDefinitions.swift in Sources */, + 9630C0201C6D0B2F000693EE /* CwlCatchException.swift in Sources */, + 9630C0141C6D0B18000693EE /* CwlCatchBadInstruction.swift in Sources */, + 9630C01D1C6D0B2F000693EE /* CwlCatchException.m in Sources */, + 9630C02D1C6D125F000693EE /* CwlBadInstructionException.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1388,7 +1480,6 @@ DDB4D5F119FE442800E9D9FE /* MatchTest.swift in Sources */, 1F4A56741A3B3210009E1637 /* ObjCBeginWithTest.m in Sources */, 1F4A56831A3B336F009E1637 /* ObjCBeLessThanOrEqualToTest.m in Sources */, - 8DF1C3F81C94FC75004B2D36 /* ObjcStringersTest.m in Sources */, 1F925F03195C189500ED456B /* ContainTest.swift in Sources */, 1F4A56891A3B33CB009E1637 /* ObjCBeFalsyTest.m in Sources */, 1F4A568F1A3B342B009E1637 /* ObjCBeFalseTest.m in Sources */, @@ -1421,6 +1512,7 @@ 1F0648CD19639F5A001F9C46 /* ObjectWithLazyProperty.swift in Sources */, 1F4A56861A3B33A0009E1637 /* ObjCBeTruthyTest.m in Sources */, DD9A9A9019CF43AD00706F49 /* BeIdenticalToObjectTest.swift in Sources */, + 1F4BB8B61DACA0E30048464B /* ThrowAssertionTest.swift in Sources */, 1F0648D51963AAB2001F9C46 /* SynchronousTests.swift in Sources */, 347155CB1C337C8900549F03 /* XCTestCaseProvider.swift in Sources */, 4793854E1BA0BB2500296F85 /* ObjCHaveCount.m in Sources */, @@ -1429,7 +1521,6 @@ 1F925F06195C18B700ED456B /* EqualTest.swift in Sources */, 1F4A566E1A3B3159009E1637 /* ObjCBeKindOfTest.m in Sources */, DD72EC651A93874A002F7651 /* AllPassTest.swift in Sources */, - 7B5358C61C39184200A23FAA /* ObjCSatisfyAnyOfTest.m in Sources */, 1F4A569E1A3B3565009E1637 /* ObjCMatchTest.m in Sources */, 1F925EEA195C124400ED456B /* BeAnInstanceOfTest.swift in Sources */, 29EA59641B551ED2002D767E /* ThrowErrorTest.swift in Sources */, @@ -1607,6 +1698,11 @@ "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(DEVELOPER_FRAMEWORKS_DIR)", ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1638,6 +1734,10 @@ "$(PLATFORM_DIR)/Developer/Library/Frameworks", "$(DEVELOPER_FRAMEWORKS_DIR)", ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1709,6 +1809,11 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1742,6 +1847,10 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -1818,6 +1927,7 @@ FRAMEWORK_VERSION = A; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", "$(inherited)", ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; @@ -1853,6 +1963,10 @@ "$(DEVELOPER_FRAMEWORKS_DIR)", ); FRAMEWORK_VERSION = A; + GCC_PREPROCESSOR_DEFINITIONS = ( + "PRODUCT_NAME=$(PRODUCT_NAME)/$(PRODUCT_NAME)", + "$(inherited)", + ); GCC_TREAT_WARNINGS_AS_ERRORS = YES; INFOPLIST_FILE = Sources/Nimble/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme b/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme index c1c4ade..2309132 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Nimble.xcodeproj/xcshareddata/xcschemes/Nimble-tvOS.xcscheme @@ -24,8 +24,8 @@ Void in fatalError() }.to(throwAssertion()) +expect { precondition(false) }.to(throwAssertion()) + +// Passes if throwing a NSError is not equal to throwing an assertion: +expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion()) + +// Passes if the post assertion code is not run: +var reachedPoint1 = false +var reachedPoint2 = false +expect { + reachedPoint1 = true + precondition(false, "condition message") + reachedPoint2 = true +}.to(throwAssertion()) + +expect(reachedPoint1) == true +expect(reachedPoint2) == false +``` + +Notes: + +* This feature is only available in Swift. +* It is only supported for `x86_64` binaries, meaning _you cannot run this matcher on iOS devices, only simulators_. +* The tvOS simulator is supported, but using a different mechanism, requiring you to turn off the `Debug executable` scheme setting for your tvOS scheme's Test configuration. + ## Swift Error Handling If you're using Swift 2.0+, you can use the `throwError` matcher to check if an error is thrown. @@ -975,10 +1047,10 @@ expect(actual).to(satisfyAnyOf(beLessThan(@10), beGreaterThan(@20))) expect(@6).to(satisfyAnyOf(equal(@2), equal(@3), equal(@4), equal(@5), equal(@6), equal(@7))) ``` -Note: This matcher allows you to chain any number of matchers together. This provides flexibility, - but if you find yourself chaining many matchers together in one test, consider whether you - could instead refactor that single test into multiple, more precisely focused tests for - better coverage. +Note: This matcher allows you to chain any number of matchers together. This provides flexibility, + but if you find yourself chaining many matchers together in one test, consider whether you + could instead refactor that single test into multiple, more precisely focused tests for + better coverage. # Writing Your Own Matchers @@ -1189,7 +1261,7 @@ extension NMBObjCMatcher { > 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). + Documentation](https://github.com/Quick/Quick/blob/master/Documentation/en-us/InstallingQuick.md). Nimble can currently be installed in one of two ways: using CocoaPods, or with git submodules. @@ -1224,7 +1296,7 @@ source 'https://github.com/CocoaPods/Specs.git' target 'YOUR_APP_NAME_HERE_Tests', :exclusive => true do use_frameworks! - pod 'Nimble', '~> 4.0.0' + pod 'Nimble', '~> 5.0.0' end ``` diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift index 5434aaf..a55cb27 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Adapters/NimbleEnvironment.swift @@ -1,3 +1,4 @@ +import Dispatch import Foundation /// "Global" state of Nimble is stored here. Only DSL functions should access / be aware of this @@ -25,7 +26,7 @@ internal class NimbleEnvironment { set { NimbleAssertionHandler = newValue } } -#if _runtime(_ObjC) + var suppressTVOSAssertionWarning: Bool = false var awaiter: Awaiter init() { @@ -41,5 +42,4 @@ internal class NimbleEnvironment { asyncQueue: .main, timeoutQueue: timeoutQueue) } -#endif } diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/DSL+Wait.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/DSL+Wait.swift index fa5a10f..619b6dc 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/DSL+Wait.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/DSL+Wait.swift @@ -1,6 +1,6 @@ +import Dispatch import Foundation -#if _runtime(_ObjC) private enum ErrorResult { case exception(NSException) case error(Error) @@ -70,10 +70,16 @@ internal class NMBWait: NSObject { } } + #if _runtime(_ObjC) @objc(untilFile:line:action:) internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) -> Void { until(timeout: 1, file: file, line: line, action: action) } + #else + internal class func until(_ file: FileString = #file, line: UInt = #line, action: @escaping (() -> Void) -> Void) -> Void { + until(timeout: 1, file: file, line: line, action: action) + } + #endif } internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: TimeInterval) -> String { @@ -90,4 +96,3 @@ internal func blockedRunLoopErrorMessageFor(_ fnName: String, leeway: TimeInterv public func waitUntil(timeout: TimeInterval = 1, file: FileString = #file, line: UInt = #line, action: @escaping (@escaping () -> Void) -> Void) -> Void { NMBWait.until(timeout: timeout, file: file, line: line, action: action) } -#endif diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift index c028f5a..6b89c76 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/AsyncMatcherWrapper.swift @@ -1,7 +1,7 @@ import Foundation -#if _runtime(_ObjC) - +/// If you are running on a slower machine, it could be useful to increase the default timeout value +/// or slow down poll interval. Default timeout interval is 1, and poll interval is 0.01. public struct AsyncDefaults { public static var Timeout: TimeInterval = 1 public static var PollInterval: TimeInterval = 0.01 @@ -144,5 +144,3 @@ extension Expectation { return toEventuallyNot(matcher, timeout: timeout, pollInterval: pollInterval, description: description) } } - -#endif diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/BeLessThan.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/BeLessThan.swift index 4cd1a05..fbcd7c7 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/BeLessThan.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/BeLessThan.swift @@ -33,7 +33,7 @@ public func <(lhs: Expectation, rhs: NMBComparable?) { extension NMBObjCMatcher { public class func beLessThanMatcher(_ expected: NMBComparable?) -> NMBObjCMatcher { return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in - let expr = actualExpression.cast { $0 as! NMBComparable? } + let expr = actualExpression.cast { $0 as? NMBComparable } return try! beLessThan(expected).matches(expr, failureMessage: failureMessage) } } diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/BeLogical.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/BeLogical.swift index ee62928..49272a3 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/BeLogical.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/BeLogical.swift @@ -144,28 +144,28 @@ public func beFalsy() -> MatcherFunc extension NMBObjCMatcher { public class func beTruthyMatcher() -> NMBObjCMatcher { return NMBObjCMatcher { actualExpression, failureMessage in - let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false as Bool? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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 Bool? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } 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? } + let expr = actualExpression.cast { ($0 as? NSNumber)?.boolValue ?? false } return try! beFalse().matches(expr, failureMessage: failureMessage) } } diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/Match.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/Match.swift index c225f88..3ad5fb5 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/Match.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/Match.swift @@ -1,7 +1,5 @@ import Foundation -#if _runtime(_ObjC) - /// A Nimble matcher that succeeds when the actual string satisfies the regular expression /// described by the expected string. public func match(_ expectedValue: String?) -> NonNilMatcherFunc { @@ -18,6 +16,8 @@ public func match(_ expectedValue: String?) -> NonNilMatcherFunc { } } +#if _runtime(_ObjC) + extension NMBObjCMatcher { public class func matchMatcher(_ expected: NSString) -> NMBMatcher { return NMBObjCMatcher(canMatchNil: false) { actualExpression, failureMessage in diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Nimble.h b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Nimble.h index 1eab61a..790d16d 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Nimble.h +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Nimble.h @@ -3,5 +3,12 @@ #import "NMBStringify.h" #import "DSL.h" +#import "CwlCatchException.h" +#import "CwlCatchBadInstruction.h" + +#if !TARGET_OS_TV + #import "mach_excServer.h" +#endif + FOUNDATION_EXPORT double NimbleVersionNumber; FOUNDATION_EXPORT const unsigned char NimbleVersionString[]; diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Utils/Async.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Utils/Async.swift index a78a147..c902692 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Utils/Async.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Utils/Async.swift @@ -1,10 +1,13 @@ +import CoreFoundation +import Dispatch import Foundation -#if _runtime(_ObjC) -import Dispatch +#if !_runtime(_ObjC) + import CDispatch +#endif -private let timeoutLeeway = DispatchTimeInterval.nanoseconds(Int(NSEC_PER_MSEC)) -private let pollLeeway = DispatchTimeInterval.nanoseconds(Int(NSEC_PER_MSEC)) +private let timeoutLeeway = DispatchTimeInterval.milliseconds(1) +private let pollLeeway = DispatchTimeInterval.milliseconds(1) /// Stores debugging information about callers internal struct WaitingInfo: CustomStringConvertible { @@ -29,8 +32,13 @@ internal class AssertionWaitLock: WaitLock { func acquireWaitingLock(_ fnName: String, file: FileString, line: UInt) { let info = WaitingInfo(name: fnName, file: file, lineNumber: line) + #if _runtime(_ObjC) + let isMainThread = Thread.isMainThread + #else + let isMainThread = _CFIsMainThread() + #endif nimblePrecondition( - Thread.isMainThread, + isMainThread, "InvalidNimbleAPIUsage", "\(fnName) can only run on the main thread." ) @@ -177,7 +185,12 @@ internal class AwaitPromiseBuilder { let semTimedOutOrBlocked = DispatchSemaphore(value: 0) semTimedOutOrBlocked.signal() let runLoop = CFRunLoopGetMain() - CFRunLoopPerformBlock(runLoop, CFRunLoopMode.defaultMode.rawValue) { + #if _runtime(_ObjC) + let runLoopMode = CFRunLoopMode.defaultMode.rawValue + #else + let runLoopMode = kCFRunLoopDefaultMode + #endif + CFRunLoopPerformBlock(runLoop, runLoopMode) { if semTimedOutOrBlocked.wait(timeout: .now()) == .success { timedOutSem.signal() semTimedOutOrBlocked.signal() @@ -237,7 +250,7 @@ internal class AwaitPromiseBuilder { self.trigger.timeoutSource.resume() while self.promise.asyncResult.isIncomplete() { // Stopping the run loop does not work unless we run only 1 mode - RunLoop.current.run(mode: .defaultRunLoopMode, before: .distantFuture) + _ = RunLoop.current.run(mode: .defaultRunLoopMode, before: .distantFuture) } self.trigger.timeoutSource.suspend() self.trigger.timeoutSource.cancel() @@ -346,5 +359,3 @@ internal func pollBlock( return result } - -#endif diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Utils/Errors.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Utils/Errors.swift index 54bed92..d424c98 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Utils/Errors.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Utils/Errors.swift @@ -77,14 +77,21 @@ internal func errorMatchesNonNilFieldsOrClosure( matches = false } } - } else if errorType != nil && closure != nil { + } else if errorType != nil { + matches = (actualError is T) // The closure expects another ErrorProtocol as argument, so this // is _supposed_ to fail, so that it becomes more obvious. - let assertions = gatherExpectations { - expect(actualError is T).to(equal(true)) + if let closure = closure { + let assertions = gatherExpectations { + if let actual = actualError as? T { + closure(actual) + } + } + let messages = assertions.map { $0.message } + if messages.count > 0 { + matches = false + } } - precondition(assertions.map { $0.message }.count > 0) - matches = false } } diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/NimbleObjectiveC/DSL.h b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/NimbleObjectiveC/DSL.h index a499059..54677ee 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/NimbleObjectiveC/DSL.h +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/NimbleObjectiveC/DSL.h @@ -6,48 +6,222 @@ @protocol NMBMatcher; +NS_ASSUME_NONNULL_BEGIN + + +#define NIMBLE_OVERLOADABLE __attribute__((overloadable)) #define NIMBLE_EXPORT FOUNDATION_EXPORT +#define NIMBLE_EXPORT_INLINE FOUNDATION_STATIC_INLINE + +#define NIMBLE_VALUE_OF(VAL) ({ \ + __typeof__((VAL)) val = (VAL); \ + [NSValue valueWithBytes:&val objCType:@encode(__typeof__((VAL)))]; \ +}) #ifdef NIMBLE_DISABLE_SHORT_SYNTAX #define NIMBLE_SHORT(PROTO, ORIGINAL) +#define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) #else #define NIMBLE_SHORT(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE PROTO { return (ORIGINAL); } +#define NIMBLE_SHORT_OVERLOADED(PROTO, ORIGINAL) FOUNDATION_STATIC_INLINE NIMBLE_OVERLOADABLE PROTO { return (ORIGINAL); } #endif -NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line); + + +#define DEFINE_NMB_EXPECT_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBExpectation *NMB_expect(TYPE(^actualBlock)(), NSString *file, NSUInteger line) { \ + return NMB_expect(^id { return EXPR; }, file, line); \ + } + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line); + + // overloaded dispatch for nils - expect(nil) + DEFINE_NMB_EXPECT_OVERLOAD(void*, nil) + DEFINE_NMB_EXPECT_OVERLOAD(NSRange, NIMBLE_VALUE_OF(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(int, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned int, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(float, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(double, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(long long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned long long, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(char, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(unsigned char, @(actualBlock())) + // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow + // the compiler to dispatch to bool. + DEFINE_NMB_EXPECT_OVERLOAD(BOOL, @(actualBlock())) + DEFINE_NMB_EXPECT_OVERLOAD(char *, @(actualBlock())) + + +#undef DEFINE_NMB_EXPECT_OVERLOAD + + + 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 id NMB_haveCount(id expectedValue); -NIMBLE_SHORT(id haveCount(id expectedValue), - NMB_haveCount(expectedValue)); -NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue); -NIMBLE_SHORT(NMBObjCBeCloseToMatcher *beCloseTo(id expectedValue), - NMB_beCloseTo(expectedValue)); +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_equal(TYPE expectedValue) { \ + return NMB_equal((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id equal(TYPE expectedValue), NMB_equal(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_equal(__nullable id expectedValue); + + NIMBLE_SHORT_OVERLOADED(id equal(__nullable id expectedValue), + NMB_equal(expectedValue)); + + // overloaded dispatch for nils - expect(nil) + DEFINE_OVERLOAD(void*__nullable, (id)nil) + DEFINE_OVERLOAD(NSRange, NIMBLE_VALUE_OF(expectedValue)) + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + // bool doesn't get the compiler to dispatch to BOOL types, but using BOOL here seems to allow + // the compiler to dispatch to bool. + DEFINE_OVERLOAD(BOOL, @(expectedValue)) + DEFINE_OVERLOAD(char *, @(expectedValue)) + +#undef DEFINE_OVERLOAD + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_haveCount(TYPE expectedValue) { \ + return NMB_haveCount((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id haveCount(TYPE expectedValue), \ + NMB_haveCount(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_haveCount(id expectedValue); + + NIMBLE_SHORT_OVERLOADED(id haveCount(id expectedValue), + NMB_haveCount(expectedValue)); + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + NMBObjCBeCloseToMatcher *NMB_beCloseTo(TYPE expectedValue) { \ + return NMB_beCloseTo((NSNumber *)(EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToMatcher *beCloseTo(TYPE expectedValue), \ + NMB_beCloseTo(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue); + NIMBLE_SHORT_OVERLOADED(NMBObjCBeCloseToMatcher *beCloseTo(NSNumber *expectedValue), + NMB_beCloseTo(expectedValue)); + + // it would be better to only overload float & double, but zero becomes ambigious + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beAnInstanceOf(Class expectedClass); -NIMBLE_SHORT(id beAnInstanceOf(Class expectedClass), - NMB_beAnInstanceOf(expectedClass)); +NIMBLE_EXPORT_INLINE id beAnInstanceOf(Class expectedClass) { + return NMB_beAnInstanceOf(expectedClass); +} NIMBLE_EXPORT id NMB_beAKindOf(Class expectedClass); -NIMBLE_SHORT(id beAKindOf(Class expectedClass), - NMB_beAKindOf(expectedClass)); +NIMBLE_EXPORT_INLINE id beAKindOf(Class expectedClass) { + return 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_INLINE id beginWith(id itemElementOrSubstring) { + return NMB_beginWith(itemElementOrSubstring); +} + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beGreaterThan(TYPE expectedValue) { \ + return NMB_beGreaterThan((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beGreaterThan(TYPE expectedValue), NMB_beGreaterThan(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beGreaterThan(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beGreaterThan(NSNumber *expectedValue) { + return NMB_beGreaterThan(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beGreaterThanOrEqualTo(TYPE expectedValue) { \ + return NMB_beGreaterThanOrEqualTo((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beGreaterThanOrEqualTo(TYPE expectedValue), \ + NMB_beGreaterThanOrEqualTo(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beGreaterThanOrEqualTo(NSNumber *expectedValue) { + return NMB_beGreaterThanOrEqualTo(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beIdenticalTo(id expectedInstance); NIMBLE_SHORT(id beIdenticalTo(id expectedInstance), @@ -57,13 +231,66 @@ NIMBLE_EXPORT id NMB_be(id expectedInstance); NIMBLE_SHORT(id be(id expectedInstance), NMB_be(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)); +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beLessThan(TYPE expectedValue) { \ + return NMB_beLessThan((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beLessThan(TYPE expectedValue), \ + NMB_beLessThan(expectedValue)); + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beLessThan(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beLessThan(NSNumber *expectedValue) { + return NMB_beLessThan(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD + + +#define DEFINE_OVERLOAD(TYPE, EXPR) \ + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE \ + id NMB_beLessThanOrEqualTo(TYPE expectedValue) { \ + return NMB_beLessThanOrEqualTo((EXPR)); \ + } \ + NIMBLE_SHORT_OVERLOADED(id beLessThanOrEqualTo(TYPE expectedValue), \ + NMB_beLessThanOrEqualTo(expectedValue)); + + + NIMBLE_EXPORT NIMBLE_OVERLOADABLE + id NMB_beLessThanOrEqualTo(NSNumber *expectedValue); + + NIMBLE_EXPORT_INLINE NIMBLE_OVERLOADABLE + id beLessThanOrEqualTo(NSNumber *expectedValue) { + return NMB_beLessThanOrEqualTo(expectedValue); + } + + DEFINE_OVERLOAD(long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long, @(expectedValue)) + DEFINE_OVERLOAD(int, @(expectedValue)) + DEFINE_OVERLOAD(unsigned int, @(expectedValue)) + DEFINE_OVERLOAD(float, @(expectedValue)) + DEFINE_OVERLOAD(double, @(expectedValue)) + DEFINE_OVERLOAD(long long, @(expectedValue)) + DEFINE_OVERLOAD(unsigned long long, @(expectedValue)) + DEFINE_OVERLOAD(char, @(expectedValue)) + DEFINE_OVERLOAD(unsigned char, @(expectedValue)) + +#undef DEFINE_OVERLOAD NIMBLE_EXPORT id NMB_beTruthy(void); NIMBLE_SHORT(id beTruthy(void), @@ -134,7 +361,7 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger #define NMB_waitUntil NMB_waitUntilBuilder(@(__FILE__), __LINE__) #ifndef NIMBLE_DISABLE_SHORT_SYNTAX -#define expect(...) NMB_expect(^id{ return (__VA_ARGS__); }, @(__FILE__), __LINE__) +#define expect(...) NMB_expect(^{ 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") @@ -142,4 +369,9 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger #define waitUntilTimeout NMB_waitUntilTimeout #define waitUntil NMB_waitUntil + +#undef NIMBLE_VALUE_OF + #endif + +NS_ASSUME_NONNULL_END diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/NimbleObjectiveC/DSL.m b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/NimbleObjectiveC/DSL.m index 2170238..cd93ddd 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/NimbleObjectiveC/DSL.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/NimbleObjectiveC/DSL.m @@ -9,7 +9,11 @@ + (void)untilFile:(NSString *)file line:(NSUInteger)line action:(void(^)())actio @end -NIMBLE_EXPORT NMBExpectation *NMB_expect(id(^actualBlock)(), NSString *file, NSUInteger line) { + +NS_ASSUME_NONNULL_BEGIN + + +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBExpectation *__nonnull NMB_expect(id __nullable(^actualBlock)(), NSString *__nonnull file, NSUInteger line) { return [[NMBExpectation alloc] initWithActualBlock:actualBlock negative:NO file:file @@ -35,7 +39,7 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beAKindOfMatcher:expectedClass]; } -NIMBLE_EXPORT NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE NMBObjCBeCloseToMatcher *NMB_beCloseTo(NSNumber *expectedValue) { return [NMBObjCMatcher beCloseToMatcher:expectedValue within:0.001]; } @@ -43,11 +47,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beginWithMatcher:itemElementOrSubstring]; } -NIMBLE_EXPORT id NMB_beGreaterThan(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beGreaterThan(NSNumber *expectedValue) { return [NMBObjCMatcher beGreaterThanMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beGreaterThanOrEqualTo(NSNumber *expectedValue) { return [NMBObjCMatcher beGreaterThanOrEqualToMatcher:expectedValue]; } @@ -59,11 +63,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher beIdenticalToMatcher:expectedInstance]; } -NIMBLE_EXPORT id NMB_beLessThan(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beLessThan(NSNumber *expectedValue) { return [NMBObjCMatcher beLessThanMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_beLessThanOrEqualTo(NSNumber *expectedValue) { return [NMBObjCMatcher beLessThanOrEqualToMatcher:expectedValue]; } @@ -113,11 +117,11 @@ NIMBLE_EXPORT void NMB_failWithMessage(NSString *msg, NSString *file, NSUInteger return [NMBObjCMatcher endWithMatcher:itemElementOrSubstring]; } -NIMBLE_EXPORT id NMB_equal(id expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_equal(__nullable id expectedValue) { return [NMBObjCMatcher equalMatcher:expectedValue]; } -NIMBLE_EXPORT id NMB_haveCount(id expectedValue) { +NIMBLE_EXPORT NIMBLE_OVERLOADABLE id NMB_haveCount(id expectedValue) { return [NMBObjCMatcher haveCountMatcher:expectedValue]; } @@ -148,3 +152,5 @@ NIMBLE_EXPORT NMBWaitUntilBlock NMB_waitUntilBuilder(NSString *file, NSUInteger [NMBWait untilFile:file line:line action:action]; }; } + +NS_ASSUME_NONNULL_END diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/LinuxMain.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/LinuxMain.swift index 6cae8ca..4210ef0 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/LinuxMain.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/LinuxMain.swift @@ -4,7 +4,7 @@ import XCTest // This is the entry point for NimbleTests on Linux XCTMain([ - // testCase(AsynchronousTests.allTests), + testCase(AsyncTest.allTests), testCase(SynchronousTest.allTests), testCase(UserDescriptionTest.allTests), @@ -29,7 +29,7 @@ XCTMain([ testCase(EndWithTest.allTests), testCase(EqualTest.allTests), testCase(HaveCountTest.allTests), - // testCase(MatchTest.allTests), + testCase(MatchTest.allTests), // testCase(RaisesExceptionTest.allTests), testCase(ThrowErrorTest.allTests), testCase(SatisfyAnyOfTest.allTests), diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/AsynchronousTest.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/AsynchronousTest.swift index 0ccd220..ff78d47 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/AsynchronousTest.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/AsynchronousTest.swift @@ -1,11 +1,8 @@ +import Dispatch import Foundation import XCTest import Nimble -// These tests require the ObjC runtimes do not currently have the GCD and run loop facilities -// required for working with Nimble's async matchers -#if _runtime(_ObjC) - final class AsyncTest: XCTestCase, XCTestCaseProvider { static var allTests: [(String, (AsyncTest) -> () throws -> Void)] { return [ @@ -24,7 +21,8 @@ final class AsyncTest: XCTestCase, XCTestCaseProvider { ] } - let errorToThrow = NSError(domain: NSExceptionName.internalInconsistencyException.rawValue, code: 42, userInfo: nil) + class Error: Swift.Error {} + let errorToThrow = Error() private func doThrowError() throws -> Int { throw errorToThrow @@ -222,5 +220,3 @@ final class AsyncTest: XCTestCase, XCTestCaseProvider { #endif } } -#endif - diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Helpers/utils.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Helpers/utils.swift index 7962ae4..0b33ea6 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Helpers/utils.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Helpers/utils.swift @@ -1,3 +1,4 @@ +import Dispatch import Foundation @testable import Nimble import XCTest @@ -58,14 +59,12 @@ func failsWithErrorMessageForNil(_ message: String, file: FileString = #file, li failsWithErrorMessage("\(message) (use beNil() to match nils)", file: file, line: line, preferOriginalSourceLocation: preferOriginalSourceLocation, closure: closure) } -#if _runtime(_ObjC) func deferToMainQueue(action: @escaping () -> Void) { DispatchQueue.main.async { Thread.sleep(forTimeInterval: 0.01) action() } } -#endif public class NimbleHelper : NSObject { public class func expectFailureMessage(_ message: NSString, block: @escaping () -> Void, file: FileString, line: UInt) { diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift index 7bd3e4c..940a214 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/MatchErrorTest.swift @@ -26,6 +26,7 @@ final class MatchErrorTest: XCTestCase, XCTestCaseProvider { func testMatchErrorNegative() { expect(NimbleError.laugh).toNot(matchError(NimbleError.cry)) expect(NimbleError.laugh as Error).toNot(matchError(NimbleError.cry)) + expect(NimbleError.laugh).toNot(matchError(EquatableError.self)) } func testMatchNSErrorPositive() { @@ -64,6 +65,10 @@ final class MatchErrorTest: XCTestCase, XCTestCaseProvider { failsWithErrorMessage("expected to not match error , got ") { expect(NimbleError.laugh).toNot(matchError(NimbleError.laugh)) } + + failsWithErrorMessage("expected to match error from type , got ") { + expect(NimbleError.laugh).to(matchError(EquatableError.self)) + } } func testDoesNotMatchNils() { diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift index 24257ba..5b6d77f 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/MatchTest.swift @@ -1,8 +1,6 @@ import XCTest import Nimble -#if _runtime(_ObjC) - final class MatchTest:XCTestCase, XCTestCaseProvider { static var allTests: [(String, (MatchTest) -> () throws -> Void)] { return [ @@ -46,4 +44,3 @@ final class MatchTest:XCTestCase, XCTestCaseProvider { } } } -#endif diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift index 8fd5baf..d7cd312 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/ThrowErrorTest.swift @@ -136,7 +136,6 @@ final class ThrowErrorTest: XCTestCase, XCTestCaseProvider { let moduleName = "NimbleTests" let innerFailureMessage = "expected to equal , got <\(moduleName).NimbleError>" let closure = { (error: Error) in - print("** In closure! With domain \(error._domain)") expect(error._domain).to(equal("foo")) } diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/SynchronousTests.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/SynchronousTests.swift index b50e19b..6234932 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/SynchronousTests.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/SynchronousTests.swift @@ -21,7 +21,9 @@ final class SynchronousTest: XCTestCase, XCTestCaseProvider { ] } - let errorToThrow = NSError(domain: NSCocoaErrorDomain, code: 42, userInfo: nil) + class Error: Swift.Error {} + let errorToThrow = Error() + private func doThrowError() throws -> Int { throw errorToThrow } @@ -36,14 +38,12 @@ final class SynchronousTest: XCTestCase, XCTestCaseProvider { } func testUnexpectedErrorsThrownFails() { -#if _runtime(_ObjC) // This test triggers a weird segfault on Linux currently 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)) } -#endif } func testToMatchesIfMatcherReturnsTrue() { diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/UserDescriptionTest.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/UserDescriptionTest.swift index ef754ec..e22d64e 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/UserDescriptionTest.swift +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/UserDescriptionTest.swift @@ -38,33 +38,27 @@ final class UserDescriptionTest: XCTestCase, XCTestCaseProvider { } func testToEventuallyMatch_CustomFailureMessage() { -#if _runtime(_ObjC) 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!") } -#endif } func testToEventuallyNotMatch_CustomFailureMessage() { -#if _runtime(_ObjC) failsWithErrorMessage( "These are eventually equal!\n" + "expected to eventually not equal <1>, got <1>") { expect { 1 }.toEventuallyNot(equal(1), description: "These are eventually equal!") } -#endif } func testToNotEventuallyMatch_CustomFailureMessage() { -#if _runtime(_ObjC) failsWithErrorMessage( "These are eventually equal!\n" + "expected to eventually not equal <1>, got <1>") { expect { 1 }.toEventuallyNot(equal(1), description: "These are eventually equal!") } -#endif } } diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m index c3f5639..c33d643 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeCloseToTest.m @@ -12,6 +12,11 @@ - (void)testPositiveMatches { expect(@1.2).to(beCloseTo(@2).within(10)); expect(@2).toNot(beCloseTo(@1)); expect(@1.00001).toNot(beCloseTo(@1).within(0.00000001)); + + 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 { @@ -21,6 +26,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be close to <0> (within 0.001), got <0.0001>", ^{ expect(@(0.0001)).toNot(beCloseTo(@0)); }); + expectFailureMessage(@"expected to be close to <0> (within 0.001), got <1>", ^{ + expect(1).to(beCloseTo(0)); + }); + expectFailureMessage(@"expected to not be close to <0> (within 0.001), got <0.0001>", ^{ + expect(0.0001).toNot(beCloseTo(0)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m index 5b99842..5a5bce8 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeFalseTest.m @@ -10,6 +10,14 @@ @implementation ObjCBeFalseTest - (void)testPositiveMatches { expect(@NO).to(beFalse()); expect(@YES).toNot(beFalse()); + + expect(false).to(beFalse()); + expect(true).toNot(beFalse()); + + expect(NO).to(beFalse()); + expect(YES).toNot(beFalse()); + + expect(10).toNot(beFalse()); } - (void)testNegativeMatches { @@ -19,6 +27,20 @@ - (void)testNegativeMatches { expectNilFailureMessage(@"expected to not be false, got ", ^{ expect(nil).toNot(beFalse()); }); + + expectFailureMessage(@"expected to be false, got <1>", ^{ + expect(true).to(beFalse()); + }); + expectFailureMessage(@"expected to not be false, got <0>", ^{ + expect(false).toNot(beFalse()); + }); + + expectFailureMessage(@"expected to be false, got <1>", ^{ + expect(YES).to(beFalse()); + }); + expectFailureMessage(@"expected to not be false, got <0>", ^{ + expect(NO).toNot(beFalse()); + }); } @end diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m index 4b6281e..f3f5c98 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeFalsyTest.m @@ -11,6 +11,15 @@ - (void)testPositiveMatches { expect(@NO).to(beFalsy()); expect(@YES).toNot(beFalsy()); expect(nil).to(beFalsy()); + + expect(true).toNot(beFalsy()); + expect(false).to(beFalsy()); + + expect(YES).toNot(beFalsy()); + expect(NO).to(beFalsy()); + + expect(10).toNot(beFalsy()); + expect(0).to(beFalsy()); } - (void)testNegativeMatches { @@ -20,8 +29,29 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be falsy, got <1>", ^{ expect(@1).to(beFalsy()); }); - expectFailureMessage(@"expected to be truthy, got <0>", ^{ - expect(@NO).to(beTruthy()); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(@NO).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <1>", ^{ + expect(true).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(false).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <1>", ^{ + expect(YES).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(NO).toNot(beFalsy()); + }); + + expectFailureMessage(@"expected to be falsy, got <10>", ^{ + expect(10).to(beFalsy()); + }); + expectFailureMessage(@"expected to not be falsy, got <0>", ^{ + expect(0).toNot(beFalsy()); }); } diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m index cec26c7..22cab3a 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanOrEqualToTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeGreaterThanOrEqualToTest - (void)testPositiveMatches { expect(@2).to(beGreaterThanOrEqualTo(@2)); expect(@2).toNot(beGreaterThanOrEqualTo(@3)); + expect(2).to(beGreaterThanOrEqualTo(0)); + expect(2).to(beGreaterThanOrEqualTo(2)); + expect(2).toNot(beGreaterThanOrEqualTo(3)); } - (void)testNegativeMatches { @@ -19,6 +22,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be greater than or equal to <1>, got <2>", ^{ expect(@2).toNot(beGreaterThanOrEqualTo(@(1))); }); + expectFailureMessage(@"expected to be greater than or equal to <0>, got <-1>", ^{ + expect(-1).to(beGreaterThanOrEqualTo(0)); + }); + expectFailureMessage(@"expected to not be greater than or equal to <1>, got <2>", ^{ + expect(2).toNot(beGreaterThanOrEqualTo(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m index 5ad3087..13336d5 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeGreaterThanTest.m @@ -10,6 +10,8 @@ @implementation ObjCBeGreaterThanTest - (void)testPositiveMatches { expect(@2).to(beGreaterThan(@1)); expect(@2).toNot(beGreaterThan(@2)); + expect(@2).to(beGreaterThan(0)); + expect(@2).toNot(beGreaterThan(2)); } - (void)testNegativeMatches { @@ -19,6 +21,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be greater than <1>, got <0>", ^{ expect(@0).toNot(beGreaterThan(@(1))); }); + expectFailureMessage(@"expected to be greater than <0>, got <-1>", ^{ + expect(-1).to(beGreaterThan(0)); + }); + expectFailureMessage(@"expected to not be greater than <1>, got <0>", ^{ + expect(0).toNot(beGreaterThan(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m index ab60a81..a9d9d51 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeIdenticalToTest.m @@ -25,9 +25,12 @@ - (void)testNegativeMatches { - (void)testNilMatches { NSNull *obj = [NSNull null]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" expectNilFailureMessage(@"expected to be identical to nil, got nil", ^{ expect(nil).to(beIdenticalTo(nil)); }); +#pragma clang diagnostic pop expectNilFailureMessage(([NSString stringWithFormat:@"expected to not be identical to <%p>, got nil", obj]), ^{ expect(nil).toNot(beIdenticalTo(obj)); }); @@ -51,9 +54,12 @@ - (void)testAliasNegativeMatches { - (void)testAliasNilMatches { NSNull *obj = [NSNull null]; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnonnull" expectNilFailureMessage(@"expected to be identical to nil, got nil", ^{ expect(nil).to(be(nil)); }); +#pragma clang diagnostic pop expectNilFailureMessage(([NSString stringWithFormat:@"expected to not be identical to <%p>, got nil", obj]), ^{ expect(nil).toNot(be(obj)); }); diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m index dbd2062..4a738ec 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanOrEqualToTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeLessThanOrEqualToTest - (void)testPositiveMatches { expect(@2).to(beLessThanOrEqualTo(@2)); expect(@2).toNot(beLessThanOrEqualTo(@1)); + expect(2).to(beLessThanOrEqualTo(2)); + expect(2).toNot(beLessThanOrEqualTo(1)); + expect(2).toNot(beLessThanOrEqualTo(0)); } - (void)testNegativeMatches { @@ -19,6 +22,13 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be less than or equal to <1>, got <1>", ^{ expect(@1).toNot(beLessThanOrEqualTo(@1)); }); + + expectFailureMessage(@"expected to be less than or equal to <1>, got <2>", ^{ + expect(2).to(beLessThanOrEqualTo(1)); + }); + expectFailureMessage(@"expected to not be less than or equal to <1>, got <1>", ^{ + expect(1).toNot(beLessThanOrEqualTo(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m index 4d9da72..7ba38b2 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeLessThanTest.m @@ -10,6 +10,9 @@ @implementation ObjCBeLessThanTest - (void)testPositiveMatches { expect(@2).to(beLessThan(@3)); expect(@2).toNot(beLessThan(@2)); + expect(2).to(beLessThan(3)); + expect(2).toNot(beLessThan(2)); + expect(2).toNot(beLessThan(0)); } - (void)testNegativeMatches { @@ -19,6 +22,12 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not be less than <1>, got <0>", ^{ expect(@0).toNot(beLessThan(@1)); }); + expectFailureMessage(@"expected to be less than <0>, got <-1>", ^{ + expect(-1).to(beLessThan(0)); + }); + expectFailureMessage(@"expected to not be less than <1>, got <0>", ^{ + expect(0).toNot(beLessThan(1)); + }); } - (void)testNilMatches { diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m index 3f10ce3..c669475 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeTrueTest.m @@ -11,6 +11,12 @@ - (void)testPositiveMatches { expect(@YES).to(beTrue()); expect(@NO).toNot(beTrue()); expect(nil).toNot(beTrue()); + + expect(true).to(beTrue()); + expect(false).toNot(beTrue()); + + expect(YES).to(beTrue()); + expect(NO).toNot(beTrue()); } - (void)testNegativeMatches { @@ -20,6 +26,22 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be true, got ", ^{ expect(nil).to(beTrue()); }); + + expectFailureMessage(@"expected to be true, got <0>", ^{ + expect(false).to(beTrue()); + }); + + expectFailureMessage(@"expected to not be true, got <1>", ^{ + expect(true).toNot(beTrue()); + }); + + expectFailureMessage(@"expected to be true, got <0>", ^{ + expect(NO).to(beTrue()); + }); + + expectFailureMessage(@"expected to not be true, got <1>", ^{ + expect(YES).toNot(beTrue()); + }); } @end diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m index 93180a2..1ad7913 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCBeTruthyTest.m @@ -11,6 +11,15 @@ - (void)testPositiveMatches { expect(@YES).to(beTruthy()); expect(@NO).toNot(beTruthy()); expect(nil).toNot(beTruthy()); + + expect(true).to(beTruthy()); + expect(false).toNot(beTruthy()); + + expect(YES).to(beTruthy()); + expect(NO).toNot(beTruthy()); + + expect(10).to(beTruthy()); + expect(0).toNot(beTruthy()); } - (void)testNegativeMatches { @@ -23,6 +32,24 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to be truthy, got <0>", ^{ expect(@NO).to(beTruthy()); }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(false).to(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <1>", ^{ + expect(true).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(NO).to(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <1>", ^{ + expect(YES).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to not be truthy, got <10>", ^{ + expect(10).toNot(beTruthy()); + }); + expectFailureMessage(@"expected to be truthy, got <0>", ^{ + expect(0).to(beTruthy()); + }); } @end diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m index e5a2be0..6c20809 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCEqualTest.m @@ -12,6 +12,31 @@ - (void)testPositiveMatches { expect(@1).toNot(equal(@2)); expect(@1).notTo(equal(@2)); expect(@"hello").to(equal(@"hello")); + expect("hello").to(equal("hello")); + expect(NSMakeRange(0, 10)).to(equal(NSMakeRange(0, 10))); + expect(NSMakeRange(0, 10)).toNot(equal(NSMakeRange(0, 5))); + expect((NSInteger)1).to(equal((NSInteger)1)); + expect((NSInteger)1).toNot(equal((NSInteger)2)); + expect((NSUInteger)1).to(equal((NSUInteger)1)); + expect((NSUInteger)1).toNot(equal((NSUInteger)2)); + expect(0).to(equal(0)); + expect(1).to(equal(1)); + expect(1).toNot(equal(2)); + expect(1.0).to(equal(1.0)); // Note: not recommended, use beCloseTo() instead + expect(1.0).toNot(equal(2.0)); // Note: not recommended, use beCloseTo() instead + expect((float)1.0).to(equal((float)1.0)); // Note: not recommended, use beCloseTo() instead + expect((float)1.0).toNot(equal((float)2.0)); // Note: not recommended, use beCloseTo() instead + expect((double)1.0).to(equal((double)1.0)); // Note: not recommended, use beCloseTo() instead + expect((double)1.0).toNot(equal((double)2.0)); // Note: not recommended, use beCloseTo() instead + expect((long long)1).to(equal((long long)1)); + expect((long long)1).toNot(equal((long long)2)); + expect((unsigned long long)1).to(equal((unsigned long long)1)); + expect((unsigned long long)1).toNot(equal((unsigned long long)2)); +} + +- (void)testNimbleCurrentlyBoxesNumbersWhichAllowsImplicitTypeConversions { + expect(1).to(equal(1.0)); + expect((long long)1).to(equal((unsigned long long)1)); } - (void)testNegativeMatches { @@ -21,9 +46,43 @@ - (void)testNegativeMatches { expectFailureMessage(@"expected to not equal <1>, got <1>", ^{ expect(@1).toNot(equal(@1)); }); + expectFailureMessage(@"expected to not equal , got ", ^{ + expect("bar").toNot(equal("foo")); + }); + expectFailureMessage(@"expected to equal , got ", ^{ + expect(NSMakeRange(0, 10)).to(equal(NSMakeRange(0, 5))); + }); + + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((NSInteger)1).to(equal((NSInteger)2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((NSUInteger)1).to(equal((NSUInteger)2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect(1).to(equal(2)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect(1.0).to(equal(2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((float)1.0).to(equal((float)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((double)1.0).to(equal((double)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((long long)1.0).to(equal((long long)2.0)); + }); + expectFailureMessage(@"expected to equal <2>, got <1>", ^{ + expect((unsigned long long)1.0).to(equal((unsigned long long)2.0)); + }); } - (void)testNilMatches { + expectNilFailureMessage(@"expected to equal , got ", ^{ + expect(NULL).to(equal(NULL)); + }); expectNilFailureMessage(@"expected to equal , got ", ^{ expect(nil).to(equal(nil)); }); diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m index d5fdf4f..31053c8 100644 --- a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/objc/ObjCHaveCount.m @@ -14,6 +14,12 @@ - (void)testHaveCountForNSArray { expect(@[]).to(haveCount(@0)); expect(@[@1]).notTo(haveCount(@0)); + expect(@[@1, @2, @3]).to(haveCount(3)); + expect(@[@1, @2, @3]).notTo(haveCount(1)); + + expect(@[]).to(haveCount(0)); + expect(@[@1]).notTo(haveCount(0)); + expectFailureMessage(@"expected to have NSArray with count 1, got 3\nActual Value: (1, 2, 3)", ^{ expect(@[@1, @2, @3]).to(haveCount(@1)); }); @@ -22,12 +28,22 @@ - (void)testHaveCountForNSArray { expect(@[@1, @2, @3]).notTo(haveCount(@3)); }); + expectFailureMessage(@"expected to have NSArray with count 1, got 3\nActual Value: (1, 2, 3)", ^{ + expect(@[@1, @2, @3]).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSArray with count 3, got 3\nActual Value: (1, 2, 3)", ^{ + expect(@[@1, @2, @3]).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSDictionary { expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(@3)); expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(@1)); + expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(3)); + expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(1)); + expectFailureMessage(@"expected to have NSDictionary with count 1, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(@1)); }); @@ -35,6 +51,14 @@ - (void)testHaveCountForNSDictionary { expectFailureMessage(@"expected to not have NSDictionary with count 3, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSDictionary with count 1, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ + expect(@{@"1":@1, @"2":@2, @"3":@3}).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSDictionary with count 3, got 3\nActual Value: {1 = 1;2 = 2;3 = 3;}", ^{ + expect(@{@"1":@1, @"2":@2, @"3":@3}).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSHashtable { @@ -46,6 +70,9 @@ - (void)testHaveCountForNSHashtable { expect(table).to(haveCount(@3)); expect(table).notTo(haveCount(@1)); + expect(table).to(haveCount(3)); + expect(table).notTo(haveCount(1)); + NSString *msg = [NSString stringWithFormat: @"expected to have NSHashTable {[2] 2[12] 1[13] 3}with count 1, got 3\nActual Value: %@", [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; @@ -53,13 +80,27 @@ - (void)testHaveCountForNSHashtable { expect(table).to(haveCount(@1)); }); - msg = [NSString stringWithFormat: @"expected to not have NSHashTable {[2] 2[12] 1[13] 3}with count 3, got 3\nActual Value: %@", [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; expectFailureMessage(msg, ^{ expect(table).notTo(haveCount(@3)); }); + + + msg = [NSString stringWithFormat: + @"expected to have NSHashTable {[2] 2[12] 1[13] 3}with count 1, got 3\nActual Value: %@", + [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; + expectFailureMessage(msg, ^{ + expect(table).to(haveCount(1)); + }); + + msg = [NSString stringWithFormat: + @"expected to not have NSHashTable {[2] 2[12] 1[13] 3}with count 3, got 3\nActual Value: %@", + [table.description stringByReplacingOccurrencesOfString:@"\n" withString:@""]]; + expectFailureMessage(msg, ^{ + expect(table).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSSet { @@ -67,6 +108,8 @@ - (void)testHaveCountForNSSet { expect(set).to(haveCount(@3)); expect(set).notTo(haveCount(@1)); + expect(set).to(haveCount(3)); + expect(set).notTo(haveCount(1)); expectFailureMessage(@"expected to have NSSet with count 1, got 3\nActual Value: {(3,1,2)}", ^{ expect(set).to(haveCount(@1)); @@ -75,6 +118,14 @@ - (void)testHaveCountForNSSet { expectFailureMessage(@"expected to not have NSSet with count 3, got 3\nActual Value: {(3,1,2)}", ^{ expect(set).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSSet with count 1, got 3\nActual Value: {(3,1,2)}", ^{ + expect(set).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSSet with count 3, got 3\nActual Value: {(3,1,2)}", ^{ + expect(set).notTo(haveCount(3)); + }); } - (void)testHaveCountForNSIndexSet { @@ -82,6 +133,8 @@ - (void)testHaveCountForNSIndexSet { expect(set).to(haveCount(@3)); expect(set).notTo(haveCount(@1)); + expect(set).to(haveCount(3)); + expect(set).notTo(haveCount(1)); expectFailureMessage(@"expected to have NSIndexSet with count 1, got 3\nActual Value: (1, 2, 3)", ^{ expect(set).to(haveCount(@1)); @@ -90,6 +143,14 @@ - (void)testHaveCountForNSIndexSet { expectFailureMessage(@"expected to not have NSIndexSet with count 3, got 3\nActual Value: (1, 2, 3)", ^{ expect(set).notTo(haveCount(@3)); }); + + expectFailureMessage(@"expected to have NSIndexSet with count 1, got 3\nActual Value: (1, 2, 3)", ^{ + expect(set).to(haveCount(1)); + }); + + expectFailureMessage(@"expected to not have NSIndexSet with count 3, got 3\nActual Value: (1, 2, 3)", ^{ + expect(set).notTo(haveCount(3)); + }); } - (void)testHaveCountForUnsupportedTypes { @@ -100,6 +161,14 @@ - (void)testHaveCountForUnsupportedTypes { expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFNumber", ^{ expect(@1).to(haveCount(@6)); }); + + expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFConstantString", ^{ + expect(@"string").to(haveCount(6)); + }); + + expectFailureMessage(@"expected to get type of NSArray, NSSet, NSDictionary, or NSHashTable, got __NSCFNumber", ^{ + expect(@1).to(haveCount(6)); + }); } @end diff --git a/Carthage/Checkouts/Quick/Package.swift b/Carthage/Checkouts/Quick/Package.swift index 6b97ba5..6d2fac9 100644 --- a/Carthage/Checkouts/Quick/Package.swift +++ b/Carthage/Checkouts/Quick/Package.swift @@ -2,14 +2,9 @@ import PackageDescription let package = Package( name: "Quick", - // TODO: Once the `test` command has been implemented in the Swift Package Manager, this should be changed to - // be `testDependencies:` instead. For now it has to be done like this for the library to get linked with the test targets. - // See: https://github.com/apple/swift-evolution/blob/master/proposals/0019-package-manager-testing.md - dependencies: [ - .Package(url: "https://github.com/Quick/Nimble", "5.0.0") - ], exclude: [ "Sources/QuickObjectiveC", + "Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests+ObjC.m", "Tests/QuickTests/QuickFocusedTests/FocusedTests+ObjC.m", "Tests/QuickTests/QuickTests/FunctionalTests/ObjC", "Tests/QuickTests/QuickTests/Helpers", diff --git a/Carthage/Checkouts/Quick/Quick.podspec b/Carthage/Checkouts/Quick/Quick.podspec index f5253d5..1cdc852 100644 --- a/Carthage/Checkouts/Quick/Quick.podspec +++ b/Carthage/Checkouts/Quick/Quick.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "Quick" - s.version = "0.10.0" + s.version = "1.0.0" s.summary = "The Swift (and Objective-C) testing framework." s.description = <<-DESC diff --git a/Carthage/Checkouts/Quick/Quick.xcodeproj/project.pbxproj b/Carthage/Checkouts/Quick/Quick.xcodeproj/project.pbxproj index d93c36c..5421a33 100644 --- a/Carthage/Checkouts/Quick/Quick.xcodeproj/project.pbxproj +++ b/Carthage/Checkouts/Quick/Quick.xcodeproj/project.pbxproj @@ -43,8 +43,6 @@ 1F118D1B1BDCA556005013A2 /* PendingTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4715903F1A488F3F00FBA644 /* PendingTests+ObjC.m */; }; 1F118D1C1BDCA556005013A2 /* BeforeSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91A419F3208B006F6675 /* BeforeSuiteTests.swift */; }; 1F118D1D1BDCA556005013A2 /* BeforeSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 47876F7B1A4999B0002575C7 /* BeforeSuiteTests+ObjC.m */; }; - 1F118D1E1BDCA556005013A2 /* AfterSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91A719F32556006F6675 /* AfterSuiteTests.swift */; }; - 1F118D1F1BDCA556005013A2 /* AfterSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 477217391A59C1B00022013E /* AfterSuiteTests+ObjC.m */; }; 1F118D201BDCA556005013A2 /* SharedExamplesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91AA19F3299E006F6675 /* SharedExamplesTests.swift */; }; 1F118D211BDCA556005013A2 /* SharedExamplesTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4728253A1A5EECCE008DC74F /* SharedExamplesTests+ObjC.m */; }; 1F118D221BDCA556005013A2 /* SharedExamples+BeforeEachTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB0136E19FC4315006AFBEE /* SharedExamples+BeforeEachTests.swift */; }; @@ -96,8 +94,6 @@ 4728253C1A5EECCE008DC74F /* SharedExamplesTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4728253A1A5EECCE008DC74F /* SharedExamplesTests+ObjC.m */; }; 4748E8941A6AEBB3009EC992 /* SharedExamples+BeforeEachTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4748E8931A6AEBB3009EC992 /* SharedExamples+BeforeEachTests+ObjC.m */; }; 4748E8951A6AEBB3009EC992 /* SharedExamples+BeforeEachTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 4748E8931A6AEBB3009EC992 /* SharedExamples+BeforeEachTests+ObjC.m */; }; - 4772173A1A59C1B00022013E /* AfterSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 477217391A59C1B00022013E /* AfterSuiteTests+ObjC.m */; }; - 4772173B1A59C1B00022013E /* AfterSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 477217391A59C1B00022013E /* AfterSuiteTests+ObjC.m */; }; 47876F7D1A49AD63002575C7 /* BeforeSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 47876F7B1A4999B0002575C7 /* BeforeSuiteTests+ObjC.m */; }; 47876F7E1A49AD71002575C7 /* BeforeSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 47876F7B1A4999B0002575C7 /* BeforeSuiteTests+ObjC.m */; }; 479C31E31A36171B00DA8718 /* ItTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 479C31E11A36156E00DA8718 /* ItTests+ObjC.m */; }; @@ -106,6 +102,17 @@ 47FAEA371A3F49EB005A1D2F /* BeforeEachTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 47FAEA341A3F45ED005A1D2F /* BeforeEachTests+ObjC.m */; }; 5A5D118719473F2100F6D13D /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A5D117C19473F2100F6D13D /* Quick.framework */; }; 5A5D11A7194740E000F6D13D /* Quick.h in Headers */ = {isa = PBXBuildFile; fileRef = DAEB6B931943873100289F44 /* Quick.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 64076CEF1D6D7C2000E2B499 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DAEB6B8E1943873100289F44 /* Quick.framework */; }; + 64076CF01D6D7C2000E2B499 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8100E901A1E4447007595ED /* Nimble.framework */; }; + 64076D021D6D7CD600E2B499 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5A5D117C19473F2100F6D13D /* Quick.framework */; }; + 64076D031D6D7CD600E2B499 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F8100E901A1E4447007595ED /* Nimble.framework */; }; + 64076D141D6D7CEA00E2B499 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F118CD51BDCA4AB005013A2 /* Quick.framework */; }; + 64076D151D6D7CEA00E2B499 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1F118D361BDCA65C005013A2 /* Nimble.framework */; }; + 64076D211D6D7E4D00E2B499 /* AfterSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64076D1D1D6D7D0B00E2B499 /* AfterSuiteTests.swift */; }; + 64076D221D6D7E5B00E2B499 /* AfterSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64076D1D1D6D7D0B00E2B499 /* AfterSuiteTests.swift */; }; + 64076D231D6D7E6B00E2B499 /* AfterSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 64076D1D1D6D7D0B00E2B499 /* AfterSuiteTests.swift */; }; + 64076D261D6D80B500E2B499 /* AfterSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 64076D241D6D80B500E2B499 /* AfterSuiteTests+ObjC.m */; }; + 64076D271D6D80B500E2B499 /* AfterSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 64076D241D6D80B500E2B499 /* AfterSuiteTests+ObjC.m */; }; 7B44ADBE1C5444940007AF2E /* HooksPhase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B44ADBD1C5444940007AF2E /* HooksPhase.swift */; }; 7B44ADBF1C5444940007AF2E /* HooksPhase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B44ADBD1C5444940007AF2E /* HooksPhase.swift */; }; 7B44ADC01C5444940007AF2E /* HooksPhase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B44ADBD1C5444940007AF2E /* HooksPhase.swift */; }; @@ -130,20 +137,21 @@ AED9C8631CC8A7BD00432F62 /* CrossReferencingSpecs.swift in Sources */ = {isa = PBXBuildFile; fileRef = AED9C8621CC8A7BD00432F62 /* CrossReferencingSpecs.swift */; }; AED9C8641CC8A7BD00432F62 /* CrossReferencingSpecs.swift in Sources */ = {isa = PBXBuildFile; fileRef = AED9C8621CC8A7BD00432F62 /* CrossReferencingSpecs.swift */; }; AED9C8651CC8A7BD00432F62 /* CrossReferencingSpecs.swift in Sources */ = {isa = PBXBuildFile; fileRef = AED9C8621CC8A7BD00432F62 /* CrossReferencingSpecs.swift */; }; + CD264DBD1DDA147A0038B0EB /* AfterSuiteTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 64076D241D6D80B500E2B499 /* AfterSuiteTests+ObjC.m */; }; CE57CEDD1C430BD200D63004 /* NSBundle+CurrentTestBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CED81C430BD200D63004 /* NSBundle+CurrentTestBundle.swift */; }; CE57CEDE1C430BD200D63004 /* QuickSelectedTestSuiteBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CED91C430BD200D63004 /* QuickSelectedTestSuiteBuilder.swift */; }; CE57CEDF1C430BD200D63004 /* QuickTestSuite.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDA1C430BD200D63004 /* QuickTestSuite.swift */; }; - CE57CEE01C430BD200D63004 /* String+FileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDB1C430BD200D63004 /* String+FileName.swift */; }; + CE57CEE01C430BD200D63004 /* URL+FileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDB1C430BD200D63004 /* URL+FileName.swift */; }; CE57CEE11C430BD200D63004 /* XCTestSuite+QuickTestSuiteBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDC1C430BD200D63004 /* XCTestSuite+QuickTestSuiteBuilder.m */; }; CE590E1A1C431FE300253D19 /* QuickTestSuite.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDA1C430BD200D63004 /* QuickTestSuite.swift */; }; CE590E1B1C431FE300253D19 /* QuickSelectedTestSuiteBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CED91C430BD200D63004 /* QuickSelectedTestSuiteBuilder.swift */; }; CE590E1C1C431FE300253D19 /* NSBundle+CurrentTestBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CED81C430BD200D63004 /* NSBundle+CurrentTestBundle.swift */; }; - CE590E1D1C431FE300253D19 /* String+FileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDB1C430BD200D63004 /* String+FileName.swift */; }; + CE590E1D1C431FE300253D19 /* URL+FileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDB1C430BD200D63004 /* URL+FileName.swift */; }; CE590E1E1C431FE300253D19 /* XCTestSuite+QuickTestSuiteBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDC1C430BD200D63004 /* XCTestSuite+QuickTestSuiteBuilder.m */; }; CE590E1F1C431FE400253D19 /* QuickTestSuite.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDA1C430BD200D63004 /* QuickTestSuite.swift */; }; CE590E201C431FE400253D19 /* QuickSelectedTestSuiteBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CED91C430BD200D63004 /* QuickSelectedTestSuiteBuilder.swift */; }; CE590E211C431FE400253D19 /* NSBundle+CurrentTestBundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CED81C430BD200D63004 /* NSBundle+CurrentTestBundle.swift */; }; - CE590E221C431FE400253D19 /* String+FileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDB1C430BD200D63004 /* String+FileName.swift */; }; + CE590E221C431FE400253D19 /* URL+FileName.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDB1C430BD200D63004 /* URL+FileName.swift */; }; CE590E231C431FE400253D19 /* XCTestSuite+QuickTestSuiteBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = CE57CEDC1C430BD200D63004 /* XCTestSuite+QuickTestSuiteBuilder.m */; }; DA02C91919A8073100093156 /* ExampleMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA02C91819A8073100093156 /* ExampleMetadata.swift */; }; DA02C91A19A8073100093156 /* ExampleMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA02C91819A8073100093156 /* ExampleMetadata.swift */; }; @@ -185,8 +193,6 @@ DA8F919E19F31921006F6675 /* FailureTests+ObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = DA8F919C19F31921006F6675 /* FailureTests+ObjC.m */; }; DA8F91A519F3208B006F6675 /* BeforeSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91A419F3208B006F6675 /* BeforeSuiteTests.swift */; }; DA8F91A619F3208B006F6675 /* BeforeSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91A419F3208B006F6675 /* BeforeSuiteTests.swift */; }; - DA8F91A819F32556006F6675 /* AfterSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91A719F32556006F6675 /* AfterSuiteTests.swift */; }; - DA8F91A919F32556006F6675 /* AfterSuiteTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91A719F32556006F6675 /* AfterSuiteTests.swift */; }; DA8F91AB19F3299E006F6675 /* SharedExamplesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91AA19F3299E006F6675 /* SharedExamplesTests.swift */; }; DA8F91AC19F3299E006F6675 /* SharedExamplesTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91AA19F3299E006F6675 /* SharedExamplesTests.swift */; }; DA8F91AE19F32CE2006F6675 /* FunctionalTests_SharedExamplesTests_SharedExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA8F91AD19F32CE2006F6675 /* FunctionalTests_SharedExamplesTests_SharedExamples.swift */; }; @@ -391,6 +397,27 @@ remoteGlobalIDString = 5A5D117B19473F2100F6D13D; remoteInfo = "Quick-iOS"; }; + 64076CE71D6D7C2000E2B499 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DAEB6B851943873100289F44 /* Project object */; + proxyType = 1; + remoteGlobalIDString = DAEB6B8D1943873100289F44; + remoteInfo = "Quick-OSX"; + }; + 64076CFA1D6D7CD600E2B499 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DAEB6B851943873100289F44 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 5A5D117B19473F2100F6D13D; + remoteInfo = "Quick-iOS"; + }; + 64076D0C1D6D7CEA00E2B499 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DAEB6B851943873100289F44 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 1F118CD41BDCA4AB005013A2; + remoteInfo = "Quick-tvOS"; + }; 93625F381951DDC8006B1FE1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = DAEB6B851943873100289F44 /* Project object */; @@ -441,12 +468,16 @@ 4715903F1A488F3F00FBA644 /* PendingTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PendingTests+ObjC.m"; sourceTree = ""; }; 4728253A1A5EECCE008DC74F /* SharedExamplesTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SharedExamplesTests+ObjC.m"; sourceTree = ""; }; 4748E8931A6AEBB3009EC992 /* SharedExamples+BeforeEachTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SharedExamples+BeforeEachTests+ObjC.m"; sourceTree = ""; }; - 477217391A59C1B00022013E /* AfterSuiteTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AfterSuiteTests+ObjC.m"; sourceTree = ""; }; 47876F7B1A4999B0002575C7 /* BeforeSuiteTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "BeforeSuiteTests+ObjC.m"; sourceTree = ""; }; 479C31E11A36156E00DA8718 /* ItTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ItTests+ObjC.m"; sourceTree = ""; }; 47FAEA341A3F45ED005A1D2F /* BeforeEachTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "BeforeEachTests+ObjC.m"; sourceTree = ""; }; 5A5D117C19473F2100F6D13D /* Quick.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Quick.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 5A5D118619473F2100F6D13D /* Quick-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Quick-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 64076CF51D6D7C2000E2B499 /* QuickAfterSuite-macOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "QuickAfterSuite-macOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 64076D081D6D7CD600E2B499 /* QuickAfterSuite-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "QuickAfterSuite-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 64076D1A1D6D7CEA00E2B499 /* QuickAfterSuite-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "QuickAfterSuite-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + 64076D1D1D6D7D0B00E2B499 /* AfterSuiteTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AfterSuiteTests.swift; sourceTree = ""; }; + 64076D241D6D80B500E2B499 /* AfterSuiteTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AfterSuiteTests+ObjC.m"; sourceTree = ""; }; 7B44ADBD1C5444940007AF2E /* HooksPhase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HooksPhase.swift; sourceTree = ""; }; 7B5358CA1C3D4E2A00A23FAA /* ContextTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContextTests.swift; sourceTree = ""; }; 8D010A561C11726F00633E2B /* DescribeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DescribeTests.swift; sourceTree = ""; }; @@ -457,7 +488,7 @@ CE57CED81C430BD200D63004 /* NSBundle+CurrentTestBundle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSBundle+CurrentTestBundle.swift"; sourceTree = ""; }; CE57CED91C430BD200D63004 /* QuickSelectedTestSuiteBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QuickSelectedTestSuiteBuilder.swift; sourceTree = ""; }; CE57CEDA1C430BD200D63004 /* QuickTestSuite.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QuickTestSuite.swift; sourceTree = ""; }; - CE57CEDB1C430BD200D63004 /* String+FileName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "String+FileName.swift"; sourceTree = ""; }; + CE57CEDB1C430BD200D63004 /* URL+FileName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "URL+FileName.swift"; sourceTree = ""; }; CE57CEDC1C430BD200D63004 /* XCTestSuite+QuickTestSuiteBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "XCTestSuite+QuickTestSuiteBuilder.m"; sourceTree = ""; }; DA02C91819A8073100093156 /* ExampleMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExampleMetadata.swift; sourceTree = ""; }; DA05D60F19F73A3800771050 /* AfterEachTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AfterEachTests.swift; sourceTree = ""; }; @@ -481,7 +512,6 @@ DA8F919819F31680006F6675 /* XCTestObservationCenter+QCKSuspendObservation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "XCTestObservationCenter+QCKSuspendObservation.h"; sourceTree = ""; }; DA8F919C19F31921006F6675 /* FailureTests+ObjC.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FailureTests+ObjC.m"; sourceTree = ""; }; DA8F91A419F3208B006F6675 /* BeforeSuiteTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BeforeSuiteTests.swift; sourceTree = ""; }; - DA8F91A719F32556006F6675 /* AfterSuiteTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AfterSuiteTests.swift; sourceTree = ""; }; DA8F91AA19F3299E006F6675 /* SharedExamplesTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharedExamplesTests.swift; sourceTree = ""; }; DA8F91AD19F32CE2006F6675 /* FunctionalTests_SharedExamplesTests_SharedExamples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FunctionalTests_SharedExamplesTests_SharedExamples.swift; sourceTree = ""; }; DA9876B21A4C70EB0004AA17 /* QuickFocused-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "QuickFocused-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -548,6 +578,33 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 64076CEE1D6D7C2000E2B499 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 64076CEF1D6D7C2000E2B499 /* Quick.framework in Frameworks */, + 64076CF01D6D7C2000E2B499 /* Nimble.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 64076D011D6D7CD600E2B499 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 64076D021D6D7CD600E2B499 /* Quick.framework in Frameworks */, + 64076D031D6D7CD600E2B499 /* Nimble.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 64076D131D6D7CEA00E2B499 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 64076D141D6D7CEA00E2B499 /* Quick.framework in Frameworks */, + 64076D151D6D7CEA00E2B499 /* Nimble.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA5663E51A4C8D8500193C88 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -594,6 +651,16 @@ name = Frameworks; sourceTree = ""; }; + 64076D1C1D6D7D0B00E2B499 /* QuickAfterSuiteTests */ = { + isa = PBXGroup; + children = ( + 64076D1D1D6D7D0B00E2B499 /* AfterSuiteTests.swift */, + 64076D241D6D80B500E2B499 /* AfterSuiteTests+ObjC.m */, + ); + name = QuickAfterSuiteTests; + path = Tests/QuickTests/QuickAfterSuiteTests; + sourceTree = ""; + }; 6C3983EE1D1E930D00637469 /* QuickObjectiveC */ = { isa = PBXGroup; children = ( @@ -634,7 +701,6 @@ isa = PBXGroup; children = ( 470D6EC91A43409600043E50 /* AfterEachTests+ObjC.m */, - 477217391A59C1B00022013E /* AfterSuiteTests+ObjC.m */, 47FAEA341A3F45ED005A1D2F /* BeforeEachTests+ObjC.m */, 47876F7B1A4999B0002575C7 /* BeforeSuiteTests+ObjC.m */, DA8F919C19F31921006F6675 /* FailureTests+ObjC.m */, @@ -701,7 +767,6 @@ DA05D60F19F73A3800771050 /* AfterEachTests.swift */, DAA63EA219F7637300CD0A3B /* PendingTests.swift */, DA8F91A419F3208B006F6675 /* BeforeSuiteTests.swift */, - DA8F91A719F32556006F6675 /* AfterSuiteTests.swift */, DA8F91AA19F3299E006F6675 /* SharedExamplesTests.swift */, DAB0136E19FC4315006AFBEE /* SharedExamples+BeforeEachTests.swift */, 7B5358CA1C3D4E2A00A23FAA /* ContextTests.swift */, @@ -763,6 +828,7 @@ 6C3983EE1D1E930D00637469 /* QuickObjectiveC */, DAEB6B9D1943873100289F44 /* QuickTests */, DA9876BE1A4C87200004AA17 /* QuickFocusedTests */, + 64076D1C1D6D7D0B00E2B499 /* QuickAfterSuiteTests */, DAEB6B8F1943873100289F44 /* Products */, 1F118D331BDCA645005013A2 /* Frameworks */, ); @@ -782,6 +848,9 @@ 1F118CD51BDCA4AB005013A2 /* Quick.framework */, 1F118CDE1BDCA4AB005013A2 /* Quick-tvOSTests.xctest */, 1F118CF01BDCA4BB005013A2 /* QuickFocused-tvOSTests.xctest */, + 64076CF51D6D7C2000E2B499 /* QuickAfterSuite-macOSTests.xctest */, + 64076D081D6D7CD600E2B499 /* QuickAfterSuite-iOSTests.xctest */, + 64076D1A1D6D7CEA00E2B499 /* QuickAfterSuite-tvOSTests.xctest */, ); name = Products; sourceTree = ""; @@ -801,7 +870,7 @@ CE57CEDA1C430BD200D63004 /* QuickTestSuite.swift */, CE57CED91C430BD200D63004 /* QuickSelectedTestSuiteBuilder.swift */, CE57CED81C430BD200D63004 /* NSBundle+CurrentTestBundle.swift */, - CE57CEDB1C430BD200D63004 /* String+FileName.swift */, + CE57CEDB1C430BD200D63004 /* URL+FileName.swift */, 34C586071C4AC5E500D4F057 /* ErrorUtility.swift */, DAEB6B911943873100289F44 /* Supporting Files */, ); @@ -914,6 +983,7 @@ 1F118CD11BDCA4AB005013A2 /* Frameworks */, 1F118CD21BDCA4AB005013A2 /* Headers */, 1F118CD31BDCA4AB005013A2 /* Resources */, + A870E6171DE00FC7006891AD /* ShellScript */, ); buildRules = ( ); @@ -968,6 +1038,7 @@ 5A5D117819473F2100F6D13D /* Frameworks */, 5A5D117919473F2100F6D13D /* Headers */, 5A5D117A19473F2100F6D13D /* Resources */, + A870E6161DE00E50006891AD /* ShellScript */, ); buildRules = ( ); @@ -1006,6 +1077,60 @@ productReference = 5A5D118619473F2100F6D13D /* Quick-iOSTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; + 64076CE51D6D7C2000E2B499 /* QuickAfterSuite-macOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 64076CF21D6D7C2000E2B499 /* Build configuration list for PBXNativeTarget "QuickAfterSuite-macOSTests" */; + buildPhases = ( + 64076CE81D6D7C2000E2B499 /* Sources */, + 64076CEE1D6D7C2000E2B499 /* Frameworks */, + 64076CF11D6D7C2000E2B499 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 64076CE61D6D7C2000E2B499 /* PBXTargetDependency */, + ); + name = "QuickAfterSuite-macOSTests"; + productName = "QuickFocused-macOSTests"; + productReference = 64076CF51D6D7C2000E2B499 /* QuickAfterSuite-macOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 64076CF81D6D7CD600E2B499 /* QuickAfterSuite-iOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 64076D051D6D7CD600E2B499 /* Build configuration list for PBXNativeTarget "QuickAfterSuite-iOSTests" */; + buildPhases = ( + 64076CFB1D6D7CD600E2B499 /* Sources */, + 64076D011D6D7CD600E2B499 /* Frameworks */, + 64076D041D6D7CD600E2B499 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 64076CF91D6D7CD600E2B499 /* PBXTargetDependency */, + ); + name = "QuickAfterSuite-iOSTests"; + productName = "QuickFocused-iOSTests"; + productReference = 64076D081D6D7CD600E2B499 /* QuickAfterSuite-iOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 64076D0A1D6D7CEA00E2B499 /* QuickAfterSuite-tvOSTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 64076D171D6D7CEA00E2B499 /* Build configuration list for PBXNativeTarget "QuickAfterSuite-tvOSTests" */; + buildPhases = ( + 64076D0D1D6D7CEA00E2B499 /* Sources */, + 64076D131D6D7CEA00E2B499 /* Frameworks */, + 64076D161D6D7CEA00E2B499 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 64076D0B1D6D7CEA00E2B499 /* PBXTargetDependency */, + ); + name = "QuickAfterSuite-tvOSTests"; + productName = "QuickFocused-tvOSTests"; + productReference = 64076D1A1D6D7CEA00E2B499 /* QuickAfterSuite-tvOSTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; DA5663E71A4C8D8500193C88 /* QuickFocused-macOSTests */ = { isa = PBXNativeTarget; buildConfigurationList = DA5663F31A4C8D8500193C88 /* Build configuration list for PBXNativeTarget "QuickFocused-macOSTests" */; @@ -1020,7 +1145,7 @@ DA5663F01A4C8D8500193C88 /* PBXTargetDependency */, ); name = "QuickFocused-macOSTests"; - productName = "QuickFocused-OSXTests"; + productName = "QuickFocused-macOSTests"; productReference = DA5663E81A4C8D8500193C88 /* QuickFocused-macOSTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; @@ -1050,6 +1175,7 @@ DAEB6B8A1943873100289F44 /* Frameworks */, DAEB6B8B1943873100289F44 /* Headers */, DAEB6B8C1943873100289F44 /* Resources */, + A870E6151DE00E37006891AD /* ShellScript */, ); buildRules = ( ); @@ -1097,7 +1223,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0710; - LastUpgradeCheck = 0800; + LastUpgradeCheck = 0810; ORGANIZATIONNAME = "Brian Ivan Gesiak"; TargetAttributes = { 1F118CD41BDCA4AB005013A2 = { @@ -1155,12 +1281,15 @@ DAEB6B8D1943873100289F44 /* Quick-macOS */, DAEB6B981943873100289F44 /* Quick-macOSTests */, DA5663E71A4C8D8500193C88 /* QuickFocused-macOSTests */, + 64076CE51D6D7C2000E2B499 /* QuickAfterSuite-macOSTests */, 5A5D117B19473F2100F6D13D /* Quick-iOS */, 5A5D118519473F2100F6D13D /* Quick-iOSTests */, DA9876B11A4C70EB0004AA17 /* QuickFocused-iOSTests */, + 64076CF81D6D7CD600E2B499 /* QuickAfterSuite-iOSTests */, 1F118CD41BDCA4AB005013A2 /* Quick-tvOS */, 1F118CDD1BDCA4AB005013A2 /* Quick-tvOSTests */, 1F118CEF1BDCA4BB005013A2 /* QuickFocused-tvOSTests */, + 64076D0A1D6D7CEA00E2B499 /* QuickAfterSuite-tvOSTests */, ); }; /* End PBXProject section */ @@ -1201,6 +1330,27 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 64076CF11D6D7C2000E2B499 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 64076D041D6D7CD600E2B499 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 64076D161D6D7CEA00E2B499 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA5663E61A4C8D8500193C88 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1231,6 +1381,48 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + A870E6151DE00E37006891AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "#if which swiftlint >/dev/null; then\n#swiftlint\n#else\n#echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\n#fi"; + }; + A870E6161DE00E50006891AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; + A870E6171DE00FC7006891AD /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 1F118CD01BDCA4AB005013A2 /* Sources */ = { isa = PBXSourcesBuildPhase; @@ -1250,7 +1442,7 @@ CE590E231C431FE400253D19 /* XCTestSuite+QuickTestSuiteBuilder.m in Sources */, 1F118D081BDCA536005013A2 /* Filter.swift in Sources */, 1F118CFD1BDCA536005013A2 /* World+DSL.swift in Sources */, - CE590E221C431FE400253D19 /* String+FileName.swift in Sources */, + CE590E221C431FE400253D19 /* URL+FileName.swift in Sources */, 1F118D0A1BDCA536005013A2 /* NSString+QCKSelectorName.m in Sources */, 1F118CFE1BDCA536005013A2 /* DSL.swift in Sources */, 7B44ADC01C5444940007AF2E /* HooksPhase.swift in Sources */, @@ -1275,7 +1467,6 @@ 1F118D141BDCA556005013A2 /* FailureTests+ObjC.m in Sources */, 1F118D0F1BDCA54B005013A2 /* FunctionalTests_SharedExamplesTests_SharedExamples.swift in Sources */, 1F118D101BDCA556005013A2 /* Configuration+AfterEach.swift in Sources */, - 1F118D1F1BDCA556005013A2 /* AfterSuiteTests+ObjC.m in Sources */, 1F118D1A1BDCA556005013A2 /* PendingTests.swift in Sources */, 1F118D171BDCA556005013A2 /* BeforeEachTests+ObjC.m in Sources */, 1F118D231BDCA556005013A2 /* SharedExamples+BeforeEachTests+ObjC.m in Sources */, @@ -1293,7 +1484,6 @@ 1F118D1B1BDCA556005013A2 /* PendingTests+ObjC.m in Sources */, 34C586051C4ABD4100D4F057 /* XCTestCaseProvider.swift in Sources */, 8D010A591C11726F00633E2B /* DescribeTests.swift in Sources */, - 1F118D1E1BDCA556005013A2 /* AfterSuiteTests.swift in Sources */, 1F118D111BDCA556005013A2 /* Configuration+AfterEachTests.swift in Sources */, 1F118D161BDCA556005013A2 /* BeforeEachTests.swift in Sources */, 7B5358D01C3D4FC000A23FAA /* ContextTests.swift in Sources */, @@ -1330,7 +1520,7 @@ CE590E1E1C431FE300253D19 /* XCTestSuite+QuickTestSuiteBuilder.m in Sources */, 34F375A819515CA700CE1B99 /* Callsite.swift in Sources */, 34F375AE19515CA700CE1B99 /* ExampleGroup.swift in Sources */, - CE590E1D1C431FE300253D19 /* String+FileName.swift in Sources */, + CE590E1D1C431FE300253D19 /* URL+FileName.swift in Sources */, 34F375BC19515CA700CE1B99 /* World.swift in Sources */, DA169E4919FF5DF100619816 /* Configuration.swift in Sources */, 7B44ADBF1C5444940007AF2E /* HooksPhase.swift in Sources */, @@ -1368,8 +1558,6 @@ 471590411A488F3F00FBA644 /* PendingTests+ObjC.m in Sources */, DA8F919E19F31921006F6675 /* FailureTests+ObjC.m in Sources */, DAE714F419FF65E7005905B8 /* Configuration+BeforeEach.swift in Sources */, - DA8F91A919F32556006F6675 /* AfterSuiteTests.swift in Sources */, - 4772173B1A59C1B00022013E /* AfterSuiteTests+ObjC.m in Sources */, 479C31E41A36172700DA8718 /* ItTests+ObjC.m in Sources */, 34C586031C4ABD4000D4F057 /* XCTestCaseProvider.swift in Sources */, 8D010A581C11726F00633E2B /* DescribeTests.swift in Sources */, @@ -1380,6 +1568,33 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 64076CE81D6D7C2000E2B499 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 64076D211D6D7E4D00E2B499 /* AfterSuiteTests.swift in Sources */, + CD264DBD1DDA147A0038B0EB /* AfterSuiteTests+ObjC.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 64076CFB1D6D7CD600E2B499 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 64076D221D6D7E5B00E2B499 /* AfterSuiteTests.swift in Sources */, + 64076D261D6D80B500E2B499 /* AfterSuiteTests+ObjC.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 64076D0D1D6D7CEA00E2B499 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 64076D231D6D7E6B00E2B499 /* AfterSuiteTests.swift in Sources */, + 64076D271D6D80B500E2B499 /* AfterSuiteTests+ObjC.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; DA5663E41A4C8D8500193C88 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1422,7 +1637,7 @@ CE57CEE11C430BD200D63004 /* XCTestSuite+QuickTestSuiteBuilder.m in Sources */, DAE7150019FF6A62005905B8 /* QuickConfiguration.m in Sources */, 34F375A719515CA700CE1B99 /* Callsite.swift in Sources */, - CE57CEE01C430BD200D63004 /* String+FileName.swift in Sources */, + CE57CEE01C430BD200D63004 /* URL+FileName.swift in Sources */, 34F375AD19515CA700CE1B99 /* ExampleGroup.swift in Sources */, 34F375BB19515CA700CE1B99 /* World.swift in Sources */, DA169E4819FF5DF100619816 /* Configuration.swift in Sources */, @@ -1460,8 +1675,6 @@ 471590401A488F3F00FBA644 /* PendingTests+ObjC.m in Sources */, DA8F919D19F31921006F6675 /* FailureTests+ObjC.m in Sources */, DAE714F319FF65E7005905B8 /* Configuration+BeforeEach.swift in Sources */, - DA8F91A819F32556006F6675 /* AfterSuiteTests.swift in Sources */, - 4772173A1A59C1B00022013E /* AfterSuiteTests+ObjC.m in Sources */, 479C31E31A36171B00DA8718 /* ItTests+ObjC.m in Sources */, 34C586011C4ABD3F00D4F057 /* XCTestCaseProvider.swift in Sources */, 8D010A571C11726F00633E2B /* DescribeTests.swift in Sources */, @@ -1595,6 +1808,21 @@ target = 5A5D117B19473F2100F6D13D /* Quick-iOS */; targetProxy = 5A5D11F1194741B500F6D13D /* PBXContainerItemProxy */; }; + 64076CE61D6D7C2000E2B499 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DAEB6B8D1943873100289F44 /* Quick-macOS */; + targetProxy = 64076CE71D6D7C2000E2B499 /* PBXContainerItemProxy */; + }; + 64076CF91D6D7CD600E2B499 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 5A5D117B19473F2100F6D13D /* Quick-iOS */; + targetProxy = 64076CFA1D6D7CD600E2B499 /* PBXContainerItemProxy */; + }; + 64076D0B1D6D7CEA00E2B499 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 1F118CD41BDCA4AB005013A2 /* Quick-tvOS */; + targetProxy = 64076D0C1D6D7CEA00E2B499 /* PBXContainerItemProxy */; + }; 93625F391951DDC8006B1FE1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DAEB6B8D1943873100289F44 /* Quick-macOS */; @@ -1870,6 +2098,139 @@ }; name = Release; }; + 64076CF31D6D7C2000E2B499 /* 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 = Tests/QuickTests/QuickAfterSuiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.10; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = "io.quick.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 64076CF41D6D7C2000E2B499 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/QuickTests/QuickAfterSuiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.10; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "io.quick.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + }; + name = Release; + }; + 64076D061D6D7CD600E2B499 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/QuickTests/QuickAfterSuiteTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_BUNDLE_IDENTIFIER = "io.quick.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 64076D071D6D7CD600E2B499 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ENABLE_MODULES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = Tests/QuickTests/QuickAfterSuiteTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_BUNDLE_IDENTIFIER = "io.quick.$(PRODUCT_NAME:rfc1034identifier)"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SWIFT_OBJC_BRIDGING_HEADER = Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 64076D181D6D7CEA00E2B499 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUG_INFORMATION_FORMAT = dwarf; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/Nimble/build/Debug-appletvos", + ); + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = Tests/QuickTests/QuickAfterSuiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_BUNDLE_IDENTIFIER = "io.quick.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_OBJC_BRIDGING_HEADER = Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h; + TVOS_DEPLOYMENT_TARGET = 9.0; + }; + name = Debug; + }; + 64076D191D6D7CEA00E2B499 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Externals/Nimble/build/Debug-appletvos", + ); + GCC_NO_COMMON_BLOCKS = YES; + INFOPLIST_FILE = Tests/QuickTests/QuickAfterSuiteTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = "io.quick.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = appletvos; + SWIFT_OBJC_BRIDGING_HEADER = Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TVOS_DEPLOYMENT_TARGET = 9.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; DA5663F11A4C8D8500193C88 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1974,8 +2335,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGNING_REQUIRED = NO; @@ -2024,8 +2387,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGNING_REQUIRED = NO; @@ -2198,6 +2563,33 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + 64076CF21D6D7C2000E2B499 /* Build configuration list for PBXNativeTarget "QuickAfterSuite-macOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 64076CF31D6D7C2000E2B499 /* Debug */, + 64076CF41D6D7C2000E2B499 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 64076D051D6D7CD600E2B499 /* Build configuration list for PBXNativeTarget "QuickAfterSuite-iOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 64076D061D6D7CD600E2B499 /* Debug */, + 64076D071D6D7CD600E2B499 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 64076D171D6D7CEA00E2B499 /* Build configuration list for PBXNativeTarget "QuickAfterSuite-tvOSTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 64076D181D6D7CEA00E2B499 /* Debug */, + 64076D191D6D7CEA00E2B499 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; DA5663F31A4C8D8500193C88 /* Build configuration list for PBXNativeTarget "QuickFocused-macOSTests" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/Carthage/Checkouts/Quick/Quick.xcodeproj/xcshareddata/xcschemes/Quick-iOS.xcscheme b/Carthage/Checkouts/Quick/Quick.xcodeproj/xcshareddata/xcschemes/Quick-iOS.xcscheme index e2eb4c7..988da03 100644 --- a/Carthage/Checkouts/Quick/Quick.xcodeproj/xcshareddata/xcschemes/Quick-iOS.xcscheme +++ b/Carthage/Checkouts/Quick/Quick.xcodeproj/xcshareddata/xcschemes/Quick-iOS.xcscheme @@ -1,6 +1,6 @@ + + + + + + + + + + + + Bool { +public func == (lhs: Callsite, rhs: Callsite) -> Bool { return lhs.file == rhs.file && lhs.line == rhs.line } diff --git a/Carthage/Checkouts/Quick/Sources/Quick/Configuration/Configuration.swift b/Carthage/Checkouts/Quick/Sources/Quick/Configuration/Configuration.swift index 9836fef..99c1c93 100644 --- a/Carthage/Checkouts/Quick/Sources/Quick/Configuration/Configuration.swift +++ b/Carthage/Checkouts/Quick/Sources/Quick/Configuration/Configuration.swift @@ -19,14 +19,14 @@ public typealias ExampleFilter = (_ example: Example) -> Bool final public class Configuration: NSObject { internal let exampleHooks = ExampleHooks() internal let suiteHooks = SuiteHooks() - internal var exclusionFilters: [ExampleFilter] = [{ example in + internal var exclusionFilters: [ExampleFilter] = [ { example in if let pending = example.filterFlags[Filter.pending] { return pending } else { return false } }] - internal var inclusionFilters: [ExampleFilter] = [{ example in + internal var inclusionFilters: [ExampleFilter] = [ { example in if let focused = example.filterFlags[Filter.focused] { return focused } else { diff --git a/Carthage/Checkouts/Quick/Sources/Quick/Example.swift b/Carthage/Checkouts/Quick/Sources/Quick/Example.swift index 844bf3f..07bc529 100644 --- a/Carthage/Checkouts/Quick/Sources/Quick/Example.swift +++ b/Carthage/Checkouts/Quick/Sources/Quick/Example.swift @@ -32,7 +32,7 @@ final public class Example: NSObject { self.callsite = callsite self.flags = flags } - + public override var description: String { return internalDescription } @@ -106,6 +106,6 @@ final public class Example: NSObject { Returns a boolean indicating whether two Example objects are equal. If two examples are defined at the exact same callsite, they must be equal. */ -public func ==(lhs: Example, rhs: Example) -> Bool { +public func == (lhs: Example, rhs: Example) -> Bool { return lhs.callsite == rhs.callsite } diff --git a/Carthage/Checkouts/Quick/Sources/Quick/ExampleGroup.swift b/Carthage/Checkouts/Quick/Sources/Quick/ExampleGroup.swift index b0b8be4..79f24ca 100644 --- a/Carthage/Checkouts/Quick/Sources/Quick/ExampleGroup.swift +++ b/Carthage/Checkouts/Quick/Sources/Quick/ExampleGroup.swift @@ -8,7 +8,7 @@ import Foundation final public class ExampleGroup: NSObject { weak internal var parent: ExampleGroup? internal let hooks = ExampleHooks() - + internal var phase: HooksPhase = .nothingExecuted private let internalDescription: String diff --git a/Carthage/Checkouts/Quick/Sources/Quick/Hooks/ExampleHooks.swift b/Carthage/Checkouts/Quick/Sources/Quick/Hooks/ExampleHooks.swift index ef6d53e..565287b 100644 --- a/Carthage/Checkouts/Quick/Sources/Quick/Hooks/ExampleHooks.swift +++ b/Carthage/Checkouts/Quick/Sources/Quick/Hooks/ExampleHooks.swift @@ -27,7 +27,7 @@ final internal class ExampleHooks { for before in befores { before(exampleMetadata) } - + phase = .beforesFinished } diff --git a/Carthage/Checkouts/Quick/Sources/Quick/QuickSelectedTestSuiteBuilder.swift b/Carthage/Checkouts/Quick/Sources/Quick/QuickSelectedTestSuiteBuilder.swift index 63b55e1..ec2e308 100644 --- a/Carthage/Checkouts/Quick/Sources/Quick/QuickSelectedTestSuiteBuilder.swift +++ b/Carthage/Checkouts/Quick/Sources/Quick/QuickSelectedTestSuiteBuilder.swift @@ -66,7 +66,8 @@ private func testCaseClassForTestCaseWithName(_ name: String) -> AnyClass? { if let testCaseClass = bundle.classNamed(className) { return testCaseClass } - guard let moduleName = bundle.bundlePath.fileName else { return nil } + let bundleFileName = bundle.bundleURL.fileName + let moduleName = bundleFileName.replacingOccurrences(of: " ", with: "_") return NSClassFromString("\(moduleName).\(className)") } diff --git a/Carthage/Checkouts/Quick/Sources/Quick/QuickSpec.swift b/Carthage/Checkouts/Quick/Sources/Quick/QuickSpec.swift index b70e32f..e4dd728 100644 --- a/Carthage/Checkouts/Quick/Sources/Quick/QuickSpec.swift +++ b/Carthage/Checkouts/Quick/Sources/Quick/QuickSpec.swift @@ -21,7 +21,7 @@ open class QuickSpec: XCTestCase { static var allTestsCache = [String : [(String, (XCTestCase) -> () throws -> Void)]]() - public class var allTests : [(String, (XCTestCase) -> () throws -> Void)] { + public class var allTests: [(String, (XCTestCase) -> () throws -> Void)] { if let cached = allTestsCache[String(describing: self)] { return cached } diff --git a/Carthage/Checkouts/Quick/Sources/Quick/String+FileName.swift b/Carthage/Checkouts/Quick/Sources/Quick/String+FileName.swift deleted file mode 100644 index 83cdfcf..0000000 --- a/Carthage/Checkouts/Quick/Sources/Quick/String+FileName.swift +++ /dev/null @@ -1,12 +0,0 @@ -import Foundation - -extension String { - - /** - If the receiver represents a path, returns its file name with a file extension. - */ - var fileName: String? { - return NSURL(string: self)?.deletingPathExtension?.lastPathComponent - } - -} diff --git a/Carthage/Checkouts/Quick/Sources/Quick/World.swift b/Carthage/Checkouts/Quick/Sources/Quick/World.swift index 56dae51..487902e 100644 --- a/Carthage/Checkouts/Quick/Sources/Quick/World.swift +++ b/Carthage/Checkouts/Quick/Sources/Quick/World.swift @@ -165,7 +165,7 @@ final internal class World: NSObject { internal var includedExampleCount: Int { return includedExamples.count } - + internal var beforesCurrentlyExecuting: Bool { let suiteBeforesExecuting = suiteHooks.phase == .beforesExecuting let exampleBeforesExecuting = exampleHooks.phase == .beforesExecuting @@ -173,10 +173,10 @@ final internal class World: NSObject { if let runningExampleGroup = currentExampleMetadata?.example.group { groupBeforesExecuting = runningExampleGroup.phase == .beforesExecuting } - + return suiteBeforesExecuting || exampleBeforesExecuting || groupBeforesExecuting } - + internal var aftersCurrentlyExecuting: Bool { let suiteAftersExecuting = suiteHooks.phase == .aftersExecuting let exampleAftersExecuting = exampleHooks.phase == .aftersExecuting @@ -184,7 +184,7 @@ final internal class World: NSObject { if let runningExampleGroup = currentExampleMetadata?.example.group { groupAftersExecuting = runningExampleGroup.phase == .aftersExecuting } - + return suiteAftersExecuting || exampleAftersExecuting || groupAftersExecuting } diff --git a/Carthage/Checkouts/Quick/Tests/LinuxMain.swift b/Carthage/Checkouts/Quick/Tests/LinuxMain.swift index c7c3a28..938f54f 100644 --- a/Carthage/Checkouts/Quick/Tests/LinuxMain.swift +++ b/Carthage/Checkouts/Quick/Tests/LinuxMain.swift @@ -5,8 +5,7 @@ import Quick Quick.QCKMain([ FunctionalTests_AfterEachSpec.self, - FunctionalTests_AfterSuite_AfterSuiteSpec.self, - FunctionalTests_AfterSuite_Spec.self, + AfterSuiteTests.self, FunctionalTests_BeforeEachSpec.self, FunctionalTests_BeforeSuite_BeforeSuiteSpec.self, FunctionalTests_BeforeSuite_Spec.self, @@ -31,7 +30,6 @@ configurations: [ ], testCases: [ testCase(AfterEachTests.allTests), - testCase(AfterSuiteTests.allTests), testCase(BeforeEachTests.allTests), testCase(BeforeSuiteTests.allTests), // testCase(DescribeTests.allTests), diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickFocusedTests/FocusedTests.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickFocusedTests/FocusedTests.swift index 28b74f2..0569a7b 100644 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickFocusedTests/FocusedTests.swift +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickFocusedTests/FocusedTests.swift @@ -21,7 +21,6 @@ class FunctionalTests_FocusedSpec_Focused: QuickSpec { fit("has a focused example that passes (3)") {} } - // TODO: Port fitBehavesLike to Swift. itBehavesLike("two passing shared examples", flags: [Filter.focused: true]) } } diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTestHelpers/TestRun.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTestHelpers/TestRun.swift index cfa160e..3ef0d6c 100644 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTestHelpers/TestRun.swift +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTestHelpers/TestRun.swift @@ -1,4 +1,3 @@ - public struct TestRun { public var executionCount: UInt public var hasSucceeded: Bool diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTestHelpers/XCTestCaseProvider.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTestHelpers/XCTestCaseProvider.swift index 78729d4..0b02978 100644 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTestHelpers/XCTestCaseProvider.swift +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTestHelpers/XCTestCaseProvider.swift @@ -48,5 +48,5 @@ public extension XCTestCaseProvider where Self: XCTestCaseProviderStatic { XCTAssert(contains, "Test '\(name)' is missing from the allTests array") } } - + #endif diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/Fixtures/FunctionalTests_SharedExamplesTests_SharedExamples.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/Fixtures/FunctionalTests_SharedExamplesTests_SharedExamples.swift index 5056a58..e5eed68 100644 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/Fixtures/FunctionalTests_SharedExamplesTests_SharedExamples.swift +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/Fixtures/FunctionalTests_SharedExamplesTests_SharedExamples.swift @@ -12,7 +12,7 @@ class FunctionalTests_SharedExamplesTests_SharedExamples: QuickConfiguration { sharedExamples("shared examples that take a context") { (sharedExampleContext: @escaping SharedExampleContext) in it("is passed the correct parameters via the context") { - let callsite = sharedExampleContext()["callsite"] as! String + let callsite = sharedExampleContext()["callsite"] as? String expect(callsite).to(equal("SharedExamplesSpec")) } } diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/AfterEachTests.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/AfterEachTests.swift index f69818c..713e8ae 100644 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/AfterEachTests.swift +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/AfterEachTests.swift @@ -19,23 +19,23 @@ class FunctionalTests_AfterEachSpec: QuickSpec { afterEach { afterEachOrder.append(AfterEachType.OuterOne) } afterEach { afterEachOrder.append(AfterEachType.OuterTwo) } afterEach { afterEachOrder.append(AfterEachType.OuterThree) } - + it("executes the outer afterEach closures once, but not before this closure [1]") { // No examples have been run, so no afterEach will have been run either. // The list should be empty. expect(afterEachOrder).to(beEmpty()) } - + it("executes the outer afterEach closures a second time, but not before this closure [2]") { // The afterEach for the previous example should have been run. // The list should contain the afterEach for that example, executed from top to bottom. expect(afterEachOrder).to(equal([AfterEachType.OuterOne, AfterEachType.OuterTwo, AfterEachType.OuterThree])) } - + context("when there are nested afterEach") { afterEach { afterEachOrder.append(AfterEachType.InnerOne) } afterEach { afterEachOrder.append(AfterEachType.InnerTwo) } - + it("executes the outer and inner afterEach closures, but not before this closure [3]") { // The afterEach for the previous two examples should have been run. // The list should contain the afterEach for those example, executed from top to bottom. @@ -45,7 +45,7 @@ class FunctionalTests_AfterEachSpec: QuickSpec { ])) } } - + context("when there are nested afterEach without examples") { afterEach { afterEachOrder.append(AfterEachType.NoExamples) } } diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/AfterSuiteTests.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/AfterSuiteTests.swift deleted file mode 100644 index 83980fd..0000000 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/AfterSuiteTests.swift +++ /dev/null @@ -1,45 +0,0 @@ -import XCTest -import Quick -import Nimble - -var afterSuiteWasExecuted = false - -class FunctionalTests_AfterSuite_AfterSuiteSpec: QuickSpec { - override func spec() { - afterSuite { - afterSuiteWasExecuted = true - } - } -} - -class FunctionalTests_AfterSuite_Spec: QuickSpec { - override func spec() { - it("is executed before afterSuite") { - expect(afterSuiteWasExecuted).to(beFalsy()) - } - } -} - -final class AfterSuiteTests: XCTestCase, XCTestCaseProvider { - static var allTests: [(String, (AfterSuiteTests) -> () throws -> Void)] { - return [ - ("testAfterSuiteIsNotExecutedBeforeAnyExamples", testAfterSuiteIsNotExecutedBeforeAnyExamples), - ] - } - - func testAfterSuiteIsNotExecutedBeforeAnyExamples() { - // Execute the spec with an assertion after the one with an afterSuite. - let result = qck_runSpecs([ - FunctionalTests_AfterSuite_AfterSuiteSpec.self, - FunctionalTests_AfterSuite_Spec.self - ]) - - // afterSuite is broken https://github.com/Quick/Quick/issues/561 - // For fixing this, need to know how it should work. -#if _runtime(_ObjC) && !SWIFT_PACKAGE - // Although this ensures that afterSuite is not called before any - // examples, it doesn't test that it's ever called in the first place. - XCTAssert(result!.hasSucceeded) -#endif - } -} diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/BeforeEachTests.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/BeforeEachTests.swift index 27a8d64..d46ae68 100644 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/BeforeEachTests.swift +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/BeforeEachTests.swift @@ -15,22 +15,22 @@ private var beforeEachOrder = [BeforeEachType]() class FunctionalTests_BeforeEachSpec: QuickSpec { override func spec() { - + describe("beforeEach ordering") { beforeEach { beforeEachOrder.append(BeforeEachType.OuterOne) } beforeEach { beforeEachOrder.append(BeforeEachType.OuterTwo) } - + it("executes the outer beforeEach closures once [1]") {} it("executes the outer beforeEach closures a second time [2]") {} - + context("when there are nested beforeEach") { beforeEach { beforeEachOrder.append(BeforeEachType.InnerOne) } beforeEach { beforeEachOrder.append(BeforeEachType.InnerTwo) } beforeEach { beforeEachOrder.append(BeforeEachType.InnerThree) } - + it("executes the outer and inner beforeEach closures [3]") {} } - + context("when there are nested beforeEach without examples") { beforeEach { beforeEachOrder.append(BeforeEachType.NoExamples) } } diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/ItTests.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/ItTests.swift index 320995d..61e4504 100644 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/ItTests.swift +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/ItTests.swift @@ -18,41 +18,39 @@ class FunctionalTests_ItSpec: QuickSpec { #if _runtime(_ObjC) && !SWIFT_PACKAGE - describe("when an example has a unique name"){ + describe("when an example has a unique name") { it("has a unique name") {} - + it("doesn't add multiple selectors for it") { let allSelectors = [String]( FunctionalTests_ItSpec.allSelectors() - .filter { $0.hasPrefix("when_an_example_has_a_unique_name__") } - ) + .filter { $0.hasPrefix("when_an_example_has_a_unique_name__") }) .sorted(by: <) - + expect(allSelectors) == [ "when_an_example_has_a_unique_name__doesn_t_add_multiple_selectors_for_it", "when_an_example_has_a_unique_name__has_a_unique_name" ] } } - + describe("when two examples have the exact name") { it("has exactly the same name") {} it("has exactly the same name") {} - + it("makes a unique name for each of the above") { let allSelectors = [String]( FunctionalTests_ItSpec.allSelectors() - .filter { $0.hasPrefix("when_two_examples_have_the_exact_name__") } - ) + .filter { $0.hasPrefix("when_two_examples_have_the_exact_name__") }) .sorted(by: <) - + expect(allSelectors) == [ "when_two_examples_have_the_exact_name__has_exactly_the_same_name", "when_two_examples_have_the_exact_name__has_exactly_the_same_name_2", "when_two_examples_have_the_exact_name__makes_a_unique_name_for_each_of_the_above" ] } - + } describe("error handling when misusing ordering") { diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/ObjC/AfterSuiteTests+ObjC.m b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/ObjC/AfterSuiteTests+ObjC.m deleted file mode 100644 index fd8f6d2..0000000 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/FunctionalTests/ObjC/AfterSuiteTests+ObjC.m +++ /dev/null @@ -1,42 +0,0 @@ -@import XCTest; -@import Quick; -@import Nimble; - -#import "QCKSpecRunner.h" - -static BOOL afterSuiteWasExecuted = NO; - -QuickSpecBegin(FunctionalTests_AfterSuite_AfterSuiteSpec_ObjC) - -afterSuite(^{ - afterSuiteWasExecuted = YES; -}); - -QuickSpecEnd - -QuickSpecBegin(FunctionalTests_AfterSuite_Spec_ObjC) - -it(@"is executed before afterSuite", ^{ - expect(@(afterSuiteWasExecuted)).to(beFalsy()); -}); - -QuickSpecEnd - -@interface AfterSuiteTests_ObjC : XCTestCase; @end - -@implementation AfterSuiteTests_ObjC - -- (void)testAfterSuiteIsNotExecutedBeforeAnyExamples { - // Execute the spec with an assertion after the one with an afterSuite. - NSArray *specs = @[ - [FunctionalTests_AfterSuite_AfterSuiteSpec_ObjC class], - [FunctionalTests_AfterSuite_Spec_ObjC class] - ]; - XCTestRun *result = qck_runSpecs(specs); - - // Although this ensures that afterSuite is not called before any - // examples, it doesn't test that it's ever called in the first place. - XCTAssert(result.hasSucceeded); -} - -@end diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h index f93b1cb..301c5d5 100644 --- a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickTests/Helpers/QuickTestsBridgingHeader.h @@ -1,2 +1,2 @@ #import "QCKSpecRunner.h" -#import "QuickSpec+QuickSpec_MethodList.h" \ No newline at end of file +#import "QuickSpec+QuickSpec_MethodList.h" diff --git a/Sources/AutoRegistration.swift b/Sources/AutoRegistration.swift index 1824bcb..faee3d8 100644 --- a/Sources/AutoRegistration.swift +++ b/Sources/AutoRegistration.swift @@ -127,7 +127,7 @@ public func autoregister(_ service: Service.Type, name: Str */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b) @@ -188,7 +188,7 @@ public func autoregister(_ service: Service.Type, name: */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c) @@ -209,7 +209,7 @@ public func autoregister(_ service: Service.Type, */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2, arg3]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c) @@ -270,7 +270,7 @@ public func autoregister(_ service: Service.Type, nam */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d) @@ -291,7 +291,7 @@ public func autoregister(_ service: Service.Typ */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2, arg3]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d) @@ -352,7 +352,7 @@ public func autoregister(_ service: Service.Type, */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e) @@ -373,7 +373,7 @@ public func autoregister(_ service: Service. */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2, arg3]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e) @@ -434,7 +434,7 @@ public func autoregister(_ service: Service.Typ */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E, F) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f) @@ -455,7 +455,7 @@ public func autoregister(_ service: Servi */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E, F) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2, arg3]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f) @@ -516,7 +516,7 @@ public func autoregister(_ service: Service. */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E, F, G) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g) @@ -537,7 +537,7 @@ public func autoregister(_ service: Se */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E, F, G) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2, arg3]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g) @@ -598,7 +598,7 @@ public func autoregister(_ service: Servi */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E, F, G, H) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2); let h: H? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h) @@ -619,7 +619,7 @@ public func autoregister(_ service: */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E, F, G, H) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2, arg3]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3); let h: H? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h) @@ -680,7 +680,7 @@ public func autoregister(_ service: Se */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, initializer: @escaping (A, B, C, D, E, F, G, H, I) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2 in let a: A? = r.resolve(arguments: arg1, arg2); let b: B? = r.resolve(arguments: arg1, arg2); let c: C? = r.resolve(arguments: arg1, arg2); let d: D? = r.resolve(arguments: arg1, arg2); let e: E? = r.resolve(arguments: arg1, arg2); let f: F? = r.resolve(arguments: arg1, arg2); let g: G? = r.resolve(arguments: arg1, arg2); let h: H? = r.resolve(arguments: arg1, arg2); let i: I? = r.resolve(arguments: arg1, arg2) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h, i) @@ -701,7 +701,7 @@ public func autoregister(_ servi */ @discardableResult public func autoregister(_ service: Service.Type, name: String? = nil, arguments arg1: Arg1.Type, _ arg2: Arg2.Type, _ arg3: Arg3.Type, initializer: @escaping (A, B, C, D, E, F, G, H, I) -> Service) -> ServiceEntry { - if !hasUnique(arguments: [arg1, arg2, arg3]) { fatalError("AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported)") } + precondition(hasUnique(arguments: [arg1, arg2, arg3]), "AutoRegistration of service with same type arguments (\(arg1), \(arg2), \(arg3)) is not supported") return self.register(service.self, name: name, factory: { r, arg1, arg2, arg3 in let a: A? = r.resolve(arguments: arg1, arg2, arg3); let b: B? = r.resolve(arguments: arg1, arg2, arg3); let c: C? = r.resolve(arguments: arg1, arg2, arg3); let d: D? = r.resolve(arguments: arg1, arg2, arg3); let e: E? = r.resolve(arguments: arg1, arg2, arg3); let f: F? = r.resolve(arguments: arg1, arg2, arg3); let g: G? = r.resolve(arguments: arg1, arg2, arg3); let h: H? = r.resolve(arguments: arg1, arg2, arg3); let i: I? = r.resolve(arguments: arg1, arg2, arg3) checkResolved(initializer: initializer, services: a, b, c, d, e, f, g, h, i) diff --git a/SwinjectAutoregistration.xcodeproj/project.pbxproj b/SwinjectAutoregistration.xcodeproj/project.pbxproj index ed214b0..53ffeb7 100644 --- a/SwinjectAutoregistration.xcodeproj/project.pbxproj +++ b/SwinjectAutoregistration.xcodeproj/project.pbxproj @@ -64,6 +64,27 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + AC4AC9591E3530DB00E6355A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CD5B9E521D832A84007ED05F /* Quick.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 64076CF51D6D7C2000E2B499; + remoteInfo = "QuickAfterSuite-macOSTests"; + }; + AC4AC95B1E3530DB00E6355A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CD5B9E521D832A84007ED05F /* Quick.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 64076D081D6D7CD600E2B499; + remoteInfo = "QuickAfterSuite-iOSTests"; + }; + AC4AC95D1E3530DB00E6355A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CD5B9E521D832A84007ED05F /* Quick.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 64076D1A1D6D7CEA00E2B499; + remoteInfo = "QuickAfterSuite-tvOSTests"; + }; CD5B9E461D832A6E007ED05F /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = CD5B9E3D1D832A6E007ED05F /* Nimble.xcodeproj */; @@ -550,12 +571,15 @@ CD5B9E641D832A84007ED05F /* Quick.framework */, CD5B9E661D832A84007ED05F /* Quick-macOSTests.xctest */, CD5B9E681D832A84007ED05F /* QuickFocused-macOSTests.xctest */, + AC4AC95A1E3530DB00E6355A /* QuickAfterSuite-macOSTests.xctest */, CD5B9E6A1D832A84007ED05F /* Quick.framework */, CD5B9E6C1D832A84007ED05F /* Quick-iOSTests.xctest */, CD5B9E6E1D832A84007ED05F /* QuickFocused-iOSTests.xctest */, + AC4AC95C1E3530DB00E6355A /* QuickAfterSuite-iOSTests.xctest */, CD5B9E701D832A84007ED05F /* Quick.framework */, CD5B9E721D832A84007ED05F /* Quick-tvOSTests.xctest */, CD5B9E741D832A84007ED05F /* QuickFocused-tvOSTests.xctest */, + AC4AC95E1E3530DB00E6355A /* QuickAfterSuite-tvOSTests.xctest */, ); name = Products; sourceTree = ""; @@ -873,6 +897,27 @@ /* End PBXProject section */ /* Begin PBXReferenceProxy section */ + AC4AC95A1E3530DB00E6355A /* QuickAfterSuite-macOSTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "QuickAfterSuite-macOSTests.xctest"; + remoteRef = AC4AC9591E3530DB00E6355A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AC4AC95C1E3530DB00E6355A /* QuickAfterSuite-iOSTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "QuickAfterSuite-iOSTests.xctest"; + remoteRef = AC4AC95B1E3530DB00E6355A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + AC4AC95E1E3530DB00E6355A /* QuickAfterSuite-tvOSTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "QuickAfterSuite-tvOSTests.xctest"; + remoteRef = AC4AC95D1E3530DB00E6355A /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; CD5B9E471D832A6E007ED05F /* Nimble.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; diff --git a/Tests/AutoregistrationSpec.swift b/Tests/AutoregistrationSpec.swift index a418519..79780ad 100644 --- a/Tests/AutoregistrationSpec.swift +++ b/Tests/AutoregistrationSpec.swift @@ -171,31 +171,31 @@ class AutoregistrationSpec: QuickSpec { expect(service).notTo(beNil()) } - xit("fails to pass arguments of the same type") { - container.autoregister(SameArgumentsService.self, arguments: String.self, Int.self, String.self, initializer: SameArgumentsService.init) - let service = container.resolve(SameArgumentsService.self, arguments: "NameA", 15, "NameB") - expect(service?.nameA) == "NameA" - expect(service?.nameB) == "NameB" - } - - //TODO: Find a way how to test that assertion was thrown - //This should fail because we generate register functions only for 10 dependencies - xit("fails to register service with ten dependencies") { - container.autoregister(Service10.self, initializer: Service10.init) - let service = container.resolve(Service10.self) - expect(service).notTo(beNil()) + it("throws assertion when same type arguments are passed") { + expect { () -> Void in + container.autoregister(SameArgumentsService.self, arguments: String.self, Int.self, String.self, initializer: SameArgumentsService.init) + }.to(throwAssertion()) } - xit("fails to register service with optional dependency") { - container.autoregister(OptionalService.self, initializer: OptionalService.init) - let service = container.resolve(OptionalService.self) - expect(service).notTo(beNil()) + it("throws assertion when trying to resolve service with ten dependencies") { + expect { () -> Void in + container.autoregister(Service10.self, initializer: Service10.init) + _ = container.resolve(Service10.self) + }.to(throwAssertion()) } - xit("fails to register service with unwrapped dependency") { - container.autoregister(UnwrappedService.self, initializer: UnwrappedService.init) - let service = container.resolve(UnwrappedService.self) - expect(service).notTo(beNil()) + it("throws assertion when trying to resolve service with optional dependency") { + expect { () -> Void in + container.autoregister(OptionalService.self, initializer: OptionalService.init) + _ = container.resolve(OptionalService.self) + }.to(throwAssertion()) + } + + it("throws assertion when trying to resolve service with unwrapped dependency") { + expect { () -> Void in + container.autoregister(UnwrappedService.self, initializer: UnwrappedService.init) + _ = container.resolve(UnwrappedService.self) + }.to(throwAssertion()) } } } diff --git a/bin/generate b/bin/generate index c6c1227..f003522 100755 --- a/bin/generate +++ b/bin/generate @@ -103,7 +103,7 @@ func registerGenerator(_ dependenciesCount: Int, argumentsCount: Int, breakIntoV ] if argumentsCount > 1 { - register += [" if !hasUnique(arguments: [\(commaConcat(genericArgumentsVars))]) { fatalError(\"AutoRegistration of service with same type arguments (\(commaConcat(genericArgumentsVars.map{ "\\(\($0))" }))) is not supported)\") }"] + register += [" precondition(hasUnique(arguments: [\(commaConcat(genericArgumentsVars))]), \"AutoRegistration of service with same type arguments (\(commaConcat(genericArgumentsVars.map{ "\\(\($0))" }))) is not supported\")"] } register += [ From a6d5428b4841001be692dd2028b0cdf9e09a4d01 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 22 Jan 2017 19:51:48 +0100 Subject: [PATCH 11/23] More checkouts, podspec fix --- .../CwlCatchException/.gitignore | 3 + .../CwlCatchException/CwlCatchException.h | 30 + .../CwlCatchException/CwlCatchException.m | 35 ++ .../CwlCatchException/CwlCatchException.swift | 32 ++ .../CwlCatchException/Info.plist | 28 + .../CwlBadInstructionException.swift | 76 +++ .../CwlCatchBadInstruction.h | 61 ++ .../CwlCatchBadInstruction.m | 50 ++ .../CwlCatchBadInstruction.swift | 194 +++++++ .../CwlCatchBadInstructionPOSIX.swift | 100 ++++ .../CwlDarwinDefinitions.swift | 63 ++ .../CwlPreconditionTesting/Info.plist | 28 + .../CwlPreconditionTesting/mach_excServer.c | 537 ++++++++++++++++++ .../CwlPreconditionTesting/mach_excServer.h | 298 ++++++++++ .../Lib/CwlPreconditionTesting/README.md | 80 +++ .../Nimble/Matchers/ThrowAssertion.swift | 55 ++ .../Matchers/ThrowAssertionTest.swift | 62 ++ Carthage/Checkouts/Quick/.Package.test.swift | 19 + .../Checkouts/Quick/.github/ISSUE_TEMPLATE | 36 ++ .../Quick/.github/PULL_REQUEST_TEMPLATE | 14 + Carthage/Checkouts/Quick/.hound.yml | 2 + Carthage/Checkouts/Quick/.swiftlint.yml | 12 + .../Documentation/pt-br/BehavioralTesting.md | 78 +++ .../Quick/Documentation/pt-br/README.md | 39 ++ .../Documentation/zh-cn/SharedExamples.md | 113 ++++ .../CwlCatchException/.gitignore | 3 + .../CwlCatchException/CwlCatchException.h | 30 + .../CwlCatchException/CwlCatchException.m | 35 ++ .../CwlCatchException/CwlCatchException.swift | 32 ++ .../CwlCatchException/Info.plist | 28 + .../CwlBadInstructionException.swift | 76 +++ .../CwlCatchBadInstruction.h | 61 ++ .../CwlCatchBadInstruction.m | 50 ++ .../CwlCatchBadInstruction.swift | 194 +++++++ .../CwlCatchBadInstructionPOSIX.swift | 100 ++++ .../CwlDarwinDefinitions.swift | 63 ++ .../CwlPreconditionTesting/Info.plist | 28 + .../CwlPreconditionTesting/mach_excServer.c | 537 ++++++++++++++++++ .../CwlPreconditionTesting/mach_excServer.h | 298 ++++++++++ .../Lib/CwlPreconditionTesting/README.md | 80 +++ .../Nimble/Matchers/ThrowAssertion.swift | 55 ++ .../Matchers/ThrowAssertionTest.swift | 62 ++ .../Quick/Sources/Quick/URL+FileName.swift | 12 + .../AfterSuiteTests+ObjC.m | 32 ++ .../AfterSuiteTests.swift | 26 + .../QuickAfterSuiteTests/Info.plist | 24 + SwinjectAutoregistration.podspec | 2 +- 47 files changed, 3872 insertions(+), 1 deletion(-) create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h create mode 100644 Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/README.md create mode 100644 Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift create mode 100644 Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift create mode 100644 Carthage/Checkouts/Quick/.Package.test.swift create mode 100644 Carthage/Checkouts/Quick/.github/ISSUE_TEMPLATE create mode 100644 Carthage/Checkouts/Quick/.github/PULL_REQUEST_TEMPLATE create mode 100644 Carthage/Checkouts/Quick/.hound.yml create mode 100644 Carthage/Checkouts/Quick/.swiftlint.yml create mode 100644 Carthage/Checkouts/Quick/Documentation/pt-br/BehavioralTesting.md create mode 100644 Carthage/Checkouts/Quick/Documentation/pt-br/README.md create mode 100644 Carthage/Checkouts/Quick/Documentation/zh-cn/SharedExamples.md create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/README.md create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift create mode 100644 Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift create mode 100644 Carthage/Checkouts/Quick/Sources/Quick/URL+FileName.swift create mode 100644 Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests+ObjC.m create mode 100644 Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests.swift create mode 100644 Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/Info.plist diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore new file mode 100644 index 0000000..5b05d7e --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +project.xcworkspace/ +xcuserdata/ diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h new file mode 100644 index 0000000..6ec6a29 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h @@ -0,0 +1,30 @@ +// +// CwlCatchException.h +// CwlCatchException +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import + +//! Project version number for CwlCatchException. +FOUNDATION_EXPORT double CwlCatchExceptionVersionNumber; + +//! Project version string for CwlCatchException. +FOUNDATION_EXPORT const unsigned char CwlCatchExceptionVersionString[]; + +__attribute__((visibility("hidden"))) +NSException* __nullable catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)()); diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m new file mode 100644 index 0000000..4f9772c --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m @@ -0,0 +1,35 @@ +// +// CwlCatchException.m +// CwlAssertionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import "CwlCatchException.h" + +__attribute__((visibility("hidden"))) +NSException* catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)()) { + @try { + inBlock(); + } @catch (NSException *exception) { + if ([exception isKindOfClass:type]) { + return exception; + } else { + @throw; + } + } + return nil; +} diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift new file mode 100644 index 0000000..b44a232 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift @@ -0,0 +1,32 @@ +// +// CwlCatchException.swift +// CwlAssertionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +// We can't simply cast to Self? in the catchInBlock method so we need this generic function wrapper to do the conversion for us. Mildly annoying. +private func catchReturnTypeConverter(_ type: T.Type, block: () -> Void) -> T? { + return catchExceptionOfKind(type, block) as? T +} + +extension NSException { + public static func catchException(in block: () -> Void) -> Self? { + return catchReturnTypeConverter(self, block: block) + } +} diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist new file mode 100644 index 0000000..f14cf1e --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2016 Matt Gallagher. All rights reserved. + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift new file mode 100644 index 0000000..2fa67c9 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift @@ -0,0 +1,76 @@ +// +// CwlBadInstructionException.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +private func raiseBadInstructionException() { + BadInstructionException().raise() +} + +/// A simple NSException subclass. It's not required to subclass NSException (since the exception type is represented in the name) but this helps for identifying the exception through runtime type. +@objc public class BadInstructionException: NSException { + static var name: String = "com.cocoawithlove.BadInstruction" + + init() { + super.init(name: NSExceptionName(rawValue: BadInstructionException.name), reason: nil, userInfo: nil) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + /// An Objective-C callable function, invoked from the `mach_exc_server` callback function `catch_mach_exception_raise_state` to push the `raiseBadInstructionException` function onto the stack. + public class func catch_mach_exception_raise_state(_ exception_port: mach_port_t, exception: exception_type_t, code: UnsafePointer, codeCnt: mach_msg_type_number_t, flavor: UnsafeMutablePointer, old_state: UnsafePointer, old_stateCnt: mach_msg_type_number_t, new_state: thread_state_t, new_stateCnt: UnsafeMutablePointer) -> kern_return_t { + + #if arch(x86_64) + // Make sure we've been given enough memory + if old_stateCnt != x86_THREAD_STATE64_COUNT || new_stateCnt.pointee < x86_THREAD_STATE64_COUNT { + return KERN_INVALID_ARGUMENT + } + + // Read the old thread state + var state = old_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { return $0.pointee } + + // 1. Decrement the stack pointer + state.__rsp -= __uint64_t(MemoryLayout.size) + + // 2. Save the old Instruction Pointer to the stack. + if let pointer = UnsafeMutablePointer<__uint64_t>(bitPattern: UInt(state.__rsp)) { + pointer.pointee = state.__rip + } else { + return KERN_INVALID_ARGUMENT + } + + // 3. Set the Instruction Pointer to the new function's address + var f: @convention(c) () -> Void = raiseBadInstructionException + withUnsafePointer(to: &f) { + state.__rip = $0.withMemoryRebound(to: __uint64_t.self, capacity: 1) { return $0.pointee } + } + + // Write the new thread state + new_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { $0.pointee = state } + new_stateCnt.pointee = x86_THREAD_STATE64_COUNT + + return KERN_SUCCESS + #else + fatalError("Unavailable for this CPU architecture") + #endif + } +} diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h new file mode 100644 index 0000000..0333ed2 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h @@ -0,0 +1,61 @@ +// +// CwlCatchBadInstruction.h +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if defined(__x86_64__) + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +// The request_mach_exception_raise_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. +typedef struct +{ + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; +} request_mach_exception_raise_t; + +// The reply_mach_exception_raise_state_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. +typedef struct +{ + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; +} reply_mach_exception_raise_state_t; + +extern boolean_t mach_exc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +NS_ASSUME_NONNULL_END + +#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m new file mode 100644 index 0000000..22c1377 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m @@ -0,0 +1,50 @@ +// +// CwlCatchBadInstruction.m +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if defined(__x86_64__) + +#import "CwlCatchBadInstruction.h" + +// Assuming the "PRODUCT_NAME" macro is defined, this will create the name of the Swift generated header file +#define STRINGIZE_NO_EXPANSION(A) #A +#define STRINGIZE_WITH_EXPANSION(A) STRINGIZE_NO_EXPANSION(A) +#define SWIFT_INCLUDE STRINGIZE_WITH_EXPANSION(PRODUCT_NAME-Swift.h) + +// Include the Swift generated header file +#import SWIFT_INCLUDE + +/// A basic function that receives callbacks from mach_exc_server and relays them to the Swift implemented BadInstructionException.catch_mach_exception_raise_state. +kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, const thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { + return [BadInstructionException catch_mach_exception_raise_state:exception_port exception:exception code:code codeCnt:codeCnt flavor:flavor old_state:old_state old_stateCnt:old_stateCnt new_state:new_state new_stateCnt:new_stateCnt]; +} + +// The mach port should be configured so that this function is never used. +kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) { + assert(false); + return KERN_FAILURE; +} + +// The mach port should be configured so that this function is never used. +kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { + assert(false); + return KERN_FAILURE; +} + +#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift new file mode 100644 index 0000000..ab460b3 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift @@ -0,0 +1,194 @@ +// +// CwlCatchBadInstruction.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +#if arch(x86_64) + + private enum PthreadError: Error { case code(Int32) } + private enum MachExcServer: Error { case code(kern_return_t) } + + /// A quick function for converting Mach error results into Swift errors + private func kernCheck(_ f: () -> Int32) throws { + let r = f() + guard r == KERN_SUCCESS else { + throw NSError(domain: NSMachErrorDomain, code: Int(r), userInfo: nil) + } + } + + extension execTypesCountTuple { + mutating func pointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: T.self, capacity: EXC_TYPES_COUNT) { ptr -> R in + return block(ptr) + } + } + } + } + + extension request_mach_exception_raise_t { + mutating func withMsgHeaderPointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: mach_msg_header_t.self, capacity: 1) { ptr -> R in + return block(ptr) + } + } + } + } + + extension reply_mach_exception_raise_state_t { + mutating func withMsgHeaderPointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: mach_msg_header_t.self, capacity: 1) { ptr -> R in + return block(ptr) + } + } + } + } + + /// A structure used to store context associated with the Mach message port + private struct MachContext { + var masks = execTypesCountTuple() + var count: mach_msg_type_number_t = 0 + var ports = execTypesCountTuple() + var behaviors = execTypesCountTuple() + var flavors = execTypesCountTuple() + var currentExceptionPort: mach_port_t = 0 + var handlerThread: pthread_t? = nil + + mutating func withUnsafeMutablePointers(in block: (UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer) -> R) -> R { + return masks.pointer { masksPtr in + return ports.pointer { portsPtr in + return behaviors.pointer { behaviorsPtr in + return flavors.pointer { flavorsPtr in + return block(masksPtr, portsPtr, behaviorsPtr, flavorsPtr) + } + } + } + } + } + } + + /// A function for receiving mach messages and parsing the first with mach_exc_server (and if any others are received, throwing them away). + private func machMessageHandler(_ arg: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { + let context = arg.assumingMemoryBound(to: MachContext.self).pointee + var request = request_mach_exception_raise_t() + var reply = reply_mach_exception_raise_state_t() + + var handledfirstException = false + repeat { do { + // Request the next mach message from the port + request.Head.msgh_local_port = context.currentExceptionPort + request.Head.msgh_size = UInt32(MemoryLayout.size) + try kernCheck { request.withMsgHeaderPointer { requestPtr in + mach_msg(requestPtr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0, request.Head.msgh_size, context.currentExceptionPort, 0, UInt32(MACH_PORT_NULL)) + } } + + // Prepare the reply structure + reply.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request.Head.msgh_bits), 0) + reply.Head.msgh_local_port = UInt32(MACH_PORT_NULL) + reply.Head.msgh_remote_port = request.Head.msgh_remote_port + reply.Head.msgh_size = UInt32(MemoryLayout.size) + reply.NDR = NDR_record + + if !handledfirstException { + // Use the MiG generated server to invoke our handler for the request and fill in the rest of the reply structure + guard request.withMsgHeaderPointer(in: { requestPtr in reply.withMsgHeaderPointer { replyPtr in + mach_exc_server(requestPtr, replyPtr) + } }) != 0 else { throw MachExcServer.code(reply.RetCode) } + + handledfirstException = true + } else { + // If multiple fatal errors occur, don't handle subsquent errors (let the program crash) + reply.RetCode = KERN_FAILURE + } + + // Send the reply + try kernCheck { reply.withMsgHeaderPointer { replyPtr in + mach_msg(replyPtr, MACH_SEND_MSG, reply.Head.msgh_size, 0, UInt32(MACH_PORT_NULL), 0, UInt32(MACH_PORT_NULL)) + } } + } catch let error as NSError where (error.domain == NSMachErrorDomain && (error.code == Int(MACH_RCV_PORT_CHANGED) || error.code == Int(MACH_RCV_INVALID_NAME))) { + // Port was already closed before we started or closed while we were listening. + // This means the controlling thread shut down. + return nil + } catch { + // Should never be reached but this is testing code, don't try to recover, just abort + fatalError("Mach message error: \(error)") + } } while true + } + + /// Run the provided block. If a mach "BAD_INSTRUCTION" exception is raised, catch it and return a BadInstructionException (which captures stack information about the throw site, if desired). Otherwise return nil. + /// NOTE: This function is only intended for use in test harnesses – use in a distributed build is almost certainly a bad choice. If a "BAD_INSTRUCTION" exception is raised, the block will be exited before completion via Objective-C exception. The risks associated with an Objective-C exception apply here: most Swift/Objective-C functions are *not* exception-safe. Memory may be leaked and the program will not necessarily be left in a safe state. + /// - parameter block: a function without parameters that will be run + /// - returns: if an EXC_BAD_INSTRUCTION is raised during the execution of `block` then a BadInstructionException will be returned, otherwise `nil`. + public func catchBadInstruction(in block: () -> Void) -> BadInstructionException? { + var context = MachContext() + var result: BadInstructionException? = nil + do { + var handlerThread: pthread_t? = nil + defer { + // 8. Wait for the thread to terminate *if* we actually made it to the creation point + // The mach port should be destroyed *before* calling pthread_join to avoid a deadlock. + if handlerThread != nil { + pthread_join(handlerThread!, nil) + } + } + + try kernCheck { + // 1. Create the mach port + mach_port_allocate(mach_task_self_, MACH_PORT_RIGHT_RECEIVE, &context.currentExceptionPort) + } + defer { + // 7. Cleanup the mach port + mach_port_destroy(mach_task_self_, context.currentExceptionPort) + } + + try kernCheck { + // 2. Configure the mach port + mach_port_insert_right(mach_task_self_, context.currentExceptionPort, context.currentExceptionPort, MACH_MSG_TYPE_MAKE_SEND) + } + + try kernCheck { context.withUnsafeMutablePointers { masksPtr, portsPtr, behaviorsPtr, flavorsPtr in + // 3. Apply the mach port as the handler for this thread + thread_swap_exception_ports(mach_thread_self(), EXC_MASK_BAD_INSTRUCTION, context.currentExceptionPort, Int32(bitPattern: UInt32(EXCEPTION_STATE) | MACH_EXCEPTION_CODES), x86_THREAD_STATE64, masksPtr, &context.count, portsPtr, behaviorsPtr, flavorsPtr) + } } + + defer { context.withUnsafeMutablePointers { masksPtr, portsPtr, behaviorsPtr, flavorsPtr in + // 6. Unapply the mach port + _ = thread_swap_exception_ports(mach_thread_self(), EXC_MASK_BAD_INSTRUCTION, 0, EXCEPTION_DEFAULT, THREAD_STATE_NONE, masksPtr, &context.count, portsPtr, behaviorsPtr, flavorsPtr) + } } + + try withUnsafeMutablePointer(to: &context) { c throws in + // 4. Create the thread + let e = pthread_create(&handlerThread, nil, machMessageHandler, c) + guard e == 0 else { throw PthreadError.code(e) } + + // 5. Run the block + result = BadInstructionException.catchException(in: block) + } + } catch { + // Should never be reached but this is testing code, don't try to recover, just abort + fatalError("Mach port error: \(error)") + } + return result + } + +#endif + diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift new file mode 100644 index 0000000..b3afb12 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift @@ -0,0 +1,100 @@ +// +// CwlCatchBadInstructionPOSIX.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 8/02/2016. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +#if arch(x86_64) + +// This file is an alternative implementation to CwlCatchBadInstruction.swift that uses a SIGILL signal action and setenv/longjmp instead of a Mach exception handler and Objective-C exception raising. +// +// WARNING: +// This code is quick and dirty. It's a proof of concept for using a SIGILL handler and setjmp/longjmp where Mach exceptions and the Obj-C runtime aren't available. I ran the automated tests when I first wrote this code but I don't personally use it at all so by the time you're reading this comment, it probably broke and I didn't notice. +// Obvious limitations: +// * It doesn't work when debugging with lldb. +// * It doesn't scope correctly to the thread (it's global) +// * In violation of rules for signal handlers, it writes to the "red zone" on the stack +// * It isn't re-entrant +// * Plus all of the same caveats as the Mach exceptions version (doesn't play well with other handlers, probably leaks ARC memory, etc) +// Treat it like a loaded shotgun. Don't point it at your face. + +private var env = jmp_buf(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0) + +private func triggerLongJmp() { + longjmp(&env.0, 1) +} + +private func sigIllHandler(code: Int32, info: UnsafeMutablePointer<__siginfo>?, uap: UnsafeMutableRawPointer?) -> Void { + guard let context = uap?.assumingMemoryBound(to: ucontext64_t.self) else { return } + + // 1. Decrement the stack pointer + context.pointee.uc_mcontext64.pointee.__ss.__rsp -= __uint64_t(MemoryLayout.size) + + // 2. Save the old Instruction Pointer to the stack. + let rsp = context.pointee.uc_mcontext64.pointee.__ss.__rsp + if let ump = UnsafeMutablePointer<__uint64_t>(bitPattern: UInt(rsp)) { + ump.pointee = rsp + } + + // 3. Set the Instruction Pointer to the new function's address + var f: @convention(c) () -> Void = triggerLongJmp + withUnsafePointer(to: &f) { $0.withMemoryRebound(to: __uint64_t.self, capacity: 1) { ptr in + context.pointee.uc_mcontext64.pointee.__ss.__rip = ptr.pointee + } } +} + +/// Without Mach exceptions or the Objective-C runtime, there's nothing to put in the exception object. It's really just a boolean – either a SIGILL was caught or not. +public class BadInstructionException { +} + +/// Run the provided block. If a POSIX SIGILL is received, handle it and return a BadInstructionException (which is just an empty object in this POSIX signal version). Otherwise return nil. +/// NOTE: This function is only intended for use in test harnesses – use in a distributed build is almost certainly a bad choice. If a SIGILL is received, the block will be interrupted using a C `longjmp`. The risks associated with abrupt jumps apply here: most Swift functions are *not* interrupt-safe. Memory may be leaked and the program will not necessarily be left in a safe state. +/// - parameter block: a function without parameters that will be run +/// - returns: if an SIGILL is raised during the execution of `block` then a BadInstructionException will be returned, otherwise `nil`. +public func catchBadInstruction( block: () -> Void) -> BadInstructionException? { + // Construct the signal action + var sigActionPrev = sigaction() + let action = __sigaction_u(__sa_sigaction: sigIllHandler) + var sigActionNew = sigaction(__sigaction_u: action, sa_mask: sigset_t(), sa_flags: SA_SIGINFO) + + // Install the signal action + if sigaction(SIGILL, &sigActionNew, &sigActionPrev) != 0 { + fatalError("Sigaction error: \(errno)") + } + + defer { + // Restore the previous signal action + if sigaction(SIGILL, &sigActionPrev, nil) != 0 { + fatalError("Sigaction error: \(errno)") + } + } + + // Prepare the jump point + if setjmp(&env.0) != 0 { + // Handle jump received + return BadInstructionException() + } + + // Run the block + block() + + return nil +} + +#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift new file mode 100644 index 0000000..12a6b9f --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift @@ -0,0 +1,63 @@ +// +// CwlDarwinDefinitions.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Darwin + +#if arch(x86_64) + +// From /usr/include/mach/port.h +// #define MACH_PORT_RIGHT_RECEIVE ((mach_port_right_t) 1) +let MACH_PORT_RIGHT_RECEIVE: mach_port_right_t = 1 + +// From /usr/include/mach/message.h +// #define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */ +// #define MACH_MSGH_BITS_REMOTE(bits) \ +// ((bits) & MACH_MSGH_BITS_REMOTE_MASK) +// #define MACH_MSGH_BITS(remote, local) /* legacy */ \ +// ((remote) | ((local) << 8)) +let MACH_MSG_TYPE_MAKE_SEND: UInt32 = 20 +func MACH_MSGH_BITS_REMOTE(_ bits: UInt32) -> UInt32 { return bits & UInt32(MACH_MSGH_BITS_REMOTE_MASK) } +func MACH_MSGH_BITS(_ remote: UInt32, _ local: UInt32) -> UInt32 { return ((remote) | ((local) << 8)) } + +// From /usr/include/mach/exception_types.h +// #define EXC_BAD_INSTRUCTION 2 /* Instruction failed */ +// #define EXC_MASK_BAD_INSTRUCTION (1 << EXC_BAD_INSTRUCTION) +// #define EXCEPTION_DEFAULT 1 +let EXC_BAD_INSTRUCTION: UInt32 = 2 +let EXC_MASK_BAD_INSTRUCTION: UInt32 = 1 << EXC_BAD_INSTRUCTION +let EXCEPTION_DEFAULT: Int32 = 1 + +// From /usr/include/mach/i386/thread_status.h +// #define THREAD_STATE_NONE 13 +// #define x86_THREAD_STATE64_COUNT ((mach_msg_type_number_t) \ +// ( sizeof (x86_thread_state64_t) / sizeof (int) )) +let THREAD_STATE_NONE: Int32 = 13 +let x86_THREAD_STATE64_COUNT = UInt32(MemoryLayout.size / MemoryLayout.size) + +let EXC_TYPES_COUNT = 14 +struct execTypesCountTuple { + // From /usr/include/mach/i386/exception.h + // #define EXC_TYPES_COUNT 14 /* incl. illegal exception 0 */ + var value: (T,T,T,T,T,T,T,T,T,T,T,T,T,T) = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + init() { + } +} + +#endif diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist new file mode 100644 index 0000000..f14cf1e --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2016 Matt Gallagher. All rights reserved. + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c new file mode 100644 index 0000000..2334538 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c @@ -0,0 +1,537 @@ +/* + * IDENTIFICATION: + * stub generated Mon Jan 11 00:24:26 2016 + * with a MiG generated by bootstrap_cmds-93 + * OPTIONS: + */ + +/* Module mach_exc */ + +#if defined(__x86_64__) + +#define __MIG_check__Request__mach_exc_subsystem__ 1 + +#include "mach_excServer.h" + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __DeclareRcvRpc +#define __DeclareRcvRpc(_NUM_, _NAME_) +#endif /* __DeclareRcvRpc */ + +#ifndef __BeforeRcvRpc +#define __BeforeRcvRpc(_NUM_, _NAME_) +#endif /* __BeforeRcvRpc */ + +#ifndef __AfterRcvRpc +#define __AfterRcvRpc(_NUM_, _NAME_) +#endif /* __AfterRcvRpc */ + +#ifndef __DeclareRcvSimple +#define __DeclareRcvSimple(_NUM_, _NAME_) +#endif /* __DeclareRcvSimple */ + +#ifndef __BeforeRcvSimple +#define __BeforeRcvSimple(_NUM_, _NAME_) +#endif /* __BeforeRcvSimple */ + +#ifndef __AfterRcvSimple +#define __AfterRcvSimple(_NUM_, _NAME_) +#endif /* __AfterRcvSimple */ + +#define novalue void + +#define msgh_request_port msgh_local_port +#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) +#define msgh_reply_port msgh_remote_port +#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) + +#define MIG_RETURN_ERROR(X, code) {\ + ((mig_reply_error_t *)X)->RetCode = code;\ + ((mig_reply_error_t *)X)->NDR = NDR_record;\ + return;\ + } + +/* Forward Declarations */ + + +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_t__defined) +#define __MIG_check__Request__mach_exception_raise_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) +{ + + typedef __Request__mach_exception_raise_t __Request; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 16)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 16)) / 8 < In0P->codeCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 16) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise */ +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_t __Request; + typedef __Reply__mach_exception_raise_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_t__defined */ + + __DeclareRcvRpc(2405, "mach_exception_raise") + __BeforeRcvRpc(2405, "mach_exception_raise") + +#if defined(__MIG_check__Request__mach_exception_raise_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_t((__Request *)In0P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ + + OutP->RetCode = catch_mach_exception_raise(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); + + OutP->NDR = NDR_record; + + + __AfterRcvRpc(2405, "mach_exception_raise") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state */ +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_t __Request; + typedef __Reply__mach_exception_raise_state_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ + + __DeclareRcvRpc(2406, "mach_exception_raise_state") + __BeforeRcvRpc(2406, "mach_exception_raise_state") + +#if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2406, "mach_exception_raise_state") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_identity_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_identity_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state_identity */ +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_identity_t __Request; + typedef __Reply__mach_exception_raise_state_identity_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ + + __DeclareRcvRpc(2407, "mach_exception_raise_state_identity") + __BeforeRcvRpc(2407, "mach_exception_raise_state_identity") + +#if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_identity_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state_identity(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2407, "mach_exception_raise_state_identity") +} + + + +/* Description of this subsystem, for use in direct RPC */ +const struct catch_mach_exc_subsystem catch_mach_exc_subsystem = { + mach_exc_server_routine, + 2405, + 2408, + (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), + (vm_address_t)0, + { + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state_identity, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, + } +}; + +mig_external boolean_t mach_exc_server + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + register mig_routine_t routine; + + OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); + OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; + /* Minimal size: routine() will update it if different */ + OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); + OutHeadP->msgh_local_port = MACH_PORT_NULL; + OutHeadP->msgh_id = InHeadP->msgh_id + 100; + + if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || + ((routine = catch_mach_exc_subsystem.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) { + ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; + ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; + return FALSE; + } + (*routine) (InHeadP, OutHeadP); + return TRUE; +} + +mig_external mig_routine_t mach_exc_server_routine + (mach_msg_header_t *InHeadP) +{ + register int msgh_id; + + msgh_id = InHeadP->msgh_id - 2405; + + if ((msgh_id > 2) || (msgh_id < 0)) + return 0; + + return catch_mach_exc_subsystem.routine[msgh_id].stub_routine; +} + +#endif + diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h new file mode 100644 index 0000000..766ba11 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h @@ -0,0 +1,298 @@ +#ifndef _mach_exc_server_ +#define _mach_exc_server_ + +/* Module mach_exc */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN VOUCHER CODE */ + +#ifndef KERNEL +#if defined(__has_include) +#if __has_include() +#ifndef USING_VOUCHERS +#define USING_VOUCHERS +#endif +#ifndef __VOUCHER_FORWARD_TYPE_DECLS__ +#define __VOUCHER_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif // __VOUCHER_FORWARD_TYPE_DECLS__ +#endif // __has_include() +#endif // __has_include +#endif // !KERNEL + +/* END VOUCHER CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_exc_MSG_COUNT +#define mach_exc_MSG_COUNT 3 +#endif /* mach_exc_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigServerHeader +__BeforeMigServerHeader +#endif /* __BeforeMigServerHeader */ + + +/* Routine mach_exception_raise */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine mach_exception_raise_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state_identity */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state_identity +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +boolean_t mach_exc_server( + mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +mig_routine_t mach_exc_server_routine( + mach_msg_header_t *InHeadP); + + +/* Description of this subsystem, for use in direct RPC */ +extern const struct catch_mach_exc_subsystem { + mig_server_routine_t server; /* Server routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + unsigned int maxsize; /* Max msg size */ + vm_address_t reserved; /* Reserved */ + struct routine_descriptor /*Array of routine descriptors */ + routine[3]; +} catch_mach_exc_subsystem; + +/* typedefs for all requests */ + +#ifndef __Request__mach_exc_subsystem__defined +#define __Request__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } __Request__mach_exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_exc_subsystem__defined */ + + +/* union of all requests */ + +#ifndef __RequestUnion__catch_mach_exc_subsystem__defined +#define __RequestUnion__catch_mach_exc_subsystem__defined +union __RequestUnion__catch_mach_exc_subsystem { + __Request__mach_exception_raise_t Request_mach_exception_raise; + __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; + __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_exc_subsystem__defined +#define __Reply__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_exc_subsystem__defined */ + + +/* union of all replies */ + +#ifndef __ReplyUnion__catch_mach_exc_subsystem__defined +#define __ReplyUnion__catch_mach_exc_subsystem__defined +union __ReplyUnion__catch_mach_exc_subsystem { + __Reply__mach_exception_raise_t Reply_mach_exception_raise; + __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; + __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_exc +#define subsystem_to_name_map_mach_exc \ + { "mach_exception_raise", 2405 },\ + { "mach_exception_raise_state", 2406 },\ + { "mach_exception_raise_state_identity", 2407 } +#endif + +#ifdef __AfterMigServerHeader +__AfterMigServerHeader +#endif /* __AfterMigServerHeader */ + +#endif /* _mach_exc_server_ */ diff --git a/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/README.md b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/README.md new file mode 100644 index 0000000..a1a9a70 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Lib/CwlPreconditionTesting/README.md @@ -0,0 +1,80 @@ +# CwlPreconditionTesting + +A Mach exception handler, written in Swift and Objective-C, that allows `EXC_BAD_INSTRUCTION` (as raised by Swift's `assertionFailure`/`preconditionFailure`/`fatalError`) to be caught and tested. + +For an extended discussion of this code, please see the Cocoa with Love article: + +[Partial functions in Swift, Part 2: Catching precondition failures](http://cocoawithlove.com/blog/2016/02/02/partial-functions-part-two-catching-precondition-failures.html) + +## Usage + +The short version is: + +1. `git clone https://github.com/mattgallagher/CwlPreconditionTesting.git` +2. drag the "CwlPreconditionTesting.xcodeproj" file into your project's file tree in Xcode +3. go to your testing target's Build Phase settings and under "Target Dependencies" press the "+" button and select the relevant "CwlPreconditionTesting" target ("_iOS" or "_OSX", depending on your testing target's SDK) +4. write `import CwlPreconditionTesting` at the top of any test file where you want to use `catchBadInstruction` (Swift should handle the linkage automatically when you do this) +5. use the `catchBadInstruction` function as shown in the [CwlCatchBadInstructionTests.swift tests file](https://github.com/mattgallagher/CwlPreconditionTesting/blob/master/CwlPreconditionTestingTests/CwlCatchBadInstructionTests.swift?ts=4) + +### Project details + +The "CwlPreconditionTesting.xcodeproj" contains two targets: + +* CwlPreconditionTesting_OSX +* CwlPreconditionTesting_iOS + +both build a framework named "CwlPreconditionTesting.framework". If you're linking manually, be certain to select the "CwlPreconditionTesting.framework" from the appropriate target. + +Remember: the iOS build is useful only in the simulator. All Mach exception handling code will be conditionally excluded in any device build. + +### Static inclusion + +Due to the complications associated with needing to call into and out of Objective-C, static inclusion in other projects is not a single file nor a quick drag and drop. There's at least 7 files and you'll need to add some project settings. + +All of the following files: + +* CwlCatchBadInstruction.swift +* CwlCatchBadInstruction.h +* CwlCatchBadInstruction.m +* CwlCatchException.swift +* CwlCatchException.h +* CwlCatchException.m + +and either: + +* $(SDKROOT)/usr/include/mach/mach_exc.defs +* mach_excServer.c + +need to be added to the testing target for OS X projects or iOS projects, respectively. + +Your target will also need to have the following macros defined in the "Apple LLVM - Preprocessing" → "Preprocessor Macros" build setting: + + PRODUCT_NAME=$(PRODUCT_NAME) + +This lets the Objective-C file generate the include directive for the autogenerated Swift header so it can call back into Swift during the Mach exception handler callbacks. This macro should stay in sync if you change the target name but if you do anything else in your project that changes the name of the autogenerated Swift header independent of the target name (or you want to add spaces or other command-line complications to the target name), you'll want to update "CwlCatchBadInstruction.m" directly with the correct include directive. + +Additionally, you'll need a standard Objective-C "Bridging header" for your testing target and it will need to include the following import statements: + +``` +#if defined(__x86_64__) +#import +#endif + +#import +``` + +### Using POSIX signals and setjmp/longjmp + +For comparison or for anyone running this code on a platform without Mach exceptions or the Objective-C runtime, I've added a proof-of-concept implementation of `catchBadInstruction` that uses a POSIX SIGILL `sigaction` and `setjmp`/`longjmp` to perform the throw. + +In Xcode, you can simply select the CwlPreconditionTesting_POSIX target (instead of the OSX or iOS targets). If you're building without Xcode: all you need is the CwlCatchBadInstructionPOSIX.swift file (compared to the Mach exception handler, the code is tiny doesn't have any weird Objective-C/MiG file dependencies). + +**Warning No. 1**: on OS X, this approach can't be used when lldb is attached since lldb's Mach exception handler blocks the SIGILL from ever occurring (I've disabled the "Debug Executable" setting for the tests in Xcode - re-enable it to witness the problem). + +**Warning No. 2**: if you're switching between the CwlPreconditionTesting_OSX and CwlPreconditionTesting_POSIX targets, Xcode (as of Xcode 7.2.1) will not detect the change and will not remove the old framework correctly so you'll need to *clean your project* otherwise the old framework will hang around. + +Additional problems in decreasing severity include: + +* the signal handler is whole process (rather than correctly scoped to the thread where the "catch" occurs) +* the signal handler doesn't deal with re-entrancy whereas the mach exception handler remains deterministic in the face of multiple fatal errors +* the signal handler overwrites the "[red zone](https://en.wikipedia.org/wiki/Red_zone_(computing))" which is technically frowned upon in signal handlers (although unlikely to cause problems here) diff --git a/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift new file mode 100644 index 0000000..67f9cf6 --- /dev/null +++ b/Carthage/Checkouts/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift @@ -0,0 +1,55 @@ +import Foundation + +public func throwAssertion() -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + #if arch(x86_64) && _runtime(_ObjC) && !SWIFT_PACKAGE + failureMessage.postfixMessage = "throw an assertion" + failureMessage.actualValue = nil + + var succeeded = true + + let caughtException: BadInstructionException? = catchBadInstruction { + #if os(tvOS) + if (!NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning) { + print() + print("[Nimble Warning]: If you're getting stuck on a debugger breakpoint for a " + + "fatal error while using throwAssertion(), please disable 'Debug Executable' " + + "in your scheme. Go to 'Edit Scheme > Test > Info' and uncheck " + + "'Debug Executable'. If you've already done that, suppress this warning " + + "by setting `NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true`. " + + "This is required because the standard methods of catching assertions " + + "(mach APIs) are unavailable for tvOS. Instead, the same mechanism the " + + "debugger uses is the fallback method for tvOS." + ) + print() + NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true + } + #endif + do { + try actualExpression.evaluate() + } catch let error { + succeeded = false + failureMessage.postfixMessage += "; threw error instead <\(error)>" + } + } + + if !succeeded { + return false + } + + if caughtException == nil { + return false + } + + return true + #elseif SWIFT_PACKAGE + fatalError("The throwAssertion Nimble matcher does not currently support Swift CLI." + + " You can silence this error by placing the test case inside an #if !SWIFT_PACKAGE" + + " conditional statement") + #else + fatalError("The throwAssertion Nimble matcher can only run on x86_64 platforms with " + + "Objective-C (e.g. Mac, iPhone 5s or later simulators). You can silence this error " + + "by placing the test case inside an #if arch(x86_64) or _runtime(_ObjC) conditional statement") + #endif + } +} diff --git a/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift new file mode 100644 index 0000000..c227b1b --- /dev/null +++ b/Carthage/Checkouts/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift @@ -0,0 +1,62 @@ +import Foundation +import XCTest +import Nimble + +#if _runtime(_ObjC) && !SWIFT_PACKAGE + +final class ThrowAssertionTest: XCTestCase, XCTestCaseProvider { + static var allTests: [(String, (ThrowAssertionTest) -> () throws -> Void)] { + return [ + ("testPositiveMatch", testPositiveMatch), + ("testErrorThrown", testErrorThrown), + ("testPostAssertionCodeNotRun", testPostAssertionCodeNotRun), + ("testNegativeMatch", testNegativeMatch), + ("testPositiveMessage", testPositiveMessage), + ("testNegativeMessage", testNegativeMessage), + ] + } + + func testPositiveMatch() { + expect { () -> Void in fatalError() }.to(throwAssertion()) + } + + func testErrorThrown() { + expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion()) + } + + func testPostAssertionCodeNotRun() { + var reachedPoint1 = false + var reachedPoint2 = false + + expect { + reachedPoint1 = true + precondition(false, "condition message") + reachedPoint2 = true + }.to(throwAssertion()) + + expect(reachedPoint1) == true + expect(reachedPoint2) == false + } + + func testNegativeMatch() { + var reachedPoint1 = false + + expect { reachedPoint1 = true }.toNot(throwAssertion()) + + expect(reachedPoint1) == true + } + + func testPositiveMessage() { + failsWithErrorMessage("expected to throw an assertion") { + expect { () -> Void? in return }.to(throwAssertion()) + } + } + + func testNegativeMessage() { + failsWithErrorMessage("expected to not throw an assertion") { + expect { () -> Void in fatalError() }.toNot(throwAssertion()) + } + } +} + +#endif diff --git a/Carthage/Checkouts/Quick/.Package.test.swift b/Carthage/Checkouts/Quick/.Package.test.swift new file mode 100644 index 0000000..34b9608 --- /dev/null +++ b/Carthage/Checkouts/Quick/.Package.test.swift @@ -0,0 +1,19 @@ +import PackageDescription + +let package = Package( + name: "Quick", + // TODO: Once the `test` command has been implemented in the Swift Package Manager, this should be changed to + // be `testDependencies:` instead. For now it has to be done like this for the library to get linked with the test targets. + // See: https://github.com/apple/swift-evolution/blob/master/proposals/0019-package-manager-testing.md + dependencies: [ + .Package(url: "https://github.com/Quick/Nimble", majorVersion: 5) + ], + exclude: [ + "Sources/QuickObjectiveC", + "Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests+ObjC.m", + "Tests/QuickTests/QuickFocusedTests/FocusedTests+ObjC.m", + "Tests/QuickTests/QuickTests/FunctionalTests/ObjC", + "Tests/QuickTests/QuickTests/Helpers", + "Tests/QuickTests/QuickTests/QuickConfigurationTests.m", + ] +) diff --git a/Carthage/Checkouts/Quick/.github/ISSUE_TEMPLATE b/Carthage/Checkouts/Quick/.github/ISSUE_TEMPLATE new file mode 100644 index 0000000..ebe5a2b --- /dev/null +++ b/Carthage/Checkouts/Quick/.github/ISSUE_TEMPLATE @@ -0,0 +1,36 @@ +- [ ] I have read [CONTRIBUTING](https://github.com/Quick/Quick/blob/master/CONTRIBUTING.md) and have done my best to follow them. + +### What did you do? + +Please replace this with what you did. + +### What did you expect to happen? + +Please replace this with what you expected to happen. + +### What actually happened instead? + +Please replace this with what happened instead. + +### Environment + +List the software versions you're using: + + - Quick: *?.?.?* + - Nimble: *?.?.?* + - Xcode Version: *?.? (????)* (Open Xcode; In menubar: Xcode > About Xcode) + - Swift Version: *?.?* (Open Xcode Preferences; Components > Toolchains. If none, use `Xcode Default`.) + +Please also mention which package manager you used and its version. Delete the +other package managers in this list: + + - Cocoapods: *?.?.?* (Use `pod --version` in Terminal) + - Carthage: *?.?* (Use `carthage version` in Terminal) + - Swift Package Manager *?.?.? (swiftpm-???)* (Use `swift build --version` in Terminal) + +### Project that demonstrates the issue + +Please link to a project we can download that reproduces the issue. Feel free +to delete this section if it's not relevant to the issue (eg - feature request). + +The project should be [short, self-contained, and correct example](http://sscce.org/). diff --git a/Carthage/Checkouts/Quick/.github/PULL_REQUEST_TEMPLATE b/Carthage/Checkouts/Quick/.github/PULL_REQUEST_TEMPLATE new file mode 100644 index 0000000..20e40c8 --- /dev/null +++ b/Carthage/Checkouts/Quick/.github/PULL_REQUEST_TEMPLATE @@ -0,0 +1,14 @@ +The PR should summarize what was changed and why. Here are some questions to +help you if you're not sure: + + - What behavior was changed? + - What code was refactored / updated to support this change? + - What issues are related to this PR? Or why was this change introduced? + +Checklist - While not every PR needs it, new features should consider this list: + + - [ ] Does this have tests? + - [ ] Does this have documentation? + - [ ] Does this break the public API (Requires major version bump)? + - [ ] Is this a new feature (Requires minor version bump)? + diff --git a/Carthage/Checkouts/Quick/.hound.yml b/Carthage/Checkouts/Quick/.hound.yml new file mode 100644 index 0000000..b867fd9 --- /dev/null +++ b/Carthage/Checkouts/Quick/.hound.yml @@ -0,0 +1,2 @@ +swift: + config_file: .swiftlint.yml diff --git a/Carthage/Checkouts/Quick/.swiftlint.yml b/Carthage/Checkouts/Quick/.swiftlint.yml new file mode 100644 index 0000000..64760d5 --- /dev/null +++ b/Carthage/Checkouts/Quick/.swiftlint.yml @@ -0,0 +1,12 @@ + +disabled_rules: + - line_length + - type_name + - valid_docs + - empty_count + - force_unwrapping + - function_body_length + - variable_name +included: + - Sources + - Tests diff --git a/Carthage/Checkouts/Quick/Documentation/pt-br/BehavioralTesting.md b/Carthage/Checkouts/Quick/Documentation/pt-br/BehavioralTesting.md new file mode 100644 index 0000000..4e41676 --- /dev/null +++ b/Carthage/Checkouts/Quick/Documentation/pt-br/BehavioralTesting.md @@ -0,0 +1,78 @@ +# Não Teste o Código, Verifique Comportamento + +Testes devem falhar somente se a aplicação **se comportar diferente**. +Eles devem testar *o que* o código da aplicação faz, não *como* faz. + +- Testes que verificam *o que* a aplicação faz são **testes de comportamento**. +- Testes que quebram se o código da aplicação muda, mesmo que o comportamento seja mantido, são **teste frágeis**. + +Vamos supor que temos uma database de bananas, chamada `GorillaDB`. +`GorillaDB` é uma database baseada em chave-valor que guarda bananas. Nós podemos salvar bananas: + +```swift +let database = GorillaDB() +let banana = Banana() +database.save(banana: banana, key: "my-banana") +``` + +E podemos ler bananas: + +```swift +let banana = database.load(key: "my-banana") +``` + +## Testes Frágeis + +Como podemos testar esse comportamento? Um jeito seria checar o tamanho da database depois de salvar uma banana: + +```swift +// GorillaDBTests.swift + +func testSave_savesTheBananaToTheDatabase() { + // Arrange: Create a database and get its original size. + let database = GorillaDB() + let originalSize = database.size + + // Act: Save a banana to the database. + let banana = Banana() + database.save(banana: banana, key: "test-banana") + + // Assert: The size of the database should have increased by one. + XCTAssertEqual(database.size, originalSize + 1) +} +``` + + +Imagine, no entanto, que o código fonte da `GorillaDB` mude. Para que a operação de leitura de bananas da database seja mais rápida, é mantido um cache com as bananas lidas com maior frequência. `GorillaDB.size` aumenta conforme o tamanho do cache aumenta, e nosso teste falha: + +![](https://raw.githubusercontent.com/Quick/Assets/master/Screenshots/Screenshot_database_size_fail.png) + +## Testes de Comportamento + +O segredo para escrever testes de comportamento é determinar exatamente o que se espera que o código da aplicação faça. + +No contexto do teste `testSave_savesTheBananaToTheDatabase`: qual é o comportamento esperado quando uma banana é salva na database? "Salvar" implica que essa banana pode ser lida mais tarde. Então, ao invés de testar que o tamanho da database aumenta, nós devemos testar que é possível ler uma banana. + +```diff +// GorillaDBTests.swift + +func testSave_savesTheBananaToTheDatabase() { + // Arrange: Create a database and get its original size. + let database = GorillaDB() +- let originalSize = database.size + + // Act: Save a banana to the database. + let banana = Banana() + database.save(banana: banana, key: "test-banana") + +- // Assert: The size of the database should have increased by one. +- XCTAssertEqual(database.size, originalSize + 1) ++ // Assert: The bananas saved to and loaded from the database should be the same. ++ XCTAssertEqual(database.load(key: "test-banana"), banana) +} +``` + +O segredo para escrever testes de comportamento é perguntar: + +- O que exatamente o código dessa aplicação deve fazer? +- O meu teste está verificando *apenas* esse comportamento? Ou o teste pode falhar devido à forma como o código funciona? \ No newline at end of file diff --git a/Carthage/Checkouts/Quick/Documentation/pt-br/README.md b/Carthage/Checkouts/Quick/Documentation/pt-br/README.md new file mode 100644 index 0000000..c170942 --- /dev/null +++ b/Carthage/Checkouts/Quick/Documentation/pt-br/README.md @@ -0,0 +1,39 @@ +# Documentação + +Quick te ajuda a verificar como programas em Swift e Objective-C se comportam. + +Fazê-lo de forma eficaz não é apenas questão de saber como usar Quick. Os guias nesse diretório podem te ajudar a escrever testes eficazes --não apenas usando Quick, mas até mesmo XCTest ou outros framework de teste. + +Cada guia cobre um tópico em particular. Se você é completamente novo a teste unitário, considere lê-los na ordem que são introduzidos abaixo: + +- **[Configurar Testes no seu Xcode Project](SettingUpYourXcodeProject.md)**: + Leia isto se você esta com problemas para usar o código da sua aplicação de dentro dos seus arquivos de teste. +- **[Testes Eficazes Usando XCTest: Arrange, Act e Assert](ArrangeActAssert.md)**: + Leia isto para aprender como escrever `XCTestcase` testes que o ajudarão a escrever código mais rápido e mais eficaz. +- **[Não Teste o Código, Verifique Comportamento](BehavioralTesting.md)**: + Leia isto para aprender que tipos de testes te deixam mais rápido e quais os que só vão acabar te deixando mais devagar. +- **[Testes Limpos Usando Nimble Assertions](NimbleAssertions.md)**: + Leia isto para aprender a usar Nimble para gerar melhores mensagens de falha. + Melhores mensagens de falha ajudam a se mover mais rápido, gastando menos tempo tentando descobrir por que +    um teste falhou. +- **[Testes Organizados com Exemplos Quick e Grupos de Exemplo](QuickExamplesAndGroups.md)**: + Leia isto para aprender como Quick pode ajudar ainda mais a escrever testes eficazes, usando *exemplos* e *grupos de exemplos* +- **[Testando Aplicações OS X e iOS](TestingApps.md)**: + Leia isto para aprender mais sobre testar código que utiliza + AppKit e UIKit frameworks. +- **[Testando com testes dublês](TestUsingTestDoubles.md)**: + Leia isto para aprender o que são testes dublês e como usa-lôs. +- **[Reduzindo Teste Boilerplate com Assertions Compartilhados](SharedExamples.md)**: + Leia isto para aprender como compartilhar conjuntos de assertions entre seus testes. +- **[Configurando como Quick se Comporta](ConfiguringQuick.md)**: + Leia isto para aprender como você pode mudar como Quick se comporta quando roda os sua suite de testes. +- **[Usando Quick com Objective-C](QuickInObjectiveC.md)**: + Leia isto se você esta com problemas para usar Quick em Objective-C. +- **[Instalando Quick](InstallingQuick.md)**: + Leia isto para instruções de como adicionar Quick no seu projeto, usando Git submodules, CocoaPods, Carthage, ou Swift Package Manager. +- **[Instalando Arquivos Templates Quick](InstallingFileTemplates.md)**: +Leia isto para aprender como instalar arquivos templates que deixam escrever Quick specs mais rápidos. +- **[Mais Recursos](MoreResources.md)**: + Uma lista de recursos adicionais sobre testes OS X e iOS. +- **[Troubleshooting](Troubleshooting.md)**: + Leia isto quando você tiver outros problemas. diff --git a/Carthage/Checkouts/Quick/Documentation/zh-cn/SharedExamples.md b/Carthage/Checkouts/Quick/Documentation/zh-cn/SharedExamples.md new file mode 100644 index 0000000..ec87138 --- /dev/null +++ b/Carthage/Checkouts/Quick/Documentation/zh-cn/SharedExamples.md @@ -0,0 +1,113 @@ +# 使用 Shared Assertion 来复用测试模板代码 + +在某种场合下,一些特定的测试代码可以应用在不同的对象上。 + +比如,假设有一个叫 `Edible` 的协议。当一只海豚吃了标识为 `Edible` 的食物时,它会变得高兴。`Mackerel` 和 `Cod` 都遵循 `Edible` 协议。这个时候,Quick 的 shared example(共享用例)能帮你更容易地测试 `Mackerel` 和 `Cod` 的行为。 + +下面的例子为一些 `Edible` 的食物定义了一组共享用例,以测试 mackerel 和 cod 的行为。 + +```swift +// Swift + +import Quick +import Nimble + +class EdibleSharedExamplesConfiguration: QuickConfiguration { + override class func configure(_ configuration: Configuration) { + sharedExamples("something edible") { (sharedExampleContext: SharedExampleContext) in + it("makes dolphins happy") { + let dolphin = Dolphin(happy: false) + let edible = sharedExampleContext()["edible"] + dolphin.eat(edible) + expect(dolphin.isHappy).to(beTruthy()) + } + } + } +} + +class MackerelSpec: QuickSpec { + override func spec() { + var mackerel: Mackerel! + beforeEach { + mackerel = Mackerel() + } + + itBehavesLike("something edible") { ["edible": mackerel] } + } +} + +class CodSpec: QuickSpec { + override func spec() { + var cod: Cod! + beforeEach { + cod = Cod() + } + + itBehavesLike("something edible") { ["edible": cod] } + } +} +``` + +```objc +// Objective-C + +@import Quick; +@import Nimble; + +QuickConfigurationBegin(EdibleSharedExamplesConfiguration) + ++ (void)configure:(Configuration *configuration) { + sharedExamples(@"something edible", ^(QCKDSLSharedExampleContext exampleContext) { + it(@"makes dolphins happy") { + Dolphin *dolphin = [[Dolphin alloc] init]; + dolphin.happy = NO; + id edible = exampleContext()[@"edible"]; + [dolphin eat:edible]; + expect(dolphin.isHappy).to(beTruthy()) + } + }); +} + +QuickConfigurationEnd + +QuickSpecBegin(MackerelSpec) + +__block Mackerel *mackerel = nil; +beforeEach(^{ + mackerel = [[Mackerel alloc] init]; +}); + +itBehavesLike(@"someting edible", ^{ return @{ @"edible": mackerel }; }); + +QuickSpecEnd + +QuickSpecBegin(CodSpec) + +__block Mackerel *cod = nil; +beforeEach(^{ + cod = [[Cod alloc] init]; +}); + +itBehavesLike(@"someting edible", ^{ return @{ @"edible": cod }; }); + +QuickSpecEnd +``` + +共享用例可以包括任意数量的 `it`, `context` 和 `describe` 代码块。当使用它们来测试不同对象的相同行为时,你可以少写*很多*不必要的重复代码。 + +一般来说,你使用共享用例进行测试时不需要依赖其他额外的对象。在 Swift 中,你可以简单地用一个不带参数的 `sharedExample` 闭包来使用共享用例。当你需要进行全局测试时,这很有用。 + +```swift +// Swift + +import Quick + +sharedExamples("everything under the sea") { + // ... +} + +itBehavesLike("everything under the sea") +``` +> 如果你使用 Objective-C 的话,你需要传入一个带 `QCKDSLSharedExampleContext` 参数的 block,即使你并不打算使用它。不好意思,你只能这样做,人生有时就是这么的无奈。:cookie: :bomb: + +你也可以使用 `fitBehavesLike` 函数来单独测试共享用例。 diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore new file mode 100644 index 0000000..5b05d7e --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +project.xcworkspace/ +xcuserdata/ diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h new file mode 100644 index 0000000..6ec6a29 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.h @@ -0,0 +1,30 @@ +// +// CwlCatchException.h +// CwlCatchException +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import + +//! Project version number for CwlCatchException. +FOUNDATION_EXPORT double CwlCatchExceptionVersionNumber; + +//! Project version string for CwlCatchException. +FOUNDATION_EXPORT const unsigned char CwlCatchExceptionVersionString[]; + +__attribute__((visibility("hidden"))) +NSException* __nullable catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)()); diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m new file mode 100644 index 0000000..4f9772c --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.m @@ -0,0 +1,35 @@ +// +// CwlCatchException.m +// CwlAssertionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#import "CwlCatchException.h" + +__attribute__((visibility("hidden"))) +NSException* catchExceptionOfKind(Class __nonnull type, __attribute__((noescape)) void (^ __nonnull inBlock)()) { + @try { + inBlock(); + } @catch (NSException *exception) { + if ([exception isKindOfClass:type]) { + return exception; + } else { + @throw; + } + } + return nil; +} diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift new file mode 100644 index 0000000..b44a232 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/CwlCatchException.swift @@ -0,0 +1,32 @@ +// +// CwlCatchException.swift +// CwlAssertionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +// We can't simply cast to Self? in the catchInBlock method so we need this generic function wrapper to do the conversion for us. Mildly annoying. +private func catchReturnTypeConverter(_ type: T.Type, block: () -> Void) -> T? { + return catchExceptionOfKind(type, block) as? T +} + +extension NSException { + public static func catchException(in block: () -> Void) -> Self? { + return catchReturnTypeConverter(self, block: block) + } +} diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist new file mode 100644 index 0000000..f14cf1e --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlCatchException/CwlCatchException/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2016 Matt Gallagher. All rights reserved. + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift new file mode 100644 index 0000000..2fa67c9 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlBadInstructionException.swift @@ -0,0 +1,76 @@ +// +// CwlBadInstructionException.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +private func raiseBadInstructionException() { + BadInstructionException().raise() +} + +/// A simple NSException subclass. It's not required to subclass NSException (since the exception type is represented in the name) but this helps for identifying the exception through runtime type. +@objc public class BadInstructionException: NSException { + static var name: String = "com.cocoawithlove.BadInstruction" + + init() { + super.init(name: NSExceptionName(rawValue: BadInstructionException.name), reason: nil, userInfo: nil) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + /// An Objective-C callable function, invoked from the `mach_exc_server` callback function `catch_mach_exception_raise_state` to push the `raiseBadInstructionException` function onto the stack. + public class func catch_mach_exception_raise_state(_ exception_port: mach_port_t, exception: exception_type_t, code: UnsafePointer, codeCnt: mach_msg_type_number_t, flavor: UnsafeMutablePointer, old_state: UnsafePointer, old_stateCnt: mach_msg_type_number_t, new_state: thread_state_t, new_stateCnt: UnsafeMutablePointer) -> kern_return_t { + + #if arch(x86_64) + // Make sure we've been given enough memory + if old_stateCnt != x86_THREAD_STATE64_COUNT || new_stateCnt.pointee < x86_THREAD_STATE64_COUNT { + return KERN_INVALID_ARGUMENT + } + + // Read the old thread state + var state = old_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { return $0.pointee } + + // 1. Decrement the stack pointer + state.__rsp -= __uint64_t(MemoryLayout.size) + + // 2. Save the old Instruction Pointer to the stack. + if let pointer = UnsafeMutablePointer<__uint64_t>(bitPattern: UInt(state.__rsp)) { + pointer.pointee = state.__rip + } else { + return KERN_INVALID_ARGUMENT + } + + // 3. Set the Instruction Pointer to the new function's address + var f: @convention(c) () -> Void = raiseBadInstructionException + withUnsafePointer(to: &f) { + state.__rip = $0.withMemoryRebound(to: __uint64_t.self, capacity: 1) { return $0.pointee } + } + + // Write the new thread state + new_state.withMemoryRebound(to: x86_thread_state64_t.self, capacity: 1) { $0.pointee = state } + new_stateCnt.pointee = x86_THREAD_STATE64_COUNT + + return KERN_SUCCESS + #else + fatalError("Unavailable for this CPU architecture") + #endif + } +} diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h new file mode 100644 index 0000000..0333ed2 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.h @@ -0,0 +1,61 @@ +// +// CwlCatchBadInstruction.h +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if defined(__x86_64__) + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +// The request_mach_exception_raise_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. +typedef struct +{ + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; +} request_mach_exception_raise_t; + +// The reply_mach_exception_raise_state_t struct is passed to mach_msg which assumes its exact layout. To avoid problems with different layouts, we keep the definition in C rather than Swift. +typedef struct +{ + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; +} reply_mach_exception_raise_state_t; + +extern boolean_t mach_exc_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +NS_ASSUME_NONNULL_END + +#endif diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m new file mode 100644 index 0000000..22c1377 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.m @@ -0,0 +1,50 @@ +// +// CwlCatchBadInstruction.m +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +#if defined(__x86_64__) + +#import "CwlCatchBadInstruction.h" + +// Assuming the "PRODUCT_NAME" macro is defined, this will create the name of the Swift generated header file +#define STRINGIZE_NO_EXPANSION(A) #A +#define STRINGIZE_WITH_EXPANSION(A) STRINGIZE_NO_EXPANSION(A) +#define SWIFT_INCLUDE STRINGIZE_WITH_EXPANSION(PRODUCT_NAME-Swift.h) + +// Include the Swift generated header file +#import SWIFT_INCLUDE + +/// A basic function that receives callbacks from mach_exc_server and relays them to the Swift implemented BadInstructionException.catch_mach_exception_raise_state. +kern_return_t catch_mach_exception_raise_state(mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, const thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { + return [BadInstructionException catch_mach_exception_raise_state:exception_port exception:exception code:code codeCnt:codeCnt flavor:flavor old_state:old_state old_stateCnt:old_stateCnt new_state:new_state new_stateCnt:new_stateCnt]; +} + +// The mach port should be configured so that this function is never used. +kern_return_t catch_mach_exception_raise(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt) { + assert(false); + return KERN_FAILURE; +} + +// The mach port should be configured so that this function is never used. +kern_return_t catch_mach_exception_raise_state_identity(mach_port_t exception_port, mach_port_t thread, mach_port_t task, exception_type_t exception, mach_exception_data_t code, mach_msg_type_number_t codeCnt, int *flavor, thread_state_t old_state, mach_msg_type_number_t old_stateCnt, thread_state_t new_state, mach_msg_type_number_t *new_stateCnt) { + assert(false); + return KERN_FAILURE; +} + +#endif diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift new file mode 100644 index 0000000..ab460b3 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstruction.swift @@ -0,0 +1,194 @@ +// +// CwlCatchBadInstruction.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +#if arch(x86_64) + + private enum PthreadError: Error { case code(Int32) } + private enum MachExcServer: Error { case code(kern_return_t) } + + /// A quick function for converting Mach error results into Swift errors + private func kernCheck(_ f: () -> Int32) throws { + let r = f() + guard r == KERN_SUCCESS else { + throw NSError(domain: NSMachErrorDomain, code: Int(r), userInfo: nil) + } + } + + extension execTypesCountTuple { + mutating func pointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: T.self, capacity: EXC_TYPES_COUNT) { ptr -> R in + return block(ptr) + } + } + } + } + + extension request_mach_exception_raise_t { + mutating func withMsgHeaderPointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: mach_msg_header_t.self, capacity: 1) { ptr -> R in + return block(ptr) + } + } + } + } + + extension reply_mach_exception_raise_state_t { + mutating func withMsgHeaderPointer(in block: (UnsafeMutablePointer) -> R) -> R { + return withUnsafeMutablePointer(to: &self) { p -> R in + return p.withMemoryRebound(to: mach_msg_header_t.self, capacity: 1) { ptr -> R in + return block(ptr) + } + } + } + } + + /// A structure used to store context associated with the Mach message port + private struct MachContext { + var masks = execTypesCountTuple() + var count: mach_msg_type_number_t = 0 + var ports = execTypesCountTuple() + var behaviors = execTypesCountTuple() + var flavors = execTypesCountTuple() + var currentExceptionPort: mach_port_t = 0 + var handlerThread: pthread_t? = nil + + mutating func withUnsafeMutablePointers(in block: (UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer, UnsafeMutablePointer) -> R) -> R { + return masks.pointer { masksPtr in + return ports.pointer { portsPtr in + return behaviors.pointer { behaviorsPtr in + return flavors.pointer { flavorsPtr in + return block(masksPtr, portsPtr, behaviorsPtr, flavorsPtr) + } + } + } + } + } + } + + /// A function for receiving mach messages and parsing the first with mach_exc_server (and if any others are received, throwing them away). + private func machMessageHandler(_ arg: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer? { + let context = arg.assumingMemoryBound(to: MachContext.self).pointee + var request = request_mach_exception_raise_t() + var reply = reply_mach_exception_raise_state_t() + + var handledfirstException = false + repeat { do { + // Request the next mach message from the port + request.Head.msgh_local_port = context.currentExceptionPort + request.Head.msgh_size = UInt32(MemoryLayout.size) + try kernCheck { request.withMsgHeaderPointer { requestPtr in + mach_msg(requestPtr, MACH_RCV_MSG | MACH_RCV_INTERRUPT, 0, request.Head.msgh_size, context.currentExceptionPort, 0, UInt32(MACH_PORT_NULL)) + } } + + // Prepare the reply structure + reply.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(request.Head.msgh_bits), 0) + reply.Head.msgh_local_port = UInt32(MACH_PORT_NULL) + reply.Head.msgh_remote_port = request.Head.msgh_remote_port + reply.Head.msgh_size = UInt32(MemoryLayout.size) + reply.NDR = NDR_record + + if !handledfirstException { + // Use the MiG generated server to invoke our handler for the request and fill in the rest of the reply structure + guard request.withMsgHeaderPointer(in: { requestPtr in reply.withMsgHeaderPointer { replyPtr in + mach_exc_server(requestPtr, replyPtr) + } }) != 0 else { throw MachExcServer.code(reply.RetCode) } + + handledfirstException = true + } else { + // If multiple fatal errors occur, don't handle subsquent errors (let the program crash) + reply.RetCode = KERN_FAILURE + } + + // Send the reply + try kernCheck { reply.withMsgHeaderPointer { replyPtr in + mach_msg(replyPtr, MACH_SEND_MSG, reply.Head.msgh_size, 0, UInt32(MACH_PORT_NULL), 0, UInt32(MACH_PORT_NULL)) + } } + } catch let error as NSError where (error.domain == NSMachErrorDomain && (error.code == Int(MACH_RCV_PORT_CHANGED) || error.code == Int(MACH_RCV_INVALID_NAME))) { + // Port was already closed before we started or closed while we were listening. + // This means the controlling thread shut down. + return nil + } catch { + // Should never be reached but this is testing code, don't try to recover, just abort + fatalError("Mach message error: \(error)") + } } while true + } + + /// Run the provided block. If a mach "BAD_INSTRUCTION" exception is raised, catch it and return a BadInstructionException (which captures stack information about the throw site, if desired). Otherwise return nil. + /// NOTE: This function is only intended for use in test harnesses – use in a distributed build is almost certainly a bad choice. If a "BAD_INSTRUCTION" exception is raised, the block will be exited before completion via Objective-C exception. The risks associated with an Objective-C exception apply here: most Swift/Objective-C functions are *not* exception-safe. Memory may be leaked and the program will not necessarily be left in a safe state. + /// - parameter block: a function without parameters that will be run + /// - returns: if an EXC_BAD_INSTRUCTION is raised during the execution of `block` then a BadInstructionException will be returned, otherwise `nil`. + public func catchBadInstruction(in block: () -> Void) -> BadInstructionException? { + var context = MachContext() + var result: BadInstructionException? = nil + do { + var handlerThread: pthread_t? = nil + defer { + // 8. Wait for the thread to terminate *if* we actually made it to the creation point + // The mach port should be destroyed *before* calling pthread_join to avoid a deadlock. + if handlerThread != nil { + pthread_join(handlerThread!, nil) + } + } + + try kernCheck { + // 1. Create the mach port + mach_port_allocate(mach_task_self_, MACH_PORT_RIGHT_RECEIVE, &context.currentExceptionPort) + } + defer { + // 7. Cleanup the mach port + mach_port_destroy(mach_task_self_, context.currentExceptionPort) + } + + try kernCheck { + // 2. Configure the mach port + mach_port_insert_right(mach_task_self_, context.currentExceptionPort, context.currentExceptionPort, MACH_MSG_TYPE_MAKE_SEND) + } + + try kernCheck { context.withUnsafeMutablePointers { masksPtr, portsPtr, behaviorsPtr, flavorsPtr in + // 3. Apply the mach port as the handler for this thread + thread_swap_exception_ports(mach_thread_self(), EXC_MASK_BAD_INSTRUCTION, context.currentExceptionPort, Int32(bitPattern: UInt32(EXCEPTION_STATE) | MACH_EXCEPTION_CODES), x86_THREAD_STATE64, masksPtr, &context.count, portsPtr, behaviorsPtr, flavorsPtr) + } } + + defer { context.withUnsafeMutablePointers { masksPtr, portsPtr, behaviorsPtr, flavorsPtr in + // 6. Unapply the mach port + _ = thread_swap_exception_ports(mach_thread_self(), EXC_MASK_BAD_INSTRUCTION, 0, EXCEPTION_DEFAULT, THREAD_STATE_NONE, masksPtr, &context.count, portsPtr, behaviorsPtr, flavorsPtr) + } } + + try withUnsafeMutablePointer(to: &context) { c throws in + // 4. Create the thread + let e = pthread_create(&handlerThread, nil, machMessageHandler, c) + guard e == 0 else { throw PthreadError.code(e) } + + // 5. Run the block + result = BadInstructionException.catchException(in: block) + } + } catch { + // Should never be reached but this is testing code, don't try to recover, just abort + fatalError("Mach port error: \(error)") + } + return result + } + +#endif + diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift new file mode 100644 index 0000000..b3afb12 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlCatchBadInstructionPOSIX.swift @@ -0,0 +1,100 @@ +// +// CwlCatchBadInstructionPOSIX.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 8/02/2016. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Foundation + +#if arch(x86_64) + +// This file is an alternative implementation to CwlCatchBadInstruction.swift that uses a SIGILL signal action and setenv/longjmp instead of a Mach exception handler and Objective-C exception raising. +// +// WARNING: +// This code is quick and dirty. It's a proof of concept for using a SIGILL handler and setjmp/longjmp where Mach exceptions and the Obj-C runtime aren't available. I ran the automated tests when I first wrote this code but I don't personally use it at all so by the time you're reading this comment, it probably broke and I didn't notice. +// Obvious limitations: +// * It doesn't work when debugging with lldb. +// * It doesn't scope correctly to the thread (it's global) +// * In violation of rules for signal handlers, it writes to the "red zone" on the stack +// * It isn't re-entrant +// * Plus all of the same caveats as the Mach exceptions version (doesn't play well with other handlers, probably leaks ARC memory, etc) +// Treat it like a loaded shotgun. Don't point it at your face. + +private var env = jmp_buf(0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0) + +private func triggerLongJmp() { + longjmp(&env.0, 1) +} + +private func sigIllHandler(code: Int32, info: UnsafeMutablePointer<__siginfo>?, uap: UnsafeMutableRawPointer?) -> Void { + guard let context = uap?.assumingMemoryBound(to: ucontext64_t.self) else { return } + + // 1. Decrement the stack pointer + context.pointee.uc_mcontext64.pointee.__ss.__rsp -= __uint64_t(MemoryLayout.size) + + // 2. Save the old Instruction Pointer to the stack. + let rsp = context.pointee.uc_mcontext64.pointee.__ss.__rsp + if let ump = UnsafeMutablePointer<__uint64_t>(bitPattern: UInt(rsp)) { + ump.pointee = rsp + } + + // 3. Set the Instruction Pointer to the new function's address + var f: @convention(c) () -> Void = triggerLongJmp + withUnsafePointer(to: &f) { $0.withMemoryRebound(to: __uint64_t.self, capacity: 1) { ptr in + context.pointee.uc_mcontext64.pointee.__ss.__rip = ptr.pointee + } } +} + +/// Without Mach exceptions or the Objective-C runtime, there's nothing to put in the exception object. It's really just a boolean – either a SIGILL was caught or not. +public class BadInstructionException { +} + +/// Run the provided block. If a POSIX SIGILL is received, handle it and return a BadInstructionException (which is just an empty object in this POSIX signal version). Otherwise return nil. +/// NOTE: This function is only intended for use in test harnesses – use in a distributed build is almost certainly a bad choice. If a SIGILL is received, the block will be interrupted using a C `longjmp`. The risks associated with abrupt jumps apply here: most Swift functions are *not* interrupt-safe. Memory may be leaked and the program will not necessarily be left in a safe state. +/// - parameter block: a function without parameters that will be run +/// - returns: if an SIGILL is raised during the execution of `block` then a BadInstructionException will be returned, otherwise `nil`. +public func catchBadInstruction( block: () -> Void) -> BadInstructionException? { + // Construct the signal action + var sigActionPrev = sigaction() + let action = __sigaction_u(__sa_sigaction: sigIllHandler) + var sigActionNew = sigaction(__sigaction_u: action, sa_mask: sigset_t(), sa_flags: SA_SIGINFO) + + // Install the signal action + if sigaction(SIGILL, &sigActionNew, &sigActionPrev) != 0 { + fatalError("Sigaction error: \(errno)") + } + + defer { + // Restore the previous signal action + if sigaction(SIGILL, &sigActionPrev, nil) != 0 { + fatalError("Sigaction error: \(errno)") + } + } + + // Prepare the jump point + if setjmp(&env.0) != 0 { + // Handle jump received + return BadInstructionException() + } + + // Run the block + block() + + return nil +} + +#endif diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift new file mode 100644 index 0000000..12a6b9f --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/CwlDarwinDefinitions.swift @@ -0,0 +1,63 @@ +// +// CwlDarwinDefinitions.swift +// CwlPreconditionTesting +// +// Created by Matt Gallagher on 2016/01/10. +// Copyright © 2016 Matt Gallagher ( http://cocoawithlove.com ). All rights reserved. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +// IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// + +import Darwin + +#if arch(x86_64) + +// From /usr/include/mach/port.h +// #define MACH_PORT_RIGHT_RECEIVE ((mach_port_right_t) 1) +let MACH_PORT_RIGHT_RECEIVE: mach_port_right_t = 1 + +// From /usr/include/mach/message.h +// #define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */ +// #define MACH_MSGH_BITS_REMOTE(bits) \ +// ((bits) & MACH_MSGH_BITS_REMOTE_MASK) +// #define MACH_MSGH_BITS(remote, local) /* legacy */ \ +// ((remote) | ((local) << 8)) +let MACH_MSG_TYPE_MAKE_SEND: UInt32 = 20 +func MACH_MSGH_BITS_REMOTE(_ bits: UInt32) -> UInt32 { return bits & UInt32(MACH_MSGH_BITS_REMOTE_MASK) } +func MACH_MSGH_BITS(_ remote: UInt32, _ local: UInt32) -> UInt32 { return ((remote) | ((local) << 8)) } + +// From /usr/include/mach/exception_types.h +// #define EXC_BAD_INSTRUCTION 2 /* Instruction failed */ +// #define EXC_MASK_BAD_INSTRUCTION (1 << EXC_BAD_INSTRUCTION) +// #define EXCEPTION_DEFAULT 1 +let EXC_BAD_INSTRUCTION: UInt32 = 2 +let EXC_MASK_BAD_INSTRUCTION: UInt32 = 1 << EXC_BAD_INSTRUCTION +let EXCEPTION_DEFAULT: Int32 = 1 + +// From /usr/include/mach/i386/thread_status.h +// #define THREAD_STATE_NONE 13 +// #define x86_THREAD_STATE64_COUNT ((mach_msg_type_number_t) \ +// ( sizeof (x86_thread_state64_t) / sizeof (int) )) +let THREAD_STATE_NONE: Int32 = 13 +let x86_THREAD_STATE64_COUNT = UInt32(MemoryLayout.size / MemoryLayout.size) + +let EXC_TYPES_COUNT = 14 +struct execTypesCountTuple { + // From /usr/include/mach/i386/exception.h + // #define EXC_TYPES_COUNT 14 /* incl. illegal exception 0 */ + var value: (T,T,T,T,T,T,T,T,T,T,T,T,T,T) = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + init() { + } +} + +#endif diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist new file mode 100644 index 0000000..f14cf1e --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2016 Matt Gallagher. All rights reserved. + NSPrincipalClass + + + diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c new file mode 100644 index 0000000..2334538 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.c @@ -0,0 +1,537 @@ +/* + * IDENTIFICATION: + * stub generated Mon Jan 11 00:24:26 2016 + * with a MiG generated by bootstrap_cmds-93 + * OPTIONS: + */ + +/* Module mach_exc */ + +#if defined(__x86_64__) + +#define __MIG_check__Request__mach_exc_subsystem__ 1 + +#include "mach_excServer.h" + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __DeclareRcvRpc +#define __DeclareRcvRpc(_NUM_, _NAME_) +#endif /* __DeclareRcvRpc */ + +#ifndef __BeforeRcvRpc +#define __BeforeRcvRpc(_NUM_, _NAME_) +#endif /* __BeforeRcvRpc */ + +#ifndef __AfterRcvRpc +#define __AfterRcvRpc(_NUM_, _NAME_) +#endif /* __AfterRcvRpc */ + +#ifndef __DeclareRcvSimple +#define __DeclareRcvSimple(_NUM_, _NAME_) +#endif /* __DeclareRcvSimple */ + +#ifndef __BeforeRcvSimple +#define __BeforeRcvSimple(_NUM_, _NAME_) +#endif /* __BeforeRcvSimple */ + +#ifndef __AfterRcvSimple +#define __AfterRcvSimple(_NUM_, _NAME_) +#endif /* __AfterRcvSimple */ + +#define novalue void + +#define msgh_request_port msgh_local_port +#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) +#define msgh_reply_port msgh_remote_port +#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) + +#define MIG_RETURN_ERROR(X, code) {\ + ((mig_reply_error_t *)X)->RetCode = code;\ + ((mig_reply_error_t *)X)->NDR = NDR_record;\ + return;\ + } + +/* Forward Declarations */ + + +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_t__defined) +#define __MIG_check__Request__mach_exception_raise_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) +{ + + typedef __Request__mach_exception_raise_t __Request; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 16)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 16)) / 8 < In0P->codeCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 16) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise */ +mig_internal novalue _Xmach_exception_raise + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_t __Request; + typedef __Reply__mach_exception_raise_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_t__defined */ + + __DeclareRcvRpc(2405, "mach_exception_raise") + __BeforeRcvRpc(2405, "mach_exception_raise") + +#if defined(__MIG_check__Request__mach_exception_raise_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_t((__Request *)In0P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ + + OutP->RetCode = catch_mach_exception_raise(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); + + OutP->NDR = NDR_record; + + + __AfterRcvRpc(2405, "mach_exception_raise") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state */ +mig_internal novalue _Xmach_exception_raise_state + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_t __Request; + typedef __Reply__mach_exception_raise_state_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ + + __DeclareRcvRpc(2406, "mach_exception_raise_state") + __BeforeRcvRpc(2406, "mach_exception_raise_state") + +#if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2406, "mach_exception_raise_state") +} + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_identity_t__defined + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_identity_t __Request; + __Request *In1P; +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + +#if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); +#if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 912) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; +#endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + +#if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ +#if __MigTypeCheck + if ( In1P->old_stateCnt > 224 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 912)) / 4 < In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 912) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine mach_exception_raise_state_identity */ +mig_internal novalue _Xmach_exception_raise_state_identity + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + typedef __Request__mach_exception_raise_state_identity_t __Request; + typedef __Reply__mach_exception_raise_state_identity_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ + + __DeclareRcvRpc(2407, "mach_exception_raise_state_identity") + __BeforeRcvRpc(2407, "mach_exception_raise_state_identity") + +#if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_identity_t((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ + + OutP->new_stateCnt = 224; + + OutP->RetCode = catch_mach_exception_raise_state_identity(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 896) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2407, "mach_exception_raise_state_identity") +} + + + +/* Description of this subsystem, for use in direct RPC */ +const struct catch_mach_exc_subsystem catch_mach_exc_subsystem = { + mach_exc_server_routine, + 2405, + 2408, + (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), + (vm_address_t)0, + { + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state_identity, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, + } +}; + +mig_external boolean_t mach_exc_server + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + register mig_routine_t routine; + + OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); + OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; + /* Minimal size: routine() will update it if different */ + OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); + OutHeadP->msgh_local_port = MACH_PORT_NULL; + OutHeadP->msgh_id = InHeadP->msgh_id + 100; + + if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || + ((routine = catch_mach_exc_subsystem.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) { + ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; + ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; + return FALSE; + } + (*routine) (InHeadP, OutHeadP); + return TRUE; +} + +mig_external mig_routine_t mach_exc_server_routine + (mach_msg_header_t *InHeadP) +{ + register int msgh_id; + + msgh_id = InHeadP->msgh_id - 2405; + + if ((msgh_id > 2) || (msgh_id < 0)) + return 0; + + return catch_mach_exc_subsystem.routine[msgh_id].stub_routine; +} + +#endif + diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h new file mode 100644 index 0000000..766ba11 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/CwlPreconditionTesting/mach_excServer.h @@ -0,0 +1,298 @@ +#ifndef _mach_exc_server_ +#define _mach_exc_server_ + +/* Module mach_exc */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN VOUCHER CODE */ + +#ifndef KERNEL +#if defined(__has_include) +#if __has_include() +#ifndef USING_VOUCHERS +#define USING_VOUCHERS +#endif +#ifndef __VOUCHER_FORWARD_TYPE_DECLS__ +#define __VOUCHER_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif + extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif // __VOUCHER_FORWARD_TYPE_DECLS__ +#endif // __has_include() +#endif // __has_include +#endif // !KERNEL + +/* END VOUCHER CODE */ + + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_exc_MSG_COUNT +#define mach_exc_MSG_COUNT 3 +#endif /* mach_exc_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigServerHeader +__BeforeMigServerHeader +#endif /* __BeforeMigServerHeader */ + + +/* Routine mach_exception_raise */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine mach_exception_raise_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state_identity */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state_identity +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +boolean_t mach_exc_server( + mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +mig_routine_t mach_exc_server_routine( + mach_msg_header_t *InHeadP); + + +/* Description of this subsystem, for use in direct RPC */ +extern const struct catch_mach_exc_subsystem { + mig_server_routine_t server; /* Server routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + unsigned int maxsize; /* Max msg size */ + vm_address_t reserved; /* Reserved */ + struct routine_descriptor /*Array of routine descriptors */ + routine[3]; +} catch_mach_exc_subsystem; + +/* typedefs for all requests */ + +#ifndef __Request__mach_exc_subsystem__defined +#define __Request__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } __Request__mach_exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[224]; + } __Request__mach_exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_exc_subsystem__defined */ + + +/* union of all requests */ + +#ifndef __RequestUnion__catch_mach_exc_subsystem__defined +#define __RequestUnion__catch_mach_exc_subsystem__defined +union __RequestUnion__catch_mach_exc_subsystem { + __Request__mach_exception_raise_t Request_mach_exception_raise; + __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; + __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_exc_subsystem__defined +#define __Reply__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[224]; + } __Reply__mach_exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_exc_subsystem__defined */ + + +/* union of all replies */ + +#ifndef __ReplyUnion__catch_mach_exc_subsystem__defined +#define __ReplyUnion__catch_mach_exc_subsystem__defined +union __ReplyUnion__catch_mach_exc_subsystem { + __Reply__mach_exception_raise_t Reply_mach_exception_raise; + __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; + __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_exc +#define subsystem_to_name_map_mach_exc \ + { "mach_exception_raise", 2405 },\ + { "mach_exception_raise_state", 2406 },\ + { "mach_exception_raise_state_identity", 2407 } +#endif + +#ifdef __AfterMigServerHeader +__AfterMigServerHeader +#endif /* __AfterMigServerHeader */ + +#endif /* _mach_exc_server_ */ diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/README.md b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/README.md new file mode 100644 index 0000000..a1a9a70 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Lib/CwlPreconditionTesting/README.md @@ -0,0 +1,80 @@ +# CwlPreconditionTesting + +A Mach exception handler, written in Swift and Objective-C, that allows `EXC_BAD_INSTRUCTION` (as raised by Swift's `assertionFailure`/`preconditionFailure`/`fatalError`) to be caught and tested. + +For an extended discussion of this code, please see the Cocoa with Love article: + +[Partial functions in Swift, Part 2: Catching precondition failures](http://cocoawithlove.com/blog/2016/02/02/partial-functions-part-two-catching-precondition-failures.html) + +## Usage + +The short version is: + +1. `git clone https://github.com/mattgallagher/CwlPreconditionTesting.git` +2. drag the "CwlPreconditionTesting.xcodeproj" file into your project's file tree in Xcode +3. go to your testing target's Build Phase settings and under "Target Dependencies" press the "+" button and select the relevant "CwlPreconditionTesting" target ("_iOS" or "_OSX", depending on your testing target's SDK) +4. write `import CwlPreconditionTesting` at the top of any test file where you want to use `catchBadInstruction` (Swift should handle the linkage automatically when you do this) +5. use the `catchBadInstruction` function as shown in the [CwlCatchBadInstructionTests.swift tests file](https://github.com/mattgallagher/CwlPreconditionTesting/blob/master/CwlPreconditionTestingTests/CwlCatchBadInstructionTests.swift?ts=4) + +### Project details + +The "CwlPreconditionTesting.xcodeproj" contains two targets: + +* CwlPreconditionTesting_OSX +* CwlPreconditionTesting_iOS + +both build a framework named "CwlPreconditionTesting.framework". If you're linking manually, be certain to select the "CwlPreconditionTesting.framework" from the appropriate target. + +Remember: the iOS build is useful only in the simulator. All Mach exception handling code will be conditionally excluded in any device build. + +### Static inclusion + +Due to the complications associated with needing to call into and out of Objective-C, static inclusion in other projects is not a single file nor a quick drag and drop. There's at least 7 files and you'll need to add some project settings. + +All of the following files: + +* CwlCatchBadInstruction.swift +* CwlCatchBadInstruction.h +* CwlCatchBadInstruction.m +* CwlCatchException.swift +* CwlCatchException.h +* CwlCatchException.m + +and either: + +* $(SDKROOT)/usr/include/mach/mach_exc.defs +* mach_excServer.c + +need to be added to the testing target for OS X projects or iOS projects, respectively. + +Your target will also need to have the following macros defined in the "Apple LLVM - Preprocessing" → "Preprocessor Macros" build setting: + + PRODUCT_NAME=$(PRODUCT_NAME) + +This lets the Objective-C file generate the include directive for the autogenerated Swift header so it can call back into Swift during the Mach exception handler callbacks. This macro should stay in sync if you change the target name but if you do anything else in your project that changes the name of the autogenerated Swift header independent of the target name (or you want to add spaces or other command-line complications to the target name), you'll want to update "CwlCatchBadInstruction.m" directly with the correct include directive. + +Additionally, you'll need a standard Objective-C "Bridging header" for your testing target and it will need to include the following import statements: + +``` +#if defined(__x86_64__) +#import +#endif + +#import +``` + +### Using POSIX signals and setjmp/longjmp + +For comparison or for anyone running this code on a platform without Mach exceptions or the Objective-C runtime, I've added a proof-of-concept implementation of `catchBadInstruction` that uses a POSIX SIGILL `sigaction` and `setjmp`/`longjmp` to perform the throw. + +In Xcode, you can simply select the CwlPreconditionTesting_POSIX target (instead of the OSX or iOS targets). If you're building without Xcode: all you need is the CwlCatchBadInstructionPOSIX.swift file (compared to the Mach exception handler, the code is tiny doesn't have any weird Objective-C/MiG file dependencies). + +**Warning No. 1**: on OS X, this approach can't be used when lldb is attached since lldb's Mach exception handler blocks the SIGILL from ever occurring (I've disabled the "Debug Executable" setting for the tests in Xcode - re-enable it to witness the problem). + +**Warning No. 2**: if you're switching between the CwlPreconditionTesting_OSX and CwlPreconditionTesting_POSIX targets, Xcode (as of Xcode 7.2.1) will not detect the change and will not remove the old framework correctly so you'll need to *clean your project* otherwise the old framework will hang around. + +Additional problems in decreasing severity include: + +* the signal handler is whole process (rather than correctly scoped to the thread where the "catch" occurs) +* the signal handler doesn't deal with re-entrancy whereas the mach exception handler remains deterministic in the face of multiple fatal errors +* the signal handler overwrites the "[red zone](https://en.wikipedia.org/wiki/Red_zone_(computing))" which is technically frowned upon in signal handlers (although unlikely to cause problems here) diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift new file mode 100644 index 0000000..67f9cf6 --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Sources/Nimble/Matchers/ThrowAssertion.swift @@ -0,0 +1,55 @@ +import Foundation + +public func throwAssertion() -> MatcherFunc { + return MatcherFunc { actualExpression, failureMessage in + #if arch(x86_64) && _runtime(_ObjC) && !SWIFT_PACKAGE + failureMessage.postfixMessage = "throw an assertion" + failureMessage.actualValue = nil + + var succeeded = true + + let caughtException: BadInstructionException? = catchBadInstruction { + #if os(tvOS) + if (!NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning) { + print() + print("[Nimble Warning]: If you're getting stuck on a debugger breakpoint for a " + + "fatal error while using throwAssertion(), please disable 'Debug Executable' " + + "in your scheme. Go to 'Edit Scheme > Test > Info' and uncheck " + + "'Debug Executable'. If you've already done that, suppress this warning " + + "by setting `NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true`. " + + "This is required because the standard methods of catching assertions " + + "(mach APIs) are unavailable for tvOS. Instead, the same mechanism the " + + "debugger uses is the fallback method for tvOS." + ) + print() + NimbleEnvironment.activeInstance.suppressTVOSAssertionWarning = true + } + #endif + do { + try actualExpression.evaluate() + } catch let error { + succeeded = false + failureMessage.postfixMessage += "; threw error instead <\(error)>" + } + } + + if !succeeded { + return false + } + + if caughtException == nil { + return false + } + + return true + #elseif SWIFT_PACKAGE + fatalError("The throwAssertion Nimble matcher does not currently support Swift CLI." + + " You can silence this error by placing the test case inside an #if !SWIFT_PACKAGE" + + " conditional statement") + #else + fatalError("The throwAssertion Nimble matcher can only run on x86_64 platforms with " + + "Objective-C (e.g. Mac, iPhone 5s or later simulators). You can silence this error " + + "by placing the test case inside an #if arch(x86_64) or _runtime(_ObjC) conditional statement") + #endif + } +} diff --git a/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift new file mode 100644 index 0000000..c227b1b --- /dev/null +++ b/Carthage/Checkouts/Quick/Externals/Nimble/Tests/NimbleTests/Matchers/ThrowAssertionTest.swift @@ -0,0 +1,62 @@ +import Foundation +import XCTest +import Nimble + +#if _runtime(_ObjC) && !SWIFT_PACKAGE + +final class ThrowAssertionTest: XCTestCase, XCTestCaseProvider { + static var allTests: [(String, (ThrowAssertionTest) -> () throws -> Void)] { + return [ + ("testPositiveMatch", testPositiveMatch), + ("testErrorThrown", testErrorThrown), + ("testPostAssertionCodeNotRun", testPostAssertionCodeNotRun), + ("testNegativeMatch", testNegativeMatch), + ("testPositiveMessage", testPositiveMessage), + ("testNegativeMessage", testNegativeMessage), + ] + } + + func testPositiveMatch() { + expect { () -> Void in fatalError() }.to(throwAssertion()) + } + + func testErrorThrown() { + expect { throw NSError(domain: "test", code: 0, userInfo: nil) }.toNot(throwAssertion()) + } + + func testPostAssertionCodeNotRun() { + var reachedPoint1 = false + var reachedPoint2 = false + + expect { + reachedPoint1 = true + precondition(false, "condition message") + reachedPoint2 = true + }.to(throwAssertion()) + + expect(reachedPoint1) == true + expect(reachedPoint2) == false + } + + func testNegativeMatch() { + var reachedPoint1 = false + + expect { reachedPoint1 = true }.toNot(throwAssertion()) + + expect(reachedPoint1) == true + } + + func testPositiveMessage() { + failsWithErrorMessage("expected to throw an assertion") { + expect { () -> Void? in return }.to(throwAssertion()) + } + } + + func testNegativeMessage() { + failsWithErrorMessage("expected to not throw an assertion") { + expect { () -> Void in fatalError() }.toNot(throwAssertion()) + } + } +} + +#endif diff --git a/Carthage/Checkouts/Quick/Sources/Quick/URL+FileName.swift b/Carthage/Checkouts/Quick/Sources/Quick/URL+FileName.swift new file mode 100644 index 0000000..23c4781 --- /dev/null +++ b/Carthage/Checkouts/Quick/Sources/Quick/URL+FileName.swift @@ -0,0 +1,12 @@ +import Foundation + +extension URL { + + /** + Returns the path file name without file extension. + */ + var fileName: String { + return self.deletingPathExtension().lastPathComponent + } + +} diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests+ObjC.m b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests+ObjC.m new file mode 100644 index 0000000..cd3522d --- /dev/null +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests+ObjC.m @@ -0,0 +1,32 @@ +@import XCTest; +@import Quick; +@import Nimble; + +static BOOL afterSuiteFirstTestExecuted = NO; +static BOOL afterSuiteTestsWasExecuted = NO; + +@interface AfterSuiteTests_ObjC : QuickSpec + +@end + +@implementation AfterSuiteTests_ObjC + +- (void)spec { + it(@"is executed before afterSuite", ^{ + expect(@(afterSuiteTestsWasExecuted)).to(beFalsy()); + }); + + afterSuite(^{ + afterSuiteTestsWasExecuted = YES; + }); +} + ++ (void)tearDown { + if (afterSuiteFirstTestExecuted) { + assert(afterSuiteTestsWasExecuted); + } else { + afterSuiteFirstTestExecuted = true; + } +} + +@end diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests.swift b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests.swift new file mode 100644 index 0000000..ea4fc3e --- /dev/null +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/AfterSuiteTests.swift @@ -0,0 +1,26 @@ +import XCTest +import Quick +import Nimble + +var afterSuiteFirstTestExecuted = false +var afterSuiteTestsWasExecuted = false + +class AfterSuiteTests: QuickSpec { + override func spec() { + afterSuite { + afterSuiteTestsWasExecuted = true + } + + it("is executed before afterSuite") { + expect(afterSuiteTestsWasExecuted).to(beFalsy()) + } + } + + override class func tearDown() { + if afterSuiteFirstTestExecuted { + assert(afterSuiteTestsWasExecuted, "afterSuiteTestsWasExecuted needs to be true") + } else { + afterSuiteFirstTestExecuted = true + } + } +} diff --git a/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/Info.plist b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/Info.plist new file mode 100644 index 0000000..ba72822 --- /dev/null +++ b/Carthage/Checkouts/Quick/Tests/QuickTests/QuickAfterSuiteTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/SwinjectAutoregistration.podspec b/SwinjectAutoregistration.podspec index 68c2da3..369ec81 100644 --- a/SwinjectAutoregistration.podspec +++ b/SwinjectAutoregistration.podspec @@ -6,7 +6,7 @@ Pod::Spec.new do |s| SwinjectAutoregistration is an extension of Swinject to automatically inject dependency into registered services. DESC - s.homepage = 'https://gitlab.ack.ee/Ackee/ACKSwinject' + s.homepage = 'https://github.com/Swinject/SwinjectAutoregistration' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = 'Swinject Contributors' s.source = { :git => 'https://github.com/Swinject/SwinjectAutoregistration', :tag => s.version.to_s } From 1b1a2da153681ca20b58f9534e0861160d1abc2d Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 29 Jan 2017 12:37:23 +0100 Subject: [PATCH 12/23] Readme update, version bump --- README.md | 99 ++++++++++++++++++-------------- Sources/Info.plist | 2 +- SwinjectAutoregistration.podspec | 4 +- 3 files changed, 60 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index ed504a2..7fb69c4 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ SwinjectAutoregistration ======== -[![Build Status](https://travis-ci.org/Swinject/SwinjectStoryboard.svg?branch=master)](https://travis-ci.org/Swinject/SwinjectAutoregistration) +[![Build Status](https://travis-ci.org/Swinject/SwinjectAutoregistration.svg?branch=master)](https://travis-ci.org/Swinject/SwinjectAutoregistration) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) [![CocoaPods Version](https://img.shields.io/cocoapods/v/SwinjectAutoregistration.svg?style=flat)](http://cocoapods.org/pods/SwinjectAutoregistration) [![License](https://img.shields.io/cocoapods/l/SwinjectAutoregistration.svg?style=flat)](http://cocoapods.org/pods/SwinjectAutoregistration) [![Platform](https://img.shields.io/cocoapods/p/SwinjectAutoregistration.svg?style=flat)](http://cocoapods.org/pods/SwinjectAutoregistration) [![Swift Version](https://img.shields.io/badge/Swift-3-F16D39.svg?style=flat)](https://developer.apple.com/swift) -SwinjectAutoregistration is an extension of Swinject that allows to automatically register your services and greatly reduces the amount of boilerplate. +SwinjectAutoregistration is an extension of Swinject that allows to automatically register your services and greatly reduce the amount of boilerplate code. ## Requirements @@ -24,8 +24,8 @@ Swinject is available through [Carthage](https://github.com/Carthage/Carthage) o To install Swinject with Carthage, add the following line to your `Cartfile`. ``` -github "Swinject/Swinject" "2.0.0-beta.2" -github "Swinject/SwinjectAutoregistration" "1.0.0-beta.2" +github "Swinject/Swinject" "2.0.0" +github "Swinject/SwinjectAutoregistration" "2.0.0" ``` Then run `carthage update --no-use-binaries` command or just `carthage update`. For details of the installation and usage of Carthage, visit [its project page](https://github.com/Carthage/Carthage). @@ -39,8 +39,8 @@ source 'https://github.com/CocoaPods/Specs.git' platform :ios, '8.0' # or platform :osx, '10.10' if your target is OS X. use_frameworks! -pod 'Swinject', '2.0.0-beta.2' -pod 'SwinjectAutoregistration', '1.0.0-beta.2' +pod 'Swinject', '2.0.0' +pod 'SwinjectAutoregistration', '2.0.0' ``` Then run `pod install` command. For details of the installation and usage of CocoaPods, visit [its official website](https://cocoapods.org). @@ -51,11 +51,23 @@ Here is a simple example to auto-register a pet owner ```swift let container = Container() -container.register(AnimalType.self) { _ in Cat(name: "Mimi") } +container.register(Animal.self) { _ in Cat(name: "Mimi") } container.autoregister(PersonType.self, initializer: PetOwner.init) ``` -That's it. The `autoregister` function is given the `PetOwner` initializer `init(pet:AnimalType)`. From its signature Swinject knows that it needs a dependency `AnimalType` and resolves it from the container. Nothing else is needed. For comparison, this is equivalent code in pure Swinject: +where PetOwner looks like this: + +```swift +class PetOwner: Person { + let pet: Animal + + init(pet: Animal) { + self.pet = pet + } +} +``` + +That's it. The `autoregister` function is given the `PetOwner` initializer `init(pet:Animal)`. From its signature Swinject knows that it needs a dependency `Animal` and resolves it from the container. Nothing else is needed. For comparison, this is equivalent code in pure Swinject: ```swift container.register(PersonType.self) { r in @@ -63,22 +75,22 @@ container.register(PersonType.self) { r in } ``` #### Registration with name -Service can be also given name same as with the regular register. +Service can be also given name - same as with the regular register method. ```swift -container.autoregister(PersonType.self, name: "johnny", initializer: PetOwner.init) +container.autoregister(Person.self, name: "johnny", initializer: PetOwner.init) ``` #### Arguments -You can also use auto-registration for services with dynamic arguments. Pet owner which name needs to be passed as argument is defined like this: +You can also use auto-registration for services with dynamic arguments. Pet owner whose name needs to be passed as argument is defined like this: ```swift -class PetOwner: PersonType { +class PetOwner: Person { let name: String - let pet: AnimalType + let pet: Animal - init(name: String, pet: AnimalType) { + init(name: String, pet: Animal) { self.name = name self.pet = pet } @@ -88,10 +100,10 @@ class PetOwner: PersonType { And registered like this ```swift -container.autoregister(PersonType.self, argument: String.self, initializer: PetOwner.init) +container.autoregister(Person.self, argument: String.self, initializer: PetOwner.init) ``` -Swinject will register `PersonType` with the argument of type `String`. When `container.resolve(PersonType.self, argument: "Michael")` is called Swinject won't try to resolve `String` as dependency but instead pass "Michael" as the name. +Swinject will register `Person` with the argument of type `String`. When `container.resolve(Person.self, argument: "Michael")` is called Swinject won't try to resolve `String` as dependency but instead pass "Michael" as the name. To also pass pet as argument you can call @@ -118,32 +130,6 @@ public func autoregister(_ service: Service.Type, initializer: (A The initializer is a function like any other. By passing it as a parameter its dependencies can be infered as `(A, B)` and automatically resolved. These functions are generated for up to 9 dependencies. Checkout the [code](https://github.com/Swinject/SwinjectAutoregistration/blob/master/Sources/AutoRegistration.swift) for more info. -### Limitations ### -When a service has multiple initializers, swift compiler can't be sure which should be used and you will get a `ambigious use of init(x: y: z:)`. This can also happen if the service is extending another class that have initializer with the same number of arguments. - -The solution is to specify the initializer like this: - -``` -container.autoregister(PersonType.self, initializer: PetOwner.init(name:pet:)) -``` - - - - -There are also cases where auto-registration **can't** be used: - - * Can't use services with **optional dependencies** in their initializers - * e.g: `PersonOwner(name:String, pet: AnimalType?)` - * Can't use services with **named dependencies** in their initializers - * There is no way to get a name of dependency from the initializer. For example, following code can't be auto-registered: - - ```swift - container.register(AnimalType.self, name: "mimi") { _ in Cat(name: "Mimi") } - container.register(PersonType.self) { - PetOwner(pet: r.resolve(AnimalType.self, name: "mimi") - } - ``` - ### Operators ### This extension also aims to reduce the amount of boilerplate while improving readability of the registration code. For that reason the operator `~>` is introduced. @@ -175,6 +161,35 @@ Petowner(pet: r ~> (Cat.self, arguments: "Mimi", UIColor.black)) ``` +### Limitations ### +When a service has multiple initializers, swift compiler can't be sure which should be used and you will get a `ambigious use of init(x: y: z:)`. This can also happen if the service is extending another class that have initializer with the same number of arguments. + +The solution is to specify the initializer like this: + +``` +container.autoregister(Person.self, initializer: PetOwner.init(name:pet:)) +``` + + + + +There are also cases where auto-registration **can't** be used: + + * Can't use services with **optional dependencies** in their initializers + * e.g: `PersonOwner(name:String, pet: AnimalType?)` + * Can't use services with **implicitly unwrapped dependencies** in their initializers + * e.g: `PersonOwner(name:String, pet: AnimalType!)` + * Can't use services with **named dependencies** in their initializers + * There is no way to get a name of dependency from the initializer. For example, following code can't be auto-registered: + + ```swift + container.register(AnimalType.self, name: "mimi") { _ in Cat(name: "Mimi") } + container.register(AnimalType.self, name: "charles") { _ in Cat(name: "Charles") } + container.register(PersonType.self) { + PetOwner(pet: r.resolve(AnimalType.self, name: "mimi") + } + ``` + ## Credits SwinjectAutoregistration generics is inspired by: diff --git a/Sources/Info.plist b/Sources/Info.plist index 2203ab6..12d8569 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 1.0 + 2.0 CFBundleSignature ???? CFBundleVersion diff --git a/SwinjectAutoregistration.podspec b/SwinjectAutoregistration.podspec index 369ec81..ad4d753 100644 --- a/SwinjectAutoregistration.podspec +++ b/SwinjectAutoregistration.podspec @@ -3,7 +3,7 @@ Pod::Spec.new do |s| s.version = '2.0.0' s.summary = 'Autoregistration for Swinject' s.description = <<-DESC -SwinjectAutoregistration is an extension of Swinject to automatically inject dependency into registered services. +SwinjectAutoregistration is an extension of Swinject that allows to automatically inject dependencies into registered services. DESC s.homepage = 'https://github.com/Swinject/SwinjectAutoregistration' @@ -15,5 +15,5 @@ SwinjectAutoregistration is an extension of Swinject to automatically inject dep s.source_files = 'Sources/**/*' - s.dependency 'Swinject', '~> 2.0.0-beta.2' + s.dependency 'Swinject', '~> 2.0.0' end From 41bc9199fb8f685c18fccb074470260884b49aa3 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 29 Jan 2017 13:52:02 +0100 Subject: [PATCH 13/23] Added pm tests, updated .travis.yml --- .Package.test.swift | 9 +++++++++ .travis.yml | 49 ++++++++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 12 deletions(-) create mode 100644 .Package.test.swift diff --git a/.Package.test.swift b/.Package.test.swift new file mode 100644 index 0000000..1a47260 --- /dev/null +++ b/.Package.test.swift @@ -0,0 +1,9 @@ +import PackageDescription + +let package = Package( + name: "Swinject", + dependencies: [ + .Package(url: "https://github.com/Quick/Quick", majorVersion: 1), + .Package(url: "https://github.com/Quick/Nimble", majorVersion: 5, minor: 1), + ] +) diff --git a/.travis.yml b/.travis.yml index 6123247..0093005 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,39 @@ -# references: -# * http://www.objc.io/issue-6/travis-ci.html -# * https://github.com/supermarin/xcpretty#usage - -osx_image: xcode7.3 language: objective-c -# cache: cocoapods -# podfile: Example/Podfile -# before_install: -# - gem install cocoapods # Since Travis is not always on latest version -# - pod install --project-directory=Example +osx_image: xcode8.1 +env: + global: + - LC_CTYPE=en_US.UTF-8 + - PROJECT=SwinjectAutoregistration.xcodeproj +git: + submodules: false +matrix: + include: + - env: JOB="LINUX_SPM" + os: linux + language: generic + sudo: required + dist: trusty + before_install: + - eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/9f442512a46d7a2af7b850d65a7e9bd31edfb09b/swiftenv-install.sh)" + script: + - mv .Package.test.swift Package.swift + - swift build + - swift test + - env: JOB="POD_LINT" + script: + - pod lib lint + - env: JOB="XCODE" DEST="OS=8.4,name=iPhone 5" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" + - env: JOB="XCODE" DEST="OS=9.3,name=iPhone 6" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" + - env: JOB="XCODE" DEST="OS=10.1,name=iPhone 7 Plus" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" + - env: JOB="XCODE" DEST="arch=x86_64" SCHEME="SwinjectAutoregistration-OSX" SDK="macosx" ACTION="test" + - env: JOB="XCODE" DEST="OS=9.2,name=Apple TV 1080p" SCHEME="SwinjectAutoregistration-tvOS" SDK="appletvsimulator" ACTION="test" + - env: JOB="XCODE" DEST="OS=10.0,name=Apple TV 1080p" SCHEME="SwinjectAutoregistration-tvOS" SDK="appletvsimulator" ACTION="test" + - env: JOB="XCODE" DEST="OS=2.2,name=Apple Watch - 42mm" SCHEME="SwinjectAutoregistration-watchOS" SDK="watchsimulator" ACTION="build" + - env: JOB="XCODE" DEST="OS=3.1,name=Apple Watch - 42mm" SCHEME="SwinjectAutoregistration-watchOS" SDK="watchsimulator" ACTION="build" script: -- set -o pipefail && xcodebuild test -workspace Example/ACKSwinject.xcworkspace -scheme ACKSwinject-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty -- pod lib lint + - set -o pipefail + - open -b com.apple.iphonesimulator # Workaround https://github.com/travis-ci/travis-ci/issues/3040 + - xcodebuild "$ACTION" -project "$PROJECT" -scheme "$SCHEME" -sdk "$SDK" -destination "$DEST" -configuration Release ENABLE_TESTABILITY=YES | xcpretty +notifications: + email: + on_success: never From 60f1249842fe830bf67af37e9c4c23b83e845c96 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 29 Jan 2017 14:03:32 +0100 Subject: [PATCH 14/23] Podspec fix --- SwinjectAutoregistration.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SwinjectAutoregistration.podspec b/SwinjectAutoregistration.podspec index ad4d753..ceb582c 100644 --- a/SwinjectAutoregistration.podspec +++ b/SwinjectAutoregistration.podspec @@ -9,7 +9,7 @@ SwinjectAutoregistration is an extension of Swinject that allows to automaticall s.homepage = 'https://github.com/Swinject/SwinjectAutoregistration' s.license = { :type => 'MIT', :file => 'LICENSE' } s.author = 'Swinject Contributors' - s.source = { :git => 'https://github.com/Swinject/SwinjectAutoregistration', :tag => s.version.to_s } + s.source = { :git => 'https://github.com/Swinject/SwinjectAutoregistration.git', :tag => s.version.to_s } s.ios.deployment_target = '8.0' From 4066693552c27fb4b83ff6d17aacf5a993933a1a Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 29 Jan 2017 14:06:26 +0100 Subject: [PATCH 15/23] Added swift version for travis --- .swift-version | 1 + 1 file changed, 1 insertion(+) create mode 100644 .swift-version diff --git a/.swift-version b/.swift-version new file mode 100644 index 0000000..cb2b00e --- /dev/null +++ b/.swift-version @@ -0,0 +1 @@ +3.0.1 From 0c4646b2b5af5dd284b3e0bf8d035270ea038699 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 29 Jan 2017 14:57:23 +0100 Subject: [PATCH 16/23] Nimble matcher fix --- Carthage/Checkouts/Swinject/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Carthage/Checkouts/Swinject/.travis.yml b/Carthage/Checkouts/Swinject/.travis.yml index 0585f86..dd3ba34 100644 --- a/Carthage/Checkouts/Swinject/.travis.yml +++ b/Carthage/Checkouts/Swinject/.travis.yml @@ -24,7 +24,7 @@ matrix: - env: JOB="POD_LINT" script: - pod lib lint - - env: JOB="XCODE" DEST="OS=8.4,name=iPhone 5" SCHEME="Swinject-iOS" SDK="iphonesimulator" ACTION="test" + - env: JOB="XCODE" DEST="OS=8.4,name=iPhone 5s" SCHEME="Swinject-iOS" SDK="iphonesimulator" ACTION="test" - env: JOB="XCODE" DEST="OS=9.3,name=iPhone 6" SCHEME="Swinject-iOS" SDK="iphonesimulator" ACTION="test" - env: JOB="XCODE" DEST="OS=10.1,name=iPhone 7 Plus" SCHEME="Swinject-iOS" SDK="iphonesimulator" ACTION="test" - env: JOB="XCODE" DEST="arch=x86_64" SCHEME="Swinject-OSX" SDK="macosx" ACTION="test" From db5fdd512ff77ecdc1d4a2a43539ece2bba378e3 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 29 Jan 2017 15:10:54 +0100 Subject: [PATCH 17/23] Travis build fixes --- .gitignore | 2 +- .travis.yml | 2 +- Carthage/Checkouts/Swinject/.travis.yml | 1 + Tests/{ => AutoregistrationTests}/AutoregistrationSpec.swift | 0 Tests/{ => AutoregistrationTests}/TypeParserTests.swift | 0 Tests/{ => AutoregistrationTests}/WarningsSpec.swift | 0 6 files changed, 3 insertions(+), 2 deletions(-) rename Tests/{ => AutoregistrationTests}/AutoregistrationSpec.swift (100%) rename Tests/{ => AutoregistrationTests}/TypeParserTests.swift (100%) rename Tests/{ => AutoregistrationTests}/WarningsSpec.swift (100%) diff --git a/.gitignore b/.gitignore index 58ffb35..c083b4f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,7 @@ playground.xcworkspace # Swift Package Manager # # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ +Packages/ .build/ # CocoaPods diff --git a/.travis.yml b/.travis.yml index 0093005..75c10ea 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ matrix: - env: JOB="POD_LINT" script: - pod lib lint - - env: JOB="XCODE" DEST="OS=8.4,name=iPhone 5" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" + - env: JOB="XCODE" DEST="OS=8.4,name=iPhone 5s" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" - env: JOB="XCODE" DEST="OS=9.3,name=iPhone 6" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" - env: JOB="XCODE" DEST="OS=10.1,name=iPhone 7 Plus" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" - env: JOB="XCODE" DEST="arch=x86_64" SCHEME="SwinjectAutoregistration-OSX" SDK="macosx" ACTION="test" diff --git a/Carthage/Checkouts/Swinject/.travis.yml b/Carthage/Checkouts/Swinject/.travis.yml index dd3ba34..636b39c 100644 --- a/Carthage/Checkouts/Swinject/.travis.yml +++ b/Carthage/Checkouts/Swinject/.travis.yml @@ -23,6 +23,7 @@ matrix: - swift test - env: JOB="POD_LINT" script: + - pod repo update - pod lib lint - env: JOB="XCODE" DEST="OS=8.4,name=iPhone 5s" SCHEME="Swinject-iOS" SDK="iphonesimulator" ACTION="test" - env: JOB="XCODE" DEST="OS=9.3,name=iPhone 6" SCHEME="Swinject-iOS" SDK="iphonesimulator" ACTION="test" diff --git a/Tests/AutoregistrationSpec.swift b/Tests/AutoregistrationTests/AutoregistrationSpec.swift similarity index 100% rename from Tests/AutoregistrationSpec.swift rename to Tests/AutoregistrationTests/AutoregistrationSpec.swift diff --git a/Tests/TypeParserTests.swift b/Tests/AutoregistrationTests/TypeParserTests.swift similarity index 100% rename from Tests/TypeParserTests.swift rename to Tests/AutoregistrationTests/TypeParserTests.swift diff --git a/Tests/WarningsSpec.swift b/Tests/AutoregistrationTests/WarningsSpec.swift similarity index 100% rename from Tests/WarningsSpec.swift rename to Tests/AutoregistrationTests/WarningsSpec.swift From 68c58aff7817db1252694c17e3925728031221d3 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 29 Jan 2017 15:34:40 +0100 Subject: [PATCH 18/23] Moved tests for spm --- .Package.test.swift | 3 +- .../project.pbxproj | 56 +++++++++++-------- .../AutoregistrationSpec.swift | 1 + .../TypeParserTests.swift | 0 .../WarningsSpec.swift | 0 5 files changed, 35 insertions(+), 25 deletions(-) rename Tests/{AutoregistrationTests => SwinjectAutoregistrationTests}/AutoregistrationSpec.swift (99%) rename Tests/{AutoregistrationTests => SwinjectAutoregistrationTests}/TypeParserTests.swift (100%) rename Tests/{AutoregistrationTests => SwinjectAutoregistrationTests}/WarningsSpec.swift (100%) diff --git a/.Package.test.swift b/.Package.test.swift index 1a47260..fc10d72 100644 --- a/.Package.test.swift +++ b/.Package.test.swift @@ -1,8 +1,9 @@ import PackageDescription let package = Package( - name: "Swinject", + name: "SwinjectAutoregistration", dependencies: [ + .Package(url: "https://github.com/Swinject/Swinject.git", majorVersion: 2), .Package(url: "https://github.com/Quick/Quick", majorVersion: 1), .Package(url: "https://github.com/Quick/Nimble", majorVersion: 5, minor: 1), ] diff --git a/SwinjectAutoregistration.xcodeproj/project.pbxproj b/SwinjectAutoregistration.xcodeproj/project.pbxproj index 53ffeb7..3e137d7 100644 --- a/SwinjectAutoregistration.xcodeproj/project.pbxproj +++ b/SwinjectAutoregistration.xcodeproj/project.pbxproj @@ -19,9 +19,6 @@ AC1191211E30211300B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; AC1191221E30211400B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; AC1191231E30211500B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; - AC4AC9081E32964C00E6355A /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9071E32964C00E6355A /* TypeParserTests.swift */; }; - AC4AC9171E3297E000E6355A /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9071E32964C00E6355A /* TypeParserTests.swift */; }; - AC4AC9181E3297E100E6355A /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9071E32964C00E6355A /* TypeParserTests.swift */; }; AC4AC9491E33C71D00E6355A /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9481E33C71D00E6355A /* TypeParser.swift */; }; AC4AC94B1E33C75200E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; AC4AC94C1E33CB9100E6355A /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9481E33C71D00E6355A /* TypeParser.swift */; }; @@ -30,14 +27,19 @@ AC4AC94F1E33CB9600E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; AC4AC9501E33CB9700E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; AC4AC9511E33CB9700E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; - AC4AC9531E33CF0600E6355A /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */; }; - AC4AC9541E33D04C00E6355A /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */; }; - AC4AC9551E33D04D00E6355A /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */; }; + ACA1032C1E3E3391004B8CD4 /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */; }; + ACA1032D1E3E3392004B8CD4 /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */; }; + ACA1032E1E3E3393004B8CD4 /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */; }; + ACA1032F1E3E3397004B8CD4 /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */; }; + ACA103301E3E3398004B8CD4 /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */; }; + ACA103311E3E339A004B8CD4 /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */; }; + ACA103321E3E339E004B8CD4 /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */; }; + ACA103331E3E339F004B8CD4 /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */; }; + ACA103341E3E33A0004B8CD4 /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */; }; CD5B9ECB1D832D5A007ED05F /* SwinjectAutoregistration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9EC01D832D5A007ED05F /* SwinjectAutoregistration.framework */; }; CD5B9EDF1D832E32007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; CD5B9EE01D833088007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; CD5B9EE11D833088007ED05F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8D1D832BF9007ED05F /* Operators.swift */; }; - CD5B9EE21D83308B007ED05F /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */; }; CD5B9EF81D8333A9007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; CD5B9EF91D8333A9007ED05F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8D1D832BF9007ED05F /* Operators.swift */; }; CD5B9EFA1D8333A9007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -45,7 +47,6 @@ CD5B9F1F1D83368E007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; CD5B9F201D833697007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; CD5B9F211D833697007ED05F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8D1D832BF9007ED05F /* Operators.swift */; }; - CD5B9F221D83369A007ED05F /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */; }; CD5B9F5B1D833772007ED05F /* Swinject.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9E7D1D832A84007ED05F /* Swinject.framework */; }; CD5B9F5C1D83377C007ED05F /* Swinject.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9E851D832A84007ED05F /* Swinject.framework */; }; CD5B9F5F1D8337B4007ED05F /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9E6A1D832A84007ED05F /* Quick.framework */; }; @@ -58,7 +59,6 @@ CD5B9F701D8338FC007ED05F /* AutoRegistration.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */; }; CD5B9F711D8338FC007ED05F /* Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8D1D832BF9007ED05F /* Operators.swift */; }; CD5B9F721D833900007ED05F /* SwinjectAutoregistration.h in Headers */ = {isa = PBXBuildFile; fileRef = CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */; settings = {ATTRIBUTES = (Public, ); }; }; - CD5B9F731D83390C007ED05F /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */; }; CD5B9F761D833A15007ED05F /* SwinjectAutoregistration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9F281D833711007ED05F /* SwinjectAutoregistration.framework */; }; CD5B9F781D833A27007ED05F /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD5B9E641D832A84007ED05F /* Quick.framework */; }; /* End PBXBuildFile section */ @@ -336,10 +336,11 @@ AC1191091E301CD200B112D9 /* Warning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Warning.swift; sourceTree = ""; }; AC1191171E301E3A00B112D9 /* Resolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Resolver.swift; sourceTree = ""; }; AC1191181E301E3A00B112D9 /* CheckResolved.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckResolved.swift; sourceTree = ""; }; - AC4AC9071E32964C00E6355A /* TypeParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParserTests.swift; sourceTree = ""; }; AC4AC9481E33C71D00E6355A /* TypeParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParser.swift; sourceTree = ""; }; AC4AC94A1E33C75200E6355A /* Type.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Type.swift; sourceTree = ""; }; - AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WarningsSpec.swift; sourceTree = ""; }; + ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoregistrationSpec.swift; sourceTree = ""; }; + ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParserTests.swift; sourceTree = ""; }; + ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WarningsSpec.swift; sourceTree = ""; }; CD5B9E231D832A4F007ED05F /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; CD5B9E251D832A4F007ED05F /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; CD5B9E261D832A4F007ED05F /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = ""; }; @@ -366,7 +367,6 @@ CD5B9E551D832A84007ED05F /* Swinject.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Swinject.xcodeproj; path = Carthage/Checkouts/Swinject/Swinject.xcodeproj; sourceTree = ""; }; CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoRegistration.swift; sourceTree = ""; }; CD5B9E8D1D832BF9007ED05F /* Operators.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Operators.swift; sourceTree = ""; }; - CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoregistrationSpec.swift; sourceTree = ""; }; CD5B9EB21D832C81007ED05F /* watchOS-Application.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Application.xcconfig"; sourceTree = ""; }; CD5B9EB31D832C81007ED05F /* watchOS-Base.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Base.xcconfig"; sourceTree = ""; }; CD5B9EB41D832C81007ED05F /* watchOS-Framework.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "watchOS-Framework.xcconfig"; sourceTree = ""; }; @@ -458,6 +458,16 @@ name = Parser; sourceTree = ""; }; + ACA103241E3E3386004B8CD4 /* SwinjectAutoregistrationTests */ = { + isa = PBXGroup; + children = ( + ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */, + ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */, + ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */, + ); + path = SwinjectAutoregistrationTests; + sourceTree = ""; + }; CD5B9E151D832813007ED05F = { isa = PBXGroup; children = ( @@ -616,10 +626,8 @@ CD5B9E8E1D832BF9007ED05F /* Tests */ = { isa = PBXGroup; children = ( - CD5B9E8F1D832BF9007ED05F /* AutoregistrationSpec.swift */, + ACA103241E3E3386004B8CD4 /* SwinjectAutoregistrationTests */, CD5B9EDD1D832E2E007ED05F /* Info.plist */, - AC4AC9521E33CF0600E6355A /* WarningsSpec.swift */, - AC4AC9071E32964C00E6355A /* TypeParserTests.swift */, ); path = Tests; sourceTree = ""; @@ -1145,9 +1153,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - AC4AC9081E32964C00E6355A /* TypeParserTests.swift in Sources */, - CD5B9EE21D83308B007ED05F /* AutoregistrationSpec.swift in Sources */, - AC4AC9531E33CF0600E6355A /* WarningsSpec.swift in Sources */, + ACA1032C1E3E3391004B8CD4 /* TypeParserTests.swift in Sources */, + ACA103321E3E339E004B8CD4 /* AutoregistrationSpec.swift in Sources */, + ACA1032F1E3E3397004B8CD4 /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1183,9 +1191,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - AC4AC9171E3297E000E6355A /* TypeParserTests.swift in Sources */, - CD5B9F221D83369A007ED05F /* AutoregistrationSpec.swift in Sources */, - AC4AC9541E33D04C00E6355A /* WarningsSpec.swift in Sources */, + ACA1032D1E3E3392004B8CD4 /* TypeParserTests.swift in Sources */, + ACA103331E3E339F004B8CD4 /* AutoregistrationSpec.swift in Sources */, + ACA103301E3E3398004B8CD4 /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1207,9 +1215,9 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - AC4AC9181E3297E100E6355A /* TypeParserTests.swift in Sources */, - CD5B9F731D83390C007ED05F /* AutoregistrationSpec.swift in Sources */, - AC4AC9551E33D04D00E6355A /* WarningsSpec.swift in Sources */, + ACA1032E1E3E3393004B8CD4 /* TypeParserTests.swift in Sources */, + ACA103341E3E33A0004B8CD4 /* AutoregistrationSpec.swift in Sources */, + ACA103311E3E339A004B8CD4 /* WarningsSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tests/AutoregistrationTests/AutoregistrationSpec.swift b/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift similarity index 99% rename from Tests/AutoregistrationTests/AutoregistrationSpec.swift rename to Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift index c89e820..b0928c4 100644 --- a/Tests/AutoregistrationTests/AutoregistrationSpec.swift +++ b/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift @@ -4,6 +4,7 @@ import Quick import Nimble import SwinjectAutoregistration import Swinject +import Foundation class AutoregistrationSpec: QuickSpec { diff --git a/Tests/AutoregistrationTests/TypeParserTests.swift b/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift similarity index 100% rename from Tests/AutoregistrationTests/TypeParserTests.swift rename to Tests/SwinjectAutoregistrationTests/TypeParserTests.swift diff --git a/Tests/AutoregistrationTests/WarningsSpec.swift b/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift similarity index 100% rename from Tests/AutoregistrationTests/WarningsSpec.swift rename to Tests/SwinjectAutoregistrationTests/WarningsSpec.swift From f7daa6f5900b2102890aeffa3850fb53071dbf53 Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 29 Jan 2017 19:30:35 +0100 Subject: [PATCH 19/23] Added pod repo update --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 75c10ea..79ba126 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ matrix: - swift test - env: JOB="POD_LINT" script: + - pod repo update - pod lib lint - env: JOB="XCODE" DEST="OS=8.4,name=iPhone 5s" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" - env: JOB="XCODE" DEST="OS=9.3,name=iPhone 6" SCHEME="SwinjectAutoregistration-iOS" SDK="iphonesimulator" ACTION="test" From 31c4d17aa34297a19069a78432160a8e9f44928f Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Mon, 30 Jan 2017 00:27:29 +0100 Subject: [PATCH 20/23] Updated tests and code to support Linux --- Sources/TypeParser.swift | 94 ++++-- Tests/LinuxMain.swift | 18 ++ .../AutoregistrationSpec.swift | 3 + .../TypeParserTests.swift | 271 +++++++++--------- .../WarningsSpec.swift | 5 + 5 files changed, 231 insertions(+), 160 deletions(-) create mode 100755 Tests/LinuxMain.swift diff --git a/Sources/TypeParser.swift b/Sources/TypeParser.swift index 0aef2fa..479aa53 100644 --- a/Sources/TypeParser.swift +++ b/Sources/TypeParser.swift @@ -7,9 +7,45 @@ // import Foundation +#if !os(Linux) + extension Scanner { + func scanString(string: String) -> String? { + var value: NSString? + if self.scanString(string, into: &value), let value = value as? String { + return value + } + return nil + } + + func scanCharactersFromSet(_ set: CharacterSet) -> String? { + var value: NSString? + if self.scanCharacters(from: set, into: &value), let value = value as? String { + return value + } + return nil + } + } + + extension NSMutableCharacterSet { + func insert(charactersIn range: Range) { + let nsRange = NSRange(location: Int(range.lowerBound.value), length: Int(range.upperBound.value - range.lowerBound.value)) + self.addCharacters(in: nsRange) + } + + func insert(charactersIn string: String) { + self.addCharacters(in: string) + } + + func formUnion(_ set: CharacterSet) { + self.formUnion(with: set) + } + } +#endif + + -private func ..<(start: Int, end: Int) -> NSRange { - return NSRange(location: start, length: end - start + 1) +private func ..<(start: Int, end: Int) -> Range { + return UnicodeScalar(start)! ..< UnicodeScalar(end)! } /// Simple top-down parser for type description based on swift grammatic: @@ -61,7 +97,7 @@ class TypeParser { let genericTypes = parseGenericArgumentClause() ?? [] var subTypeIdentifier: TypeIdentifier? = nil - if scanner.scanString(".", into: nil), let typeIdentifier = parseTypeIdentifier() { + if scanner.scanString(string: ".") != nil, let typeIdentifier = parseTypeIdentifier() { subTypeIdentifier = typeIdentifier } @@ -70,16 +106,16 @@ class TypeParser { } func parseGenericArgumentClause() -> [Type]? { - guard scanner.scanString("<", into: nil) else { return nil } + guard scanner.scanString(string: "<") != nil else { return nil } guard let type = parseType() else { return nil } var types: [Type] = [type] - while scanner.scanString(",", into: nil), let type = parseType(){ + while scanner.scanString(string: ",") != nil, let type = parseType(){ types.append(type) } - guard scanner.scanString(">", into: nil) else { return nil } + guard scanner.scanString(string: ">") != nil else { return nil } return types } @@ -90,7 +126,7 @@ class TypeParser { var protocolTypes: [TypeIdentifier] = [protocolType] - while scanner.scanString("&", into: nil), let protocolType = parseTypeIdentifier() { + while scanner.scanString(string: "&") != nil, let protocolType = parseTypeIdentifier() { protocolTypes.append(protocolType) } @@ -100,17 +136,17 @@ class TypeParser { } func parseTupleType() -> [Type]? { - guard scanner.scanString("(", into: nil) else { return nil } + guard scanner.scanString(string: "(") != nil else { return nil } var types: [Type] = [] if let type = parseType() { types.append(type) } - while scanner.scanString(",", into: nil), let type = parseType() { + while scanner.scanString(string: ",") != nil, let type = parseType() { types.append(type) } - guard scanner.scanString(")", into: nil) else { return nil } + guard scanner.scanString(string: ")") != nil else { return nil } return types } @@ -120,10 +156,10 @@ class TypeParser { guard let parameters = parseTupleType() else { return nil } - let `throws` = scanner.scanString("throws", into: nil) + let `throws` = scanner.scanString(string: "throws") != nil // - rethrows is not allowed for closures - guard scanner.scanString("->", into: nil) else { scanner.scanLocation = originalLocation; return nil } + guard scanner.scanString(string: "->") != nil else { scanner.scanLocation = originalLocation; return nil } guard let returnType = parseType() else { scanner.scanLocation = originalLocation; return nil } @@ -132,14 +168,16 @@ class TypeParser { } func parseIdentifier() -> String? { - - let head = NSMutableCharacterSet() - // See https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/swift/grammar/identifier-head //Identifier head - head.formUnion(with: CharacterSet.letters) - head.addCharacters(in: "_") + #if os(Linux) + var head = CharacterSet() + #else + let head = NSMutableCharacterSet() + #endif + head.formUnion(CharacterSet.letters) + head.insert(charactersIn: "_") let ranges = [ 0x00A8 ..< 0x00A8, 0x00AA ..< 0x00AA, 0x00AD ..< 0x00AD, 0x00AF ..< 0x00AF, 0x00B2..<0x00B5, 0x00B7..<0x00BA, @@ -158,22 +196,24 @@ class TypeParser { 0x90000..<0x9FFFD, 0xA0000..<0xAFFFD, 0xB0000..<0xBFFFD, 0xC0000..<0xCFFFD, 0xD0000..<0xDFFFD, 0xE0000..<0xEFFFD] - ranges.forEach { head.addCharacters(in: $0) } + ranges.forEach { head.insert(charactersIn: $0) } //Identifier characters - let characters = head.copy() as! NSMutableCharacterSet - characters.addCharacters(in: "0123456789") + #if os(Linux) + var characters = head + #else + let characters = head.copy() as! NSMutableCharacterSet + #endif + characters.insert(charactersIn: "0123456789") - let charactersRanges = [0x0300..<0x036F, 0x1DC0..<0x1DFF, 0x20D0..<0x20FF, 0xFE20..<0xFE2F] - charactersRanges.forEach { characters.addCharacters(in: $0) } - var headString: NSString? - var charactersString: NSString? + let charactersRanges = [0x0300..<0x036F, 0x1DC0..<0x1DFF, 0x20D0..<0x20FF, 0xFE20..<0xFE2F] + charactersRanges.forEach { characters.insert(charactersIn: $0) } - guard scanner.scanCharacters(from: head as CharacterSet, into: &headString) else { return nil } + guard let headString = scanner.scanCharactersFromSet(head as CharacterSet) else { return nil } - scanner.scanCharacters(from: characters as CharacterSet, into: &charactersString) - return "\(headString!)\(charactersString ?? "")" + let charactersString = scanner.scanCharactersFromSet(characters as CharacterSet) + return "\(headString)\(charactersString ?? "")" } } diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift new file mode 100755 index 0000000..f6e041b --- /dev/null +++ b/Tests/LinuxMain.swift @@ -0,0 +1,18 @@ +// +// LinuxMain.swift +// SwinjectAutoregistration +// +// Created by Tomas Kohout on 01/29/17. +// Copyright © 2017 Swinject Contributors. All rights reserved. +// + +import XCTest +import Quick + +@testable import SwinjectAutoregistrationTests + +Quick.QCKMain([ + AutoregistrationSpec.self, + WarningsSpec.self, + TypeParserSpec.self +]) diff --git a/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift b/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift index b0928c4..f563342 100644 --- a/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift +++ b/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift @@ -214,6 +214,7 @@ class AutoregistrationSpec: QuickSpec { expect(logs.count) == 1 } + #if !os(Linux) it("does not loose any logs while multithreading"){ var logs: [String] = [] Container.loggingFunction = { logs.append($0) } @@ -239,6 +240,8 @@ class AutoregistrationSpec: QuickSpec { expect(logs.count).toEventually(equal(resolutionsCount)) } + #endif + } } } diff --git a/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift b/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift index 637fd6a..e8e1945 100644 --- a/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift +++ b/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift @@ -7,6 +7,8 @@ // import XCTest +import Quick +import Nimble protocol ProtocolA{} protocol ProtocolB{} @@ -21,7 +23,7 @@ class `protocol` {} @testable import SwinjectAutoregistration -class TypeParserTests: XCTestCase { +class TypeParserSpec: QuickSpec { //Helpers func identifier(_ name: String, generics: [Type] = []) -> Type { @@ -32,138 +34,141 @@ class TypeParserTests: XCTestCase { return Type.identifier(TypeIdentifier(name: name, genericTypes: generics.map { identifier($0) })) } - - func testScansTypeIdentifier() { - let string = "\(_x0😪name²〡yﷰ.self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, identifier(string)) - } - - func testDoesntScanNonTypeIdentifier() { - let string = "1Array" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, nil) + override func spec() { + describe("autoregistration") { + + it("scans type identifier") { + let string = "\(_x0😪name²〡yﷰ.self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, self.identifier(string)) + } + + it("doesnt scan non type identifier") { + let string = "1Array" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, nil) + } + + + it("scans subtype identifier") { + let string = "\(ClassA.Nested.self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, self.identifier("Nested")) + } + + it("scans array type") { + let string = "\([String].self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, self.generic_identifier("Array", generics: ["String"])) + } + + it("scans generic type with multiple arguments") { + let string = "\([Int: String].self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, self.generic_identifier("Dictionary", generics: ["Int", "String"])) + } + + it("scans tuple type") { + let string = "\((name: String, count: Int).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.tuple([self.identifier("String"), self.identifier("Int")])) + } + + it("scans tuple of tuples") { + let string = "\(((String, Int, Double), [String]).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.tuple([Type.tuple([self.identifier("String"), self.identifier("Int"), self.identifier("Double")]), self.generic_identifier("Array", generics: ["String"])])) + } + + it("scans closure type") { + let string = "\(((String, Int) -> String).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.closure(parameters: [Type.tuple([self.identifier("String"), self.identifier("Int")])], returnType: self.identifier("String"), throws: false)) + } + + it("scans nested function type") { + let string = "\((((String) -> String, Int) -> String).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + //Type print adds one unneccessary tuple to the output + XCTAssertEqual(type, Type.closure(parameters: [Type.tuple([Type.closure(parameters: [self.identifier("String")], returnType: self.identifier("String"), throws: false), self.identifier("Int")])], returnType: self.identifier("String"), throws: false)) + } + + it("scans no parameter function type") { + let string = "\(((Void) -> Void).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + let void = Type.tuple([]) // Void is empty tuple + XCTAssertEqual(type, Type.closure(parameters: [void], returnType: void, throws: false)) + } + + it("scans throwing function type") { + let string = "\(((Void) throws -> Void).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + let void = Type.tuple([]) // Void is empty tuple + XCTAssertEqual(type, Type.closure(parameters: [void], returnType: void, throws: true)) + } + + it("scans implicitly unwrapped optional") { + let string = "\((String!).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, self.generic_identifier("ImplicitlyUnwrappedOptional", generics: ["String"])) + } + + it("scans optional") { + let string = "\((Int?).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, self.generic_identifier("Optional", generics: ["Int"])) + } + + it("scans protocol composition type") { + let string = "\((ProtocolA & ProtocolB).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.protocolComposition([TypeIdentifier(name: "ProtocolA"), TypeIdentifier(name: "ProtocolB")])) + } + + it("scans metatypes") { + let string = "\((ProtocolA.Type.Type).self)" // Very meta + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, Type.identifier(TypeIdentifier(name: "ProtocolA", subTypeIdentifier: TypeIdentifier(name: "Type", subTypeIdentifier: TypeIdentifier(name: "Type"))))) + } + + it("scans backticked type") { + let string = "\((`protocol`).self)" + let parser = TypeParser(string: string) + let type = parser.parseType() + + XCTAssertEqual(type, self.identifier(string)) + } + } } - - func testScanSubTypeIdentifier() { - let string = "\(ClassA.Nested.self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, identifier("Nested")) - } - - func testScansArrayType() { - let string = "\([String].self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, generic_identifier("Array", generics: ["String"])) - } - - func testScansGenericTypeWithMultipleArguments() { - let string = "\([Int: String].self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, generic_identifier("Dictionary", generics: ["Int", "String"])) - } - - func testScansTupleType() { - let string = "\((name: String, count: Int).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, Type.tuple([identifier("String"), identifier("Int")])) - } - - func testScansTupleOfTuples() { - let string = "\(((String, Int, Double), [String]).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, Type.tuple([Type.tuple([identifier("String"), identifier("Int"), identifier("Double")]), generic_identifier("Array", generics: ["String"])])) - } - - func testScansClosureType() { - let string = "\(((String, Int) -> String).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, Type.closure(parameters: [Type.tuple([identifier("String"), identifier("Int")])], returnType: identifier("String"), throws: false)) - } - - func testScansNestedFunctionType() { - let string = "\((((String) -> String, Int) -> String).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - //Type print adds one unneccessary tuple to the output - XCTAssertEqual(type, Type.closure(parameters: [Type.tuple([Type.closure(parameters: [identifier("String")], returnType: identifier("String"), throws: false), identifier("Int")])], returnType: identifier("String"), throws: false)) - } - - func testScansNoParameterFunctionType() { - let string = "\(((Void) -> Void).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - let void = Type.tuple([]) // Void is empty tuple - XCTAssertEqual(type, Type.closure(parameters: [void], returnType: void, throws: false)) - } - - func testScansThrowingFunctionType() { - let string = "\(((Void) throws -> Void).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - let void = Type.tuple([]) // Void is empty tuple - XCTAssertEqual(type, Type.closure(parameters: [void], returnType: void, throws: true)) - } - - func testScansImplicitlyUnwrappedOptional() { - let string = "\((String!).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, generic_identifier("ImplicitlyUnwrappedOptional", generics: ["String"])) - } - - func testScansOptional() { - let string = "\((Int?).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, generic_identifier("Optional", generics: ["Int"])) - } - - func testScansProtocolCompositionType() { - let string = "\((ProtocolA & ProtocolB).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, Type.protocolComposition([TypeIdentifier(name: "ProtocolA"), TypeIdentifier(name: "ProtocolB")])) - } - - func testScansMetatypes() { - let string = "\((ProtocolA.Type.Type).self)" // Very meta - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, Type.identifier(TypeIdentifier(name: "ProtocolA", subTypeIdentifier: TypeIdentifier(name: "Type", subTypeIdentifier: TypeIdentifier(name: "Type"))))) - } - - func testScansBacktickedType() { - let string = "\((`protocol`).self)" - let parser = TypeParser(string: string) - let type = parser.parseType() - - XCTAssertEqual(type, identifier(string)) - } - - } diff --git a/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift b/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift index c4a78ca..01ba048 100644 --- a/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift +++ b/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift @@ -82,6 +82,7 @@ class WarningsSpec: QuickSpec { override func spec() { describe("warnings checker") { + //fails on linux it("does show warning for service with more than 9 dependencies"){ let w = warnings(forInitializer: Service10.init) expect(w.first) == Warning.tooManyDependencies(10) @@ -97,16 +98,19 @@ class WarningsSpec: QuickSpec { expect(w.count) == 0 } + //fails on linux it("does show warning for service with optional dependency"){ let w = warnings(forInitializer: OptionalService.init) expect(w.first) == Warning.optional("DependencyB") } + //fails on linux it("does show warning for service with implicitly unwrapped dependency"){ let w = warnings(forInitializer: UnwrappedService.init) expect(w.first) == Warning.implicitlyUnwrappedOptional("DependencyA") } + //fails on linux it("does show multiple warnings"){ let w = warnings(forInitializer: BadService.init) expect(w.count) == 5 @@ -129,6 +133,7 @@ class WarningsSpec: QuickSpec { expect(w.count) == 0 } + //fails on linux it("does show warning for optional closure"){ let w = warnings(forInitializer: OptionalNestedClosureService.init) expect(w.count) == 1 From f7a4d2e58509f4b20b2afd68298631b7f28690ab Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Mon, 30 Jan 2017 00:48:17 +0100 Subject: [PATCH 21/23] Removed linux support for warnings --- Sources/Warning.swift | 4 ++++ Tests/LinuxMain.swift | 6 +++--- .../AutoregistrationSpec.swift | 2 ++ Tests/SwinjectAutoregistrationTests/TypeParserTests.swift | 3 ++- Tests/SwinjectAutoregistrationTests/WarningsSpec.swift | 7 ++----- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Sources/Warning.swift b/Sources/Warning.swift index 9450962..9ee69af 100644 --- a/Sources/Warning.swift +++ b/Sources/Warning.swift @@ -27,6 +27,10 @@ enum Warning { /// Shows warnings based on information parsed from initializers description func warnings(forInitializer initializer: (Parameters) -> Service) -> [Warning] { + #if os(Linux) + //Warnings are not supported on Linux + return [] + #endif let parser = TypeParser(string: String(describing: Parameters.self)) guard let type = parser.parseType() else { return [] } diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index f6e041b..10170bd 100755 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -12,7 +12,7 @@ import Quick @testable import SwinjectAutoregistrationTests Quick.QCKMain([ - AutoregistrationSpec.self, - WarningsSpec.self, - TypeParserSpec.self + AutoregistrationSpec.self +// WarningsSpec.self, +// TypeParserSpec.self ]) diff --git a/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift b/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift index f563342..0dbece3 100644 --- a/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift +++ b/Tests/SwinjectAutoregistrationTests/AutoregistrationSpec.swift @@ -172,6 +172,7 @@ class AutoregistrationSpec: QuickSpec { expect(service).notTo(beNil()) } + #if !os(Linux) it("throws assertion when same type arguments are passed") { expect { () -> Void in container.autoregister(SameArgumentsService.self, arguments: String.self, Int.self, String.self, initializer: SameArgumentsService.init) @@ -198,6 +199,7 @@ class AutoregistrationSpec: QuickSpec { _ = container.resolve(UnwrappedService.self) }.to(throwAssertion()) } + #endif it("does not erase logging function"){ var logs: [String] = [] diff --git a/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift b/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift index e8e1945..5b195b5 100644 --- a/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift +++ b/Tests/SwinjectAutoregistrationTests/TypeParserTests.swift @@ -5,7 +5,7 @@ // Created by Tomas Kohout on 20/01/2017. // Copyright © 2017 Swinject Contributors. All rights reserved. // - +#if !os(Linux) import XCTest import Quick import Nimble @@ -172,3 +172,4 @@ class TypeParserSpec: QuickSpec { } } +#endif diff --git a/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift b/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift index 01ba048..e67d121 100644 --- a/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift +++ b/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift @@ -1,3 +1,4 @@ +#if !os(Linux) import Quick import Nimble @@ -82,7 +83,6 @@ class WarningsSpec: QuickSpec { override func spec() { describe("warnings checker") { - //fails on linux it("does show warning for service with more than 9 dependencies"){ let w = warnings(forInitializer: Service10.init) expect(w.first) == Warning.tooManyDependencies(10) @@ -98,19 +98,16 @@ class WarningsSpec: QuickSpec { expect(w.count) == 0 } - //fails on linux it("does show warning for service with optional dependency"){ let w = warnings(forInitializer: OptionalService.init) expect(w.first) == Warning.optional("DependencyB") } - //fails on linux it("does show warning for service with implicitly unwrapped dependency"){ let w = warnings(forInitializer: UnwrappedService.init) expect(w.first) == Warning.implicitlyUnwrappedOptional("DependencyA") } - //fails on linux it("does show multiple warnings"){ let w = warnings(forInitializer: BadService.init) expect(w.count) == 5 @@ -133,7 +130,6 @@ class WarningsSpec: QuickSpec { expect(w.count) == 0 } - //fails on linux it("does show warning for optional closure"){ let w = warnings(forInitializer: OptionalNestedClosureService.init) expect(w.count) == 1 @@ -143,3 +139,4 @@ class WarningsSpec: QuickSpec { } } +#endif From b18fcb7b79d56a4b8607d724cc61f3631fb6894f Mon Sep 17 00:00:00 2001 From: Tomas Kohout Date: Sun, 12 Feb 2017 22:22:23 +0100 Subject: [PATCH 22/23] Fixed throw assertion test fail --- .../xcschemes/SwinjectAutoregistration-tvOS.xcscheme | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SwinjectAutoregistration.xcodeproj/xcshareddata/xcschemes/SwinjectAutoregistration-tvOS.xcscheme b/SwinjectAutoregistration.xcodeproj/xcshareddata/xcschemes/SwinjectAutoregistration-tvOS.xcscheme index 9bb868b..be7c56e 100644 --- a/SwinjectAutoregistration.xcodeproj/xcshareddata/xcschemes/SwinjectAutoregistration-tvOS.xcscheme +++ b/SwinjectAutoregistration.xcodeproj/xcshareddata/xcschemes/SwinjectAutoregistration-tvOS.xcscheme @@ -24,8 +24,8 @@ Date: Sat, 18 Feb 2017 19:07:05 +0100 Subject: [PATCH 23/23] Refactored warnings to resolution error --- Sources/CheckResolved.swift | 36 +++++++++---------- .../{Warning.swift => ResolutionError.swift} | 6 ++-- .../project.pbxproj | 36 +++++++++---------- ...gsSpec.swift => ResolutionErrorSpec.swift} | 32 ++++++++--------- bin/generate | 4 +-- 5 files changed, 57 insertions(+), 57 deletions(-) rename Sources/{Warning.swift => ResolutionError.swift} (92%) rename Tests/SwinjectAutoregistrationTests/{WarningsSpec.swift => ResolutionErrorSpec.swift} (75%) diff --git a/Sources/CheckResolved.swift b/Sources/CheckResolved.swift index 4997530..1e9ae7c 100644 --- a/Sources/CheckResolved.swift +++ b/Sources/CheckResolved.swift @@ -17,8 +17,8 @@ func unresolvedService(_ a: A?) -> String? { func checkResolved(initializer: (A) -> Service, services a: A?){ let unresolved = ( [a] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a)!)\nInitializer: (\(A.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a)!)\nInitializer: (\(A.self)) -> \(Service.self)") } } @@ -29,8 +29,8 @@ func unresolvedService(_ a: A?, _ b: B?) -> String? { func checkResolved(initializer: (A, B) -> Service, services a: A?, _ b: B?){ let unresolved = ( [a, b] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a, b)!)\nInitializer: (\(A.self), \(B.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a, b)!)\nInitializer: (\(A.self), \(B.self)) -> \(Service.self)") } } @@ -41,8 +41,8 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?) -> String? { func checkResolved(initializer: (A, B, C) -> Service, services a: A?, _ b: B?, _ c: C?){ let unresolved = ( [a, b, c] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a, b, c)!)\nInitializer: (\(A.self), \(B.self), \(C.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a, b, c)!)\nInitializer: (\(A.self), \(B.self), \(C.self)) -> \(Service.self)") } } @@ -53,8 +53,8 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?) -> String func checkResolved(initializer: (A, B, C, D) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?){ let unresolved = ( [a, b, c, d] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a, b, c, d)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a, b, c, d)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self)) -> \(Service.self)") } } @@ -65,8 +65,8 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E func checkResolved(initializer: (A, B, C, D, E) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?){ let unresolved = ( [a, b, c, d, e] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a, b, c, d, e)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a, b, c, d, e)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self)) -> \(Service.self)") } } @@ -77,8 +77,8 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, _ e func checkResolved(initializer: (A, B, C, D, E, F) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?){ let unresolved = ( [a, b, c, d, e, f] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a, b, c, d, e, f)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a, b, c, d, e, f)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self)) -> \(Service.self)") } } @@ -89,8 +89,8 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D?, func checkResolved(initializer: (A, B, C, D, E, F, G) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?){ let unresolved = ( [a, b, c, d, e, f, g] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a, b, c, d, e, f, g)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a, b, c, d, e, f, g)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self)) -> \(Service.self)") } } @@ -101,8 +101,8 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d: D func checkResolved(initializer: (A, B, C, D, E, F, G, H) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?){ let unresolved = ( [a, b, c, d, e, f, g, h] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a, b, c, d, e, f, g, h)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a, b, c, d, e, f, g, h)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self)) -> \(Service.self)") } } @@ -113,7 +113,7 @@ func unresolvedService(_ a: A?, _ b: B?, _ c: C?, _ d func checkResolved(initializer: (A, B, C, D, E, F, G, H, I) -> Service, services a: A?, _ b: B?, _ c: C?, _ d: D?, _ e: E?, _ f: F?, _ g: G?, _ h: H?, _ i: I?){ let unresolved = ( [a, b, c, d, e, f, g, h, i] as [Any?] ).filter { $0 == nil } if unresolved.count > 0 { - let warningsMessage = warnings(forInitializer: initializer).map { "\($0.message)\n" }.joined() - fatalError("SwinjectAutoregistration: Resolution failed.\n\(warningsMessage)Unresolved service: \(unresolvedService(a, b, c, d, e, f, g, h, i)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self), \(I.self)) -> \(Service.self)") + let errorMessage = resolutionErrors(forInitializer: initializer).map { "\($0.message)\n" }.joined() + fatalError("SwinjectAutoregistration: Resolution failed.\n\(errorMessage)Unresolved service: \(unresolvedService(a, b, c, d, e, f, g, h, i)!)\nInitializer: (\(A.self), \(B.self), \(C.self), \(D.self), \(E.self), \(F.self), \(G.self), \(H.self), \(I.self)) -> \(Service.self)") } } \ No newline at end of file diff --git a/Sources/Warning.swift b/Sources/ResolutionError.swift similarity index 92% rename from Sources/Warning.swift rename to Sources/ResolutionError.swift index 9ee69af..9c753ac 100644 --- a/Sources/Warning.swift +++ b/Sources/ResolutionError.swift @@ -8,7 +8,7 @@ import Foundation -enum Warning { +enum ResolutionError { case optional(String) case implicitlyUnwrappedOptional(String) case tooManyDependencies(Int) @@ -26,7 +26,7 @@ enum Warning { /// Shows warnings based on information parsed from initializers description -func warnings(forInitializer initializer: (Parameters) -> Service) -> [Warning] { +func resolutionErrors(forInitializer initializer: (Parameters) -> Service) -> [ResolutionError] { #if os(Linux) //Warnings are not supported on Linux return [] @@ -46,7 +46,7 @@ func warnings(forInitializer initializer: (Parameters) -> S return [] } - var warnings: [Warning] = [] + var warnings: [ResolutionError] = [] if dependencies.count > maxDependencies { diff --git a/SwinjectAutoregistration.xcodeproj/project.pbxproj b/SwinjectAutoregistration.xcodeproj/project.pbxproj index 3e137d7..4a25656 100644 --- a/SwinjectAutoregistration.xcodeproj/project.pbxproj +++ b/SwinjectAutoregistration.xcodeproj/project.pbxproj @@ -7,7 +7,7 @@ objects = { /* Begin PBXBuildFile section */ - AC11910A1E301CD200B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; + AC11910A1E301CD200B112D9 /* ResolutionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* ResolutionError.swift */; }; AC1191191E301E3A00B112D9 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191171E301E3A00B112D9 /* Resolver.swift */; }; AC11911A1E301E3A00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; AC11911B1E30210200B112D9 /* Resolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191171E301E3A00B112D9 /* Resolver.swift */; }; @@ -16,9 +16,9 @@ AC11911E1E30210A00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; AC11911F1E30210B00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; AC1191201E30210C00B112D9 /* CheckResolved.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191181E301E3A00B112D9 /* CheckResolved.swift */; }; - AC1191211E30211300B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; - AC1191221E30211400B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; - AC1191231E30211500B112D9 /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* Warning.swift */; }; + AC1191211E30211300B112D9 /* ResolutionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* ResolutionError.swift */; }; + AC1191221E30211400B112D9 /* ResolutionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* ResolutionError.swift */; }; + AC1191231E30211500B112D9 /* ResolutionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC1191091E301CD200B112D9 /* ResolutionError.swift */; }; AC4AC9491E33C71D00E6355A /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9481E33C71D00E6355A /* TypeParser.swift */; }; AC4AC94B1E33C75200E6355A /* Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC94A1E33C75200E6355A /* Type.swift */; }; AC4AC94C1E33CB9100E6355A /* TypeParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC4AC9481E33C71D00E6355A /* TypeParser.swift */; }; @@ -30,9 +30,9 @@ ACA1032C1E3E3391004B8CD4 /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */; }; ACA1032D1E3E3392004B8CD4 /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */; }; ACA1032E1E3E3393004B8CD4 /* TypeParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */; }; - ACA1032F1E3E3397004B8CD4 /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */; }; - ACA103301E3E3398004B8CD4 /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */; }; - ACA103311E3E339A004B8CD4 /* WarningsSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */; }; + ACA1032F1E3E3397004B8CD4 /* ResolutionErrorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* ResolutionErrorSpec.swift */; }; + ACA103301E3E3398004B8CD4 /* ResolutionErrorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* ResolutionErrorSpec.swift */; }; + ACA103311E3E339A004B8CD4 /* ResolutionErrorSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103271E3E3386004B8CD4 /* ResolutionErrorSpec.swift */; }; ACA103321E3E339E004B8CD4 /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */; }; ACA103331E3E339F004B8CD4 /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */; }; ACA103341E3E33A0004B8CD4 /* AutoregistrationSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */; }; @@ -333,14 +333,14 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - AC1191091E301CD200B112D9 /* Warning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Warning.swift; sourceTree = ""; }; + AC1191091E301CD200B112D9 /* ResolutionError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResolutionError.swift; sourceTree = ""; }; AC1191171E301E3A00B112D9 /* Resolver.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Resolver.swift; sourceTree = ""; }; AC1191181E301E3A00B112D9 /* CheckResolved.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CheckResolved.swift; sourceTree = ""; }; AC4AC9481E33C71D00E6355A /* TypeParser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParser.swift; sourceTree = ""; }; AC4AC94A1E33C75200E6355A /* Type.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Type.swift; sourceTree = ""; }; ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoregistrationSpec.swift; sourceTree = ""; }; ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeParserTests.swift; sourceTree = ""; }; - ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WarningsSpec.swift; sourceTree = ""; }; + ACA103271E3E3386004B8CD4 /* ResolutionErrorSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResolutionErrorSpec.swift; sourceTree = ""; }; CD5B9E231D832A4F007ED05F /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = ""; }; CD5B9E251D832A4F007ED05F /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; CD5B9E261D832A4F007ED05F /* Profile.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Profile.xcconfig; sourceTree = ""; }; @@ -463,7 +463,7 @@ children = ( ACA103251E3E3386004B8CD4 /* AutoregistrationSpec.swift */, ACA103261E3E3386004B8CD4 /* TypeParserTests.swift */, - ACA103271E3E3386004B8CD4 /* WarningsSpec.swift */, + ACA103271E3E3386004B8CD4 /* ResolutionErrorSpec.swift */, ); path = SwinjectAutoregistrationTests; sourceTree = ""; @@ -616,7 +616,7 @@ AC1191181E301E3A00B112D9 /* CheckResolved.swift */, CD5B9E8C1D832BF9007ED05F /* AutoRegistration.swift */, CD5B9E8D1D832BF9007ED05F /* Operators.swift */, - AC1191091E301CD200B112D9 /* Warning.swift */, + AC1191091E301CD200B112D9 /* ResolutionError.swift */, CD5B9ED81D832E18007ED05F /* Info.plist */, CD5B9ED91D832E18007ED05F /* SwinjectAutoregistration.h */, ); @@ -1140,7 +1140,7 @@ buildActionMask = 2147483647; files = ( CD5B9EE01D833088007ED05F /* AutoRegistration.swift in Sources */, - AC11910A1E301CD200B112D9 /* Warning.swift in Sources */, + AC11910A1E301CD200B112D9 /* ResolutionError.swift in Sources */, AC11911A1E301E3A00B112D9 /* CheckResolved.swift in Sources */, CD5B9EE11D833088007ED05F /* Operators.swift in Sources */, AC1191191E301E3A00B112D9 /* Resolver.swift in Sources */, @@ -1155,7 +1155,7 @@ files = ( ACA1032C1E3E3391004B8CD4 /* TypeParserTests.swift in Sources */, ACA103321E3E339E004B8CD4 /* AutoregistrationSpec.swift in Sources */, - ACA1032F1E3E3397004B8CD4 /* WarningsSpec.swift in Sources */, + ACA1032F1E3E3397004B8CD4 /* ResolutionErrorSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1168,7 +1168,7 @@ AC4AC94C1E33CB9100E6355A /* TypeParser.swift in Sources */, CD5B9EF81D8333A9007ED05F /* AutoRegistration.swift in Sources */, AC4AC94F1E33CB9600E6355A /* Type.swift in Sources */, - AC1191211E30211300B112D9 /* Warning.swift in Sources */, + AC1191211E30211300B112D9 /* ResolutionError.swift in Sources */, CD5B9EF91D8333A9007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1182,7 +1182,7 @@ AC4AC94D1E33CB9100E6355A /* TypeParser.swift in Sources */, CD5B9F201D833697007ED05F /* AutoRegistration.swift in Sources */, AC4AC9501E33CB9700E6355A /* Type.swift in Sources */, - AC1191221E30211400B112D9 /* Warning.swift in Sources */, + AC1191221E30211400B112D9 /* ResolutionError.swift in Sources */, CD5B9F211D833697007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1193,7 +1193,7 @@ files = ( ACA1032D1E3E3392004B8CD4 /* TypeParserTests.swift in Sources */, ACA103331E3E339F004B8CD4 /* AutoregistrationSpec.swift in Sources */, - ACA103301E3E3398004B8CD4 /* WarningsSpec.swift in Sources */, + ACA103301E3E3398004B8CD4 /* ResolutionErrorSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1206,7 +1206,7 @@ AC4AC94E1E33CB9200E6355A /* TypeParser.swift in Sources */, CD5B9F701D8338FC007ED05F /* AutoRegistration.swift in Sources */, AC4AC9511E33CB9700E6355A /* Type.swift in Sources */, - AC1191231E30211500B112D9 /* Warning.swift in Sources */, + AC1191231E30211500B112D9 /* ResolutionError.swift in Sources */, CD5B9F711D8338FC007ED05F /* Operators.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1217,7 +1217,7 @@ files = ( ACA1032E1E3E3393004B8CD4 /* TypeParserTests.swift in Sources */, ACA103341E3E33A0004B8CD4 /* AutoregistrationSpec.swift in Sources */, - ACA103311E3E339A004B8CD4 /* WarningsSpec.swift in Sources */, + ACA103311E3E339A004B8CD4 /* ResolutionErrorSpec.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift b/Tests/SwinjectAutoregistrationTests/ResolutionErrorSpec.swift similarity index 75% rename from Tests/SwinjectAutoregistrationTests/WarningsSpec.swift rename to Tests/SwinjectAutoregistrationTests/ResolutionErrorSpec.swift index e67d121..b89e225 100644 --- a/Tests/SwinjectAutoregistrationTests/WarningsSpec.swift +++ b/Tests/SwinjectAutoregistrationTests/ResolutionErrorSpec.swift @@ -4,9 +4,9 @@ import Nimble @testable import SwinjectAutoregistration -extension Warning: Equatable {} +extension ResolutionError: Equatable {} -public func ==(lhs: Warning, rhs: Warning) -> Bool { +public func ==(lhs: ResolutionError, rhs: ResolutionError) -> Bool { switch (lhs, rhs){ case (.optional(let lname), .optional(let rname)): return lname == rname @@ -19,7 +19,7 @@ public func ==(lhs: Warning, rhs: Warning) -> Bool { } } -class WarningsSpec: QuickSpec { +class ResolutionErrorSpec: QuickSpec { class DependencyA {} class DependencyB {} @@ -84,54 +84,54 @@ class WarningsSpec: QuickSpec { override func spec() { describe("warnings checker") { it("does show warning for service with more than 9 dependencies"){ - let w = warnings(forInitializer: Service10.init) - expect(w.first) == Warning.tooManyDependencies(10) + let w = resolutionErrors(forInitializer: Service10.init) + expect(w.first) == ResolutionError.tooManyDependencies(10) } it("doesnt show warning for single dependency"){ - let w = warnings(forInitializer: Service1.init) + let w = resolutionErrors(forInitializer: Service1.init) expect(w.count) == 0 } it("doesnt show warning for service with 9 dependencies"){ - let w = warnings(forInitializer: Service9.init) + let w = resolutionErrors(forInitializer: Service9.init) expect(w.count) == 0 } it("does show warning for service with optional dependency"){ - let w = warnings(forInitializer: OptionalService.init) - expect(w.first) == Warning.optional("DependencyB") + let w = resolutionErrors(forInitializer: OptionalService.init) + expect(w.first) == ResolutionError.optional("DependencyB") } it("does show warning for service with implicitly unwrapped dependency"){ - let w = warnings(forInitializer: UnwrappedService.init) - expect(w.first) == Warning.implicitlyUnwrappedOptional("DependencyA") + let w = resolutionErrors(forInitializer: UnwrappedService.init) + expect(w.first) == ResolutionError.implicitlyUnwrappedOptional("DependencyA") } it("does show multiple warnings"){ - let w = warnings(forInitializer: BadService.init) + let w = resolutionErrors(forInitializer: BadService.init) expect(w.count) == 5 } // This fails // Single argument tuple looks exactly the same as multiple arguments when printed xit("doesnt show warning for single argument tuple of optionals"){ - let w = warnings(forInitializer: OptionalSingleTupleService.init) + let w = resolutionErrors(forInitializer: OptionalSingleTupleService.init) expect(w.count) == 0 } it("doesnt show warning for mutiple argument tuples of optionals"){ - let w = warnings(forInitializer: OptionalMutipleTupleService.init) + let w = resolutionErrors(forInitializer: OptionalMutipleTupleService.init) expect(w.count) == 0 } it("doesnt show warning for nested closures"){ - let w = warnings(forInitializer: NestedClosureService.init) + let w = resolutionErrors(forInitializer: NestedClosureService.init) expect(w.count) == 0 } it("does show warning for optional closure"){ - let w = warnings(forInitializer: OptionalNestedClosureService.init) + let w = resolutionErrors(forInitializer: OptionalNestedClosureService.init) expect(w.count) == 1 } diff --git a/bin/generate b/bin/generate index aec02e5..3611163 100755 --- a/bin/generate +++ b/bin/generate @@ -160,8 +160,8 @@ func checkGenerator(_ dependencies: Int) -> String { "func checkResolved(initializer: (\(generics)) -> Service, services\(servicesDefinition)){", " let unresolved = ( [\(lowercasedServicesString)] as [Any?] ).filter { $0 == nil }", " if unresolved.count > 0 {", - " let warningsMessage = warnings(forInitializer: initializer).map { \"\\($0.message)\\n\" }.joined()", - " fatalError(\"SwinjectAutoregistration: Resolution failed.\\n\\(warningsMessage)Unresolved service: \\(unresolvedService(\(lowercasedServicesString))!)\\nInitializer: (\(commaConcat(genericParameters.map{ "\\(\($0).self)" }))) -> \\(Service.self)\")", + " let errorMessage = resolutionErrors(forInitializer: initializer).map { \"\\($0.message)\\n\" }.joined()", + " fatalError(\"SwinjectAutoregistration: Resolution failed.\\n\\(errorMessage)Unresolved service: \\(unresolvedService(\(lowercasedServicesString))!)\\nInitializer: (\(commaConcat(genericParameters.map{ "\\(\($0).self)" }))) -> \\(Service.self)\")", " }", "}" ]