Repository: reduxjs/redux
File: test/createStore.spec.ts (TypeScript)

Code before:
    const store = createStore(reducers.subscribeInTheMiddleOfReducer)

    expect(() =>
      store.dispatch(subscribeInMiddle(store.subscribe.bind(store, () => {})))
    ).toThrow(/You may not call store.subscribe()/)
  })

  it('does not allow unsubscribe from subscribe() from within a reducer', () => {
    const store = createStore(reducers.unsubscribeInTheMiddleOfReducer)
    const unsubscribe = store.subscribe(() => {})

    expect(() =>
      store.dispatch(unsubscribeInMiddle(unsubscribe.bind(store)))
    ).toThrow(/You may not unsubscribe from a store/)
  })

  it('recovers from an error within a reducer', () => {
    const store = createStore(reducers.errorThrowingReducer)
    expect(() => store.dispatch(throwError())).toThrow()

    expect(() => store.dispatch(unknownAction())).not.toThrow()
  })

  it('throws if action type is missing', () => {
    const store = createStore(reducers.todos)
    // @ts-ignore
    expect(() => store.dispatch({})).toThrow(
      /Actions may not have an undefined "type" property/
    )
  })

  it('throws if action type is undefined', () => {
    const store = createStore(reducers.todos)
    expect(() => store.dispatch({ type: undefined })).toThrow(
      /Actions may not have an undefined "type" property/
    )
  })

  it('does not throw if action type is falsy', () => {
    const store = createStore(reducers.todos)
    expect(() => store.dispatch({ type: false } as any)).not.toThrow()
    expect(() => store.dispatch({ type: 0 } as any)).not.toThrow()
    expect(() => store.dispatch({ type: null })).not.toThrow()
    expect(() => store.dispatch({ type: '' } as any)).not.toThrow()
  })

  it('accepts enhancer as the third argument', () => {
    const emptyArray = []
    const spyEnhancer = vanillaCreateStore => (...args) => {
      expect(args[0]).toBe(reducers.todos)
      expect(args[1]).toBe(emptyArray)

Review comment (suggestion):
TypeScript won't let you call `store.dispatch` with a missing action type, now that the `store` is typed properly; thus, we need to `// @ts-ignore` this line to allow the test to run w/o compilation errors.

Code after:
    const store = createStore(reducers.subscribeInTheMiddleOfReducer)

    expect(() =>
      store.dispatch(subscribeInMiddle(store.subscribe.bind(store, () => {})))
    ).toThrow(/You may not call store.subscribe()/)
  })

  it('does not allow unsubscribe from subscribe() from within a reducer', () => {
    const store = createStore(reducers.unsubscribeInTheMiddleOfReducer)
    const unsubscribe = store.subscribe(() => {})

    expect(() =>
      store.dispatch(unsubscribeInMiddle(unsubscribe.bind(store)))
    ).toThrow(/You may not unsubscribe from a store/)
  })

  it('recovers from an error within a reducer', () => {
    const store = createStore(reducers.errorThrowingReducer)
    expect(() => store.dispatch(throwError())).toThrow()

    expect(() => store.dispatch(unknownAction())).not.toThrow()
  })

  it('throws if action type is missing', () => {
    const store = createStore(reducers.todos)
    expect(() => store.dispatch({})).toThrow(
      /Actions may not have an undefined "type" property/
    )
  })

  it('throws if action type is undefined', () => {
    const store = createStore(reducers.todos)
    expect(() => store.dispatch({ type: undefined })).toThrow(
      /Actions may not have an undefined "type" property/
    )
  })

  it('does not throw if action type is falsy', () => {
    const store = createStore(reducers.todos)
    expect(() => store.dispatch({ type: false })).not.toThrow()
    expect(() => store.dispatch({ type: 0 })).not.toThrow()
    expect(() => store.dispatch({ type: null })).not.toThrow()
    expect(() => store.dispatch({ type: '' })).not.toThrow()
  })

  it('accepts enhancer as the third argument', () => {
    const emptyArray = []
    const spyEnhancer = vanillaCreateStore => (...args) => {
      expect(args[0]).toBe(reducers.todos)
      expect(args[1]).toBe(emptyArray)
      expect(args.length).toBe(2)