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

Bug: Consecutive Mounts Clears Emitted Events Cache #1445

Closed
BrettLargent opened this issue Apr 21, 2022 · 5 comments
Closed

Bug: Consecutive Mounts Clears Emitted Events Cache #1445

BrettLargent opened this issue Apr 21, 2022 · 5 comments
Labels
bug Something isn't working

Comments

@BrettLargent
Copy link
Contributor

Describe the bug
The current attachEmitListener implementation that runs in the mount function clears the entirety of the events cache after a new component is mounted. This prevents a user from mounting multiple components consecutively and checking their emitted arrays.

var attachEmitListener = function () {
    events = {};
    // use devtools to capture this "emit"
    Vue.setDevtoolsHook(createDevTools(), {});
};

To Reproduce
With a test component like this:
test.vue

<script setup>
import {onMounted} from "vue";
const emit = defineEmits(["component-mounted"]);
onMounted(() => {
    emit("component-mounted")
})
</script>

<template>
    <h1>Hello, World!</h1>
</template>

and a test spec file like this:
test.spec.js

import { mount } from "@vue/test-utils";
import { beforeAll, describe, expect, test } from "vitest";
import TestComponent from "./test.vue";

describe("Bug Reproduction", () => {
    let wrapper1;
    beforeAll(() => {
        wrapper1 = mount(TestComponent);
    });

    test("Here's the bug", () => {
        expect(wrapper1.emitted()["component-mounted"].length).toBe(1); // Passes

        const wrapper2 = mount(TestComponent);
        expect(wrapper2.emitted()["component-mounted"].length).toBe(1); // Passes
        expect(wrapper1.emitted()["component-mounted"].length).toBe(1); // TypeError: Cannot read properties of undefined (reading 'length')
    });
});

You can run a test suite like vitest or jest to see that the first check of wrapper1's emitted array passes, but a subsequent check after mounting another component throws a TypeError explaining that wrapper1.emitted()["component-mounted"] is undefined.

Expected behavior
I expect to be able to mount any number of components without the emit history of those previously mounted components being cleared unless I deliberately want them to be cleared.

Related information:

  • @vue/test-utils version: 2.0.0-rc.18
  • Vue version: 3.2.25
  • vitest version: 0.9.0
  • node version: v16.13.2
  • npm version: 8.1.2
@BrettLargent BrettLargent added the bug Something isn't working label Apr 21, 2022
@lmiller1990
Copy link
Member

Nice bug report. This is a pretty big oversight, we should probably generate a unique id each time we mount a component and cache the emitted events like that, something like:

{
  'foo-component-1': { /* events map */ },
  'foo-component-2': { /* events map */ },
}

Is this something you'd like to try your hand at fixing?

@BrettLargent
Copy link
Contributor Author

Sure, I can give it a go 👍

@BrettLargent
Copy link
Contributor Author

Do you all have a contribution guide or something similar? Just want to make sure I'm following expected practices.

@lmiller1990
Copy link
Member

We don't have a contribution guide - we probably should work on one. For now, you could add your test to to the emit.spec.js file: https://github.com/vuejs/test-utils/blob/main/tests/emit.spec.ts.

That's pretty much it! yarn test to run the tests 👍

@BrettLargent
Copy link
Contributor Author

All good. I've created #1449 to merge in my fixes. Let me know what, if anything, needs to change.

BrettLargent added a commit to BrettLargent/test-utils that referenced this issue Apr 26, 2022
Refactoring attachEmitListener function to not clear entire emitted events history on every call. A new removeEventHistory has been exposed and added to the unmount method logic so that specific emit history will be cleared on wrapper unmount. Unit testing has been added as well to show that the bug has been fixed.

fixes issue vuejs#1445
BrettLargent added a commit to BrettLargent/test-utils that referenced this issue Apr 26, 2022
Refactoring attachEmitListener function to not clear entire emitted events history on every call. A new removeEventHistory has been exposed and added to the unmount method logic so that specific emit history will be cleared on wrapper unmount. Unit testing has been added as well to show that the bug has been fixed.

fixes issue vuejs#1445
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants