Skip to content

Commit

Permalink
rename slice to name, make required
Browse files Browse the repository at this point in the history
  • Loading branch information
phryneas committed Sep 22, 2019
1 parent 16e0686 commit c58aa2c
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 63 deletions.
16 changes: 8 additions & 8 deletions docs/api/createSlice.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ hide_title: true

# `createSlice`

A function that accepts an initial state, an object full of reducer functions, and optionally a "slice name",
A function that accepts an initial state, an object full of reducer functions, and a "slice name",
and automatically generates action creators and action types that correspond to the reducers and state.

## Parameters
Expand All @@ -20,8 +20,8 @@ function createSlice({
reducers: Object<string, ReducerFunction>
// The initial state for the reducer
initialState: any,
// An optional name, used in action types
slice?: string,
// A name, used in action types
name: string,
// An additional object of "case reducers". Keys should be other action types.
extraReducers?: Object<string, ReducerFunction>
})
Expand All @@ -44,9 +44,9 @@ state they are given.

The initial state value for this slice of state.

### `slice`
### `name`

An optional string name for this slice of state. Generated action type constants will use this as a prefix.
A string name for this slice of state. Generated action type constants will use this as a prefix.

### `extraReducers`

Expand All @@ -73,7 +73,7 @@ to force the TS compiler to accept the computed property.)

