Skip to content

Commit

Permalink
feat: upgrade to react v18 (#1789)
Browse files Browse the repository at this point in the history
  • Loading branch information
ripecosta authored Aug 14, 2024
1 parent 8276a35 commit 5b492e8
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 281 deletions.
344 changes: 139 additions & 205 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.7",
"@rollup/plugin-terser": "0.4.4",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.4.8",
"@testing-library/react": "^12.1.5",
"@testing-library/react-hooks": "^7.0.2",
"@testing-library/react": "^16.0.0",
"@types/jest": "^29.5.12",
"@types/react": "^18.2.52",
"@types/react": "^18.3.3",
"@vitest/coverage-v8": "^2.0.5",
"all-contributors-cli": "^6.26.1",
"babel-core": "^7.0.0-bridge.0",
Expand All @@ -111,9 +111,9 @@
"lint-staged": "^15.2.8",
"mkdirp": "^3.0.1",
"prettier": "^3.3.3",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"react-test-renderer": "^16.14.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-test-renderer": "^18.3.1",
"rimraf": "^6.0.1",
"rollup": "^4.20.0",
"typescript": "~5.5.4",
Expand Down
16 changes: 2 additions & 14 deletions src/I18nextProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,6 @@ import { createElement, useMemo } from 'react';
import { I18nContext } from './context.js';

export function I18nextProvider({ i18n, defaultNS, children }) {
const value = useMemo(
() => ({
i18n,
defaultNS,
}),
[i18n, defaultNS],
);
return createElement(
I18nContext.Provider,
{
value,
},
children,
);
const value = useMemo(() => ({ i18n, defaultNS }), [i18n, defaultNS]);
return createElement(I18nContext.Provider, { value }, children);
}
2 changes: 1 addition & 1 deletion test/useSSR.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, vitest, beforeAll, afterAll, expect } from 'vitest';
import { renderHook } from '@testing-library/react-hooks/server';
import { renderHook } from '@testing-library/react';
import i18n from './i18n';
import { setI18n } from '../src/context';
import { useSSR } from '../src/useSSR';
Expand Down
26 changes: 13 additions & 13 deletions test/useTranslation.loading.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, vitest, beforeEach, expect } from 'vitest';
import { renderHook } from '@testing-library/react-hooks';
import { renderHook, waitFor } from '@testing-library/react';
import i18n from './i18n';
import { BackendMock } from './backendMock';
import { useTranslation } from '../src/useTranslation';
Expand All @@ -23,26 +23,26 @@ describe('useTranslation loading ns', () => {
});

it('should wait for correct translation with suspense', async () => {
const { result, waitForNextUpdate } = renderHook(() =>
useTranslation('common', { i18n: newI18n, useSuspense: true }),
);
expect(result.all).toHaveLength(0);
const all = [];
const { result } = renderHook(() => {
const value = useTranslation('common', { i18n: newI18n, useSuspense: true });
all.push(value);
return value;
});

expect(all).toHaveLength(0);
backend.flush();
await waitForNextUpdate();
const { t } = result.current;
expect(t('key1')).toBe('test');
await waitFor(() => expect(result.current.t('key1')).toBe('test'));
});

it('should wait for correct translation without suspense', async () => {
const { result, waitForNextUpdate } = renderHook(() =>
const { result } = renderHook(() =>
useTranslation('common', { i18n: newI18n, useSuspense: false }),
);
const { t } = result.current;
expect(t('key1')).toBe('key1');

expect(result.current.t('key1')).toBe('key1');
backend.flush();
await waitForNextUpdate();
expect(t('key1')).toBe('test');
await waitFor(() => expect(result.current.t('key1')).toBe('test'));
});

it('should return defaultValue if i18n instance not found', async () => {
Expand Down
31 changes: 15 additions & 16 deletions test/useTranslation.loadingLng.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, vitest, beforeEach, afterEach, expect } from 'vitest';
import { renderHook, cleanup } from '@testing-library/react-hooks';
import { renderHook, cleanup, waitFor } from '@testing-library/react';
import i18n from './i18n';
import { BackendLngAwareMock } from './backendLngAwareMock';
import { useTranslation } from '../src/useTranslation';
Expand All @@ -23,14 +23,16 @@ describe('useTranslation loading ns with lng via props', () => {
afterEach(cleanup);

it('should wait for correct translation with suspense', async () => {
const { result, waitForNextUpdate } = renderHook(() =>
useTranslation('common', { i18n: newI18n, useSuspense: true, lng: 'de' }),
);
expect(result.all).toHaveLength(0);
const all = [];
const { result } = renderHook(() => {
const value = useTranslation('common', { i18n: newI18n, useSuspense: true, lng: 'de' });
all.push(value);
return value;
});

expect(all).toHaveLength(0);
backend.flush();
await waitForNextUpdate();
const { t } = result.current;
expect(t('key1')).toBe('de/common for key1');
await waitFor(() => expect(result.current.t('key1')).toBe('de/common for key1'));
});

it('should wait for correct translation without suspense', async () => {
Expand Down Expand Up @@ -63,24 +65,21 @@ describe('useTranslation loading ns with lng via props', () => {

it('should correctly return and render correct translations in multiple useTranslation usages', async () => {
{
const { result, waitForNextUpdate } = renderHook(() =>
const { result } = renderHook(() =>
useTranslation('newns', { i18n: newI18n, useSuspense: true, lng: 'pt' }),
);

backend.flush();
await waitForNextUpdate();
const { t } = result.current;
expect(t('key1')).toBe('pt/newns for key1');
await waitFor(() => expect(result.current.t('key1')).toBe('pt/newns for key1'));
}

{
const { result, waitForNextUpdate } = renderHook(() =>
const { result } = renderHook(() =>
useTranslation('newns', { i18n: newI18n, useSuspense: true, lng: 'de' }),
);

backend.flush({ language: 'de' });
await waitForNextUpdate();
const { t } = result.current;
expect(t('key1')).toBe('de/newns for key1');
await waitFor(() => expect(result.current.t('key1')).toBe('de/newns for key1'));
}

{
Expand Down
21 changes: 9 additions & 12 deletions test/useTranslation.ready.spec.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { describe, it, vitest, expect, beforeEach, afterEach } from 'vitest';
import React from 'react';
import { renderHook, cleanup as cleanupHook } from '@testing-library/react-hooks';
import { render, cleanup } from '@testing-library/react';
import React, { Suspense } from 'react';
import { render, renderHook, cleanup, screen } from '@testing-library/react';
import { useTranslation } from '../src/useTranslation';
import hasLoadedNamespace from './hasLoadedNamespaceMock.js';

Expand All @@ -10,7 +9,6 @@ vitest.unmock('../src/useTranslation');
describe('useTranslation', () => {
afterEach(() => {
cleanup();
cleanupHook();
});

let instance;
Expand Down Expand Up @@ -42,15 +40,14 @@ describe('useTranslation', () => {
return <div>{t('keyOne')}</div>;
}

it('should throw a suspense if not ready (having not all ns)', async () => {
expect(() => {
console.error = vitest.fn(); // silent down the error boundary error from react-dom

render(<TestComponentNotReady i18n={instance} />);
}).toThrow(
'TestComponentNotReady suspended while rendering, but no fallback UI was specified.',
it('should render suspense if not ready (having not all ns)', async () => {
render(
<Suspense fallback="Suspended">
<TestComponentNotReady i18n={instance} />
</Suspense>,
);
expect(console.error).toHaveBeenCalled(); // silent down the error boundary error from react-dom

expect(screen.getByText('Suspended')).toBeInTheDocument();
});

it('should render correct content if ready (having all ns)', () => {
Expand Down
20 changes: 7 additions & 13 deletions test/useTranslation.spec.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, it, vitest, expect, beforeAll, afterAll, afterEach } from 'vitest';
import React from 'react';
import { renderHook, cleanup } from '@testing-library/react-hooks';
import { renderHook, cleanup } from '@testing-library/react';
import i18nInstance from './i18n';
import { useTranslation } from '../src/useTranslation';
import { setI18n } from '../src/context';
Expand Down Expand Up @@ -162,25 +162,19 @@ describe('useTranslation', () => {
describe('replacing i18n instance in provider', () => {
i18nInstance.addResource('fr', 'translation', 'key1', 'test2');
const i18nInstanceClone = i18nInstance.cloneInstance({ lng: 'fr' });
const wrapper = ({ children, i18n }) => (
<I18nextProvider i18n={i18n}>{children}</I18nextProvider>
const wrapper = ({ children }) => (
<I18nextProvider i18n={children?.props?.renderCallbackProps.i18n}>{children}</I18nextProvider>
);

it('should render correct content', () => {
it('should render correct content', async () => {
const { result, rerender } = renderHook(() => useTranslation(), {
wrapper,
initialProps: {
i18n: i18nInstance,
},
initialProps: { i18n: i18nInstance },
});

const { t: t1 } = result.current;
expect(t1('key1')).toBe('test');

expect(result.current.t('key1')).toBe('test');
rerender({ i18n: i18nInstanceClone });

const { t: t2 } = result.current;
expect(t2('key1')).toBe('test2');
expect(result.current.t('key1')).toBe('test2');
});
});

Expand Down
4 changes: 3 additions & 1 deletion test/useTranslation.usedNamespaces.spec.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { describe, it, vitest, expect, afterEach } from 'vitest';
import { renderHook, cleanup } from '@testing-library/react-hooks/server';
import { renderHook, cleanup } from '@testing-library/react';
import { useTranslation } from '../src/useTranslation';

vitest.unmock('../src/useTranslation');
Expand All @@ -22,13 +22,15 @@ describe('useTranslation', () => {
isInitialized: true,
changeLanguage: () => {},
getFixedT: () => (message) => message,
hasLoadedNamespace: () => false,
hasResourceBundle: (lng, ns) => ns === 'ns1' || ns === 'ns2' || ns === 'ns3',
loadNamespaces: () => {},
on: () => {},
off: () => {},
options: {},
};
renderHook(() => useTranslation(['ns1', 'ns2', 'ns3'], { i18n }));

expect(i18n.reportNamespaces.getUsedNamespaces()).toEqual(['ns1', 'ns2', 'ns3']);
});
});

0 comments on commit 5b492e8

Please sign in to comment.