store2be/redux-belt

View on GitHub
src/utils.test.js

Summary

Maintainability
A
1 hr
Test Coverage
import jsc from 'jsverify'
import * as utils from './utils'

describe('action', () => {
  it('is a function', () => {
    expect(typeof utils.action).toBe('function')
  })

  it('returns a well formed action with the default meta', () => {
    expect(utils.action('thetype', { message: 'the payload' })).toEqual({
      type: 'thetype',
      payload: {
        message: 'the payload',
      },
      meta: undefined,
    })
  })

  it('works even without a payload', () => {
    expect(utils.action('some type')).toEqual({
      type: 'some type',
      payload: undefined,
      meta: undefined,
    })
  })

  it('works without a meta field', () => {
    expect(utils.action('some type', '', { garbage: 'day' })).toEqual({
      type: 'some type',
      payload: '',
      meta: {
        garbage: 'day',
      },
    })
  })
})

describe('actionCreator', () => {
  it('is a function', () => {
    expect(typeof utils.actionCreator).toBe('function')
  })

  it('returns a function', () => {
    expect(typeof utils.actionCreator('action type')).toBe('function')
  })

  it('ultimately produces the expected action with the default meta', () => {
    const action = {
      type: 'AN_ACTION',
      payload: { id: 21, data: 'the_data' },
      meta: {},
    }
    // const result = actionCreator(action.type)(action.payload)
    expect(JSON.stringify(utils.actionCreator(action.type)(action.payload))).toBe(
      JSON.stringify(action),
    )
  })
})

describe('snakeCaseToCamel', () => [
  ['ADD', 'add'],
  ['FETCH_STORES', 'fetchStores'],
  ['FETCH_ABOUT_200_STORES', 'fetchAbout200Stores'],
  ['REMOVE_SPACE', 'removeSpace'],
  ['', ''],
].forEach((item) => {
  it(`returns "${item[1]}" when given "${item[0]}"`, () => {
    expect(utils.snakeCaseToCamel(item[0])).toBe(item[1])
  })
}))

describe('refresh', () => {
  it('is a function', () => {
    expect(typeof utils.refresh).toBe('function')
  })

  it('preserves the action type', () => {
    expect(utils.refresh(utils.actionCreator('THE-TYPE'))().type).toBe('THE-TYPE')
  })

  it('preserves the action payload', () => {
    expect(utils.refresh(utils.actionCreator('THE-TYPE'))({ a: true }).payload.a).toBe(true)
  })

  it('preserves the action meta field', () => {
    expect(utils.refresh(() => ({ type: 'meh', meta: { aa: 'aaa' } }))().meta.aa).toBe('aaa')
  })

  it('sets refresh to true in the meta field', () => {
    expect(utils.refresh(utils.actionCreator('TY'))().meta.refresh).toBe(true)
  })
})

describe('updateEntryWithId', () => {
  const oldEntry = { id: 'ab12449', name: 'troufignole' }
  const newEntry = { id: 'ab12449', name: 'tartempion' }
  const unrelatedEntry = { id: '989e22-21', name: 'something else' }

  test('returns an empty array when given an empty array', () => {
    expect(utils.updateEntryWithId([], newEntry).length).toEqual(0)
  })

  test('does not change entries with different ids', () => {
    expect(
      utils.updateEntryWithId([oldEntry, unrelatedEntry],
        newEntry)[1].id,
    ).toEqual(unrelatedEntry.id)
  })

  test('does not change the order of entries', () => {
    expect(utils.updateEntryWithId(
      [unrelatedEntry, oldEntry, unrelatedEntry],
      newEntry)[2].id,
    ).toEqual(unrelatedEntry.id)
  })

  test('does not change the array length', () => {
    expect(utils.updateEntryWithId(
      [unrelatedEntry, oldEntry, unrelatedEntry],
      newEntry,
    ).length).toEqual(3)
  })

  test('replaces the old entry with the new one', () => {
    expect(utils.updateEntryWithId(
      [unrelatedEntry, oldEntry, unrelatedEntry],
      newEntry,
    )[1].id).toEqual(newEntry.id)
  })

  test('does not mutate the old array', () => {
    const oldArray = [unrelatedEntry, oldEntry, unrelatedEntry]
    utils.updateEntryWithId([unrelatedEntry, oldEntry, unrelatedEntry], newEntry)
    expect(oldArray[1].id).toEqual(oldEntry.id)
  })
})

describe('strict', () => {
  it('returns an object with the same keys', () => {
    jsc.assertForall(jsc.dict(jsc.string), (target) => {
      expect(Object.keys(utils.strict(target))).toEqual(Object.keys(target))
      return true
    })
  })

  it('throws when an undefined property is accessed', () => {
    const target = { a: 'b', c: 'd' }
    expect(() => utils.strict(target).something).toThrow(TypeError)
  })

  it('allows normal access to other properties', () => {
    const target = { a: 'b' }
    expect(utils.strict(target).a).toBe('b')
  })
})