```ts
{
slice : string,
name : string,
reducer : ReducerFunction,
actions : Object<string, ActionCreator},
}
Expand Down Expand Up @@ -104,7 +104,7 @@ import { createSlice } from 'redux-starter-kit'
import { createStore, combineReducers } from 'redux'
const counter = createSlice({
slice: 'counter', // slice is optional, and could be blank ''
name: 'counter',
initialState: 0,
reducers: {
increment: state => state + 1,
Expand All @@ -114,7 +114,7 @@ const counter = createSlice({
})
const user = createSlice({
slice: 'user',
name: 'user',
initialState: { name: '', age: 20 },
reducers: {
setUserName: (state, action) => {
Expand Down
74 changes: 32 additions & 42 deletions src/createSlice.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,46 +2,35 @@ import { createSlice } from './createSlice'
import { createAction, PayloadAction } from './createAction'

describe('createSlice', () => {
describe('when slice is empty', () => {
const { actions, reducer } = createSlice({
reducers: {
increment: state => state + 1,
multiply: (state, action: PayloadAction<number>) =>
state * action.payload
},
initialState: 0
})

it('should create increment action', () => {
expect(actions.hasOwnProperty('increment')).toBe(true)
})

it('should create multiply action', () => {
expect(actions.hasOwnProperty('multiply')).toBe(true)
})

it('should have the correct action for increment', () => {
expect(actions.increment()).toEqual({
type: 'increment',
payload: undefined
})
})

it('should have the correct action for multiply', () => {
expect(actions.multiply(3)).toEqual({
type: 'multiply',
payload: 3
})
describe('when slice is undefined', () => {
it('should throw an error', () => {
expect(() =>
// @ts-ignore
createSlice({
reducers: {
increment: state => state + 1,
multiply: (state, action: PayloadAction<number>) =>
state * action.payload
},
initialState: 0
})
).toThrowError()
})
})

describe('when using reducer', () => {
it('should return the correct value from reducer with increment', () => {
expect(reducer(undefined, actions.increment())).toEqual(1)
})

it('should return the correct value from reducer with multiply', () => {
expect(reducer(2, actions.multiply(3))).toEqual(6)
})
describe('when slice is an empty string', () => {
it('should throw an error', () => {
expect(() =>
createSlice({
name: '',
reducers: {
increment: state => state + 1,
multiply: (state, action: PayloadAction<number>) =>
state * action.payload
},
initialState: 0
})
).toThrowError()
})
})

Expand All @@ -51,7 +40,7 @@ describe('createSlice', () => {
increment: state => state + 1
},
initialState: 0,
slice: 'cool'
name: 'cool'
})

it('should create increment action', () => {
Expand Down Expand Up @@ -80,7 +69,7 @@ describe('createSlice', () => {
}
},
initialState,
slice: 'user'
name: 'user'
})

it('should set the username', () => {
Expand All @@ -94,6 +83,7 @@ describe('createSlice', () => {
const addMore = createAction('ADD_MORE')

const { reducer } = createSlice({
name: 'test',
reducers: {
increment: state => state + 1,
multiply: (state, action) => state * action.payload
Expand All @@ -116,7 +106,7 @@ describe('createSlice', () => {
const prepare = jest.fn((payload, somethingElse) => ({ payload }))

const testSlice = createSlice({
slice: 'test',
name: 'test',
initialState: 0,
reducers: {
testReducer: {
Expand All @@ -137,7 +127,7 @@ describe('createSlice', () => {
const reducer = jest.fn()

const testSlice = createSlice({
slice: 'test',
name: 'test',
initialState: 0,
reducers: {
testReducer: {
Expand Down
19 changes: 11 additions & 8 deletions src/createSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export interface Slice<
/**
* The slice name.
*/
slice: string
name: string

/**
* The slice's reducer.
Expand All @@ -47,7 +47,7 @@ export interface CreateSliceOptions<
/**
* The slice's name. Used to namespace the generated action types.
*/
slice?: string
name: string

/**
* The initial state to be returned by the slice reducer.
Expand Down Expand Up @@ -140,12 +140,12 @@ type RestrictEnhancedReducersToMatchReducerAndPrepare<
> = { reducers: SliceCaseReducersCheck<S, NoInfer<CR>> }

function getType(slice: string, actionKey: string): string {
return slice ? `${slice}/${actionKey}` : actionKey
return `${slice}/${actionKey}`
}

/**
* A function that accepts an initial state, an object full of reducer
* functions, and optionally a "slice name", and automatically generates
* functions, and a "slice name", and automatically generates
* action creators and action types that correspond to the
* reducers and state.
*
Expand All @@ -166,14 +166,17 @@ export function createSlice<
>(
options: CreateSliceOptions<State, CaseReducers>
): Slice<State, CaseReducerActions<CaseReducers>> {
const { slice = '', initialState } = options
const { name, initialState } = options
if (!name) {
throw new Error('`name` is a required option for createSlice')
}
const reducers = options.reducers || {}
const extraReducers = options.extraReducers || {}
const actionKeys = Object.keys(reducers)

const reducerMap = actionKeys.reduce((map, actionKey) => {
let maybeEnhancedReducer = reducers[actionKey]
map[getType(slice, actionKey)] =
map[getType(name, actionKey)] =
typeof maybeEnhancedReducer === 'function'
? maybeEnhancedReducer
: maybeEnhancedReducer.reducer
Expand All @@ -185,7 +188,7 @@ export function createSlice<
const actionMap = actionKeys.reduce(
(map, action) => {
let maybeEnhancedReducer = reducers[action]
const type = getType(slice, action)
const type = getType(name, action)
map[action] =
typeof maybeEnhancedReducer === 'function'
? createAction(type)
Expand All @@ -196,7 +199,7 @@ export function createSlice<
)

return {
slice,
name,
reducer,
actions: actionMap
}
Expand Down
10 changes: 5 additions & 5 deletions type-tests/files/createSlice.typetest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function expectType<T>(t: T) {
const firstAction = createAction<{ count: number }>('FIRST_ACTION')

const slice = createSlice({
slice: 'counter',
name: 'counter',
initialState: 0,
reducers: {
increment: (state: number, action) => state + action.payload,
Expand Down Expand Up @@ -47,7 +47,7 @@ function expectType<T>(t: T) {
*/
{
const counter = createSlice({
slice: 'counter',
name: 'counter',
initialState: 0,
reducers: {
increment: state => state + 1,
Expand Down Expand Up @@ -85,7 +85,7 @@ function expectType<T>(t: T) {
*/
{
const counter = createSlice({
slice: 'counter',
name: 'counter',
initialState: 0,
reducers: {
increment: state => state + 1,
Expand All @@ -112,7 +112,7 @@ function expectType<T>(t: T) {
*/
{
const counter = createSlice({
slice: 'test',
name: 'test',
initialState: { counter: 0, concat: '' },
reducers: {
incrementByStrLen: {
Expand Down Expand Up @@ -153,7 +153,7 @@ function expectType<T>(t: T) {
{
// typings:expect-error
const counter = createSlice({
slice: 'counter',
name: 'counter',
initialState: { counter: 0 },
reducers: {
increment: {
Expand Down

0 comments on commit c58aa2c

Please sign in to comment.