I'm facing an issue where the following component gets stuck in an infinite re-render loop during testing, even though it works perfectly fine in the application. The component simply receives some data via an event bus, maps it to something usable in a component
tags 'is' property, and then pushes it into an array.
<template>
<div id="notification-area">
<div v-for="(component, index) in notificationComponents" :key="index">
<component
:is="component.options"
:notification="component.notification"
/>
</div>
</div>
</template>
<script lang="ts">
import {Component, Inject, Vue} from "vue-property-decorator";
import {Notification, UserErrorNotification, InfoNotification} from "@/Notification";
import InfoNotificationView from "@/components/notifications/InfoNotificationView.vue";
import UserErrorNotificationView from "@/components/notifications/UserErrorNotificationView.vue";
import {ComponentOptions, DefaultComputed, DefaultData, DefaultMethods, PropsDefinition} from "vue/types/options";
type VueOptions = ComponentOptions<
Vue,
DefaultData<Vue>,
DefaultMethods<Vue>,
DefaultComputed,
PropsDefinition<Record<string, {}>>
>
interface NotificationComponent {
options: VueOptions;
notification: Notification;
}
@Component({})
export default class NotificationArea extends Vue {
@Inject('eventBus') private eventBus!: Vue;
private notificationComponents = [] as Array<NotificationComponent>;
private static asNotificationComponent(notification: UserErrorNotification | InfoNotification): NotificationComponent{
if (notification instanceof UserErrorNotification) {
return {options: new UserErrorNotificationView().$options, notification: notification}
}
return {options: new InfoNotificationView().$options, notification: notification}
}
created() {
this.eventBus.$on('notification', (notification: UserErrorNotification | InfoNotification) => {
this.notificationComponents.push(NotificationArea.asNotificationComponent(notification));
})
}
}
</script>
Just to provide some context, InfoNotificationView
and UserErrorNotificationView
are basic wrappers around a BAlert component.
Below is the test case that seems to be causing an out of memory exception:
describe("NotificationArea.vue", () => {
let wrapper: Wrapper<NotificationArea>;
beforeEach(() => {
wrapper = shallowMount(NotificationArea, {
provide: {
eventBus: new MockEventBus()
},
created() {}
});
});
it("renders the notifications correctly", async () => {
wrapper.setData({
notificationComponents: [successNotificationComponent, warningNotificationComponent]
});
await wrapper.vm.$nextTick() // <-- Here it hangs.
const infoNotification = wrapper.find("infonotificationview-stub");
expect(infoNotification.props('notification')).toBe(successNotificationComponent);
const userErrorNotification = wrapper.find("usererrornotificationview-stub")
expect(userErrorNotification.props("notification")).toBe(warningNotificationComponent);
});
});