From d1b4023796f8bab778f52a11eb058c070f00860d Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 14 Jul 2018 16:13:54 +0200
Subject: [PATCH 01/57] Adding support to Xcode 10 and Swift 4.2
---
.swift-version | 2 +-
CHANGELOG.md | 6 ++++++
Queuer.podspec | 2 +-
Queuer.xcodeproj/project.pbxproj | 6 ++++--
Queuer.xcodeproj/xcshareddata/xcschemes/Queuer iOS.xcscheme | 6 ++----
.../xcshareddata/xcschemes/Queuer macOS.xcscheme | 6 ++----
.../xcshareddata/xcschemes/Queuer tvOS.xcscheme | 6 ++----
.../xcshareddata/xcschemes/Queuer watchOS.xcscheme | 6 ++----
README.md | 1 +
9 files changed, 21 insertions(+), 20 deletions(-)
diff --git a/.swift-version b/.swift-version
index 7d5c902..bf77d54 100644
--- a/.swift-version
+++ b/.swift-version
@@ -1 +1 @@
-4.1
+4.2
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 67ba6ae..ced3328 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,6 +16,12 @@ All notable changes to this project will be documented in this file.
---
+## Swift 4.2
+### Added
+- Added support to Xcode 10 and Swift 4.2
+
+---
+
## Develop
### Removed
- Removed Hound CI
diff --git a/Queuer.podspec b/Queuer.podspec
index 4477a21..d9eefa3 100644
--- a/Queuer.podspec
+++ b/Queuer.podspec
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
s.source = { :git => 'https://github.com/FabrizioBrancati/Queuer.git', :tag => s.version }
s.documentation_url = 'https://github.fabriziobrancati.com/documentation/Queuer/'
- s.swift_version = '4.1'
+ s.swift_version = '4.2'
s.source_files = 'Sources/**/*.swift'
diff --git a/Queuer.xcodeproj/project.pbxproj b/Queuer.xcodeproj/project.pbxproj
index 618e7f1..1975dd6 100644
--- a/Queuer.xcodeproj/project.pbxproj
+++ b/Queuer.xcodeproj/project.pbxproj
@@ -728,6 +728,7 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -784,7 +785,7 @@
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
- SWIFT_VERSION = 4.0;
+ SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@@ -809,6 +810,7 @@
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
@@ -857,7 +859,7 @@
PRODUCT_NAME = Queuer;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
- SWIFT_VERSION = 4.0;
+ SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
diff --git a/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer iOS.xcscheme b/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer iOS.xcscheme
index 5a9199e..be2f8d0 100644
--- a/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer iOS.xcscheme
+++ b/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer iOS.xcscheme
@@ -26,9 +26,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
- shouldUseLaunchSchemeArgsEnv = "YES"
- codeCoverageEnabled = "YES">
+ codeCoverageEnabled = "YES"
+ shouldUseLaunchSchemeArgsEnv = "YES">
@@ -57,7 +56,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer macOS.xcscheme b/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer macOS.xcscheme
index f32be8e..394e377 100644
--- a/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer macOS.xcscheme
+++ b/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer macOS.xcscheme
@@ -26,9 +26,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
- shouldUseLaunchSchemeArgsEnv = "YES"
- codeCoverageEnabled = "YES">
+ codeCoverageEnabled = "YES"
+ shouldUseLaunchSchemeArgsEnv = "YES">
@@ -57,7 +56,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer tvOS.xcscheme b/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer tvOS.xcscheme
index 2cdf53b..a0fc727 100644
--- a/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer tvOS.xcscheme
+++ b/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer tvOS.xcscheme
@@ -26,9 +26,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
- shouldUseLaunchSchemeArgsEnv = "YES"
- codeCoverageEnabled = "YES">
+ codeCoverageEnabled = "YES"
+ shouldUseLaunchSchemeArgsEnv = "YES">
@@ -57,7 +56,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer watchOS.xcscheme b/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer watchOS.xcscheme
index 0624fe0..485d9c2 100644
--- a/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer watchOS.xcscheme
+++ b/Queuer.xcodeproj/xcshareddata/xcschemes/Queuer watchOS.xcscheme
@@ -26,9 +26,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
- shouldUseLaunchSchemeArgsEnv = "YES"
- codeCoverageEnabled = "YES">
+ codeCoverageEnabled = "YES"
+ shouldUseLaunchSchemeArgsEnv = "YES">
@@ -38,7 +37,6 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- language = ""
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
diff --git a/README.md b/README.md
index c0bc462..bfff7b2 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,7 @@ Requirements
| 3.1...3.2 | 8.3...9.0 | 1.0.0...1.1.0 | 8.0+ | 10.10 | 9.0 | 2.0+ | ![✓] `*` |
| 4.0 | 9.0...9.2 | 1.3.0 | 8.0+ | 10.10 | 9.0 | 2.0+ | ![✓] `*` |
| 4.1 | 9.3...9.4 | 1.3.1...1.3.2 | 8.0+ | 10.10 | 9.0 | 2.0+ | ![✓] `*` |
+| 4.2 | 10.0 | 1.x.x | 8.0+ | 10.10 | 9.0 | 2.0+ | ![✓] `*` |
> `*` Currently, `URLSession.shared` property is not yet implemented on Linux.
From 363bac4149c2579f1d69653ee11f9e1f405fa682 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 4 Aug 2018 12:49:59 +0200
Subject: [PATCH 02/57] Minor changes to project
---
Queuer.xcodeproj/project.pbxproj | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Queuer.xcodeproj/project.pbxproj b/Queuer.xcodeproj/project.pbxproj
index 1975dd6..ce71b7f 100644
--- a/Queuer.xcodeproj/project.pbxproj
+++ b/Queuer.xcodeproj/project.pbxproj
@@ -757,7 +757,6 @@
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -781,9 +780,9 @@
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
+ OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-expression-type-checking=100 -Xfrontend -warn-long-function-bodies=100";
PRODUCT_NAME = Queuer;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
- SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -856,8 +855,9 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
MTL_ENABLE_DEBUG_INFO = NO;
+ OTHER_SWIFT_FLAGS = "-Xfrontend -warn-long-expression-type-checking=100 -Xfrontend -warn-long-function-bodies=100";
PRODUCT_NAME = Queuer;
- SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
+ SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = "1,2";
From 2195c647822f419147ef831b54c0dfcf7964bbdf Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 25 Aug 2018 19:27:43 +0200
Subject: [PATCH 03/57] Updating to Xcode 10
---
.travis.yml | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 78ed9a2..92bd072 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,23 +14,23 @@ matrix:
env: SPM="YES"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: SPM="YES"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.4,name=iPhone X" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="YES"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.1,name=iPhone 7 Plus" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="YES" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=10.3.1,name=iPhone 6" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=9.0,name=iPhone 5s" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
@@ -38,31 +38,31 @@ matrix:
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=8.1,name=iPhone 4S" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.2,name=Apple TV 4K" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=9.0,name=Apple TV 1080p" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=4.2,name=Apple Watch Series 3 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=3.2,name=Apple Watch Series 2 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=2.0,name=Apple Watch - 38mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
- osx_image: xcode9.4
+ osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="arch=x86_64" SCHEME="$MACOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
before_install:
From 8c542f83b47fc2604b8d3e3e787240308bf55c4a Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 25 Aug 2018 19:46:11 +0200
Subject: [PATCH 04/57] Updating to iOS 12
---
.travis.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 92bd072..8a6dd99 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,11 +19,11 @@ matrix:
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.4,name=iPhone X" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="YES"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=12.0,name=iPhone X" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="YES"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.1,name=iPhone 7 Plus" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="YES" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.4,name=iPhone 7 Plus" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="YES" CODECOV="NO"
- os: osx
language: objective-c
osx_image: xcode10
From 3380fbd79b44afde1b0f85e61df09365f579e725 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 25 Aug 2018 19:46:20 +0200
Subject: [PATCH 05/57] Minor change
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 8a6dd99..4f1bff7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -31,7 +31,7 @@ matrix:
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=9.0,name=iPhone 5s" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=9.0,name=iPhone 5s" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
- os: osx
language: objective-c
osx_image: xcode9.2
From 31456ce3dd80154afdbc0b9f302b3659342b1ff3 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 26 Aug 2018 12:36:09 +0200
Subject: [PATCH 06/57] Fixing tests
---
Tests/QueuerTests/RequestOperationTests.swift | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/Tests/QueuerTests/RequestOperationTests.swift b/Tests/QueuerTests/RequestOperationTests.swift
index b0f5422..7837137 100644
--- a/Tests/QueuerTests/RequestOperationTests.swift
+++ b/Tests/QueuerTests/RequestOperationTests.swift
@@ -73,8 +73,11 @@ internal class RequestOperationTests: XCTestCase {
requestOperation.addToQueue(queue)
XCTAssertEqual(requestOperation.url?.absoluteString, self.testAddress)
- XCTAssertEqual(requestOperation.query, "?test=test&test2=test2")
- XCTAssertEqual(requestOperation.completeURL, URL(string: self.testAddress + "?test=test&test2=test2"))
+ XCTAssertTrue(requestOperation.query?.contains("test=test") ?? false)
+ XCTAssertTrue(requestOperation.query?.contains("test2=test2") ?? false)
+ XCTAssertTrue(requestOperation.completeURL?.absoluteString.contains(self.testAddress) ?? false)
+ XCTAssertTrue(requestOperation.completeURL?.absoluteString.contains("test=test") ?? false)
+ XCTAssertTrue(requestOperation.completeURL?.absoluteString.contains("test2=test2") ?? false)
XCTAssertEqual(requestOperation.timeout, 30)
XCTAssertEqual(requestOperation.method, .get)
XCTAssertEqual(requestOperation.headers ?? [:], ["test": "test", "test2": "test2"])
From 5395910de7deb8e90ecc649fa1209f46d102ae21 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 27 Aug 2018 00:14:28 +0200
Subject: [PATCH 07/57] Updating Swiftenv
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 4f1bff7..93cc90d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -75,7 +75,7 @@ before_install:
install:
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then
- eval "$(curl -sL https://gist.githubusercontent.com/kylef/5c0475ff02b7c7671d2a/raw/02090c7ede5a637b76e6df1710e83cd0bbe7dcdf/swiftenv-install.sh)";
+ eval "$(curl -sL https://swiftenv.fuller.li/install.sh)";
fi
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
./install_swiftlint.sh;
From 611ec1c4d7b076f3885f0ba5490718f5a446311d Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 27 Aug 2018 00:30:15 +0200
Subject: [PATCH 08/57] Using to Coveralls
---
.travis.yml | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 93cc90d..689bbc2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,51 +19,51 @@ matrix:
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=12.0,name=iPhone X" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="YES"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=12.0,name=iPhone X" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="YES"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.4,name=iPhone 7 Plus" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="YES" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.4,name=iPhone 7 Plus" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="YES" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=10.3.1,name=iPhone 6" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=10.3.1,name=iPhone 6" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=9.0,name=iPhone 5s" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=9.0,name=iPhone 5s" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode9.2
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=8.1,name=iPhone 4S" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=8.1,name=iPhone 4S" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.2,name=Apple TV 4K" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=11.2,name=Apple TV 4K" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=9.0,name=Apple TV 1080p" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=9.0,name=Apple TV 1080p" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=4.2,name=Apple Watch Series 3 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=4.2,name=Apple Watch Series 3 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=3.2,name=Apple Watch Series 2 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=3.2,name=Apple Watch Series 2 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=2.0,name=Apple Watch - 38mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=2.0,name=Apple Watch - 38mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="arch=x86_64" SCHEME="$MACOS_SCHEME" RUN_TESTS="YES" LINT="NO" CODECOV="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="arch=x86_64" SCHEME="$MACOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
before_install:
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
@@ -71,6 +71,7 @@ before_install:
gem install cocoapods --pre --no-rdoc --no-ri --no-document;
brew update;
brew outdated carthage || brew upgrade carthage;
+ gem install slather;
fi
install:
@@ -110,6 +111,6 @@ script:
fi
after_success:
- - if [ "$CODECOV" == "YES" ]; then
- bash <(curl -s https://codecov.io/bash) -X xcodeplist;
+ - if [ "$COVERAGE" == "YES" ]; then
+ slather;
fi
From b77a72afde76dd0b24697526a0d2b11f55c67110 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Tue, 28 Aug 2018 00:03:57 +0200
Subject: [PATCH 09/57] Adding Slather file
---
.slather.yml | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 .slather.yml
diff --git a/.slather.yml b/.slather.yml
new file mode 100644
index 0000000..4cf7de0
--- /dev/null
+++ b/.slather.yml
@@ -0,0 +1,5 @@
+coverage_service: coveralls
+xcodeproj: Queuer.xcodeproj
+scheme: Queuer iOS
+ignore:
+ - Tests/*
From eabe8e57de9375efbde89925ed1e349f7c348f70 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Wed, 29 Aug 2018 01:32:54 +0200
Subject: [PATCH 10/57] Moving to Coveralls
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 93370c6..5aabf3a 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[![Build Status](https://travis-ci.org/FabrizioBrancati/Queuer.svg?branch=master)](https://travis-ci.org/FabrizioBrancati/Queuer)
-[![Codecov](https://codecov.io/gh/FabrizioBrancati/Queuer/branch/master/graph/badge.svg)](https://codecov.io/gh/FabrizioBrancati/Queuer)
+[![Coverage Status](https://coveralls.io/repos/github/FabrizioBrancati/Queuer/badge.svg?branch=master)](https://coveralls.io/github/FabrizioBrancati/Queuer?branch=master)
[![Documentation](https://github.fabriziobrancati.com/documentation/Queuer/badge.svg)](https://github.fabriziobrancati.com/documentation/Queuer/)
[![codebeat badge](https://codebeat.co/badges/50844e60-f4f2-4f9f-a688-5ccc976b7c8c)](https://codebeat.co/projects/github-com-fabriziobrancati-queuer-master-9833cda0-af64-433d-a08a-cd0d50d6b579)
[![Swift Package Manager Compatible](https://img.shields.io/badge/SPM-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)
From 0cb58902e0bcf8184da95e233e6b296560344119 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 9 Sep 2018 23:48:20 +0200
Subject: [PATCH 11/57] Updating changelog
---
CHANGELOG.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 48b209d..20e370f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,9 @@ All notable changes to this project will be documented in this file.
### Added
- Added support to Xcode 10 and Swift 4.2
+### Changed
+- Changed from Codecov to Coveralls service for code coverage
+
---
## Develop
From 00e2bdba19a267fb0bb3ee1febf0654dcff3d884 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Tue, 11 Sep 2018 01:41:54 +0200
Subject: [PATCH 12/57] Removing Codecov file
---
.codecov.yml | 6 ------
1 file changed, 6 deletions(-)
delete mode 100644 .codecov.yml
diff --git a/.codecov.yml b/.codecov.yml
deleted file mode 100644
index cd68870..0000000
--- a/.codecov.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-coverage:
- status:
- patch: on
-
-ignore:
- - Tests/**/*
From 60835be4adeb4654aad8925e01cf3a9d62ab6257 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:03:39 +0200
Subject: [PATCH 13/57] Updated package tools version to 4.2
---
Package.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Package.swift b/Package.swift
index c14ec86..5cd57f1 100644
--- a/Package.swift
+++ b/Package.swift
@@ -1,4 +1,4 @@
-// swift-tools-version:4.0
+// swift-tools-version:4.2
//
// Package.swift
// Queuer
From 1a5632a7f7f2195a968c1d3b28619895f96cde56 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:04:50 +0200
Subject: [PATCH 14/57] Removing RequestOperation class
---
Queuer.xcodeproj/project.pbxproj | 18 --
README.md | 41 +---
Sources/Queuer/RequestOperation.swift | 230 ------------------
Tests/QueuerTests/RequestOperationTests.swift | 203 ----------------
4 files changed, 3 insertions(+), 489 deletions(-)
delete mode 100644 Sources/Queuer/RequestOperation.swift
delete mode 100644 Tests/QueuerTests/RequestOperationTests.swift
diff --git a/Queuer.xcodeproj/project.pbxproj b/Queuer.xcodeproj/project.pbxproj
index ce71b7f..a348365 100644
--- a/Queuer.xcodeproj/project.pbxproj
+++ b/Queuer.xcodeproj/project.pbxproj
@@ -15,47 +15,33 @@
49B28E2E1F27EDCC00D0819A /* Queuer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49C7BCC11F26938F00F4FFBC /* Queuer.h */; settings = {ATTRIBUTES = (Public, ); }; };
49C7BCCE1F26938F00F4FFBC /* ConcurrentOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBB1F26938F00F4FFBC /* ConcurrentOperation.swift */; };
49C7BCCF1F26938F00F4FFBC /* Queuer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBC1F26938F00F4FFBC /* Queuer.swift */; };
- 49C7BCD01F26938F00F4FFBC /* RequestOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBD1F26938F00F4FFBC /* RequestOperation.swift */; };
49C7BCD11F26938F00F4FFBC /* Semaphore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBE1F26938F00F4FFBC /* Semaphore.swift */; };
49C7BCD21F26938F00F4FFBC /* SynchronousOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBF1F26938F00F4FFBC /* SynchronousOperation.swift */; };
- 49C7BCD31F26938F00F4FFBC /* URLBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCC01F26938F00F4FFBC /* URLBuilder.swift */; };
49C7BCD41F26938F00F4FFBC /* Queuer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49C7BCC11F26938F00F4FFBC /* Queuer.h */; settings = {ATTRIBUTES = (Public, ); }; };
49C7BCD51F26939900F4FFBC /* ConcurrentOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBB1F26938F00F4FFBC /* ConcurrentOperation.swift */; };
49C7BCD61F26939900F4FFBC /* Queuer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBC1F26938F00F4FFBC /* Queuer.swift */; };
- 49C7BCD71F26939900F4FFBC /* RequestOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBD1F26938F00F4FFBC /* RequestOperation.swift */; };
49C7BCD81F26939900F4FFBC /* Semaphore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBE1F26938F00F4FFBC /* Semaphore.swift */; };
49C7BCD91F26939900F4FFBC /* SynchronousOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBF1F26938F00F4FFBC /* SynchronousOperation.swift */; };
- 49C7BCDA1F26939900F4FFBC /* URLBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCC01F26938F00F4FFBC /* URLBuilder.swift */; };
49C7BCDB1F26939A00F4FFBC /* ConcurrentOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBB1F26938F00F4FFBC /* ConcurrentOperation.swift */; };
49C7BCDC1F26939A00F4FFBC /* Queuer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBC1F26938F00F4FFBC /* Queuer.swift */; };
- 49C7BCDD1F26939A00F4FFBC /* RequestOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBD1F26938F00F4FFBC /* RequestOperation.swift */; };
49C7BCDE1F26939A00F4FFBC /* Semaphore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBE1F26938F00F4FFBC /* Semaphore.swift */; };
49C7BCDF1F26939A00F4FFBC /* SynchronousOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBF1F26938F00F4FFBC /* SynchronousOperation.swift */; };
- 49C7BCE01F26939A00F4FFBC /* URLBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCC01F26938F00F4FFBC /* URLBuilder.swift */; };
49C7BCE11F26939A00F4FFBC /* ConcurrentOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBB1F26938F00F4FFBC /* ConcurrentOperation.swift */; };
49C7BCE21F26939A00F4FFBC /* Queuer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBC1F26938F00F4FFBC /* Queuer.swift */; };
- 49C7BCE31F26939A00F4FFBC /* RequestOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBD1F26938F00F4FFBC /* RequestOperation.swift */; };
49C7BCE41F26939A00F4FFBC /* Semaphore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBE1F26938F00F4FFBC /* Semaphore.swift */; };
49C7BCE51F26939A00F4FFBC /* SynchronousOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCBF1F26938F00F4FFBC /* SynchronousOperation.swift */; };
- 49C7BCE61F26939A00F4FFBC /* URLBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCC01F26938F00F4FFBC /* URLBuilder.swift */; };
49C7BCE71F26939F00F4FFBC /* ConcurrentOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCAF1F26938F00F4FFBC /* ConcurrentOperationTests.swift */; };
49C7BCE81F26939F00F4FFBC /* QueuerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB01F26938F00F4FFBC /* QueuerTests.swift */; };
- 49C7BCE91F26939F00F4FFBC /* RequestOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB11F26938F00F4FFBC /* RequestOperationTests.swift */; };
49C7BCEA1F26939F00F4FFBC /* SemaphoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB21F26938F00F4FFBC /* SemaphoreTests.swift */; };
49C7BCEB1F26939F00F4FFBC /* SynchronousOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB31F26938F00F4FFBC /* SynchronousOperationTests.swift */; };
- 49C7BCEC1F26939F00F4FFBC /* URLBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB41F26938F00F4FFBC /* URLBuilderTests.swift */; };
49C7BCED1F2693A000F4FFBC /* ConcurrentOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCAF1F26938F00F4FFBC /* ConcurrentOperationTests.swift */; };
49C7BCEE1F2693A000F4FFBC /* QueuerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB01F26938F00F4FFBC /* QueuerTests.swift */; };
- 49C7BCEF1F2693A000F4FFBC /* RequestOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB11F26938F00F4FFBC /* RequestOperationTests.swift */; };
49C7BCF01F2693A000F4FFBC /* SemaphoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB21F26938F00F4FFBC /* SemaphoreTests.swift */; };
49C7BCF11F2693A000F4FFBC /* SynchronousOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB31F26938F00F4FFBC /* SynchronousOperationTests.swift */; };
- 49C7BCF21F2693A000F4FFBC /* URLBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB41F26938F00F4FFBC /* URLBuilderTests.swift */; };
49C7BCF31F2693A100F4FFBC /* ConcurrentOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCAF1F26938F00F4FFBC /* ConcurrentOperationTests.swift */; };
49C7BCF41F2693A100F4FFBC /* QueuerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB01F26938F00F4FFBC /* QueuerTests.swift */; };
- 49C7BCF51F2693A100F4FFBC /* RequestOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB11F26938F00F4FFBC /* RequestOperationTests.swift */; };
49C7BCF61F2693A100F4FFBC /* SemaphoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB21F26938F00F4FFBC /* SemaphoreTests.swift */; };
49C7BCF71F2693A100F4FFBC /* SynchronousOperationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB31F26938F00F4FFBC /* SynchronousOperationTests.swift */; };
- 49C7BCF81F2693A100F4FFBC /* URLBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49C7BCB41F26938F00F4FFBC /* URLBuilderTests.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -93,20 +79,16 @@
49C7BCAC1F26938F00F4FFBC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
49C7BCAF1F26938F00F4FFBC /* ConcurrentOperationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentOperationTests.swift; sourceTree = ""; };
49C7BCB01F26938F00F4FFBC /* QueuerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueuerTests.swift; sourceTree = ""; };
- 49C7BCB11F26938F00F4FFBC /* RequestOperationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestOperationTests.swift; sourceTree = ""; };
49C7BCB21F26938F00F4FFBC /* SemaphoreTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SemaphoreTests.swift; sourceTree = ""; };
49C7BCB31F26938F00F4FFBC /* SynchronousOperationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronousOperationTests.swift; sourceTree = ""; };
- 49C7BCB41F26938F00F4FFBC /* URLBuilderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLBuilderTests.swift; sourceTree = ""; };
49C7BCB61F26938F00F4FFBC /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; };
49C7BCB71F26938F00F4FFBC /* Info-macOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = ""; };
49C7BCB81F26938F00F4FFBC /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; };
49C7BCB91F26938F00F4FFBC /* Info-watchOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-watchOS.plist"; sourceTree = ""; };
49C7BCBB1F26938F00F4FFBC /* ConcurrentOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentOperation.swift; sourceTree = ""; };
49C7BCBC1F26938F00F4FFBC /* Queuer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Queuer.swift; sourceTree = ""; };
- 49C7BCBD1F26938F00F4FFBC /* RequestOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestOperation.swift; sourceTree = ""; };
49C7BCBE1F26938F00F4FFBC /* Semaphore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Semaphore.swift; sourceTree = ""; };
49C7BCBF1F26938F00F4FFBC /* SynchronousOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronousOperation.swift; sourceTree = ""; };
- 49C7BCC01F26938F00F4FFBC /* URLBuilder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLBuilder.swift; sourceTree = ""; };
49C7BCC11F26938F00F4FFBC /* Queuer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Queuer.h; sourceTree = ""; };
/* End PBXFileReference section */
diff --git a/README.md b/README.md
index 5aabf3a..b23d3a8 100644
--- a/README.md
+++ b/README.md
@@ -226,13 +226,13 @@ queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
queue.pause()
```
> By calling `pause()` you will not be sure that every operation will be paused.
- If the Operation is already started it will not be on pause until it's a custom Operation that overrides `pause()` function or is a `RequestOperation`.
+ If the Operation is already started it will not be on pause until it's a custom Operation that overrides `pause()` function.
- Resume queue:
```swift
queue.resume()
```
- > To have a complete `pause` and `resume` states you must create a custom Operation that overrides `pause()` and `resume()` function or use a `RequestOperation`.
+ > To have a complete `pause` and `resume` states you must create a custom Operation that overrides `pause()` and `resume()` function.
- Wait until all operations are finished:
```swift
@@ -245,8 +245,7 @@ queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
It allows synchronous and asynchronous tasks, has a pause and resume states, can be easily added to a queue and can be created with a block.
You can create your custom `ConcurrentOperation` by subclassing it.
-You must override `execute()` function and call the `finish()` function inside it, when the task has finished its job to notify the queue.
-Look at [RequestOperation.swift](https://github.com/FabrizioBrancati/Queuer/blob/master/Sources/Queuer/RequestOperation.swift) if you are looking for an example.
+You must override `execute()` function and call the `finish()` function inside it, when the task has finished its job to notify the queue.
For convenience it has an `init` function with a completion block:
```swift
@@ -294,40 +293,6 @@ concurrentOperation.addToQueue(queue)
semaphore.wait()
```
-### Request Operation `*`
-`RequestOperation` allows you to easily create a network request and add it to a queue:
-```swift
-let requestOperation: RequestOperation = RequestOperation(url: self.testAddress) { success, response, data, error in
-
-}
-requestOperation.addToQueue(queue)
-```
-Allowed parameters in `RequestOperation` `init` function:
-- `url` is a `String` representing the request URL
-- `query` is `Dictionary` representing the request query parameters to be added to the `url` with `?` and `&` characters
-- `timeout` is the request timeout
-- `method` is the request method, you can choose to one of: `connect`, `delete`, `get`, `head`, `options`, `patch`, `post` and `put`
-- `cachePolicy` is the request cache policy, referrer to [CachePolicy documentation](https://developer.apple.com/documentation/foundation/nsurlrequest.cachepolicy)
-- `headers` is a `Dictionary` representing the request headers
-- `body` is a `Data` representing the request body
-- `completionHandler` is the request response handler
-
-Response handler variables:
-- `success` is a `Bool` indicating if the request was successful.
- It's successful if its status is between 200 and 399, it wasn't cancelled and did't get any other network error.
-- `respose` is an `HTTPURLResponse` instance.
- It contains all the response headers and the status code.
- May be `nil`.
-- `data` is a `Data` instance with the request body.
- You must convert, to a JSON or String in example, it in order to use.
- May be `nil`.
-- `error` is an `Error` instance with the request error.
- May be `nil`.
-
-It can be `pause`d, `resume`d, `cancel`led and chained with other `Operation`s.
-
-> `*` Currently, `URLSession.shared` property is not yet implemented on Linux, also `RequestOperation` is currently deprecated and will be removed in Queuer 2.
-
Documentation
=============
diff --git a/Sources/Queuer/RequestOperation.swift b/Sources/Queuer/RequestOperation.swift
deleted file mode 100644
index 3fc7c40..0000000
--- a/Sources/Queuer/RequestOperation.swift
+++ /dev/null
@@ -1,230 +0,0 @@
-//
-// RequestOperation.swift
-// Queuer
-//
-// MIT License
-//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati
-//
-// 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.
-
-#if !os(Linux)
-
-import Foundation
-
-/// HTTP Method enum.
-public enum HTTPMethod: String {
- /// CONNECT method.
- case connect = "CONNECT"
- /// DELETE method.
- case delete = "DELETE"
- /// GET method.
- case get = "GET"
- /// HEAD method.
- case head = "HEAD"
- /// OPTIONS method.
- case options = "OPTIONS"
- /// PATCH method.
- case patch = "PATCH"
- /// POST method.
- case post = "POST"
- /// PUT method.
- case put = "PUT"
-}
-
-/// RequestOperation helps you to create network operation with an easy interface.
-@available(*, deprecated: 1.3.2, message: "`RequestOperation` is deprecated and will be removed in Queuer 2.")
-open class RequestOperation: ConcurrentOperation {
- /// Custom HTTP errors.
- public enum RequestError: Error {
- /// URL doesn't exist.
- case urlError
- /// Operation has been cancelled.
- case operationCancelled
- }
-
- /// Request closure alias.
- public typealias RequestClosure = (Bool, HTTPURLResponse?, Data?, Error?) -> Void
-
- /// Global cache policy for all request.
- /// Also cache policy can be set per request.
- public static var globalCachePolicy: URLRequest.CachePolicy = .useProtocolCachePolicy
-
- /// Request task.
- public private(set) var task: URLSessionDataTask?
- /// Request URL.
- public private(set) var url: URL?
- /// Request query.
- public private(set) var query: String?
- /// Request complete URL
- public private(set) var completeURL: URL?
- /// Request timeout.
- public private(set) var timeout: TimeInterval = 30
- /// Request HTTP method.
- public private(set) var method: HTTPMethod = .get
- /// Request cache policy.
- public private(set) var cachePolicy: URLRequest.CachePolicy = globalCachePolicy
- /// Request headers.
- public private(set) var headers: [String: String]?
- /// Request body.
- public private(set) var body: Data?
- /// Request completionHandler.
- public private(set) var completionHandler: RequestClosure?
-
- /// URLSession instance.
- open var session: URLSession {
- let configuration = URLSessionConfiguration.default
- if #available(iOS 11, macOS 10.13, tvOS 11, watchOS 4, *) {
- configuration.waitsForConnectivity = true
- }
- return URLSession(configuration: configuration)
- }
-
- /// URLRequest instance.
- private var request: URLRequest! // swiftlint:disable:this implicitly_unwrapped_optional
-
- /// Private init with executrion block.
- /// You can't create a RequestOperation with only an execution block.
- ///
- /// - Parameter block: Execution block.
- override internal init(executionBlock: (() -> Void)? = nil) {
- super.init(executionBlock: nil)
- }
-
- /// Creates a RequestOperation, ready to be added in a queue.
- ///
- /// - Parameters:
- /// - url: Request URL String.
- /// - query: Request query. Default is nil.
- /// - timeout: Request timeout. Default is 30 seconds.
- /// - method: Request HTTP method. Default is `.get`.
- /// - cachePolicy: Request cache policy. Use static var `globalCachePolicy`
- /// to set a global cache policy for all the RequestOperations.
- /// - headers: Request headers. Defatult is nil.
- /// - body: Request body. Default is nil.
- /// - completionHandler: Request completion handler. Default is nil.
- public init(url: String, query: [String: String]? = nil, timeout: TimeInterval = 30, method: HTTPMethod = .get, cachePolicy: URLRequest.CachePolicy = globalCachePolicy, headers: [String: String]? = nil, body: Data? = nil, completionHandler: RequestClosure? = nil) {
- super.init()
-
- let query = URLBuilder.build(query: query)
-
- self.query = query
- self.url = URL(string: url)
- self.completeURL = URL(string: url + query)
- self.timeout = timeout
- self.method = method
- self.cachePolicy = cachePolicy
- self.headers = headers
- self.body = body
- self.completionHandler = completionHandler
- }
-
- /// Executes the request operation asynchronously.
- override open func execute() {
- /// Check if the Operation has been cancelled.
- guard !self.isCancelled else {
- if let completionHandler = completionHandler {
- completionHandler(false, nil, nil, RequestError.operationCancelled)
- }
-
- /// Notify that the Operation has finished execution.
- self.finish()
-
- return
- }
-
- /// Check if the URL can be used.
- guard let url = self.completeURL else {
- if let completionHandler = completionHandler {
- completionHandler(false, nil, nil, RequestError.urlError)
- }
-
- /// Notify that the Operation has finished execution.
- finish()
-
- return
- }
-
- /// Creates the request.
- request = URLRequest(url: url, cachePolicy: self.cachePolicy, timeoutInterval: self.timeout)
- /// Set the HTTP method.
- request.httpMethod = method.rawValue
- /// Set the HTTP body.
- if let body = body {
- request.httpBody = body
- }
- /// Set all the HTTP headers.
- if let headers = headers {
- headers.forEach { request.addValue($1, forHTTPHeaderField: $0) }
- }
-
- /// Create the task.
- task = session.dataTask(with: request) { [weak self] data, response, error in
- /// Check if the Operation has a completion handler, has an HTTP response
- /// and has not been canceled.
- if let strongSelf = self {
- if let completionHandler = strongSelf.completionHandler {
- if let httpResponse = response as? HTTPURLResponse {
- var error: Error? = error
- /// Set `success` to true if the HTTP status code
- /// is greater or equal than 200 and less than 400
- /// and has not been cancelled.
- let success: Bool = httpResponse.statusCode >= 200 && httpResponse.statusCode < 400 && !strongSelf.isCancelled
-
- /// Check again if the request has not been cancelled.
- if strongSelf.isCancelled {
- error = RequestError.operationCancelled
- }
-
- completionHandler(success, httpResponse, data, error)
- } else {
- completionHandler(false, nil, data, error)
- }
- }
- /// Notify that the Operation has finished execution.
- strongSelf.finish()
- }
- }
- /// Start the task.
- task?.resume()
- }
-
- /// Cancels the request operation.
- override open func cancel() {
- super.cancel()
-
- task?.cancel()
- }
-
- /// Suspends the request operation.
- override open func pause() {
- super.pause()
-
- task?.suspend()
- }
-
- /// Resumes the request operation.
- override open func resume() {
- super.resume()
-
- task?.resume()
- }
-}
-
-#endif
diff --git a/Tests/QueuerTests/RequestOperationTests.swift b/Tests/QueuerTests/RequestOperationTests.swift
deleted file mode 100644
index 7837137..0000000
--- a/Tests/QueuerTests/RequestOperationTests.swift
+++ /dev/null
@@ -1,203 +0,0 @@
-//
-// RequestOperationTests.swift
-// Queuer
-//
-// MIT License
-//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati
-//
-// 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.
-
-#if !os(Linux)
-
-@testable import Queuer
-import XCTest
-
-internal class RequestOperationTests: XCTestCase {
- internal static let allTests = [
- ("testInitFull", testInitFull),
- ("testExecute", testExecute),
- ("testUnsupportedURL", testUnsupportedURL),
- ("testWrongURL", testWrongURL),
- ("testWithoutCompletionHandler", testWithoutCompletionHandler),
- ("testCancel", testCancel),
- ("testPauseAndResume", testPauseAndResume)
- ]
-
- internal let testAddress: String = "https://google.com"
-
- override internal func setUp() {
- super.setUp()
-
- RequestOperation.globalCachePolicy = .reloadIgnoringLocalCacheData
- }
-
- internal func testInit() {
- let queue = Queuer(name: "RequestOperationTestInit")
-
- let requestOperation = RequestOperation()
- requestOperation.addToQueue(queue)
-
- XCTAssertNil(requestOperation.url?.absoluteString)
- XCTAssertNil(requestOperation.query)
- XCTAssertNil(requestOperation.completeURL)
- XCTAssertEqual(requestOperation.timeout, 30)
- XCTAssertEqual(requestOperation.method, .get)
- XCTAssertEqual(requestOperation.headers ?? [:], [:])
- XCTAssertNil(requestOperation.body)
- }
-
- internal func testInitFull() {
- let queue = Queuer(name: "RequestOperationTestInitFull")
- let testExpectation = expectation(description: "InitFull")
-
- let requestOperation = RequestOperation(url: self.testAddress, query: ["test": "test", "test2": "test2"], timeout: 30, method: .get, headers: ["test": "test", "test2": "test2"], body: Data()) { _, _, _, _ in
- testExpectation.fulfill()
- }
- requestOperation.addToQueue(queue)
-
- XCTAssertEqual(requestOperation.url?.absoluteString, self.testAddress)
- XCTAssertTrue(requestOperation.query?.contains("test=test") ?? false)
- XCTAssertTrue(requestOperation.query?.contains("test2=test2") ?? false)
- XCTAssertTrue(requestOperation.completeURL?.absoluteString.contains(self.testAddress) ?? false)
- XCTAssertTrue(requestOperation.completeURL?.absoluteString.contains("test=test") ?? false)
- XCTAssertTrue(requestOperation.completeURL?.absoluteString.contains("test2=test2") ?? false)
- XCTAssertEqual(requestOperation.timeout, 30)
- XCTAssertEqual(requestOperation.method, .get)
- XCTAssertEqual(requestOperation.headers ?? [:], ["test": "test", "test2": "test2"])
- XCTAssertEqual(requestOperation.body, Data())
-
- waitForExpectations(timeout: 5) { error in
- XCTAssertNil(error)
- }
- }
-
- internal func testExecute() {
- let queue = Queuer(name: "RequestOperationTestExecute")
- let testExpectation = expectation(description: "Execute")
-
- let requestOperation = RequestOperation(url: self.testAddress) { success, _, _, error in
- XCTAssertNil(error)
- XCTAssertTrue(success)
- testExpectation.fulfill()
- }
- requestOperation.addToQueue(queue)
-
- waitForExpectations(timeout: 5) { error in
- XCTAssertNil(error)
- }
- }
-
- internal func testUnsupportedURL() {
- let queue = Queuer(name: "RequestOperationTestUnsupportedURL")
- let testExpectation = expectation(description: "Unsupported URL")
-
- let requestOperation = RequestOperation(url: "/path/to/something") { success, _, _, error in
- XCTAssertTrue(error is URLError)
- XCTAssertFalse(success)
- testExpectation.fulfill()
- }
- requestOperation.addToQueue(queue)
-
- waitForExpectations(timeout: 5) { error in
- XCTAssertNil(error)
- }
- }
-
- internal func testWrongURL() {
- let queue = Queuer(name: "RequestOperationTestWrongURL")
- let testExpectation = expectation(description: "Wrong URL")
-
- let requestOperation = RequestOperation(url: "👍") { success, _, _, error in
- XCTAssertEqual(error as? RequestOperation.RequestError, RequestOperation.RequestError.urlError)
- XCTAssertFalse(success)
- testExpectation.fulfill()
- }
- requestOperation.addToQueue(queue)
-
- waitForExpectations(timeout: 5) { error in
- XCTAssertNil(error)
- }
- }
-
- internal func testWithoutCompletionHandler() {
- let queue = Queuer(name: "RequestOperationTestWithoutCompletionHandler")
- let requestOperation = RequestOperation(url: self.testAddress)
- requestOperation.addToQueue(queue)
-
- XCTAssertEqual(queue.operations, [requestOperation])
- XCTAssertEqual(queue.operationCount, 1)
- }
-
- internal func testCancel() {
- let queue = Queuer(name: "RequestOperationTestCancel")
- let testExpectation = expectation(description: "Cancel")
-
- let requestOperation = RequestOperation(url: "http://fakehttpaddress.com/", cachePolicy: .reloadIgnoringLocalCacheData) { success, _, _, _ in
- // Currently there is no easy way to check in time if the operation was cancelled before completion.
- // XCTAssertEqual(error as? RequestOperation.RequestError, RequestOperation.RequestError.operationCancelled)
- XCTAssertFalse(success)
- testExpectation.fulfill()
- }
- requestOperation.addToQueue(queue)
-
- requestOperation.cancel()
-
- waitForExpectations(timeout: 5) { error in
- XCTAssertNil(error)
- }
- }
-
- internal func testPauseAndResume() {
- let queue = Queuer(name: "RequestOperationTestPauseAndResume")
- let testExpectation = expectation(description: "Pause and Resume")
- var order: [Int] = []
-
- let requestOperation1 = RequestOperation(url: self.testAddress) { success, _, _, error in
- XCTAssertNil(error)
- XCTAssertTrue(success)
- order.append(0)
- }
- let requestOperation2 = RequestOperation(url: self.testAddress) { success, _, _, error in
- XCTAssertNil(error)
- XCTAssertTrue(success)
- order.append(1)
- }
- queue.addChainedOperations([requestOperation1, requestOperation2]) {
- order.append(2)
- }
-
- queue.pause()
- testExpectation.fulfill()
-
- XCTAssertLessThanOrEqual(queue.operationCount, 3)
-
- waitForExpectations(timeout: 5) { error in
- XCTAssertNil(error)
- XCTAssertFalse(queue.isExecuting)
- XCTAssertLessThanOrEqual(queue.operationCount, 3)
- XCTAssertNotEqual(order, [0, 1, 2])
-
- queue.resume()
- XCTAssertTrue(queue.isExecuting)
- }
- }
-}
-
-#endif
From 37df161711b235b3eaece652fc66925338c6d853 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:05:05 +0200
Subject: [PATCH 15/57] Removing URLBuilder
---
Sources/Queuer/URLBuilder.swift | 50 -----------------
Tests/QueuerTests/URLBuilderTests.swift | 73 -------------------------
2 files changed, 123 deletions(-)
delete mode 100644 Sources/Queuer/URLBuilder.swift
delete mode 100644 Tests/QueuerTests/URLBuilderTests.swift
diff --git a/Sources/Queuer/URLBuilder.swift b/Sources/Queuer/URLBuilder.swift
deleted file mode 100644
index c139701..0000000
--- a/Sources/Queuer/URLBuilder.swift
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// URLBuilder.swift
-// Queuer
-//
-// MIT License
-//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati
-//
-// 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.
-
-import Foundation
-
-/// URL builder struct.
-internal enum URLBuilder {
- /// Builds the query as a string, ready to be added in the URL.
- ///
- /// - Parameter query: Query dictionary.
- /// - Returns: Returns the query as a String.
- internal static func build(query: [String: String]?) -> String {
- guard let query = query else {
- return ""
- }
-
- var finalQuery: String = ""
- for (index, parameter) in query.enumerated() {
- guard let parameterKey = parameter.key.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed), let parameterValue = parameter.value.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) else {
- continue
- }
- finalQuery += index == 0 ? "?" : "&"
- finalQuery += parameterKey + "=" + parameterValue
- }
- return finalQuery
- }
-}
diff --git a/Tests/QueuerTests/URLBuilderTests.swift b/Tests/QueuerTests/URLBuilderTests.swift
deleted file mode 100644
index d730d6d..0000000
--- a/Tests/QueuerTests/URLBuilderTests.swift
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// URLBuilderTests.swift
-// Queuer
-//
-// MIT License
-//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati
-//
-// 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.
-
-@testable import Queuer
-import XCTest
-
-internal class URLBuilderTests: XCTestCase {
- internal static let allTests = [
- ("testWithoutParameters", testWithoutParameters),
- ("testWithSingleParameter", testBuildURLWithSingleParameter),
- ("testWithMultipleParameters", testWithMultipleParameters),
- ("testWithEmojiCharctersInParameters", testWithEmojiCharctersInParameters)
- //("testWithStrangeCharctersInParameters", testWithStrangeCharctersInParameters)
- ]
-
- internal func testWithoutParameters() {
- let query = URLBuilder.build(query: [:])
-
- XCTAssertEqual(query, "")
- }
-
- internal func testBuildURLWithSingleParameter() {
- let query = URLBuilder.build(query: ["test": "test"])
-
- XCTAssertEqual(query, "?test=test")
- }
-
- internal func testWithMultipleParameters() {
- let query = URLBuilder.build(query: ["test": "test", "test2": "test2"])
-
- XCTAssert(query == "?test=test&test2=test2" || query == "?test2=test2&test=test")
- }
-
- internal func testWithEmojiCharctersInParameters() {
- let query = URLBuilder.build(query: ["test": "test", "test👍": "test👍"])
-
- XCTAssert(query == "?test=test&test%F0%9F%91%8D=test%F0%9F%91%8D" || query == "?test%F0%9F%91%8D=test%F0%9F%91%8D&test=test")
- }
-
- /// Thanks to [Stack Overflow](https://stackoverflow.com/a/33558934/4032046 ).
- internal func testWithStrangeCharctersInParameters() {
- guard let string = String(bytes: [0xD8, 0x00] as [UInt8], encoding: String.Encoding.utf16BigEndian) else {
- XCTFail("`testWithStrangeCharctersInParameters` error")
- return
- }
-
- let query = URLBuilder.build(query: [string: "test", "test👍": string])
- XCTAssertEqual(query, "")
- }
-}
From 577115246618387ce4f53c97cfc338868342f5ce Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:05:26 +0200
Subject: [PATCH 16/57] Allowing custom timeout on Semaphore
---
Sources/Queuer/Semaphore.swift | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Sources/Queuer/Semaphore.swift b/Sources/Queuer/Semaphore.swift
index a31987c..17722f5 100644
--- a/Sources/Queuer/Semaphore.swift
+++ b/Sources/Queuer/Semaphore.swift
@@ -46,8 +46,8 @@ public struct Semaphore {
/// Wait for a `continue` function call.
@discardableResult
- public func wait() -> DispatchTimeoutResult {
- return semaphore.wait(timeout: .distantFuture)
+ public func wait(_ timeout: DispatchTime = .distantFuture) -> DispatchTimeoutResult {
+ return semaphore.wait(timeout: timeout)
}
/// This function returns non-zero if a thread is woken. Otherwise, zero is returned.
From 7447d0d9a0dba665c9ebe0939104baec95b2a095 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:05:34 +0200
Subject: [PATCH 17/57] Minor changes
---
README.md | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index b23d3a8..24baef3 100644
--- a/README.md
+++ b/README.md
@@ -56,12 +56,12 @@ Here is the list of all the features:
Requirements
============
-| **Swift** | **Xcode** | **Queuer** | **iOS** | **macOS** | **tvOS** | **watchOS** | **Linux** |
-|-----------|-----------|---------------|---------|-----------|----------|-------------|-----------|
-| 3.1...3.2 | 8.3...9.0 | 1.0.0...1.1.0 | 8.0+ | 10.10 | 9.0 | 2.0+ | ![✓] `*` |
-| 4.0 | 9.0...9.2 | 1.3.0 | 8.0+ | 10.10 | 9.0 | 2.0+ | ![✓] `*` |
-| 4.1 | 9.3...9.4 | 1.3.1...1.3.2 | 8.0+ | 10.10 | 9.0 | 2.0+ | ![✓] `*` |
-| 4.2 | 10.0 | 1.x.x | 8.0+ | 10.10 | 9.0 | 2.0+ | ![✓] `*` |
+| **Swift** | **Xcode** | **Queuer** | **iOS** | **macOS** | **tvOS** | **watchOS** | **Linux** |
+|-----------|-----------|---------------|---------|------------|-----------|-------------|-----------|
+| 3.1...3.2 | 8.3...9.0 | 1.0.0...1.1.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] `*` |
+| 4.0 | 9.0...9.2 | 1.3.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] `*` |
+| 4.1 | 9.3...9.4 | 1.3.1...1.3.2 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] `*` |
+| 4.2 | 10.0 | 2.x.x | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] `*` |
> `*` Currently, `URLSession.shared` property is not yet implemented on Linux.
@@ -132,7 +132,7 @@ See [Requirements](https://github.com/FabrizioBrancati/Queuer#requirements) sect
- Create a **Package.swift** file in your **project directory** and write into:
```swift
- // swift-tools-version:4.0
+ // swift-tools-version:4.2
import PackageDescription
let package = Package(
From 35ea8175327c26043aa3f5f19fe1724399bb7626 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:05:47 +0200
Subject: [PATCH 18/57] Fixing Linux tests
---
Tests/LinuxMain.swift | 1 -
1 file changed, 1 deletion(-)
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
index fd29c7b..c1defa8 100644
--- a/Tests/LinuxMain.swift
+++ b/Tests/LinuxMain.swift
@@ -31,7 +31,6 @@ import XCTest
XCTMain([
testCase(ConcurrentOperationTests.allTests),
testCase(QueuerTests.allTests),
- testCase(URLBuilderTests.allTests),
testCase(SemaphoreTests.allTests),
testCase(SynchronousOperationTests.allTests)
])
From 70ec90e598ba099f978046312c2622459c25b880 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:10:25 +0200
Subject: [PATCH 19/57] Improving README
---
README.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/README.md b/README.md
index 24baef3..c718e7e 100644
--- a/README.md
+++ b/README.md
@@ -283,6 +283,11 @@ defer { semaphore.continue() }
/// Your task here
```
+You can even set a custom timeout, default is `.distantFuture`:
+```swift
+semaphore.wait(DispatchTime(uptimeNanoseconds: 1_000_000_000))
+```
+
It's more useful if used inside an asynchronous task:
```swift
let concurrentOperation = ConcurrentOperation {
From 565ad5fa2881793e9ab1fec7b99a8393061dac62 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:10:47 +0200
Subject: [PATCH 20/57] Adding Scheduler struct
---
Queuer.xcodeproj/project.pbxproj | 36 +++++++--------
Sources/Queuer/Scheduler.swift | 61 +++++++++++++++++++++++++
Tests/LinuxMain.swift | 1 +
Tests/QueuerTests/SchedulerTests.swift | 63 ++++++++++++++++++++++++++
4 files changed, 143 insertions(+), 18 deletions(-)
create mode 100644 Sources/Queuer/Scheduler.swift
create mode 100644 Tests/QueuerTests/SchedulerTests.swift
diff --git a/Queuer.xcodeproj/project.pbxproj b/Queuer.xcodeproj/project.pbxproj
index a348365..fdac045 100644
--- a/Queuer.xcodeproj/project.pbxproj
+++ b/Queuer.xcodeproj/project.pbxproj
@@ -8,6 +8,13 @@
/* Begin PBXBuildFile section */
493F57291F21F32B009EC8FA /* Queuer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 493F57201F21F32B009EC8FA /* Queuer.framework */; };
+ 4946BDF6214D586900FAFC84 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4946BDF5214D586900FAFC84 /* Scheduler.swift */; };
+ 4946BDF7214D586900FAFC84 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4946BDF5214D586900FAFC84 /* Scheduler.swift */; };
+ 4946BDF8214D586900FAFC84 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4946BDF5214D586900FAFC84 /* Scheduler.swift */; };
+ 4946BDF9214D586900FAFC84 /* Scheduler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4946BDF5214D586900FAFC84 /* Scheduler.swift */; };
+ 4946BDFB214D5C0100FAFC84 /* SchedulerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4946BDFA214D5C0100FAFC84 /* SchedulerTests.swift */; };
+ 4946BDFC214D5C0100FAFC84 /* SchedulerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4946BDFA214D5C0100FAFC84 /* SchedulerTests.swift */; };
+ 4946BDFD214D5C0100FAFC84 /* SchedulerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4946BDFA214D5C0100FAFC84 /* SchedulerTests.swift */; };
4995D7431F21E19C00A34E6E /* Queuer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4995D7391F21E19B00A34E6E /* Queuer.framework */; };
4995D76F1F21ED1C00A34E6E /* Queuer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4995D7661F21ED1B00A34E6E /* Queuer.framework */; };
49B28E2C1F27EDCB00D0819A /* Queuer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49C7BCC11F26938F00F4FFBC /* Queuer.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -71,6 +78,8 @@
/* Begin PBXFileReference section */
493F57201F21F32B009EC8FA /* Queuer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Queuer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
493F57281F21F32B009EC8FA /* QueuerTests macOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "QueuerTests macOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 4946BDF5214D586900FAFC84 /* Scheduler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scheduler.swift; sourceTree = ""; };
+ 4946BDFA214D5C0100FAFC84 /* SchedulerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SchedulerTests.swift; sourceTree = ""; };
4995D7391F21E19B00A34E6E /* Queuer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Queuer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4995D7421F21E19C00A34E6E /* QueuerTests iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "QueuerTests iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
4995D7581F21EA3F00A34E6E /* Queuer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Queuer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -185,10 +194,9 @@
children = (
49C7BCAF1F26938F00F4FFBC /* ConcurrentOperationTests.swift */,
49C7BCB01F26938F00F4FFBC /* QueuerTests.swift */,
- 49C7BCB11F26938F00F4FFBC /* RequestOperationTests.swift */,
+ 4946BDFA214D5C0100FAFC84 /* SchedulerTests.swift */,
49C7BCB21F26938F00F4FFBC /* SemaphoreTests.swift */,
49C7BCB31F26938F00F4FFBC /* SynchronousOperationTests.swift */,
- 49C7BCB41F26938F00F4FFBC /* URLBuilderTests.swift */,
);
path = QueuerTests;
sourceTree = "";
@@ -211,10 +219,9 @@
children = (
49C7BCBB1F26938F00F4FFBC /* ConcurrentOperation.swift */,
49C7BCBC1F26938F00F4FFBC /* Queuer.swift */,
- 49C7BCBD1F26938F00F4FFBC /* RequestOperation.swift */,
+ 4946BDF5214D586900FAFC84 /* Scheduler.swift */,
49C7BCBE1F26938F00F4FFBC /* Semaphore.swift */,
49C7BCBF1F26938F00F4FFBC /* SynchronousOperation.swift */,
- 49C7BCC01F26938F00F4FFBC /* URLBuilder.swift */,
);
path = Queuer;
sourceTree = "";
@@ -510,12 +517,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 49C7BCE31F26939A00F4FFBC /* RequestOperation.swift in Sources */,
49C7BCE21F26939A00F4FFBC /* Queuer.swift in Sources */,
49C7BCE41F26939A00F4FFBC /* Semaphore.swift in Sources */,
49C7BCE11F26939A00F4FFBC /* ConcurrentOperation.swift in Sources */,
+ 4946BDF7214D586900FAFC84 /* Scheduler.swift in Sources */,
49C7BCE51F26939A00F4FFBC /* SynchronousOperation.swift in Sources */,
- 49C7BCE61F26939A00F4FFBC /* URLBuilder.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -523,12 +529,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 49C7BCEF1F2693A000F4FFBC /* RequestOperationTests.swift in Sources */,
49C7BCEE1F2693A000F4FFBC /* QueuerTests.swift in Sources */,
49C7BCF01F2693A000F4FFBC /* SemaphoreTests.swift in Sources */,
+ 4946BDFC214D5C0100FAFC84 /* SchedulerTests.swift in Sources */,
49C7BCED1F2693A000F4FFBC /* ConcurrentOperationTests.swift in Sources */,
49C7BCF11F2693A000F4FFBC /* SynchronousOperationTests.swift in Sources */,
- 49C7BCF21F2693A000F4FFBC /* URLBuilderTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -539,9 +544,8 @@
49C7BCCE1F26938F00F4FFBC /* ConcurrentOperation.swift in Sources */,
49C7BCD21F26938F00F4FFBC /* SynchronousOperation.swift in Sources */,
49C7BCCF1F26938F00F4FFBC /* Queuer.swift in Sources */,
- 49C7BCD31F26938F00F4FFBC /* URLBuilder.swift in Sources */,
+ 4946BDF6214D586900FAFC84 /* Scheduler.swift in Sources */,
49C7BCD11F26938F00F4FFBC /* Semaphore.swift in Sources */,
- 49C7BCD01F26938F00F4FFBC /* RequestOperation.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -549,12 +553,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 49C7BCE91F26939F00F4FFBC /* RequestOperationTests.swift in Sources */,
49C7BCE81F26939F00F4FFBC /* QueuerTests.swift in Sources */,
49C7BCEA1F26939F00F4FFBC /* SemaphoreTests.swift in Sources */,
+ 4946BDFB214D5C0100FAFC84 /* SchedulerTests.swift in Sources */,
49C7BCE71F26939F00F4FFBC /* ConcurrentOperationTests.swift in Sources */,
49C7BCEB1F26939F00F4FFBC /* SynchronousOperationTests.swift in Sources */,
- 49C7BCEC1F26939F00F4FFBC /* URLBuilderTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -562,12 +565,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 49C7BCD71F26939900F4FFBC /* RequestOperation.swift in Sources */,
49C7BCD61F26939900F4FFBC /* Queuer.swift in Sources */,
49C7BCD81F26939900F4FFBC /* Semaphore.swift in Sources */,
49C7BCD51F26939900F4FFBC /* ConcurrentOperation.swift in Sources */,
+ 4946BDF9214D586900FAFC84 /* Scheduler.swift in Sources */,
49C7BCD91F26939900F4FFBC /* SynchronousOperation.swift in Sources */,
- 49C7BCDA1F26939900F4FFBC /* URLBuilder.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -575,12 +577,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 49C7BCDD1F26939A00F4FFBC /* RequestOperation.swift in Sources */,
49C7BCDC1F26939A00F4FFBC /* Queuer.swift in Sources */,
49C7BCDE1F26939A00F4FFBC /* Semaphore.swift in Sources */,
49C7BCDB1F26939A00F4FFBC /* ConcurrentOperation.swift in Sources */,
+ 4946BDF8214D586900FAFC84 /* Scheduler.swift in Sources */,
49C7BCDF1F26939A00F4FFBC /* SynchronousOperation.swift in Sources */,
- 49C7BCE01F26939A00F4FFBC /* URLBuilder.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -588,12 +589,11 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 49C7BCF51F2693A100F4FFBC /* RequestOperationTests.swift in Sources */,
49C7BCF41F2693A100F4FFBC /* QueuerTests.swift in Sources */,
49C7BCF61F2693A100F4FFBC /* SemaphoreTests.swift in Sources */,
+ 4946BDFD214D5C0100FAFC84 /* SchedulerTests.swift in Sources */,
49C7BCF31F2693A100F4FFBC /* ConcurrentOperationTests.swift in Sources */,
49C7BCF71F2693A100F4FFBC /* SynchronousOperationTests.swift in Sources */,
- 49C7BCF81F2693A100F4FFBC /* URLBuilderTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
diff --git a/Sources/Queuer/Scheduler.swift b/Sources/Queuer/Scheduler.swift
new file mode 100644
index 0000000..8e0216c
--- /dev/null
+++ b/Sources/Queuer/Scheduler.swift
@@ -0,0 +1,61 @@
+//
+// Scheduler.swift
+// Queuer
+//
+// MIT License
+//
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
+//
+// 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.
+
+import Dispatch
+import Foundation
+
+public struct Scheduler {
+ public private(set) var timer: DispatchSourceTimer
+ public private(set) var deadline: DispatchTime
+ public private(set) var repeating: DispatchTimeInterval
+ public private(set) var qualityOfService: DispatchQoS
+ public private(set) var handler: (() -> Void)? = nil
+
+ public init(deadline: DispatchTime, repeating: DispatchTimeInterval, qualityOfService: DispatchQoS = .default, handler: (() -> Void)? = nil) {
+ self.deadline = deadline
+ self.repeating = repeating
+ self.qualityOfService = qualityOfService
+ self.handler = handler
+
+ timer = DispatchSource.makeTimerSource()
+ timer.schedule(deadline: deadline, repeating: repeating)
+ if let handler = handler {
+ timer.setEventHandler(qos: qualityOfService) {
+ handler()
+ }
+ timer.resume()
+ }
+ }
+
+ public mutating func setHandler(_ handler: @escaping () -> Void) {
+ self.handler = handler
+
+ timer.setEventHandler(qos: qualityOfService) {
+ handler()
+ }
+ timer.resume()
+ }
+}
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
index c1defa8..3f8de96 100644
--- a/Tests/LinuxMain.swift
+++ b/Tests/LinuxMain.swift
@@ -31,6 +31,7 @@ import XCTest
XCTMain([
testCase(ConcurrentOperationTests.allTests),
testCase(QueuerTests.allTests),
+ testCase(SchedulerTests.allTests),
testCase(SemaphoreTests.allTests),
testCase(SynchronousOperationTests.allTests)
])
diff --git a/Tests/QueuerTests/SchedulerTests.swift b/Tests/QueuerTests/SchedulerTests.swift
new file mode 100644
index 0000000..ed2db2f
--- /dev/null
+++ b/Tests/QueuerTests/SchedulerTests.swift
@@ -0,0 +1,63 @@
+//
+// SchedulerTests.swift
+// Queuer
+//
+// MIT License
+//
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
+//
+// 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.
+
+import Dispatch
+@testable import Queuer
+import XCTest
+
+internal class SchedulerTests: XCTestCase {
+ internal static let allTests = [
+ ("testInitWithoutHandler", testInitWithoutHandler),
+ ("testInitWithHandler", testInitWithHandler)
+ ]
+
+ internal func testInitWithoutHandler() {
+ let testExpectation = expectation(description: "Init Without Handler")
+
+ var schedule = Scheduler(deadline: .now(), repeating: .seconds(1))
+ schedule.setHandler {
+ testExpectation.fulfill()
+ schedule.timer.cancel()
+ }
+
+ waitForExpectations(timeout: 2) { error in
+ XCTAssertNil(error)
+ }
+ }
+
+ internal func testInitWithHandler() {
+ let testExpectation = expectation(description: "Init With Handler")
+
+ let schedule = Scheduler(deadline: .now(), repeating: .seconds(1)) {
+ testExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 2) { error in
+ XCTAssertNil(error)
+ schedule.timer.cancel()
+ }
+ }
+}
From 9cae3f744b7766732a869ea0ad9bfc1732a96f87 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 15 Sep 2018 18:17:49 +0200
Subject: [PATCH 21/57] Improving documentation
---
README.md | 22 ++++++++++++++++++++++
Sources/Queuer/Scheduler.swift | 16 ++++++++++++++++
Tests/QueuerTests/SchedulerTests.swift | 2 +-
3 files changed, 39 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c718e7e..91bc9eb 100644
--- a/README.md
+++ b/README.md
@@ -272,6 +272,28 @@ let synchronousOperation = SynchronousOperation {
synchronousOperation.addToQueue(queue)
```
+### Scheduler
+A `Scheduler` is a struct that uses the GDC's `DispatchSourceTimer` to create a timer that can execute functions with a specified interval and quality of service.
+
+```swift
+let schedule = Scheduler(deadline: .now(), repeating: .seconds(1)) {
+ /// Your task here
+}
+```
+
+You can even create a `Scheduler` without the handler and set it later:
+```swift
+var schedule = Scheduler(deadline: .now(), repeating: .seconds(1))
+schedule.setHandler {
+ /// Your task here.
+}
+```
+
+With `timer` property you can access to all `DispatchSourceTimer` properties and functions, like `cancel()`:
+```swift
+schedule.timer.cancel()
+```
+
### Semaphore
A `Semaphore` is a struct that uses the GCD's `DispatchSemaphore` to create a semaphore on the function and wait until it finish its job.
I recommend you to use a `defer { semaphore.continue() }` right after the `Semaphore` creation and `wait()` call.
diff --git a/Sources/Queuer/Scheduler.swift b/Sources/Queuer/Scheduler.swift
index 8e0216c..1dc5137 100644
--- a/Sources/Queuer/Scheduler.swift
+++ b/Sources/Queuer/Scheduler.swift
@@ -27,13 +27,26 @@
import Dispatch
import Foundation
+/// Scheduler struct, based on top of `DispatchSourceTimer`.
public struct Scheduler {
+ /// Schedule timer.
public private(set) var timer: DispatchSourceTimer
+ /// Schedule deadline.
public private(set) var deadline: DispatchTime
+ /// Schedule repeating interval.
public private(set) var repeating: DispatchTimeInterval
+ /// Schedule quality of service.
public private(set) var qualityOfService: DispatchQoS
+ /// Schedule handler.
public private(set) var handler: (() -> Void)? = nil
+ /// Create a schedule.
+ ///
+ /// - Parameters:
+ /// - deadline: Deadline.
+ /// - repeating: Repeating interval
+ /// - qualityOfService: Quality of service.
+ /// - handler: Closure handler.
public init(deadline: DispatchTime, repeating: DispatchTimeInterval, qualityOfService: DispatchQoS = .default, handler: (() -> Void)? = nil) {
self.deadline = deadline
self.repeating = repeating
@@ -50,6 +63,9 @@ public struct Scheduler {
}
}
+ /// Set the handler after schedule creation.
+ ///
+ /// - Parameter handler: Closure handler.
public mutating func setHandler(_ handler: @escaping () -> Void) {
self.handler = handler
diff --git a/Tests/QueuerTests/SchedulerTests.swift b/Tests/QueuerTests/SchedulerTests.swift
index ed2db2f..c4cf963 100644
--- a/Tests/QueuerTests/SchedulerTests.swift
+++ b/Tests/QueuerTests/SchedulerTests.swift
@@ -51,7 +51,7 @@ internal class SchedulerTests: XCTestCase {
internal func testInitWithHandler() {
let testExpectation = expectation(description: "Init With Handler")
- let schedule = Scheduler(deadline: .now(), repeating: .seconds(1)) {
+ let schedule = Scheduler(deadline: .now(), repeating: .never) {
testExpectation.fulfill()
}
From d66b913ba82d15bdf4cd8db1067fc7a23cb141b7 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 16 Sep 2018 19:30:40 +0200
Subject: [PATCH 22/57] Updating README
---
README.md | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/README.md b/README.md
index 91bc9eb..dfb3fae 100644
--- a/README.md
+++ b/README.md
@@ -38,32 +38,29 @@ Queuer is a queue manager, built on top of [OperationQueue](https://developer.ap
It allows you to create any synchronous and asynchronous task easily, with just a few lines.
Here is the list of all the features:
-- [x] Works on all Swift compatible platforms (even Linux `*`)
+- [x] Works on all Swift compatible platforms (even Linux)
- [x] Easy to use
- [x] Well documented (100% documented)
-- [x] Well tested (currently 99% of code coverage)
+- [x] Well tested (100% of code coverage)
- [x] Create an operation block
- [x] Create a single operation
- [x] Create chained operations
- [x] Manage a centralized queue
- [x] Create unlimited queue
- [x] Declare how many concurrent operation a queue can handle
+- [x] Create semaphores
+- [x] Create and handle schedules
- [ ] Ability to restore uncompleted operations
-- [ ] Wrappers for other frameworks (like Alamofire, Moya, ecc) maybe with pod subspecs
-
-> `*` Currently, `URLSession.shared` property is not yet implemented on Linux.
Requirements
============
| **Swift** | **Xcode** | **Queuer** | **iOS** | **macOS** | **tvOS** | **watchOS** | **Linux** |
|-----------|-----------|---------------|---------|------------|-----------|-------------|-----------|
-| 3.1...3.2 | 8.3...9.0 | 1.0.0...1.1.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] `*` |
-| 4.0 | 9.0...9.2 | 1.3.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] `*` |
-| 4.1 | 9.3...9.4 | 1.3.1...1.3.2 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] `*` |
-| 4.2 | 10.0 | 2.x.x | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] `*` |
-
-> `*` Currently, `URLSession.shared` property is not yet implemented on Linux.
+| 3.1...3.2 | 8.3...9.0 | 1.0.0...1.1.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
+| 4.0 | 9.0...9.2 | 1.3.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
+| 4.1 | 9.3...9.4 | 1.3.1...1.3.2 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
+| 4.2 | 10.0 | 2.x.x | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
Installing
==========
From 79d1ead2b50213533f9e5b49dd8b14f017d7527a Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 17 Sep 2018 01:00:34 +0200
Subject: [PATCH 23/57] Minor change
---
Sources/Queuer/Scheduler.swift | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Sources/Queuer/Scheduler.swift b/Sources/Queuer/Scheduler.swift
index 1dc5137..12014e0 100644
--- a/Sources/Queuer/Scheduler.swift
+++ b/Sources/Queuer/Scheduler.swift
@@ -38,7 +38,7 @@ public struct Scheduler {
/// Schedule quality of service.
public private(set) var qualityOfService: DispatchQoS
/// Schedule handler.
- public private(set) var handler: (() -> Void)? = nil
+ public private(set) var handler: (() -> Void)?
/// Create a schedule.
///
From 4260749d6b203a9bfc0ee3166989362fb39607f2 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 17 Sep 2018 01:23:11 +0200
Subject: [PATCH 24/57] Adding `addCompletionHandler(_:)` function
---
Sources/Queuer/Queuer.swift | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/Sources/Queuer/Queuer.swift b/Sources/Queuer/Queuer.swift
index 49796bc..8a7a3df 100644
--- a/Sources/Queuer/Queuer.swift
+++ b/Sources/Queuer/Queuer.swift
@@ -120,11 +120,7 @@ public class Queuer {
return
}
- let completionOperation = BlockOperation(block: completionHandler)
- if !operations.isEmpty {
- completionOperation.addDependency(operations[operations.count - 1])
- }
- addOperation(completionOperation)
+ addCompletionHandler(completionHandler)
}
/// Add an Array of chained Operations.
@@ -141,6 +137,17 @@ public class Queuer {
addChainedOperations(operations, completionHandler: completionHandler)
}
+ /// Add a completion block to the queue.
+ ///
+ /// - Parameter completionHandler: Completion handler to be executed as last operation.
+ public func addCompletionHandler(_ completionHandler: @escaping () -> Void) {
+ let completionOperation = BlockOperation(block: completionHandler)
+ if let lastOperation = operations.last {
+ completionOperation.addDependency(lastOperation)
+ }
+ addOperation(completionOperation)
+ }
+
/// Cancel all Operations in queue.
public func cancelAll() {
queue.cancelAllOperations()
From fc3a20f00b04289a071d57758c25efecc591c42b Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 17 Sep 2018 01:23:48 +0200
Subject: [PATCH 25/57] Adding retry feature #10
---
Sources/Queuer/ConcurrentOperation.swift | 38 +++++++++++++++----
Sources/Queuer/SynchronousOperation.swift | 8 +++-
.../ConcurrentOperationTests.swift | 2 +-
Tests/QueuerTests/QueuerTests.swift | 34 ++++++++---------
Tests/QueuerTests/SemaphoreTests.swift | 4 +-
.../SynchronousOperationTests.swift | 12 +++---
6 files changed, 63 insertions(+), 35 deletions(-)
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index 2906a98..e1132ea 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -29,12 +29,12 @@ import Foundation
/// It allows asynchronous tasks, has a pause and resume states, can be easily added to a queue and can be created with a block.
open class ConcurrentOperation: Operation {
/// Operation's execution block.
- public var executionBlock: (() -> Void)?
+ public var executionBlock: ((_ operation: ConcurrentOperation) -> Void)?
/// Creates the Operation with an execution block.
///
/// - Parameter executionBlock: Execution block.
- public init(executionBlock: (() -> Void)? = nil) {
+ public init(executionBlock: ((_ operation: ConcurrentOperation) -> Void)? = nil) {
super.init()
self.executionBlock = executionBlock
@@ -75,6 +75,20 @@ open class ConcurrentOperation: Operation {
return _finished
}
+ /// You should use `hasFailed` if retry is enabled.
+ /// Set it to `true` if the operation has failed, otherwise `false`.
+ /// Default is `false` to avoid retries.
+ open var hasFailed = false
+
+ /// Maximum allowed retries.
+ open var maximumRetries = 3
+
+ /// Current retry tentative.
+ open var currentRetry = 0
+
+ /// Specify if the operation should retry another time.
+ private var shouldRetry = true
+
/// Start the Operation.
override open func start() {
_executing = true
@@ -85,16 +99,26 @@ open class ConcurrentOperation: Operation {
/// If `executionBlock` is set, it will be executed and also `finish()` will be called.
open func execute() {
if let executionBlock = executionBlock {
- executionBlock()
- self.finish()
+ while shouldRetry {
+ executionBlock(self)
+ self.finish(hasFailed)
+ }
}
}
/// Notify the completion of async task and hence the completion of the operation.
/// Must be called when the Operation is finished.
- open func finish() {
- _executing = false
- _finished = true
+ ///
+ /// - Parameter hasFailed: Set it to `true` if the operation has failed, otherwise `false`.
+ open func finish(_ hasFailed: Bool) {
+ if !hasFailed || currentRetry >= maximumRetries {
+ _executing = false
+ _finished = true
+ shouldRetry = false
+ } else {
+ currentRetry += 1
+ shouldRetry = true
+ }
}
/// Pause the current Operation, if it's supported.
diff --git a/Sources/Queuer/SynchronousOperation.swift b/Sources/Queuer/SynchronousOperation.swift
index db89b70..c9a5b02 100644
--- a/Sources/Queuer/SynchronousOperation.swift
+++ b/Sources/Queuer/SynchronousOperation.swift
@@ -36,9 +36,13 @@ public class SynchronousOperation: ConcurrentOperation {
return false
}
- /// Notify the completion of sync task and hence the completion of the operation.
+ /// Notify the completion of async task and hence the completion of the operation.
/// Must be called when the Operation is finished.
- override public func finish() {
+ ///
+ /// - Parameter hasFailed: Set it to `true` if the operation has failed, otherwise `false`.
+ override public func finish(_ hasFailed: Bool) {
+ super.finish(hasFailed)
+
semaphore.continue()
}
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index 90a6a74..c60ebdb 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -40,7 +40,7 @@ internal class ConcurrentOperationTests: XCTestCase {
let testExpectation = expectation(description: "Init With Execution Block")
- let concurrentOperation = ConcurrentOperation {
+ let concurrentOperation = ConcurrentOperation { _ in
testExpectation.fulfill()
}
concurrentOperation.addToQueue(queue)
diff --git a/Tests/QueuerTests/QueuerTests.swift b/Tests/QueuerTests/QueuerTests.swift
index 16e50ec..b591e27 100644
--- a/Tests/QueuerTests/QueuerTests.swift
+++ b/Tests/QueuerTests/QueuerTests.swift
@@ -55,7 +55,7 @@ internal class QueuerTests: XCTestCase {
XCTAssertEqual(queue.operationCount, 0)
- let concurrentOperation = ConcurrentOperation {
+ let concurrentOperation = ConcurrentOperation { _ in
Thread.sleep(forTimeInterval: 2)
testExpectation.fulfill()
}
@@ -72,7 +72,7 @@ internal class QueuerTests: XCTestCase {
let queue = Queuer(name: "QueuerTestOperations")
let testExpectation = expectation(description: "Operations")
- let concurrentOperation = ConcurrentOperation {
+ let concurrentOperation = ConcurrentOperation { _ in
Thread.sleep(forTimeInterval: 2)
testExpectation.fulfill()
}
@@ -137,7 +137,7 @@ internal class QueuerTests: XCTestCase {
let queue = Queuer(name: "QueuerTestAddOperation")
let testExpectation = expectation(description: "Add Operation")
- let concurrentOperation = ConcurrentOperation {
+ let concurrentOperation = ConcurrentOperation { _ in
XCTAssertEqual(queue.operationCount, 1)
testExpectation.fulfill()
}
@@ -154,10 +154,10 @@ internal class QueuerTests: XCTestCase {
let testExpectation = expectation(description: "Add Operations")
var check = 0
- let concurrentOperation1 = ConcurrentOperation {
+ let concurrentOperation1 = ConcurrentOperation { _ in
check += 1
}
- let concurrentOperation2 = ConcurrentOperation {
+ let concurrentOperation2 = ConcurrentOperation { _ in
check += 1
}
queue.addOperation(concurrentOperation1)
@@ -180,11 +180,11 @@ internal class QueuerTests: XCTestCase {
let testExpectation = expectation(description: "Add Chained Operations")
var order: [Int] = []
- let concurrentOperation1 = ConcurrentOperation {
+ let concurrentOperation1 = ConcurrentOperation { _ in
Thread.sleep(forTimeInterval: 2)
order.append(0)
}
- let concurrentOperation2 = ConcurrentOperation {
+ let concurrentOperation2 = ConcurrentOperation { _ in
order.append(1)
}
queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
@@ -203,11 +203,11 @@ internal class QueuerTests: XCTestCase {
let testExpectation = expectation(description: "Add Chained Operations List")
var order: [Int] = []
- let concurrentOperation1 = ConcurrentOperation {
+ let concurrentOperation1 = ConcurrentOperation { _ in
Thread.sleep(forTimeInterval: 2)
order.append(0)
}
- let concurrentOperation2 = ConcurrentOperation {
+ let concurrentOperation2 = ConcurrentOperation { _ in
order.append(1)
}
queue.addChainedOperations(concurrentOperation1, concurrentOperation2) {
@@ -240,10 +240,10 @@ internal class QueuerTests: XCTestCase {
let testExpectation = expectation(description: "Add Chained Operations Without Completion")
var order: [Int] = []
- let concurrentOperation1 = ConcurrentOperation {
+ let concurrentOperation1 = ConcurrentOperation { _ in
order.append(0)
}
- let concurrentOperation2 = ConcurrentOperation {
+ let concurrentOperation2 = ConcurrentOperation { _ in
order.append(1)
testExpectation.fulfill()
}
@@ -261,11 +261,11 @@ internal class QueuerTests: XCTestCase {
let testExpectation = expectation(description: "Cancell All Operations")
var order: [Int] = []
- let concurrentOperation1 = SynchronousOperation {
+ let concurrentOperation1 = SynchronousOperation { _ in
Thread.sleep(forTimeInterval: 2)
order.append(0)
}
- let concurrentOperation2 = SynchronousOperation {
+ let concurrentOperation2 = SynchronousOperation { _ in
order.append(1)
}
queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
@@ -290,11 +290,11 @@ internal class QueuerTests: XCTestCase {
let testExpectation = expectation(description: "Pause and Resume")
var order: [Int] = []
- let concurrentOperation1 = ConcurrentOperation {
+ let concurrentOperation1 = ConcurrentOperation { _ in
Thread.sleep(forTimeInterval: 2)
order.append(0)
}
- let concurrentOperation2 = ConcurrentOperation {
+ let concurrentOperation2 = ConcurrentOperation { _ in
order.append(1)
}
queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
@@ -322,11 +322,11 @@ internal class QueuerTests: XCTestCase {
let testExpectation = expectation(description: "Wait Unitl All Operations Are Finished")
var order: [Int] = []
- let concurrentOperation1 = ConcurrentOperation {
+ let concurrentOperation1 = ConcurrentOperation { _ in
Thread.sleep(forTimeInterval: 2)
order.append(0)
}
- let concurrentOperation2 = ConcurrentOperation {
+ let concurrentOperation2 = ConcurrentOperation { _ in
order.append(1)
}
queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
diff --git a/Tests/QueuerTests/SemaphoreTests.swift b/Tests/QueuerTests/SemaphoreTests.swift
index 82f08f6..698fa34 100644
--- a/Tests/QueuerTests/SemaphoreTests.swift
+++ b/Tests/QueuerTests/SemaphoreTests.swift
@@ -39,7 +39,7 @@ internal class SemaphoreTests: XCTestCase {
let testExpectation = expectation(description: "With Semaphore")
var testString = ""
- let concurrentOperation = ConcurrentOperation {
+ let concurrentOperation = ConcurrentOperation { _ in
Thread.sleep(forTimeInterval: 2)
testString = "Tested"
semaphore.continue()
@@ -60,7 +60,7 @@ internal class SemaphoreTests: XCTestCase {
let testExpectation = expectation(description: "Without Semaphore")
var testString = ""
- let concurrentOperation = ConcurrentOperation {
+ let concurrentOperation = ConcurrentOperation { _ in
Thread.sleep(forTimeInterval: 2)
testString = "Tested"
testExpectation.fulfill()
diff --git a/Tests/QueuerTests/SynchronousOperationTests.swift b/Tests/QueuerTests/SynchronousOperationTests.swift
index b0dcffa..9b9fd8d 100644
--- a/Tests/QueuerTests/SynchronousOperationTests.swift
+++ b/Tests/QueuerTests/SynchronousOperationTests.swift
@@ -40,10 +40,10 @@ internal class SynchronousOperationTests: XCTestCase {
let testExpectation = expectation(description: "Synchronous Operation")
var testString = ""
- let synchronousOperation1 = SynchronousOperation {
+ let synchronousOperation1 = SynchronousOperation { _ in
testString = "Tested1"
}
- let synchronousOperation2 = SynchronousOperation {
+ let synchronousOperation2 = SynchronousOperation { _ in
Thread.sleep(forTimeInterval: 2)
testString = "Tested2"
@@ -65,10 +65,10 @@ internal class SynchronousOperationTests: XCTestCase {
let testExpectation = expectation(description: "Synchronous Operation")
var testString = ""
- let synchronousOperation1 = SynchronousOperation {
+ let synchronousOperation1 = SynchronousOperation { _ in
testString = "Tested1"
}
- let synchronousOperation2 = SynchronousOperation {
+ let synchronousOperation2 = SynchronousOperation { _ in
Thread.sleep(forTimeInterval: 2)
testString = "Tested2"
@@ -98,11 +98,11 @@ internal class SynchronousOperationTests: XCTestCase {
testExpectation.fulfill()
}
- let synchronousOperation1 = SynchronousOperation {
+ let synchronousOperation1 = SynchronousOperation { _ in
testString = "Tested1"
Thread.sleep(forTimeInterval: 4)
}
- let synchronousOperation2 = SynchronousOperation {
+ let synchronousOperation2 = SynchronousOperation { _ in
testString = "Tested2"
}
synchronousOperation1.addToQueue(queue)
From 2ea83764510a0f547de805a24862f6acf62e200f Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 17 Sep 2018 01:24:00 +0200
Subject: [PATCH 26/57] Updating CHANGELOG
---
CHANGELOG.md | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 20e370f..6ace826 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,8 +19,16 @@ All notable changes to this project will be documented in this file.
## Swift 4.2
### Added
- Added support to Xcode 10 and Swift 4.2
+- Added retry feature to `ConcurrentOperation` class [#32](https://github.com/FabrizioBrancati/BFKit-Swift/issues/10)
+- Added `addCompletionHandler(_:)` function to `Queuer` class
### Changed
+- Changed `executionBlock` of `ConcurrentOperation` to pass the `concurrentOperation` variable inside the closure to be able to use the retry feature. If you don't need it simply put `_ in` after the block creation
+ ```swift
+ let concurrentOperation = ConcurrentOperation { _ in
+ /// Your task here
+ }
+ ```
- Changed from Codecov to Coveralls service for code coverage
---
@@ -105,7 +113,7 @@ Thanks to [@BabyAzerty](https://github.com/BabyAzerty) for this release
- Updated SwiftLint to 0.21.0
### Fixed
-- Now `ConcurrentOperation` is subclassable with `open` instead of `public` Access Control [#2](https://github.com/FabrizioBrancati/Queuer/issue/2)
+- Now `ConcurrentOperation` is subclassable with `open` instead of `public` Access Control [#2](https://github.com/FabrizioBrancati/Queuer/issues/2)
- Fixed tests that sometimes fails
---
From 95e424f4c6343524c5194d3e50c360e93ef44bb8 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Wed, 19 Sep 2018 00:57:23 +0200
Subject: [PATCH 27/57] Auto-generating Linux tests
---
.travis.yml | 3 +-
Tests/LinuxMain.swift | 30 ++-
.../ConcurrentOperationTests+XCTest.swift | 45 ++++
.../ConcurrentOperationTests.swift | 7 -
Tests/QueuerTests/QueuerTests+XCTest.swift | 57 ++++
Tests/QueuerTests/QueuerTests.swift | 19 --
Tests/QueuerTests/SchedulerTests+XCTest.swift | 43 +++
Tests/QueuerTests/SchedulerTests.swift | 7 +-
Tests/QueuerTests/SemaphoreTests+XCTest.swift | 43 +++
Tests/QueuerTests/SemaphoreTests.swift | 5 -
.../SynchronousOperationTests+XCTest.swift | 44 ++++
.../SynchronousOperationTests.swift | 6 -
generate_linux_tests.rb | 245 ++++++++++++++++++
13 files changed, 499 insertions(+), 55 deletions(-)
create mode 100644 Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
create mode 100644 Tests/QueuerTests/QueuerTests+XCTest.swift
create mode 100644 Tests/QueuerTests/SchedulerTests+XCTest.swift
create mode 100644 Tests/QueuerTests/SemaphoreTests+XCTest.swift
create mode 100644 Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
create mode 100644 generate_linux_tests.rb
diff --git a/.travis.yml b/.travis.yml
index 689bbc2..8e411c6 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -88,7 +88,8 @@ script:
- swift -version
- if [ "$SPM" == "YES" ]; then
- swift build;
+ swift package clean;
+ ruby generate_linux_tests.rb;
swift test --parallel;
fi
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
index 3f8de96..e545a75 100644
--- a/Tests/LinuxMain.swift
+++ b/Tests/LinuxMain.swift
@@ -2,9 +2,9 @@
// LinuxMain.swift
// Queuer
//
-// MIT License
+// The MIT License (MIT)
//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati
+// Copyright (c) 2017 - 2018 Fabrizio Brancati.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -23,16 +23,24 @@
// 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.
+//
+//
+//
+// NOTE: This file was generated by generate_linux_tests.rb
+//
+// Do NOT edit this file directly as it will be regenerated automatically when needed.
+//
-#if os(Linux)
-@testable import QueuerTests
import XCTest
-XCTMain([
- testCase(ConcurrentOperationTests.allTests),
- testCase(QueuerTests.allTests),
- testCase(SchedulerTests.allTests),
- testCase(SemaphoreTests.allTests),
- testCase(SynchronousOperationTests.allTests)
-])
+#if os(Linux) || os(FreeBSD)
+ @testable import QueuerTests
+
+ XCTMain([
+ testCase(ConcurrentOperationTests.allTests),
+ testCase(QueuerTests.allTests),
+ testCase(SchedulerTests.allTests),
+ testCase(SemaphoreTests.allTests),
+ testCase(SynchronousOperationTests.allTests)
+ ])
#endif
diff --git a/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift b/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
new file mode 100644
index 0000000..8fa163b
--- /dev/null
+++ b/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
@@ -0,0 +1,45 @@
+//
+// ConcurrentOperationTests+XCTest.swift
+// Queuer
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+//
+// 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.
+//
+//
+//
+// NOTE: This file was generated by generate_linux_tests.rb
+//
+// Do NOT edit this file directly as it will be regenerated automatically when needed.
+//
+
+import XCTest
+
+internal extension ConcurrentOperationTests {
+ internal static var allTests: [(String, (ConcurrentOperationTests) -> () throws -> Void)] {
+ return [
+ ("testInitWithExecutionBlock", testInitWithExecutionBlock),
+ ("testIsAsynchronous", testIsAsynchronous),
+ ("testAddToSharedQueuer", testAddToSharedQueuer),
+ ("testAddToQueue", testAddToQueue)
+ ]
+ }
+}
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index c60ebdb..863c828 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -28,13 +28,6 @@
import XCTest
internal class ConcurrentOperationTests: XCTestCase {
- internal static let allTests = [
- ("testInitWithExecutionBlock", testInitWithExecutionBlock),
- ("testIsAsynchronous", testIsAsynchronous),
- ("testAddToSharedQueuer", testAddToSharedQueuer),
- ("testAddToQueue", testAddToQueue)
- ]
-
internal func testInitWithExecutionBlock() {
let queue = Queuer(name: "ConcurrentOperationTestInitWithExecutionBlock")
diff --git a/Tests/QueuerTests/QueuerTests+XCTest.swift b/Tests/QueuerTests/QueuerTests+XCTest.swift
new file mode 100644
index 0000000..b2fe8d1
--- /dev/null
+++ b/Tests/QueuerTests/QueuerTests+XCTest.swift
@@ -0,0 +1,57 @@
+//
+// QueuerTests+XCTest.swift
+// Queuer
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+//
+// 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.
+//
+//
+//
+// NOTE: This file was generated by generate_linux_tests.rb
+//
+// Do NOT edit this file directly as it will be regenerated automatically when needed.
+//
+
+import XCTest
+
+internal extension QueuerTests {
+ internal static var allTests: [(String, (QueuerTests) -> () throws -> Void)] {
+ return [
+ ("testOperationCount", testOperationCount),
+ ("testOperations", testOperations),
+ ("testMaxConcurrentOperationCount", testMaxConcurrentOperationCount),
+ ("testQualityOfService", testQualityOfService),
+ ("testInitWithNameMaxConcurrentOperationCount", testInitWithNameMaxConcurrentOperationCount),
+ ("testInitWithNameMaxConcurrentOperationCountQualityOfService", testInitWithNameMaxConcurrentOperationCountQualityOfService),
+ ("testAddOperationBlock", testAddOperationBlock),
+ ("testAddOperation", testAddOperation),
+ ("testAddOperations", testAddOperations),
+ ("testAddChainedOperations", testAddChainedOperations),
+ ("testAddChainedOperationsList", testAddChainedOperationsList),
+ ("testAddChainedOperationsEmpty", testAddChainedOperationsEmpty),
+ ("testAddChainedOperationsWithoutCompletion", testAddChainedOperationsWithoutCompletion),
+ ("testCancelAll", testCancelAll),
+ ("testPauseAndResume", testPauseAndResume),
+ ("testWaitUnitlAllOperationsAreFinished", testWaitUnitlAllOperationsAreFinished)
+ ]
+ }
+}
diff --git a/Tests/QueuerTests/QueuerTests.swift b/Tests/QueuerTests/QueuerTests.swift
index b591e27..f9e2342 100644
--- a/Tests/QueuerTests/QueuerTests.swift
+++ b/Tests/QueuerTests/QueuerTests.swift
@@ -30,25 +30,6 @@ import XCTest
// swiftlint:disable type_body_length
internal class QueuerTests: XCTestCase {
- internal static let allTests = [
- ("testOperationCount", testOperationCount),
- ("testOperations", testOperations),
- ("testMaxConcurrentOperationCount", testMaxConcurrentOperationCount),
- ("testQualityOfService", testQualityOfService),
- ("testInitWithNameMaxConcurrentOperationCount", testInitWithNameMaxConcurrentOperationCount),
- ("testInitWithNameMaxConcurrentOperationCountQualityOfService", testInitWithNameMaxConcurrentOperationCountQualityOfService),
- ("testAddOperationBlock", testAddOperationBlock),
- ("testAddOperation", testAddOperation),
- ("testAddOperations", testAddOperations),
- ("testAddChainedOperations", testAddChainedOperations),
- ("testAddChainedOperationsList", testAddChainedOperationsList),
- ("testAddChainedOperationsEmpty", testAddChainedOperationsEmpty),
- ("testAddChainedOperationsWithoutCompletion", testAddChainedOperationsWithoutCompletion),
- ("testCancelAll", testCancelAll),
- ("testPauseAndResume", testPauseAndResume),
- ("testWaitUnitlAllOperationsAreFinished", testWaitUnitlAllOperationsAreFinished)
- ]
-
internal func testOperationCount() {
let queue = Queuer(name: "QueuerTestOperationCount")
let testExpectation = expectation(description: "Operation Count")
diff --git a/Tests/QueuerTests/SchedulerTests+XCTest.swift b/Tests/QueuerTests/SchedulerTests+XCTest.swift
new file mode 100644
index 0000000..4523b2e
--- /dev/null
+++ b/Tests/QueuerTests/SchedulerTests+XCTest.swift
@@ -0,0 +1,43 @@
+//
+// SchedulerTests+XCTest.swift
+// Queuer
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+//
+// 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.
+//
+//
+//
+// NOTE: This file was generated by generate_linux_tests.rb
+//
+// Do NOT edit this file directly as it will be regenerated automatically when needed.
+//
+
+import XCTest
+
+internal extension SchedulerTests {
+ internal static var allTests: [(String, (SchedulerTests) -> () throws -> Void)] {
+ return [
+ ("testInitWithoutHandler", testInitWithoutHandler),
+ ("testInitWithHandler", testInitWithHandler)
+ ]
+ }
+}
diff --git a/Tests/QueuerTests/SchedulerTests.swift b/Tests/QueuerTests/SchedulerTests.swift
index c4cf963..ddbc1ce 100644
--- a/Tests/QueuerTests/SchedulerTests.swift
+++ b/Tests/QueuerTests/SchedulerTests.swift
@@ -28,12 +28,7 @@ import Dispatch
@testable import Queuer
import XCTest
-internal class SchedulerTests: XCTestCase {
- internal static let allTests = [
- ("testInitWithoutHandler", testInitWithoutHandler),
- ("testInitWithHandler", testInitWithHandler)
- ]
-
+internal class SchedulerTests: XCTestCase {
internal func testInitWithoutHandler() {
let testExpectation = expectation(description: "Init Without Handler")
diff --git a/Tests/QueuerTests/SemaphoreTests+XCTest.swift b/Tests/QueuerTests/SemaphoreTests+XCTest.swift
new file mode 100644
index 0000000..e773f9a
--- /dev/null
+++ b/Tests/QueuerTests/SemaphoreTests+XCTest.swift
@@ -0,0 +1,43 @@
+//
+// SemaphoreTests+XCTest.swift
+// Queuer
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+//
+// 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.
+//
+//
+//
+// NOTE: This file was generated by generate_linux_tests.rb
+//
+// Do NOT edit this file directly as it will be regenerated automatically when needed.
+//
+
+import XCTest
+
+internal extension SemaphoreTests {
+ internal static var allTests: [(String, (SemaphoreTests) -> () throws -> Void)] {
+ return [
+ ("testWithSemaphore", testWithSemaphore),
+ ("testWithoutSemaphore", testWithoutSemaphore)
+ ]
+ }
+}
diff --git a/Tests/QueuerTests/SemaphoreTests.swift b/Tests/QueuerTests/SemaphoreTests.swift
index 698fa34..038f186 100644
--- a/Tests/QueuerTests/SemaphoreTests.swift
+++ b/Tests/QueuerTests/SemaphoreTests.swift
@@ -28,11 +28,6 @@
import XCTest
internal class SemaphoreTests: XCTestCase {
- internal static let allTests = [
- ("testWithSemaphore", testWithSemaphore),
- ("testWithoutSemaphore", testWithoutSemaphore)
- ]
-
internal func testWithSemaphore() {
let semaphore = Semaphore()
let queue = Queuer(name: "SemaphoreTestWithSemaphore")
diff --git a/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift b/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
new file mode 100644
index 0000000..9bbdaa7
--- /dev/null
+++ b/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
@@ -0,0 +1,44 @@
+//
+// SynchronousOperationTests+XCTest.swift
+// Queuer
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+//
+// 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.
+//
+//
+//
+// NOTE: This file was generated by generate_linux_tests.rb
+//
+// Do NOT edit this file directly as it will be regenerated automatically when needed.
+//
+
+import XCTest
+
+internal extension SynchronousOperationTests {
+ internal static var allTests: [(String, (SynchronousOperationTests) -> () throws -> Void)] {
+ return [
+ ("testSynchronousOperation", testSynchronousOperation),
+ ("testSynchronousOperationOnSharedQueuer", testSynchronousOperationOnSharedQueuer),
+ ("testCancel", testCancel)
+ ]
+ }
+}
diff --git a/Tests/QueuerTests/SynchronousOperationTests.swift b/Tests/QueuerTests/SynchronousOperationTests.swift
index 9b9fd8d..b542a31 100644
--- a/Tests/QueuerTests/SynchronousOperationTests.swift
+++ b/Tests/QueuerTests/SynchronousOperationTests.swift
@@ -29,12 +29,6 @@ import Dispatch
import XCTest
internal class SynchronousOperationTests: XCTestCase {
- internal static let allTests = [
- ("testSynchronousOperation", testSynchronousOperation),
- ("testSynchronousOperationOnSharedQueuer", testSynchronousOperationOnSharedQueuer),
- ("testCancel", testCancel)
- ]
-
internal func testSynchronousOperation() {
let queue = Queuer(name: "SynchronousOperationTestSynchronousOperation")
let testExpectation = expectation(description: "Synchronous Operation")
diff --git a/generate_linux_tests.rb b/generate_linux_tests.rb
new file mode 100644
index 0000000..4e732e8
--- /dev/null
+++ b/generate_linux_tests.rb
@@ -0,0 +1,245 @@
+#!/usr/bin/env ruby
+
+#
+# process_test_files.rb
+#
+# Copyright 2016 Tony Stone
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# Created by Tony Stone on 5/4/16.
+#
+require 'getoptlong'
+require 'fileutils'
+require 'pathname'
+
+include FileUtils
+
+#
+# This ruby script will auto generate LinuxMain.swift and the +XCTest.swift extension files for Swift Package Manager on Linux platforms.
+#
+# See https://github.com/apple/swift-corelibs-xctest/blob/master/Documentation/Linux.md
+#
+def header(file_name)
+ string = <<-eos
+//
+//
+// Queuer
+//
+// The MIT License (MIT)
+//
+// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+//
+// 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.
+//
+//
+//
+// NOTE: This file was generated by generate_linux_tests.rb
+//
+// Do NOT edit this file directly as it will be regenerated automatically when needed.
+//
+
+import XCTest
+ eos
+
+ string
+ .sub('', File.basename(file_name))
+ .sub('', Time.now.to_s)
+end
+
+def create_extension_file(file_name, classes)
+ extension_file = file_name.sub! '.swift', '+XCTest.swift'
+ print 'Creating file: ' + extension_file + "\n"
+
+ File.open(extension_file, 'w') do |file|
+ file.write header(extension_file)
+ file.write "\n"
+
+ for class_array in classes
+ file.write 'internal extension ' + class_array[0] + " {\n"
+ file.write ' internal static var allTests: [(String, (' + class_array[0] + ") -> () throws -> Void)] {\n"
+ file.write " return [\n"
+
+ class_count = class_array[1].size
+ count = 0
+ for func_name in class_array[1]
+ count += 1
+
+ file.write ' ("' + func_name + '", ' + func_name + (count == class_count ? ")\n" : "),\n")
+ end
+
+ file.write " ]\n"
+ file.write " }\n"
+ file.write "}\n"
+ end
+ end
+end
+
+def create_linux_main(tests_directory, all_test_sub_directories, files)
+ file_name = tests_directory + '/LinuxMain.swift'
+ print 'Creating file: ' + file_name + "\n"
+
+ File.open(file_name, 'w') do |file|
+ file.write header(file_name)
+ file.write "\n"
+
+ file.write "#if os(Linux) || os(FreeBSD)\n"
+ for test_sub_directory in all_test_sub_directories.sort { |x, y| x <=> y }
+ file.write ' @testable import ' + test_sub_directory + "\n"
+ end
+ file.write "\n"
+ file.write " XCTMain([\n"
+
+ test_cases = []
+ for classes in files
+ for class_array in classes
+ test_cases << class_array[0]
+ end
+ end
+
+ cases_count = test_cases.size
+ count = 0
+ for test_case in test_cases.sort { |x, y| x <=> y }
+ count += 1
+
+ file.write ' testCase(' + test_case + (count == cases_count ? ".allTests)\n" : ".allTests),\n")
+ end
+ file.write " ])\n"
+ file.write "#endif\n"
+ end
+end
+
+def parse_source_file(file_name)
+ puts 'Parsing file: ' + file_name + "\n"
+
+ classes = []
+ current_class = nil
+ in_if_linux = false
+ in_else = false
+ ignore = false
+
+ #
+ # Read the file line by line
+ # and parse to find the class
+ # names and func names
+ #
+ File.readlines(file_name).each do |line|
+ if in_if_linux
+ if /\#else/ =~ line
+ in_else = true
+ ignore = true
+ elsif /\#end/ =~ line
+ in_else = false
+ in_if_linux = false
+ ignore = false
+ end
+ elsif /\#if[ \t]+os\(Linux\)/ =~ line
+ in_if_linux = true
+ ignore = false
+ end
+
+ next if ignore
+ # Match class or func
+ match = line[/class[ \t]+[a-zA-Z0-9_]*(?=[ \t]*:[ \t]*XCTestCase)|func[ \t]+test[a-zA-Z0-9_]*(?=[ \t]*\(\))/, 0]
+ if match
+ if match[/class/, 0] == 'class'
+ class_name = match.sub(/^class[ \t]+/, '')
+ #
+ # Create a new class / func structure
+ # and add it to the classes array.
+ #
+ current_class = [class_name, []]
+ classes << current_class
+ else # Must be a func
+ func_name = match.sub(/^func[ \t]+/, '')
+ #
+ # Add each func name the the class / func
+ # structure created above.
+ #
+ current_class[1] << func_name
+ end
+ end
+ end
+ classes
+end
+
+#
+# Main routine
+#
+#
+
+tests_directory = 'Tests'
+
+options = GetoptLong.new(['--tests-dir', GetoptLong::OPTIONAL_ARGUMENT])
+options.quiet = true
+
+begin
+ options.each do |option, value|
+ case option
+ when '--tests-dir'
+ tests_directory = value
+ end
+ end
+ rescue GetoptLong::InvalidOption
+end
+
+all_test_sub_directories = []
+all_files = []
+
+Dir[tests_directory + '/*'].each do |sub_directory|
+ next unless File.directory?(sub_directory)
+ directory_has_classes = false
+ Dir[sub_directory + '/*Test{s,}.swift'].each do |file_name|
+ next unless File.file? file_name
+ file_classes = parse_source_file(file_name)
+
+ #
+ # If there are classes in the
+ # test source file, create an extension
+ # file for it.
+ #
+ next unless file_classes.count.positive?
+ create_extension_file(file_name, file_classes)
+ directory_has_classes = true
+ all_files << file_classes
+ end
+
+ if directory_has_classes
+ all_test_sub_directories << Pathname.new(sub_directory).split.last.to_s
+ end
+end
+
+#
+# Last step is the create a LinuxMain.swift file that
+# references all the classes and funcs in the source files.
+#
+if all_files.count.positive?
+ create_linux_main(tests_directory, all_test_sub_directories, all_files)
+end
+# eof
From dbcc3405d292fb4fe5d1101f7593c0649be5a438 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Wed, 19 Sep 2018 23:50:22 +0200
Subject: [PATCH 28/57] Adding new tests
---
Sources/Queuer/ConcurrentOperation.swift | 6 +--
.../ConcurrentOperationTests.swift | 45 +++++++++++++++++++
2 files changed, 48 insertions(+), 3 deletions(-)
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index e1132ea..513ba66 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -84,7 +84,7 @@ open class ConcurrentOperation: Operation {
open var maximumRetries = 3
/// Current retry tentative.
- open var currentRetry = 0
+ open var currentAttempt = 1
/// Specify if the operation should retry another time.
private var shouldRetry = true
@@ -111,12 +111,12 @@ open class ConcurrentOperation: Operation {
///
/// - Parameter hasFailed: Set it to `true` if the operation has failed, otherwise `false`.
open func finish(_ hasFailed: Bool) {
- if !hasFailed || currentRetry >= maximumRetries {
+ if !hasFailed || currentAttempt >= maximumRetries {
_executing = false
_finished = true
shouldRetry = false
} else {
- currentRetry += 1
+ currentAttempt += 1
shouldRetry = true
}
}
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index 863c828..0c8bcfc 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -66,4 +66,49 @@ internal class ConcurrentOperationTests: XCTestCase {
XCTAssertEqual(queue.operationCount, 1)
XCTAssertEqual(queue.operations, [concurrentOperation])
}
+
+ internal func testSimpleRetry() {
+ let queue = Queuer(name: "ConcurrentOperationTestSimpleRetry")
+
+ let testExpectation = expectation(description: "Simple Retry")
+
+ let concurrentOperation = ConcurrentOperation { operation in
+ operation.hasFailed = true
+ }
+ concurrentOperation.addToQueue(queue)
+ queue.addCompletionHandler {
+ testExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 5) { error in
+ XCTAssertNil(error)
+ XCTAssertTrue(concurrentOperation.hasFailed)
+ XCTAssertEqual(concurrentOperation.currentAttempt, 3)
+ }
+ }
+
+ internal func testChainedRetry() {
+ let queue = Queuer(name: "ConcurrentOperationTestChainedRetry")
+ let testExpectation = expectation(description: "Chained Retry")
+ var order: [Int] = []
+
+ let concurrentOperation1 = ConcurrentOperation { operation in
+ Thread.sleep(forTimeInterval: 1)
+ order.append(0)
+ operation.hasFailed = true
+ }
+ let concurrentOperation2 = ConcurrentOperation { operation in
+ order.append(1)
+ operation.hasFailed = true
+ }
+ queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
+ order.append(2)
+ testExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 5) { error in
+ XCTAssertNil(error)
+ XCTAssertEqual(order, [0, 0, 0, 1, 1, 1, 2])
+ }
+ }
}
From 793257ab7beaa50e9c02979e528c73940c4a61d8 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Thu, 20 Sep 2018 00:05:39 +0200
Subject: [PATCH 29/57] Resolving SwiftLint issues
---
Sources/Queuer/ConcurrentOperation.swift | 18 +++++++++---------
Tests/LinuxMain.swift | 4 ++--
.../ConcurrentOperationTests+XCTest.swift | 8 +++++---
Tests/QueuerTests/QueuerTests+XCTest.swift | 4 ++--
Tests/QueuerTests/QueuerTests.swift | 1 -
Tests/QueuerTests/SchedulerTests+XCTest.swift | 4 ++--
Tests/QueuerTests/SemaphoreTests+XCTest.swift | 4 ++--
.../SynchronousOperationTests+XCTest.swift | 4 ++--
generate_linux_tests.rb | 4 ++--
9 files changed, 26 insertions(+), 25 deletions(-)
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index 513ba66..139f74c 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -31,15 +31,6 @@ open class ConcurrentOperation: Operation {
/// Operation's execution block.
public var executionBlock: ((_ operation: ConcurrentOperation) -> Void)?
- /// Creates the Operation with an execution block.
- ///
- /// - Parameter executionBlock: Execution block.
- public init(executionBlock: ((_ operation: ConcurrentOperation) -> Void)? = nil) {
- super.init()
-
- self.executionBlock = executionBlock
- }
-
/// Set the Operation as asynchronous.
override open var isAsynchronous: Bool {
return true
@@ -89,6 +80,15 @@ open class ConcurrentOperation: Operation {
/// Specify if the operation should retry another time.
private var shouldRetry = true
+ /// Creates the Operation with an execution block.
+ ///
+ /// - Parameter executionBlock: Execution block.
+ public init(executionBlock: ((_ operation: ConcurrentOperation) -> Void)? = nil) {
+ super.init()
+
+ self.executionBlock = executionBlock
+ }
+
/// Start the Operation.
override open func start() {
_executing = true
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
index e545a75..23b901b 100644
--- a/Tests/LinuxMain.swift
+++ b/Tests/LinuxMain.swift
@@ -2,9 +2,9 @@
// LinuxMain.swift
// Queuer
//
-// The MIT License (MIT)
+// MIT License
//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift b/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
index 8fa163b..d6f4540 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
@@ -2,9 +2,9 @@
// ConcurrentOperationTests+XCTest.swift
// Queuer
//
-// The MIT License (MIT)
+// MIT License
//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
@@ -39,7 +39,9 @@ internal extension ConcurrentOperationTests {
("testInitWithExecutionBlock", testInitWithExecutionBlock),
("testIsAsynchronous", testIsAsynchronous),
("testAddToSharedQueuer", testAddToSharedQueuer),
- ("testAddToQueue", testAddToQueue)
+ ("testAddToQueue", testAddToQueue),
+ ("testSimpleRetry", testSimpleRetry),
+ ("testChainedRetry", testChainedRetry)
]
}
}
diff --git a/Tests/QueuerTests/QueuerTests+XCTest.swift b/Tests/QueuerTests/QueuerTests+XCTest.swift
index b2fe8d1..bfe5de0 100644
--- a/Tests/QueuerTests/QueuerTests+XCTest.swift
+++ b/Tests/QueuerTests/QueuerTests+XCTest.swift
@@ -2,9 +2,9 @@
// QueuerTests+XCTest.swift
// Queuer
//
-// The MIT License (MIT)
+// MIT License
//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/Tests/QueuerTests/QueuerTests.swift b/Tests/QueuerTests/QueuerTests.swift
index f9e2342..93a8be1 100644
--- a/Tests/QueuerTests/QueuerTests.swift
+++ b/Tests/QueuerTests/QueuerTests.swift
@@ -28,7 +28,6 @@ import Dispatch
@testable import Queuer
import XCTest
-// swiftlint:disable type_body_length
internal class QueuerTests: XCTestCase {
internal func testOperationCount() {
let queue = Queuer(name: "QueuerTestOperationCount")
diff --git a/Tests/QueuerTests/SchedulerTests+XCTest.swift b/Tests/QueuerTests/SchedulerTests+XCTest.swift
index 4523b2e..5842cdf 100644
--- a/Tests/QueuerTests/SchedulerTests+XCTest.swift
+++ b/Tests/QueuerTests/SchedulerTests+XCTest.swift
@@ -2,9 +2,9 @@
// SchedulerTests+XCTest.swift
// Queuer
//
-// The MIT License (MIT)
+// MIT License
//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/Tests/QueuerTests/SemaphoreTests+XCTest.swift b/Tests/QueuerTests/SemaphoreTests+XCTest.swift
index e773f9a..9e795ba 100644
--- a/Tests/QueuerTests/SemaphoreTests+XCTest.swift
+++ b/Tests/QueuerTests/SemaphoreTests+XCTest.swift
@@ -2,9 +2,9 @@
// SemaphoreTests+XCTest.swift
// Queuer
//
-// The MIT License (MIT)
+// MIT License
//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift b/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
index 9bbdaa7..8aa49d0 100644
--- a/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
+++ b/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
@@ -2,9 +2,9 @@
// SynchronousOperationTests+XCTest.swift
// Queuer
//
-// The MIT License (MIT)
+// MIT License
//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
diff --git a/generate_linux_tests.rb b/generate_linux_tests.rb
index 4e732e8..8727017 100644
--- a/generate_linux_tests.rb
+++ b/generate_linux_tests.rb
@@ -36,9 +36,9 @@ def header(file_name)
//
// Queuer
//
-// The MIT License (MIT)
+// MIT License
//
-// Copyright (c) 2017 - 2018 Fabrizio Brancati.
+// Copyright (c) 2017 - 2018 Fabrizio Brancati
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
From 860d7a888202e1254408eebccfbe342bd387f749 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Thu, 20 Sep 2018 00:16:42 +0200
Subject: [PATCH 30/57] Improving documentation
---
Sources/Queuer/ConcurrentOperation.swift | 40 +++++++++++------------
Sources/Queuer/Queuer.swift | 38 ++++++++++-----------
Sources/Queuer/Semaphore.swift | 6 ++--
Sources/Queuer/SynchronousOperation.swift | 14 ++++----
4 files changed, 49 insertions(+), 49 deletions(-)
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index 139f74c..5774695 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -28,15 +28,15 @@ import Foundation
/// It allows asynchronous tasks, has a pause and resume states, can be easily added to a queue and can be created with a block.
open class ConcurrentOperation: Operation {
- /// Operation's execution block.
+ /// `Operation`'s execution block.
public var executionBlock: ((_ operation: ConcurrentOperation) -> Void)?
- /// Set the Operation as asynchronous.
+ /// Set the `Operation` as asynchronous.
override open var isAsynchronous: Bool {
return true
}
- /// Set if the Operation is executing.
+ /// Set if the `Operation` is executing.
private var _executing = false {
willSet {
willChangeValue(forKey: "isExecuting")
@@ -46,12 +46,12 @@ open class ConcurrentOperation: Operation {
}
}
- /// Set if the Operation is executing.
+ /// Set if the `Operation` is executing.
override open var isExecuting: Bool {
return _executing
}
- /// Set if the Operation is finished.
+ /// Set if the `Operation` is finished.
private var _finished = false {
willSet {
willChangeValue(forKey: "isFinished")
@@ -61,13 +61,13 @@ open class ConcurrentOperation: Operation {
}
}
- /// Set if the Operation is finished.
+ /// Set if the `Operation` is finished.
override open var isFinished: Bool {
return _finished
}
- /// You should use `hasFailed` if retry is enabled.
- /// Set it to `true` if the operation has failed, otherwise `false`.
+ /// You should use `hasFailed` if you want the retry feature.
+ /// Set it to `true` if the `Operation` has failed, otherwise `false`.
/// Default is `false` to avoid retries.
open var hasFailed = false
@@ -77,10 +77,10 @@ open class ConcurrentOperation: Operation {
/// Current retry tentative.
open var currentAttempt = 1
- /// Specify if the operation should retry another time.
+ /// Specify if the `Operation` should retry another time.
private var shouldRetry = true
- /// Creates the Operation with an execution block.
+ /// Creates the `Operation` with an execution block.
///
/// - Parameter executionBlock: Execution block.
public init(executionBlock: ((_ operation: ConcurrentOperation) -> Void)? = nil) {
@@ -89,13 +89,13 @@ open class ConcurrentOperation: Operation {
self.executionBlock = executionBlock
}
- /// Start the Operation.
+ /// Start the `Operation`.
override open func start() {
_executing = true
execute()
}
- /// Execute the Operation.
+ /// Execute the `Operation`.
/// If `executionBlock` is set, it will be executed and also `finish()` will be called.
open func execute() {
if let executionBlock = executionBlock {
@@ -106,10 +106,10 @@ open class ConcurrentOperation: Operation {
}
}
- /// Notify the completion of async task and hence the completion of the operation.
- /// Must be called when the Operation is finished.
+ /// Notify the completion of async task and hence the completion of the `Operation`.
+ /// Must be called when the `Operation` is finished.
///
- /// - Parameter hasFailed: Set it to `true` if the operation has failed, otherwise `false`.
+ /// - Parameter hasFailed: Set it to `true` if the `Operation` has failed, otherwise `false`.
open func finish(_ hasFailed: Bool) {
if !hasFailed || currentAttempt >= maximumRetries {
_executing = false
@@ -121,22 +121,22 @@ open class ConcurrentOperation: Operation {
}
}
- /// Pause the current Operation, if it's supported.
+ /// Pause the current `Operation`, if it's supported.
/// Must be overridend by subclass to get a custom pause action.
open func pause() {}
- /// Resume the current Operation, if it's supported.
+ /// Resume the current `Operation`, if it's supported.
/// Must be overridend by subclass to get a custom resume action.
open func resume() {}
- /// Adds the Operation to `shared` Queuer.
+ /// Adds the `Operation` to `shared` Queuer.
public func addToSharedQueuer() {
Queuer.shared.addOperation(self)
}
- /// Adds the Operation to the custom queue.
+ /// Adds the `Operation` to the custom queue.
///
- /// - Parameter queue: Custom queue where the Operation will be added.
+ /// - Parameter queue: Custom queue where the `Operation` will be added.
public func addToQueue(_ queue: Queuer) {
queue.addOperation(self)
}
diff --git a/Sources/Queuer/Queuer.swift b/Sources/Queuer/Queuer.swift
index 8a7a3df..60aec42 100644
--- a/Sources/Queuer/Queuer.swift
+++ b/Sources/Queuer/Queuer.swift
@@ -31,20 +31,20 @@ public class Queuer {
/// Shared Queuer.
public static let shared = Queuer(name: "Queuer")
- /// Queuer OperationQueue.
+ /// Queuer `OperationQueue`.
public let queue = OperationQueue()
- /// Total Operation count in queue.
+ /// Total `Operation` count in queue.
public var operationCount: Int {
return queue.operationCount
}
- /// Operations currently in queue.
+ /// `Operation`s currently in queue.
public var operations: [Operation] {
return queue.operations
}
- /// The default service level to apply to operations executed using the queue.
+ /// The default service level to apply to `Operation`s executed using the queue.
public var qualityOfService: QualityOfService {
get {
return queue.qualityOfService
@@ -61,7 +61,7 @@ public class Queuer {
return !queue.isSuspended
}
- /// Define the max concurrent operation count.
+ /// Define the max concurrent `Operation`s count.
public var maxConcurrentOperationCount: Int {
get {
return queue.maxConcurrentOperationCount
@@ -75,37 +75,37 @@ public class Queuer {
///
/// - Parameters:
/// - name: Custom queue name.
- /// - maxConcurrentOperationCount: The max concurrent operation count.
- /// - qualityOfService: The default service level to apply to operations executed using the queue.
+ /// - maxConcurrentOperationCount: The max concurrent `Operation`s count.
+ /// - qualityOfService: The default service level to apply to `Operation`s executed using the queue.
public init(name: String, maxConcurrentOperationCount: Int = Int.max, qualityOfService: QualityOfService = .default) {
queue.name = name
self.maxConcurrentOperationCount = maxConcurrentOperationCount
self.qualityOfService = qualityOfService
}
- /// Add an Operation to be executed asynchronously.
+ /// Add an `Operation` to be executed asynchronously.
///
/// - Parameter block: Block to be executed.
public func addOperation(_ operation: @escaping () -> Void) {
queue.addOperation(operation)
}
- /// Add an Operation to be executed asynchronously.
+ /// Add an `Operation` to be executed asynchronously.
///
- /// - Parameter operation: Operation to be executed.
+ /// - Parameter operation: `Operation` to be executed.
public func addOperation(_ operation: Operation) {
queue.addOperation(operation)
}
- /// Add an Array of chained Operations.
+ /// Add an Array of chained `Operation`s.
///
/// Example:
///
/// [A, B, C] = A -> B -> C -> completionHandler.
///
/// - Parameters:
- /// - operations: Operations Array.
- /// - completionHandler: Completion block to be exectuted when all Operations
+ /// - operations: `Operation`s Array.
+ /// - completionHandler: Completion block to be exectuted when all `Operation`s
/// are finished.
public func addChainedOperations(_ operations: [Operation], completionHandler: (() -> Void)? = nil) {
for (index, operation) in operations.enumerated() {
@@ -123,15 +123,15 @@ public class Queuer {
addCompletionHandler(completionHandler)
}
- /// Add an Array of chained Operations.
+ /// Add an Array of chained `Operation`s.
///
/// Example:
///
/// [A, B, C] = A -> B -> C -> completionHandler.
///
/// - Parameters:
- /// - operations: Operations list.
- /// - completionHandler: Completion block to be exectuted when all Operations
+ /// - operations: `Operation`s list.
+ /// - completionHandler: Completion block to be exectuted when all `Operation`s
/// are finished.
public func addChainedOperations(_ operations: Operation..., completionHandler: (() -> Void)? = nil) {
addChainedOperations(operations, completionHandler: completionHandler)
@@ -139,7 +139,7 @@ public class Queuer {
/// Add a completion block to the queue.
///
- /// - Parameter completionHandler: Completion handler to be executed as last operation.
+ /// - Parameter completionHandler: Completion handler to be executed as last `Operation`.
public func addCompletionHandler(_ completionHandler: @escaping () -> Void) {
let completionOperation = BlockOperation(block: completionHandler)
if let lastOperation = operations.last {
@@ -148,7 +148,7 @@ public class Queuer {
addOperation(completionOperation)
}
- /// Cancel all Operations in queue.
+ /// Cancel all `Operation`s in queue.
public func cancelAll() {
queue.cancelAllOperations()
}
@@ -172,7 +172,7 @@ public class Queuer {
}
/// Blocks the current thread until all of the receiver’s queued and executing
- /// operations finish executing.
+ /// `Operation`s finish executing.
public func waitUntilAllOperationsAreFinished() {
queue.waitUntilAllOperationsAreFinished()
}
diff --git a/Sources/Queuer/Semaphore.swift b/Sources/Queuer/Semaphore.swift
index 17722f5..e2e1645 100644
--- a/Sources/Queuer/Semaphore.swift
+++ b/Sources/Queuer/Semaphore.swift
@@ -27,9 +27,9 @@
import Dispatch
import Foundation
-/// DispatchSemaphore struct wrapper.
+/// `DispatchSemaphore` struct wrapper.
public struct Semaphore {
- /// Private DispatchSemaphore.
+ /// Private `DispatchSemaphore`.
private let semaphore: DispatchSemaphore
/// Creates new counting semaphore with an initial value.
@@ -39,7 +39,7 @@ public struct Semaphore {
/// to the value.
///
/// - Parameter poolSize: The starting value for the semaphore.
- /// Passing a value less than zero will cause NULL to be returned.
+ /// Passing a value less than zero will cause `NULL` to be returned.
public init(poolSize: Int = 0) {
semaphore = DispatchSemaphore(value: poolSize)
}
diff --git a/Sources/Queuer/SynchronousOperation.swift b/Sources/Queuer/SynchronousOperation.swift
index c9a5b02..6f51c82 100644
--- a/Sources/Queuer/SynchronousOperation.swift
+++ b/Sources/Queuer/SynchronousOperation.swift
@@ -28,32 +28,32 @@ import Foundation
/// It allows synchronous tasks, has a pause and resume states, can be easily added to a queue and can be created with a block.
public class SynchronousOperation: ConcurrentOperation {
- /// Private semaphore instance.
+ /// Private `Semaphore` instance.
private let semaphore = Semaphore()
- /// Set the Operation as synchronous.
+ /// Set the `Operation` as synchronous.
override public var isAsynchronous: Bool {
return false
}
- /// Notify the completion of async task and hence the completion of the operation.
- /// Must be called when the Operation is finished.
+ /// Notify the completion of async task and hence the completion of the `Operation`.
+ /// Must be called when the `Operation` is finished.
///
- /// - Parameter hasFailed: Set it to `true` if the operation has failed, otherwise `false`.
+ /// - Parameter hasFailed: Set it to `true` if the `Operation` has failed, otherwise `false`.
override public func finish(_ hasFailed: Bool) {
super.finish(hasFailed)
semaphore.continue()
}
- /// Advises the operation object that it should stop executing its task.
+ /// Advises the `Operation` object that it should stop executing its task.
override public func cancel() {
super.cancel()
semaphore.continue()
}
- /// Execute the Operation.
+ /// Execute the `Operation`.
/// If `executionBlock` is set, it will be executed and also `finish()` will be called.
override public func execute() {
super.execute()
From ecb2f9974a1276fdc04cb8df20780b77e60fd7aa Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Thu, 20 Sep 2018 00:41:25 +0200
Subject: [PATCH 31/57] Improving tests
---
.../ConcurrentOperationTests.swift | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index 0c8bcfc..8aceb39 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -111,4 +111,33 @@ internal class ConcurrentOperationTests: XCTestCase {
XCTAssertEqual(order, [0, 0, 0, 1, 1, 1, 2])
}
}
+
+ internal func testCanceledChainedRetry() {
+ let queue = Queuer(name: "ConcurrentOperationTestCanceledChainedRetry")
+ let testExpectation = expectation(description: "Canceled Chained Retry")
+ var order: [Int] = []
+
+ let concurrentOperation1 = ConcurrentOperation { operation in
+ Thread.sleep(forTimeInterval: 1)
+ order.append(0)
+ operation.hasFailed = true
+ }
+ let concurrentOperation2 = ConcurrentOperation { operation in
+ operation.cancel()
+ if operation.isCancelled {
+ return
+ }
+ order.append(1)
+ operation.hasFailed = true
+ }
+ queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
+ order.append(2)
+ testExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 5) { error in
+ XCTAssertNil(error)
+ XCTAssertEqual(order, [0, 0, 0, 2])
+ }
+ }
}
From 43b39ac9f38f68a87ddac4e87a34255afe206d37 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Thu, 20 Sep 2018 00:47:09 +0200
Subject: [PATCH 32/57] Improving code
---
Sources/Queuer/ConcurrentOperation.swift | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index 5774695..a184005 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -128,7 +128,10 @@ open class ConcurrentOperation: Operation {
/// Resume the current `Operation`, if it's supported.
/// Must be overridend by subclass to get a custom resume action.
open func resume() {}
-
+}
+
+/// `ConcurrentOperation` extension with queue handling.
+public extension ConcurrentOperation {
/// Adds the `Operation` to `shared` Queuer.
public func addToSharedQueuer() {
Queuer.shared.addOperation(self)
From 60ec73cc9850e80f2e8ec444484bef890c1f3709 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Thu, 20 Sep 2018 00:49:26 +0200
Subject: [PATCH 33/57] Improving code
---
Sources/Queuer/Queuer.swift | 61 +++++++++++++++++++------------------
1 file changed, 32 insertions(+), 29 deletions(-)
diff --git a/Sources/Queuer/Queuer.swift b/Sources/Queuer/Queuer.swift
index 60aec42..0f4d151 100644
--- a/Sources/Queuer/Queuer.swift
+++ b/Sources/Queuer/Queuer.swift
@@ -83,6 +83,38 @@ public class Queuer {
self.qualityOfService = qualityOfService
}
+ /// Cancel all `Operation`s in queue.
+ public func cancelAll() {
+ queue.cancelAllOperations()
+ }
+
+ /// Pause the queue.
+ public func pause() {
+ queue.isSuspended = true
+
+ for operation in queue.operations where operation is ConcurrentOperation {
+ (operation as? ConcurrentOperation)?.pause()
+ }
+ }
+
+ /// Resume the queue.
+ public func resume() {
+ queue.isSuspended = false
+
+ for operation in queue.operations where operation is ConcurrentOperation {
+ (operation as? ConcurrentOperation)?.resume()
+ }
+ }
+
+ /// Blocks the current thread until all of the receiver’s queued and executing
+ /// `Operation`s finish executing.
+ public func waitUntilAllOperationsAreFinished() {
+ queue.waitUntilAllOperationsAreFinished()
+ }
+}
+
+/// `Queuer` extension with `Operation`s handling.
+public extension Queuer {
/// Add an `Operation` to be executed asynchronously.
///
/// - Parameter block: Block to be executed.
@@ -147,33 +179,4 @@ public class Queuer {
}
addOperation(completionOperation)
}
-
- /// Cancel all `Operation`s in queue.
- public func cancelAll() {
- queue.cancelAllOperations()
- }
-
- /// Pause the queue.
- public func pause() {
- queue.isSuspended = true
-
- for operation in queue.operations where operation is ConcurrentOperation {
- (operation as? ConcurrentOperation)?.pause()
- }
- }
-
- /// Resume the queue.
- public func resume() {
- queue.isSuspended = false
-
- for operation in queue.operations where operation is ConcurrentOperation {
- (operation as? ConcurrentOperation)?.resume()
- }
- }
-
- /// Blocks the current thread until all of the receiver’s queued and executing
- /// `Operation`s finish executing.
- public func waitUntilAllOperationsAreFinished() {
- queue.waitUntilAllOperationsAreFinished()
- }
}
From 57a68b5c3364ac11b07f6273fc5acce169f3e17a Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 22 Sep 2018 18:34:26 +0200
Subject: [PATCH 34/57] Improving tests
---
.../SynchronousOperationTests.swift | 29 +++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/Tests/QueuerTests/SynchronousOperationTests.swift b/Tests/QueuerTests/SynchronousOperationTests.swift
index b542a31..6f5d688 100644
--- a/Tests/QueuerTests/SynchronousOperationTests.swift
+++ b/Tests/QueuerTests/SynchronousOperationTests.swift
@@ -80,6 +80,35 @@ internal class SynchronousOperationTests: XCTestCase {
}
}
+ internal func testSynchronousOperationRetry() {
+ let queue = Queuer(name: "SynchronousOperationTestRetry")
+ let testExpectation = expectation(description: "Synchronous Operation Retry")
+ var order: [Int] = []
+
+ let synchronousOperation1 = SynchronousOperation { operation in
+ Thread.sleep(forTimeInterval: 1)
+ order.append(0)
+ operation.hasFailed = true
+
+ if operation.currentAttempt == 3 {
+ testExpectation.fulfill()
+ }
+ }
+ let synchronousOperation2 = SynchronousOperation { _ in
+ order.append(1)
+ }
+ synchronousOperation1.addToQueue(queue)
+ synchronousOperation2.addToQueue(queue)
+
+ XCTAssertFalse(synchronousOperation1.isAsynchronous)
+ XCTAssertFalse(synchronousOperation2.isAsynchronous)
+
+ waitForExpectations(timeout: 5) { error in
+ XCTAssertNil(error)
+ XCTAssertEqual(order, [1, 0, 0, 0])
+ }
+ }
+
internal func testCancel() {
let queue = Queuer(name: "SynchronousOperationTestCancel")
queue.maxConcurrentOperationCount = 1
From 3ffb15b0d4e6cecb58479a09ba8b55c9122f352e Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sat, 22 Sep 2018 19:27:49 +0200
Subject: [PATCH 35/57] Adding manual retry feature
---
Sources/Queuer/ConcurrentOperation.swift | 23 ++++++-
.../ConcurrentOperationTests.swift | 60 +++++++++++++++++++
2 files changed, 80 insertions(+), 3 deletions(-)
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index a184005..242fb32 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -72,10 +72,16 @@ open class ConcurrentOperation: Operation {
open var hasFailed = false
/// Maximum allowed retries.
+ /// Default are 3 retries.
open var maximumRetries = 3
- /// Current retry tentative.
- open var currentAttempt = 1
+ /// Current retry attempt.
+ private(set) open var currentAttempt = 1
+
+ /// Allows for manual retries.
+ /// If set to `true`, `retry()` function must be manually called.
+ /// Default is `false` to automatically retry.
+ open var manualRetry = false
/// Specify if the `Operation` should retry another time.
private var shouldRetry = true
@@ -95,14 +101,25 @@ open class ConcurrentOperation: Operation {
execute()
}
+ /// Retry function.
+ /// It only works if `manualRetry` property has been set to `true`.
+ open func retry() {
+ if manualRetry, shouldRetry, let executionBlock = executionBlock {
+ executionBlock(self)
+ self.finish(hasFailed)
+ }
+ }
+
/// Execute the `Operation`.
/// If `executionBlock` is set, it will be executed and also `finish()` will be called.
open func execute() {
if let executionBlock = executionBlock {
- while shouldRetry {
+ while shouldRetry, !manualRetry {
executionBlock(self)
self.finish(hasFailed)
}
+
+ retry()
}
}
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index 8aceb39..8b63bcb 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -140,4 +140,64 @@ internal class ConcurrentOperationTests: XCTestCase {
XCTAssertEqual(order, [0, 0, 0, 2])
}
}
+
+ internal func testChainedManualRetry() {
+ let queue = Queuer(name: "ConcurrentOperationTestChainedManualRetry")
+ let testExpectation = expectation(description: "Chained Manual Retry")
+ var order: [Int] = []
+
+ let concurrentOperation1 = ConcurrentOperation { operation in
+ order.append(0)
+ operation.hasFailed = true
+ }
+ concurrentOperation1.manualRetry = true
+ let _ = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
+ concurrentOperation1.retry()
+ if concurrentOperation1.currentAttempt > concurrentOperation1.maximumRetries {
+ timer.invalidate()
+ }
+ }
+
+ let concurrentOperation2 = ConcurrentOperation { operation in
+ order.append(1)
+ operation.hasFailed = true
+ }
+ queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
+ order.append(2)
+ testExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 5) { error in
+ XCTAssertNil(error)
+ XCTAssertEqual(order, [0, 0, 0, 1, 1, 1, 2])
+ }
+ }
+
+ internal func testChainedWrongManualRetry() {
+ let queue = Queuer(name: "ConcurrentOperationTestChainedWrongManualRetry")
+ let testExpectation = expectation(description: "Chained Wrong Manual Retry")
+ var order: [Int] = []
+
+ let concurrentOperation1 = ConcurrentOperation { operation in
+ order.append(0)
+ operation.hasFailed = true
+ }
+ concurrentOperation1.manualRetry = true
+
+ let concurrentOperation2 = ConcurrentOperation { operation in
+ order.append(1)
+ }
+ queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
+ order.append(2)
+ }
+
+ let _ = Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { timer in
+ testExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 5) { error in
+ XCTAssertNil(error)
+ XCTAssertEqual(order, [0])
+ }
+ }
}
From 8df97eeb67c7e7d7a1c2dcb3fe0b689b7b366c72 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 23 Sep 2018 18:42:36 +0200
Subject: [PATCH 36/57] Improving documentation
---
CHANGELOG.md | 19 +++++------
README.md | 58 ++++++++++++++++++++++++++++++----
Sources/Queuer/Semaphore.swift | 3 ++
3 files changed, 65 insertions(+), 15 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6ace826..6130a14 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,27 +16,28 @@ All notable changes to this project will be documented in this file.
---
-## Swift 4.2
+## [2.0.0](https://github.com/FabrizioBrancati/Queuer/releases/tag/2.0.0) - Let Me Retry
+### XX XXX 2018
### Added
- Added support to Xcode 10 and Swift 4.2
-- Added retry feature to `ConcurrentOperation` class [#32](https://github.com/FabrizioBrancati/BFKit-Swift/issues/10)
+- Added retry feature to `ConcurrentOperation` class [#32](https://github.com/FabrizioBrancati/BFKit-Swift/issues/10), more info on how to use it [here](https://github.com/FabrizioBrancati/Queuer#automatically-retry-an-operation) and [here](https://github.com/FabrizioBrancati/Queuer#manually-retry-an-operation)
- Added `addCompletionHandler(_:)` function to `Queuer` class
+- Added a `Scheduler` class to better schedule your tasks
+
+### Improved
+- Improved `Semaphore` with timeout handling
+- Updated SwiftLint to 0.27.0
### Changed
-- Changed `executionBlock` of `ConcurrentOperation` to pass the `concurrentOperation` variable inside the closure to be able to use the retry feature. If you don't need it simply put `_ in` after the block creation
+- Changed `executionBlock` of `ConcurrentOperation` to pass the `concurrentOperation` variable inside the closure to be able to use the retry feature. If you don't need it simply put `_ in` after the block creation:
```swift
let concurrentOperation = ConcurrentOperation { _ in
/// Your task here
}
```
+ This also affects `SynchronousOperation`
- Changed from Codecov to Coveralls service for code coverage
----
-
-## Develop
-### Improved
-- Updated SwiftLint to 0.27.0
-
### Removed
- Removed Hound CI
diff --git a/README.md b/README.md
index dfb3fae..815b438 100644
--- a/README.md
+++ b/README.md
@@ -153,6 +153,18 @@ See [Requirements](https://github.com/FabrizioBrancati/Queuer#requirements) sect
Usage
=====
+- [Shared Queuer](https://github.com/FabrizioBrancati/Queuer#shared-queuer)
+- [Custom Queue](https://github.com/FabrizioBrancati/Queuer#custom-queue)
+- [Create an Operation Block](https://github.com/FabrizioBrancati/Queuer#create-an-operation-block)
+- [Chained Operations](https://github.com/FabrizioBrancati/Queuer#chained-operations)
+- [Queue States](https://github.com/FabrizioBrancati/Queuer#queue-states)
+- [Asynchronous Operation](https://github.com/FabrizioBrancati/Queuer#anynchronous-operation)
+- [Synchronous Operation](https://github.com/FabrizioBrancati/Queuer#synchronous-operation)
+- [Automatically Retry an Operation](https://github.com/FabrizioBrancati/Queuer#automatically-retry-an-operation)
+- [Manually Retry an Operation](https://github.com/FabrizioBrancati/Queuer#manually-retry-an-operation)
+- [Scheduler](https://github.com/FabrizioBrancati/Queuer#scheduler)
+- [Semaphore](https://github.com/FabrizioBrancati/Queuer#semaphore)
+
### Shared Queuer
```swift
@@ -182,7 +194,7 @@ You have three methods to add an `Operation` block:
- Creating a `ConcurrentOperation` with a block:
```swift
- let concurrentOperation = ConcurrentOperation {
+ let concurrentOperation = ConcurrentOperation { _ in
/// Your task here
}
queue.addOperation(concurrentOperation)
@@ -190,7 +202,7 @@ You have three methods to add an `Operation` block:
- Creating a `SynchronousOperation` with a block:
```swift
- let synchronousOperation = SynchronousOperation {
+ let synchronousOperation = SynchronousOperation { _ in
/// Your task here
}
queue.addOperation(concurrentOperation)
@@ -202,10 +214,10 @@ You have three methods to add an `Operation` block:
Chained Operations are operations that add a dependency each other.
They follow the given array order, for example: `[A, B, C] = A -> B -> C -> completionBlock`.
```swift
-let concurrentOperation1 = ConcurrentOperation {
+let concurrentOperation1 = ConcurrentOperation { _ in
/// Your task 1 here
}
-let concurrentOperation2 = ConcurrentOperation {
+let concurrentOperation2 = ConcurrentOperation { _ in
/// Your task 2 here
}
queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
@@ -246,7 +258,7 @@ You must override `execute()` function and call the `finish()` function inside i
For convenience it has an `init` function with a completion block:
```swift
-let concurrentOperation = ConcurrentOperation {
+let concurrentOperation = ConcurrentOperation { _ in
/// Your task here
}
concurrentOperation.addToQueue(queue)
@@ -263,12 +275,46 @@ There are three methods to create synchronous tasks or even queue:
For convenience it has an `init` function with a completion block:
```swift
-let synchronousOperation = SynchronousOperation {
+let synchronousOperation = SynchronousOperation { _ in
/// Your task here
}
synchronousOperation.addToQueue(queue)
```
+### Automatically Retry an Operation
+An `Operation` is passed to every closure, with it you can set and handle the retry feature.
+By default the retry feature is disabled, to enable it simply set the `hasFailed` property to `true`. With `hasFailed` to `true` the `Operation` will retry until reaches `maximumRetries` property value. To let the `Operation` know when everything is ok, you must set `hasFailed` to `false`.
+With `currentAttempt` you can know at which attempt the `Operation` is.
+```swift
+let concurrentOperation = ConcurrentOperation { operation in
+ /// Your task here
+ if /* Failing */ {
+ operation.hasFailed = true
+ } else {
+ operation.hasFailed = false
+ }
+}
+```
+
+### Manually Retry an Operation
+It's even possible to manually retry an `Operation` when you think that the execution will be successful.
+An `Operation` is passed to every closure, with it you can set and handle the retry feature.
+By default the manual retry feature is disabled, to enable it simply set the `manualRetry` property to `true`, you must do this outside of the execution closure. You must also set `hasFailed` to `true` or `false` to let the `Operation` when is everything ok, like the automatic retry feature.
+To let the `Operation` retry your execution closure, you have to call the `retry()` function. If the `retry()` is not called, you may block the entire queue. Be sure to call it at least `maximumRetries` times, it is not a problem if you call `retry()` more times than is needed, your execution closure will not be executed more times than the `maximumRetries` value.
+```swift
+let concurrentOperation = ConcurrentOperation { operation in
+ /// Your task here
+ if /* Failing */ {
+ operation.hasFailed = true
+ } else {
+ operation.hasFailed = false
+ }
+}
+concurrentOperation.manualRetry = true
+/// Later on your code
+concurrentOperation.retry()
+```
+
### Scheduler
A `Scheduler` is a struct that uses the GDC's `DispatchSourceTimer` to create a timer that can execute functions with a specified interval and quality of service.
diff --git a/Sources/Queuer/Semaphore.swift b/Sources/Queuer/Semaphore.swift
index e2e1645..cc9fe31 100644
--- a/Sources/Queuer/Semaphore.swift
+++ b/Sources/Queuer/Semaphore.swift
@@ -45,6 +45,9 @@ public struct Semaphore {
}
/// Wait for a `continue` function call.
+ ///
+ /// - Parameter timeout: The timeout `DispatchTime`, default is `.distantFuture`.
+ /// - Returns: Returns a `DispatchTimeoutResult`.
@discardableResult
public func wait(_ timeout: DispatchTime = .distantFuture) -> DispatchTimeoutResult {
return semaphore.wait(timeout: timeout)
From 25b733b847798bb81fc6b6bd42b834f8a9c646eb Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 23 Sep 2018 18:42:45 +0200
Subject: [PATCH 37/57] Improving code
---
Sources/Queuer/ConcurrentOperation.swift | 2 +-
Tests/QueuerTests/ConcurrentOperationTests.swift | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index 242fb32..ddf2d70 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -76,7 +76,7 @@ open class ConcurrentOperation: Operation {
open var maximumRetries = 3
/// Current retry attempt.
- private(set) open var currentAttempt = 1
+ open private(set) var currentAttempt = 1
/// Allows for manual retries.
/// If set to `true`, `retry()` function must be manually called.
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index 8b63bcb..724c6e6 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -124,7 +124,7 @@ internal class ConcurrentOperationTests: XCTestCase {
}
let concurrentOperation2 = ConcurrentOperation { operation in
operation.cancel()
- if operation.isCancelled {
+ guard !operation.isCancelled else {
return
}
order.append(1)
@@ -151,7 +151,7 @@ internal class ConcurrentOperationTests: XCTestCase {
operation.hasFailed = true
}
concurrentOperation1.manualRetry = true
- let _ = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
+ _ = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
concurrentOperation1.retry()
if concurrentOperation1.currentAttempt > concurrentOperation1.maximumRetries {
timer.invalidate()
@@ -184,14 +184,14 @@ internal class ConcurrentOperationTests: XCTestCase {
}
concurrentOperation1.manualRetry = true
- let concurrentOperation2 = ConcurrentOperation { operation in
+ let concurrentOperation2 = ConcurrentOperation { _ in
order.append(1)
}
queue.addChainedOperations([concurrentOperation1, concurrentOperation2]) {
order.append(2)
}
- let _ = Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { timer in
+ _ = Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { _ in
testExpectation.fulfill()
}
From 388b34e2dc3d7d8e73c81863f592abe14798cb28 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 23 Sep 2018 18:59:48 +0200
Subject: [PATCH 38/57] Fixing tests
---
Tests/QueuerTests/ConcurrentOperationTests.swift | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index 724c6e6..11497ae 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -151,11 +151,9 @@ internal class ConcurrentOperationTests: XCTestCase {
operation.hasFailed = true
}
concurrentOperation1.manualRetry = true
- _ = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
+ var schedule = Scheduler(deadline: .now(), repeating: .seconds(1))
+ schedule.setHandler {
concurrentOperation1.retry()
- if concurrentOperation1.currentAttempt > concurrentOperation1.maximumRetries {
- timer.invalidate()
- }
}
let concurrentOperation2 = ConcurrentOperation { operation in
From f0d3d921931b582f8f4103206cd23807cbdee769 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 23 Sep 2018 19:30:45 +0200
Subject: [PATCH 39/57] Fixing tests
---
Tests/QueuerTests/ConcurrentOperationTests.swift | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index 11497ae..fea20ae 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -189,8 +189,10 @@ internal class ConcurrentOperationTests: XCTestCase {
order.append(2)
}
- _ = Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { _ in
+ var schedule = Scheduler(deadline: .now(), repeating: .seconds(3))
+ schedule.setHandler {
testExpectation.fulfill()
+ schedule.timer.cancel()
}
waitForExpectations(timeout: 5) { error in
From 9a49c7f6bf9400b1477f75716af68bf31a6e00da Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 23 Sep 2018 21:21:55 +0200
Subject: [PATCH 40/57] Fixing tests
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index 8e411c6..fa5e0d8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -90,7 +90,7 @@ script:
- if [ "$SPM" == "YES" ]; then
swift package clean;
ruby generate_linux_tests.rb;
- swift test --parallel;
+ swift test;
fi
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then
From fb55764c8f3686b51a62135e9c6e64a82b64e1cb Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 23 Sep 2018 22:45:07 +0200
Subject: [PATCH 41/57] Fixing tests
---
.../ConcurrentOperationTests.swift | 14 ++++---
Tests/QueuerTests/QueuerTests.swift | 3 +-
Tests/QueuerTests/SchedulerTests.swift | 37 +++++++++++++++++--
3 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index fea20ae..0b3b383 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -151,8 +151,14 @@ internal class ConcurrentOperationTests: XCTestCase {
operation.hasFailed = true
}
concurrentOperation1.manualRetry = true
- var schedule = Scheduler(deadline: .now(), repeating: .seconds(1))
- schedule.setHandler {
+
+ DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) {
+ concurrentOperation1.retry()
+ }
+ DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
+ concurrentOperation1.retry()
+ }
+ DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
concurrentOperation1.retry()
}
@@ -189,10 +195,8 @@ internal class ConcurrentOperationTests: XCTestCase {
order.append(2)
}
- var schedule = Scheduler(deadline: .now(), repeating: .seconds(3))
- schedule.setHandler {
+ DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(3)) {
testExpectation.fulfill()
- schedule.timer.cancel()
}
waitForExpectations(timeout: 5) { error in
diff --git a/Tests/QueuerTests/QueuerTests.swift b/Tests/QueuerTests/QueuerTests.swift
index 93a8be1..d9181a8 100644
--- a/Tests/QueuerTests/QueuerTests.swift
+++ b/Tests/QueuerTests/QueuerTests.swift
@@ -143,8 +143,7 @@ internal class QueuerTests: XCTestCase {
queue.addOperation(concurrentOperation1)
queue.addOperation(concurrentOperation2)
- let deadline = DispatchTime.now() + .seconds(2)
- DispatchQueue.global(qos: .background).asyncAfter(deadline: deadline) {
+ DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) {
testExpectation.fulfill()
}
diff --git a/Tests/QueuerTests/SchedulerTests.swift b/Tests/QueuerTests/SchedulerTests.swift
index ddbc1ce..395e8c8 100644
--- a/Tests/QueuerTests/SchedulerTests.swift
+++ b/Tests/QueuerTests/SchedulerTests.swift
@@ -31,28 +31,59 @@ import XCTest
internal class SchedulerTests: XCTestCase {
internal func testInitWithoutHandler() {
let testExpectation = expectation(description: "Init Without Handler")
+ var order: [Int] = []
var schedule = Scheduler(deadline: .now(), repeating: .seconds(1))
schedule.setHandler {
+ order.append(0)
+ }
+
+ DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(3500)) {
testExpectation.fulfill()
- schedule.timer.cancel()
}
- waitForExpectations(timeout: 2) { error in
+ waitForExpectations(timeout: 5) { error in
XCTAssertNil(error)
+ XCTAssertEqual(order, [0 ,0 ,0, 0])
}
}
internal func testInitWithHandler() {
let testExpectation = expectation(description: "Init With Handler")
+ var order: [Int] = []
let schedule = Scheduler(deadline: .now(), repeating: .never) {
+ order.append(0)
+ }
+
+ DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(3500)) {
testExpectation.fulfill()
}
- waitForExpectations(timeout: 2) { error in
+ waitForExpectations(timeout: 5) { error in
XCTAssertNil(error)
+ XCTAssertEqual(order, [0])
schedule.timer.cancel()
}
}
+
+ internal func testCancel() {
+ let testExpectation = expectation(description: "Init Without Handler")
+ var order: [Int] = []
+
+ var schedule = Scheduler(deadline: .now(), repeating: .seconds(1))
+ schedule.setHandler {
+ order.append(0)
+ schedule.timer.cancel()
+ }
+
+ DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(3500)) {
+ testExpectation.fulfill()
+ }
+
+ waitForExpectations(timeout: 5) { error in
+ XCTAssertNil(error)
+ XCTAssertEqual(order, [0])
+ }
+ }
}
From c49891153baaa03760da1b109a008a33192e9826 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 23 Sep 2018 23:11:12 +0200
Subject: [PATCH 42/57] Fixing tests
---
Tests/QueuerTests/ConcurrentOperationTests.swift | 2 +-
Tests/QueuerTests/QueuerTests.swift | 1 -
2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/Tests/QueuerTests/ConcurrentOperationTests.swift b/Tests/QueuerTests/ConcurrentOperationTests.swift
index 0b3b383..5ea45d9 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests.swift
@@ -75,10 +75,10 @@ internal class ConcurrentOperationTests: XCTestCase {
let concurrentOperation = ConcurrentOperation { operation in
operation.hasFailed = true
}
- concurrentOperation.addToQueue(queue)
queue.addCompletionHandler {
testExpectation.fulfill()
}
+ concurrentOperation.addToQueue(queue)
waitForExpectations(timeout: 5) { error in
XCTAssertNil(error)
diff --git a/Tests/QueuerTests/QueuerTests.swift b/Tests/QueuerTests/QueuerTests.swift
index d9181a8..7976beb 100644
--- a/Tests/QueuerTests/QueuerTests.swift
+++ b/Tests/QueuerTests/QueuerTests.swift
@@ -109,7 +109,6 @@ internal class QueuerTests: XCTestCase {
waitForExpectations(timeout: 5) { error in
XCTAssertNil(error)
- XCTAssertEqual(queue.operationCount, 0)
}
}
From 421d395837c7e7c23a3f264c7796479d53100abb Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 24 Sep 2018 00:00:40 +0200
Subject: [PATCH 43/57] Improving README
---
README.md | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 815b438..bd42236 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,7 @@ Features
========
Queuer is a queue manager, built on top of [OperationQueue](https://developer.apple.com/documentation/foundation/operationqueue) and [Dispatch](https://developer.apple.com/documentation/dispatch) (aka GCD).
-It allows you to create any synchronous and asynchronous task easily, with just a few lines.
+It allows you to create any asynchronous and synchronous task easily, all managed by a queue, with just a few lines.
Here is the list of all the features:
- [x] Works on all Swift compatible platforms (even Linux)
@@ -50,6 +50,7 @@ Here is the list of all the features:
- [x] Declare how many concurrent operation a queue can handle
- [x] Create semaphores
- [x] Create and handle schedules
+- [x] Automatically or manually retry an operation
- [ ] Ability to restore uncompleted operations
Requirements
@@ -60,7 +61,7 @@ Requirements
| 3.1...3.2 | 8.3...9.0 | 1.0.0...1.1.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
| 4.0 | 9.0...9.2 | 1.3.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
| 4.1 | 9.3...9.4 | 1.3.1...1.3.2 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
-| 4.2 | 10.0 | 2.x.x | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
+| 4.2 | 10.0 | 2.0.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
Installing
==========
From a3c29afa1ff1af019144e1f54e77d407f713448a Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 24 Sep 2018 00:00:56 +0200
Subject: [PATCH 44/57] Improving README
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index bd42236..da34860 100644
--- a/README.md
+++ b/README.md
@@ -52,6 +52,7 @@ Here is the list of all the features:
- [x] Create and handle schedules
- [x] Automatically or manually retry an operation
- [ ] Ability to restore uncompleted operations
+- [ ] Add throlling between each automatic operation retry
Requirements
============
From 4f30c30f2eee95adae8f590a0f66d11afd77ed0c Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 24 Sep 2018 00:11:03 +0200
Subject: [PATCH 45/57] Bumping version to 2.0.0
---
CHANGELOG.md | 3 +++
Queuer.podspec | 2 +-
Queuer.xcodeproj/project.pbxproj | 4 ++--
Sources/Info-iOS.plist | 2 +-
Sources/Info-macOS.plist | 2 +-
Sources/Info-tvOS.plist | 2 +-
Sources/Info-watchOS.plist | 2 +-
Tests/Info.plist | 2 +-
jazzy.sh | 2 +-
9 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6130a14..f629e26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,9 @@ All notable changes to this project will be documented in this file.
---
+### 2.x Releases
+- `2.0.x` Releases - [2.0.0](#200---let-me-retry)
+
### 1.x Releases
- `1.3.x` Releases - [1.3.0](#130---open-everything) | [1.3.1](#131---swift-41-support) | [1.3.2](#132---linux-quality)
- `1.2.x` Releases - [1.2.0](#120---swift-4-support) | [1.2.1](#121---unwanted-alert)
diff --git a/Queuer.podspec b/Queuer.podspec
index d9eefa3..8d6be88 100644
--- a/Queuer.podspec
+++ b/Queuer.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = 'Queuer'
s.module_name = 'Queuer'
- s.version = '1.3.2'
+ s.version = '2.0.0'
s.summary = 'Queuer is a queue manager, built on top of OperationQueue and Dispatch (aka GCD).'
s.homepage = 'https://github.com/FabrizioBrancati/Queuer'
s.screenshots = 'https://github.fabriziobrancati.com/queuer/resources/queuer-screenshot.png'
diff --git a/Queuer.xcodeproj/project.pbxproj b/Queuer.xcodeproj/project.pbxproj
index fdac045..8465193 100644
--- a/Queuer.xcodeproj/project.pbxproj
+++ b/Queuer.xcodeproj/project.pbxproj
@@ -732,7 +732,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 1.3.2;
+ CURRENT_PROJECT_VERSION = 2.0.0;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
@@ -813,7 +813,7 @@
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 1.3.2;
+ CURRENT_PROJECT_VERSION = 2.0.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
diff --git a/Sources/Info-iOS.plist b/Sources/Info-iOS.plist
index 2a3d8ce..d87c8b3 100644
--- a/Sources/Info-iOS.plist
+++ b/Sources/Info-iOS.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 1.3.2
+ 2.0.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/Sources/Info-macOS.plist b/Sources/Info-macOS.plist
index 0d1adf9..ae553b9 100644
--- a/Sources/Info-macOS.plist
+++ b/Sources/Info-macOS.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 1.3.2
+ 2.0.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSHumanReadableCopyright
diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist
index 0fb03af..267478e 100644
--- a/Sources/Info-tvOS.plist
+++ b/Sources/Info-tvOS.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 1.3.2
+ 2.0.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist
index 2a3d8ce..d87c8b3 100644
--- a/Sources/Info-watchOS.plist
+++ b/Sources/Info-watchOS.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 1.3.2
+ 2.0.0
CFBundleVersion
$(CURRENT_PROJECT_VERSION)
NSPrincipalClass
diff --git a/Tests/Info.plist b/Tests/Info.plist
index df52bb5..60e89d2 100644
--- a/Tests/Info.plist
+++ b/Tests/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 1.3.2
+ 2.0.0
CFBundleVersion
1
diff --git a/jazzy.sh b/jazzy.sh
index e49fa0d..c384069 100755
--- a/jazzy.sh
+++ b/jazzy.sh
@@ -2,7 +2,7 @@
# Creates documentation using Jazzy.
-FRAMEWORK_VERSION=1.3.2
+FRAMEWORK_VERSION=2.0.0
jazzy \
--clean \
From 7bf6e74e0f2aa0b40a2b95339b4e0bf1b3834edf Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 24 Sep 2018 00:29:04 +0200
Subject: [PATCH 46/57] Updating README
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index da34860..d010b51 100644
--- a/README.md
+++ b/README.md
@@ -11,8 +11,8 @@
[![Version](https://img.shields.io/cocoapods/v/Queuer.svg?style=flat)][Documentation]
[![License](https://img.shields.io/badge/license-MIT-lightgrey.svg)](https://github.com/FabrizioBrancati/Queuer/blob/master/LICENSE)
-[![Language](https://img.shields.io/badge/language-Swift%204.0%20%7C%204.1-orange.svg)](https://swift.org/)
-[![Platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS%20%7C%20Linux-ffc713.svg)][Documentation]
+[![Language](https://img.shields.io/badge/language-Swift%204.2-orange.svg)](https://swift.org/)
+[![Platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20macOS%20%7C%20tvOS%20%7C%20watchOS%20%7C%20Linux-cc9c00.svg)][Documentation]
---
From 678860443a3253518ce9c5ffc775d6b9cf6c7368 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 24 Sep 2018 00:29:14 +0200
Subject: [PATCH 47/57] Adding missing tests
---
Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift | 5 ++++-
Tests/QueuerTests/SchedulerTests+XCTest.swift | 3 ++-
Tests/QueuerTests/SynchronousOperationTests+XCTest.swift | 1 +
3 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift b/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
index d6f4540..b4025d9 100644
--- a/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
+++ b/Tests/QueuerTests/ConcurrentOperationTests+XCTest.swift
@@ -41,7 +41,10 @@ internal extension ConcurrentOperationTests {
("testAddToSharedQueuer", testAddToSharedQueuer),
("testAddToQueue", testAddToQueue),
("testSimpleRetry", testSimpleRetry),
- ("testChainedRetry", testChainedRetry)
+ ("testChainedRetry", testChainedRetry),
+ ("testCanceledChainedRetry", testCanceledChainedRetry),
+ ("testChainedManualRetry", testChainedManualRetry),
+ ("testChainedWrongManualRetry", testChainedWrongManualRetry)
]
}
}
diff --git a/Tests/QueuerTests/SchedulerTests+XCTest.swift b/Tests/QueuerTests/SchedulerTests+XCTest.swift
index 5842cdf..c893436 100644
--- a/Tests/QueuerTests/SchedulerTests+XCTest.swift
+++ b/Tests/QueuerTests/SchedulerTests+XCTest.swift
@@ -37,7 +37,8 @@ internal extension SchedulerTests {
internal static var allTests: [(String, (SchedulerTests) -> () throws -> Void)] {
return [
("testInitWithoutHandler", testInitWithoutHandler),
- ("testInitWithHandler", testInitWithHandler)
+ ("testInitWithHandler", testInitWithHandler),
+ ("testCancel", testCancel)
]
}
}
diff --git a/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift b/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
index 8aa49d0..e8a4e19 100644
--- a/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
+++ b/Tests/QueuerTests/SynchronousOperationTests+XCTest.swift
@@ -38,6 +38,7 @@ internal extension SynchronousOperationTests {
return [
("testSynchronousOperation", testSynchronousOperation),
("testSynchronousOperationOnSharedQueuer", testSynchronousOperationOnSharedQueuer),
+ ("testSynchronousOperationRetry", testSynchronousOperationRetry),
("testCancel", testCancel)
]
}
From 283f71b9ff8769142b08f72a6293fce26db8c2a6 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 14 Oct 2018 23:59:46 +0200
Subject: [PATCH 48/57] Minor change
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f629e26..900585a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,7 +20,7 @@ All notable changes to this project will be documented in this file.
---
## [2.0.0](https://github.com/FabrizioBrancati/Queuer/releases/tag/2.0.0) - Let Me Retry
-### XX XXX 2018
+### 2018
### Added
- Added support to Xcode 10 and Swift 4.2
- Added retry feature to `ConcurrentOperation` class [#32](https://github.com/FabrizioBrancati/BFKit-Swift/issues/10), more info on how to use it [here](https://github.com/FabrizioBrancati/Queuer#automatically-retry-an-operation) and [here](https://github.com/FabrizioBrancati/Queuer#manually-retry-an-operation)
From 03027dc4c40fc06847d92862f8f63a0b72e3f46a Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 15 Oct 2018 00:43:01 +0200
Subject: [PATCH 49/57] Minor change
---
CHANGELOG.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 900585a..f629e26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,7 +20,7 @@ All notable changes to this project will be documented in this file.
---
## [2.0.0](https://github.com/FabrizioBrancati/Queuer/releases/tag/2.0.0) - Let Me Retry
-### 2018
+### XX XXX 2018
### Added
- Added support to Xcode 10 and Swift 4.2
- Added retry feature to `ConcurrentOperation` class [#32](https://github.com/FabrizioBrancati/BFKit-Swift/issues/10), more info on how to use it [here](https://github.com/FabrizioBrancati/Queuer#automatically-retry-an-operation) and [here](https://github.com/FabrizioBrancati/Queuer#manually-retry-an-operation)
From 09b09777a660e0019bfced4eb1ae26a353664de4 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Tue, 16 Oct 2018 00:23:15 +0200
Subject: [PATCH 50/57] Improving project
---
Queuer.xcodeproj/project.pbxproj | 26 +++++++++-------------
Sources/Info-iOS.plist | 24 --------------------
Sources/Info-tvOS.plist | 28 ------------------------
Sources/Info-watchOS.plist | 24 --------------------
Sources/{Info-macOS.plist => Info.plist} | 4 ++++
5 files changed, 14 insertions(+), 92 deletions(-)
delete mode 100644 Sources/Info-iOS.plist
delete mode 100644 Sources/Info-tvOS.plist
delete mode 100644 Sources/Info-watchOS.plist
rename Sources/{Info-macOS.plist => Info.plist} (90%)
diff --git a/Queuer.xcodeproj/project.pbxproj b/Queuer.xcodeproj/project.pbxproj
index 8465193..c61aa1d 100644
--- a/Queuer.xcodeproj/project.pbxproj
+++ b/Queuer.xcodeproj/project.pbxproj
@@ -90,10 +90,7 @@
49C7BCB01F26938F00F4FFBC /* QueuerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueuerTests.swift; sourceTree = ""; };
49C7BCB21F26938F00F4FFBC /* SemaphoreTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SemaphoreTests.swift; sourceTree = ""; };
49C7BCB31F26938F00F4FFBC /* SynchronousOperationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SynchronousOperationTests.swift; sourceTree = ""; };
- 49C7BCB61F26938F00F4FFBC /* Info-iOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-iOS.plist"; sourceTree = ""; };
- 49C7BCB71F26938F00F4FFBC /* Info-macOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-macOS.plist"; sourceTree = ""; };
- 49C7BCB81F26938F00F4FFBC /* Info-tvOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-tvOS.plist"; sourceTree = ""; };
- 49C7BCB91F26938F00F4FFBC /* Info-watchOS.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-watchOS.plist"; sourceTree = ""; };
+ 49C7BCB71F26938F00F4FFBC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
49C7BCBB1F26938F00F4FFBC /* ConcurrentOperation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentOperation.swift; sourceTree = ""; };
49C7BCBC1F26938F00F4FFBC /* Queuer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Queuer.swift; sourceTree = ""; };
49C7BCBE1F26938F00F4FFBC /* Semaphore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Semaphore.swift; sourceTree = ""; };
@@ -204,10 +201,7 @@
49C7BCB51F26938F00F4FFBC /* Sources */ = {
isa = PBXGroup;
children = (
- 49C7BCB61F26938F00F4FFBC /* Info-iOS.plist */,
- 49C7BCB71F26938F00F4FFBC /* Info-macOS.plist */,
- 49C7BCB81F26938F00F4FFBC /* Info-tvOS.plist */,
- 49C7BCB91F26938F00F4FFBC /* Info-watchOS.plist */,
+ 49C7BCB71F26938F00F4FFBC /* Info.plist */,
49C7BCBA1F26938F00F4FFBC /* Queuer */,
49C7BCC11F26938F00F4FFBC /* Queuer.h */,
);
@@ -629,7 +623,7 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-macOS.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
@@ -651,7 +645,7 @@
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
FRAMEWORK_VERSION = A;
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-macOS.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
@@ -859,7 +853,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.FabrizioBrancati.Queuer-iOS";
@@ -879,7 +873,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-iOS.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.FabrizioBrancati.Queuer-iOS";
@@ -931,7 +925,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-watchOS.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.FabrizioBrancati.Queuer-watchOS";
@@ -953,7 +947,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-watchOS.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.FabrizioBrancati.Queuer-watchOS";
@@ -975,7 +969,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-tvOS.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.FabrizioBrancati.Queuer-tvOS";
@@ -997,7 +991,7 @@
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
- INFOPLIST_FILE = "$(SRCROOT)/Sources/Info-tvOS.plist";
+ INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.FabrizioBrancati.Queuer-tvOS";
diff --git a/Sources/Info-iOS.plist b/Sources/Info-iOS.plist
deleted file mode 100644
index d87c8b3..0000000
--- a/Sources/Info-iOS.plist
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- en
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- FMWK
- CFBundleShortVersionString
- 2.0.0
- CFBundleVersion
- $(CURRENT_PROJECT_VERSION)
- NSPrincipalClass
-
-
-
diff --git a/Sources/Info-tvOS.plist b/Sources/Info-tvOS.plist
deleted file mode 100644
index 267478e..0000000
--- a/Sources/Info-tvOS.plist
+++ /dev/null
@@ -1,28 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- en
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- FMWK
- CFBundleShortVersionString
- 2.0.0
- CFBundleVersion
- $(CURRENT_PROJECT_VERSION)
- NSPrincipalClass
-
- UIRequiredDeviceCapabilities
-
- arm64
-
-
-
diff --git a/Sources/Info-watchOS.plist b/Sources/Info-watchOS.plist
deleted file mode 100644
index d87c8b3..0000000
--- a/Sources/Info-watchOS.plist
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
- CFBundleDevelopmentRegion
- en
- CFBundleExecutable
- $(EXECUTABLE_NAME)
- CFBundleIdentifier
- $(PRODUCT_BUNDLE_IDENTIFIER)
- CFBundleInfoDictionaryVersion
- 6.0
- CFBundleName
- $(PRODUCT_NAME)
- CFBundlePackageType
- FMWK
- CFBundleShortVersionString
- 2.0.0
- CFBundleVersion
- $(CURRENT_PROJECT_VERSION)
- NSPrincipalClass
-
-
-
diff --git a/Sources/Info-macOS.plist b/Sources/Info.plist
similarity index 90%
rename from Sources/Info-macOS.plist
rename to Sources/Info.plist
index ae553b9..73dbae2 100644
--- a/Sources/Info-macOS.plist
+++ b/Sources/Info.plist
@@ -22,5 +22,9 @@
Copyright © 2017 - 2018 Fabrizio Brancati.
NSPrincipalClass
+ UIRequiredDeviceCapabilities
+
+ arm64
+
From 7976a04490d43031f7c6a9cc26a1a3ae62e4f996 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Tue, 16 Oct 2018 00:33:19 +0200
Subject: [PATCH 51/57] Adding missing platforms
---
.travis.yml | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index fa5e0d8..f8bbe1c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,6 +36,10 @@ matrix:
language: objective-c
osx_image: xcode9.2
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=8.1,name=iPhone 4S" SCHEME="$IOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
+ - os: osx
+ language: objective-c
+ osx_image: xcode10
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=12.0,name=Apple TV 4K" SCHEME="$TVOS_SCHEME" RUN_TESTS="YES" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
@@ -51,7 +55,11 @@ matrix:
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=4.2,name=Apple Watch Series 3 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=5.0,name=Apple Watch Series 4 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
+ - os: osx
+ language: objective-c
+ osx_image: xcode10
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=4.2,name=Apple Watch Series 3 - 38mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
From 17c6171b8b8f8a0ca9b8f78d4213676d6afe41c4 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Tue, 16 Oct 2018 07:48:56 +0200
Subject: [PATCH 52/57] Fixing build
---
.travis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.travis.yml b/.travis.yml
index f8bbe1c..89f180f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -55,7 +55,7 @@ matrix:
- os: osx
language: objective-c
osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=5.0,name=Apple Watch Series 4 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
+ env: PROJ="Queuer.xcodeproj" DESTINATION="OS=5.0,name=Apple Watch Series 4 - 44mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
From ec40d6d7b967c4ab38540ca2d7849d12e8fc450b Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 21 Oct 2018 23:20:10 +0200
Subject: [PATCH 53/57] Fixes #11
---
Queuer.podspec | 2 +-
Queuer.xcodeproj/project.pbxproj | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/Queuer.podspec b/Queuer.podspec
index 8d6be88..eb86c90 100644
--- a/Queuer.podspec
+++ b/Queuer.podspec
@@ -18,5 +18,5 @@ Pod::Spec.new do |s|
s.ios.deployment_target = '8.0'
s.osx.deployment_target = '10.10'
s.tvos.deployment_target = '9.0'
- s.watchos.deployment_target = '2.0'
+ s.watchos.deployment_target = '3.0'
end
diff --git a/Queuer.xcodeproj/project.pbxproj b/Queuer.xcodeproj/project.pbxproj
index c61aa1d..40dce84 100644
--- a/Queuer.xcodeproj/project.pbxproj
+++ b/Queuer.xcodeproj/project.pbxproj
@@ -933,7 +933,7 @@
SDKROOT = watchos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = 4;
- WATCHOS_DEPLOYMENT_TARGET = 2.0;
+ WATCHOS_DEPLOYMENT_TARGET = 3.0;
};
name = Debug;
};
@@ -955,7 +955,7 @@
SDKROOT = watchos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = 4;
- WATCHOS_DEPLOYMENT_TARGET = 2.0;
+ WATCHOS_DEPLOYMENT_TARGET = 3.0;
};
name = Release;
};
From f15a86114eb0d01ca1dc78382e501aba6e6d95e5 Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 21 Oct 2018 23:20:24 +0200
Subject: [PATCH 54/57] Removing watchOS 2.0
---
.travis.yml | 4 ----
1 file changed, 4 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 89f180f..1e63593 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -64,10 +64,6 @@ matrix:
language: objective-c
osx_image: xcode10
env: PROJ="Queuer.xcodeproj" DESTINATION="OS=3.2,name=Apple Watch Series 2 - 42mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
- - os: osx
- language: objective-c
- osx_image: xcode10
- env: PROJ="Queuer.xcodeproj" DESTINATION="OS=2.0,name=Apple Watch - 38mm" SCHEME="$WATCHOS_SCHEME" RUN_TESTS="NO" LINT="NO" COVERAGE="NO"
- os: osx
language: objective-c
osx_image: xcode10
From 26a6634a26dd1937ceaa818791db2f8030ca145d Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Sun, 21 Oct 2018 23:20:37 +0200
Subject: [PATCH 55/57] Updating documentation
---
CHANGELOG.md | 5 ++++-
README.md | 2 +-
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f629e26..a84f13e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,7 +23,7 @@ All notable changes to this project will be documented in this file.
### XX XXX 2018
### Added
- Added support to Xcode 10 and Swift 4.2
-- Added retry feature to `ConcurrentOperation` class [#32](https://github.com/FabrizioBrancati/BFKit-Swift/issues/10), more info on how to use it [here](https://github.com/FabrizioBrancati/Queuer#automatically-retry-an-operation) and [here](https://github.com/FabrizioBrancati/Queuer#manually-retry-an-operation)
+- Added retry feature to `ConcurrentOperation` class [#10](https://github.com/FabrizioBrancati/BFKit-Swift/issues/10), more info on how to use it [here](https://github.com/FabrizioBrancati/Queuer#automatically-retry-an-operation) and [here](https://github.com/FabrizioBrancati/Queuer#manually-retry-an-operation)
- Added `addCompletionHandler(_:)` function to `Queuer` class
- Added a `Scheduler` class to better schedule your tasks
@@ -32,6 +32,7 @@ All notable changes to this project will be documented in this file.
- Updated SwiftLint to 0.27.0
### Changed
+- Changed watchOS target to watchOS 3.0 instead of 2.0, thanks to an App Store submission rule [#11](https://github.com/FabrizioBrancati/BFKit-Swift/issues/11)
- Changed `executionBlock` of `ConcurrentOperation` to pass the `concurrentOperation` variable inside the closure to be able to use the retry feature. If you don't need it simply put `_ in` after the block creation:
```swift
let concurrentOperation = ConcurrentOperation { _ in
@@ -44,6 +45,8 @@ All notable changes to this project will be documented in this file.
### Removed
- Removed Hound CI
+Thanks to [@zykloman](https://github.com/zykloman) and [@debjitk](https://github.com/debjitk) for this release
+
---
## [1.3.2](https://github.com/FabrizioBrancati/Queuer/releases/tag/1.3.2) - Linux Quality
diff --git a/README.md b/README.md
index d010b51..bbaa1e3 100644
--- a/README.md
+++ b/README.md
@@ -62,7 +62,7 @@ Requirements
| 3.1...3.2 | 8.3...9.0 | 1.0.0...1.1.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
| 4.0 | 9.0...9.2 | 1.3.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
| 4.1 | 9.3...9.4 | 1.3.1...1.3.2 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
-| 4.2 | 10.0 | 2.0.0 | 8.0+ | 10.10+ | 9.0+ | 2.0+ | ![✓] |
+| 4.2 | 10.0 | 2.0.0 | 8.0+ | 10.10+ | 9.0+ | 3.0+ | ![✓] |
Installing
==========
From f206ae107af1e1126ddfd4d3f02170d3b3e49acb Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Mon, 22 Oct 2018 00:20:48 +0200
Subject: [PATCH 56/57] Minor changes
---
CHANGELOG.md | 8 ++++----
Sources/Queuer/ConcurrentOperation.swift | 3 ++-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a84f13e..c3d7b34 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,10 +27,6 @@ All notable changes to this project will be documented in this file.
- Added `addCompletionHandler(_:)` function to `Queuer` class
- Added a `Scheduler` class to better schedule your tasks
-### Improved
-- Improved `Semaphore` with timeout handling
-- Updated SwiftLint to 0.27.0
-
### Changed
- Changed watchOS target to watchOS 3.0 instead of 2.0, thanks to an App Store submission rule [#11](https://github.com/FabrizioBrancati/BFKit-Swift/issues/11)
- Changed `executionBlock` of `ConcurrentOperation` to pass the `concurrentOperation` variable inside the closure to be able to use the retry feature. If you don't need it simply put `_ in` after the block creation:
@@ -42,6 +38,10 @@ All notable changes to this project will be documented in this file.
This also affects `SynchronousOperation`
- Changed from Codecov to Coveralls service for code coverage
+### Improved
+- Improved `Semaphore` with timeout handling
+- Updated SwiftLint to 0.27.0
+
### Removed
- Removed Hound CI
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index ddf2d70..e63a761 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -26,7 +26,8 @@
import Foundation
-/// It allows asynchronous tasks, has a pause and resume states, can be easily added to a queue and can be created with a block.
+/// It allows asynchronous tasks, has a pause and resume states,
+/// can be easily added to a queue and can be created with a block.
open class ConcurrentOperation: Operation {
/// `Operation`'s execution block.
public var executionBlock: ((_ operation: ConcurrentOperation) -> Void)?
From 83b28f3beeeb6eec507455be998e5829a846667d Mon Sep 17 00:00:00 2001
From: Fabrizio Brancati
Date: Tue, 23 Oct 2018 00:41:04 +0200
Subject: [PATCH 57/57] Minor changes
---
README.md | 2 +-
Sources/Queuer/ConcurrentOperation.swift | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/README.md b/README.md
index bbaa1e3..4b9e05c 100644
--- a/README.md
+++ b/README.md
@@ -52,7 +52,7 @@ Here is the list of all the features:
- [x] Create and handle schedules
- [x] Automatically or manually retry an operation
- [ ] Ability to restore uncompleted operations
-- [ ] Add throlling between each automatic operation retry
+- [ ] Throlling between each automatic operation retry
Requirements
============
diff --git a/Sources/Queuer/ConcurrentOperation.swift b/Sources/Queuer/ConcurrentOperation.swift
index e63a761..db1cc2f 100644
--- a/Sources/Queuer/ConcurrentOperation.swift
+++ b/Sources/Queuer/ConcurrentOperation.swift
@@ -107,7 +107,7 @@ open class ConcurrentOperation: Operation {
open func retry() {
if manualRetry, shouldRetry, let executionBlock = executionBlock {
executionBlock(self)
- self.finish(hasFailed)
+ finish(hasFailed)
}
}
@@ -117,7 +117,7 @@ open class ConcurrentOperation: Operation {
if let executionBlock = executionBlock {
while shouldRetry, !manualRetry {
executionBlock(self)
- self.finish(hasFailed)
+ finish(hasFailed)
}
retry()