@johngw/stream
Version:
Reactive programming tools using the WHATWG Streams API.
126 lines (111 loc) • 3.19 kB
text/typescript
import '@johngw/stream-jest'
import { Pass, check, checks } from '@johngw/stream-test'
import { fromTimeline } from '@johngw/stream-jest'
import {
StateReducerInput,
StateReducerOutput,
StateReducers,
stateReducer,
} from '@johngw/stream/transformers/stateReducer'
interface State {
authors: string[]
}
type Actions = {
'add author': string
nothing: void
}
function transform() {
return stateReducer<Actions, State>({
__INIT__: () => ({ authors: [] }),
'add author': (state, author) =>
state.authors.includes(author)
? state
: {
...state,
authors: [...state.authors, author],
},
nothing: (state) => state,
})
}
test('StateReducerInput', () => {
checks([
check<
StateReducerInput<{ foo: string; bar: number; nothing: void }>,
| { action: '__INIT__'; param: void }
| { action: 'foo'; param: string }
| { action: 'bar'; param: number }
| { action: 'nothing'; param: void },
Pass
>(),
])
})
test('StateReducerOutput', () => {
checks([
check<
StateReducerOutput<{ foo: string; bar: number; nothing: void }, string>,
| { action: '__INIT__'; param: void; state: string }
| { action: 'foo'; param: string; state: string }
| { action: 'bar'; param: number; state: string }
| { action: 'nothing'; param: void; state: string },
Pass
>(),
])
})
test('StateReducers', () => {
interface State {
foos: string[]
}
type Actions = {
foo: string
nothing: void
}
check<
StateReducers<Actions, State>,
{
__INI__(): State
foo(state: State, param: string): State
nothing(state: State): State
},
Pass
>()
})
test('the __INIT__ action', async () => {
await expect(
fromTimeline(`
-|
`).pipeThrough(transform())
).toMatchTimeline(`
-{ action: __INIT__, state: { authors: [] } }-
`)
})
test('a reducer that changes state', async () => {
await expect(
fromTimeline(`
----------------------------------------------{ action: add author, param: Jane Austin }-----------------------------------|
`).pipeThrough(transform())
).toMatchTimeline(`
-{ action: __INIT__, state: { authors: [] } }-{ action: add author, param: Jane Austin, state: { authors: [Jane Austin] } }-
`)
})
test('a reducer that doesnt change state', async () => {
await expect(
fromTimeline(`
----------------------------------------------{ action: nothing }-|
`).pipeThrough(transform())
).toMatchTimeline(`
-{ action: __INIT__, state: { authors: [] } }----------------------
`)
})
test('multiple calls', async () => {
await expect(
fromTimeline(
'-{ action: add author, param: Jane Austin }-' +
'-{ action: add author, param: George Orwell }-' +
'-{ action: add author, param: Jane Austin }-|'
).pipeThrough(transform())
).toMatchTimeline(
'-{ action: __INIT__, state: { authors: [] } }-' +
'-{ action: add author, param: Jane Austin, state: { authors: [Jane Austin] } }-' +
'-{ action: add author, param: George Orwell, state: { authors: [Jane Austin, George Orwell] } }-'
)
})