Compare commits
42 Commits
release/7.0.1
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| c3b601df0f | |||
| 56b0768d60 | |||
| 8cf87efb95 | |||
| 3aa9b334f1 | |||
| b2a0cda242 | |||
| 07eb66e87d | |||
| 82e3d02497 | |||
| 3b2f5a272f | |||
| eab2d424e7 | |||
| 0f2cda0a52 | |||
| 05c02c9645 | |||
| fa086dad8f | |||
| cdc09f5a03 | |||
| b94ed3bea2 | |||
| 0fd70e65dd | |||
| 97e7f4782f | |||
| f1fdbbc988 | |||
| e368bb3051 | |||
| 4ce4832960 | |||
| d3bd0c27e3 | |||
| be0c39ab6b | |||
| 0de45e7d53 | |||
| 3b421d0cff | |||
| f1234bf2b9 | |||
| b0d7153bfe | |||
| 0193aa6bf6 | |||
| de7ad3ac48 | |||
| 40ad490c48 | |||
| 95cc5df26f | |||
| 09a7115aff | |||
| 15c0002ea3 | |||
| 0644d85a9c | |||
| e1522a0bf3 | |||
| a659415496 | |||
| efe25d575b | |||
| 22c67fa30c | |||
| 7a091da44d | |||
| 9580976dd8 | |||
| a4f0256313 | |||
| 815e9ccd66 | |||
| b9bf9c4d75 | |||
| 530a20999a |
@@ -36,3 +36,4 @@ Carthage
|
||||
# SPM
|
||||
.build/
|
||||
Packages
|
||||
.swiftpm
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
4.2
|
||||
+30
-5
@@ -5,14 +5,25 @@ matrix:
|
||||
- script:
|
||||
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk macosx -destination 'platform=macOS,arch=x86_64' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
- pod spec lint --allow-warnings
|
||||
# - pod spec lint --allow-warnings
|
||||
- carthage build --no-skip-current
|
||||
- swift package clean && swift build && swift test
|
||||
os: osx
|
||||
osx_image: xcode10
|
||||
osx_image: xcode10.2
|
||||
language: objective-c
|
||||
before_install:
|
||||
- gem install cocoapods --version 1.6.0.beta.1 --no-document
|
||||
- gem install cocoapods --version 1.8.4 --no-document
|
||||
- script:
|
||||
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 11,OS=latest' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
- set -o pipefail && xcodebuild test -workspace Dip.xcworkspace -scheme Dip -sdk macosx -destination 'platform=macOS,arch=x86_64' ONLY_ACTIVE_ARCH=NO | xcpretty -c
|
||||
# - pod spec lint --allow-warnings
|
||||
- carthage build --no-skip-current
|
||||
- swift package clean && swift build && swift test
|
||||
os: osx
|
||||
osx_image: xcode11.2
|
||||
language: objective-c
|
||||
before_install:
|
||||
- gem install cocoapods --version 1.8.4 --no-document
|
||||
- script:
|
||||
- swift package clean && swift build && swift test
|
||||
os: linux
|
||||
@@ -22,8 +33,22 @@ matrix:
|
||||
before_install:
|
||||
- wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import -
|
||||
- cd ..
|
||||
- export SWIFT_VERSION=swift-4.2-RELEASE
|
||||
- wget https://swift.org/builds/swift-4.2-release/ubuntu1404/$SWIFT_VERSION/$SWIFT_VERSION-ubuntu14.04.tar.gz
|
||||
- export SWIFT_VERSION=swift-5.1-RELEASE
|
||||
- wget https://swift.org/builds/swift-5.1-release/ubuntu1404/$SWIFT_VERSION/$SWIFT_VERSION-ubuntu14.04.tar.gz
|
||||
- tar xzf $SWIFT_VERSION-ubuntu14.04.tar.gz
|
||||
- export PATH="${PWD}/${SWIFT_VERSION}-ubuntu14.04/usr/bin:${PATH}"
|
||||
- cd Dip
|
||||
- script:
|
||||
- swift package clean && swift build && swift test
|
||||
os: linux
|
||||
dist: trusty
|
||||
sudo: required
|
||||
language: generic
|
||||
before_install:
|
||||
- wget -q -O - https://swift.org/keys/all-keys.asc | gpg --import -
|
||||
- cd ..
|
||||
- export SWIFT_VERSION=swift-5.0-RELEASE
|
||||
- wget https://swift.org/builds/swift-5.0-release/ubuntu1404/$SWIFT_VERSION/$SWIFT_VERSION-ubuntu14.04.tar.gz
|
||||
- tar xzf $SWIFT_VERSION-ubuntu14.04.tar.gz
|
||||
- export PATH="${PWD}/${SWIFT_VERSION}-ubuntu14.04/usr/bin:${PATH}"
|
||||
- cd Dip
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# CHANGELOG
|
||||
|
||||
## Develop
|
||||
|
||||
## 7.1.1
|
||||
|
||||
* Fixed using `StoryboardInstantiatable` with SPM ([#233](https://github.com/AliSoftware/Dip/pull/233)).
|
||||
|
||||
## 7.1.0
|
||||
|
||||
* You can now use a shorthand syntax for resolving a single property using a key path, i.e. `resolvingProperty(\.value)`.
|
||||
* Swift 5.0 support ([#224](https://github.com/AliSoftware/Dip/pull/224)).
|
||||
* Fixed resolving nested types with the same local names ([#221](https://github.com/AliSoftware/Dip/pull/221)).
|
||||
* `@Injected` and `@IntectedWeak` property wrappers ([#225](https://github.com/AliSoftware/Dip/pull/225)).
|
||||
* Thread safety can be disabled on container level.
|
||||
|
||||
## 7.0.1
|
||||
|
||||
* Added a workaround for Swift 4.2 regression related to retaining weak properties ([#214](https://github.com/AliSoftware/Dip/issues/214)).
|
||||
|
||||
+4
-2
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "Dip"
|
||||
s.version = "7.0.1"
|
||||
s.version = "7.1.1"
|
||||
s.summary = "Dependency Injection for Swift made easy."
|
||||
|
||||
s.description = <<-DESC
|
||||
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
|
||||
|
||||
s.homepage = "https://github.com/AliSoftware/Dip"
|
||||
s.license = 'MIT'
|
||||
s.authors = { "Olivier Halligon" => "olivier@halligon.net", "Ilya Puchka" => "ilya@puchka.me" }
|
||||
s.authors = { "Olivier Halligon" => "olivier@halligon.net", "Ilya Puchka" => "ilyapuchka@gmail.com" }
|
||||
s.source = { :git => "https://github.com/AliSoftware/Dip.git", :tag => s.version.to_s }
|
||||
s.social_media_url = 'https://twitter.com/aligatr'
|
||||
|
||||
@@ -23,4 +23,6 @@ Pod::Spec.new do |s|
|
||||
s.requires_arc = true
|
||||
|
||||
s.source_files = 'Sources/**/*.swift'
|
||||
|
||||
s.swift_version = "5.0", "5.1"
|
||||
end
|
||||
|
||||
@@ -221,25 +221,26 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0730;
|
||||
LastUpgradeCheck = 0930;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = AliSoftware;
|
||||
TargetAttributes = {
|
||||
0903B3571C161543002241C1 = {
|
||||
CreatedOnToolsVersion = 7.1.1;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 1020;
|
||||
};
|
||||
0903B3601C161543002241C1 = {
|
||||
CreatedOnToolsVersion = 7.1.1;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 1020;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 0945268B1BEA1CFF0034E72A /* Build configuration list for PBXProject "Dip" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
Base,
|
||||
);
|
||||
mainGroup = 094526871BEA1CFF0034E72A;
|
||||
productRefGroup = 094526921BEA1CFF0034E72A /* Products */;
|
||||
@@ -360,7 +361,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alisoftware.Dip;
|
||||
PRODUCT_NAME = Dip;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -380,7 +381,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alisoftware.Dip;
|
||||
PRODUCT_NAME = Dip;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -402,7 +403,7 @@
|
||||
"STORYBOARD_NAME_PREFIX[sdk=iphoneos*]" = UI;
|
||||
"STORYBOARD_NAME_PREFIX[sdk=iphonesimulator*]" = UI;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -419,7 +420,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.alisoftware.DipTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
STORYBOARD_NAME_PREFIX = "";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -427,6 +428,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
@@ -477,12 +479,12 @@
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SUPPORTED_PLATFORMS = "macosx watchsimulator iphonesimulator appletvsimulator watchos appletvos iphoneos";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 3.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -490,6 +492,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
@@ -533,13 +536,13 @@
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SUPPORTED_PLATFORMS = "macosx watchsimulator iphonesimulator appletvsimulator watchos appletvos iphoneos";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 4.0;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2,3,4";
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
VERSION_INFO_PREFIX = "";
|
||||
WATCHOS_DEPLOYMENT_TARGET = 2.0;
|
||||
WATCHOS_DEPLOYMENT_TARGET = 3.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0930"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>7.0.1</string>
|
||||
<string>7.1.1</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>7.0.1</string>
|
||||
<string>7.1.1</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.0)
|
||||
activesupport (4.2.11)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
atomos (0.1.3)
|
||||
claide (1.0.2)
|
||||
cocoapods (1.4.0)
|
||||
activesupport (>= 4.0.2, < 5)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.4.0)
|
||||
cocoapods-deintegrate (>= 1.0.2, < 2.0)
|
||||
cocoapods-downloader (>= 1.1.3, < 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.3.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (~> 2.0.1)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.6.4)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (~> 1.1)
|
||||
xcodeproj (>= 1.5.4, < 2.0)
|
||||
cocoapods-core (1.4.0)
|
||||
activesupport (>= 4.0.2, < 6)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.2)
|
||||
cocoapods-downloader (1.2.2)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.0)
|
||||
cocoapods-stats (1.0.0)
|
||||
cocoapods-trunk (1.3.1)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.1.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.1.4)
|
||||
escape (0.0.4)
|
||||
fourflusher (2.0.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
minitest (5.11.3)
|
||||
molinillo (0.6.6)
|
||||
nanaimo (0.2.6)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
ruby-macho (1.3.1)
|
||||
thread_safe (0.3.6)
|
||||
tzinfo (1.2.5)
|
||||
thread_safe (~> 0.1)
|
||||
xcodeproj (1.7.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.2.6)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods (= 1.4.0)
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.5
|
||||
@@ -0,0 +1,8 @@
|
||||
import XCTest
|
||||
|
||||
import DipTests
|
||||
|
||||
var tests = [XCTestCaseEntry]()
|
||||
tests += DipTests.__allTests()
|
||||
|
||||
XCTMain(tests)
|
||||
+9
-24
@@ -1,30 +1,15 @@
|
||||
//
|
||||
// Dip
|
||||
//
|
||||
// Copyright (c) 2015 Olivier Halligon <olivier@halligon.net>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
// swift-tools-version:5.0
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "Dip"
|
||||
name: "Dip",
|
||||
products: [
|
||||
.library(name: "Dip", targets: ["Dip"]),
|
||||
],
|
||||
targets: [
|
||||
.target(name: "Dip", dependencies: [], path: "Sources"),
|
||||
.testTarget(name: "DipTests", dependencies: ["Dip"], path: "Tests"),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@@ -279,7 +279,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0930;
|
||||
LastUpgradeCheck = 1020;
|
||||
ORGANIZATIONNAME = AliSoftware;
|
||||
TargetAttributes = {
|
||||
0990225E1BC123C000E76F43 = {
|
||||
@@ -292,7 +292,7 @@
|
||||
};
|
||||
buildConfigurationList = 607FACCB1AFB9204008FA782 /* Build configuration list for PBXProject "DipSampleApp" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
@@ -423,6 +423,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
@@ -479,6 +480,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0930"
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>7.0.1</string>
|
||||
<string>7.1.1</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>7.0.1</string>
|
||||
<string>7.1.1</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
|
||||
+205
-81
@@ -78,7 +78,7 @@ extension DependencyContainer {
|
||||
```
|
||||
|
||||
*/
|
||||
public protocol AutoInjectedPropertyBox: class {
|
||||
public protocol AutoInjectedPropertyBox {
|
||||
///The type of wrapped property.
|
||||
static var wrappedType: Any.Type { get }
|
||||
|
||||
@@ -93,40 +93,108 @@ public protocol AutoInjectedPropertyBox: class {
|
||||
func resolve(_ container: DependencyContainer) throws
|
||||
}
|
||||
|
||||
#if swift(>=5.1)
|
||||
/**
|
||||
Use this wrapper to identify _strong_ properties of the instance that should be
|
||||
auto-injected by `DependencyContainer`. Type T can be any type.
|
||||
|
||||
- warning: Do not define this property as optional or container will not be able to inject it.
|
||||
Instead define it with initial value of `Injected<T>()`.
|
||||
|
||||
|
||||
**Example**:
|
||||
|
||||
```swift
|
||||
class ClientImp: Client {
|
||||
@Injected var service: Service?
|
||||
}
|
||||
```
|
||||
|
||||
- seealso: `InjectedWeak`
|
||||
|
||||
*/
|
||||
@propertyWrapper
|
||||
public struct Injected<T>: _InjectedPropertyBox, AutoInjectedPropertyBox {
|
||||
let valueBox: NullableBox<T> = NullableBox(nil)
|
||||
|
||||
///Wrapped value.
|
||||
public var wrappedValue: T? {
|
||||
get {
|
||||
return valueBox.unboxed
|
||||
}
|
||||
set {
|
||||
guard (required && newValue != nil) || !required else {
|
||||
fatalError("Can not set required property to nil.")
|
||||
}
|
||||
valueBox.unboxed = newValue
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let required: Bool
|
||||
let didInject: (T) -> ()
|
||||
let tag: DependencyContainer.Tag?
|
||||
let overrideTag: Bool
|
||||
|
||||
public init(wrappedValue initialValue: T?) {
|
||||
self.init()
|
||||
}
|
||||
}
|
||||
#else
|
||||
/**
|
||||
Use this wrapper to identify _strong_ properties of the instance that should be
|
||||
auto-injected by `DependencyContainer`. Type T can be any type.
|
||||
|
||||
- warning: Do not define this property as optional or container will not be able to inject it.
|
||||
Instead define it with initial value of `Injected<T>()`.
|
||||
|
||||
**Example**:
|
||||
|
||||
```swift
|
||||
class ClientImp: Client {
|
||||
var service = Injected<Service>()
|
||||
}
|
||||
```
|
||||
|
||||
- seealso: `InjectedWeak`
|
||||
|
||||
*/
|
||||
public final class Injected<T>: _InjectedPropertyBox<T>, AutoInjectedPropertyBox {
|
||||
|
||||
*/
|
||||
public struct Injected<T>: _InjectedPropertyBox, AutoInjectedPropertyBox {
|
||||
let valueBox: NullableBox<T> = NullableBox(nil)
|
||||
|
||||
///Wrapped value.
|
||||
public var value: T? {
|
||||
return valueBox.unboxed
|
||||
}
|
||||
|
||||
let required: Bool
|
||||
let didInject: (T) -> ()
|
||||
let tag: DependencyContainer.Tag?
|
||||
let overrideTag: Bool
|
||||
|
||||
/// Returns a new wrapper with provided value.
|
||||
func setValue(_ value: T?) -> Injected {
|
||||
guard (required && value != nil) || !required else {
|
||||
fatalError("Can not set required property to nil.")
|
||||
}
|
||||
|
||||
return Injected(value: value, required: required, tag: tag, overrideTag: overrideTag, didInject: didInject)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public extension Injected {
|
||||
///The type of wrapped property.
|
||||
public static var wrappedType: Any.Type {
|
||||
static var wrappedType: Any.Type {
|
||||
return T.self
|
||||
}
|
||||
|
||||
///Wrapped value.
|
||||
public internal(set) var value: T? {
|
||||
didSet {
|
||||
if let value = value { didInject(value) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init(value: T?, required: Bool = true, tag: DependencyTagConvertible?, overrideTag: Bool, didInject: @escaping (T) -> ()) {
|
||||
self.value = value
|
||||
super.init(required: required, tag: tag, overrideTag: overrideTag, didInject: didInject)
|
||||
self.init(required: required, tag: tag, overrideTag: overrideTag, didInject: didInject)
|
||||
self.valueBox.unboxed = value
|
||||
}
|
||||
|
||||
init(required: Bool = true, tag: DependencyTagConvertible?, overrideTag: Bool, didInject: @escaping (T) -> () = { _ in }) {
|
||||
self.required = required
|
||||
self.tag = tag?.dependencyTag
|
||||
self.overrideTag = overrideTag
|
||||
self.didInject = didInject
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,30 +208,24 @@ public final class Injected<T>: _InjectedPropertyBox<T>, AutoInjectedPropertyBox
|
||||
- didInject: Block that will be called when concrete instance is injected in this property.
|
||||
Similar to `didSet` property observer. Default value does nothing.
|
||||
*/
|
||||
public convenience init(required: Bool = true, didInject: @escaping (T) -> () = { _ in }) {
|
||||
init(required: Bool = true, didInject: @escaping (T) -> () = { _ in }) {
|
||||
self.init(value: nil, required: required, tag: nil, overrideTag: false, didInject: didInject)
|
||||
}
|
||||
|
||||
public convenience init(required: Bool = true, tag: DependencyTagConvertible?, didInject: @escaping (T) -> () = { _ in }) {
|
||||
init(required: Bool = true, tag: DependencyTagConvertible?, didInject: @escaping (T) -> () = { _ in }) {
|
||||
self.init(value: nil, required: required, tag: tag, overrideTag: true, didInject: didInject)
|
||||
}
|
||||
|
||||
public func resolve(_ container: DependencyContainer) throws {
|
||||
let resolved: T? = try super.resolve(with: container)
|
||||
value = resolved
|
||||
}
|
||||
|
||||
/// Returns a new wrapper with provided value.
|
||||
public func setValue(_ value: T?) -> Injected {
|
||||
guard (required && value != nil) || !required else {
|
||||
fatalError("Can not set required property to nil.")
|
||||
func resolve(_ container: DependencyContainer) throws {
|
||||
let resolved: T? = try self.resolve(with: container, tag: tag, overrideTag: overrideTag, required: required)
|
||||
valueBox.unboxed = resolved
|
||||
if let resolved = resolved {
|
||||
didInject(resolved)
|
||||
}
|
||||
|
||||
return Injected(value: value, required: required, tag: tag, overrideTag: overrideTag, didInject: didInject)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if swift(>=5.1)
|
||||
/**
|
||||
Use this wrapper to identify _weak_ properties of the instance that should be
|
||||
auto-injected by `DependencyContainer`. Type T should be a **class** type.
|
||||
@@ -185,42 +247,124 @@ public final class Injected<T>: _InjectedPropertyBox<T>, AutoInjectedPropertyBox
|
||||
|
||||
```swift
|
||||
class ServiceImp: Service {
|
||||
var client = InjectedWeak<Client>()
|
||||
@InjectedWeak var client: Client?
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
- seealso: `Injected`
|
||||
|
||||
*/
|
||||
public final class InjectedWeak<T>: _InjectedPropertyBox<T>, AutoInjectedPropertyBox {
|
||||
@propertyWrapper
|
||||
public struct InjectedWeak<T>: _InjectedPropertyBox, AutoInjectedPropertyBox {
|
||||
|
||||
//Only classes (means AnyObject) can be used as `weak` properties
|
||||
//but we can not make <T: AnyObject> because that will prevent using protocol as generic type
|
||||
//so we just rely on user reading documentation and passing AnyObject in runtime
|
||||
//also we will throw fatal error if type can not be casted to AnyObject during resolution.
|
||||
|
||||
///The type of wrapped property.
|
||||
public static var wrappedType: Any.Type {
|
||||
return T.self
|
||||
}
|
||||
|
||||
var valueBox: WeakBox<T>? = nil {
|
||||
didSet {
|
||||
if let value = value { didInject(value) }
|
||||
|
||||
let valueBox: WeakBox<T> = WeakBox(nil)
|
||||
|
||||
///Wrapped value.
|
||||
public var wrappedValue: T? {
|
||||
get {
|
||||
return valueBox.value
|
||||
}
|
||||
set {
|
||||
guard (required && newValue != nil) || !required else {
|
||||
fatalError("Can not set required property to nil.")
|
||||
}
|
||||
|
||||
valueBox.unboxed = newValue as AnyObject
|
||||
}
|
||||
}
|
||||
|
||||
let required: Bool
|
||||
let didInject: (T) -> ()
|
||||
let tag: DependencyContainer.Tag?
|
||||
let overrideTag: Bool
|
||||
|
||||
public init(wrappedValue initialValue: T?) {
|
||||
self.init()
|
||||
}
|
||||
}
|
||||
#else
|
||||
/**
|
||||
Use this wrapper to identify _weak_ properties of the instance that should be
|
||||
auto-injected by `DependencyContainer`. Type T should be a **class** type.
|
||||
Otherwise it will cause runtime exception when container will try to resolve the property.
|
||||
Use this wrapper to define one of two circular dependencies to avoid retain cycle.
|
||||
|
||||
- note: The only difference between `InjectedWeak` and `Injected` is that `InjectedWeak` uses
|
||||
_weak_ reference to store underlying value, when `Injected` uses _strong_ reference.
|
||||
For that reason if you resolve instance that has a _weak_ auto-injected property this property
|
||||
will be released when `resolve` will complete.
|
||||
|
||||
Use `InjectedWeak<T>` to define one of two circular dependecies if another dependency is defined as `Injected<U>`.
|
||||
This will prevent a retain cycle between resolved instances.
|
||||
|
||||
- warning: Do not define this property as optional or container will not be able to inject it.
|
||||
Instead define it with initial value of `InjectedWeak<T>()`.
|
||||
|
||||
**Example**:
|
||||
|
||||
```swift
|
||||
class ServiceImp: Service {
|
||||
var client = InjectedWeak<Client>()
|
||||
}
|
||||
```
|
||||
|
||||
- seealso: `Injected`
|
||||
|
||||
*/
|
||||
public struct InjectedWeak<T>: _InjectedPropertyBox, AutoInjectedPropertyBox {
|
||||
|
||||
//Only classes (means AnyObject) can be used as `weak` properties
|
||||
//but we can not make <T: AnyObject> because that will prevent using protocol as generic type
|
||||
//so we just rely on user reading documentation and passing AnyObject in runtime
|
||||
//also we will throw fatal error if type can not be casted to AnyObject during resolution.
|
||||
|
||||
let valueBox: WeakBox<T> = WeakBox(nil)
|
||||
|
||||
///Wrapped value.
|
||||
public var value: T? {
|
||||
return valueBox?.value
|
||||
return valueBox.value
|
||||
}
|
||||
|
||||
init(value: T?, required: Bool = true, tag: DependencyTagConvertible?, overrideTag: Bool, didInject: @escaping (T) -> ()) {
|
||||
self.valueBox = value.map(WeakBox.init)
|
||||
super.init(required: required, tag: tag, overrideTag: overrideTag, didInject: didInject)
|
||||
let required: Bool
|
||||
let didInject: (T) -> ()
|
||||
let tag: DependencyContainer.Tag?
|
||||
let overrideTag: Bool
|
||||
|
||||
|
||||
/// Returns a new wrapper with provided value.
|
||||
func setValue(_ value: T?) -> InjectedWeak {
|
||||
guard (required && value != nil) || !required else {
|
||||
fatalError("Can not set required property to nil.")
|
||||
}
|
||||
|
||||
return InjectedWeak(value: value, required: required, tag: tag, overrideTag: overrideTag, didInject: didInject)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public extension InjectedWeak {
|
||||
///The type of wrapped property.
|
||||
static var wrappedType: Any.Type {
|
||||
return T.self
|
||||
}
|
||||
|
||||
init(value: T?, required: Bool = true, tag: DependencyTagConvertible?, overrideTag: Bool, didInject: @escaping (T) -> ()) {
|
||||
self.init(required: required, tag: tag, overrideTag: overrideTag, didInject: didInject)
|
||||
self.valueBox.unboxed = value as AnyObject
|
||||
}
|
||||
|
||||
init(required: Bool = true, tag: DependencyTagConvertible?, overrideTag: Bool, didInject: @escaping (T) -> () = { _ in }) {
|
||||
self.required = required
|
||||
self.tag = tag?.dependencyTag
|
||||
self.overrideTag = overrideTag
|
||||
self.didInject = didInject
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a new wrapper for weak auto-injected property.
|
||||
|
||||
@@ -232,46 +376,28 @@ public final class InjectedWeak<T>: _InjectedPropertyBox<T>, AutoInjectedPropert
|
||||
- didInject: Block that will be called when concrete instance is injected in this property.
|
||||
Similar to `didSet` property observer. Default value does nothing.
|
||||
*/
|
||||
public convenience init(required: Bool = true, didInject: @escaping (T) -> () = { _ in }) {
|
||||
init(required: Bool = true, didInject: @escaping (T) -> () = { _ in }) {
|
||||
self.init(value: nil, required: required, tag: nil, overrideTag: false, didInject: didInject)
|
||||
}
|
||||
|
||||
public convenience init(required: Bool = true, tag: DependencyTagConvertible?, didInject: @escaping (T) -> () = { _ in }) {
|
||||
init(required: Bool = true, tag: DependencyTagConvertible?, didInject: @escaping (T) -> () = { _ in }) {
|
||||
self.init(value: nil, required: required, tag: tag, overrideTag: true, didInject: didInject)
|
||||
}
|
||||
|
||||
public func resolve(_ container: DependencyContainer) throws {
|
||||
let resolved: T? = try super.resolve(with: container)
|
||||
valueBox = resolved.map(WeakBox.init)
|
||||
}
|
||||
|
||||
/// Returns a new wrapper with provided value.
|
||||
public func setValue(_ value: T?) -> InjectedWeak {
|
||||
guard (required && value != nil) || !required else {
|
||||
fatalError("Can not set required property to nil.")
|
||||
func resolve(_ container: DependencyContainer) throws {
|
||||
let resolved: T? = try self.resolve(with: container, tag: tag, overrideTag: overrideTag, required: required)
|
||||
valueBox.unboxed = resolved as AnyObject
|
||||
if let resolved = resolved {
|
||||
didInject(resolved)
|
||||
}
|
||||
|
||||
return InjectedWeak(value: value, required: required, tag: tag, overrideTag: overrideTag, didInject: didInject)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class _InjectedPropertyBox<T> {
|
||||
protocol _InjectedPropertyBox {}
|
||||
|
||||
let required: Bool
|
||||
let didInject: (T) -> ()
|
||||
let tag: DependencyContainer.Tag?
|
||||
let overrideTag: Bool
|
||||
|
||||
init(required: Bool = true, tag: DependencyTagConvertible?, overrideTag: Bool, didInject: @escaping (T) -> () = { _ in }) {
|
||||
self.required = required
|
||||
self.tag = tag?.dependencyTag
|
||||
self.overrideTag = overrideTag
|
||||
self.didInject = didInject
|
||||
}
|
||||
|
||||
func resolve(with container: DependencyContainer) throws -> T? {
|
||||
let tag = overrideTag ? self.tag : container.context.tag
|
||||
extension _InjectedPropertyBox {
|
||||
func resolve<T>(with container: DependencyContainer, tag: DependencyContainer.Tag?, overrideTag: Bool, required: Bool) throws -> T? {
|
||||
let tag = overrideTag ? tag : container.context.tag
|
||||
do {
|
||||
container.context.key = container.context.key.tagged(with: tag)
|
||||
let key = DefinitionKey(type: T.self, typeOfArguments: Void.self, tag: tag?.dependencyTag)
|
||||
@@ -289,12 +415,10 @@ public class _InjectedPropertyBox<T> {
|
||||
}
|
||||
}
|
||||
|
||||
private func resolve<U>(with container: DependencyContainer, key: DefinitionKey, builder: ((U) throws -> Any) throws -> Any) throws -> Any {
|
||||
func resolve<U>(with container: DependencyContainer, key: DefinitionKey, builder: ((U) throws -> Any) throws -> Any) throws -> Any {
|
||||
return try container._resolve(key: key, builder: { definition throws -> Any in
|
||||
try builder(definition.weakFactory)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,5 @@
|
||||
#if _runtime(_ObjC)
|
||||
extension String {
|
||||
func has(prefix aPrefix: String) -> Bool {
|
||||
return hasPrefix(aPrefix)
|
||||
}
|
||||
extension String {
|
||||
func has(prefix aPrefix: String) -> Bool {
|
||||
return hasPrefix(aPrefix)
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
extension String {
|
||||
func has(prefix aPrefix: String) -> Bool {
|
||||
return aPrefix ==
|
||||
String(self.characters.prefix(aPrefix.characters.count))
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -34,12 +34,14 @@ public struct DefinitionKey: Hashable, CustomStringConvertible {
|
||||
self.tag = tag
|
||||
}
|
||||
|
||||
public var hashValue: Int {
|
||||
return "\(type)-\(typeOfArguments)-\(tag.desc)".hashValue
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(ObjectIdentifier(type))
|
||||
hasher.combine(ObjectIdentifier(typeOfArguments))
|
||||
hasher.combine(tag.desc)
|
||||
}
|
||||
|
||||
public var description: String {
|
||||
return "type: \(type), arguments: \(typeOfArguments), tag: \(tag.desc)"
|
||||
return "type: \(String(reflecting: type)), arguments: \(typeOfArguments), tag: \(tag.desc)"
|
||||
}
|
||||
|
||||
func tagged(with tag: DependencyContainer.Tag?) -> DefinitionKey {
|
||||
@@ -53,7 +55,7 @@ public struct DefinitionKey: Hashable, CustomStringConvertible {
|
||||
return
|
||||
lhs.type == rhs.type &&
|
||||
lhs.typeOfArguments == rhs.typeOfArguments &&
|
||||
lhs.tag == rhs.tag
|
||||
lhs.tag.desc == rhs.tag.desc
|
||||
}
|
||||
|
||||
}
|
||||
@@ -126,6 +128,22 @@ public final class Definition<T, U>: DefinitionType {
|
||||
return self
|
||||
}
|
||||
|
||||
@discardableResult public func resolvingProperty<Root, V>(_ keyPath: ReferenceWritableKeyPath<Root, V>, as type: Any.Type = V.self, tag: DependencyTagConvertible? = nil) -> Definition {
|
||||
return resolvingProperties { (container, instance) in
|
||||
precondition(instance is Root, "Type of resolved instance \(Swift.type(of: instance)) does not match expected type \(Root.self)")
|
||||
let resolved = try container.resolve(type, tag: tag)
|
||||
precondition(resolved is V, "Type of resolved property \(Swift.type(of: resolved)) does not match expected type \(type)")
|
||||
(instance as! Root)[keyPath: keyPath] = resolved as! V
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult public func resolvingProperty<Root, V>(_ keyPath: ReferenceWritableKeyPath<Root, V>, factory: @escaping (DependencyContainer) throws -> V = { try $0.resolve() }) -> Definition {
|
||||
return resolvingProperties { (container, instance) in
|
||||
precondition(instance is Root, "Type of resolved instance \(Swift.type(of: instance)) does not match expected type \(Root.self)")
|
||||
(instance as! Root)[keyPath: keyPath] = try factory(container)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Whether container should perform properties auto-injection when resolving using this definition.
|
||||
If called will override container configuration. Can be called together with `resolvingProperties`
|
||||
|
||||
+8
-1
@@ -40,6 +40,7 @@ public final class DependencyContainer {
|
||||
}
|
||||
|
||||
var autoInjectProperties: Bool
|
||||
var threadSafe: Bool
|
||||
internal(set) public var context: Context!
|
||||
var definitions = [DefinitionKey: _Definition]()
|
||||
var resolvedInstances = ResolvedInstances()
|
||||
@@ -63,6 +64,7 @@ public final class DependencyContainer {
|
||||
|
||||
- Parameters:
|
||||
- autoInjectProperties: Whether container should perform properties auto-injection. Default is `true`.
|
||||
- threadSafe: Whether container should be thread-safe. Default is `true`. You may want to disable it for better performance.
|
||||
- configBlock: A configuration block in which you typically put all you `register` calls.
|
||||
|
||||
- note: The `configBlock` is simply called at the end of the `init` to let you configure everything.
|
||||
@@ -82,8 +84,9 @@ public final class DependencyContainer {
|
||||
|
||||
- returns: A new DependencyContainer.
|
||||
*/
|
||||
public init(autoInjectProperties: Bool = true, configBlock: (DependencyContainer)->() = { _ in }) {
|
||||
public init(autoInjectProperties: Bool = true, threadSafe: Bool = true, configBlock: (DependencyContainer)->() = { _ in }) {
|
||||
self.autoInjectProperties = autoInjectProperties
|
||||
self.threadSafe = threadSafe
|
||||
configBlock(self)
|
||||
}
|
||||
|
||||
@@ -104,6 +107,10 @@ public final class DependencyContainer {
|
||||
}
|
||||
|
||||
func threadSafe<T>(_ closure: () throws -> T) rethrows -> T {
|
||||
guard threadSafe else {
|
||||
return try closure()
|
||||
}
|
||||
|
||||
lock.lock()
|
||||
defer { lock.unlock() }
|
||||
return try closure()
|
||||
|
||||
@@ -77,18 +77,16 @@ public enum DipError: Error, CustomStringConvertible {
|
||||
public var description: String {
|
||||
switch self {
|
||||
case let .definitionNotFound(key):
|
||||
return "No definition registered for \(key).\nCheck the tag, type you try to resolve, number, order and types of runtime arguments passed to `resolve()` and match them with registered factories for type \(key.type)."
|
||||
return "No definition registered for \(key).\nCheck the tag, type you try to resolve, number, order and types of runtime arguments passed to `resolve()` and match them with registered factories for type \(String(reflecting: key.type))."
|
||||
case let .autoInjectionFailed(label, type, error):
|
||||
return "Failed to auto-inject property \"\(label.desc)\" of type \(type). \(error)"
|
||||
return "Failed to auto-inject property \"\(label.desc)\" of type \(String(reflecting: type)). \(error)"
|
||||
case let .autoWiringFailed(type, error):
|
||||
return "Failed to auto-wire type \"\(type)\". \(error)"
|
||||
return "Failed to auto-wire type \"\(String(reflecting: type))\". \(error)"
|
||||
case let .ambiguousDefinitions(type, definitions):
|
||||
return "Ambiguous definitions for \(type):\n" +
|
||||
return "Ambiguous definitions for \(String(reflecting: type)):\n" +
|
||||
definitions.map({ "\($0)" }).joined(separator: ";\n")
|
||||
case let .invalidType(resolved, key):
|
||||
return "Resolved instance \(resolved ?? "nil") does not implement expected type \(key.type)."
|
||||
return "Resolved instance \(resolved ?? "nil") does not implement expected type \(String(reflecting: key.type))."
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ extension DependencyContainer {
|
||||
return previouslyResolved
|
||||
}
|
||||
|
||||
log(level: .Verbose, context)
|
||||
if let context = context { log(level: .Verbose, context) }
|
||||
var resolvedInstance = try builder(definition)
|
||||
|
||||
/*
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#if (canImport(UIKit) || canImport(AppKit) || canImport(WatchKit)) && !SWIFT_PACKAGE
|
||||
#if (canImport(UIKit) || canImport(AppKit) || canImport(WatchKit))
|
||||
|
||||
extension DependencyContainer {
|
||||
///Containers that will be used to resolve dependencies of instances, created by stroyboards.
|
||||
|
||||
+9
-9
@@ -56,6 +56,13 @@ class Box<T> {
|
||||
}
|
||||
}
|
||||
|
||||
class NullableBox<T> {
|
||||
var unboxed: T?
|
||||
init(_ value: T?) {
|
||||
self.unboxed = value
|
||||
}
|
||||
}
|
||||
|
||||
protocol WeakBoxType {
|
||||
var unboxed: AnyObject? { get }
|
||||
}
|
||||
@@ -66,15 +73,8 @@ class WeakBox<T>: WeakBoxType {
|
||||
return unboxed as? T
|
||||
}
|
||||
|
||||
init(_ value: T) {
|
||||
#if _runtime(_ObjC)
|
||||
weak var value: AnyObject? = value as AnyObject
|
||||
#else
|
||||
weak var value: AnyObject? = value as? AnyObject
|
||||
#endif
|
||||
guard value != nil else {
|
||||
fatalError("Can not store weak reference to not a class instance (\(T.self))")
|
||||
}
|
||||
init(_ value: T?) {
|
||||
weak var value: AnyObject? = value as AnyObject
|
||||
self.unboxed = value
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,34 @@ private protocol Client: class {
|
||||
var anotherServer: Server! {get set}
|
||||
}
|
||||
|
||||
#if swift(>=5.1)
|
||||
private class ServerImp: Server {
|
||||
|
||||
@InjectedWeak(didInject: { _ in
|
||||
AutoInjectionTests.clientDidInjectCalled = true
|
||||
}) var client: Client!
|
||||
|
||||
@InjectedWeak(required: false) var _optionalProperty: AnyObject?
|
||||
|
||||
weak var anotherClient: Client!
|
||||
}
|
||||
|
||||
private class ClientImp: Client {
|
||||
|
||||
@Injected(didInject: { _ in
|
||||
AutoInjectionTests.serverDidInjectCalled = true
|
||||
}) var server: Server
|
||||
|
||||
@Injected(required: false) var _optionalProperty: AnyObject?
|
||||
|
||||
@Injected(tag: "tagged") var taggedServer: Server
|
||||
@Injected(tag: nil) var nilTaggedServer: Server
|
||||
|
||||
var anotherServer: Server!
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
private class ServerImp: Server {
|
||||
|
||||
var _client = InjectedWeak<Client>() { _ in
|
||||
@@ -67,7 +95,18 @@ private class ClientImp: Client {
|
||||
var taggedServer = Injected<Server>(tag: "tagged")
|
||||
var nilTaggedServer = Injected<Server>(tag: nil)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if swift(>=5.1)
|
||||
private class Obj1 {
|
||||
@InjectedWeak var obj2: Obj2?
|
||||
@Injected var obj3: Obj3?
|
||||
}
|
||||
|
||||
private class Obj2 {
|
||||
@Injected var obj1: Obj1?
|
||||
}
|
||||
#else
|
||||
private class Obj1 {
|
||||
let obj2 = InjectedWeak<Obj2>()
|
||||
let obj3 = Injected<Obj3>()
|
||||
@@ -76,6 +115,7 @@ private class Obj1 {
|
||||
private class Obj2 {
|
||||
let obj1 = Injected<Obj1>()
|
||||
}
|
||||
#endif
|
||||
|
||||
private class Obj3 {
|
||||
|
||||
@@ -92,29 +132,6 @@ class AutoInjectionTests: XCTestCase {
|
||||
static var clientDidInjectCalled: Bool = false
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testThatItResolvesAutoInjectedDependencies", testThatItResolvesAutoInjectedDependencies),
|
||||
("testThatItResolvesInheritedDependencies", testThatItResolvesInheritedDependencies),
|
||||
("testThatItCanSetInjectedProperty", testThatItCanSetInjectedProperty),
|
||||
("testThatItThrowsErrorIfFailsToAutoInjectDependency", testThatItThrowsErrorIfFailsToAutoInjectDependency),
|
||||
("testThatItResolvesAutoInjectedSingletons", testThatItResolvesAutoInjectedSingletons),
|
||||
("testThatItCallsResolveDependencyBlockWhenAutoInjecting", testThatItCallsResolveDependencyBlockWhenAutoInjecting),
|
||||
("testThatItReusesResolvedAutoInjectedInstances", testThatItReusesResolvedAutoInjectedInstances),
|
||||
("testThatItReusesAutoInjectedInstancesOnNextResolveOrAutoInjection", testThatItReusesAutoInjectedInstancesOnNextResolveOrAutoInjection),
|
||||
("testThatThereIsNoRetainCycleBetweenAutoInjectedCircularDependencies", testThatThereIsNoRetainCycleBetweenAutoInjectedCircularDependencies),
|
||||
("testThatItCallsDidInjectOnAutoInjectedProperty", testThatItCallsDidInjectOnAutoInjectedProperty),
|
||||
("testThatNoErrorThrownWhenOptionalPropertiesAreNotAutoInjected", testThatNoErrorThrownWhenOptionalPropertiesAreNotAutoInjected),
|
||||
("testThatItResolvesTaggedAutoInjectedProperties", testThatItResolvesTaggedAutoInjectedProperties),
|
||||
("testThatItPassesTagToAutoInjectedProperty", testThatItPassesTagToAutoInjectedProperty),
|
||||
("testThatItDoesNotPassTagToAutoInjectedPropertyWithExplicitTag", testThatItDoesNotPassTagToAutoInjectedPropertyWithExplicitTag),
|
||||
("testThatItAutoInjectsPropertyWithCollaboratingContainer", testThatItAutoInjectsPropertyWithCollaboratingContainer),
|
||||
("testThatItDoesNotAutoInjectIfDisabled", testThatItDoesNotAutoInjectIfDisabledInDefinition),
|
||||
("testThatItDoesNotAutoInjectIfDisabledInContainer", testThatItDoesNotAutoInjectIfDisabledInContainer),
|
||||
("testThatItAutoInjectsWhenOverridenInDefinition", testThatItAutoInjectsWhenOverridenInDefinition),
|
||||
]
|
||||
}()
|
||||
|
||||
override func setUp() {
|
||||
container.reset()
|
||||
@@ -131,10 +148,18 @@ class AutoInjectionTests: XCTestCase {
|
||||
|
||||
func testThatItResolvesInheritedDependencies() {
|
||||
class ServerImp2: ServerImp {
|
||||
#if swift(>=5.1)
|
||||
@InjectedWeak(didInject: { _ in
|
||||
XCTAssertTrue(AutoInjectionTests.serverDidInjectCalled, "Inherited properties should be resolved first")
|
||||
}) var client2: Client?
|
||||
#else
|
||||
var _client2 = InjectedWeak<Client>() { _ in
|
||||
XCTAssertTrue(AutoInjectionTests.serverDidInjectCalled, "Inherited properties should be resolved first")
|
||||
}
|
||||
var client2: Client? { return _client2.value }
|
||||
var client2: Client? {
|
||||
return _client2.value
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
container.register { ServerImp2() as Server }
|
||||
@@ -156,17 +181,23 @@ class AutoInjectionTests: XCTestCase {
|
||||
|
||||
let newServer = ServerImp()
|
||||
let newClient = ClientImp()
|
||||
#if swift(>=5.1)
|
||||
client.server = newServer
|
||||
server.client = newClient
|
||||
#else
|
||||
client._server = client._server.setValue(newServer)
|
||||
server._client = server._client.setValue(newClient)
|
||||
#endif
|
||||
|
||||
XCTAssertTrue(client.server === newServer)
|
||||
XCTAssertTrue(server.client === newClient)
|
||||
}
|
||||
|
||||
|
||||
|
||||
func testThatItThrowsErrorIfFailsToAutoInjectDependency() {
|
||||
container.register { ClientImp() as Client }
|
||||
|
||||
AssertThrows(expression: try container.resolve() as Client)
|
||||
XCTAssertThrowsError(try self.container.resolve() as Client)
|
||||
}
|
||||
|
||||
func testThatItResolvesAutoInjectedSingletons() {
|
||||
@@ -248,11 +279,19 @@ class AutoInjectionTests: XCTestCase {
|
||||
let obj2 = try! container.resolve() as Obj2
|
||||
|
||||
//then
|
||||
XCTAssertTrue(obj2 === obj2.obj1.value!.obj2.value!,
|
||||
#if swift(>=5.1)
|
||||
XCTAssertTrue(obj2 === obj2.obj1!.obj2!,
|
||||
"Auto-injected instance should be reused on next auto-injection")
|
||||
|
||||
XCTAssertTrue(obj2.obj1.value! === obj2.obj1.value!.obj3.value!.obj1,
|
||||
XCTAssertTrue(obj2.obj1! === obj2.obj1!.obj3!.obj1,
|
||||
"Auto-injected instance should be reused on next resolve")
|
||||
#else
|
||||
XCTAssertTrue(obj2 === obj2.obj1.value!.obj2.value!,
|
||||
"Auto-injected instance should be reused on next auto-injection")
|
||||
|
||||
XCTAssertTrue(obj2.obj1.value! === obj2.obj1.value!.obj3.value!.obj1,
|
||||
"Auto-injected instance should be reused on next resolve")
|
||||
#endif
|
||||
}
|
||||
|
||||
func testThatThereIsNoRetainCycleBetweenAutoInjectedCircularDependencies() {
|
||||
@@ -297,7 +336,10 @@ class AutoInjectionTests: XCTestCase {
|
||||
container.register { ServerImp() as Server }
|
||||
container.register { ClientImp() as Client }
|
||||
|
||||
AssertNoThrow(expression: try container.resolve() as Client, "Container should not throw error if failed to resolve optional auto-injected properties.")
|
||||
XCTAssertNoThrow(
|
||||
try container.resolve() as Client,
|
||||
"Container should not throw error if failed to resolve optional auto-injected properties."
|
||||
)
|
||||
}
|
||||
|
||||
func testThatItResolvesTaggedAutoInjectedProperties() {
|
||||
@@ -310,7 +352,11 @@ class AutoInjectionTests: XCTestCase {
|
||||
let client = try! container.resolve() as Client
|
||||
|
||||
//then
|
||||
#if swift(>=5.1)
|
||||
let taggedServer = (client as! ClientImp).taggedServer!
|
||||
#else
|
||||
let taggedServer = (client as! ClientImp).taggedServer.value!
|
||||
#endif
|
||||
let server = client.server!
|
||||
|
||||
//server and tagged server should be resolved as different instances
|
||||
@@ -329,7 +375,11 @@ class AutoInjectionTests: XCTestCase {
|
||||
let client = try! container.resolve(tag: "tagged") as Client
|
||||
|
||||
//then
|
||||
#if swift(>=5.1)
|
||||
let taggedServer = (client as! ClientImp).taggedServer!
|
||||
#else
|
||||
let taggedServer = (client as! ClientImp).taggedServer.value!
|
||||
#endif
|
||||
let server = client.server!
|
||||
|
||||
//server and tagged server should be resolved as the same instance
|
||||
@@ -350,8 +400,13 @@ class AutoInjectionTests: XCTestCase {
|
||||
let client = try! container.resolve(tag: "otherTag") as Client
|
||||
|
||||
//then
|
||||
#if swift(>=5.1)
|
||||
let taggedServer = (client as! ClientImp).taggedServer!
|
||||
let nilTaggedServer = (client as! ClientImp).nilTaggedServer!
|
||||
#else
|
||||
let taggedServer = (client as! ClientImp).taggedServer.value!
|
||||
let nilTaggedServer = (client as! ClientImp).nilTaggedServer.value!
|
||||
#endif
|
||||
let server = client.server!
|
||||
|
||||
//server and tagged server should be resolved as different instances
|
||||
@@ -362,15 +417,50 @@ class AutoInjectionTests: XCTestCase {
|
||||
XCTAssertNotNil(taggedServer)
|
||||
XCTAssertNotNil(nilTaggedServer)
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct Foo
|
||||
{
|
||||
struct Bar
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct Baz
|
||||
{
|
||||
struct Bar
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func testScopedTypes() {
|
||||
let key1 = DefinitionKey(type: Baz.Bar.self, typeOfArguments: Void.self)
|
||||
let key2 = DefinitionKey(type: Foo.Bar.self, typeOfArguments: Void.self)
|
||||
|
||||
XCTAssertNotEqual(key1, key2)
|
||||
XCTAssertNotEqual(key1.hashValue, key2.hashValue)
|
||||
|
||||
container.register { Baz.Bar() }
|
||||
|
||||
XCTAssertNotNil(try? container.resolve() as Baz.Bar)
|
||||
XCTAssertThrowsError(try container.resolve() as Foo.Bar)
|
||||
|
||||
container.register { Foo.Bar() }
|
||||
|
||||
XCTAssertNotNil(try? container.resolve() as Foo.Bar)
|
||||
}
|
||||
|
||||
func testThatItAutoInjectsPropertyWithCollaboratingContainer() {
|
||||
let collaborator = DependencyContainer()
|
||||
collaborator.register { ServerImp() as Server }
|
||||
container.register { ClientImp() as Client }
|
||||
|
||||
|
||||
container.collaborate(with: collaborator)
|
||||
collaborator.collaborate(with: container)
|
||||
|
||||
|
||||
let client = try! container.resolve() as Client
|
||||
let server = client.server
|
||||
XCTAssertTrue(client === server?.client)
|
||||
|
||||
@@ -50,30 +50,6 @@ class AutoWiringTests: XCTestCase {
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testThatItCanResolveWithAutoWiring", testThatItCanResolveWithAutoWiring),
|
||||
("testThatItUsesAutoWireFactoryWithMostNumberOfArguments", testThatItUsesAutoWireFactoryWithMostNumberOfArguments),
|
||||
("testThatItThrowsAmbiguityErrorWhenUsingAutoWire", testThatItThrowsAmbiguityErrorWhenUsingAutoWire),
|
||||
("testThatItUsesAutoWireFactoryWithMostNumberOfArguments", testThatItUsesAutoWireFactoryWithMostNumberOfArguments),
|
||||
("testThatItPrefersTaggedFactoryWithDifferentNumberOfArgumentsWhenUsingAutoWire", testThatItPrefersTaggedFactoryWithDifferentNumberOfArgumentsWhenUsingAutoWire),
|
||||
("testThatItPrefersTaggedFactoryWithDifferentTypesOfArgumentsWhenUsingAutoWire", testThatItPrefersTaggedFactoryWithDifferentTypesOfArgumentsWhenUsingAutoWire),
|
||||
("testThatItFallbackToNotTaggedFactoryWhenUsingAutoWire", testThatItFallbackToNotTaggedFactoryWhenUsingAutoWire),
|
||||
("testThatItDoesNotTryToUseAutoWiringWhenCallingResolveWithArguments", testThatItDoesNotTryToUseAutoWiringWhenCallingResolveWithArguments),
|
||||
("testThatItDoesNotUseAutoWiringWhenFailedToResolveLowLevelDependency", testThatItDoesNotUseAutoWiringWhenFailedToResolveLowLevelDependency),
|
||||
("testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgain", testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgain),
|
||||
("testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithTheSameTag", testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithTheSameTag),
|
||||
("testThatItDoesNotReuseInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithAnotherTag", testThatItDoesNotReuseInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithAnotherTag),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith1Argument", testThatItUsesTagToResolveDependenciesWithAutoWiringWith1Argument),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith2Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith2Arguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith3Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith3Arguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith4Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith4Arguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith5Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith5Arguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith6Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith6Arguments),
|
||||
("testThatItCanAutoWireOptional", testThatItCanAutoWireOptional)
|
||||
]
|
||||
}()
|
||||
|
||||
override func setUp() {
|
||||
container.reset()
|
||||
}
|
||||
@@ -138,12 +114,10 @@ class AutoWiringTests: XCTestCase {
|
||||
container.register { ServiceImp2() }
|
||||
|
||||
//when
|
||||
AssertThrows(expression: try container.resolve() as AutoWiredClient) { error -> Bool in
|
||||
switch error {
|
||||
case let DipError.autoWiringFailed(_, error):
|
||||
if case DipError.ambiguousDefinitions = error { return true }
|
||||
else { return false }
|
||||
default: return false
|
||||
XCTAssertThrowsError(try self.container.resolve() as AutoWiredClient) { (error) in
|
||||
guard case DipError.autoWiringFailed(_, DipError.ambiguousDefinitions) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,8 +207,12 @@ class AutoWiringTests: XCTestCase {
|
||||
|
||||
//when
|
||||
let service = try! container.resolve() as Service
|
||||
AssertThrows(expression: try container.resolve(arguments: service) as AutoWiredClient,
|
||||
"Container should not use auto-wiring when resolving with runtime arguments")
|
||||
|
||||
// then
|
||||
XCTAssertThrowsError(
|
||||
try self.container.resolve(arguments: service) as AutoWiredClient,
|
||||
"Container should not use auto-wiring when resolving with runtime arguments"
|
||||
)
|
||||
}
|
||||
|
||||
func testThatItDoesNotUseAutoWiringWhenFailedToResolveLowLevelDependency() {
|
||||
@@ -259,12 +237,13 @@ class AutoWiringTests: XCTestCase {
|
||||
container.register { ServiceImp2() }
|
||||
|
||||
//then
|
||||
AssertThrows(expression: try container.resolve() as AutoWiredClient,
|
||||
"Container should not use auto-wiring when definition for resolved type is registered.")
|
||||
XCTAssertThrowsError(
|
||||
try self.container.resolve() as AutoWiredClient,
|
||||
"Container should not use auto-wiring when definition for resolved type is registered."
|
||||
)
|
||||
}
|
||||
|
||||
func testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgain() {
|
||||
|
||||
//given
|
||||
container.register { ServiceImp1() as Service }
|
||||
container.register { ServiceImp2() }
|
||||
@@ -282,8 +261,10 @@ class AutoWiringTests: XCTestCase {
|
||||
let resolved = try! container.resolve() as AutoWiredClient
|
||||
|
||||
//then
|
||||
//when doing another auto-wiring during resolve we should reuse instance
|
||||
XCTAssertTrue((resolved as! AutoWiredClientImp) === (anotherInstance as! AutoWiredClientImp))
|
||||
XCTAssertTrue(
|
||||
(resolved as! AutoWiredClientImp) === (anotherInstance as! AutoWiredClientImp),
|
||||
"when doing another auto-wiring during resolve we should reuse instance"
|
||||
)
|
||||
}
|
||||
|
||||
func testThatItReusesInstancesResolvedWithoutAutoWiringWhenUsingAutoWiringAgain() {
|
||||
@@ -307,8 +288,10 @@ class AutoWiringTests: XCTestCase {
|
||||
let resolved = try! container.resolve(arguments: service1, service2) as AutoWiredClient
|
||||
|
||||
//then
|
||||
//when doing another auto-wiring during resolve we should reuse instance
|
||||
XCTAssertTrue((resolved as! AutoWiredClientImp) === (anotherInstance as! AutoWiredClientImp))
|
||||
XCTAssertTrue(
|
||||
(resolved as! AutoWiredClientImp) === (anotherInstance as! AutoWiredClientImp),
|
||||
"when doing another auto-wiring during resolve we should reuse instance"
|
||||
)
|
||||
}
|
||||
|
||||
func testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithTheSameTag() {
|
||||
@@ -330,8 +313,10 @@ class AutoWiringTests: XCTestCase {
|
||||
let resolved = try! container.resolve(tag: "tag") as AutoWiredClient
|
||||
|
||||
//then
|
||||
//when doing another auto-wiring during resolve we should reuse instance
|
||||
XCTAssertTrue((resolved as! AutoWiredClientImp) === (anotherInstance as! AutoWiredClientImp))
|
||||
XCTAssertTrue(
|
||||
(resolved as! AutoWiredClientImp) === (anotherInstance as! AutoWiredClientImp),
|
||||
"when doing another auto-wiring during resolve we should reuse instance"
|
||||
)
|
||||
}
|
||||
|
||||
func testThatItDoesNotReuseInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithAnotherTag() {
|
||||
@@ -353,8 +338,10 @@ class AutoWiringTests: XCTestCase {
|
||||
let resolved = try! container.resolve(tag: "tag") as AutoWiredClient
|
||||
|
||||
//then
|
||||
//when doing another auto-wiring during resolve we should reuse instance
|
||||
XCTAssertTrue((resolved as! AutoWiredClientImp) !== (anotherInstance as! AutoWiredClientImp))
|
||||
XCTAssertTrue(
|
||||
(resolved as! AutoWiredClientImp) !== (anotherInstance as! AutoWiredClientImp),
|
||||
"when doing another auto-wiring during resolve we should reuse instance"
|
||||
)
|
||||
}
|
||||
|
||||
func testThatItUsesTagToResolveDependenciesWithAutoWiringWith1Argument() {
|
||||
@@ -464,11 +451,11 @@ class AutoWiringTests: XCTestCase {
|
||||
|
||||
var resolved: AutoWiredClient?
|
||||
//when
|
||||
AssertNoThrow(expression: resolved = try container.resolve() as AutoWiredClient?)
|
||||
XCTAssertNoThrow(resolved = try self.container.resolve() as AutoWiredClient?)
|
||||
XCTAssertNotNil(resolved)
|
||||
|
||||
//when
|
||||
AssertNoThrow(expression: resolved = try container.resolve(tag: "tag") as AutoWiredClient?)
|
||||
XCTAssertNoThrow(resolved = try self.container.resolve(tag: "tag") as AutoWiredClient?)
|
||||
XCTAssertNotNil(resolved)
|
||||
}
|
||||
|
||||
|
||||
@@ -47,27 +47,6 @@ class ComponentScopeTests: XCTestCase {
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testThatSharedIsDefaultScope", testThatSharedIsDefaultScope),
|
||||
("testThatScopeCanBeChanged", testThatScopeCanBeChanged),
|
||||
("testThatItResolvesTypeAsNewInstanceForUniqueScope", testThatItResolvesTypeAsNewInstanceForUniqueScope),
|
||||
("testThatItReusesInstanceForSingletonScope", testThatItReusesInstanceForSingletonScope),
|
||||
("testThatSingletonIsNotReusedAcrossContainers", testThatSingletonIsNotReusedAcrossContainers),
|
||||
("testThatSingletonIsReleasedWhenDefinitionIsRemoved", testThatSingletonIsReleasedWhenDefinitionIsRemoved),
|
||||
("testThatSingletonIsReleasedWhenDefinitionIsOverridden", testThatSingletonIsReleasedWhenDefinitionIsOverridden),
|
||||
("testThatSingletonIsReleasedWhenContainerIsReset", testThatSingletonIsReleasedWhenContainerIsReset),
|
||||
("testThatItReusesInstanceInSharedScopeDuringResolve", testThatItReusesInstanceInSharedScopeDuringResolve),
|
||||
("testThatItDoesNotReuseInstanceInSharedScopeInNextResolve", testThatItDoesNotReuseInstanceInSharedScopeInNextResolve),
|
||||
("testThatItDoesNotReuseInstanceInSharedScopeResolvedForNilTag", testThatItDoesNotReuseInstanceInSharedScopeResolvedForNilTagWhenResolvingForAnotherTag),
|
||||
("testThatItReusesInstanceInSharedScopeResolvedForNilTag", testThatItReusesInstanceInSharedScopeResolvedForNilTag),
|
||||
("testThatItReusesResolvedInstanceWhenResolvingOptional", testThatItReusesResolvedInstanceWhenResolvingOptional),
|
||||
("testThatItHoldsWeakReferenceToWeakSingletonInstance", testThatItHoldsWeakReferenceToWeakSingletonInstance),
|
||||
("testThatItResolvesWeakSingletonAgainAfterItWasReleased", testThatItResolvesWeakSingletonAgainAfterItWasReleased),
|
||||
("testThatCollaboratingContainersReuseSingletonsResolvedByAnotherContainer", testThatCollaboratingContainersReuseSingletonsResolvedByAnotherContainer)
|
||||
]
|
||||
}()
|
||||
|
||||
override func setUp() {
|
||||
container.reset()
|
||||
}
|
||||
@@ -341,7 +320,10 @@ class ComponentScopeTests: XCTestCase {
|
||||
_ = try? container.resolve() as ServiceImp1
|
||||
|
||||
//then
|
||||
AssertNoThrow(expression: try container.resolve() as Service, "Weak singleton should be resolved again.")
|
||||
XCTAssertNoThrow(
|
||||
try container.resolve() as Service,
|
||||
"Weak singleton should be resolved again."
|
||||
)
|
||||
}
|
||||
|
||||
func testThatCollaboratingContainersReuseSingletonsResolvedByAnotherContainer() {
|
||||
|
||||
@@ -39,20 +39,6 @@ class ContextTests: XCTestCase {
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testThatContextStoresCurrentlyResolvedType", testThatContextStoresCurrentlyResolvedType),
|
||||
("testThatContextStoresInjectedInType", testThatContextStoresInjectedInType),
|
||||
("testThatContextStoresTheTagPassedToResolve", testThatContextStoresTheTagPassedToResolve),
|
||||
("testThatContextStoresTheTagPassedToResolveWhenAutoInjecting", testThatContextStoresTheTagPassedToResolveWhenAutoInjecting),
|
||||
("testThatContextStoresTheTagPassedToResolveWhenAutoWiring", testThatContextStoresTheTagPassedToResolveWhenAutoWiring),
|
||||
("testThatContextDoesNotOverrideNilTagPassedToResolve", testThatContextDoesNotOverrideNilTagPassedToResolve),
|
||||
("testThatContextStoresNameOfAutoInjectedProperty", testThatContextStoresNameOfAutoInjectedProperty),
|
||||
("testThatItDoesNotSetInjectedInTypeWhenResolvingWithCollaboration", testThatItDoesNotSetInjectedInTypeWhenResolvingWithCollaboration),
|
||||
("testThatContextIsPreservedWhenResolvingWithCollaboration", testThatContextIsPreservedWhenResolvingWithCollaboration)
|
||||
]
|
||||
}()
|
||||
|
||||
override func setUp() {
|
||||
container.reset()
|
||||
container.register { ServiceImp2() }
|
||||
|
||||
@@ -36,18 +36,6 @@ class DefinitionTests: XCTestCase {
|
||||
let tag1 = DependencyContainer.Tag.String("tag1")
|
||||
let tag2 = DependencyContainer.Tag.String("tag2")
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testThatDefinitionKeyIsEqualBy_Type_Factory_Tag", testThatDefinitionKeyIsEqualBy_Type_Factory_Tag),
|
||||
("testThatDefinitionKeysWithDifferentTypesAreNotEqual", testThatDefinitionKeysWithDifferentTypesAreNotEqual),
|
||||
("testThatDefinitionKeysWithDifferentFactoriesAreNotEqual", testThatDefinitionKeysWithDifferentFactoriesAreNotEqual),
|
||||
("testThatDefinitionKeysWithDifferentTagsAreNotEqual", testThatDefinitionKeysWithDifferentTagsAreNotEqual),
|
||||
("testThatResolveDependenciesCallsResolveDependenciesBlock", testThatResolveDependenciesCallsResolveDependenciesBlock),
|
||||
("testThatResolveDependenciesBlockIsNotCalledWhenPassedWrongInstance", testThatResolveDependenciesBlockIsNotCalledWhenPassedWrongInstance),
|
||||
("testThatItRegisteresOptionalTypesAsForwardedTypes", testThatItRegisteresOptionalTypesAsForwardedTypes)
|
||||
]
|
||||
}()
|
||||
|
||||
func testThatDefinitionKeyIsEqualBy_Type_Factory_Tag() {
|
||||
let equalKey1 = DefinitionKey(type: Service.self, typeOfArguments: F1.self, tag: tag1)
|
||||
let equalKey2 = DefinitionKey(type: Service.self, typeOfArguments: F1.self, tag: tag1)
|
||||
|
||||
@@ -49,31 +49,6 @@ class DipTests: XCTestCase {
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testThatCreatingContainerWithConfigBlockDoesNotCreateRetainCycle", testThatCreatingContainerWithConfigBlockDoesNotCreateRetainCycle),
|
||||
("testThatItResolvesInstanceRegisteredWithoutTag", testThatItResolvesInstanceRegisteredWithoutTag),
|
||||
("testThatItResolvesInstanceRegisteredWithTag", testThatItResolvesInstanceRegisteredWithTag),
|
||||
("testThatItResolvesDifferentInstancesRegisteredForDifferentTags", testThatItResolvesDifferentInstancesRegisteredForDifferentTags),
|
||||
("testThatNewRegistrationOverridesPreviousRegistration", testThatNewRegistrationOverridesPreviousRegistration),
|
||||
("testThatItCallsResolveDependenciesOnDefinition", testThatItCallsResolveDependenciesOnDefinition),
|
||||
("testThatItThrowsErrorIfCanNotFindDefinitionForType", testThatItThrowsErrorIfCanNotFindDefinitionForType),
|
||||
("testThatItThrowsErrorIfCanNotFindDefinitionForTag", testThatItThrowsErrorIfCanNotFindDefinitionForTag),
|
||||
("testThatItThrowsErrorIfCanNotFindDefinitionForFactoryWithArguments", testThatItThrowsErrorIfCanNotFindDefinitionForFactoryWithArguments),
|
||||
("testThatItThrowsErrorIfConstructorThrows", testThatItThrowsErrorIfConstructorThrows),
|
||||
("testThatItThrowsErrorIfFailsToResolveDependency", testThatItThrowsErrorIfFailsToResolveDependency),
|
||||
("testThatItCallsDidResolveDependenciesOnResolvableIntance", testThatItCallsDidResolveDependenciesOnResolvableIntance),
|
||||
("testThatItCallsDidResolveDependenciesInReverseOrder", testThatItCallsDidResolveDependenciesInReverseOrder),
|
||||
("testItCallsResolveDependenciesOnResolableInstance", testItCallsResolveDependenciesOnResolableInstance),
|
||||
("testThatItResolvesCircularDependencies", testThatItResolvesCircularDependencies),
|
||||
("testThatItCanResolveUsingContainersCollaboration", testThatItCanResolveUsingContainersCollaboration),
|
||||
("testThatCollaboratingWithSelfIsIgnored", testThatCollaboratingWithSelfIsIgnored),
|
||||
("testThatCollaboratingContainersAreWeakReferences", testThatCollaboratingContainersAreWeakReferences),
|
||||
("testThatCollaboratingContainersReuseInstancesResolvedByAnotherContainer", testThatCollaboratingContainersReuseInstancesResolvedByAnotherContainer),
|
||||
("testThatItCanHandleSeparateContainersAndTheirCollaboration", testThatItCanHandleSeparateContainersAndTheirCollaboration)
|
||||
]
|
||||
}()
|
||||
|
||||
override func setUp() {
|
||||
container.reset()
|
||||
}
|
||||
@@ -229,25 +204,27 @@ class DipTests: XCTestCase {
|
||||
container.register { ServiceImp1() as ServiceImp1 }
|
||||
|
||||
//when
|
||||
AssertThrows(expression: try container.resolve() as Service) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else { return false }
|
||||
XCTAssertThrowsError(try self.container.resolve() as Service) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
//then
|
||||
let expectedKey = DefinitionKey(type: Service.self, typeOfArguments: Void.self, tag: nil)
|
||||
XCTAssertEqual(key, expectedKey)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//and when
|
||||
AssertThrows(expression: try container.resolve(Service.self)) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else { return false }
|
||||
XCTAssertThrowsError(try self.container.resolve(Service.self)) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
//then
|
||||
let expectedKey = DefinitionKey(type: Service.self, typeOfArguments: Void.self, tag: nil)
|
||||
XCTAssertEqual(key, expectedKey)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,25 +233,27 @@ class DipTests: XCTestCase {
|
||||
container.register(tag: "some tag") { ServiceImp1() as Service }
|
||||
|
||||
//when
|
||||
AssertThrows(expression: try container.resolve(tag: "other tag") as Service) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else { return false }
|
||||
XCTAssertThrowsError(try self.container.resolve(tag: "other tag") as Service) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
//then
|
||||
let expectedKey = DefinitionKey(type: Service.self, typeOfArguments: Void.self, tag: "other tag")
|
||||
XCTAssertEqual(key, expectedKey)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//and when
|
||||
AssertThrows(expression: try container.resolve(Service.self, tag: "other tag")) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else { return false }
|
||||
XCTAssertThrowsError(try self.container.resolve(Service.self, tag: "other tag")) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
//then
|
||||
let expectedKey = DefinitionKey(type: Service.self, typeOfArguments: Void.self, tag: "other tag")
|
||||
XCTAssertEqual(key, expectedKey)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,25 +262,27 @@ class DipTests: XCTestCase {
|
||||
container.register { ServiceImp1() as Service }
|
||||
|
||||
//when
|
||||
AssertThrows(expression: try container.resolve(arguments: "some string") as Service) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else { return false }
|
||||
XCTAssertThrowsError(try self.container.resolve(arguments: "some string") as Service) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
//then
|
||||
let expectedKey = DefinitionKey(type: Service.self, typeOfArguments: String.self, tag: nil)
|
||||
XCTAssertEqual(key, expectedKey)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//and when
|
||||
AssertThrows(expression: try container.resolve(Service.self, arguments: "some string")) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else { return false }
|
||||
XCTAssertThrowsError(try self.container.resolve(Service.self, arguments: "some string")) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
//then
|
||||
let expectedKey = DefinitionKey(type: Service.self, typeOfArguments: String.self, tag: nil)
|
||||
XCTAssertEqual(key, expectedKey)
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,18 +293,18 @@ class DipTests: XCTestCase {
|
||||
container.register { () throws -> Service in throw expectedError }
|
||||
|
||||
//when
|
||||
AssertThrows(expression: try container.resolve() as Service) { error in
|
||||
switch error {
|
||||
case let DipError.definitionNotFound(key) where key == failedKey: return true
|
||||
default: return false
|
||||
XCTAssertThrowsError(try self.container.resolve() as Service) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error, key == failedKey else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//and when
|
||||
AssertThrows(expression: try container.resolve(Service.self)) { error in
|
||||
switch error {
|
||||
case let DipError.definitionNotFound(key) where key == failedKey: return true
|
||||
default: return false
|
||||
XCTAssertThrowsError(try self.container.resolve(Service.self)) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error, key == failedKey else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -339,18 +320,18 @@ class DipTests: XCTestCase {
|
||||
}
|
||||
|
||||
//when
|
||||
AssertThrows(expression: try container.resolve() as Service) { error in
|
||||
switch error {
|
||||
case let DipError.definitionNotFound(key) where key == failedKey: return true
|
||||
default: return false
|
||||
XCTAssertThrowsError(try self.container.resolve() as Service) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error, key == failedKey else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
//and when
|
||||
AssertThrows(expression: try container.resolve(Service.self)) { error in
|
||||
switch error {
|
||||
case let DipError.definitionNotFound(key) where key == failedKey: return true
|
||||
default: return false
|
||||
XCTAssertThrowsError(try self.container.resolve(Service.self)) { error in
|
||||
guard case let DipError.definitionNotFound(key) = error, key == failedKey else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -495,22 +476,15 @@ class DipTests: XCTestCase {
|
||||
XCTAssertNotNil(self.server?.client)
|
||||
XCTAssertNotNil(self.secondServer?.client)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//given
|
||||
container.register { try ResolvableServer(client: self.container.resolve()) as Server }
|
||||
.resolvingProperties { (container: DependencyContainer, server: Server) in
|
||||
let server = server as! ResolvableServer
|
||||
server.secondClient = try container.resolve() as Client
|
||||
}
|
||||
.resolvingProperty(\ResolvableServer.secondClient, as: Client.self)
|
||||
|
||||
container.register { ResolvableClient() as Client }
|
||||
.resolvingProperties { (container: DependencyContainer, client: Client) in
|
||||
let client = client as! ResolvableClient
|
||||
client.server = try container.resolve() as Server
|
||||
client.secondServer = try container.resolve() as Server
|
||||
}
|
||||
.resolvingProperty(\ResolvableClient.server, factory: { try $0.resolve() })
|
||||
.resolvingProperty(\ResolvableClient.secondServer)
|
||||
|
||||
//when
|
||||
let client = (try! container.resolve() as Client) as! ResolvableClient
|
||||
@@ -558,7 +532,7 @@ class DipTests: XCTestCase {
|
||||
}
|
||||
|
||||
//then
|
||||
AssertNoThrow(expression: try container.validate("arg"))
|
||||
XCTAssertNoThrow(try self.container.validate("arg"))
|
||||
XCTAssertTrue(createdService1)
|
||||
XCTAssertTrue(createdService2)
|
||||
XCTAssertTrue(createdService3)
|
||||
@@ -581,8 +555,8 @@ class DipTests: XCTestCase {
|
||||
}
|
||||
|
||||
//then
|
||||
AssertNoThrow(expression:
|
||||
try container.validate(
|
||||
XCTAssertNoThrow(
|
||||
try self.container.validate(
|
||||
"1",
|
||||
expectedIntArgument,
|
||||
"x",
|
||||
@@ -597,8 +571,18 @@ class DipTests: XCTestCase {
|
||||
container.register { (a: Int) -> Service in ServiceImp1() as Service }
|
||||
|
||||
//then
|
||||
AssertThrows(expression: try container.validate()) { error in error is DipError }
|
||||
AssertThrows(expression: try container.validate("1")) { error in error is DipError }
|
||||
XCTAssertThrowsError(try self.container.validate()) { error in
|
||||
guard error is DipError else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
XCTAssertThrowsError(try self.container.validate("1")) { error in
|
||||
guard error is DipError else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testThatItFailsValidationOnlyForDipErrors() {
|
||||
@@ -610,7 +594,7 @@ class DipTests: XCTestCase {
|
||||
}
|
||||
|
||||
//then
|
||||
AssertNoThrow(expression: try container.validate())
|
||||
XCTAssertNoThrow(try self.container.validate())
|
||||
|
||||
//given
|
||||
let key = DefinitionKey(type: Service.self, typeOfArguments: Void.self, tag: nil)
|
||||
@@ -619,9 +603,11 @@ class DipTests: XCTestCase {
|
||||
}
|
||||
|
||||
//then
|
||||
AssertThrows(expression: try container.validate()) { error in
|
||||
if case let DipError.definitionNotFound(_key) = error, _key == key { return true }
|
||||
else { return false }
|
||||
XCTAssertThrowsError(try self.container.validate()) { error in
|
||||
guard case let DipError.definitionNotFound(_key) = error, _key == key else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,10 +625,10 @@ extension DipTests {
|
||||
container.collaborate(with: collaborator)
|
||||
|
||||
//then
|
||||
AssertNoThrow(expression: try container.resolve() as Service)
|
||||
AssertNoThrow(expression: try container.resolve(Service.self))
|
||||
AssertNoThrow(expression: try collaborator.resolve() as String)
|
||||
AssertNoThrow(expression: try collaborator.resolve(String.self))
|
||||
XCTAssertNoThrow(try self.container.resolve() as Service)
|
||||
XCTAssertNoThrow(try self.container.resolve(Service.self))
|
||||
XCTAssertNoThrow(try collaborator.resolve() as String)
|
||||
XCTAssertNoThrow(try collaborator.resolve(String.self))
|
||||
}
|
||||
|
||||
func testThatCollaboratingWithSelfIsIgnored() {
|
||||
|
||||
@@ -51,22 +51,6 @@ class RuntimeArgumentsTests: XCTestCase {
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testThatItResolvesInstanceWithOneArgument", testThatItResolvesInstanceWithOneArgument),
|
||||
("testThatItResolvesInstanceWithTwoArguments", testThatItResolvesInstanceWithTwoArguments),
|
||||
("testThatItResolvesInstanceWithThreeArguments", testThatItResolvesInstanceWithThreeArguments),
|
||||
("testThatItResolvesInstanceWithFourArguments", testThatItResolvesInstanceWithFourArguments),
|
||||
("testThatItResolvesInstanceWithFiveArguments", testThatItResolvesInstanceWithFiveArguments),
|
||||
("testThatItResolvesInstanceWithSixArguments", testThatItResolvesInstanceWithSixArguments),
|
||||
("testThatItRegistersDifferentFactoriesForDifferentNumberOfArguments", testThatItRegistersDifferentFactoriesForDifferentNumberOfArguments),
|
||||
("testThatItRegistersDifferentFactoriesForDifferentTypesOfArguments", testThatItRegistersDifferentFactoriesForDifferentTypesOfArguments),
|
||||
("testThatItRegistersDifferentFactoriesForDifferentOrderOfArguments", testThatItRegistersDifferentFactoriesForDifferentOrderOfArguments),
|
||||
("testThatNewRegistrationWithSameArgumentsOverridesPreviousRegistration", testThatNewRegistrationWithSameArgumentsOverridesPreviousRegistration),
|
||||
("testThatDifferentFactoriesRegisteredIfArgumentIsOptional", testThatDifferentFactoriesRegisteredIfArgumentIsOptional)
|
||||
]
|
||||
}()
|
||||
|
||||
override func setUp() {
|
||||
container.reset()
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
|
||||
#if canImport(ObjectiveC)
|
||||
import XCTest
|
||||
@testable import Dip
|
||||
|
||||
@@ -48,8 +49,8 @@ private class ServerImp: Server, Hashable {
|
||||
weak var client: Client!
|
||||
init() {}
|
||||
|
||||
var hashValue: Int {
|
||||
return Unmanaged.passUnretained(self).toOpaque().hashValue
|
||||
func hash(into hasher: inout Hasher) {
|
||||
hasher.combine(ObjectIdentifier(self))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,22 +63,6 @@ private var resolvedClients = Array<ClientImp>()
|
||||
|
||||
private var container: DependencyContainer!
|
||||
|
||||
#if os(Linux)
|
||||
import Glibc
|
||||
|
||||
private var runningThreads: Int = 0
|
||||
private var lock: pthread_spinlock_t = 0
|
||||
|
||||
private let resolveClientSync: () -> Client? = {
|
||||
let pointer = dispatch_sync { _ in
|
||||
let resolved = try! container.resolve() as Client
|
||||
return UnsafeMutableRawPointer(Unmanaged.passRetained(resolved as! ClientImp).toOpaque())
|
||||
}
|
||||
guard let clientPointer = pointer else { return nil }
|
||||
return Unmanaged<ClientImp>.fromOpaque(clientPointer).takeRetainedValue()
|
||||
}
|
||||
|
||||
#else
|
||||
let queue = OperationQueue()
|
||||
let lock = RecursiveLock()
|
||||
|
||||
@@ -88,18 +73,11 @@ private let resolveClientSync: () -> Client? = {
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
let resolveServerAsync = {
|
||||
let server = try! container.resolve() as Server
|
||||
lock.lock()
|
||||
resolvedServers.insert(server as! ServerImp)
|
||||
|
||||
#if os(Linux)
|
||||
runningThreads -= 1
|
||||
#endif
|
||||
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
@@ -107,31 +85,11 @@ let resolveClientAsync = {
|
||||
let client = try! container.resolve() as Client
|
||||
lock.lock()
|
||||
resolvedClients.append(client as! ClientImp)
|
||||
|
||||
#if os(Linux)
|
||||
runningThreads -= 1
|
||||
#endif
|
||||
|
||||
lock.unlock()
|
||||
}
|
||||
|
||||
class ThreadSafetyTests: XCTestCase {
|
||||
|
||||
#if os(Linux)
|
||||
required init(name: String, testClosure: @escaping (XCTestCase) throws -> Void) {
|
||||
pthread_spin_init(&lock, 0)
|
||||
super.init(name: name, testClosure: testClosure)
|
||||
}
|
||||
#endif
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testSingletonThreadSafety", testSingletonThreadSafety),
|
||||
("testFactoryThreadSafety", testFactoryThreadSafety),
|
||||
("testCircularReferenceThreadSafety", testCircularReferenceThreadSafety)
|
||||
]
|
||||
}()
|
||||
|
||||
override func setUp() {
|
||||
Dip.logLevel = .Verbose
|
||||
container = DependencyContainer()
|
||||
@@ -146,25 +104,10 @@ class ThreadSafetyTests: XCTestCase {
|
||||
container.register(.singleton) { ServerImp() as Server }
|
||||
|
||||
for _ in 0..<100 {
|
||||
#if os(Linux)
|
||||
lock.lock()
|
||||
runningThreads += 1
|
||||
lock.unlock()
|
||||
|
||||
dispatch_async { _ in
|
||||
resolveServerAsync()
|
||||
return nil
|
||||
}
|
||||
#else
|
||||
queue.addOperation(resolveServerAsync)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
while runningThreads > 0 { sleep(1) }
|
||||
#else
|
||||
queue.waitUntilAllOperationsAreFinished()
|
||||
#endif
|
||||
|
||||
XCTAssertEqual(resolvedServers.count, 1, "Should create only one instance")
|
||||
}
|
||||
@@ -174,25 +117,10 @@ class ThreadSafetyTests: XCTestCase {
|
||||
container.register { ServerImp() as Server }
|
||||
|
||||
for _ in 0..<100 {
|
||||
#if os(Linux)
|
||||
lock.lock()
|
||||
runningThreads += 1
|
||||
lock.unlock()
|
||||
|
||||
dispatch_async { _ in
|
||||
resolveServerAsync()
|
||||
return nil
|
||||
}
|
||||
#else
|
||||
queue.addOperation(resolveServerAsync)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
while runningThreads > 0 { sleep(1) }
|
||||
#else
|
||||
queue.waitUntilAllOperationsAreFinished()
|
||||
#endif
|
||||
|
||||
XCTAssertEqual(resolvedServers.count, 100, "All instances should be different")
|
||||
}
|
||||
@@ -209,25 +137,10 @@ class ThreadSafetyTests: XCTestCase {
|
||||
}
|
||||
|
||||
for _ in 0..<100 {
|
||||
#if os(Linux)
|
||||
lock.lock()
|
||||
runningThreads += 1
|
||||
lock.unlock()
|
||||
|
||||
dispatch_async { _ in
|
||||
resolveClientAsync()
|
||||
return nil
|
||||
}
|
||||
#else
|
||||
queue.addOperation(resolveClientAsync)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
while runningThreads > 0 { sleep(1) }
|
||||
#else
|
||||
queue.waitUntilAllOperationsAreFinished()
|
||||
#endif
|
||||
|
||||
XCTAssertEqual(resolvedClients.count, 100, "Instances should be not reused in different object graphs")
|
||||
for client in resolvedClients {
|
||||
@@ -238,5 +151,4 @@ class ThreadSafetyTests: XCTestCase {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,8 +27,13 @@ import XCTest
|
||||
|
||||
private protocol Service: class { }
|
||||
private protocol ForwardedType: class { }
|
||||
#if os(Linux)
|
||||
private class ServiceImp1: Service, ForwardedType { }
|
||||
private class ServiceImp2: Service, ForwardedType { }
|
||||
#else
|
||||
private class ServiceImp1: NSObject, Service, ForwardedType { }
|
||||
private class ServiceImp2: NSObject, Service, ForwardedType { }
|
||||
#endif
|
||||
|
||||
private protocol Dependency {}
|
||||
private struct DependencyImpl: Dependency {}
|
||||
@@ -52,24 +57,6 @@ private struct OptionalDependencyClient {
|
||||
class TypeForwardingTests: XCTestCase {
|
||||
|
||||
let container = DependencyContainer()
|
||||
|
||||
static var allTests = {
|
||||
return [
|
||||
("testThatItResolvesInstanceByTypeForwarding", testThatItResolvesInstanceByTypeForwarding),
|
||||
("testThatItReusesInstanceResolvedByTypeForwarding", testThatItReusesInstanceResolvedByTypeForwarding),
|
||||
("testThatItDoesNotResolveByTypeForwardingIfRegisteredForAnotherTag", testThatItDoesNotResolveByTypeForwardingIfRegisteredForAnotherTag),
|
||||
("testThatItDoesNotReuseInstanceResolvedByTypeForwardingRegisteredForAnotherTag", testThatItDoesNotReuseInstanceResolvedByTypeForwardingRegisteredForAnotherTag),
|
||||
("testThatItCallsResolvedDependenciesBlockWhenResolvingByTypeForwarding", testThatItCallsResolvedDependenciesBlockWhenResolvingByTypeForwarding),
|
||||
("testThatItCallsResolvedDependenciesBlockProvidedAfterRegistrationWhenResolvingByTypeForwarding",testThatItCallsResolvedDependenciesBlockProvidedAfterRegistrationWhenResolvingByTypeForwarding),
|
||||
("testThatItFallbackToDefinitionWithNoTagWhenResolvingInstanceByTypeForwarding", testThatItFallbackToDefinitionWithNoTagWhenResolvingInstanceByTypeForwarding),
|
||||
("testThatItCanResolveOptional", testThatItCanResolveOptional),
|
||||
("testThatItReusesInstancesResolvedForOptionalType", testThatItReusesInstancesResolvedForOptionalType),
|
||||
("testThatItFirstUsesTaggedDefinitionWhenResolvingOptional", testThatItFirstUsesTaggedDefinitionWhenResolvingOptional),
|
||||
("testThatItThrowsErrorWhenResolvingNotImplementedTypeWithTypeForwarding", testThatItThrowsErrorWhenResolvingNotImplementedTypeWithTypeForwarding),
|
||||
("testThatItOverridesIfSeveralDefinitionsWithTheSameTagForwardTheSameType", testThatItOverridesIfSeveralDefinitionsWithTheSameTagForwardTheSameType),
|
||||
("testThatItDoesNotOverrideIfDefinitionForwardsTheSameTypeWithDifferentTag", testThatItDoesNotOverrideIfDefinitionForwardsTheSameTypeWithDifferentTag)
|
||||
]
|
||||
}()
|
||||
|
||||
override func setUp() {
|
||||
container.reset()
|
||||
@@ -129,15 +116,15 @@ class TypeForwardingTests: XCTestCase {
|
||||
def.implements(ForwardedType.self, tag: "otherTag")
|
||||
|
||||
//then
|
||||
AssertThrows(expression: try container.resolve(tag: "tag") as ForwardedType)
|
||||
AssertThrows(expression: try container.resolve(ForwardedType.self, tag: "tag"))
|
||||
XCTAssertThrowsError(try self.container.resolve(tag: "tag") as ForwardedType)
|
||||
XCTAssertThrowsError(try self.container.resolve(ForwardedType.self, tag: "tag"))
|
||||
|
||||
//and given
|
||||
def.implements(ForwardedType.self, tag: "tag")
|
||||
|
||||
//then
|
||||
AssertNoThrow(expression: try container.resolve(tag: "tag") as ForwardedType)
|
||||
AssertNoThrow(expression: try container.resolve(ForwardedType.self, tag: "tag"))
|
||||
XCTAssertNoThrow(try self.container.resolve(tag: "tag") as ForwardedType)
|
||||
XCTAssertNoThrow(try self.container.resolve(ForwardedType.self, tag: "tag"))
|
||||
}
|
||||
|
||||
func testThatItDoesNotReuseInstanceResolvedByTypeForwardingRegisteredForAnotherTag() {
|
||||
@@ -325,19 +312,23 @@ class TypeForwardingTests: XCTestCase {
|
||||
.implements(ServiceImp2.self)
|
||||
|
||||
//then
|
||||
AssertThrows(expression: try container.resolve() as ServiceImp2) { error in
|
||||
guard case let DipError.invalidType(_, key) = error else { return false }
|
||||
XCTAssertThrowsError(try self.container.resolve() as ServiceImp2) { error in
|
||||
guard case let DipError.invalidType(_, key) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
let expectedKey = DefinitionKey(type: ServiceImp2.self, typeOfArguments: Void.self, tag: nil)
|
||||
XCTAssertEqual(key, expectedKey)
|
||||
return true
|
||||
}
|
||||
AssertThrows(expression: try container.resolve(ServiceImp2.self)) { error in
|
||||
guard case let DipError.invalidType(_, key) = error else { return false }
|
||||
XCTAssertThrowsError(try self.container.resolve(ServiceImp2.self)) { error in
|
||||
guard case let DipError.invalidType(_, key) = error else {
|
||||
XCTFail("Thrown unexpected error: \(error)")
|
||||
return
|
||||
}
|
||||
|
||||
let expectedKey = DefinitionKey(type: ServiceImp2.self, typeOfArguments: Void.self, tag: nil)
|
||||
XCTAssertEqual(key, expectedKey)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,41 +28,6 @@ import XCTest
|
||||
typealias NSObject = AnyObject
|
||||
#endif
|
||||
|
||||
func AssertThrows<T>(_ file: StaticString = #file, line: UInt = #line, expression: @autoclosure () throws -> T) {
|
||||
AssertThrows(file, line: line, expression: expression, "")
|
||||
}
|
||||
|
||||
func AssertThrows<T>(_ file: StaticString = #file, line: UInt = #line, expression: @autoclosure () throws -> T, _ message: String) {
|
||||
AssertThrows(expression: expression, checkError: { _ in true }, message)
|
||||
}
|
||||
|
||||
func AssertThrows<T>(_ file: StaticString = #file, line: UInt = #line, expression: @autoclosure () throws -> T, checkError: (Error) -> Bool) {
|
||||
AssertThrows(file, line: line, expression: expression, checkError: checkError, "")
|
||||
}
|
||||
|
||||
func AssertThrows<T>(_ file: StaticString = #file, line: UInt = #line, expression: @autoclosure () throws -> T, checkError: (Error) -> Bool, _ message: String) {
|
||||
do {
|
||||
let _ = try expression()
|
||||
XCTFail(message, file: file, line: line)
|
||||
}
|
||||
catch {
|
||||
XCTAssertTrue(checkError(error), "Thrown unexpected error: \(error)", file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
func AssertNoThrow<T>(_ file: StaticString = #file, line: UInt = #line, expression: @autoclosure () throws -> T) {
|
||||
AssertNoThrow(file, line: line, expression: expression, "")
|
||||
}
|
||||
|
||||
func AssertNoThrow<T>(_ file: StaticString = #file, line: UInt = #line, expression: @autoclosure () throws -> T, _ message: String) {
|
||||
do {
|
||||
let _ = try expression()
|
||||
}
|
||||
catch {
|
||||
XCTFail(message, file: file, line: line)
|
||||
}
|
||||
}
|
||||
|
||||
#if os(Linux)
|
||||
import Glibc
|
||||
typealias TMain = @convention(c) (UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer?
|
||||
@@ -78,7 +43,7 @@ func dispatch_async(block: @escaping TMain) -> pthread_t {
|
||||
}
|
||||
|
||||
func dispatch_sync(block: @escaping TMain) -> UnsafeMutableRawPointer? {
|
||||
var result: UnsafeMutableRawPointer? = UnsafeMutableRawPointer.allocate(bytes: 1, alignedTo: 0)
|
||||
var result: UnsafeMutableRawPointer? = UnsafeMutableRawPointer.allocate(byteCount: 1, alignment: 0)
|
||||
let pid = startThread(block)
|
||||
pthread_join(pid, &result)
|
||||
return result
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
import XCTest
|
||||
@testable import DipTests
|
||||
|
||||
XCTMain([
|
||||
testCase(DipTests.allTests),
|
||||
testCase(DefinitionTests.allTests),
|
||||
testCase(RuntimeArgumentsTests.allTests),
|
||||
testCase(ComponentScopeTests.allTests),
|
||||
testCase(AutoInjectionTests.allTests),
|
||||
// testCase(ThreadSafetyTests.allTests),
|
||||
testCase(AutoWiringTests.allTests),
|
||||
testCase(ContextTests.allTests),
|
||||
testCase(TypeForwardingTests.allTests)
|
||||
])
|
||||
@@ -0,0 +1,202 @@
|
||||
#if !canImport(ObjectiveC)
|
||||
import XCTest
|
||||
|
||||
extension AutoInjectionTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__AutoInjectionTests = [
|
||||
("testThatItAutoInjectsPropertyWithCollaboratingContainer", testThatItAutoInjectsPropertyWithCollaboratingContainer),
|
||||
("testThatItAutoInjectsWhenOverridenInDefinition", testThatItAutoInjectsWhenOverridenInDefinition),
|
||||
("testThatItCallsDidInjectOnAutoInjectedProperty", testThatItCallsDidInjectOnAutoInjectedProperty),
|
||||
("testThatItCallsResolveDependencyBlockWhenAutoInjecting", testThatItCallsResolveDependencyBlockWhenAutoInjecting),
|
||||
("testThatItDoesNotAutoInjectIfDisabledInContainer", testThatItDoesNotAutoInjectIfDisabledInContainer),
|
||||
("testThatItDoesNotAutoInjectIfDisabledInDefinition", testThatItDoesNotAutoInjectIfDisabledInDefinition),
|
||||
("testThatItDoesNotPassTagToAutoInjectedPropertyWithExplicitTag", testThatItDoesNotPassTagToAutoInjectedPropertyWithExplicitTag),
|
||||
("testThatItPassesTagToAutoInjectedProperty", testThatItPassesTagToAutoInjectedProperty),
|
||||
("testThatItResolvesAutoInjectedDependencies", testThatItResolvesAutoInjectedDependencies),
|
||||
("testThatItResolvesAutoInjectedSingletons", testThatItResolvesAutoInjectedSingletons),
|
||||
("testThatItResolvesInheritedDependencies", testThatItResolvesInheritedDependencies),
|
||||
("testThatItResolvesTaggedAutoInjectedProperties", testThatItResolvesTaggedAutoInjectedProperties),
|
||||
("testThatItReusesAutoInjectedInstancesOnNextResolveOrAutoInjection", testThatItReusesAutoInjectedInstancesOnNextResolveOrAutoInjection),
|
||||
("testThatItReusesResolvedAutoInjectedInstances", testThatItReusesResolvedAutoInjectedInstances),
|
||||
("testThatItThrowsErrorIfFailsToAutoInjectDependency", testThatItThrowsErrorIfFailsToAutoInjectDependency),
|
||||
("testThatNoErrorThrownWhenOptionalPropertiesAreNotAutoInjected", testThatNoErrorThrownWhenOptionalPropertiesAreNotAutoInjected),
|
||||
("testThatThereIsNoRetainCycleBetweenAutoInjectedCircularDependencies", testThatThereIsNoRetainCycleBetweenAutoInjectedCircularDependencies),
|
||||
]
|
||||
}
|
||||
|
||||
extension AutoWiringTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__AutoWiringTests = [
|
||||
("testThatItCanAutoWireOptional", testThatItCanAutoWireOptional),
|
||||
("testThatItCanResolveWithAutoWiring", testThatItCanResolveWithAutoWiring),
|
||||
("testThatItDoesNotReuseInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithAnotherTag", testThatItDoesNotReuseInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithAnotherTag),
|
||||
("testThatItDoesNotTryToUseAutoWiringWhenCallingResolveWithArguments", testThatItDoesNotTryToUseAutoWiringWhenCallingResolveWithArguments),
|
||||
("testThatItDoesNotUseAutoWiringWhenFailedToResolveLowLevelDependency", testThatItDoesNotUseAutoWiringWhenFailedToResolveLowLevelDependency),
|
||||
("testThatItFallbackToNotTaggedFactoryWhenUsingAutoWire", testThatItFallbackToNotTaggedFactoryWhenUsingAutoWire),
|
||||
("testThatItPrefersTaggedFactoryWithDifferentNumberOfArgumentsWhenUsingAutoWire", testThatItPrefersTaggedFactoryWithDifferentNumberOfArgumentsWhenUsingAutoWire),
|
||||
("testThatItPrefersTaggedFactoryWithDifferentTypesOfArgumentsWhenUsingAutoWire", testThatItPrefersTaggedFactoryWithDifferentTypesOfArgumentsWhenUsingAutoWire),
|
||||
("testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgain", testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgain),
|
||||
("testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithTheSameTag", testThatItReusesInstancesResolvedWithAutoWiringWhenUsingAutoWiringAgainWithTheSameTag),
|
||||
("testThatItReusesInstancesResolvedWithoutAutoWiringWhenUsingAutoWiringAgain", testThatItReusesInstancesResolvedWithoutAutoWiringWhenUsingAutoWiringAgain),
|
||||
("testThatItThrowsAmbiguityErrorWhenUsingAutoWire", testThatItThrowsAmbiguityErrorWhenUsingAutoWire),
|
||||
("testThatItUsesAutoWireFactoryWithMostNumberOfArguments", testThatItUsesAutoWireFactoryWithMostNumberOfArguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith1Argument", testThatItUsesTagToResolveDependenciesWithAutoWiringWith1Argument),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith2Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith2Arguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith3Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith3Arguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith4Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith4Arguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith5Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith5Arguments),
|
||||
("testThatItUsesTagToResolveDependenciesWithAutoWiringWith6Arguments", testThatItUsesTagToResolveDependenciesWithAutoWiringWith6Arguments),
|
||||
]
|
||||
}
|
||||
|
||||
extension ComponentScopeTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__ComponentScopeTests = [
|
||||
("testThatCollaboratingContainersReuseSingletonsResolvedByAnotherContainer", testThatCollaboratingContainersReuseSingletonsResolvedByAnotherContainer),
|
||||
("testThatContainerCanBeBootstrappedAgainAfterReset", testThatContainerCanBeBootstrappedAgainAfterReset),
|
||||
("testThatItDoesNotReuseInstanceInSharedScopeInNextResolve", testThatItDoesNotReuseInstanceInSharedScopeInNextResolve),
|
||||
("testThatItDoesNotReuseInstanceInSharedScopeResolvedForNilTagWhenResolvingForAnotherTag", testThatItDoesNotReuseInstanceInSharedScopeResolvedForNilTagWhenResolvingForAnotherTag),
|
||||
("testThatItHoldsWeakReferenceToWeakSingletonInstance", testThatItHoldsWeakReferenceToWeakSingletonInstance),
|
||||
("testThatItResolvesTypeAsNewInstanceForUniqueScope", testThatItResolvesTypeAsNewInstanceForUniqueScope),
|
||||
("testThatItResolvesWeakSingletonAgainAfterItWasReleased", testThatItResolvesWeakSingletonAgainAfterItWasReleased),
|
||||
("testThatItReusesInstanceForSingletonScope", testThatItReusesInstanceForSingletonScope),
|
||||
("testThatItReusesInstanceInSharedScopeDuringResolve", testThatItReusesInstanceInSharedScopeDuringResolve),
|
||||
("testThatItReusesInstanceInSharedScopeResolvedForNilTag", testThatItReusesInstanceInSharedScopeResolvedForNilTag),
|
||||
("testThatItReusesResolvedInstanceWhenResolvingOptional", testThatItReusesResolvedInstanceWhenResolvingOptional),
|
||||
("testThatOnlyEagerSingletonIsCreatedWhenContainerIsBootsrapped", testThatOnlyEagerSingletonIsCreatedWhenContainerIsBootsrapped),
|
||||
("testThatScopeCanBeChanged", testThatScopeCanBeChanged),
|
||||
("testThatSharedIsDefaultScope", testThatSharedIsDefaultScope),
|
||||
("testThatSingletonIsNotReusedAcrossContainers", testThatSingletonIsNotReusedAcrossContainers),
|
||||
("testThatSingletonIsReleasedWhenContainerIsReset", testThatSingletonIsReleasedWhenContainerIsReset),
|
||||
("testThatSingletonIsReleasedWhenDefinitionIsOverridden", testThatSingletonIsReleasedWhenDefinitionIsOverridden),
|
||||
("testThatSingletonIsReleasedWhenDefinitionIsRemoved", testThatSingletonIsReleasedWhenDefinitionIsRemoved),
|
||||
]
|
||||
}
|
||||
|
||||
extension ContextTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__ContextTests = [
|
||||
("testThatContextDoesNotOverrideNilTagPassedToResolve", testThatContextDoesNotOverrideNilTagPassedToResolve),
|
||||
("testThatContextIsPreservedWhenResolvingWithCollaboration", testThatContextIsPreservedWhenResolvingWithCollaboration),
|
||||
("testThatContextStoresCurrentlyResolvedType", testThatContextStoresCurrentlyResolvedType),
|
||||
("testThatContextStoresInjectedInType", testThatContextStoresInjectedInType),
|
||||
("testThatContextStoresNameOfAutoInjectedProperty", testThatContextStoresNameOfAutoInjectedProperty),
|
||||
("testThatContextStoresTheTagPassedToResolve", testThatContextStoresTheTagPassedToResolve),
|
||||
("testThatContextStoresTheTagPassedToResolveWhenAutoInjecting", testThatContextStoresTheTagPassedToResolveWhenAutoInjecting),
|
||||
("testThatContextStoresTheTagPassedToResolveWhenAutoWiring", testThatContextStoresTheTagPassedToResolveWhenAutoWiring),
|
||||
("testThatItDoesNotSetInjectedInTypeWhenResolvingWithCollaboration", testThatItDoesNotSetInjectedInTypeWhenResolvingWithCollaboration),
|
||||
]
|
||||
}
|
||||
|
||||
extension DefinitionTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__DefinitionTests = [
|
||||
("testThatDefinitionKeyIsEqualBy_Type_Factory_Tag", testThatDefinitionKeyIsEqualBy_Type_Factory_Tag),
|
||||
("testThatDefinitionKeysWithDifferentFactoriesAreNotEqual", testThatDefinitionKeysWithDifferentFactoriesAreNotEqual),
|
||||
("testThatDefinitionKeysWithDifferentTagsAreNotEqual", testThatDefinitionKeysWithDifferentTagsAreNotEqual),
|
||||
("testThatDefinitionKeysWithDifferentTypesAreNotEqual", testThatDefinitionKeysWithDifferentTypesAreNotEqual),
|
||||
("testThatItRegisteresOptionalTypesAsForwardedTypes", testThatItRegisteresOptionalTypesAsForwardedTypes),
|
||||
("testThatResolveDependenciesBlockIsNotCalledWhenPassedWrongInstance", testThatResolveDependenciesBlockIsNotCalledWhenPassedWrongInstance),
|
||||
("testThatResolveDependenciesCallsResolveDependenciesBlock", testThatResolveDependenciesCallsResolveDependenciesBlock),
|
||||
]
|
||||
}
|
||||
|
||||
extension DipTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__DipTests = [
|
||||
("test_weak_mirror_regression", test_weak_mirror_regression),
|
||||
("testItCallsResolveDependenciesOnResolableInstance", testItCallsResolveDependenciesOnResolableInstance),
|
||||
("testThatCollaboratingContainersAreWeakReferences", testThatCollaboratingContainersAreWeakReferences),
|
||||
("testThatCollaboratingContainersReuseInstancesResolvedByAnotherContainer", testThatCollaboratingContainersReuseInstancesResolvedByAnotherContainer),
|
||||
("testThatCollaboratingWithSelfIsIgnored", testThatCollaboratingWithSelfIsIgnored),
|
||||
("testThatCollaborationReferencesAreRecursivelyUpdate", testThatCollaborationReferencesAreRecursivelyUpdate),
|
||||
("testThatContainerAutowireBeforeCollaboration", testThatContainerAutowireBeforeCollaboration),
|
||||
("testThatContainersShareTheirSingletonsOnlyWithCollaborators", testThatContainersShareTheirSingletonsOnlyWithCollaborators),
|
||||
("testThatCreatingContainerWithConfigBlockDoesNotCreateRetainCycle", testThatCreatingContainerWithConfigBlockDoesNotCreateRetainCycle),
|
||||
("testThatItCallsDidResolveDependenciesInReverseOrder", testThatItCallsDidResolveDependenciesInReverseOrder),
|
||||
("testThatItCallsDidResolveDependenciesOnResolvableIntance", testThatItCallsDidResolveDependenciesOnResolvableIntance),
|
||||
("testThatItCallsResolveDependenciesOnDefinition", testThatItCallsResolveDependenciesOnDefinition),
|
||||
("testThatItCanHandleSeparateContainersAndTheirCollaboration", testThatItCanHandleSeparateContainersAndTheirCollaboration),
|
||||
("testThatItCanResolveUsingContainersCollaboration", testThatItCanResolveUsingContainersCollaboration),
|
||||
("testThatItFailsValidationIfNoMatchingArgumentsFound", testThatItFailsValidationIfNoMatchingArgumentsFound),
|
||||
("testThatItFailsValidationOnlyForDipErrors", testThatItFailsValidationOnlyForDipErrors),
|
||||
("testThatItPicksRuntimeArgumentsWhenValidatingConfiguration", testThatItPicksRuntimeArgumentsWhenValidatingConfiguration),
|
||||
("testThatItResolvesCircularDependencies", testThatItResolvesCircularDependencies),
|
||||
("testThatItResolvesDifferentInstancesRegisteredForDifferentTags", testThatItResolvesDifferentInstancesRegisteredForDifferentTags),
|
||||
("testThatItResolvesInstanceRegisteredWithoutTag", testThatItResolvesInstanceRegisteredWithoutTag),
|
||||
("testThatItResolvesInstanceRegisteredWithTag", testThatItResolvesInstanceRegisteredWithTag),
|
||||
("testThatItThrowsErrorIfCanNotFindDefinitionForFactoryWithArguments", testThatItThrowsErrorIfCanNotFindDefinitionForFactoryWithArguments),
|
||||
("testThatItThrowsErrorIfCanNotFindDefinitionForTag", testThatItThrowsErrorIfCanNotFindDefinitionForTag),
|
||||
("testThatItThrowsErrorIfCanNotFindDefinitionForType", testThatItThrowsErrorIfCanNotFindDefinitionForType),
|
||||
("testThatItThrowsErrorIfConstructorThrows", testThatItThrowsErrorIfConstructorThrows),
|
||||
("testThatItThrowsErrorIfFailsToResolveDependency", testThatItThrowsErrorIfFailsToResolveDependency),
|
||||
("testThatItValidatesConfiguration", testThatItValidatesConfiguration),
|
||||
("testThatNewRegistrationOverridesPreviousRegistration", testThatNewRegistrationOverridesPreviousRegistration),
|
||||
]
|
||||
}
|
||||
|
||||
extension RuntimeArgumentsTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__RuntimeArgumentsTests = [
|
||||
("testThatDifferentFactoriesRegisteredIfArgumentIsOptional", testThatDifferentFactoriesRegisteredIfArgumentIsOptional),
|
||||
("testThatItRegistersDifferentFactoriesForDifferentNumberOfArguments", testThatItRegistersDifferentFactoriesForDifferentNumberOfArguments),
|
||||
("testThatItRegistersDifferentFactoriesForDifferentOrderOfArguments", testThatItRegistersDifferentFactoriesForDifferentOrderOfArguments),
|
||||
("testThatItRegistersDifferentFactoriesForDifferentTypesOfArguments", testThatItRegistersDifferentFactoriesForDifferentTypesOfArguments),
|
||||
("testThatItResolvesInstanceWithFiveArguments", testThatItResolvesInstanceWithFiveArguments),
|
||||
("testThatItResolvesInstanceWithFourArguments", testThatItResolvesInstanceWithFourArguments),
|
||||
("testThatItResolvesInstanceWithOneArgument", testThatItResolvesInstanceWithOneArgument),
|
||||
("testThatItResolvesInstanceWithSixArguments", testThatItResolvesInstanceWithSixArguments),
|
||||
("testThatItResolvesInstanceWithThreeArguments", testThatItResolvesInstanceWithThreeArguments),
|
||||
("testThatItResolvesInstanceWithTwoArguments", testThatItResolvesInstanceWithTwoArguments),
|
||||
("testThatNewRegistrationWithSameArgumentsOverridesPreviousRegistration", testThatNewRegistrationWithSameArgumentsOverridesPreviousRegistration),
|
||||
]
|
||||
}
|
||||
|
||||
extension TypeForwardingTests {
|
||||
// DO NOT MODIFY: This is autogenerated, use:
|
||||
// `swift test --generate-linuxmain`
|
||||
// to regenerate.
|
||||
static let __allTests__TypeForwardingTests = [
|
||||
("testThatItCallsResolvedDependenciesBlockProvidedAfterRegistrationWhenResolvingByTypeForwarding", testThatItCallsResolvedDependenciesBlockProvidedAfterRegistrationWhenResolvingByTypeForwarding),
|
||||
("testThatItCallsResolvedDependenciesBlockWhenResolvingByTypeForwarding", testThatItCallsResolvedDependenciesBlockWhenResolvingByTypeForwarding),
|
||||
("testThatItCanResolveOptional", testThatItCanResolveOptional),
|
||||
("testThatItDoesNotOverrideIfDefinitionForwardsTheSameTypeWithDifferentTag", testThatItDoesNotOverrideIfDefinitionForwardsTheSameTypeWithDifferentTag),
|
||||
("testThatItDoesNotResolveByTypeForwardingIfRegisteredForAnotherTag", testThatItDoesNotResolveByTypeForwardingIfRegisteredForAnotherTag),
|
||||
("testThatItDoesNotReuseInstanceResolvedByTypeForwardingRegisteredForAnotherTag", testThatItDoesNotReuseInstanceResolvedByTypeForwardingRegisteredForAnotherTag),
|
||||
("testThatItFallbackToDefinitionWithNoTagWhenResolvingInstanceByTypeForwarding", testThatItFallbackToDefinitionWithNoTagWhenResolvingInstanceByTypeForwarding),
|
||||
("testThatItFirstUsesTaggedDefinitionWhenResolvingOptional", testThatItFirstUsesTaggedDefinitionWhenResolvingOptional),
|
||||
("testThatItOverridesIfSeveralDefinitionsWithTheSameTagForwardTheSameType", testThatItOverridesIfSeveralDefinitionsWithTheSameTagForwardTheSameType),
|
||||
("testThatItResolvesInstanceByTypeForwarding", testThatItResolvesInstanceByTypeForwarding),
|
||||
("testThatItReusesInstanceResolvedByTypeForwarding", testThatItReusesInstanceResolvedByTypeForwarding),
|
||||
("testThatItReusesInstancesResolvedForOptionalType", testThatItReusesInstancesResolvedForOptionalType),
|
||||
("testThatItThrowsErrorWhenResolvingNotImplementedTypeWithTypeForwarding", testThatItThrowsErrorWhenResolvingNotImplementedTypeWithTypeForwarding),
|
||||
]
|
||||
}
|
||||
|
||||
public func __allTests() -> [XCTestCaseEntry] {
|
||||
return [
|
||||
testCase(AutoInjectionTests.__allTests__AutoInjectionTests),
|
||||
testCase(AutoWiringTests.__allTests__AutoWiringTests),
|
||||
testCase(ComponentScopeTests.__allTests__ComponentScopeTests),
|
||||
testCase(ContextTests.__allTests__ContextTests),
|
||||
testCase(DefinitionTests.__allTests__DefinitionTests),
|
||||
testCase(DipTests.__allTests__DipTests),
|
||||
testCase(RuntimeArgumentsTests.__allTests__RuntimeArgumentsTests),
|
||||
testCase(TypeForwardingTests.__allTests__TypeForwardingTests),
|
||||
]
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user