Skip to content
This repository was archived by the owner on May 13, 2020. It is now read-only.

Commit 17deb96

Browse files
committed
Adapt UT to match Lenses and Mutators
1 parent 80e85d9 commit 17deb96

File tree

16 files changed

+179
-178
lines changed

16 files changed

+179
-178
lines changed

RxReduce.xcodeproj/project.pbxproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
/* Begin PBXBuildFile section */
1010
1A26CF05212BA111008A6D7B /* Lens.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A26CF04212BA111008A6D7B /* Lens.swift */; };
1111
1A26CF07212BA15D008A6D7B /* Mutator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A26CF06212BA15D008A6D7B /* Mutator.swift */; };
12-
1A2A7571208D4750009883BF /* RxReduce.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A2A7567208D474F009883BF /* RxReduce.framework */; };
1312
1A2A7576208D4750009883BF /* ActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A2A7575208D4750009883BF /* ActionTests.swift */; };
1413
1A2A7578208D4750009883BF /* RxReduce.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A2A756A208D4750009883BF /* RxReduce.h */; settings = {ATTRIBUTES = (Public, ); }; };
1514
1A2A7584208D50BC009883BF /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A2A7582208D50BC009883BF /* RxSwift.framework */; };
@@ -24,6 +23,8 @@
2423
1A708BAB20CF1F8000F30C9C /* Actions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A708BAA20CF1F8000F30C9C /* Actions.swift */; };
2524
1A708BAD20CF1FE100F30C9C /* States.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A708BAC20CF1FE100F30C9C /* States.swift */; };
2625
1A708BB020CF233600F30C9C /* Reducers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A708BAF20CF233600F30C9C /* Reducers.swift */; };
26+
1A7139792134E4A200903866 /* RxBlocking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A7139782134E4A200903866 /* RxBlocking.framework */; };
27+
1A71397A2134E4C400903866 /* RxBlocking.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A7139782134E4A200903866 /* RxBlocking.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
2728
/* End PBXBuildFile section */
2829

2930
/* Begin PBXContainerItemProxy section */
@@ -43,6 +44,7 @@
4344
dstPath = "";
4445
dstSubfolderSpec = 10;
4546
files = (
47+
1A71397A2134E4C400903866 /* RxBlocking.framework in CopyFiles */,
4648
1A708BA620CF1BFC00F30C9C /* RxCocoa.framework in CopyFiles */,
4749
1A708BA720CF1BFC00F30C9C /* RxSwift.framework in CopyFiles */,
4850
);
@@ -67,6 +69,7 @@
6769
1A708BAA20CF1F8000F30C9C /* Actions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actions.swift; sourceTree = "<group>"; };
6870
1A708BAC20CF1FE100F30C9C /* States.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = States.swift; sourceTree = "<group>"; };
6971
1A708BAF20CF233600F30C9C /* Reducers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reducers.swift; sourceTree = "<group>"; };
72+
1A7139782134E4A200903866 /* RxBlocking.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = RxBlocking.framework; path = Carthage/Build/iOS/RxBlocking.framework; sourceTree = "<group>"; };
7073
/* End PBXFileReference section */
7174

7275
/* Begin PBXFrameworksBuildPhase section */
@@ -83,7 +86,7 @@
8386
isa = PBXFrameworksBuildPhase;
8487
buildActionMask = 2147483647;
8588
files = (
86-
1A2A7571208D4750009883BF /* RxReduce.framework in Frameworks */,
89+
1A7139792134E4A200903866 /* RxBlocking.framework in Frameworks */,
8790
1A708BA420CF187300F30C9C /* RxSwift.framework in Frameworks */,
8891
1A708BA320CF187300F30C9C /* RxCocoa.framework in Frameworks */,
8992
);
@@ -138,6 +141,7 @@
138141
1A2A7581208D50BB009883BF /* Frameworks */ = {
139142
isa = PBXGroup;
140143
children = (
144+
1A7139782134E4A200903866 /* RxBlocking.framework */,
141145
1A2A7583208D50BC009883BF /* RxCocoa.framework */,
142146
1A2A7582208D50BC009883BF /* RxSwift.framework */,
143147
);

RxReduce/Lens.swift

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,18 @@
1010
public struct Lens<State, SubState> {
1111

1212
/// retrieves a Substate from a State
13-
public let get: (State) -> SubState
13+
let get: (State) -> SubState
1414

15-
/// Generates a new State based on an original State and on an original SubState
16-
public let set: (State, SubState) -> State
15+
/// Generates a new State based on an original State and on an original SubState
16+
let set: (State, SubState) -> State
17+
18+
/// Lens initializer
19+
///
20+
/// - Parameters:
21+
/// - get: the closure that allows to get a subState given a state
22+
/// - set: the closure that allows to mutate a state given a subState
23+
public init (get: @escaping (State) -> SubState, set: @escaping (State, SubState) -> State) {
24+
self.get = get
25+
self.set = set
26+
}
1727
}

RxReduce/Mutator.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,18 @@
99
/// A Mutator holds all the required tools to mutate a State's Substate and
1010
// generate a new State
1111
public struct Mutator<State, SubState> {
12+
13+
/// The functional Lens used to focus on a subState of a State (both for accessing and mutating)
1214
let lens: Lens<State, SubState>
15+
16+
/// The reducer function that allows to mutate a State according to an Action
1317
let reducer: (State, Action) -> SubState
1418

19+
public init(lens: Lens<State, SubState>, reducer: @escaping (State, Action) -> SubState) {
20+
self.lens = lens
21+
self.reducer = reducer
22+
}
23+
1524
/// Mutates a State according to an Action.
1625
/// It uses the defined lens and reducer to
1726
/// generate this mutation

RxReduceDemo/Cartfile.resolved

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
github "Alamofire/Alamofire" "4.7.2"
1+
github "Alamofire/Alamofire" "4.7.3"
22
github "Alamofire/AlamofireImage" "3.3.1"
3-
github "AliSoftware/Reusable" "4.0.2"
4-
github "ReactiveX/RxSwift" "4.1.2"
5-
github "twittemb/RxReduce" "c0ed1c4ed8d39b9a91c8bd106f4d8c4d46818b89"
3+
github "AliSoftware/Reusable" "4.0.3"
4+
github "ReactiveX/RxSwift" "4.2.0"
5+
github "twittemb/RxReduce" "80e85d94ce40413b7aa3cded92c0d7b4df33af01"

RxReduceDemo/RxReduceDemo.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
1A16F86B20C31E1400D5BE85 /* DiscoverTVResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A16F86820C31E1400D5BE85 /* DiscoverTVResponse.swift */; };
1313
1A16F86C20C31E1400D5BE85 /* DiscoverMovieResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A16F86920C31E1400D5BE85 /* DiscoverMovieResponse.swift */; };
1414
1A16F86D20C31E1400D5BE85 /* Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A16F86A20C31E1400D5BE85 /* Media.swift */; };
15+
1A74D063212E4A0400BAE637 /* AppLenses.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A74D062212E4A0400BAE637 /* AppLenses.swift */; };
1516
1AAA7E1B20952A7F00BED242 /* RxCocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A3BB49E2093A4F500B1E37F /* RxCocoa.framework */; };
1617
1AAA7E1C20952A7F00BED242 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A3BB4A02093A4F500B1E37F /* RxSwift.framework */; };
1718
1AAA7E1F20952BAD00BED242 /* Alamofire.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A3BB49D2093A4F500B1E37F /* Alamofire.framework */; };
@@ -47,6 +48,7 @@
4748
1A16F86820C31E1400D5BE85 /* DiscoverTVResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiscoverTVResponse.swift; sourceTree = "<group>"; };
4849
1A16F86920C31E1400D5BE85 /* DiscoverMovieResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiscoverMovieResponse.swift; sourceTree = "<group>"; };
4950
1A16F86A20C31E1400D5BE85 /* Media.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Media.swift; sourceTree = "<group>"; };
51+
1A74D062212E4A0400BAE637 /* AppLenses.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLenses.swift; sourceTree = "<group>"; };
5052
1AAA7E2320952BF900BED242 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
5153
1AAA7E2520952C3300BED242 /* AppActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppActions.swift; sourceTree = "<group>"; };
5254
1AAA7E272095305800BED242 /* AppReducers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppReducers.swift; sourceTree = "<group>"; };
@@ -121,6 +123,7 @@
121123
1AAA7E272095305800BED242 /* AppReducers.swift */,
122124
1AFFA38420B25C3400A0BB81 /* AppMiddlewares.swift */,
123125
1AAA7E2520952C3300BED242 /* AppActions.swift */,
126+
1A74D062212E4A0400BAE637 /* AppLenses.swift */,
124127
);
125128
path = State;
126129
sourceTree = "<group>";
@@ -343,6 +346,7 @@
343346
1A16F86C20C31E1400D5BE85 /* DiscoverMovieResponse.swift in Sources */,
344347
1AC102CC20C8DAF30083BB46 /* MovieListViewCell.swift in Sources */,
345348
4A3BB48420939F9000B1E37F /* AppDelegate.swift in Sources */,
349+
1A74D063212E4A0400BAE637 /* AppLenses.swift in Sources */,
346350
1AC102D620C99CA60083BB46 /* MovieDetailViewController.swift in Sources */,
347351
1AAA7E2620952C3300BED242 /* AppActions.swift in Sources */,
348352
1AFFA38520B25C3400A0BB81 /* AppMiddlewares.swift in Sources */,

