Skip to content

Instantly share code, notes, and snippets.

@andrew8088
Created May 21, 2022 14:16
Show Gist options
  • Save andrew8088/c1be92df4dd99b609b2d162f5a58dcd0 to your computer and use it in GitHub Desktop.
Save andrew8088/c1be92df4dd99b609b2d162f5a58dcd0 to your computer and use it in GitHub Desktop.
Testing Promise Race Conditions with fast-check

To run this:

  1. use create-react-app to spin up a project
  2. yarn install fast-check
  3. copy Progress.tsx and Progress.test.tsx into the src directory
  4. run yarn test
import { cleanup, render, screen, fireEvent, act } from '@testing-library/react';
import Progress from './Progress';
import * as fc from 'fast-check';
test('renders learn react link', async () => {
await fc.assert(
fc.asyncProperty(fc.scheduler(), async (s) => {
let number = 0;
const mockGetProgress = s.scheduleFunction(async () => number += 10);
render(<Progress getProgress={mockGetProgress} />);
const button = screen.getByRole('button');
fireEvent.click(button);
fireEvent.click(button);
fireEvent.click(button);
await act(async () => await s.waitAll());
const progressValue = screen.getByText(/30/);
expect(progressValue).toBeInTheDocument();
}).beforeEach(() => {
cleanup();
})
);
});
import { useState } from 'react';
export default function Progress({ getProgress }: { getProgress: () => Promise<number> }) {
const [loading, setLoading] = useState(false);
const [value, setValue] = useState<number>(0);
const updateProgress = () => {
setLoading(true);
getProgress().then(newValue => {
setValue((oldValue) => Math.max(newValue, oldValue));
setLoading(false);
});
};
return (
<div>
<div>
<label htmlFor="p">File progress:</label>
<progress id="p" max="100" value={value}> {value}% </progress>
</div>
<div>
<button onClick={updateProgress}>
Update Progress
</button>
{loading && <p>updating...</p>}
</div>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment