-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#000 okan add tests, clean up code and build scripts
- Loading branch information
okan.cetin
committed
Sep 13, 2016
1 parent
53bfc79
commit ef8453c
Showing
9 changed files
with
224 additions
and
74 deletions.
There are no files selected for viewing
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import { AsyncAction, ShowLoading, HideLoading } from './actionHelpers' | ||
|
||
|
||
const isAsyncAction = (action: AsyncAction | any): action is AsyncAction => { | ||
return action.resolve !== undefined && typeof action.resolve === "function"; | ||
} | ||
|
||
export const asyncMiddleware = <S>(store: Redux.MiddlewareAPI<S>) => (next: Redux.Dispatch<S>): Redux.Dispatch<S> => (action: Redux.Action) => { | ||
//Fix: Actions must be plain objects. | ||
action = _.merge({}, action); | ||
|
||
if (isAsyncAction(action)) { | ||
|
||
//First dispatch show loading action synchronously | ||
store.dispatch(new ShowLoading()); | ||
|
||
//Change state immediately and register async operations | ||
var nextState = next(action); | ||
|
||
//Lastly dispatch hide loading action asynchronously | ||
action.then(dispatch => { | ||
dispatch(new HideLoading()); | ||
}); | ||
|
||
//After original dispatch lifecycle, resolve dispatch in order to handle async operations | ||
setTimeout(() => { | ||
(<any>action).resolve(store.dispatch); | ||
}); | ||
return nextState; | ||
} | ||
return next(action); | ||
}; |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import 'mocha' | ||
import { expect } from 'chai' | ||
import { StoreBuilder } from './storeBuilder' | ||
import { ReducerBuilder } from './reducerBuilder' | ||
import { SyncAction, AsyncAction, Action, HideLoading, ShowLoading } from './actionHelpers' | ||
|
||
|
||
interface SampleState { | ||
isSet: boolean; | ||
} | ||
|
||
interface SampleStore { | ||
reducer: SampleState | ||
} | ||
|
||
@Action | ||
class SampleAction extends SyncAction { | ||
} | ||
|
||
@Action | ||
class SampleAsyncAction extends AsyncAction { | ||
} | ||
|
||
|
||
describe("Reducer", () => { | ||
|
||
describe("with inital state", () => { | ||
var reducer = new ReducerBuilder<SampleState>() | ||
.init({ isSet: true }) | ||
.build(); | ||
|
||
var store = new StoreBuilder<SampleStore>() | ||
.withReducersMap({ reducer }) | ||
.build(); | ||
|
||
it("should have correct value", () => { | ||
expect(store.getState().reducer.isSet).equal(true); | ||
}); | ||
}); | ||
|
||
describe("with sync action handler", () => { | ||
var reducer = new ReducerBuilder<SampleState>() | ||
.handle(SampleAction, (state: SampleState, action: SampleAction) => { | ||
state.isSet = true; | ||
return state; | ||
}) | ||
.build(); | ||
|
||
var store = new StoreBuilder<SampleStore>() | ||
.withReducersMap({ reducer }) | ||
.build(); | ||
|
||
store.dispatch(new SampleAction()); | ||
|
||
it("should be called on dispatch action", () => { | ||
expect(store.getState().reducer.isSet).equal(true); | ||
}); | ||
}); | ||
|
||
describe("with async action handler", () => { | ||
var dispatchedEvents: any[] = []; | ||
|
||
var reducer: Redux.Reducer<any> = (state: any = {}, action: Redux.Action) => { | ||
if (!action.type.startsWith("@@")) { | ||
dispatchedEvents.push(action.type); | ||
} | ||
return state; | ||
}; | ||
|
||
var store = new StoreBuilder<SampleStore>() | ||
.withReducersMap({ reducer }) | ||
.build(); | ||
|
||
before(done => { | ||
var action = new SampleAsyncAction(); | ||
store.dispatch(action); | ||
|
||
action.then(dispatch => { | ||
dispatch(new SampleAction()); | ||
done(); | ||
}) | ||
}) | ||
|
||
it("should be dispatched in correct order", () => { | ||
expect(dispatchedEvents).deep.equal([ | ||
ShowLoading.prototype.type, | ||
SampleAsyncAction.prototype.type, | ||
HideLoading.prototype.type, | ||
SampleAction.prototype.type | ||
]); | ||
}); | ||
}); | ||
|
||
}); |
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
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
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
Oops, something went wrong.