Skip to content

Commit c995882

Browse files
author
tyler
committed
chore: drop Node 18 from CI matrix, fix useObservable test for Vitest 4
Vite 8 (via rolldown) requires Node 20+ for styleText from node:util. Update CI test matrix to Node 20/22 and build/publish jobs to Node 20. Node 18 reached EOL in April 2025. Also fix the "throws an error if no observableId is provided" test which was failing under Vitest 4. React 18 dispatches a window error event when a component throws during render, even when the throw is caught by expect().toThrow(). Vitest 4 surfaces these as uncaught errors. Fix by adding a window error listener that calls preventDefault(), and match on the error message via expect.objectContaining to account for React setting _suppressLogging on the error object. Also widen the firebase peerDependency to accept v10/v11/v12.
1 parent ce413a7 commit c995882

3 files changed

Lines changed: 14 additions & 5 deletions

File tree

.github/workflows/test.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- name: Setup node
2424
uses: actions/setup-node@v4
2525
with:
26-
node-version: '18'
26+
node-version: '20'
2727
cache: 'npm'
2828
- name: Install deps
2929
run: npm ci
@@ -44,7 +44,7 @@ jobs:
4444
needs: build
4545
strategy:
4646
matrix:
47-
node: ["18", "20"]
47+
node: ["20", "22"]
4848
fail-fast: false
4949
name: Test Node.js ${{ matrix.node }} (Ubuntu)
5050
steps:
@@ -83,7 +83,7 @@ jobs:
8383
- name: Setup node
8484
uses: actions/setup-node@v4
8585
with:
86-
node-version: '18'
86+
node-version: '20'
8787
registry-url: 'https://registry.npmjs.org'
8888
- name: 'Download Artifacts'
8989
uses: actions/download-artifact@v4

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"docs:fork": "typedoc --options typedoc.json --gitRemote upstream && markdown-toc -i docs/use.md"
3737
},
3838
"peerDependencies": {
39-
"firebase": "^9.0.0 || next",
39+
"firebase": "^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || next",
4040
"react": ">=16 || experimental"
4141
},
4242
"husky": {

test/useObservable.test.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,23 @@ describe('useObservable', () => {
137137
const spy = vi.spyOn(console, 'error');
138138
spy.mockImplementation(() => {});
139139

140+
// React 18 dispatches a window error event when a component throws during render
141+
// even when caught by expect().toThrow(). Prevent it from surfacing as an uncaught
142+
// error in environments where Vitest treats those as test failures.
143+
// Note: e.preventDefault() causes React to set _suppressLogging:true on the error,
144+
// so we match on message only via expect.objectContaining.
145+
const onError = (e: ErrorEvent) => e.preventDefault();
146+
window.addEventListener('error', onError);
147+
140148
const observable$: Subject<any> = new Subject();
141149

142150
// @ts-expect-error we're trying to break useObservable
143151
expect(() => renderHook(() => useObservable(undefined, observable$, { suspense: true }))).toThrow(
144-
Error('cannot call useObservable without an observableId')
152+
expect.objectContaining({ message: 'cannot call useObservable without an observableId' })
145153
);
146154

147155
spy.mockRestore();
156+
window.removeEventListener('error', onError);
148157
});
149158

150159
it('can return a startval and then the observable once it is ready', () => {

0 commit comments

Comments
 (0)