Help Needed: Issues with react and setInterval in test mode


#1

I’ve got a really weird issue with the minimap specs, you can see that in the Travis CI output.

There’s no stack trace on Travis so I put it here:

Uncaught Error: Invariant Violation: replaceState(...): Can only update a mounted or mounting component. .../atom/node_modules/react-atom-fork/lib/invariant.js:49 
invariant     .../atom/node_modules/react-atom-fork/lib/ReactCompositeComponent.js:444
validateLifeCycleOnReplaceState   .../atom/node_modules/react-atom-fork/lib/ReactCompositeComponent.js:869 
ReactCompositeComponentMixin.replaceState   .../atom/node_modules/react-atom-fork/lib/ReactCompositeComponent.js:850 
ReactCompositeComponentMixin.setState  cursors-component.coffee:55 
module.exports.React.createClass.toggleCursorBlink  .../atom/node_modules/react-atom-fork/lib/ReactCompositeComponent.js:1295 
boundMethod

These errors only occurs in tests, I haven’t once got it in dev or normal mode in Atom.

It seems that the cursor blink interval is restarted after the tests, triggering a state change, but the component is supposedly unmounted after the tests and I don’t see why it keeps running except for an issue with the way setInterval is mocked in tests.
They starts appearing something like 1s after the end of the test, as if clearing the fake setInterval was restarting previous interval with the original version.

Here’s the test setup:

https://github.com/fundon/atom-minimap/blob/master/spec/minimap-element-spec.coffee#L68-L111

This is roughly the same setup that core use to test the text editor component

Specifically it seems the issue comes from the spies on setInterval, if I comment them the errors stop popping up (but some tests fails as the clock can’t be advanced synchronously).

I’ve tried using the jasmine.Clock instead and the results is the same (errors keeps popping up in the console).
I’ve tried manually clearing the fake interval, no success.
I can’t patch the react component as the exports is only a function.

I considered at some point changing the blinking period to a value in hours so that it doesn’t meddle with the test but there’s just no place where this value is defined/set.

I’m quite at loss here, it doesn’t make Travis fails but it frequently crash Atom when running the tests on my computer. And I’m not inclined to replace the fake intervals in the tests with waitsFor directives.

Any suggestion is welcomed at this point.


#2

A quick follow-up given that I’m probably the only one to have experienced that issue, after having tried all the dirty hacks I could think of, the only solution to prevent these errors is to not mock setInterval and use a sleep-like block instead of advanceClock to make time passes.

I’m left with the errors raised in interval-skip-list that I can’t catch neither.


#3

Yeah, unfortunately, I haven’t ever run into this as I’ve never had to deal with setInterval or it’s related functions.