RxReduceDemo/RxReduceDemo/AppDelegate.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,24 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
1717
var window: UIWindow?
1818

1919
let networkService: NetworkService = NetworkService(withBaseUrl: URL(string: "https://api.themoviedb.org/3/")!, andApiKey: "3afafd21270fe0414eb760a41f2620eb")
20-
let store = Store<AppState>(withReducers: [movieReducer], withMiddlewares: [loggingMiddleware])
20+
private lazy var store: Store<AppState> = {
21+
let store = Store<AppState>(withState: AppState(movieListState: .empty, movieDetailState: .empty))
22+
23+
let movieListMutator = Mutator<AppState, MovieListState>(lens: AppLenses.movieListLens, reducer: movieListReducer)
24+
let movieDetailMutator = Mutator<AppState, MovieDetailState>(lens: AppLenses.movieDetailLens, reducer: movieDetailReducer)
25+
26+
store.register(mutator: movieListMutator)
27+
store.register(mutator: movieDetailMutator)
28+
store.register(middleware: loggingMiddleware)
29+
30+
return store
31+
}()
32+
2133
lazy var dependencyContainer: DependencyContainer = {
2234
return DependencyContainer(withStore: self.store, withNetworkService: self.networkService)
2335
}()
2436

25-
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
37+
internal func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
2638

2739
guard let window = self.window else { return false }
2840

RxReduceDemo/RxReduceDemo/Features/MovieDetail/MovieDetailViewModel.swift

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,11 @@ final class MovieDetailViewModel: ViewModel, Injectable {
2424

2525
func loadMovieDetail () -> Driver<MovieDetailState> {
2626

27-
// build a synchronous action to pick the movie
28-
let loadMovieDetailAction = LoadMovieDetailAction(movieId: self.movieId)
29-
3027
// dispatch the synchronous Load Movie Detail action
31-
self.injectionContainer.store.dispatch(action: loadMovieDetailAction)
32-
33-
// listen for the store's state
34-
return self.injectionContainer.store.state { $0.movieDetailState }
28+
return self.injectionContainer
29+
.store
30+
.dispatch(action: MovieAction.loadMovie(movieId: self.movieId)) { $0.movieDetailState }
31+
.asDriver(onErrorJustReturn: MovieDetailState.empty)
3532
}
3633

3734
}

RxReduceDemo/RxReduceDemo/Features/MovieList/MovieListViewController.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,13 @@ final class MovieListViewController: UITableViewController, StoryboardBased, Vie
5252
case .loading:
5353
self.movies.removeAll()
5454
self.activityIndicator.isHidden = false
55-
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.none
55+
self.tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
5656
self.activityIndicator.startAnimating()
5757
case .loaded(let movies):
5858
self.movies = movies
5959
self.tableView.isHidden = false
6060
self.activityIndicator.stopAnimating()
61-
self.tableView.separatorStyle = UITableViewCellSeparatorStyle.singleLine
61+
self.tableView.separatorStyle = UITableViewCell.SeparatorStyle.singleLine
6262
self.tableView.reloadData()
6363
}
6464
}

RxReduceDemo/RxReduceDemo/Features/MovieList/MovieListViewModel.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@ final class MovieListViewModel: ViewModel, Injectable {
2626
.fetch(withRoute: Routes.discoverMovie)
2727
.asObservable()
2828
.map { $0.movies.filter {$0.backdropPath != nil } }
29-
.map { LoadMovieListAction.init(movies: $0) }
30-
.startWith(FetchMovieListAction())
29+
.map { MovieAction.loadMovies(movies: $0) }
30+
.startWith(MovieAction.startLoadingMovies)
3131

3232
// dispatch the asynchronous fetch action
33-
self.injectionContainer.store.dispatch(action: loadMovieAction)
34-
35-
// listen for the store's state
36-
return self.injectionContainer.store.state { $0.movieListState }
33+
return self.injectionContainer
34+
.store
35+
.dispatch(action: loadMovieAction) { $0.movieListState }
36+
.asDriver(onErrorJustReturn: .empty)
3737
}
3838
}

RxReduceDemo/RxReduceDemo/State/AppActions.swift

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,8 @@
99
import Foundation
1010
import RxReduce
1111

12-
struct FetchMovieListAction: Action {}
13-
14-
struct LoadMovieListAction: Action {
15-
let movies: [DiscoverMovieModel]
16-
}
17-
18-
struct LoadMovieDetailAction: Action {
19-
let movieId: Int
12+
enum MovieAction: Action {
13+
case startLoadingMovies
14+
case loadMovies (movies: [DiscoverMovieModel])
15+
case loadMovie (movieId: Int)
2016
}
21-

0 commit comments

Comments
 (0)