Skip to content

Commit 1e35388

Browse files
lightsprint09ch-one
authored andcommitted
Final Release Merge for 1.1 (#82)
* Fixes small linter warning * updates to recommended build settings * upgrade swift version * Update NetworkServiceMock.swift NetworkServiceMock now supports request response chains, where one response leads to an other request. * Fixes tests of RetryNetworkService using the NetworkServiceMock * Made new implementation of returnError/returnSuccess not depend on old implemention * improves tests for RetryNetworkTask * Update README.md * small clean ups * Added unit tests for NetworkServiceMock * Resolved linter warnings * Updated documentation of NetworkServiceMock * Fixed an other linter warning * bump version * Removes unneeded file
1 parent 456ee27 commit 1e35388

15 files changed

+341
-54
lines changed

.swift-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4.0
1+
4.1

.travis.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ matrix:
1717
script:
1818
- swift test --verbose
1919
- os: osx
20-
osx_image: xcode9.2
21-
language: objective-c
20+
osx_image: xcode9.3
2221
env: "macOS"
2322
skip-cleanup: true
2423
before_install:

DBNetworkStack.podspec

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Pod::Spec.new do |s|
1616
#
1717

1818
s.name = "DBNetworkStack"
19-
s.version = "1.0.0"
19+
s.version = "1.1.0"
2020
s.summary = "DBNetworkStack is a network abstraction for fetching request and mapping them to model objects."
2121

2222
# This description is used to generate tags and improve search results.

DBNetworkStack.xcodeproj/project.pbxproj

+5-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@
325325
isa = PBXProject;
326326
attributes = {
327327
LastSwiftUpdateCheck = 0730;
328-
LastUpgradeCheck = 0900;
328+
LastUpgradeCheck = 0930;
329329
ORGANIZATIONNAME = DBSystel;
330330
TargetAttributes = {
331331
C60BE65A1D6B2BF3006B0364 = {
@@ -466,12 +466,14 @@
466466
CLANG_WARN_BOOL_CONVERSION = YES;
467467
CLANG_WARN_COMMA = YES;
468468
CLANG_WARN_CONSTANT_CONVERSION = YES;
469+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
469470
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
470471
CLANG_WARN_EMPTY_BODY = YES;
471472
CLANG_WARN_ENUM_CONVERSION = YES;
472473
CLANG_WARN_INFINITE_RECURSION = YES;
473474
CLANG_WARN_INT_CONVERSION = YES;
474475
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
476+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
475477
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
476478
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
477479
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
@@ -527,12 +529,14 @@
527529
CLANG_WARN_BOOL_CONVERSION = YES;
528530
CLANG_WARN_COMMA = YES;
529531
CLANG_WARN_CONSTANT_CONVERSION = YES;
532+
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
530533
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
531534
CLANG_WARN_EMPTY_BODY = YES;
532535
CLANG_WARN_ENUM_CONVERSION = YES;
533536
CLANG_WARN_INFINITE_RECURSION = YES;
534537
CLANG_WARN_INT_CONVERSION = YES;
535538
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
539+
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
536540
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
537541
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
538542
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;

DBNetworkStack.xcodeproj/xcshareddata/xcschemes/DBNetworkStack.xcscheme

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0900"
3+
LastUpgradeVersion = "0930"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"
@@ -26,8 +26,8 @@
2626
buildConfiguration = "Debug"
2727
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
2828
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29-
shouldUseLaunchSchemeArgsEnv = "YES"
30-
codeCoverageEnabled = "YES">
29+
codeCoverageEnabled = "YES"
30+
shouldUseLaunchSchemeArgsEnv = "YES">
3131
<Testables>
3232
<TestableReference
3333
skipped = "NO">

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Create a resource with a request to fetch your data.
3636
```swift
3737

3838
let url = URL(string: "https://httpbin.org")!
39-
let request = URLRequest(path: "/", baseURL: url)
39+
let request = URLRequest(path: "/", baseURL: url, HTTPMethod: .GET)
4040
let resource = Resource(request: request, parse: { String(data: $0, encoding: .utf8) })
4141

4242
```
@@ -112,7 +112,7 @@ The following table shows all the protocols and their default implementations.
112112
Specify the following in your `Cartfile`:
113113

114114
```ogdl
115-
github "dbsystel/dbnetworkstack" ~> 1.0
115+
github "dbsystel/dbnetworkstack" ~> 1.1
116116
```
117117

118118
### CocoaPods

Source/Info.plist

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<key>CFBundlePackageType</key>
1616
<string>FMWK</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>1.0.0</string>
18+
<string>1.1.0</string>
1919
<key>CFBundleSignature</key>
2020
<string>????</string>
2121
<key>CFBundleVersion</key>

Source/NetworkServiceMock.swift

+93-23
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ struct NetworkServiceMockCallback {
4949
}
5050

5151
/**
52-
Mocks a `NetworkService`. You can configure expected results or errors to have a fully functional mock.
52+
Mocks a `NetworkService`.
53+
You can configure expected results or errors to have a fully functional mock.
5354

5455
**Example**:
5556
```swift
@@ -58,12 +59,46 @@ struct NetworkServiceMockCallback {
5859
let resource: Resource<String> = //
5960

6061
//When
61-
// Your test code
62+
networkService.request(
63+
resource,
64+
onCompletion: { string in /*...*/ },
65+
onError: { error in /*...*/ }
66+
)
6267
networkService.returnSuccess(with: "Sucess")
6368

6469
//Then
6570
//Test your expectations
6671

72+
```
73+
74+
It is possible to start multiple requests at a time.
75+
All requests and responses (or errors) are processed
76+
in order they have been called. So, everything is serial.
77+
78+
**Example**:
79+
```swift
80+
//Given
81+
let networkServiceMock = NetworkServiceMock()
82+
let resource: Resource<String> = //
83+
84+
//When
85+
networkService.request(
86+
resource,
87+
onCompletion: { string in /* Success */ },
88+
onError: { error in /*...*/ }
89+
)
90+
networkService.request(
91+
resource,
92+
onCompletion: { string in /*...*/ },
93+
onError: { error in /*. cancel error .*/ }
94+
)
95+
96+
networkService.returnSuccess(with: "Sucess")
97+
networkService.returnError(with: .cancelled)
98+
99+
//Then
100+
//Test your expectations
101+
67102
```
68103

69104
- seealso: `NetworkService`
@@ -76,11 +111,11 @@ public final class NetworkServiceMock: NetworkService {
76111
/// Set this to hava a custom networktask returned by the mock
77112
public var nextNetworkTask: NetworkTask?
78113

79-
private var callbacks: NetworkServiceMockCallback?
114+
private var callbacks: [NetworkServiceMockCallback] = []
80115

81116
/// Creates an instace of `NetworkServiceMock`
82117
public init() {}
83-
118+
84119
/**
85120
Fetches a resource asynchronously from remote location. Execution of the requests starts immediately.
86121
Execution happens on no specific queue. It dependes on the network access which queue is used.
@@ -93,9 +128,9 @@ public final class NetworkServiceMock: NetworkService {
93128
let resource: Resource<String> = //
94129

95130
networkService.request(queue: .main, resource: resource, onCompletionWithResponse: { htmlText, response in
96-
print(htmlText, response)
131+
print(htmlText, response)
97132
}, onError: { error in
98-
// Handle errors
133+
// Handle errors
99134
})
100135
```
101136

@@ -108,11 +143,15 @@ public final class NetworkServiceMock: NetworkService {
108143
*/
109144
@discardableResult
110145
public func request<Result>(queue: DispatchQueue, resource: Resource<Result>, onCompletionWithResponse: @escaping (Result, HTTPURLResponse) -> Void,
111-
onError: @escaping (NetworkError) -> Void) -> NetworkTask {
112-
146+
onError: @escaping (NetworkError) -> Void) -> NetworkTask {
147+
113148
lastRequest = resource.request
114149
requestCount += 1
115-
callbacks = NetworkServiceMockCallback(resource: resource, onCompletionWithResponse: onCompletionWithResponse, onError: onError)
150+
callbacks.append(NetworkServiceMockCallback(
151+
resource: resource,
152+
onCompletionWithResponse: onCompletionWithResponse,
153+
onError: onError
154+
))
116155

117156
return nextNetworkTask ?? NetworkTaskMock()
118157
}
@@ -121,25 +160,44 @@ public final class NetworkServiceMock: NetworkService {
121160
///
122161
/// - Parameters:
123162
/// - error: the error which gets passed to the caller
124-
/// - count: the count, how often the error accours. 1 by default
125-
public func returnError(with error: NetworkError, count: Int = 1) {
126-
for _ in 0..<count {
127-
callbacks?.onErrorCallback?(error)
163+
public func returnError(with error: NetworkError) {
164+
callbacks.removeFirst().onErrorCallback?(error)
165+
}
166+
167+
/// Will return an error to the current waiting request.
168+
///
169+
/// - Parameters:
170+
/// - error: the error which gets passed to the caller
171+
/// - count: the count, how often the error occours.
172+
@available(*, deprecated, message: "Use returnError without count parameter instead. Multiple calls can be done manually.")
173+
public func returnError(with error: NetworkError, count: Int) {
174+
(0..<count).forEach { _ in
175+
precondition(!callbacks.isEmpty, "There is no request left to return an error for.")
176+
returnError(with: error)
128177
}
129-
callbacks = nil
178+
}
179+
180+
/// Will return a successful request, by using the given data as a server response.
181+
///
182+
/// - Parameters:
183+
/// - data: the mock response from the server.
184+
/// - httpResponse: the mock `HTTPURLResponse` from the server. `HTTPURLResponse()` by default
185+
public func returnSuccess(with data: Data, httpResponse: HTTPURLResponse = HTTPURLResponse()) {
186+
callbacks.removeFirst().onSuccess?(data, httpResponse)
130187
}
131188

132189
/// Will return a successful request, by using the given data as a server response.
133190
///
134191
/// - Parameters:
135192
/// - data: the mock response from the server. `Data()` by default
136193
/// - httpResponse: the mock `HTTPURLResponse` from the server. `HTTPURLResponse()` by default
137-
/// - count: the count how often the response gets triggerd. 1 by default
194+
/// - count: the count how often the response gets triggerd.
195+
@available(*, deprecated, message: "Use returnSuccess without count parameter instead. Multiple calls can be done manually.")
138196
public func returnSuccess(with data: Data = Data(), httpResponse: HTTPURLResponse = HTTPURLResponse(), count: Int = 1) {
139-
for _ in 0..<count {
140-
callbacks?.onSuccess?(data, httpResponse)
197+
(0..<count).forEach { _ in
198+
precondition(!callbacks.isEmpty, "There is no request left to return a success for.")
199+
returnSuccess(with: data, httpResponse: httpResponse)
141200
}
142-
callbacks = nil
143201
}
144202

145203
/// Will return a successful request, by using the given type `T` as serialized result of a request.
@@ -149,12 +207,24 @@ public final class NetworkServiceMock: NetworkService {
149207
/// - Parameters:
150208
/// - data: the mock response from the server. `Data()` by default
151209
/// - httpResponse: the mock `HTTPURLResponse` from the server. `HTTPURLResponse()` by default
152-
/// - count: the count how often the response gets triggerd. 1 by default
153-
public func returnSuccess<T>(with serializedResponse: T, httpResponse: HTTPURLResponse = HTTPURLResponse(), count: Int = 1) {
154-
for _ in 0..<count {
155-
callbacks?.onTypedSuccess?(serializedResponse, httpResponse)
210+
public func returnSuccess<T>(with serializedResponse: T, httpResponse: HTTPURLResponse = HTTPURLResponse()) {
211+
callbacks.removeFirst().onTypedSuccess?(serializedResponse, httpResponse)
212+
}
213+
214+
/// Will return a successful request, by using the given type `T` as serialized result of a request.
215+
///
216+
/// **Warning:** This will crash if type `T` does not match your expected ResponseType of your current request
217+
///
218+
/// - Parameters:
219+
/// - data: the mock response from the server. `Data()` by default
220+
/// - httpResponse: the mock `HTTPURLResponse` from the server. `HTTPURLResponse()` by default
221+
/// - count: the count how often the response gets triggerd.
222+
@available(*, deprecated, message: "Use returnSuccess without count parameter instead. Multiple calls can be done manually.")
223+
public func returnSuccess<T>(with serializedResponse: T, httpResponse: HTTPURLResponse = HTTPURLResponse(), count: Int) {
224+
(0..<count).forEach { _ in
225+
precondition(!callbacks.isEmpty, "There is no request left to return a typed success for.")
226+
returnSuccess(with: serializedResponse, httpResponse: httpResponse)
156227
}
157-
callbacks = nil
158228
}
159229

160230
}

Source/Resource+Map.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extension Resource {
2727
///
2828
/// - Parameter transform: transforms the original result of the resource
2929
/// - Returns: the transformed resource
30-
public func map<T>(transform: @escaping (Model) throws -> (T)) -> Resource<T> {
30+
public func map<T>(transform: @escaping (Model) throws -> T) -> Resource<T> {
3131
return Resource<T>(request: request, parse: { data in
3232
return try transform(try self.parse(data))
3333
})

Source/RetryNetworkTask.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import Foundation
2525
import Dispatch
2626

2727
/// A NetworkTaskRepresenting which can be used together with `RetryNetworkService` to keep a task alife to repeat the task after a given time
28-
class RetryNetworkTask<T> : NetworkTask {
28+
final class RetryNetworkTask<T>: NetworkTask {
29+
2930
private let maxmimumNumberOfRetries: Int
3031
private let idleTimeInterval: TimeInterval
3132
private let shouldRetry: (NetworkError) -> Bool

Tests/DBNetworkStackTests/NetworkResponseProcessorTest.swift

+3-4
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class NetworkResponseProcessingTests: XCTestCase {
5151
XCTFail("Expected cancelled error (got \(error)")
5252
}
5353
} catch let error {
54-
XCTFail("Expected NetworkError (got \(type(of:error)))")
54+
XCTFail("Expected NetworkError (got \(type(of: error)))")
5555
}
5656

5757
XCTAssertNil(result, "Expected processing to fail")
@@ -80,12 +80,11 @@ class NetworkResponseProcessingTests: XCTestCase {
8080
}
8181

8282
XCTAssertEqual(recievedData, data)
83-
break
8483
default:
8584
XCTFail("Expected cancelled error (got \(error)")
8685
}
8786
} catch let error {
88-
XCTFail("Expected NetworkError (got \(type(of:error)))")
87+
XCTFail("Expected NetworkError (got \(type(of: error)))")
8988
}
9089
}
9190

@@ -105,7 +104,7 @@ class NetworkResponseProcessingTests: XCTestCase {
105104
XCTFail("Expected cancelled error (got \(error)")
106105
}
107106
} catch let error {
108-
XCTFail("Expected NetworkError (got \(type(of:error)))")
107+
XCTFail("Expected NetworkError (got \(type(of: error)))")
109108
}
110109

111110
}

0 commit comments

Comments
 (0)