useTimeout.spec.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import {reactHooks} from 'sentry-test/reactTestingLibrary';
  2. import useTimeout from './useTimeout';
  3. jest.useFakeTimers();
  4. describe('useTimeout', () => {
  5. const timeMs = 500;
  6. const onTimeout = jest.fn();
  7. beforeEach(() => {
  8. onTimeout.mockReset();
  9. });
  10. it('should timeout after a specified delay', () => {
  11. const {result} = reactHooks.renderHook(useTimeout, {
  12. initialProps: {timeMs, onTimeout},
  13. });
  14. result.current.start();
  15. expect(onTimeout).not.toHaveBeenCalled();
  16. jest.advanceTimersByTime(timeMs + 10);
  17. expect(onTimeout).toHaveBeenCalled();
  18. });
  19. it('should call the callback if a timeout is ended early', () => {
  20. const {result} = reactHooks.renderHook(useTimeout, {
  21. initialProps: {timeMs, onTimeout},
  22. });
  23. result.current.start();
  24. expect(onTimeout).not.toHaveBeenCalled();
  25. result.current.end();
  26. expect(onTimeout).toHaveBeenCalled();
  27. });
  28. it('should not exec the callback if a timeout is cancelled', () => {
  29. const {result} = reactHooks.renderHook(useTimeout, {
  30. initialProps: {timeMs, onTimeout},
  31. });
  32. result.current.start();
  33. expect(onTimeout).not.toHaveBeenCalled();
  34. result.current.cancel();
  35. expect(onTimeout).not.toHaveBeenCalled();
  36. });
  37. it('should return stable start/cancel/end callbacks', () => {
  38. const {result, rerender} = reactHooks.renderHook(useTimeout, {
  39. initialProps: {timeMs, onTimeout},
  40. });
  41. const firstRender = {...result.current};
  42. rerender();
  43. expect(result.current.start).toBe(firstRender.start);
  44. expect(result.current.cancel).toBe(firstRender.cancel);
  45. expect(result.current.end).toBe(firstRender.end);
  46. });
  47. it('should return a new start() method when timeMs changes', () => {
  48. const {result, rerender} = reactHooks.renderHook(useTimeout, {
  49. initialProps: {timeMs, onTimeout},
  50. });
  51. const firstRender = {...result.current};
  52. rerender({timeMs: 999, onTimeout});
  53. expect(result.current.cancel).toBe(firstRender.cancel);
  54. expect(result.current.end).toBe(firstRender.end);
  55. expect(result.current.start).not.toBe(firstRender.start);
  56. });
  57. it('should return a new start() and end() method when onTimeout changes', () => {
  58. const {result, rerender} = reactHooks.renderHook(useTimeout, {
  59. initialProps: {timeMs, onTimeout},
  60. });
  61. const firstRender = {...result.current};
  62. rerender({timeMs, onTimeout: jest.fn()});
  63. expect(result.current.cancel).toBe(firstRender.cancel);
  64. expect(result.current.start).not.toBe(firstRender.start);
  65. expect(result.current.end).not.toBe(firstRender.end);
  66. });
  67. it('should not exec the callback after unmount', () => {
  68. const {result, unmount} = reactHooks.renderHook(useTimeout, {
  69. initialProps: {timeMs, onTimeout},
  70. });
  71. result.current.start();
  72. unmount();
  73. jest.runAllTimers();
  74. expect(onTimeout).not.toHaveBeenCalled();
  75. });
  76. });