Skip to content

Commit dc0a702

Browse files
authored
Merge pull request #15 from sgr-ksmt/work/combine_extension
2 parents 2b2f699 + 309974e commit dc0a702

File tree

7 files changed

+382
-99
lines changed

7 files changed

+382
-99
lines changed

Lobster.xcodeproj/project.pbxproj

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
16FCE999223CE14A00F6D643 /* Lobster.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 163143FF1FA8BE8600D25996 /* Lobster.framework */; };
2323
16FCE9A4223CE2F400F6D643 /* FirebaseSetupHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16FCE9A3223CE2F400F6D643 /* FirebaseSetupHandler.swift */; };
2424
3531D90E61A46EE45DFAAFD6 /* Pods_LobsterTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C41C95928D6368D180C45B2E /* Pods_LobsterTests.framework */; };
25+
3A75BD8A24E045FA00ADBBAB /* Lobster+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A75BD8924E045FA00ADBBAB /* Lobster+Combine.swift */; };
26+
3A75BD8C24E0514500ADBBAB /* LobsterTests+Combine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A75BD8B24E0514500ADBBAB /* LobsterTests+Combine.swift */; };
27+
3A75BD8E24E0529800ADBBAB /* Definitions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A75BD8D24E0529800ADBBAB /* Definitions.swift */; };
2528
C446D99F0AB2B1B651481608 /* Pods_Lobster.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7094F96770D14C9622820F42 /* Pods_Lobster.framework */; };
2629
C461801624DBCEFE0061A5E4 /* UserDefault+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = C461801524DBCEFE0061A5E4 /* UserDefault+Ex.swift */; };
2730
C4A2602B24D81D54005A3FB7 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4A2602A24D81D54005A3FB7 /* AppDelegate.swift */; };
@@ -70,6 +73,9 @@
7073
16FCE998223CE14A00F6D643 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7174
16FCE9A3223CE2F400F6D643 /* FirebaseSetupHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirebaseSetupHandler.swift; sourceTree = "<group>"; };
7275
2FFEEC768519AD92F404C651 /* Pods-Lobster.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Lobster.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Lobster/Pods-Lobster.debug.xcconfig"; sourceTree = "<group>"; };
76+
3A75BD8924E045FA00ADBBAB /* Lobster+Combine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Lobster+Combine.swift"; sourceTree = "<group>"; };
77+
3A75BD8B24E0514500ADBBAB /* LobsterTests+Combine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "LobsterTests+Combine.swift"; sourceTree = "<group>"; };
78+
3A75BD8D24E0529800ADBBAB /* Definitions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Definitions.swift; sourceTree = "<group>"; };
7379
6F586FBD5180A54BFE0C53FA /* Pods-LobsterTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-LobsterTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-LobsterTests/Pods-LobsterTests.release.xcconfig"; sourceTree = "<group>"; };
7480
7094F96770D14C9622820F42 /* Pods_Lobster.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Lobster.framework; sourceTree = BUILT_PRODUCTS_DIR; };
7581
B5B16D1323062E1020502A3F /* Pods-Lobster.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Lobster.release.xcconfig"; path = "Pods/Target Support Files/Pods-Lobster/Pods-Lobster.release.xcconfig"; sourceTree = "<group>"; };
@@ -149,6 +155,7 @@
149155
1631440A1FA8BE9700D25996 /* Sources */ = {
150156
isa = PBXGroup;
151157
children = (
158+
3A75BD8824E045F000ADBBAB /* Combine */,
152159
3A75BD8324E0357A00ADBBAB /* Core */,
153160
);
154161
path = Sources;
@@ -167,9 +174,11 @@
167174
isa = PBXGroup;
168175
children = (
169176
16FCE996223CE14A00F6D643 /* LobsterTests.swift */,
177+
3A75BD8B24E0514500ADBBAB /* LobsterTests+Combine.swift */,
170178
C4A2604024D81EC5005A3FB7 /* GoogleService-Info.plist */,
171179
16FCE998223CE14A00F6D643 /* Info.plist */,
172180
16FCE9A3223CE2F400F6D643 /* FirebaseSetupHandler.swift */,
181+
3A75BD8D24E0529800ADBBAB /* Definitions.swift */,
173182
);
174183
path = LobsterTests;
175184
sourceTree = "<group>";
@@ -223,6 +232,14 @@
223232
path = Store;
224233
sourceTree = "<group>";
225234
};
235+
3A75BD8824E045F000ADBBAB /* Combine */ = {
236+
isa = PBXGroup;
237+
children = (
238+
3A75BD8924E045FA00ADBBAB /* Lobster+Combine.swift */,
239+
);
240+
path = Combine;
241+
sourceTree = "<group>";
242+
};
226243
C4A2602924D81D54005A3FB7 /* AppForTest */ = {
227244
isa = PBXGroup;
228245
children = (
@@ -457,6 +474,7 @@
457474
16FCE986223CBDBF00F6D643 /* ConfigBridge+BuiltIns.swift in Sources */,
458475
16FCE980223CB83500F6D643 /* StaleValueStore.swift in Sources */,
459476
16FCE98B223CC7E000F6D643 /* ConfigSerializable+BuiltIns.swift in Sources */,
477+
3A75BD8A24E045FA00ADBBAB /* Lobster+Combine.swift in Sources */,
460478
162860CA1FAA353A003D85A6 /* UIColor+Ex.swift in Sources */,
461479
16FCE989223CC42800F6D643 /* DefaultStore.swift in Sources */,
462480
16FCE984223CBC8A00F6D643 /* ConfigBridge.swift in Sources */,
@@ -468,6 +486,8 @@
468486
isa = PBXSourcesBuildPhase;
469487
buildActionMask = 2147483647;
470488
files = (
489+
3A75BD8E24E0529800ADBBAB /* Definitions.swift in Sources */,
490+
3A75BD8C24E0514500ADBBAB /* LobsterTests+Combine.swift in Sources */,
471491
16FCE997223CE14A00F6D643 /* LobsterTests.swift in Sources */,
472492
16FCE9A4223CE2F400F6D643 /* FirebaseSetupHandler.swift in Sources */,
473493
);

LobsterTests/Definitions.swift

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//
2+
// Definitions.swift
3+
// LobsterTests
4+
//
5+
// Created by Suguru Kishimoto on 2020/08/10.
6+
// Copyright © 2020 Suguru Kishimoto. All rights reserved.
7+
//
8+
9+
import XCTest
10+
@testable import Lobster
11+
12+
enum Direction: Int, ConfigSerializable {
13+
case unknown = 0, forward, back, left, right
14+
}
15+
16+
enum NetWork: String, ConfigSerializable {
17+
case unknown, LTE, wifi
18+
init(rawValue: String) {
19+
switch rawValue.uppercased() {
20+
case "LTE":
21+
self = .LTE
22+
case "WIFI":
23+
self = .wifi
24+
default:
25+
self = .unknown
26+
}
27+
}
28+
}
29+
30+
struct Settings: Decodable, ConfigSerializable, Equatable {
31+
let flag: Bool
32+
let minimumVersion: String
33+
}
34+
35+
struct Person: Codable, ConfigSerializable, Equatable {
36+
let name: String
37+
let age: Int
38+
}
39+
40+
class MockStaleValueStore: StaleValueStore {
41+
var isStaled: Bool = false
42+
}
43+
44+
extension ConfigKeys {
45+
static let text = ConfigKey<String>("text")
46+
static let textOptional = ConfigKey<String?>("text_optional")
47+
48+
static let price = ConfigKey<Int>("price")
49+
static let priceOptional = ConfigKey<Int?>("price_optional")
50+
51+
static let meter = ConfigKey<Double>("meter")
52+
static let meterOptional = ConfigKey<Double?>("meter_optional")
53+
54+
static let alpha = ConfigKey<Float>("alpha")
55+
static let alphaOptional = ConfigKey<Float?>("alpha_optional")
56+
57+
static let flag = ConfigKey<Bool>("flag")
58+
static let flagOptional = ConfigKey<Bool?>("flag_optional")
59+
60+
static let url = ConfigKey<URL>("url")
61+
static let urlOptional = ConfigKey<URL?>("url_optional")
62+
63+
static let bgColor = ConfigKey<UIColor>("bg_color")
64+
static let bgColorOptional = ConfigKey<UIColor?>("bg_color_optional")
65+
66+
static let direction = ConfigKey<Direction>("direction")
67+
static let directionOptional = ConfigKey<Direction?>("direction_optional")
68+
69+
static let network = ConfigKey<NetWork>("network")
70+
static let networkOptional = ConfigKey<NetWork?>("network_optional")
71+
72+
static let settings = ConfigKey<Settings>("settings")
73+
static let settingsOptional = ConfigKey<Settings?>("settings_optional")
74+
75+
static let person = ConfigKey<Person>("person")
76+
static let personOptional = ConfigKey<Person?>("person_optional")
77+
78+
static let names = ConfigKey<[String]>("names")
79+
static let namesOptional = ConfigKey<[String]?>("names_optional")
80+
81+
static let scores = ConfigKey<[Int]>("scores")
82+
static let scoresOptional = ConfigKey<[Int]?>("score_optional")
83+
84+
static let directions = ConfigKey<[Direction]>("directions")
85+
static let directionsOptional = ConfigKey<[Direction]?>("directions_optional")
86+
87+
static let persons = ConfigKey<[Person]>("persons")
88+
static let personsOptional = ConfigKey<[Person]?>("persons_optional")
89+
}
90+
91+
extension ConfigKeys {
92+
static let title = ConfigKey<String>("title")
93+
static let titleOptional = ConfigKey<String?>("title_optional")
94+
static let count = ConfigKey<Int>("count")
95+
static let friendNames = ConfigKey<[String]>("friend_names")
96+
static let mike = ConfigKey<Person>("mike")
97+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//
2+
// LobsterTests+Combine.swift
3+
// LobsterTests
4+
//
5+
// Created by Suguru Kishimoto on 2020/08/10.
6+
// Copyright © 2020 Suguru Kishimoto. All rights reserved.
7+
//
8+
9+
import XCTest
10+
@testable import Lobster
11+
import Firebase
12+
import Combine
13+
14+
@available(iOS 13.0, *)
15+
class Lobster_Combine_Tests: XCTestCase {
16+
17+
override func setUp() {
18+
_ = FirebaseSetupHandler.handler
19+
Lobster.shared.clearDefaults()
20+
Lobster.shared.debugMode = true
21+
Lobster.shared.fetchExpirationDuration = 0
22+
}
23+
24+
override func tearDown() {
25+
Lobster.shared.clearDefaults()
26+
}
27+
28+
func testFetched() {
29+
let exp = expectation(description: "test fetched")
30+
31+
let cancellable = Lobster.shared.combine.fetched().sink(receiveCompletion: { _ in }) { _ in
32+
exp.fulfill()
33+
}
34+
35+
Lobster.shared.fetch()
36+
37+
wait(for: [exp], timeout: 5.0)
38+
cancellable.cancel()
39+
}
40+
41+
func testFetchedTwice() {
42+
let exp = expectation(description: "test fetched twice")
43+
exp.expectedFulfillmentCount = 2
44+
45+
let cancellable = Lobster.shared.combine.fetched().sink(receiveCompletion: { _ in }) { _ in
46+
exp.fulfill()
47+
}
48+
49+
Lobster.shared.fetch { _ in
50+
Lobster.shared.fetch()
51+
}
52+
53+
wait(for: [exp], timeout: 10.0)
54+
cancellable.cancel()
55+
}
56+
57+
func testFetchedWithCancel() {
58+
let exp = expectation(description: "test fetched with cancel")
59+
exp.expectedFulfillmentCount = 2
60+
exp.isInverted = true
61+
62+
let cancellable = Lobster.shared.combine.fetched().sink(receiveCompletion: { _ in }) { _ in
63+
exp.fulfill()
64+
}
65+
66+
Lobster.shared.fetch { _ in
67+
cancellable.cancel()
68+
Lobster.shared.fetch()
69+
}
70+
wait(for: [exp], timeout: 5.0)
71+
}
72+
73+
74+
func testFetchedString() {
75+
let exp = expectation(description: "test fetched string")
76+
77+
let cancellable = Lobster.shared.combine.fetched(.title).sink(receiveCompletion: { _ in }) { title in
78+
XCTAssertEqual(title, "abc")
79+
exp.fulfill()
80+
}
81+
82+
Lobster.shared.fetch()
83+
84+
wait(for: [exp], timeout: 5.0)
85+
cancellable.cancel()
86+
}
87+
88+
func testFetchedOptionalString() {
89+
let exp = expectation(description: "test fetched optional string")
90+
91+
let cancellable = Lobster.shared.combine.fetched(.titleOptional).sink(receiveCompletion: { _ in }) { title in
92+
XCTAssertEqual(title, "def")
93+
exp.fulfill()
94+
}
95+
96+
Lobster.shared.fetch()
97+
98+
wait(for: [exp], timeout: 5.0)
99+
cancellable.cancel()
100+
}
101+
}

LobsterTests/LobsterTests.swift

Lines changed: 1 addition & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -10,92 +10,6 @@ import XCTest
1010
@testable import Lobster
1111
import Firebase
1212

13-
enum Direction: Int, ConfigSerializable {
14-
case unknown = 0, forward, back, left, right
15-
}
16-
17-
enum NetWork: String, ConfigSerializable {
18-
case unknown, LTE, wifi
19-
init(rawValue: String) {
20-
switch rawValue.uppercased() {
21-
case "LTE":
22-
self = .LTE
23-
case "WIFI":
24-
self = .wifi
25-
default:
26-
self = .unknown
27-
}
28-
}
29-
}
30-
31-
struct Settings: Decodable, ConfigSerializable, Equatable {
32-
let flag: Bool
33-
let minimumVersion: String
34-
}
35-
36-
struct Person: Codable, ConfigSerializable, Equatable {
37-
let name: String
38-
let age: Int
39-
}
40-
41-
class MockStaleValueStore: StaleValueStore {
42-
var isStaled: Bool = false
43-
}
44-
45-
extension ConfigKeys {
46-
static let text = ConfigKey<String>("text")
47-
static let textOptional = ConfigKey<String?>("text_optional")
48-
49-
static let price = ConfigKey<Int>("price")
50-
static let priceOptional = ConfigKey<Int?>("price_optional")
51-
52-
static let meter = ConfigKey<Double>("meter")
53-
static let meterOptional = ConfigKey<Double?>("meter_optional")
54-
55-
static let alpha = ConfigKey<Float>("alpha")
56-
static let alphaOptional = ConfigKey<Float?>("alpha_optional")
57-
58-
static let flag = ConfigKey<Bool>("flag")
59-
static let flagOptional = ConfigKey<Bool?>("flag_optional")
60-
61-
static let url = ConfigKey<URL>("url")
62-
static let urlOptional = ConfigKey<URL?>("url_optional")
63-
64-
static let bgColor = ConfigKey<UIColor>("bg_color")
65-
static let bgColorOptional = ConfigKey<UIColor?>("bg_color_optional")
66-
67-
static let direction = ConfigKey<Direction>("direction")
68-
static let directionOptional = ConfigKey<Direction?>("direction_optional")
69-
70-
static let network = ConfigKey<NetWork>("network")
71-
static let networkOptional = ConfigKey<NetWork?>("network_optional")
72-
73-
static let settings = ConfigKey<Settings>("settings")
74-
static let settingsOptional = ConfigKey<Settings?>("settings_optional")
75-
76-
static let person = ConfigKey<Person>("person")
77-
static let personOptional = ConfigKey<Person?>("person_optional")
78-
79-
static let names = ConfigKey<[String]>("names")
80-
static let namesOptional = ConfigKey<[String]?>("names_optional")
81-
82-
static let scores = ConfigKey<[Int]>("scores")
83-
static let scoresOptional = ConfigKey<[Int]?>("score_optional")
84-
85-
static let directions = ConfigKey<[Direction]>("directions")
86-
static let directionsOptional = ConfigKey<[Direction]?>("directions_optional")
87-
88-
static let persons = ConfigKey<[Person]>("persons")
89-
static let personsOptional = ConfigKey<[Person]?>("persons_optional")
90-
}
91-
92-
extension ConfigKeys {
93-
static let title = ConfigKey<String>("title")
94-
static let count = ConfigKey<Int>("count")
95-
static let friendNames = ConfigKey<[String]>("friend_names")
96-
static let mike = ConfigKey<Person>("mike")
97-
}
98-
9913
class LobsterTests: XCTestCase {
10014

10115
override func setUp() {
@@ -461,6 +375,7 @@ class LobsterTests: XCTestCase {
461375
Lobster.shared.fetchExpirationDuration = 0
462376
Lobster.shared.fetch { error in
463377
XCTAssertEqual(Lobster.shared[.title], "abc")
378+
XCTAssertEqual(Lobster.shared[.titleOptional], "def")
464379
XCTAssertEqual(Lobster.shared[default: .title], "xxx")
465380
XCTAssertEqual(Lobster.shared[.count], 1234)
466381
XCTAssertEqual(Lobster.shared[default: .count], 1)

0 commit comments

Comments
 (0)