Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ui-react-utils): fix ID counter wrong when not in context #1313

Merged
merged 2 commits into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import React from 'react'
import { generateInstanceCounterMap } from './generateInstanceCounterMap'

const DeterministicIdContext = React.createContext(generateInstanceCounterMap())
const defaultDeterministicIDMap = generateInstanceCounterMap()
const DeterministicIdContext = React.createContext(defaultDeterministicIDMap)

export { DeterministicIdContext }
export { DeterministicIdContext, defaultDeterministicIDMap }
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,25 @@
* SOFTWARE.
*/
import React from 'react'
import { generateInstanceCounterMap } from './generateInstanceCounterMap'
import { DeterministicIdContext } from './DeterministicIdContext'
import {
DeterministicIdContext,
defaultDeterministicIDMap
} from './DeterministicIdContext'

type DeterministicIdProviderValue = Map<string, number>
type DeterministicIdProviderProps = React.PropsWithChildren<{
instanceCounterMap?: DeterministicIdProviderValue
}>

const defaultContextValue = generateInstanceCounterMap()

/**
* ---
* category: components/utilities
* ---
* WARNING: providing the `instanceCounterMap` prop will result in unexpected behaviour. DO NOT USE IT!
*
* DEPRECATED: the `instanceCounterMap` prop is deprecated. You don't need to supply the
* `instanceCounterMap` to the component. It handles it internally.
*
* This is utility component for wrapping components with `DeterministicIdContext.Provider`
* See detailed documentation about how to use it: [InstUISettingsProvider](/#InstUISettingsProvider)
*/
Expand All @@ -50,7 +56,7 @@ const DeterministicIdContextProvider = ({
)
}
DeterministicIdContextProvider.defaultProps = {
instanceCounterMap: defaultContextValue
instanceCounterMap: defaultDeterministicIDMap
}

export { DeterministicIdContextProvider }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,45 @@ class TestComponent extends React.Component<
}
}

const uniqueIds = (el: { getDOMNode: () => Element }) => {
const idList = Array.from(el.getDOMNode().children).map((el) => el.id)

return new Set(idList).size === idList.length
}

describe('DeterministicIdContext', () => {
it('should add id correctly by default', async () => {
const el = await mount(<TestComponent></TestComponent>)
const domNode = el.getDOMNode()
it('should generate unique ids without Provider wrapper', async () => {
const el = await mount(
<div>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
</div>
)

expect(domNode.id).to.eq('TestComponent_0')
expect(uniqueIds(el)).to.be.true()
})

it('should generate unique ids when components are rendered both out and inside of provider', async () => {
const el = await mount(
<div>
<DeterministicIdContextProvider>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
</DeterministicIdContextProvider>
<TestComponent></TestComponent>
<TestComponent></TestComponent>
</div>
)

expect(uniqueIds(el)).to.be.true()
})

//skipping this test because it will fail either in strictmode or normal mode
it.skip('should increment id by default', async () => {
it('should generate unique ids with provider only', async () => {
const Wrapper = ({ children }: any) => {
return (
<DeterministicIdContextProvider
Expand All @@ -65,36 +95,7 @@ describe('DeterministicIdContext', () => {
}

const el = await mount(<Wrapper>{children}</Wrapper>)
Array.from(el.getDOMNode().children).forEach((el, i) => {
// since the double mounting we have to increase i by i*2 every iteration
expect(el.id).to.eq(`TestComponent_${i * 2}`)
})
})

it('should work when instanceCounterMap is reset', async () => {
for (let i = 0; i < 10; i++) {
const el = await mount(
<DeterministicIdContextProvider
instanceCounterMap={generateInstanceCounterMap()}
>
<TestComponent></TestComponent>
</DeterministicIdContextProvider>
)
const domNode = el.getDOMNode()

expect(domNode.id).to.eq('TestComponent_0')
}
})
it('should work correctly when seeding the instanceCounterMap to the Context', async () => {
const seed = generateInstanceCounterMap()
seed.set('TestComponent', 20)
const el = await mount(
<DeterministicIdContextProvider instanceCounterMap={seed}>
<TestComponent></TestComponent>
</DeterministicIdContextProvider>
)
const domNode = el.getDOMNode()

expect(domNode.id).to.eq('TestComponent_21')
expect(uniqueIds(el)).to.be.true()
})
})
Loading