Created
November 5, 2019 21:10
-
-
Save dustingetz/7cdcb182d4edc31ebf1c9f8eb1a41189 to your computer and use it in GitHub Desktop.
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
var Mocha = require('mocha') | |
var assert = require('assert') | |
var _ = require('lodash') | |
var mocha = new Mocha() | |
mocha.suite.emit('pre-require', this, 'solution', mocha) | |
describe('Test suite', function() { | |
it('should work', function() { | |
assert(true) | |
}) | |
it("can create a store", () => { | |
const store = createStore(state => state); | |
assert(typeof store.subscribe === "function"); | |
assert(typeof store.dispatch === "function"); | |
assert(typeof store.getState === "function"); | |
}); | |
it("initializes with initial state", () => { | |
const initialState = { foo: true, bar: false }; | |
const store = createStore((state, action) => state, initialState); | |
const state = store.getState(); | |
assert(Object.keys(state).length === 2); | |
assert(state.foo === true); | |
assert(state.bar === false); | |
}); | |
it("can dispatch actions", () => { | |
const reducer = (state, action) => { | |
if (action.type !== "SET_NAME") { | |
return state; | |
} | |
return { | |
...state, | |
name: action.payload | |
}; | |
}; | |
const store = createStore(reducer); | |
store.dispatch({ type: "FOO", payload: "bar" }); | |
assert(store.getState().name === undefined); | |
store.dispatch({ type: "SET_NAME", payload: "foo" }); | |
assert(store.getState().name === "foo"); | |
}); | |
it("can subscribe and unsubscribe", () => { | |
const reducer = (state, action) => { | |
if (action.type !== "SET_NAME") { | |
return state; | |
} | |
return { | |
...state, | |
name: action.payload | |
}; | |
}; | |
const store = createStore(reducer); | |
let name = undefined; | |
const unsubscribe = store.subscribe(state => { | |
name = state.name; | |
unsubscribe(); | |
}); | |
assert(name === undefined); | |
store.dispatch({ type: "SET_NAME", payload: "bar" }); | |
assert(name === "bar"); | |
assert(store.getState().name === "bar"); | |
store.dispatch({ type: "SET_NAME", payload: "baz" }); | |
assert(name === "bar"); | |
assert(store.getState().name === "baz"); | |
}); | |
it("can have multiple subscribers", () => { | |
const store = createStore(state => state); | |
let callCount1 = 0; | |
let callCount2 = 0; | |
let callCount3 = 0; | |
store.subscribe(() => { | |
callCount1++; | |
}) | |
const unsubscribe = store.subscribe(() => { | |
callCount2++; | |
unsubscribe(); | |
}) | |
store.subscribe(() => { | |
callCount3++; | |
}) | |
store.dispatch({ type: 'foo' }); | |
assert(callCount1 === 1); | |
assert(callCount2 === 1); | |
assert(callCount3 === 1); | |
store.dispatch({ type: 'foo' }); | |
assert(callCount1 === 2); | |
assert(callCount2 === 1); | |
assert(callCount3 === 2); | |
}); | |
it("initializes reducer", () => { | |
const initialState = { name: "foo" }; | |
const reducer = (state = initialState, action) => { | |
if (action.type !== "SET_NAME") { | |
return state; | |
} | |
return { | |
...state, | |
name: action.payload | |
}; | |
}; | |
const store = createStore(reducer); | |
assert(store.getState().name === "foo"); | |
}); | |
}) | |
class Store { | |
constructor (reducer, initialState) { | |
this.reducer = reducer; | |
this.state = initialState || reducer(undefined, {}) || {}; | |
this.subscribers = []; | |
} | |
subscribe(f) { | |
this.subscribers.push(f); | |
return () => { | |
this.subscribers = _.without(this.subscribers, f); | |
} | |
} | |
dispatch(action) { | |
let newState = this.reducer(this.state, action); | |
this.subscribers.forEach(f => f(newState)); | |
this.state = newState; | |
} | |
getState() { | |
return this.state; | |
} | |
} | |
function createStore (r, initialState) { | |
return new Store(r, initialState); | |
} | |
mocha.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment