Skip to content

Commit

Permalink
Merge d3dd302 into 53f0128
Browse files Browse the repository at this point in the history
  • Loading branch information
Oni-zerone committed Feb 24, 2019
2 parents 53f0128 + d3dd302 commit a77421f
Show file tree
Hide file tree
Showing 14 changed files with 296 additions and 19 deletions.
26 changes: 21 additions & 5 deletions Example/Pods/Pods.xcodeproj/project.pbxproj

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions Example/PunkAPI.xcodeproj/project.pbxproj
Expand Up @@ -15,6 +15,10 @@
607FACE01AFB9204008FA782 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 607FACDE1AFB9204008FA782 /* LaunchScreen.xib */; };
9767CBF7221993F900E684C4 /* BeerParsingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9767CBF6221993F800E684C4 /* BeerParsingTests.swift */; };
9767CBFA2219958F00E684C4 /* BeerStubs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9767CBF82219958800E684C4 /* BeerStubs.swift */; };
9767CC092222B63700E684C4 /* URLBuildTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9767CC072222B60F00E684C4 /* URLBuildTests.swift */; };
9767CC0B2222BB1E00E684C4 /* MockSession.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9767CC0A2222BB1E00E684C4 /* MockSession.swift */; };
9767CC0D2222BDD000E684C4 /* BeerRequestTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9767CC0C2222BDD000E684C4 /* BeerRequestTests.swift */; };
9767CC0F2223550E00E684C4 /* ConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9767CC0E2223550E00E684C4 /* ConfigurationTests.swift */; };
EBB1B4D6901624C6A90359CA /* Pods_PunkAPI_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 46341D8F014E1940E53D4F02 /* Pods_PunkAPI_Tests.framework */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -45,6 +49,10 @@
613B14F018C28CF1557EC3D5 /* Pods-PunkAPI_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PunkAPI_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PunkAPI_Tests/Pods-PunkAPI_Tests.debug.xcconfig"; sourceTree = "<group>"; };
9767CBF6221993F800E684C4 /* BeerParsingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BeerParsingTests.swift; sourceTree = "<group>"; };
9767CBF82219958800E684C4 /* BeerStubs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BeerStubs.swift; sourceTree = "<group>"; };
9767CC072222B60F00E684C4 /* URLBuildTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLBuildTests.swift; sourceTree = "<group>"; };
9767CC0A2222BB1E00E684C4 /* MockSession.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockSession.swift; sourceTree = "<group>"; };
9767CC0C2222BDD000E684C4 /* BeerRequestTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BeerRequestTests.swift; sourceTree = "<group>"; };
9767CC0E2223550E00E684C4 /* ConfigurationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfigurationTests.swift; sourceTree = "<group>"; };
9A440A355337DF96D159D208 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
A4CA42C1E1AE14F816574722 /* Pods-PunkAPI_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PunkAPI_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-PunkAPI_Example/Pods-PunkAPI_Example.debug.xcconfig"; sourceTree = "<group>"; };
E294694CD6DD5DA5A6B471F1 /* Pods-PunkAPI_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PunkAPI_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-PunkAPI_Example/Pods-PunkAPI_Example.release.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -126,6 +134,7 @@
607FACE81AFB9204008FA782 /* Tests */ = {
isa = PBXGroup;
children = (
9767CC032222B0C900E684C4 /* Request */,
9767CBF5221993DA00E684C4 /* BeerParsing */,
607FACE91AFB9204008FA782 /* Supporting Files */,
);
Expand Down Expand Up @@ -170,6 +179,17 @@
name = BeerParsing;
sourceTree = "<group>";
};
9767CC032222B0C900E684C4 /* Request */ = {
isa = PBXGroup;
children = (
9767CC072222B60F00E684C4 /* URLBuildTests.swift */,
9767CC0C2222BDD000E684C4 /* BeerRequestTests.swift */,
9767CC0A2222BB1E00E684C4 /* MockSession.swift */,
9767CC0E2223550E00E684C4 /* ConfigurationTests.swift */,
);
name = Request;
sourceTree = "<group>";
};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
Expand Down Expand Up @@ -373,8 +393,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9767CC0D2222BDD000E684C4 /* BeerRequestTests.swift in Sources */,
9767CBF7221993F900E684C4 /* BeerParsingTests.swift in Sources */,
9767CC0F2223550E00E684C4 /* ConfigurationTests.swift in Sources */,
9767CBFA2219958F00E684C4 /* BeerStubs.swift in Sources */,
9767CC0B2222BB1E00E684C4 /* MockSession.swift in Sources */,
9767CC092222B63700E684C4 /* URLBuildTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
2 changes: 1 addition & 1 deletion Example/PunkAPI/ViewController.swift
Expand Up @@ -21,7 +21,7 @@ class ViewController: UIViewController {

@IBAction func loadBeerAction(_ sender: Any) {

PunkAPI().get(BeerRequest(id: 6), queue: .main) { [weak self] beersResult in
PunkAPI().get(RandomBeerRequest(), queue: .main) { [weak self] beersResult in

guard let strongSelf = self else { return }
switch beersResult {
Expand Down
42 changes: 42 additions & 0 deletions Example/Tests/BeerRequestTests.swift
@@ -0,0 +1,42 @@
//
// BeerRequestTests.swift
// PunkAPI_Tests
//
// Created by Andrea Altea on 24/02/2019.
// Copyright © 2019 CocoaPods. All rights reserved.
//

import Foundation

import XCTest
@testable import PunkAPI

class BeerRequestTest: XCTestCase {

func testRandomBeerRequest() {

let request = RandomBeerRequest()
XCTAssert(request.path == "beers/random")
XCTAssert(request.parameters == nil)
}

func testBeerRequests() {

self.testBeerRequest(with: 1)
self.testBeerRequest(with: 2)
self.testBeerRequest(with: 3)
self.testBeerRequest(with: 4)
self.testBeerRequest(with: 5)
self.testBeerRequest(with: 6)
self.testBeerRequest(with: 10)
self.testBeerRequest(with: 1000)
self.testBeerRequest(with: 165)
}

func testBeerRequest(with id: Int) {

let request = BeerRequest(id: id)
XCTAssert(request.path == "beers/\(id)")
XCTAssert(request.parameters == nil)
}
}
27 changes: 27 additions & 0 deletions Example/Tests/ConfigurationTests.swift
@@ -0,0 +1,27 @@
//
// ConfigurationTests.swift
// PunkAPI_Tests
//
// Created by Andrea Altea on 24/02/2019.
// Copyright © 2019 CocoaPods. All rights reserved.
//

import XCTest
@testable import PunkAPI

class ConfigurationTests: XCTestCase {

func testConfigurationBuild() {

let baseURL = URL(string: "test://api.test.it/")!
let configuration = Configuration(sessionConfiguration: .ephemeral, baseURL: baseURL)

XCTAssert(configuration.baseURL == baseURL)
}

func testDefaultConfiguration() {

let configuration = Configuration.default
XCTAssert(configuration.baseURL.absoluteString == "https://api.punkapi.com/v2/")
}
}
65 changes: 65 additions & 0 deletions Example/Tests/MockSession.swift
@@ -0,0 +1,65 @@
//
// MockSession.swift
// PunkAPI_Tests
//
// Created by Andrea Altea on 24/02/2019.
// Copyright © 2019 CocoaPods. All rights reserved.
//

import Foundation

class MockURLSession: URLSession {

var urlCheckBlock: ((_ url: URL) -> Void)?

var responseConfig: (data: Data?, response: HTTPURLResponse?, error: Error?)?

override func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {

if let urlCheckBlock = self.urlCheckBlock {
urlCheckBlock(url)
}

return MockSessionDataTask(config: self.responseConfig, completionHandler: completionHandler)
}
}

class MockSessionDataTask: URLSessionDataTask {

enum DataError: String, ConvertibleError {

case notConfigured = "Not Configured"
}

var config: (data: Data?, response: HTTPURLResponse?, error: Error?)?

var completionHandler: (Data?, URLResponse?, Error?) -> Void

init(config: (data: Data?, response: HTTPURLResponse?, error: Error?)?, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) {

self.config = config
self.completionHandler = completionHandler
}

override func resume() {

guard let config = self.config else {

completionHandler(nil, nil, DataError.notConfigured)
return
}
completionHandler(config.data, config.response, config.error)
}
}

protocol ConvertibleError: Error {

var message: String { get }
}

extension ConvertibleError where Self: RawRepresentable, Self.RawValue == String{

var message: String {
return self.rawValue
}
}
57 changes: 57 additions & 0 deletions Example/Tests/URLBuildTests.swift
@@ -0,0 +1,57 @@
//
// URLBuildTests.swift
// PunkAPI_Example
//
// Created by Andrea Altea on 24/02/2019.
// Copyright © 2019 CocoaPods. All rights reserved.
//

import XCTest
@testable import PunkAPI

class URLBuildTests: XCTestCase {

var baseURL: URL!

override func setUp() {
super.setUp()

self.baseURL = URL(string: "https://api.test.it/v2")
}

func testBaseURLBuilding() {

let request = MockRequest(path: "beer/1", parameters: nil)
let url = self.baseURL.url(request: request)
XCTAssert(url?.absoluteString == "https://api.test.it/v2/beer/1")
}

func testWrongRelativePathURLBuilding() {

let request = MockRequest(path: "/beer/1", parameters: nil)
let url = self.baseURL.url(request: request)
XCTAssert(url?.absoluteString == "https://api.test.it/v2/beer/1")
}

func testParametersURLBuilding() {

let request = MockRequest(path: "/beer",
parameters: ["integer": 1, "string": "text", "object": NSNumber(value: 3)])
guard let url = self.baseURL.url(request: request) else {
return XCTFail("undefined url")
}
guard let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: true)?.queryItems else {
return XCTFail("undefined query")
}
XCTAssert(queryItems.count == 3)
XCTAssert(queryItems.contains(URLQueryItem(name: "integer", value: "1")))
XCTAssert(queryItems.contains(URLQueryItem(name: "string", value: "text")))
XCTAssert(queryItems.contains(URLQueryItem(name: "object", value: "3")))
}
}

struct MockRequest: Request {

var path: String
var parameters: [String : Any]? = nil
}
12 changes: 9 additions & 3 deletions PunkAPI/Classes/Configuration.swift
Expand Up @@ -11,11 +11,17 @@ public struct Configuration {

var session: URLSession

var baseComponent: URLComponents
var baseURL: URL

init(sessionConfiguration: URLSessionConfiguration) {
public init(sessionConfiguration: URLSessionConfiguration, baseURL: URL) {

self.session = URLSession(configuration: sessionConfiguration)
self.baseComponent = URLComponents(string: "https://api.punkapi.com/v2/")!
self.baseURL = baseURL
}
}

public extension Configuration {

public static let `default` = Configuration(sessionConfiguration: .default,
baseURL: URL(string: "https://api.punkapi.com/v2/")!)
}
12 changes: 3 additions & 9 deletions PunkAPI/Classes/PunkAPI.swift
Expand Up @@ -11,20 +11,14 @@ public class PunkAPI {

var configuration: Configuration

public init(sessionConfiguration: URLSessionConfiguration) {
public init(configuration: Configuration = .default) {

self.configuration = Configuration(sessionConfiguration: sessionConfiguration)
}

public convenience init() {
self.init(sessionConfiguration: .default)
self.configuration = configuration
}

public func get(_ request: Request, queue: DispatchQueue = .global(qos: .background), completion: @escaping (Result<[Beer]>) -> Void) {

var urlComponent = self.configuration.baseComponent
urlComponent.path += request.path
guard let url = urlComponent.url else {
guard let url = configuration.baseURL.url(request: request) else {
queue.async { completion(.failure(APIError.invalidURL)) }
return
}
Expand Down

0 comments on commit a77421f

Please sign in to comment.