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

Mocking date in past breaks event handlers #2005

Closed
Weetbix opened this issue Sep 9, 2022 · 1 comment
Closed

Mocking date in past breaks event handlers #2005

Weetbix opened this issue Sep 9, 2022 · 1 comment

Comments

@Weetbix
Copy link

Weetbix commented Sep 9, 2022

Mocking date in past breaks event handlers

It seems that when mocking the date with a date in the past, in a test in vue 3, the click handler is never called.

Steps to reproduce

I have a minimal reproduction on these two branches here:
Vue 3 (broken): https://github.com/Weetbix/vue-compat-composition-api-bug-repo/tree/jh/fake-date-vue3-broken
Vue 2 (working): https://github.com/Weetbix/vue-compat-composition-api-bug-repo/tree/jh/fake-date-vue2

You can run yarn then yarn test to see the results.

These are the tests:

import { defineComponent } from 'vue';
import {fireEvent, mount} from '@vue/test-utils';
import { afterEach, beforeEach, describe, expect, vi } from 'vitest';

const TestComponent = defineComponent({
    name: 'test',
    template: '<div>{{ text }}<button @click="onclick">clickme</button></div>',
    data() {
        return {
            text: '',
        };
    },
    methods: {
        async onclick() {
            this.text = 'set';
        },
    },
});

const stubDate = (isoDateString) => {
    class MockDate extends Date {
        static now() {
            return new Date(isoDateString).valueOf();
        }
    }
    vi.stubGlobal('Date', MockDate);
};

const fakeTimers = (date) => {
    vi.useFakeTimers();
    vi.setSystemTime(date);
};

it('should show text on click', async () => {
    const wrapper = mount(TestComponent);
    await wrapper.find('button').trigger('click');

    expect(wrapper.text()).toContain('set');
});

describe('', () => {
    beforeEach(() => {
        stubDate('2022-01-11T00:00:00Z');
    });

    afterEach(() => {
        vi.unmock('Date');
    });

    it('should show text when time mocked directly', async () => {
        const wrapper = mount(TestComponent);
        await wrapper.find('button').trigger('click');
        expect(wrapper.text()).toContain('set');
    });
})

describe('', () => {
    beforeEach(() => {
        fakeTimers('2022-01-11T00:00:00Z');
    });

    afterEach(() => {
        vi.useRealTimers();
    });

    it('should show text when time mocked with fake timers', async () => {
        const wrapper = mount(TestComponent);
        await wrapper.find('button').trigger('click');
        expect(wrapper.text()).toContain('set');
    });
});

Expected behaviour

Clicking the button should call the event handler, which in this test updates the dom to contain "set"

Actual behaviour

Event handler is never actually called when the date is mocked in the past. Console.logs in there show it is not called.

Other

If you change the date to a date in the future, you will see the tests all pass on the vue 3 branch.

@Weetbix
Copy link
Author

Weetbix commented Sep 9, 2022

Actually I think this is an issue with vue itself, there is a workaround that relies on the date being actual. See this vitest issue: vitest-dev/vitest#649

I will close this 👍

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