From a473befca20a7536c3ab4effe994edcbb73451b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20CG?= Date: Thu, 1 Aug 2024 16:21:07 +0200 Subject: [PATCH 01/12] test(auto-progress-bar): fix test after Vue3 update --- packages/x-components/src/plugins/x-emitters.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-components/src/plugins/x-emitters.ts b/packages/x-components/src/plugins/x-emitters.ts index 7d3a4ff9ae..a4bfdbda06 100644 --- a/packages/x-components/src/plugins/x-emitters.ts +++ b/packages/x-components/src/plugins/x-emitters.ts @@ -33,7 +33,7 @@ export function registerStoreEmitters( newValue: XEventPayload, oldValue?: XEventPayload ) => void = (newValue, oldValue) => { - if (filter(newValue, oldValue, store.state.x[name])) { + if (filter!(newValue, oldValue, store.state.x[name])) { bus.emit(event, newValue, { ...metadata, moduleName: name, oldValue }); } }; From 38cd759e416697f81a3c0231d6c534f0e086c06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20CG?= Date: Thu, 1 Aug 2024 16:21:07 +0200 Subject: [PATCH 02/12] test(auto-progress-bar): fix test after Vue3 update --- packages/x-components/src/plugins/x-emitters.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/x-components/src/plugins/x-emitters.ts b/packages/x-components/src/plugins/x-emitters.ts index a4bfdbda06..87ec07c963 100644 --- a/packages/x-components/src/plugins/x-emitters.ts +++ b/packages/x-components/src/plugins/x-emitters.ts @@ -6,6 +6,7 @@ import { AnySimpleStateSelector, AnyStateSelector } from '../store/utils/store-e import { XEventPayload, XEventsTypes } from '../wiring/events.types'; import { WireMetadata } from '../wiring/wiring.types'; import { AnyXModule } from '../x-modules/x-modules.types'; +import { WatchOptionsBase } from 'vue'; /** * Registers the store emitters, making them emit the event when the part of the state selected @@ -63,6 +64,7 @@ function normalizeStateSelector(stateSelector: AnySimpleStateSelector | AnyState return { deep: false, immediate: false, + once: false, filter: () => true, metadata: { replaceable: true From 4f19bd9d5deb8e8ec9e86257db3acb7bf4ef1fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20CG?= Date: Mon, 5 Aug 2024 12:08:55 +0200 Subject: [PATCH 03/12] test(components): fix tests after Vue3 update BATCH 1 --- packages/x-components/src/__tests__/utils.ts | 14 ++++---- .../__tests__/base-dropdown.spec.ts | 18 +++++----- .../__tests__/base-event-button.spec.ts | 33 +++++++++---------- .../base-keyboard-navigation.spec.ts | 18 ++++------ .../components/__tests__/base-rating.spec.ts | 10 +++--- .../src/components/x-component.utils.ts | 16 +++++---- .../x-components/src/composables/use-x-bus.ts | 17 +++++++--- packages/x-components/src/shims-vue.d.ts | 5 +-- .../x-components/src/wiring/wiring.types.ts | 3 +- 9 files changed, 68 insertions(+), 66 deletions(-) diff --git a/packages/x-components/src/__tests__/utils.ts b/packages/x-components/src/__tests__/utils.ts index 9d850332fd..b7f2f9c882 100644 --- a/packages/x-components/src/__tests__/utils.ts +++ b/packages/x-components/src/__tests__/utils.ts @@ -193,17 +193,15 @@ function mergeStates( */ export function installNewXPlugin( options: Partial = {}, - localVue = undefined, bus = new XDummyBus() -): [XPlugin, undefined] { +): [XPlugin, XPluginOptions] { XPlugin.resetInstance(); const xPlugin = new XPlugin(bus); - // const installOptions: XPluginOptions = { - // adapter: XComponentsAdapterDummy, - // ...options - // }; - // localVue.use(xPlugin, installOptions); - return [xPlugin, localVue]; + const installOptions: XPluginOptions = { + adapter: XComponentsAdapterDummy, + ...options + }; + return [xPlugin, installOptions]; } /** diff --git a/packages/x-components/src/components/__tests__/base-dropdown.spec.ts b/packages/x-components/src/components/__tests__/base-dropdown.spec.ts index 4c59fd563c..bac66c6d1f 100644 --- a/packages/x-components/src/components/__tests__/base-dropdown.spec.ts +++ b/packages/x-components/src/components/__tests__/base-dropdown.spec.ts @@ -42,7 +42,7 @@ function renderDropdown({ } const clickToggleButton = () => getDropdownToggle().trigger('click'); - const clickNthItem = (nth: number) => getListItems().at(nth).trigger('click'); + const clickNthItem = (nth: number) => getListItems().at(nth)?.trigger('click'); const pressKeyFromToggle = (key: Key) => getDropdownToggle().trigger(`keydown`, { key }); const pressKeyFromFocusedItem = (key: Key) => getHighlightedItem().trigger(`keydown`, { key }); @@ -71,7 +71,7 @@ function renderDropdown({ } function isListVisible() { - const element = dropdown.find(getDataTestSelector('dropdown-list')).element; + const element = dropdown.find(getDataTestSelector('dropdown-list')).element as HTMLElement; return element.style.display !== 'none'; } @@ -116,7 +116,7 @@ describe('testing Dropdown component', () => { const listItemWrappers = getListItems(); expect(listItemWrappers).toHaveLength(4); items.forEach((item, index) => { - expect(listItemWrappers.at(index).text()).toBe(typeof item === 'string' ? item : item.id); + expect(listItemWrappers.at(index)?.text()).toBe(typeof item === 'string' ? item : item.id); }); }); @@ -143,8 +143,8 @@ describe('testing Dropdown component', () => { const listItemWrappers = getListItems(); expect(getDropdownToggle().text()).toBe('select something'); expect(listItemWrappers.length).toBeGreaterThan(0); - expect(getHighlightedItem().text()).toBe(listItemWrappers.at(0).text()); - expect(getSelectedItem().element).toBeUndefined(); + expect(getHighlightedItem().text()).toBe(listItemWrappers.at(0)?.text()); + expect(getSelectedItem().exists()).toBeFalsy(); }); it('allows to customize the toggle button', async () => { @@ -177,7 +177,7 @@ describe('testing Dropdown component', () => { await pressKeyFromToggle('ArrowDown'); const selectedElement = getListItems().at(selectedIndex); - expect(getHighlightedItem().text()).toBe(selectedElement.text()); + expect(getHighlightedItem().text()).toBe(selectedElement?.text()); }); it('opens and focuses the selected element when the button has focus and arrow UP key is pressed', async () => { @@ -189,7 +189,7 @@ describe('testing Dropdown component', () => { await pressKeyFromToggle('ArrowUp'); const selectedElement = getListItems().at(selectedIndex); - expect(getHighlightedItem().text()).toBe(selectedElement.text()); + expect(getHighlightedItem().text()).toBe(selectedElement?.text()); }); }); @@ -291,10 +291,10 @@ describe('testing Dropdown component', () => { const listItems = getListItems(); await pressKeyFromFocusedItem('End'); - expect(getHighlightedItem().text()).toBe(listItems.at(-1).text()); + expect(getHighlightedItem().text()).toBe(listItems.at(-1)?.text()); await pressKeyFromFocusedItem('Home'); - expect(getHighlightedItem().text()).toBe(listItems.at(0).text()); + expect(getHighlightedItem().text()).toBe(listItems.at(0)?.text()); }); it('focuses the first element starting to search from the focused one which its text starts with the typed characters', async () => { diff --git a/packages/x-components/src/components/__tests__/base-event-button.spec.ts b/packages/x-components/src/components/__tests__/base-event-button.spec.ts index 35e0a22757..9e2f08d70e 100644 --- a/packages/x-components/src/components/__tests__/base-event-button.spec.ts +++ b/packages/x-components/src/components/__tests__/base-event-button.spec.ts @@ -1,25 +1,22 @@ -import { mount } from '@vue/test-utils'; +import { ComponentMountingOptions, mount } from '@vue/test-utils'; import { installNewXPlugin } from '../../__tests__/utils'; import { XPlugin } from '../../plugins'; import { WireMetadata } from '../../wiring/wiring.types'; import BaseEventButton from '../base-event-button.vue'; +import { XEventsTypes } from 'src/wiring'; -function render() { - installNewXPlugin(); +const stubSlot = `button text + `; - const wrapper = mount( - { - template: ` - button text - - `, - components: { BaseEventButton }, - props: ['events'] +function render(options: ComponentMountingOptions = {}) { + const wrapper = mount(BaseEventButton, { + props: { events: {} }, + slots: { default: stubSlot }, + global: { + plugins: [installNewXPlugin()] }, - { - propsData: { events: {} } - } - ); + ...options + }); return { wrapper, @@ -44,7 +41,7 @@ describe('testing Base Event Button Component', () => { it('emits an event with a payload', async () => { const { wrapper, emitSpy, expectedMetadata } = render(); - await wrapper.setProps({ events: { testEvent: 'test-payload' } }); + await wrapper.setProps({ events: { testEvent: 'test-payload' } as Partial }); await wrapper.trigger('click'); expect(emitSpy).toHaveBeenCalledTimes(1); @@ -54,7 +51,7 @@ describe('testing Base Event Button Component', () => { it('emits an event with no payload', async () => { const { wrapper, emitSpy, expectedMetadata } = render(); - await wrapper.setProps({ events: { testEvent: undefined } }); + await wrapper.setProps({ events: { testEvent: undefined } as Partial }); await wrapper.trigger('click'); expect(emitSpy).toHaveBeenCalledTimes(1); @@ -68,7 +65,7 @@ describe('testing Base Event Button Component', () => { testEvent1: 'test-payload-1', testEvent2: 'test-payload-2', testEvent3: undefined - }; + } as Partial; await wrapper.setProps({ events }); await wrapper.trigger('click'); diff --git a/packages/x-components/src/components/__tests__/base-keyboard-navigation.spec.ts b/packages/x-components/src/components/__tests__/base-keyboard-navigation.spec.ts index 8f10cde4b1..fbd947aa9a 100644 --- a/packages/x-components/src/components/__tests__/base-keyboard-navigation.spec.ts +++ b/packages/x-components/src/components/__tests__/base-keyboard-navigation.spec.ts @@ -1,25 +1,18 @@ import { mount } from '@vue/test-utils'; -import Vue from 'vue'; import { SearchInput } from '../../x-modules/search-box/components/index'; import { installNewXPlugin } from '../../__tests__/utils'; import BaseKeyboardNavigation from '../base-keyboard-navigation.vue'; import { DirectionalFocusNavigationService } from '../../services/directional-focus-navigation.service'; +import { XPlugin } from '../../plugins/x-plugin'; describe('testing keyboard navigation component', () => { - let localVue: typeof Vue; - - beforeEach(() => { - [, localVue] = installNewXPlugin(); - }); - it('takes control of the navigation when a defined condition is triggered', () => { const navigateToSpy = jest.spyOn( DirectionalFocusNavigationService.prototype as any, 'navigateTo' ); - const searchInput = mount(SearchInput, { localVue }); mount(BaseKeyboardNavigation, { - localVue, + global: { plugins: [installNewXPlugin()] }, propsData: { navigationHijacker: [ { @@ -30,6 +23,8 @@ describe('testing keyboard navigation component', () => { ] } }); + + const searchInput = mount(SearchInput); searchInput.trigger('keydown', { key: 'ArrowUp' }); expect(navigateToSpy).not.toHaveBeenCalled(); @@ -44,15 +39,14 @@ describe('testing keyboard navigation component', () => { .spyOn(DirectionalFocusNavigationService.prototype as any, 'navigateTo') .mockReturnValue(undefined); const keyboardNavigation = mount(BaseKeyboardNavigation, { - localVue, + global: { plugins: [installNewXPlugin()] }, propsData: { - takeNavigationControl: [], eventsForDirectionLimit: { ArrowUp: 'UserReachedEmpathizeTop' } } }); - keyboardNavigation.vm.$x.on('UserReachedEmpathizeTop').subscribe(listener); + XPlugin.bus.on('UserReachedEmpathizeTop').subscribe(listener); keyboardNavigation.trigger('keydown', { key: 'ArrowUp' }); expect(listener).toHaveBeenCalled(); diff --git a/packages/x-components/src/components/__tests__/base-rating.spec.ts b/packages/x-components/src/components/__tests__/base-rating.spec.ts index 3e8858980d..44a8b15c3c 100644 --- a/packages/x-components/src/components/__tests__/base-rating.spec.ts +++ b/packages/x-components/src/components/__tests__/base-rating.spec.ts @@ -1,4 +1,4 @@ -import { mount, WrapperArray } from '@vue/test-utils'; +import { mount, DOMWrapper } from '@vue/test-utils'; import { getDataTestSelector } from '../../__tests__/utils'; import BaseRating from '../base-rating.vue'; @@ -6,9 +6,9 @@ function renderBaseRating({ template }: RenderBaseRatingOptions): RenderBaseRati const wrapper = mount({ template }, { components: { BaseRating } }); return { - getFilledIcons: (): WrapperArray => + getFilledIcons: (): DOMWrapper[] => wrapper.find(getDataTestSelector('rating-filled')).findAll(':scope > *'), - getEmptyIcons: (): WrapperArray => + getEmptyIcons: (): DOMWrapper[] => wrapper.find(getDataTestSelector('rating-empty')).findAll(':scope > *') }; } @@ -39,6 +39,6 @@ interface RenderBaseRatingOptions { } interface RenderBaseRatingApi { - getFilledIcons: () => WrapperArray; - getEmptyIcons: () => WrapperArray; + getFilledIcons: () => DOMWrapper[]; + getEmptyIcons: () => DOMWrapper[]; } diff --git a/packages/x-components/src/components/x-component.utils.ts b/packages/x-components/src/components/x-component.utils.ts index ee6a25ae59..3b44646e8a 100644 --- a/packages/x-components/src/components/x-component.utils.ts +++ b/packages/x-components/src/components/x-component.utils.ts @@ -1,4 +1,4 @@ -import Vue from 'vue'; +import { ComponentPublicInstance } from 'vue'; import { XModuleName } from '../x-modules/x-modules.types'; /** @@ -9,7 +9,9 @@ import { XModuleName } from '../x-modules/x-modules.types'; * x-component. * @internal */ -export function getXComponentXModuleName(component: Vue | undefined): XModuleName | null { +export function getXComponentXModuleName( + component: ComponentPublicInstance | undefined +): XModuleName | null { return component?.$options.xModule ?? null; } @@ -21,7 +23,7 @@ export function getXComponentXModuleName(component: Vue | undefined): XModuleNam * @returns A boolean which flags if a component is a X-Component. * @public */ -export function isXComponent(component: Vue): boolean { +export function isXComponent(component: ComponentPublicInstance): boolean { return !!getXComponentXModuleName(component); } @@ -32,9 +34,11 @@ export function isXComponent(component: Vue): boolean { * @returns The root XComponent or undefined if it has not. * @public */ -export function getRootXComponent(component: Vue | null): Vue | undefined { - let xComponent: Vue | undefined; - let currentComponent: Vue | null = component; +export function getRootXComponent( + component: ComponentPublicInstance | null +): ComponentPublicInstance | undefined { + let xComponent: ComponentPublicInstance | undefined; + let currentComponent = component; while (currentComponent != null) { if (isXComponent(currentComponent)) { xComponent = currentComponent; diff --git a/packages/x-components/src/composables/use-x-bus.ts b/packages/x-components/src/composables/use-x-bus.ts index 3909d795a7..beae63b4fe 100644 --- a/packages/x-components/src/composables/use-x-bus.ts +++ b/packages/x-components/src/composables/use-x-bus.ts @@ -1,5 +1,12 @@ import { Subscription } from 'rxjs'; -import Vue, { getCurrentInstance, inject, isRef, onBeforeUnmount, Ref } from 'vue'; +import { + ComponentPublicInstance, + getCurrentInstance, + inject, + isRef, + onBeforeUnmount, + Ref +} from 'vue'; import { EventPayload, SubjectPayload, XBus } from '@empathyco/x-bus'; import { XEvent, XEventPayload, XEventsTypes } from '../wiring/events.types'; import { WireMetadata } from '../wiring/wiring.types'; @@ -8,8 +15,8 @@ import { FeatureLocation } from '../types/origin'; import { XPlugin } from '../plugins/x-plugin'; import { bus as xBus } from '../plugins/x-bus'; -interface PrivateExtendedVueComponent extends Vue { - xComponent?: Vue; +interface PrivateExtendedVueComponent extends ComponentPublicInstance { + xComponent?: ComponentPublicInstance; } /** @@ -26,10 +33,10 @@ interface PrivateExtendedVueComponent extends Vue { export function useXBus() { const injectedLocation = inject | FeatureLocation>('location', 'none'); - const component = getCurrentInstance()?.proxy; + const component = getCurrentInstance()?.proxy as PrivateExtendedVueComponent; const xComponent = getRootXComponent(component ?? null); if (component && xComponent) { - (component as PrivateExtendedVueComponent).xComponent = xComponent; + component.xComponent = xComponent; } let bus: XBus; diff --git a/packages/x-components/src/shims-vue.d.ts b/packages/x-components/src/shims-vue.d.ts index 8f6f410263..506bf2e5c9 100644 --- a/packages/x-components/src/shims-vue.d.ts +++ b/packages/x-components/src/shims-vue.d.ts @@ -1,4 +1,5 @@ declare module '*.vue' { - import Vue from 'vue'; - export default Vue; + import { DefineComponent } from 'vue'; + const component: DefineComponent<{}, {}, any>; + export default component; } diff --git a/packages/x-components/src/wiring/wiring.types.ts b/packages/x-components/src/wiring/wiring.types.ts index ba0b466c95..18f53ca145 100644 --- a/packages/x-components/src/wiring/wiring.types.ts +++ b/packages/x-components/src/wiring/wiring.types.ts @@ -7,6 +7,7 @@ import { FeatureLocation, QueryFeature, ResultFeature } from '../types/origin'; import { FirstParameter, MaybeArray, MonadicFunction, NiladicFunction } from '../utils/types'; import { XModuleName } from '../x-modules/x-modules.types'; import { XEvent, XEventPayload, XEventsTypes } from './events.types'; +import { Component } from 'vue'; /** * A Wire is a function that receives an observable, the store and the on function of the bus it @@ -45,7 +46,7 @@ export interface WireMetadata { /** The DOM element that triggered the event emission. */ target?: HTMLElement; /** The component instance that triggered the event emission. */ - component?: Vue; + component?: Component; /** The event priority to use when sorting the bus queue for event batching. */ priority?: Priority; /** From b6974efd324c0cf40037ed303ad6af3613fd3321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20CG?= Date: Wed, 7 Aug 2024 12:54:34 +0200 Subject: [PATCH 04/12] Revert "test(auto-progress-bar): fix test after Vue3 update" This reverts commit 019f1aa937aa590f5520ce7c01abf20ef3b2260c. --- packages/x-components/src/plugins/x-emitters.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/x-components/src/plugins/x-emitters.ts b/packages/x-components/src/plugins/x-emitters.ts index 87ec07c963..a4bfdbda06 100644 --- a/packages/x-components/src/plugins/x-emitters.ts +++ b/packages/x-components/src/plugins/x-emitters.ts @@ -6,7 +6,6 @@ import { AnySimpleStateSelector, AnyStateSelector } from '../store/utils/store-e import { XEventPayload, XEventsTypes } from '../wiring/events.types'; import { WireMetadata } from '../wiring/wiring.types'; import { AnyXModule } from '../x-modules/x-modules.types'; -import { WatchOptionsBase } from 'vue'; /** * Registers the store emitters, making them emit the event when the part of the state selected @@ -64,7 +63,6 @@ function normalizeStateSelector(stateSelector: AnySimpleStateSelector | AnyState return { deep: false, immediate: false, - once: false, filter: () => true, metadata: { replaceable: true From 1152fd3a8b7bd19abbf1e5e161559442e0ddc4a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20CG?= Date: Wed, 7 Aug 2024 15:31:07 +0200 Subject: [PATCH 05/12] test(components): propsData is now props --- .../src/components/__tests__/base-dropdown.spec.ts | 2 +- .../src/components/__tests__/base-event-button.spec.ts | 4 +--- .../src/components/__tests__/base-keyboard-navigation.spec.ts | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/x-components/src/components/__tests__/base-dropdown.spec.ts b/packages/x-components/src/components/__tests__/base-dropdown.spec.ts index bac66c6d1f..264ff6831f 100644 --- a/packages/x-components/src/components/__tests__/base-dropdown.spec.ts +++ b/packages/x-components/src/components/__tests__/base-dropdown.spec.ts @@ -25,7 +25,7 @@ function renderDropdown({ data: () => ({ value: initialValue }) }, { - propsData: { items } + props: { items } } ); diff --git a/packages/x-components/src/components/__tests__/base-event-button.spec.ts b/packages/x-components/src/components/__tests__/base-event-button.spec.ts index 9e2f08d70e..65dbbac43c 100644 --- a/packages/x-components/src/components/__tests__/base-event-button.spec.ts +++ b/packages/x-components/src/components/__tests__/base-event-button.spec.ts @@ -12,9 +12,7 @@ function render(options: ComponentMountingOptions = {}) const wrapper = mount(BaseEventButton, { props: { events: {} }, slots: { default: stubSlot }, - global: { - plugins: [installNewXPlugin()] - }, + global: { plugins: [installNewXPlugin()] }, ...options }); diff --git a/packages/x-components/src/components/__tests__/base-keyboard-navigation.spec.ts b/packages/x-components/src/components/__tests__/base-keyboard-navigation.spec.ts index fbd947aa9a..466b9a7011 100644 --- a/packages/x-components/src/components/__tests__/base-keyboard-navigation.spec.ts +++ b/packages/x-components/src/components/__tests__/base-keyboard-navigation.spec.ts @@ -13,7 +13,7 @@ describe('testing keyboard navigation component', () => { ); mount(BaseKeyboardNavigation, { global: { plugins: [installNewXPlugin()] }, - propsData: { + props: { navigationHijacker: [ { xEvent: 'UserPressedArrowKey', @@ -40,7 +40,7 @@ describe('testing keyboard navigation component', () => { .mockReturnValue(undefined); const keyboardNavigation = mount(BaseKeyboardNavigation, { global: { plugins: [installNewXPlugin()] }, - propsData: { + props: { eventsForDirectionLimit: { ArrowUp: 'UserReachedEmpathizeTop' } From e6a2d95c597165d03ffba39a46406e8e8a72f1de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vi=CC=81ctor=20CG?= Date: Wed, 7 Aug 2024 16:14:51 +0200 Subject: [PATCH 06/12] test(components): fix tests after Vue3 update BATCH 2 --- .../base-variable-column-grid.spec.ts | 46 +++------- .../__tests__/display-emitter.spec.ts | 9 +- .../__tests__/dynamic-props.mixin.spec.ts | 35 -------- .../components/__tests__/global-x-bus.spec.ts | 9 +- .../components/__tests__/highlight.spec.ts | 89 ++++++------------- .../components/__tests__/items-list.spec.ts | 26 ++---- .../__tests__/location-provider.spec.ts | 51 ++++------- .../__tests__/page-loader-button.spec.ts | 21 ++--- .../__tests__/snippet-callbacks.spec.ts | 6 +- .../__tests__/x-component-mixin.spec.ts | 38 -------- .../__tests__/x-component-utils.spec.ts | 16 ++-- 11 files changed, 94 insertions(+), 252 deletions(-) delete mode 100644 packages/x-components/src/components/__tests__/dynamic-props.mixin.spec.ts delete mode 100644 packages/x-components/src/components/__tests__/x-component-mixin.spec.ts diff --git a/packages/x-components/src/components/__tests__/base-variable-column-grid.spec.ts b/packages/x-components/src/components/__tests__/base-variable-column-grid.spec.ts index 8f4df9bb7d..1189e1bee9 100644 --- a/packages/x-components/src/components/__tests__/base-variable-column-grid.spec.ts +++ b/packages/x-components/src/components/__tests__/base-variable-column-grid.spec.ts @@ -1,8 +1,7 @@ -import { mount, Wrapper } from '@vue/test-utils'; -import Vue, { nextTick } from 'vue'; +import { mount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import { getSearchResponseStub } from '../../__stubs__/search-response-stubs.factory'; import { getDataTestSelector, installNewXPlugin } from '../../__tests__/utils'; -import { ListItem } from '../../utils/types'; import BaseVariableColumnGrid from '../base-variable-column-grid.vue'; import { XPlugin } from '../../plugins/x-plugin'; @@ -13,16 +12,14 @@ const itemsStub = [ ...searchResponse.results ]; -function renderComponent({ items = itemsStub }: RenderOptions = {}): RenderAPI { - const [, localVue] = installNewXPlugin(); - function mountComponent(): Wrapper { +function renderComponent({ items = itemsStub } = {}) { + function mountComponent() { return mount(BaseVariableColumnGrid, { - props: ['items'], - propsData: { + global: { plugins: [installNewXPlugin()] }, + props: { items }, - localVue, - scopedSlots: { + slots: { default: '{{ item.id }}', result: '{{ item.name }}' } @@ -34,12 +31,9 @@ function renderComponent({ items = itemsStub }: RenderOptions = {}): RenderAPI { return { wrapper: wrapper, mountComponent, - hasColumns(columns: number): boolean { - return wrapper.classes(`x-base-grid--cols-${columns}`); - }, - isScopedSlotOverridden(selector): boolean { - return wrapper.find(getDataTestSelector(selector)).exists(); - } + hasColumns: (columns: number) => wrapper.classes(`x-base-grid--cols-${columns}`), + isScopedSlotOverridden: (selector: string) => + wrapper.find(getDataTestSelector(selector)).exists() }; } @@ -70,22 +64,10 @@ describe('testing BaseVariableColumnGrid component', () => { expect(hasColumns(6)).toBe(true); const wrapper2 = mountComponent(); + + console.log(wrapper2.classes()); + await nextTick(); + expect(wrapper2.classes('x-base-grid--cols-6')).toBe(true); }); }); - -interface RenderOptions { - /** The array of items to render in the grid. */ - items?: ListItem[]; -} - -interface RenderAPI { - /** The grid's wrapper. */ - wrapper: Wrapper; - /** Mounts the grid component. */ - mountComponent: () => Wrapper; - /** Checks if the grid has a certain number of columns. */ - hasColumns: (columns: number) => boolean; - /** Check if a scoped slot is overridden. */ - isScopedSlotOverridden: (selector: string) => boolean; -} diff --git a/packages/x-components/src/components/__tests__/display-emitter.spec.ts b/packages/x-components/src/components/__tests__/display-emitter.spec.ts index 0a436d073d..d94f412ac8 100644 --- a/packages/x-components/src/components/__tests__/display-emitter.spec.ts +++ b/packages/x-components/src/components/__tests__/display-emitter.spec.ts @@ -24,7 +24,8 @@ function render({ }); return { - wrapper: wrapper.findComponent(DisplayEmitter), + wrapper, + displayEmiter: wrapper.findComponent(DisplayEmitter), element: wrapper.find(getDataTestSelector('child')).element, payload, eventMetadata @@ -38,9 +39,9 @@ describe('testing DisplayEmitter component', () => { }); it('renders everything passed to its default slot', () => { - const { wrapper } = render(); + const { displayEmiter } = render(); - expect(wrapper.find(getDataTestSelector('child')).exists()).toBeTruthy(); + expect(displayEmiter.find(getDataTestSelector('child')).exists()).toBeTruthy(); }); it('executes `useEmitDisplayEvent` composable underneath', () => { @@ -70,7 +71,7 @@ describe('testing DisplayEmitter component', () => { it('removes the watcher on unmount', async () => { const { wrapper } = render(); - wrapper.destroy(); + wrapper.unmount(); await nextTick(); expect(unwatchDisplaySpy).toHaveBeenCalled(); diff --git a/packages/x-components/src/components/__tests__/dynamic-props.mixin.spec.ts b/packages/x-components/src/components/__tests__/dynamic-props.mixin.spec.ts deleted file mode 100644 index dd7011d226..0000000000 --- a/packages/x-components/src/components/__tests__/dynamic-props.mixin.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import Vue from 'vue'; -import { mount, Wrapper } from '@vue/test-utils'; -import { dynamicPropsMixin } from '../dynamic-props.mixin'; - -const renderComponent = ({ props = ['list', 'button'] }: ComponentOptions = {}): ComponentAPI => { - const wrapper = mount({ - mixins: [dynamicPropsMixin(props)], - render: h => h(), - props: ['data'] - }); - return { wrapper }; -}; - -describe('dynamicPropsMixin', () => { - it('expects to have the defined props from the mixin', () => { - const { wrapper } = renderComponent(); - const props = Object.keys(wrapper.props()); - expect(props).toEqual(['list', 'button', 'data']); - }); -}); - -/** - * The options for the `renderComponent` function. - */ -interface ComponentOptions { - props?: string[]; -} - -/** - * Test API for the component. - */ -interface ComponentAPI { - /** The wrapper for the component. */ - wrapper: Wrapper; -} diff --git a/packages/x-components/src/components/__tests__/global-x-bus.spec.ts b/packages/x-components/src/components/__tests__/global-x-bus.spec.ts index 79ddbf4652..df08e641f4 100644 --- a/packages/x-components/src/components/__tests__/global-x-bus.spec.ts +++ b/packages/x-components/src/components/__tests__/global-x-bus.spec.ts @@ -4,10 +4,11 @@ import { XPlugin } from '../../plugins/index'; import GlobalXBus from '../global-x-bus.vue'; function renderGlobalXBus({ listeners = {} } = {}) { - installNewXPlugin(); - return { - wrapper: mount(GlobalXBus, { listeners }) + wrapper: mount(GlobalXBus, { + props: { listeners }, + global: { plugins: [installNewXPlugin()] } + }) } as const; } @@ -41,7 +42,7 @@ describe('testing GlobalXBus component', () => { await XPlugin.bus.emit('UserClickedColumnPicker'); expect(clickedColumnPickerCallback).toHaveBeenCalledTimes(1); - wrapper.destroy(); + wrapper.unmount(); await XPlugin.bus.emit('UserClickedColumnPicker'); expect(clickedColumnPickerCallback).toHaveBeenCalledTimes(1); diff --git a/packages/x-components/src/components/__tests__/highlight.spec.ts b/packages/x-components/src/components/__tests__/highlight.spec.ts index 43fee3bd02..b5fbbc4cff 100644 --- a/packages/x-components/src/components/__tests__/highlight.spec.ts +++ b/packages/x-components/src/components/__tests__/highlight.spec.ts @@ -1,33 +1,26 @@ -import { mount, Wrapper } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; import Highlight from '../highlight.vue'; import { getDataTestSelector } from '../../__tests__/utils'; +import { nextTick } from 'vue'; function renderHighlight({ - template = '', - text, - highlight, - noMatchClass, - matchingPartClass, - matchClass -}: RenderHighlightOptions): RenderHighlightAPI { - const wrapper = mount( - { - inheritAttrs: false, - components: { - Highlight - }, - template + slots = {}, + text = '', + highlight = '', + noMatchClass = '', + matchingPartClass = '', + matchClass = '' +} = {}) { + const wrapper = mount(Highlight, { + props: { + text, + highlight, + noMatchClass, + matchingPartClass, + matchClass }, - { - propsData: { - text, - highlight, - noMatchClass, - matchingPartClass, - matchClass - } - } - ); + slots: { ...slots } + }); return { wrapper, getStartPart() { @@ -39,7 +32,7 @@ function renderHighlight({ getEndPart() { return wrapper.find(getDataTestSelector('highlight-end')); }, - async setHighlight(highlight) { + async setHighlight(highlight: string) { return await wrapper.setProps({ highlight }); } }; @@ -112,13 +105,14 @@ describe('testing Highlight component', () => { expect(getEndPart().exists()).toBe(false); }); - it('allows to add classes when the text matches', () => { + it('allows to add classes when the text matches', async () => { const { getMatchingPart, wrapper } = renderHighlight({ text: 'salchichón', highlight: 'sal', matchClass: 'custom-match-class', matchingPartClass: 'custom-matching-part-class' }); + await nextTick(); expect(wrapper.classes('custom-match-class')).toBe(true); expect(getMatchingPart().classes('custom-matching-part-class')).toBe(true); }); @@ -133,14 +127,13 @@ describe('testing Highlight component', () => { }); it('allows customising the HTML', async () => { + const customHtml = ` + + {{ start }}{{ match }}{{ end }} + + {{ text }}`; const { wrapper, setHighlight } = renderHighlight({ - template: ` - - - {{ start }}{{ match }}{{ end }} - - {{ text }} - `, + slots: { default: customHtml }, text: 'churrasco', highlight: 'chur' }); @@ -154,31 +147,3 @@ describe('testing Highlight component', () => { ); }); }); - -interface RenderHighlightOptions { - /** The template to render. */ - template?: string; - /** The text to be highlighted. */ - text: string; - /** The part of the text to highlight. */ - highlight: string; - /** Class to add to the root node when the given text doesn't contain the part to highlight. */ - noMatchClass?: string; - /** Class to add to the node wrapping the matching text. */ - matchingPartClass?: string; - /** Class to add to the root node when the given text contains the part to highlight. */ - matchClass?: string; -} - -interface RenderHighlightAPI { - /** Testing wrapper component. */ - wrapper: Wrapper; - /** Only the start node wrapper. */ - getStartPart: () => Wrapper; - /** Only the matching node wrapper. */ - getMatchingPart: () => Wrapper; - /** Only the end node wrapper. */ - getEndPart: () => Wrapper; - /** Sets the part of the text to highlight. */ - setHighlight: (highlight: string) => Promise; -} diff --git a/packages/x-components/src/components/__tests__/items-list.spec.ts b/packages/x-components/src/components/__tests__/items-list.spec.ts index c38d5ded80..abd7d5f3ff 100644 --- a/packages/x-components/src/components/__tests__/items-list.spec.ts +++ b/packages/x-components/src/components/__tests__/items-list.spec.ts @@ -1,5 +1,4 @@ -import { mount, Wrapper } from '@vue/test-utils'; -import Vue from 'vue'; +import { mount, VueWrapper } from '@vue/test-utils'; import { ListItem } from '../../utils/types'; import { getDataTestSelector } from '../../__tests__/utils'; import { getBannersStub } from '../../__stubs__/banners-stubs.factory'; @@ -13,20 +12,13 @@ import { getPromotedsStub } from '../../__stubs__/promoteds-stubs.factory'; * @param options - The options to render the component with. * @returns The API for testing the `BannersList` component. */ -function renderItemsList({ - items = [], - scopedSlots -}: RenderItemsListOptions = {}): RendersItemsListAPI { +function renderItemsList({ items = [], slots }: RenderItemsListOptions = {}): RendersItemsListAPI { const wrapper = mount(ItemsList, { - propsData: { - items - }, - scopedSlots + props: { items }, + slots }); - return { - wrapper - }; + return { wrapper }; } describe('testing ItemsList component', () => { @@ -50,7 +42,7 @@ describe('testing ItemsList component', () => { const itemsWrapperArray = wrapper.findAll('.x-items-list__item'); expect(itemsWrapperArray).toHaveLength(resultsStub.length); resultsStub.forEach((result, index: number) => { - expect(itemsWrapperArray.at(index).text()).toBe(result.id); + expect(itemsWrapperArray.at(index)?.text()).toBe(result.id); }); }); @@ -74,7 +66,7 @@ describe('testing ItemsList component', () => { it('allows to customize each item using the slot', () => { const { wrapper } = renderItemsList({ - scopedSlots: { + slots: { result: ``, banner: ``, promoted: `` @@ -100,10 +92,10 @@ interface RenderItemsListOptions { /** Items to be passed to the component. */ items?: ListItem[]; /** Scoped slots to be passed to the mount function. */ - scopedSlots?: Record; + slots?: Record; } interface RendersItemsListAPI { /** The `wrapper` wrapper component. */ - wrapper: Wrapper; + wrapper: VueWrapper; } diff --git a/packages/x-components/src/components/__tests__/location-provider.spec.ts b/packages/x-components/src/components/__tests__/location-provider.spec.ts index 21acafb1f5..8888a2e8bc 100644 --- a/packages/x-components/src/components/__tests__/location-provider.spec.ts +++ b/packages/x-components/src/components/__tests__/location-provider.spec.ts @@ -1,18 +1,16 @@ -import { mount, Wrapper } from '@vue/test-utils'; -import Vue from 'vue'; -import { Component, Inject } from 'vue-property-decorator'; +import { mount, VueWrapper } from '@vue/test-utils'; +import { defineComponent, inject } from 'vue'; import { FeatureLocation } from '../../types'; import LocationProvider from '../location-provider.vue'; -@Component({ - template: ` -