Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jasmine.clock().tick() does not trigger timeout for lodash.debounce() unless debugging #1787

Closed
jgonggrijp opened this issue Feb 21, 2020 · 1 comment

Comments

@jgonggrijp
Copy link

jgonggrijp commented Feb 21, 2020

When I install jasmine's mock clock, create a debounced function using lodash's implementation of _.debounce, invoke the debounced function and tell jasmine.clock() to .tick() beyond the debounce interval, a strange behavioral bifurcation occurs:

  • when run normally, the test fails (debounced function is never invoked);
  • when stepping through the code with a debugger, the test passes (debounced function is invoked).

See https://gitlab.com/jgonggrijp/jasmine-clock-debounce-testcase for a packaged, ready-to-run reduced testcase.

Are you creating an issue in the correct repository?

Maybe. This might be a bug in jasmine-core or in lodash. Since lodash.debounce appears to do the right thing in general, I'm trying Jasmine first.

Expected Behavior

The example suite should always pass.

Current Behavior

The example suite fails when run normally but passes when stepping through the code with a debugger.

Possible Solution

One apparent difference between the underscore implementation and the lodash implementation is that lodash inspects the numerical value of the current time while underscore does not. If the problem is in jasmine-core, then one of the possibilities is that the current time is somehow reported in an incorrect or incoherent way. However, I cannot explain why debugging would change this.

Suite that reproduces the behavior (for bugs)

The example suite below omits the underscore version; see https://gitlab.com/jgonggrijp/jasmine-clock-debounce-testcase for the full reduced testcase.

const lodash = require('lodash');

describe('jasmine.clock', function() {
    const timeout = 200;

    beforeEach(function() {
        jasmine.clock().install();
    });

    afterEach(function() {
        jasmine.clock().uninstall();
    });

    it('interacts strangely with lodash.debounce', function() {
        let state = 'initial';
        const trigger = lodash.debounce(transition, timeout);
        trigger();
        jasmine.clock().tick(timeout - 1);
        expect(state).toBe('initial');
        // Insert breakpoint here to make the test pass.
        jasmine.clock().tick(2);
        expect(state).toBe('final');

        function transition() {
            state = 'final';
        }
    });
});

Context

I am implementing a state machine with machina.js where some transitions are triggered automatically after a timeout. Some inputs should delay this transition, which is why I am using _.debounce. The fact that the test fails, except when I try to debug it, is really unhelpful.

Your Environment

@jgonggrijp
Copy link
Author

I have resolved my issue. My earlier observation, that lodash uses the numerical value of the current time while underscore does not, turned out to be the crucial difference.

After finding lodash/lodash#3559 and then jestjs/jest#3465, I realized that I needed to not only .install() the mock clock but also to invoke .mockDate() on it. I had seen this method mentioned in the Jasmine documentation before, but didn't make the connection until now.

So no bug in either library after all (although I'd argue that the lodash implementation of debounce looks overly complicated compared to the underscore implementation). Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant