Skip to content

Commit

Permalink
Fix db.test.
Browse files Browse the repository at this point in the history
- Fake timers cause an infinite loop on _.debounce.
- Jest v26 contains a 'modern' option for useFakeTimers, but create-react-app uses an older version of jest
jestjs/jest#3465 (comment)
- Mock debounce
- Test fails without a dummy call to the database. Why?
  • Loading branch information
raineorshine committed Aug 2, 2020
1 parent 9a0815d commit ed68665
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 10 deletions.
5 changes: 1 addition & 4 deletions src/action-creators/loadLocalState.js
Expand Up @@ -7,15 +7,12 @@ import { never } from '../util'
/** Loads the local state from the IndexedDB database. */
const loadLocalState = () => async (dispatch, getState) => {

// TODO: Fix IndexedDB during tests
const test = process.env.NODE_ENV === 'test'

// load helpers and settings from local database
const [{
cursor: localUrl,
lastUpdated,
recentlyEdited,
}, settings] = test ? [{}] : await Promise.all([
}, settings] = await Promise.all([
db.getHelpers(),
db.getContext([EM_TOKEN, 'Settings'])
])
Expand Down
61 changes: 55 additions & 6 deletions src/db.test.js
@@ -1,23 +1,72 @@
import { store } from './store'
import * as db from './data-providers/dexie'
import { initialize } from './initialize'
import { hashThought } from './util'
import { getThought } from './selectors'

// mock debounce to use 0 delay
jest.mock('lodash', () => ({
...jest.requireActual('lodash'),

// jest.mock must be inline
// possible workarounds: https://stackoverflow.com/questions/40465047/how-can-i-mock-an-es6-module-import-using-jest
debounce: jest.fn().mockImplementation((callback, delay) => {
let timer = null
let pendingArgs = null

const cancel = jest.fn(() => {
if (timer) {
clearTimeout(timer)
}
timer = null
pendingArgs = null
})

const flush = jest.fn(() => {
if (timer) {
callback(...pendingArgs)
cancel()
}
})

const wrapped = (...args) => {
cancel()

pendingArgs = args

// TODO: why doesn't jest.runAllTimers work here?
// use 0 instead of given delay as a workaround
timer = setTimeout(flush, 0)
}

wrapped.cancel = cancel
wrapped.flush = flush
wrapped.delay = delay

return wrapped
}),
}))


beforeAll(async () => {
await initialize()
})

// TODO: Make pass with iterative loading
it.skip('load settings into indexedDB on initialization', async () => {
const hash = hashThought('Settings')
// fake timers cause an infinite loop on _.debounce
// Jest v26 contains a 'modern' option for useFakeTimers, but create-react-app uses an older version of jest
// https://github.com/facebook/jest/issues/3465#issuecomment-504908570
jest.useFakeTimers()
jest.runAllTimers()
})

it('load settings into indexedDB on initialization', async () => {
const thoughtState = getThought(store.getState(), 'Settings')

expect(thoughtState).not.toBeUndefined()
expect(thoughtState.contexts).toHaveLength(1)

const thoughtDB = await db.getThought(hash)
// TODO: Tests fail without a dummy call to the database. Why?
await db.getHelpers()

const thoughtDB = await db.getThought('Settings')

expect(thoughtDB).not.toBeUndefined()
expect(thoughtDB.contexts).toHaveLength(1)
Expand Down

0 comments on commit ed68665

Please sign in to comment.