diff --git a/Gemfile b/Gemfile index 2b20351d..1b8283e2 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,8 @@ gem "danger-swiftlint" gem "danger-xcode_summary" gem 'danger-swiftformat' gem 'danger-xcov' +# Fix issue with Cocoapods 13.0 when activesupport is 7.1.0 +gem 'activesupport', '~> 7.0.0', '>= 7.0.8' plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile') eval_gemfile(plugins_path) if File.exist?(plugins_path) diff --git a/Tuist/Interfaces/SwiftUI/Project/Podfile b/Tuist/Interfaces/SwiftUI/Project/Podfile index 6dbc2e01..7a0d2eed 100644 --- a/Tuist/Interfaces/SwiftUI/Project/Podfile +++ b/Tuist/Interfaces/SwiftUI/Project/Podfile @@ -7,6 +7,7 @@ def testing_pods pod 'Nimble', '~> 11.0' pod 'Sourcery' pod 'SwiftFormat/CLI' + pod 'OHHTTPStubs/Swift', :configurations => ['Debug Staging', 'Debug Production'] end target '{PROJECT_NAME}' do diff --git a/Tuist/Interfaces/UIKit/Project/.sourcery.yml b/Tuist/Interfaces/UIKit/Project/.sourcery.yml index 29469316..492262a4 100644 --- a/Tuist/Interfaces/UIKit/Project/.sourcery.yml +++ b/Tuist/Interfaces/UIKit/Project/.sourcery.yml @@ -7,6 +7,3 @@ output: args: autoMockableTestableImports: - {PROJECT_NAME} - autoMockableImports: - - RxSwift - - RxCocoa diff --git a/Tuist/Interfaces/UIKit/Project/Podfile b/Tuist/Interfaces/UIKit/Project/Podfile index cf4fbd43..ab75d34b 100644 --- a/Tuist/Interfaces/UIKit/Project/Podfile +++ b/Tuist/Interfaces/UIKit/Project/Podfile @@ -1,12 +1,13 @@ -platform :ios, '11.0' +platform :ios, '13.0' use_frameworks! inhibit_all_warnings! def testing_pods - pod 'Quick' - pod 'Nimble' + pod 'Quick', '~> 6.0' + pod 'Nimble', '~> 11.0' pod 'Sourcery' pod 'SwiftFormat/CLI' + pod 'OHHTTPStubs/Swift', :configurations => ['Debug Staging', 'Debug Production'] end target '{PROJECT_NAME}' do diff --git a/{PROJECT_NAME}Tests/Sources/Dummy/.gitkeep b/{PROJECT_NAME}Tests/Sources/Dummy/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/{PROJECT_NAME}Tests/Sources/Dummy/Data/DummyNetworkModel.swift b/{PROJECT_NAME}Tests/Sources/Dummy/Data/DummyNetworkModel.swift new file mode 100644 index 00000000..e6dfb70c --- /dev/null +++ b/{PROJECT_NAME}Tests/Sources/Dummy/Data/DummyNetworkModel.swift @@ -0,0 +1,14 @@ +// +// DummyNetworkModel.swift +// + +import Foundation + +struct DummyNetworkModel: Decodable { + + static let json = + """ + {"message": "Hello"} + """ + let message: String +} diff --git a/{PROJECT_NAME}Tests/Sources/Dummy/Data/DummyRequestConfiguration.swift b/{PROJECT_NAME}Tests/Sources/Dummy/Data/DummyRequestConfiguration.swift new file mode 100644 index 00000000..1359b72b --- /dev/null +++ b/{PROJECT_NAME}Tests/Sources/Dummy/Data/DummyRequestConfiguration.swift @@ -0,0 +1,29 @@ +// +// DummyRequestConfiguration.swift +// + +import Alamofire + +@testable import {PROJECT_NAME} + +struct DummyRequestConfiguration: RequestConfiguration { + + var baseURL: String { "https://example.com" } + + var endpoint: String { "" } + + var method: Alamofire.HTTPMethod { .get } + + var encoding: Alamofire.ParameterEncoding { URLEncoding.queryString } +} + +extension DummyRequestConfiguration: RequestConfigurationStubable { + + var sampleData: Data { + DummyNetworkModel.json.data(using: .utf8) ?? Data() + } + + var path: String { + (try? url.asURL().path).string + } +} diff --git a/{PROJECT_NAME}Tests/Sources/Specs/Data/NetworkAPI/NetworkAPISpec.swift b/{PROJECT_NAME}Tests/Sources/Specs/Data/NetworkAPI/NetworkAPISpec.swift new file mode 100644 index 00000000..c26bbdd0 --- /dev/null +++ b/{PROJECT_NAME}Tests/Sources/Specs/Data/NetworkAPI/NetworkAPISpec.swift @@ -0,0 +1,64 @@ +// +// NetworkAPISpec.swift +// + +import Nimble +import Quick + +@testable import {PROJECT_NAME} + +final class NetworkAPISpec: QuickSpec { + + override func spec() { + + describe("a NetworkAPI") { + + var networkAPI: NetworkAPI! + var requestConfiguration: DummyRequestConfiguration! + + describe("its performRequest") { + + beforeEach { + requestConfiguration = DummyRequestConfiguration() + } + + afterEach { + NetworkStubber.removeAllStubs() + } + + context("when network returns value") { + + beforeEach { + NetworkStubber.stub(requestConfiguration) + networkAPI = NetworkAPI() + } + + it("returns message as Hello") { + let response = try await networkAPI.performRequest( + requestConfiguration, + for: DummyNetworkModel.self + ) + expect(response.message) == "Hello" + } + } + + context("when network returns error") { + + beforeEach { + NetworkStubber.stub(requestConfiguration, data: Data(), statusCode: 400) + networkAPI = NetworkAPI() + } + + it("throws error") { + await expect { + try await networkAPI.performRequest( + requestConfiguration, + for: DummyNetworkModel.self + ) + }.to(throwError()) + } + } + } + } + } +} diff --git a/{PROJECT_NAME}Tests/Sources/Utilities/.gitkeep b/{PROJECT_NAME}Tests/Sources/Utilities/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/{PROJECT_NAME}Tests/Sources/Utilities/NetworkStubber.swift b/{PROJECT_NAME}Tests/Sources/Utilities/NetworkStubber.swift new file mode 100644 index 00000000..85ccb721 --- /dev/null +++ b/{PROJECT_NAME}Tests/Sources/Utilities/NetworkStubber.swift @@ -0,0 +1,32 @@ +// +// NetworkStubber.swift +// + +import OHHTTPStubs + +protocol RequestConfigurationStubable { + + var sampleData: Data { get } + var path: String { get } +} + +enum NetworkStubber { + + static func removeAllStubs() { + HTTPStubs.removeAllStubs() + } + + static func stub( + _ request: RequestConfigurationStubable, + data: Data? = nil, + statusCode: Int32 = 200 + ) { + OHHTTPStubs.stub(condition: isPath(request.path)) { _ in + HTTPStubsResponse( + data: data ?? request.sampleData, + statusCode: statusCode, + headers: nil + ) + } + } +}