Tests for @preact/signals-react/runtime fail on latest main on Mac OS 10.15.7 and Chrome 123
Full logs:
```
signals git:(main) pnpm test
> preact-signals@ test /Users/alex/src/github.com/preactjs/signals
> pnpm test:karma && pnpm test:mocha
> preact-signals@ test:karma /Users/alex/src/github.com/preactjs/signals
> cross-env COVERAGE=true karma start karma.conf.js --single-run
Transforming tests using /Users/alex/src/github.com/preactjs/signals/packages/react-transform/dist/signals-transform.js.
Manually re-compile & re-run tests to validate changes to react-transform
START:
30 03 2024 14:19:04.318:INFO [esbuild]: Compiling...
30 03 2024 14:19:05.654:INFO [esbuild]: Compiling done (1s)
30 03 2024 14:19:05.659:INFO [karma-server]: Karma v6.4.2 server started at http://localhost:9876/
30 03 2024 14:19:05.659:INFO [launcher]: Launching browsers ChromeNoSandboxHeadless with concurrency 2
30 03 2024 14:19:05.665:INFO [launcher]: Starting browser Chrome
30 03 2024 14:19:12.303:INFO [Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)]: Connected on socket fXymWpkUFmFIDJnfAAAB with id 82731752
signal
✔ should return value
✔ should inherit from Signal
✔ should support .toString()
✔ should support .toJSON()
✔ should support JSON.Stringify()
✔ should support .valueOf()
✔ should notify other listeners of changes after one listener is disposed
✔ signals should be identified with a symbol
✔ should be identified with a symbol
.peek()
✔ should get value
✔ should get the updated value after a value change
✔ should not make surrounding effect depend on the signal
✔ should not make surrounding computed depend on the signal
.subscribe()
✔ should subscribe to a signal
✔ should run the callback when the signal value changes
✔ should unsubscribe from a signal
✔ should not start triggering on when a signal accessed in the callback changes
✔ should not cause surrounding effect to subscribe to changes to a signal accessed in the callback
effect()
✔ should init with value
✔ should subscribe to signals
✔ should subscribe to multiple signals
✔ should dispose of subscriptions
✔ should unsubscribe from signal
✔ should conditionally unsubscribe from signals
✔ should batch writes
✔ should call the cleanup callback before the next run
✔ should call only the callback from the previous run
✔ should call the cleanup callback function when disposed
✔ should not recompute if the effect has been notified about changes, but no direct dependency has actually changed
✔ should not recompute dependencies unnecessarily
✔ should not recompute dependencies out of order
✔ should recompute if a dependency changes during computation after becoming a dependency
✔ should run the cleanup in an implicit batch
✔ should not retrigger the effect if the cleanup modifies one of the dependencies
✔ should run the cleanup if the effect disposes itself
✔ should not run the effect if the cleanup function disposes it
✔ should not subscribe to anything if first run throws
✔ should reset the cleanup if the effect throws
✔ should dispose the effect if the cleanup callback throws
✔ should run cleanups outside any evaluation context
✔ should throw on cycles
✔ should throw on indirect cycles
✔ should allow disposing the effect multiple times
✔ should allow disposing a running effect
✔ should not run if it's first been triggered and then disposed in a batch
✔ should not run if it's been triggered, disposed and then triggered again in a batch
✔ should not rerun parent effect if a nested child effect's signal's value changes
internals
✔ should pass in the effect instance in callback's `this`
✔ should allow setting _callback that replaces the default functionality
✔ should return a function for closing the effect scope from _start
✔ should throw on out-of-order start1-start2-end1 sequences
✔ should throw a cycle detection error when _start is called while the effect is running
✔ should dispose the effect on _dispose
✔ should allow reusing the effect after disposing it
✔ should have property _sources that is undefined when and only when the effect has no sources
computed()
✔ should return value
✔ should inherit from Signal
✔ should return updated value
✔ should be lazily computed on demand
✔ should be computed only when a dependency has changed at some point
✔ should recompute if a dependency changes during computation after becoming a dependency
✔ should detect simple dependency cycles
✔ should detect deep dependency cycles
✔ should not allow a computed signal to become a direct dependency of itself
✔ should store thrown errors and recompute only after a dependency changes
✔ should store thrown non-errors and recompute only after a dependency changes
✔ should conditionally unsubscribe from signals
✔ should consider undefined value separate from uninitialized value
✔ should not leak errors raised by dependencies
✔ should propagate notifications even right after first subscription
✔ should get marked as outdated right after first subscription
✔ should propagate notification to other listeners after one listener is disposed
✔ should not recompute dependencies out of order
✔ should not recompute dependencies unnecessarily
.peek()
✔ should get value
✔ should throw when evaluation throws
✔ should throw when previous evaluation threw and dependencies haven't changed
✔ should refresh value if stale
✔ should detect simple dependency cycles
✔ should detect deep dependency cycles
✔ should not make surrounding effect depend on the computed
✔ should not make surrounding computed depend on the computed
✔ should not make surrounding effect depend on the peeked computed's dependencies
✔ should not make surrounding computed depend on peeked computed's dependencies
garbage collection
✔ should be garbage collectable if nothing is listening to its changes
✔ should be garbage collectable after it has lost all of its listeners
graph updates
✔ should run computeds once for multiple dep changes
✔ should drop A->B->A updates
✔ should only update every signal once (diamond graph)
✔ should only update every signal once (diamond graph + tail)
✔ should bail out if result is the same
✔ should only update every signal once (jagged diamond graph + tails)
✔ should only subscribe to signals listened to
✔ should only subscribe to signals listened to
✔ should ensure subs update even if one dep unmarks it
✔ should ensure subs update even if two deps unmark it
error handling
✔ should throw when writing to computeds
✔ should keep graph consistent on errors during activation
✔ should keep graph consistent on errors in computeds
✔ should support lazy branches
✔ should not update a sub if all deps unmark it
batch/transaction
✔ should return the value from the callback
✔ should throw errors thrown from the callback
✔ should throw non-errors thrown from the callback
✔ should delay writes
✔ should delay writes until outermost batch is complete
✔ should read signals written to
✔ should read computed signals with updated source signals
✔ should not block writes after batching completed
✔ should not lead to stale signals with .value in batch
✔ should not lead to stale signals with peek() in batch
✔ should run pending effects even if the callback throws
✔ should run pending effects even if some effects throw
✔ should run effect's first run immediately even inside a batch
untracked
✔ should block tracking inside effects
✔ should block tracking even when run inside effect run inside untracked
✔ should not cause signal assignments throw
✔ should block tracking inside computed signals
@preact/signals
exports
✔ should re-export core
inheritance
✔ should have signals inherit from Signal
✔ should have computed inherit from Signal
SignalValue bindings
✔ should render text without signals
✔ should render Signals as SignalValue
✔ should update Signal-based SignalValue (no parent component)
✔ should update Signal-based SignalValue (in a parent component)
✔ should support swapping Signals in SignalValue positions
✔ should support rendering JSX in SignalValue positions
✔ JSX in SignalValue should be reactive
✔ should support swapping between JSX and string in SignalValue positions
Component bindings
✔ should subscribe to signals
✔ should activate signal accessed in render
✔ should not subscribe to child signals
✔ should minimize rerenders when passing signals through context
✔ should not subscribe to computed signals only created and not used
✔ should properly subscribe and unsubscribe to conditionally rendered computed signals
prop bindings
✔ should set the initial value of the checked property
✔ should update the checked property on change
✔ should update props without re-rendering
✔ should set and update string style property
✔ should set updated signal prop values at most once
✔ should set SVG values
hooks mixed with signals
✔ signals should not stop context from propagating
useSignalEffect()
✔ should be invoked after commit
✔ should invoke any returned cleanup function for updates
✔ should invoke any returned cleanup function for unmounts
SSR
✔ should render without erroring
✔ should not subscribe properties to signals
✔ should not subscribe Components to Signals
✔ should allow re-rendering signals multiple times
✔ should render computed signals
✔ should render updated values for mutated computed signals
✔ should allow signal mutation during rendering
SignalValue bindings
✔ should render strings
✔ should encode HTML entities
✔ should render numbers as text
✔ should not render booleans
Property bindings
✔ should render Signal prop values
React Signals babel transfrom - browser E2E tests
✔ should rerender components when using signals as text
✔ should rerender components when signals they use change
✔ should rerender components with custom hooks that use signals
✔ should rerender components with multiple custom hooks that use signals
✔ should rerender components that use signals with multiple custom hooks that use signals
✔ should rerender components wrapped in memo
✔ should rerender components wrapped in memo inline
✔ should rerender components wrapped in forwardRef
✔ should rerender components wrapped in forwardRef inline
✔ should rerender components wrapped in forwardRef with memo
✔ should rerender registry-style declared components
✔ should transform components authored inside a test's body
✔ should work when an ambiguous function is manually transformed and used as a hook
✔ loads useSignals from a custom source
✔ works with the `using` keyword
@preact/signals-react/auto
mounting
mount text bindings
✔ should render text without signals
✔ should render Signals as SignalValue
✔ should render computed as SignalValue
mount component bindings
✔ should mount component with signals as text
✔ should activate signal accessed in render
✔ should properly mount in strict mode
✔ should correctly mount components that have useReducer()
✔ should not fail when a component calls setState while mounting
✔ should not fail when a component calls setState multiple times while mounting
useSignal()
✔ should create a signal from a primitive value
✔ should properly update signal values changed during mount
updating
SignalValue bindings
✔ should render text without signals
✔ should render Signals as SignalValue
✔ should render computed as SignalValue
✔ should update Signal-based SignalValue (no parent component)
✔ should update Signal-based SignalValue (in a parent component)
✔ should work with JSX inside signal
Component bindings
✔ should subscribe to signals
✔ should rerender components when signals they use change
✔ should subscribe to signals passed as props to DOM elements
✔ should activate signal accessed in render
✔ should not subscribe to child signals
✔ should update memo'ed component via signals
✔ should update forwardRef'ed component via signals
✔ should consistently rerender in strict mode
✔ should consistently rerender in strict mode (with memo)
✔ should render static markup of a component
✔ should correctly render components that have useReducer()
✔ should not fail when a component calls setState while rendering
✔ should not fail when a component calls setState multiple times while rendering
✔ should not fail when a component only uses state-less hooks
✔ should minimize rerenders when passing signals through context
✔ should not subscribe to computed signals only created and not used
✔ should properly subscribe and unsubscribe to conditionally rendered computed signals
useSignal()
✔ should create a signal from a primitive value
useSignalEffect()
✔ should be invoked after commit
✔ should invoke any returned cleanup function for updates
✔ should invoke any returned cleanup function for unmounts
@preact/signals-react/runtime
mounting
mount text bindings
✔ should render text without signals
✔ should render Signals as SignalValue
✔ should render computed as SignalValue
mount component bindings
✔ should mount component with signals as text
✔ should activate signal accessed in render
✔ should properly mount in strict mode
✔ should correctly mount components that have useReducer()
✔ should not fail when a component calls setState while mounting
✔ should not fail when a component calls setState multiple times while mounting
useSignal()
✔ should create a signal from a primitive value
✔ should properly update signal values changed during mount
updating
SignalValue bindings
✔ should render text without signals
✔ should render Signals as SignalValue
✔ should render computed as SignalValue
✔ should update Signal-based SignalValue (no parent component)
✔ should update Signal-based SignalValue (in a parent component)
✔ should work with JSX inside signal
Component bindings
✖ should subscribe to signals
✔ should rerender components when signals they use change
✔ should activate signal accessed in render
✔ should not subscribe to child signals
✖ should update memo'ed component via signals
✖ should update forwardRef'ed component via signals
✖ should consistently rerender in strict mode
✖ should consistently rerender in strict mode (with memo)
✖ should correctly render components that have useReducer()
✔ should not fail when a component calls setState while rendering
✔ should not fail when a component calls setState multiple times while rendering
✔ should not fail when a component only uses state-less hooks
✖ should minimize rerenders when passing signals through context
✖ should not subscribe to computed signals only created and not used
✖ should properly subscribe and unsubscribe to conditionally rendered computed signals
useSignal()
✔ should create a signal from a primitive value
useSignalEffect()
✖ should be invoked after commit
✖ should invoke any returned cleanup function for updates
✔ should invoke any returned cleanup function for unmounts
useSignals
✔ should rerender components when signals they use change
✔ should correctly invoke rerenders if useSignals is called multiple times in the same component
✔ should not rerender components when signals they use do not change
✔ should not rerender components when signals they use change but they are not mounted
✔ should not rerender components that only update signals in event handlers
✔ should not rerender components that only read signals in event handlers
✔ should properly rerender components that use custom hooks
✔ should properly rerender components that use custom hooks and signals
✖ (managed) should work with components that use render props (skipped)
✔ (unmanaged) should work with components that use render props
ERROR: 'Warning: An update to %s inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act%s', 'C', '
at C (http://localhost:9876/base/packages/react/runtime/test/browser/useSignals.test.js?42b846454994019967306412fa3dc0b12d1b7a72:48956:13)'
✔ (unmanaged) (React 16 specific) should work with rerenders that update signals before async final cleanup
using hooks that call useSignal in components that call useSignals
✔ ManagedComponent > managed hook
✔ ManagedComponent > unmanaged hook
✔ UnmanagedComponent > managed hook
✔ UnmanagedComponent > unmanaged hook
✔ ManagedComponent > managed hook + managed hook
✔ ManagedComponent > managed hook + unmanaged hook
✔ ManagedComponent > unmanaged hook + managed hook
✔ ManagedComponent > unmanaged hook + unmanaged hook
✔ UnmanagedComponent > managed hook + managed hook
✔ UnmanagedComponent > managed hook + unmanaged hook
✔ UnmanagedComponent > unmanaged hook + managed hook
✔ UnmanagedComponent > unmanaged hook + unmanaged hook
using nested hooks that each call useSignals in components that call useSignals
✔ ManagedComponent > managed hook > managed hook
✔ ManagedComponent > managed hook > unmanaged hook
✔ ManagedComponent > unmanaged hook > managed hook
✔ ManagedComponent > unmanaged hook > unmanaged hook
✔ UnmanagedComponent > managed hook > managed hook
✔ UnmanagedComponent > managed hook > unmanaged hook
✔ UnmanagedComponent > unmanaged hook > managed hook
✔ UnmanagedComponent > unmanaged hook > unmanaged hook
@preact/signals-react
exports
✔ should re-export core
react-router-dom
✔ Route component should render
Finished in 0.425 secs / 0.309 secs @ 14:19:13 GMT-0400 (Eastern Daylight Time)
SUMMARY:
✔ 267 tests completed
ℹ 1 test skipped
✖ 11 tests failed
FAILED TESTS:
@preact/signals-react/runtime
updating
Component bindings
✖ should subscribe to signals
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected 'foo' to equal 'bar'
+ expected - actual
-foo
+bar
at (packages/react/test/shared/updates.tsx:164:35)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should update memo'ed component via signals
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected 'foo' to equal 'bar'
+ expected - actual
-foo
+bar
at (packages/react/test/shared/updates.tsx:285:35)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should update forwardRef'ed component via signals
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected 'foo' to equal 'bar'
+ expected - actual
-foo
+bar
at (packages/react/test/shared/updates.tsx:305:35)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should consistently rerender in strict mode
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected '-1' to equal '0'
+ expected - actual
--1
+0
at (packages/react/test/shared/updates.tsx:325:36)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should consistently rerender in strict mode (with memo)
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected '-1' to equal '0'
+ expected - actual
--1
+0
at (packages/react/test/shared/updates.tsx:346:36)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should correctly render components that have useReducer()
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected '
-20-22-20
+
-22
at (packages/react/test/shared/updates.tsx:414:34)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should minimize rerenders when passing signals through context
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected 'https://domain.com/test?a=1' to equal 'https://domain.com/test?a=2'
+ expected - actual
-https://domain.com/test?a=1
+https://domain.com/test?a=2
at (packages/react/test/shared/updates.tsx:621:31)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should not subscribe to computed signals only created and not used
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected '
1
' to equal '
2
'
+ expected - actual
-
1
+
2
at (packages/react/test/shared/updates.tsx:652:33)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should properly subscribe and unsubscribe to conditionally rendered computed signals
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected '
1
' to equal '
2
'
+ expected - actual
-
1
+
2
at (packages/react/test/shared/updates.tsx:675:33)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
useSignalEffect()
✖ should be invoked after commit
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected 'foo' to equal 'bar'
+ expected - actual
-foo
+bar
at (packages/react/test/shared/updates.tsx:751:35)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
✖ should invoke any returned cleanup function for updates
Chrome Headless 123.0.6312.87 (Mac OS 10.15.7)
AssertionError: expected 'foo' to equal 'bar'
+ expected - actual
-foo
+bar
at (packages/react/test/shared/updates.tsx:802:35)
at Generator.next ()
at fulfilled (null:null:1 <- packages/react/runtime/test/browser/updates.test.js:35:26)
=============================== Coverage summary ===============================
Statements : 92.89% ( 719/774 )
Branches : 84.8% ( 374/441 )
Functions : 91.83% ( 135/147 )
Lines : 93.91% ( 694/739 )
================================================================================
ELIFECYCLE Command failed with exit code 1.
ELIFECYCLE Test failed. See above for more details.
```
Looks like I was running off of an outdated build and was mislead by seeing the esbuild logs in the tests thinking we ran a fresh build before tests. Tests are all green now.
Tests for
@preact/signals-react/runtime
fail on latest main on Mac OS 10.15.7 and Chrome 123Full logs:
1
' to equal '2
' + expected - actual -1
+2
at (packages/react/test/shared/updates.tsx:652:33) at Generator.next (1
' to equal '2
' + expected - actual -1
+2
at (packages/react/test/shared/updates.tsx:675:33) at Generator.next (