I tried to test the hook, that used the ResizeObserver
. Also, I need to check if the element was overflow or wasn't after resizing. So I wrote such a decision:
import { useLayoutEffect, useState } from 'react';
import ResizeObserver from 'resize-observer-polyfill';
export default function useOverflowCheck(ref) {
const [isOverflowing, setIsOverflowing] = useState(false);
const isOverflow = current => {
if (current) {
const hasOverflowX = current.offsetWidth < current.scrollWidth;
const hasOverflowY = current.offsetHeight < current.scrollHeight;
setIsOverflowing(hasOverflowX || hasOverflowY);
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
useLayoutEffect(() => {
const element = ref.current;
const resizeObserver = new ResizeObserver(entries => {
entries && entries.length && isOverflow(entries[0].target);
});
if (element) {
resizeObserver.observe(element);
return () => {
resizeObserver.disconnect();
};
}
});
return isOverflowing;
}
And I tried to unit test this code, but my tests didn't cover the resizeObserver
callback.
Test:
import { renderHook } from '@testing-library/react-hooks';
import useOverflowCheck from './index';
describe('useOverflowCheck', () => {
it('should return true for an overflowing component', () => {
const el: HTMLDivElement = document.createElement('div');
Object.defineProperties(el, {
offsetWidth: { value: 30, configurable: true },
offsetHeight: { value: 30, configurable: true },
});
const ref = {
current: el,
};
expect(renderHook(() => useOverflowCheck(ref)).result.current).toBeTruthy();
});
});
Should define Resize Observer constructor and add a listener to test Resize Observer callback.
let listener: ((rect: any) => void) | undefined = undefined;
(global as any).ResizeObserver = class ResizeObserver {
constructor(ls) {
listener = ls;
}
observe() {}
unobserve() {}
disconnect() {}
};
Then should specify needed properties:
act(() => {
listener!([
{
target: {
clientWidth: 100,
scrollWidth: 200,
clientHeight: 100,
scrollHeight: 200,
},
},
]);
});
Inspired by https://github.com/streamich/react-use/blob/master/tests/useMeasure.test.ts