79 lines
1.7 KiB
JavaScript
79 lines
1.7 KiB
JavaScript
'use strict'
|
|
|
|
/* eslint-env jest */
|
|
|
|
const { deduped } = require('./deduped')
|
|
|
|
describe('deduped()', () => {
|
|
it('calls the resource function only once', async () => {
|
|
const value = {}
|
|
const getResource = jest.fn(async () => ({
|
|
value,
|
|
dispose: Function.prototype,
|
|
}))
|
|
|
|
const dedupedGetResource = deduped(getResource)
|
|
|
|
const { value: v1 } = await dedupedGetResource()
|
|
const { value: v2 } = await dedupedGetResource()
|
|
|
|
expect(getResource).toHaveBeenCalledTimes(1)
|
|
expect(v1).toBe(value)
|
|
expect(v2).toBe(value)
|
|
})
|
|
|
|
it('only disposes the source disposable when its all copies dispose', async () => {
|
|
const dispose = jest.fn()
|
|
const getResource = async () => ({
|
|
value: '',
|
|
dispose,
|
|
})
|
|
|
|
const dedupedGetResource = deduped(getResource)
|
|
|
|
const { dispose: d1 } = await dedupedGetResource()
|
|
const { dispose: d2 } = await dedupedGetResource()
|
|
|
|
d1()
|
|
|
|
expect(dispose).not.toHaveBeenCalled()
|
|
|
|
d2()
|
|
|
|
expect(dispose).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('works with sync factory', () => {
|
|
const value = {}
|
|
const dispose = jest.fn()
|
|
const dedupedGetResource = deduped(() => ({ value, dispose }))
|
|
|
|
const d1 = dedupedGetResource()
|
|
expect(d1.value).toBe(value)
|
|
|
|
const d2 = dedupedGetResource()
|
|
expect(d2.value).toBe(value)
|
|
|
|
d1.dispose()
|
|
|
|
expect(dispose).not.toHaveBeenCalled()
|
|
|
|
d2.dispose()
|
|
|
|
expect(dispose).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('no race condition on dispose before async acquisition', async () => {
|
|
const dispose = jest.fn()
|
|
const dedupedGetResource = deduped(async () => ({ value: 42, dispose }))
|
|
|
|
const d1 = await dedupedGetResource()
|
|
|
|
dedupedGetResource()
|
|
|
|
d1.dispose()
|
|
|
|
expect(dispose).not.toHaveBeenCalled()
|
|
})
|
|
})
|