Last active
July 24, 2020 01:14
Star
You must be signed in to star a gist
A container for a resource requested from the backend
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright © 2019 Alexey Naumov. MIT License | |
import Foundation | |
enum Loadable<Value> { | |
case notRequested | |
case isLoading(prevValue: Value?) | |
case loaded(Value) | |
case failed(Error) | |
} | |
extension Loadable { | |
var value: Value? { | |
switch self { | |
case .notRequested, .failed: return nil | |
case let .loaded(value): return value | |
case let .isLoading(value): return value | |
} | |
} | |
var error: Error? { | |
switch self { | |
case let .failed(error): return error | |
default: return nil | |
} | |
} | |
var isLoading: Bool { | |
switch self { | |
case .isLoading: return true | |
default: return false | |
} | |
} | |
var isLoaded: Bool { | |
switch self { | |
case .loaded: return true | |
default: return false | |
} | |
} | |
var isFailed: Bool { | |
switch self { | |
case .failed: return true | |
default: return false | |
} | |
} | |
} | |
extension Loadable: Equatable where Value: Equatable { | |
static func == (lhs: Loadable<Value>, rhs: Loadable<Value>) -> Bool { | |
switch (lhs, rhs) { | |
case (.notRequested, .notRequested): | |
return true | |
case let (.isLoading(lhsPrev), .isLoading(rhsPrev)): | |
return lhsPrev == rhsPrev | |
case let (.loaded(lhsValue), .loaded(rhsValue)): | |
return lhsValue == rhsValue | |
case let (.failed(lhsError), .failed(rhsError)): | |
return lhsError.localizedDescription == rhsError.localizedDescription | |
default: return false | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright © 2019 Alexey Naumov. MIT License | |
import XCTest | |
@testable import AppName | |
class LoadableTests: XCTestCase { | |
func testEquality() { | |
let possibleValues: [Loadable<Int>] = [ | |
.notRequested, | |
.isLoading(prevValue: nil), | |
.isLoading(prevValue: 9), | |
.loaded(5), | |
.loaded(6), | |
.failed(NSError(domain: "", code: 0, userInfo: nil)) | |
] | |
possibleValues.enumerated().forEach { (index1, value1) in | |
possibleValues.enumerated().forEach { (index2, value2) in | |
if index1 == index2 { | |
XCTAssertEqual(value1, value2) | |
} else { | |
XCTAssertNotEqual(value1, value2) | |
} | |
} | |
} | |
} | |
func testHelpers() { | |
let notRequested = Loadable<Int>.notRequested | |
let loadingNil = Loadable<Int>.isLoading(prevValue: nil) | |
let loadingValue = Loadable<Int>.isLoading(prevValue: 9) | |
let loaded = Loadable<Int>.loaded(5) | |
let failedErrValue = Loadable<Int>.failed(NSError(domain: "", code: 0, userInfo: nil)) | |
[notRequested, loadingNil].forEach { | |
XCTAssertNil($0.value) | |
} | |
[loadingValue, loaded].forEach { | |
XCTAssertNotNil($0.value) | |
} | |
[notRequested, loadingNil, loadingValue, loaded].forEach { | |
XCTAssertNil($0.error) | |
} | |
XCTAssertNotNil(failedErrValue.error) | |
XCTAssertTrue(loadingNil.isLoading) | |
XCTAssertTrue(loaded.isLoaded) | |
XCTAssertFalse(notRequested.isLoading) | |
XCTAssertFalse(loadingValue.isLoaded) | |
XCTAssertFalse(loaded.isFailed) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment