Skip to content

Commit

Permalink
added addParamsAction()
Browse files Browse the repository at this point in the history
  • Loading branch information
gavrya committed Apr 20, 2020
1 parent 78f342d commit b0ede00
Show file tree
Hide file tree
Showing 5 changed files with 575 additions and 321 deletions.
18 changes: 18 additions & 0 deletions src/reduxHotModule.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ class ReduxHotModule {
addAction(this.actionsRepo, name, { isParam: true, defaultValue })
}

addParamsAction(name, defaultValue = {}) {
addAction(this.actionsRepo, name, {
isParams: true,
defaultValue,
keys: Object.keys(defaultValue)
})
}

addEventAction(name, defaultValue = null) {
addAction(this.actionsRepo, name, { isEvent: true, defaultValue })
}
Expand All @@ -24,6 +32,7 @@ class ReduxHotModule {
const types = {}
const actions = {}
const paramTypes = {}
const paramsTypes = {}
const resetTypes = {}
const defaultState = {}
const namespace = `@@${this.module}`
Expand All @@ -46,6 +55,9 @@ class ReduxHotModule {
actions[actionName] = (value = defaultValue) => ({ type, payload: { [name]: value } })
defaultState[name] = defaultValue
paramTypes[type] = meta
} else if (meta.isParams) {
actions[actionName] = (value = {}) => ({ type, payload: { ...defaultValue, ...value } })
paramsTypes[type] = meta
} else if (meta.isEvent) {
actions[actionName] = (value = defaultValue) => ({ type, payload: value })
} else {
Expand All @@ -67,6 +79,12 @@ class ReduxHotModule {
return { ...state, ...action.payload }
}

if (hasOwnProp(paramsTypes, type)) {
const { keys } = paramsTypes[type]

return mergeProps(state, action.payload, keys)
}

if (hasOwnProp(resetTypes, type)) {
const { keys } = resetTypes[type]

Expand Down
100 changes: 100 additions & 0 deletions tests/reduxHotModule/actions/paramsActions.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { ReduxHotModule } from '../../../src/reduxHotModule'

jest.mock('react-redux', () => ({
connect: jest.fn((mapStateToProps, mapDispatchToProps) => (component) => component)
}))

describe('test params actions', () => {
beforeEach(() => {
jest.clearAllMocks()
})

test('should have expected name', () => {
const ml = new ReduxHotModule('moduleName')

ml.addParamsAction('ready', {})

const { actions } = ml.create()

expect(typeof actions).toBe('object')

const actionNames = Object.keys(actions)

expect(actionNames).toHaveLength(1)
expect(actionNames).toContain('readyAction')
})

test('should return redux action with default value', () => {
const ml = new ReduxHotModule('moduleName')

const defaultValue = {}

ml.addParamsAction('ready', defaultValue)

const { actions } = ml.create()

expect(Object.keys(actions)).toHaveLength(1)

const { readyAction } = actions

expect(typeof readyAction).toBe('function')

const reduxAction = readyAction()
const expected = {
type: '@@moduleName/READY',
payload: defaultValue
}

expect(typeof reduxAction).toBe('object')
expect(reduxAction).toStrictEqual(expected)
expect(reduxAction.payload).not.toBe(defaultValue)
})

test('should return redux action with provided value', () => {
const ml = new ReduxHotModule('moduleName')

ml.addParamsAction('ready', { a: 'a', b: 'b' })

const { actions } = ml.create()

expect(Object.keys(actions)).toHaveLength(1)

const { readyAction } = actions

expect(typeof readyAction).toBe('function')

const value = { b: 'new b' }
const reduxAction = readyAction(value)
const expected = {
type: '@@moduleName/READY',
payload: { a: 'a', b: 'new b' }
}

expect(typeof reduxAction).toBe('object')
expect(reduxAction).toStrictEqual(expected)
expect(reduxAction.payload).not.toBe(value)
})

test('should return redux action with empty object value if action added without default value', () => {
const ml = new ReduxHotModule('moduleName')

ml.addParamsAction('ready')

const { actions } = ml.create()

expect(Object.keys(actions)).toHaveLength(1)

const { readyAction } = actions

expect(typeof readyAction).toBe('function')

const reduxAction = readyAction()
const expected = {
type: '@@moduleName/READY',
payload: {}
}

expect(typeof reduxAction).toBe('object')
expect(reduxAction).toStrictEqual(expected)
})
})
61 changes: 61 additions & 0 deletions tests/reduxHotModule/reducer/paramsReducer.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { ReduxHotModule } from '../../../src/reduxHotModule'

jest.mock('react-redux', () => ({
connect: jest.fn((mapStateToProps, mapDispatchToProps) => (component) => component)
}))

describe('test params reducer', () => {
beforeEach(() => {
jest.clearAllMocks()
})

test('should set default values when action value is not provided', () => {
const ml = new ReduxHotModule('moduleName')
const defaultValue = { a: 'new a', b: 'bew b' }

ml.addParamAction('a', 'a')
ml.addParamAction('b', 'b')
ml.addParamAction('c', 'c')

ml.addParamsAction('items', defaultValue)

const { actions, reducer, initialState } = ml.create()

expect(typeof actions).toBe('object')
expect(typeof reducer).toBe('function')
expect(typeof initialState).toBe('object')
expect(initialState).toStrictEqual({ a: 'a', b: 'b', c: 'c' })

const { itemsAction } = actions
const nextState = reducer(initialState, itemsAction())

expect(nextState).not.toBe(initialState)
expect(nextState).toStrictEqual({ a: 'new a', b: 'bew b', c: 'c' })
})

test('should set provided value when action value is provided', () => {
const ml = new ReduxHotModule('moduleName')

const defaultValue = { a: 'new a', b: 'new b' }

ml.addParamAction('a', 'a')
ml.addParamAction('b', 'b')
ml.addParamAction('c', 'c')

ml.addParamsAction('items', defaultValue)

const { actions, reducer, initialState } = ml.create()

expect(typeof actions).toBe('object')
expect(typeof reducer).toBe('function')
expect(typeof initialState).toBe('object')
expect(initialState).toStrictEqual({ a: 'a', b: 'b', c: 'c' })

const { itemsAction } = actions
const value = { b: 'bbb' }
const nextState = reducer(initialState, itemsAction(value))

expect(nextState).not.toBe(initialState)
expect(nextState).toStrictEqual({ a: 'new a', b: 'bbb', c: 'c' })
})
})
10 changes: 8 additions & 2 deletions tests/reduxHotModule/types.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ describe('test types', () => {
test('should return expected types', () => {
const ml = new ReduxHotModule('moduleName')

ml.addParamAction('isLoading', false)
ml.addParamAction('isLoading', true)
ml.addParamAction('data', [])

ml.addParamsAction('dataReady', {
isLoading: false,
data: [1, 2, 3]
})

ml.addEventAction('loadEvent')
ml.addEventAction('loadedEvent')

Expand All @@ -26,13 +31,14 @@ describe('test types', () => {
const expectedTypes = {
MODULE_NAME_IS_LOADING: '@@moduleName/IS_LOADING',
MODULE_NAME_DATA: '@@moduleName/DATA',
MODULE_NAME_DATA_READY: '@@moduleName/DATA_READY',
MODULE_NAME_LOAD_EVENT: '@@moduleName/LOAD_EVENT',
MODULE_NAME_LOADED_EVENT: '@@moduleName/LOADED_EVENT',
MODULE_NAME_RESET: '@@moduleName/RESET',
MODULE_NAME_RESET_ALL: '@@moduleName/RESET_ALL'
}

expect(Object.keys(types)).toHaveLength(6)
expect(Object.keys(types)).toHaveLength(7)
expect(types).toStrictEqual(expectedTypes)
})

Expand Down
Loading

0 comments on commit b0ede00

Please sign in to comment.