diff --git a/__tests__/atomWithLocation_spec.tsx b/__tests__/atomWithLocation_spec.tsx
index 194065b..3a26cb4 100644
--- a/__tests__/atomWithLocation_spec.tsx
+++ b/__tests__/atomWithLocation_spec.tsx
@@ -1,12 +1,52 @@
import { useAtom } from 'jotai';
import React, { StrictMode } from 'react';
-import { act, render } from '@testing-library/react';
+import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { atomWithLocation } from '../src/index';
+function assertPathNameAndHistoryLength(
+ expectedPathname: string,
+ expectedHistoryLength: number,
+) {
+ expect(window.location.pathname).toEqual(expectedPathname);
+ expect(window.history.length).toEqual(expectedHistoryLength);
+}
+
+async function assertStartState(
+ startTestHistoryLength: number,
+ findByText: any,
+) {
+ await findByText('current pathname in atomWithLocation: /');
+ assertPathNameAndHistoryLength('/', startTestHistoryLength);
+}
+
+function clickButtonAndAssertTemplate(localFindByText: any) {
+ return async function clickButtonAndAssert(
+ target: `button${number}` | 'back' | 'buttonWithReplace' | 'buttonWithPush',
+ historyLength: number,
+ targetPathName?: string,
+ ) {
+ let expectedPathname: string = '/';
+ if (target === 'buttonWithReplace') {
+ expectedPathname = '/123';
+ } else if (target === 'buttonWithPush') {
+ expectedPathname = '/234';
+ } else if (target.startsWith('button')) {
+ expectedPathname = `/${target.slice(-1)}`;
+ } else if (target === 'back' && targetPathName) {
+ expectedPathname = targetPathName;
+ }
+ await userEvent.click(await localFindByText(target));
+ await localFindByText(
+ `current pathname in atomWithLocation: ${expectedPathname}`,
+ );
+ assertPathNameAndHistoryLength(expectedPathname, historyLength);
+ };
+}
+
describe('atomWithLocation', () => {
beforeEach(() => {
- window.history.replaceState(null, '', '/');
+ window.history.pushState(null, '', '/');
});
it('can replace state', async () => {
@@ -37,25 +77,18 @@ describe('atomWithLocation', () => {
);
};
- const { findByText, getByText } = render(
+ const { findByText } = render(
,
);
- await findByText('current pathname in atomWithLocation: /');
- expect(window.location.pathname).toEqual('/');
- expect(window.history.length).toEqual(1);
-
- await userEvent.click(getByText('button1'));
-
- await findByText('current pathname in atomWithLocation: /1');
- expect(window.location.pathname).toEqual('/1');
- expect(window.history.length).toEqual(1);
+ const clickButtonAndAssert = clickButtonAndAssertTemplate(findByText);
+ const startHistoryLength = window.history.length;
+ assertStartState(startHistoryLength, findByText);
- await userEvent.click(getByText('button2'));
- expect(window.location.pathname).toEqual('/2');
- expect(window.history.length).toEqual(1);
+ await clickButtonAndAssert('button1', startHistoryLength);
+ await clickButtonAndAssert('button2', startHistoryLength);
});
it('can push state', async () => {
@@ -86,36 +119,22 @@ describe('atomWithLocation', () => {
);
};
- const { findByText, getByText } = render(
+ const { findByText } = render(
,
);
- await findByText('current pathname in atomWithLocation: /');
- expect(window.location.pathname).toEqual('/');
- expect(window.history.length).toEqual(1);
-
- await userEvent.click(getByText('button1'));
-
- await findByText('current pathname in atomWithLocation: /1');
- expect(window.location.pathname).toEqual('/1');
- expect(window.history.length).toEqual(2);
-
- await userEvent.click(getByText('button2'));
+ const clickButtonAndAssert = clickButtonAndAssertTemplate(findByText);
+ const startHistoryLength = window.history.length;
+ assertStartState(startHistoryLength, findByText);
- await findByText('current pathname in atomWithLocation: /2');
- expect(window.location.pathname).toEqual('/2');
- expect(window.history.length).toEqual(3);
-
- await userEvent.click(getByText('back'));
-
- await findByText('current pathname in atomWithLocation: /1');
- expect(window.location.pathname).toEqual('/1');
- expect(window.history.length).toEqual(3);
+ await clickButtonAndAssert('button1', startHistoryLength + 1);
+ await clickButtonAndAssert('button2', startHistoryLength + 2);
+ await clickButtonAndAssert('back', startHistoryLength + 2, '/1');
});
- it('can override atomOptions', async () => {
+ it('can override atomOptions, from replace=false to replace=true', async () => {
const locationAtom = atomWithLocation({ replace: false });
const Navigation = () => {
@@ -128,71 +147,100 @@ describe('atomWithLocation', () => {
>
);
};
- const { findByText, getByText } = render(
+ const { findByText } = render(
,
);
- const previousTestHistoryLength = 3;
+ const clickButtonAndAssert = clickButtonAndAssertTemplate(findByText);
+ const startHistoryLength = window.history.length;
- await act(async () => {
- window.history.pushState(null, '', '/');
- });
+ assertStartState(startHistoryLength, findByText);
- await findByText('current pathname in atomWithLocation: /');
- expect(window.location.pathname).toEqual('/');
- expect(window.history.length).toEqual(previousTestHistoryLength);
+ await clickButtonAndAssert('buttonWithPush', startHistoryLength + 1);
+ await clickButtonAndAssert('buttonWithReplace', startHistoryLength + 1);
+ await clickButtonAndAssert('back', startHistoryLength + 1, '/');
- await userEvent.click(getByText('button1'));
-
- await findByText('current pathname in atomWithLocation: /123');
- expect(window.location.pathname).toEqual('/123');
- expect(window.history.length).toEqual(previousTestHistoryLength + 1);
-
- await userEvent.click(getByText('button2'));
+ // This click overwrites the history entry we
+ // went back from. The history length remains the same.
+ await clickButtonAndAssert('buttonWithPush', startHistoryLength + 1);
- await findByText('current pathname in atomWithLocation: /234');
- expect(window.location.pathname).toEqual('/234');
- expect(window.history.length).toEqual(previousTestHistoryLength + 1);
+ // The second click adds a new history entry, which now increments the history length.
+ await clickButtonAndAssert('buttonWithPush', startHistoryLength + 2);
+ });
- await userEvent.click(getByText('back'));
+ it('can override atomOptions, from replace=true to replace=false', async () => {
+ const locationAtom = atomWithLocation({ replace: true });
- await findByText('current pathname in atomWithLocation: /');
- expect(window.location.pathname).toEqual('/');
- expect(window.history.length).toEqual(previousTestHistoryLength + 1);
+ const Navigation = () => {
+ const [location, setLocation] = useAtom(locationAtom);
+ return (
+ <>
+
current pathname in atomWithLocation: {location.pathname}
+
+
+
+ >
+ );
+ };
- // The first click overwrites the history entry we
- // went back from. The history length remains the same.
- await userEvent.click(getByText('button1'));
+ const { findByText } = render(
+
+
+ ,
+ );
- // The second click adds a new history entry, which now increments the history length.
- await userEvent.click(getByText('button1'));
+ const clickButtonAndAssert = clickButtonAndAssertTemplate(findByText);
+ const startTestHistoryLength = window.history.length;
+ assertStartState(startTestHistoryLength, findByText);
- await findByText('current pathname in atomWithLocation: /123');
- expect(window.location.pathname).toEqual('/123');
- expect(window.history.length).toEqual(previousTestHistoryLength + 2);
+ await clickButtonAndAssert('buttonWithReplace', startTestHistoryLength);
+ await clickButtonAndAssert('buttonWithPush', startTestHistoryLength + 1);
+ await clickButtonAndAssert('back', startTestHistoryLength + 1, '/123');
+ await clickButtonAndAssert('buttonWithReplace', startTestHistoryLength + 1);
+ await clickButtonAndAssert('buttonWithPush', startTestHistoryLength + 1);
+ await clickButtonAndAssert('buttonWithPush', startTestHistoryLength + 2);
});
});