← Back to all jobsRenatus · signed audit report
migrateAudit 704ec574
Repository: https://github.com/streamich/react-use · 18.0.0 → 19.0.0
Summary
State
done
Total events
28
Patches
3
Tests
2
Failures
1
Signature
- Algorithm
ed25519- Public key
b0958269516bb44d6f08a5d2be6451a47e5c7e26a1f480689243416aeba0c401- Message hash
969b7fc80153608ccffabbebc4e29e9e5c32a651fa07f5356dde8b2b58dabca9- Signature
7a352feb5bc0f39d8b8e3a0d6babbdcf5af4f1a8227684cc4ff395d3956f3dad1e38b5e579a89e18e407c2830f59875d8b28184401190771f41c1ba2bc45dc05- Signed at
2026-05-17T15:16:55.725Z
Verify cryptographically
Hand this signed report to a third party — auditor, compliance, or yourself in six months — and they can confirm tamper-freedom without trusting Renatus.
The verifier runs entirely in your browser — paste-and-verify, or click "Open in verifier" to auto-fill both fields.
Patches (3)
stories/usePinchZoom.story.tsxproposedconfidence 85%· Updated useRef() calls to provide an initial value of null, as required by React 19.
Before
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { usePinchZoom } from '../src';
import { ZoomState } from '../src/usePinchZoom';
import ShowDocs from './util/ShowDocs';
const Demo = () => {
const [scale, setState] = useState(1);
const scaleRef = useRef();
const { zoomingState, pinchState } = usePinchZoom(scaleRef);
useEffect(() => {
if (zoomingState === ZoomState.ZOOMING_IN) {
// perform zoom in scaling
setState(scale + 0.1);
} else if (zoomingState === ZoomState.ZOOMING_OUT) {
// perform zoom out in scaling
setState(scale - 0.1);
}
}, [zoomingState, pinchState]);
return (
<div ref={scaleRef}>
<img
src="https://www.olympus-imaging.co.in/content/000107506.jpg"
style={{
zoom: scale,
}}
alt="scale img"
/>
</div>
);
};
storiesOf('Sensors/usePinchZoom', module)
.add('Docs', () => <ShowDocs md={require('../docs/usePinchZoom.md')} />)
.add('Default', () => <Demo />);
After
import { storiesOf } from '@storybook/react';
import * as React from 'react';
import { useEffect, useRef, useState } from 'react';
import { usePinchZoom } from '../src';
import { ZoomState } from '../src/usePinchZoom';
import ShowDocs from './util/ShowDocs';
const Demo = () => {
const [scale, setState] = useState(1);
const scaleRef = useRef(null);
const { zoomingState, pinchState } = usePinchZoom(scaleRef);
useEffect(() => {
if (zoomingState === ZoomState.ZOOMING_IN) {
// perform zoom in scaling
setState(scale + 0.1);
} else if (zoomingState === ZoomState.ZOOMING_OUT) {
// perform zoom out in scaling
setState(scale - 0.1);
}
}, [zoomingState, pinchState]);
return (
<div ref={scaleRef}>
<img
src="https://www.olympus-imaging.co.in/content/000107506.jpg"
style={{ zoom: scale }}
alt="scale img"
/>
</div>
);
};
storiesOf('Sensors/usePinchZoom', module)
.add('Docs', () => <ShowDocs md={require('../docs/usePinchZoom.md')} />)
.add('Default', () => <Demo />);
tests/useEnsuredForwardedRef.test.tsxproposedconfidence 85%· Updated ReactDOM.render to ReactDOM.createRoot to comply with React 19's removal of the legacy ReactDOM.render API.
Before
import React, { useRef } from 'react';
import ReactDOM from 'react-dom';
import { renderHook } from '@testing-library/react-hooks';
import TestUtils from 'react-dom/test-utils';
import { ensuredForwardRef, useEnsuredForwardedRef } from '../src';
let container: HTMLDivElement;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
document.body.removeChild(container);
container = null!;
});
test('should return a valid ref with existing forwardedRef', () => {
const { result } = renderHook(() => {
const ref = useRef(null);
const ensuredRef = useEnsuredForwardedRef(ref);
TestUtils.act(() => {
ReactDOM.render(<div ref={ensuredRef} />, container);
});
return {
initialRef: ref,
ensuredForwardedRef: ensuredRef,
};
});
const { initialRef, ensuredForwardedRef } = result.current;
expect(ensuredForwardedRef).toStrictEqual(initialRef);
});
test('should return a valid ref when the forwarded ref is undefined', () => {
const { result } = renderHook(() => {
const ref = useEnsuredForwardedRef<HTMLDivElement>(undefined!);
TestUtils.act(() => {
ReactDOM.render(<div id="test_id" ref={ref} />, container);
});
return { ensuredRef: ref };
});
const { ensuredRef } = result.current;
expect(ensuredRef.current.id).toBe('test_id');
});
test('should return a valid ref when using the wrapper function style', () => {
const { result } = renderHook(() => {
const initialRef = useRef<HTMLDivElement | null>(null);
const WrappedComponent = ensuredForwardRef<HTMLDivElement>((_props, ref) => {
return <div id="test_id" ref={ref} />;
});
TestUtils.act(() => {
ReactDOM.render(<WrappedComponent ref={initialRef} />, container);
});
return { initialRef };
});
const { initialRef } = result.current;
expect(initialRef.current).toBeTruthy();
expect(initialRef.current?.id).toBe('test_id');
});
After
import React, { useRef } from 'react';
import { createRoot } from 'react-dom/client';
import TestUtils from 'react-dom/test-utils';
import { ensuredForwardRef, useEnsuredForwardedRef } from '../src';
let container: HTMLDivElement;
beforeEach(() => {
container = document.createElement('div');
document.body.appendChild(container);
});
afterEach(() => {
document.body.removeChild(container);
container = null!;
});
test('should return a valid ref with existing forwardedRef', () => {
const { result } = renderHook(() => {
const ref = useRef(null);
const ensuredRef = useEnsuredForwardedRef(ref);
TestUtils.act(() => {
const root = createRoot(container);
root.render(<div ref={ensuredRef} />);
});
return { initialRef: ref, ensuredForwardedRef: ensuredRef };
});
const { initialRef, ensuredForwardedRef } = result.current;
expect(ensuredForwardedRef).toStrictEqual(initialRef);
});
test('should return a valid ref when the forwarded ref is undefined', () => {
const { result } = renderHook(() => {
const ref = useEnsuredForwardedRef<HTMLDivElement>(undefined!);
TestUtils.act(() => {
const root = createRoot(container);
root.render(<div id="test_id" ref={ref} />);
});
return { ensuredRef: ref };
});
const { ensuredRef } = result.current;
expect(ensuredRef.current.id).toBe('test_id');
});
test('should return a valid ref when using the wrapper function style', () => {
const { result } = renderHook(() => {
const initialRef = useRef<HTMLDivElement | null>(null);
const WrappedComponent = ensuredForwardRef<HTMLDivElement>((_props, ref) => {
return <div id="test_id" ref={ref} />;
});
TestUtils.act(() => {
const root = createRoot(container);
root.render(<WrappedComponent ref={initialRef} />);
});
return { initialRef };
});
const { initialRef } = result.current;
expect(initialRef.current).toBeTruthy();
expect(initialRef.current?.id).toBe('test_id');
});
tests/useIntersection.test.tsxproposedconfidence 85%· Updated ReactDOM.render to ReactDOM.createRoot to comply with React 19's removal of the legacy ReactDOM.render API.
Before
import React, { createRef } from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-dom/test-utils';
import TestRenderer from 'react-test-renderer';
import { intersectionObserver } from '@shopify/jest-dom-mocks';
import { renderHook } from '@testing-library/react-hooks';
import { useIntersection } from '../src';
beforeEach(() => {
intersectionObserver.mock();
const IO = IntersectionObserver;
jest.spyOn(IO.prototype, 'disconnect');
jest.spyOn(global as any, 'IntersectionObserver');
IntersectionObserver.prototype = IO.prototype;
});
afterEach(() => {
intersectionObserver.restore();
});
describe('useIntersection', () => {
const container = document.createElement('div');
let targetRef;
it('should be defined', () => {
expect(useIntersection).toBeDefined();
});
it('should setup an IntersectionObserver targeting the ref element and using the options provided', () => {
TestUtils.act(() => {
targetRef = createRef();
ReactDOM.render(<div ref={targetRef} />, container);
});
expect(intersectionObserver.observers).toHaveLength(0);
const observerOptions = { root: null, threshold: 0.8 };
renderHook(() => useIntersection(targetRef, observerOptions));
expect(intersectionObserver.observers).toHaveLength(1);
expect(intersectionObserver.observers[0].target).toEqual(targetRef.current);
expect(intersectionObserver.observers[0].options).toEqual(observerOptions);
});
it('should return null if a ref without a current value is provided', () => {
targetRef = createRef();
const { result } = renderHook(() => useIntersection(targetRef, { root: null, threshold: 1 }));
expect(result.current).toBe(null);
});
it('should reset an intersectionObserverEntry when the ref changes', () => {
TestUtils.act(() => {
targetRef = createRef();
ReactDOM.render(<div ref={targetRef} />, container);
});
const { result, rerender } = renderHook(() =>
useIntersection(targetRef, { root: container, threshold: 0.8 })
);
const mockIntersectionObserverEntry = {
boundingClientRect: targetRef.current.getBoundingClientRect(),
intersectionRatio: 0.81,
intersectionRect: container.getBoundingClientRect(),
isIntersecting: true,
rootBounds: container.getBoundingClientRect(),
target: targetRef.current,
time: 300,
};
TestRenderer.act(() => {
intersectionObserver.simulate(mockIntersectionObserverEntry);
});
expect(result.current).toEqual(mockIntersectionObserverEntry);
targetRef.current = document.createElement('div');
rerender();
expect(result.current).toEqual(null);
});
it('should return null if IntersectionObserver is not supported', () => {
targetRef = createRef();
targetRef.current = document.createElement('div');
delete (window as any).IntersectionObserver;
expect(() => renderHook(() => useIntersection(targetRef, {}))).not.toThrow();
});
it('should disconnect an old IntersectionObserver instance when the ref changes', () => {
targetRef = createRef();
targetRef.current = document.createElement('div');
const { rerender } = renderHook(() => useIntersection(targetRef, {}));
targetRef.current = document.createElement('div');
rerender();
targetRef.current = null;
rerender();
expect(IntersectionObserver).toHaveBeenCalledTimes(2);
expect(IntersectionObserver.prototype.disconnect).toHaveBeenCalledTimes(2);
});
it('should return the first IntersectionObserverEntry when the IntersectionObserver registers an intersection', () => {
TestUtils.act(() => {
targetRef = createRef();
ReactDOM.render(<div ref={targetRef} />, container);
});
const { result } = renderHook(() =>
useIntersection(targetRef, { root: container, threshold: 0.8 })
);
const mockIntersectionObserverEntry = {
boundingClientRect: targetRef.current.getBoundingClientRect(),
intersectionRatio: 0.81,
intersectionRect: container.getBoundingClientRect(),
isIntersecting: true,
rootBounds: container.getBoundingClientRect(),
target: targetRef.current,
time: 300,
};
TestRenderer.act(() => {
intersectionObserver.simulate(mockIntersectionObserverEntry);
});
expect(result.current).toEqual(mockIntersectionObserverEntry);
});
it('should setup a new IntersectionObserver when the ref changes', () => {
let newRef;
TestUtils.act(() => {
targetRef = createRef();
newRef = createRef();
ReactDOM.render(
<div ref={targetRef}>
<span ref={newRef} />
</div>,
container
);
});
const observerOptions = { root: null, threshold: 0.8 };
const { rerender } = renderHook(({ ref, options }) => useIntersection(ref, options), {
initialProps: { ref: targetRef, options: observerOptions },
});
expect(intersectionObserver.observers[0].target).toEqual(targetRef.current);
TestRenderer.act(() => {
rerender({ ref: newRef, options: observerOptions });
});
expect(intersectionObserver.observers[0].target).toEqual(newRef.current);
});
it('should setup a new IntersectionObserver when the options change', () => {
TestUtils.act(() => {
targetRef = createRef();
ReactDOM.render(<div ref={targetRef} />, container);
});
const initialObserverOptions = { root: null as HTMLElement | null, threshold: 0.8 };
const { rerender } = renderHook(({ ref, options }) => useIntersection(ref, options), {
initialProps: { ref: targetRef, options: initialObserverOptions },
});
expect(intersectionObserver.observers[0].options).toEqual(initialObserverOptions);
const newObserverOptions = { root: container, threshold: 1 };
TestRenderer.act(() => {
rerender({ ref: targetRef, options: newObserverOptions });
});
expect(intersectionObserver.observers[0].options).toEqual(newObserverOptions);
});
});
After
import React, { createRef } from 'react';
import ReactDOM from 'react-dom/client';
import TestUtils from 'react-dom/test-utils';
import TestRenderer from 'react-test-renderer';
import { intersectionObserver } from '@shopify/jest-dom-mocks';
import { useIntersection } from '../src';
beforeEach(() => {
intersectionObserver.mock();
const IO = IntersectionObserver;
jest.spyOn(IO.prototype, 'disconnect');
jest.spyOn(global as any, 'IntersectionObserver');
IntersectionObserver.prototype = IO.prototype;
});
afterEach(() => {
intersectionObserver.restore();
});
describe('useIntersection', () => {
const container = document.createElement('div');
let targetRef;
it('should be defined', () => {
expect(useIntersection).toBeDefined();
});
it('should setup an IntersectionObserver targeting the ref element and using the options provided', () => {
TestUtils.act(() => {
targetRef = createRef();
ReactDOM.createRoot(container).render(<div ref={targetRef} />);
});
expect(intersectionObserver.observers).toHaveLength(0);
const observerOptions = { root: null, threshold: 0.8 };
renderHook(() => useIntersection(targetRef, observerOptions));
expect(intersectionObserver.observers).toHaveLength(1);
expect(intersectionObserver.observers[0].target).toEqual(targetRef.current);
expect(intersectionObserver.observers[0].options).toEqual(observerOptions);
});
it('should return null if a ref without a current value is provided', () => {
targetRef = createRef();
const { result } = renderHook(() => useIntersection(targetRef, { root: null, threshold: 1 }));
expect(result.current).toBe(null);
});
it('should reset an intersectionObserverEntry when the ref changes', () => {
TestUtils.act(() => {
targetRef = createRef();
ReactDOM.createRoot(container).render(<div ref={targetRef} />);
});
const { result, rerender } = renderHook(() =>
useIntersection(targetRef, { root: container, threshold: 0.8 })
);
const mockIntersectionObserverEntry = {
boundingClientRect: targetRef.current.getBoundingClientRect(),
intersectionRatio: 0.81,
intersectionRect: container.getBoundingClientRect(),
isIntersecting: true,
rootBounds: container.getBoundingClientRect(),
target: targetRef.current,
time: 300,
};
TestRenderer.act(() => {
intersectionObserver.simulate(mockIntersectionObserverEntry);
});
expect(result.current).toEqual(mockIntersectionObserverEntry);
targetRef.current = document.createElement('div');
rerender();
expect(result.current).toEqual(null);
});
it('should return null if IntersectionObserver is not supported', () => {
targetRef = createRef();
targetRef.current = document.createElement('div');
delete (window as any).IntersectionObserver;
expect(() => renderHook(() => useIntersection(targetRef, {}))).not.toThrow();
});
it('should disconnect an old IntersectionObserver instance when the ref changes', () => {
targetRef = createRef();
targetRef.current = document.createElement('div');
const { rerender } = renderHook(() => useIntersection(targetRef, {}));
targetRef.current = document.createElement('div');
rerender();
targetRef.current = null;
rerender();
expect(IntersectionObserver).toHaveBeenCalledTimes(2);
expect(IntersectionObserver.prototype.disconnect).toHaveBeenCalledTimes(2);
});
it('should return the first IntersectionObserverEntry when the IntersectionObserver registers an intersection', () => {
TestUtils.act(() => {
targetRef = createRef();
ReactDOM.createRoot(container).render(<div ref={targetRef} />);
});
const { result } = renderHook(() =>
useIntersection(targetRef, { root: container, threshold: 0.8 })
);
const mockIntersectionObserverEntry = {
boundingClientRect: targetRef.current.getBoundingClientRect(),
intersectionRatio: 0.81,
intersectionRect: container.getBoundingClientRect(),
isIntersecting: true,
rootBounds: container.getBoundingClientRect(),
target: targetRef.current,
time: 300,
};
TestRenderer.act(() => {
intersectionObserver.simulate(mockIntersectionObserverEntry);
});
expect(result.current).toEqual(mockIntersectionObserverEntry);
});
it('should setup a new IntersectionObserver when the ref changes', () => {
let newRef;
TestUtils.act(() => {
targetRef = createRef();
newRef = createRef();
ReactDOM.createRoot(container).render(
<div ref={targetRef}>
<span ref={newRef} />
</div>
);
});
const observerOptions = { root: null as HTMLElement | null, threshold: 0.8 };
const { rerender } = renderHook(({ ref, options }) => useIntersection(ref, options), { initialProps: { ref: targetRef, options: observerOptions } });
expect(intersectionObserver.observers[0].target).toEqual(targetRef.current);
TestRenderer.act(() => {
rerender({ ref: newRef, options: observerOptions });
});
expect(intersectionObserver.observers[0].target).toEqual(newRef.current);
});
it('should setup a new IntersectionObserver when the options change', () => {
TestUtils.act(() => {
targetRef = createRef();
ReactDOM.createRoot(container).render(<div ref={targetRef} />);
});
const initialObserverOptions = { root: null as HTMLElement | null, threshold: 0.8 };
const { rerender } = renderHook(({ ref, options }) => useIntersection(ref, options), { initialProps: { ref: targetRef, options: initialObserverOptions } });
expect(intersectionObserver.observers[0].options).toEqual(initialObserverOptions);
const newObserverOptions = { root: container, threshold: 1 };
TestRenderer.act(() => {
rerender({ ref: targetRef, options: newObserverOptions });
});
expect(intersectionObserver.observers[0].options).toEqual(newObserverOptions);
});
});Continue with this codebase
Snapshot ID:
21b64a1d-ac66-438a-8311-e4a3f4f103ebSame engine, different agent. Click any to pre-fill the form with this repo.
Generated tests (2)
tests/useEnsuredForwardedRef.test.test.tsxjestsnapshotunruntests/useIntersection.test.test.tsxjestsnapshotunrun
The full event log is also available via GET /api/jobs/704ec574-8a4a-4f9e-9294-ab6e21a8e7b2/audit-report as canonical JSON.