← Back to all jobsRenatus · signed audit report
migrateAudit fcfabfee
Repository: https://github.com/streamich/react-use · 18.0.0 → 19.0.0
Summary
State
done
Total events
28
Patches
3
Tests
3
Failures
0
Signature
- Algorithm
ed25519- Public key
6accf63e988bb5b68cef123f6df6c9f2c4a779e0bfc7fd8e4028ab6737d870ce- Message hash
1f07d50ca99fc3730ccef4e03ebf5e7497fcabef24e6f8541dca65a22b152c84- Signature
addbea4392bffa993217d6dea8b81483eb8add8f588edcae92bb172d3b2e41f33c2c8fb4ac0dc6fe13028f00519fcaf6ffdef5b2672f5c6440cd8100a4dc370e- Signed at
2026-05-17T13:02:53.823Z
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 createRoot as per the rule react-19-reactdom-render-removal.
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);
createRoot(container).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!);
createRoot(container).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} />;
});
createRoot(container).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:
198c5ae0-675f-427f-954b-40945768a0f3Same engine, different agent. Click any to pre-fill the form with this repo.
Generated tests (3)
stories/usePinchZoom.story.test.tsxjestsnapshotunruntests/useEnsuredForwardedRef.test.test.tsxjestsnapshotunruntests/useIntersection.test.test.tsxjestsnapshotunrun
The full event log is also available via GET /api/jobs/fcfabfee-8401-4142-be18-5999a01ef151/audit-report as canonical JSON.