/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { act } from 'react-dom/test-utils'
import useStable from '..'
function createRoot(rootNode) {
return {
render(element) {
ReactDOM.render(element, rootNode)
},
}
}
describe('useStable', () => {
let root
let rootNode
let spy = {}
const TestComponent = ({ initialValueCallback }): React.ReactNode => {
const value = useStable(initialValueCallback)
spy.value = value
return null
}
beforeEach(() => {
spy = {}
rootNode = document.createElement('div')
document.body.appendChild(rootNode)
root = createRoot(rootNode)
})
afterEach(() => {
root.render(null)
document.body.removeChild(rootNode)
rootNode = null
root = null
})
test('correctly sets the initial value', () => {
const initialValueCallback = () => 5
act(() => {
root.render()
})
expect(spy.value).toBe(5)
})
test('does not change the value', () => {
let counter = 0
const initialValueCallback = () => counter++
act(() => {
root.render()
})
expect(spy.value).toBe(0)
act(() => {
root.render()
})
expect(spy.value).toBe(0)
})
test('only calls the callback once', () => {
let counter = 0
const initialValueCallback = () => counter++
act(() => {
root.render()
})
expect(counter).toBe(1)
act(() => {
root.render()
})
expect(counter).toBe(1)
})
test('does not change the value if the callback initially returns null', () => {
let counter = 0
const initialValueCallback = () => {
if (counter === 0) {
counter++
return null
}
return counter++
}
act(() => {
root.render()
})
expect(spy.value).toBe(null)
act(() => {
root.render()
})
expect(spy.value).toBe(null)
})
})