@vue/test-utils#shallowMount TypeScript Examples
The following examples show how to use
@vue/test-utils#shallowMount.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: example.spec.ts From master-frontend-lemoncode with MIT License | 6 votes |
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message'
const wrapper = shallowMount(HelloWorld, {
props: { msg },
})
expect(wrapper.text()).toMatch(msg)
})
})
Example #2
Source File: example.spec.ts From vue-element-typescript-admin with MIT License | 6 votes |
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message'
const wrapper = shallowMount(HelloWorld, {
propsData: { msg }
})
expect(wrapper.text()).toMatch(msg)
})
})
Example #3
Source File: NeonAlertContainer.spec.ts From neon with MIT License | 6 votes |
describe('NeonAlertContainer', () => {
it('removes alert on close', () => {
// given
const msg = { id: 42, level: NeonAlertLevel.Info, title: 'test', dismissable: true };
const wrapper = shallowMount(NeonAlertContainer, {
propsData: {
value: [msg],
placement: NeonAlertPlacement.TopLeft,
},
});
// when
wrapper.find('.neon-alert__message').trigger('click');
// then
expect(wrapper.emitted().input[0]).toEqual([[]]);
});
});
Example #4
Source File: example.spec.ts From vue3-ts-base with MIT License | 6 votes |
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message'
const wrapper = shallowMount(HelloWorld, {
props: { msg }
})
expect(wrapper.text()).to.include(msg)
})
})
Example #5
Source File: index.ts From vuehooks with MIT License | 6 votes |
// export function createCompositionVue() {
// const localVue = createLocalVue()
// localVue.use(api)
// return localVue
// }
export function renderHook<V>(setup: () => V, vue?: VueConstructor<Vue>) {
const App = defineComponent({
template: '<div ref="app" id="app"></div>',
setup
})
return shallowMount<Vue & V>(App, vue)
}
Example #6
Source File: invokeHook.ts From vhook with MIT License | 6 votes |
export function invokeHook (setup: () => any, template = defaultTemplate) {
document.body.innerHTML = `
<div id="app"></div>
`
const App = defineComponent({
template,
setup
})
// @ts-ignore
return shallowMount(App, {
attachTo: document.getElementById('app')
})
}
Example #7
Source File: AppBar.spec.ts From MDDL with MIT License | 6 votes |
describe('AppBar component', () => {
let vuetify: Vuetify
beforeEach(() => {
vuetify = new Vuetify()
})
it('exports a valid component', () => {
const wrapper = shallowMount(AppBar, {
vuetify,
})
expect(wrapper.html()).toBeTruthy()
expect(true).toBe(true)
})
})
Example #8
Source File: index.ts From vue-storefront-1 with MIT License | 6 votes |
mountMixin = <V extends Vue>(
component: ComponentOptions<V>,
mountOptions: ThisTypedShallowMountOptions<V> = {},
template = '<div />'
): Wrapper<V> => {
const localVue = createLocalVue();
localVue.use(Vuex);
return shallowMount({
template,
mixins: [component]
}, {
localVue,
...mountOptions
})
}
Example #9
Source File: Button.test.ts From wvui with GNU General Public License v2.0 | 6 votes |
describe( 'matches the snapshot', () => {
type Case = [msg: string, props: Record<keyof unknown, unknown>, slot: string];
const cases: Case[] = [
[ 'No props and no slot', {}, '' ],
...( Object.values( ButtonAction ).map( ( action ) => [
`${action} action`,
{ action },
''
] ) as Case[] ),
...( Object.values( ButtonType ).map( ( type ) => [
`${type} type`,
{ type },
''
] ) as Case [] ),
[ 'Slotted', {}, '<span>Label</span>' ]
];
test.each( cases )( 'Case %# %s: (%p) => HTML', ( _, props, slot ) => {
const wrapper = shallowMount( WvuiButton, { propsData: props, slots: { default: slot } } );
expect( wrapper.element ).toMatchSnapshot();
} );
} );
Example #10
Source File: VPerfectSignature.test.ts From v-perfect-signature with MIT License | 6 votes |
describe('#props', () => {
it('should receive default props', () => {
const wrapper = shallowMount(VPerfectSignature)
const expectedWidth = '100%'
const expectedHeight = '100%'
const expectedPenColor = '#000'
const expectedBackgroundColor = 'rgba(0,0,0,0)'
const expectedStrokeOptions = {}
expect(wrapper.props().width).toBe(expectedWidth)
expect(wrapper.props().height).toBe(expectedHeight)
expect(wrapper.props().penColor).toBe(expectedPenColor)
expect(wrapper.props().backgroundColor).toBe(expectedBackgroundColor)
expect(wrapper.props().strokeOptions).toEqual(expectedStrokeOptions)
})
})
Example #11
Source File: NeonExpansionIndicator.spec.ts From neon with MIT License | 5 votes |
describe('NeonExpansionIndicator', () => {
it('renders indicator closed', () => {
// given
const wrapper = shallowMount(NeonExpansionIndicator, {
propsData: {},
});
// when / then
expect(wrapper.find('.neon-expansion-indicator--expanded').element).toBeUndefined();
});
it('renders indicator expanded', () => {
// given
const wrapper = shallowMount(NeonExpansionIndicator, {
propsData: { expanded: true },
});
// when / then
expect(wrapper.find('.neon-expansion-indicator--expanded').element).toBeDefined();
});
it('renders inverse', () => {
// given
const wrapper = shallowMount(NeonExpansionIndicator, {
propsData: { inverse: true },
});
// when / then
expect(wrapper.find('.neon-expansion-indicator--inverse').element).toBeDefined();
});
it('renders disabled', () => {
// given
const wrapper = shallowMount(NeonExpansionIndicator, {
propsData: { disabled: true },
});
// when / then
expect(wrapper.find('.neon-expansion-indicator--disabled').element).toBeDefined();
});
it('renders indicator color', () => {
// given
const wrapper = shallowMount(NeonExpansionIndicator, {
propsData: { color: NeonFunctionalColor.Info },
});
// when / then
expect(wrapper.find('.neon-expansion-indicator--info').element).toBeDefined();
});
});
Example #12
Source File: LabelContentSplit.spec.ts From webapp with MIT License | 5 votes |
describe("LabelContentSplit.vue", () => {
let state: any;
let store: any;
const localVue = createLocalVue();
localVue.use(Vuex);
beforeEach(() => {
state = {
darkMode: false
};
store = new Vuex.Store({
modules: {
general: {
namespaced: true,
state
}
}
});
});
it("renders props when passed", () => {
const label = "Price Impact";
const value = numeral(0.03).format("0.0000%");
const wrapper = shallowMount(LabelContentSplit, {
propsData: { label, value },
store,
localVue
});
expect(wrapper.text()).toMatch(label);
expect(wrapper.text()).toMatch(value);
});
it("displays tooltip icon and popover when passed", () => {
const tooltip = "Tooltip";
const wrapper = shallowMount(LabelContentSplit, {
propsData: { tooltip },
store,
localVue
});
expect(wrapper.find("#popover-target").exists()).toBe(true);
expect(wrapper.text()).toMatch(tooltip);
});
it("should not displays value while loading", () => {
const value = numeral(0.03).format("0.0000%");
const wrapper = shallowMount(LabelContentSplit, {
propsData: { value, loading: true },
store,
localVue
});
expect(wrapper.text()).not.toMatch(value);
});
it("displays red text when isAlert prop has passed", () => {
const value = numeral(0.03).format("0.0000%");
const wrapper = shallowMount(LabelContentSplit, {
propsData: { value, isAlert: true },
store,
localVue
});
const span = wrapper.findAll("span").at(1);
expect(span.text()).toBe(value);
expect(span.element.classList.contains("text-red")).toBe(true);
});
});
Example #13
Source File: namespaced-helpers.test.ts From vuex-composition-helpers with MIT License | 5 votes |
describe('"createNamespacedHelpers" - generic namespaced helpers', () => {
let localVue: typeof Vue;
beforeEach(() => {
localVue = getLocalVue();
});
describe('when created helpers outside of component', () => {
it('should get getters', () => {
const value = 'getter-demo' + Math.random();
const storeModule: Module<any, any> = {
namespaced: true,
getters: {
valGetter: () => value
}
};
const store = new Vuex.Store({
modules: {
foo: storeModule
}
});
const {useGetters} = createNamespacedHelpers('foo');
const wrapper = shallowMount({
template: '<div>{{valGetter}}</div>',
setup() {
const {valGetter} = useGetters(['valGetter']);
return {
valGetter
}
}
},
{localVue, store}
);
expect(wrapper.text()).toBe(store.getters['foo/valGetter']);
expect(wrapper.text()).toBe(value);
})
it('should get strict getters', () => {
interface ModuleGetter {
valGetter: string;
}
const value = 'getter-demo' + Math.random();
const storeModule: Module<any, any> = {
namespaced: true,
getters: {
valGetter: () => value
}
};
const store = new Vuex.Store({
modules: {
foo: storeModule
}
});
const {useGetters} = createNamespacedHelpers<any, ModuleGetter>('foo');
const wrapper = shallowMount({
template: '<div>{{valGetter}}</div>',
setup() {
const {valGetter} = useGetters(['valGetter']);
return {
valGetter
}
}
},
{localVue, store}
);
expect(wrapper.text()).toBe(store.getters['foo/valGetter']);
expect(wrapper.text()).toBe(value);
})
})
});
Example #14
Source File: ActivityList.spec.ts From MDDL with MIT License | 5 votes |
describe('ActivityList component', () => {
it('exports a valid component', () => {
const wrapper = shallowMount(ActivityList)
expect(wrapper.html()).toBeTruthy()
})
})
Example #15
Source File: Button.test.ts From wvui with GNU General Public License v2.0 | 5 votes |
it( 'emits click events', () => {
const wrapper = shallowMount( WvuiButton );
wrapper.get( 'button' ).trigger( 'click' );
expect( wrapper.emitted().click ).toBeTruthy();
} );
Example #16
Source File: index.test.tsx From vue-request with MIT License | 4 votes |
describe('useRequest', () => { beforeAll(() => { jest.useFakeTimers('modern'); }); const successApi = 'http://example.com/200'; const failApi = 'http://example.com/404'; // mock fetch fetchMock.get(successApi, { data: 'success' }); fetchMock.get(failApi, 404); const originalError = console.error; beforeEach(() => { console.error = jest.fn(); // clear cache clearCache(); // clear global options clearGlobalOptions(); // clear listener RECONNECT_LISTENER.clear(); FOCUS_LISTENER.clear(); VISIBLE_LISTENER.clear(); }); afterEach(() => { console.error = originalError; }); test('should be defined', () => { expect(useRequest).toBeDefined(); }); test('should auto run', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { data } = useRequest(request); return () => <button>{`data:${data.value}`}</button>; }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:success'); }); test('can be manually triggered', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { data, run } = useRequest(request, { manual: true }); return () => ( <button onClick={() => run()}>{`data:${data.value}`}</button> ); }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:undefined'); await wrapper.find('button').trigger('click'); await waitForAll(); expect(wrapper.text()).toBe('data:success'); }); test('params should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { run, params } = useRequest(request, { defaultParams: ['hello', 'world'], }); return () => ( <button onClick={() => run('hi there')}> {params.value?.join(',')} </button> ); }, }), ); await waitForTime(1000); expect(wrapper.text()).toBe('hello,world'); await wrapper.find('button').trigger('click'); await waitForTime(1000); expect(wrapper.text()).toEqual('hi there'); }); test('defaultParams should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { data } = useRequest(request, { defaultParams: ['hello', 'world'], }); return () => <button>{`data:${data.value}`}</button>; }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:hello,world'); }); test('run can be accept params', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { data, run } = useRequest(request); return () => ( <button onClick={() => run('hello', 'world')}> {`data:${data.value}`} </button> ); }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:success'); await wrapper.find('button').trigger('click'); await waitForAll(); expect(wrapper.text()).toBe('data:hello,world'); }); test('mutate should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { data, mutate } = useRequest(request); return () => ( <button onClick={() => mutate('ok')}>{`data:${data.value}`}</button> ); }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:success'); await wrapper.find('button').trigger('click'); expect(wrapper.text()).toBe('data:ok'); }); test('mutate callback should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { data, mutate } = useRequest(request); return () => ( <button onClick={() => mutate(() => 'ok')}> {`data:${data.value}`} </button> ); }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:success'); await wrapper.find('button').trigger('click'); expect(wrapper.text()).toBe('data:ok'); }); test('refresh should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { refresh, loading } = useRequest(request); return () => ( <button onClick={() => refresh()}> {`loading:${loading.value}`} </button> ); }, }), ); await wrapper.find('button').trigger('click'); expect(wrapper.text()).toBe('loading:true'); await waitForAll(); expect(wrapper.text()).toBe('loading:false'); }); test('log request error by default', async () => { console.error = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest(failedRequest, { manual: true }); const handleClick = () => run(); return () => <button onClick={handleClick}></button>; }, }), ); await wrapper.find('button').trigger('click'); await waitForAll(); expect(console.error).toHaveBeenCalledWith(new Error('fail')); }); test('onSuccess should work', async () => { const mockSuccessCallback = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest(request, { manual: true, onSuccess: mockSuccessCallback, }); const handleClick = () => run(); return () => <button onClick={handleClick}></button>; }, }), ); await wrapper.find('button').trigger('click'); await waitForAll(); expect(mockSuccessCallback).toHaveBeenCalledWith('success', []); }); test('onError should work', async () => { const mockErrorCallback = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest(failedRequest, { manual: true, onError: mockErrorCallback, }); const handleClick = () => run(); return () => <button onClick={handleClick}></button>; }, }), ); await wrapper.find('button').trigger('click'); await waitForAll(); expect(mockErrorCallback).toHaveBeenCalledWith(new Error('fail'), []); }); test('initData should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { data } = useRequest(request, { initialData: 'init', }); return () => <button>{`data:${data.value}`}</button>; }, }), ); expect(wrapper.text()).toBe('data:init'); await waitForAll(); expect(wrapper.text()).toBe('data:success'); }); test('ready should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const readyRef = ref(false); const { data } = useRequest(request, { ready: readyRef, }); return () => ( <button onClick={() => { readyRef.value = true; }} > {`data:${data.value}`} </button> ); }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:undefined'); await wrapper.find('button').trigger('click'); await waitForAll(); expect(wrapper.text()).toBe('data:success'); }); test('ready should save the first time request params : case 1', async () => { const wrapper = shallowMount( defineComponent({ setup() { const readyRef = ref(false); const { data, run } = useRequest(request, { ready: readyRef, defaultParams: ['default'], }); return () => ( <div> <button id="run" onClick={() => run('run')} /> <button id="ready" onClick={() => { readyRef.value = true; }} /> <span id="text">{`data:${data.value}`}</span> </div> ); }, }), ); await waitForAll(); expect(wrapper.find('#text').text()).toBe('data:undefined'); await wrapper.find('#ready').trigger('click'); await waitForAll(); expect(wrapper.find('#text').text()).toBe('data:default'); await wrapper.find('#run').trigger('click'); await waitForAll(); expect(wrapper.find('#text').text()).toBe('data:run'); }); test('ready should save the first time request params : case 2', async () => { const wrapper = shallowMount( defineComponent({ setup() { const readyRef = ref(false); const { data, run } = useRequest(request, { ready: readyRef, defaultParams: ['default'], }); return () => ( <div> <button id="run" onClick={() => run('run')} /> <button id="ready" onClick={() => { readyRef.value = true; }} /> <span id="text">{`data:${data.value}`}</span> </div> ); }, }), ); await waitForAll(); expect(wrapper.find('#text').text()).toBe('data:undefined'); await wrapper.find('#run').trigger('click'); await wrapper.find('#ready').trigger('click'); await waitForAll(); expect(wrapper.find('#text').text()).toBe('data:run'); }); test('track ready when ready initial value is false', async () => { const wrapper = shallowMount( defineComponent({ setup() { const readyRef = ref(true); const count = ref(0); const { data, run } = useRequest(request, { ready: readyRef, defaultParams: [count.value], }); return () => ( <button onClick={() => { readyRef.value = !readyRef.value; count.value += 1; run(count.value); }} > {`data:${data.value}`} </button> ); }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:0'); await wrapper.find('button').trigger('click'); await waitForAll(); expect(wrapper.text()).toBe('data:1'); }); test('ready should work only once', async () => { const wrapper = shallowMount( defineComponent({ setup() { const readyRef = ref(false); const count = ref(0); const { data, run } = useRequest(request, { ready: readyRef, defaultParams: [count.value], }); return () => ( <button onClick={async () => { readyRef.value = !readyRef.value; count.value += 1; run(count.value); }} > {`data:${data.value}`} </button> ); }, }), ); await waitForAll(); expect(wrapper.text()).toBe('data:undefined'); await wrapper.find('button').trigger('click'); // first click await waitForAll(); expect(wrapper.text()).toBe('data:1'); await wrapper.find('button').trigger('click'); // second click await waitForAll(); expect(wrapper.text()).toBe('data:2'); }); test('formatResult should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { data } = useRequest(request, { formatResult: () => 'formatted', }); return () => <button>{`data:${data.value}`}</button>; }, }), ); expect(wrapper.text()).toBe('data:undefined'); await waitForAll(); expect(wrapper.text()).toBe('data:formatted'); }); test('refreshDeps should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const refreshRef = ref(0); const refreshReactive = reactive({ count: 0, }); const { loading } = useRequest(request, { refreshDeps: [refreshRef, () => refreshReactive.count], }); return () => ( <div> <div id="data">{String(loading.value)}</div> <button id="ref" onClick={() => { refreshRef.value++; }} /> <button id="reactive" onClick={() => { refreshReactive.count++; }} /> </div> ); }, }), ); await waitForTime(1000); expect(wrapper.find('#data').text()).toBe('false'); for (let index = 0; index < 100; index++) { await wrapper.find('#ref').trigger('click'); expect(wrapper.find('#data').text()).toBe('true'); await waitForTime(1000); expect(wrapper.find('#data').text()).toBe('false'); } for (let index = 0; index < 100; index++) { await wrapper.find('#reactive').trigger('click'); expect(wrapper.find('#data').text()).toBe('true'); await waitForTime(1000); expect(wrapper.find('#data').text()).toBe('false'); } }); test('loadingDelay should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { loading } = useRequest(request, { loadingDelay: 800, }); return () => <button>{`loading:${loading.value}`}</button>; }, }), ); expect(wrapper.text()).toBe('loading:false'); await waitForTime(800); expect(wrapper.text()).toBe('loading:true'); await waitForTime(200); expect(wrapper.text()).toBe('loading:false'); }); test('cancel loadingDelay should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { loading, cancel } = useRequest(request, { loadingDelay: 800, }); return () => ( <button onClick={() => cancel()}> {`loading:${loading.value}`} </button> ); }, }), ); expect(wrapper.text()).toBe('loading:false'); await waitForTime(800); expect(wrapper.text()).toBe('loading:true'); await wrapper.find('button').trigger('click'); expect(wrapper.text()).toBe('loading:false'); }); test('cancel should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { cancel, data, run } = useRequest(request); return () => ( <div> <button onClick={() => cancel()} id="cancel" /> <button onClick={() => run()} id="run" /> <span id="data">{`data:${data.value}`}</span> </div> ); }, }), ); expect(wrapper.find('#data').text()).toBe('data:undefined'); await wrapper.find('#cancel').trigger('click'); await waitForAll(); expect(wrapper.find('#data').text()).toBe('data:undefined'); await wrapper.find('#run').trigger('click'); await waitForAll(); expect(wrapper.find('#data').text()).toBe('data:success'); }); test('cancel should work when request error', async () => { console.error = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { data, run, cancel } = useRequest(failedRequest, { manual: true, }); return () => ( <div> <button id="run" onClick={() => run().catch(() => {})}></button>; <button id="cancel" onClick={() => cancel()}></button>; <span id="data">{`data:${data.value}`}</span> </div> ); }, }), ); expect(wrapper.find('#data').text()).toBe('data:undefined'); await wrapper.find('#run').trigger('click'); await waitForTime(200); await wrapper.find('#cancel').trigger('click'); await waitForAll(); expect(wrapper.find('#data').text()).toBe('data:undefined'); await wrapper.find('#run').trigger('click'); await waitForAll(); expect(console.error).toHaveBeenCalledWith(new Error('fail')); }); test('pollingInterval should work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { loading, cancel } = useRequest(request, { pollingInterval: 500, }); return () => ( <button onClick={() => cancel()}> {`loading:${loading.value}`} </button> ); }, }), ); expect(wrapper.text()).toBe('loading:true'); await waitForTime(1000); expect(wrapper.text()).toBe('loading:false'); await waitForTime(500); expect(wrapper.text()).toBe('loading:true'); await waitForTime(1000); expect(wrapper.text()).toBe('loading:false'); await wrapper.find('button').trigger('click'); waitForTime(600); expect(wrapper.text()).toBe('loading:false'); }); test('pollingInterval less than 0 should not work', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { loading, cancel } = useRequest(request, { pollingInterval: -0.1, }); return () => ( <button onClick={() => cancel()}> {`loading:${loading.value}`} </button> ); }, }), ); expect(wrapper.text()).toBe('loading:true'); await waitForTime(1000); expect(wrapper.text()).toBe('loading:false'); await waitForTime(10); expect(wrapper.text()).toBe('loading:false'); }); test('pollingWhenHidden be false should work', async () => { let count = 0; const wrapper = shallowMount( defineComponent({ setup() { const { data } = useRequest(() => request((count += 1)), { pollingInterval: 1000, pollingWhenHidden: false, }); return () => <button>{`data:${data.value}`}</button>; }, }), ); expect(wrapper.text()).toBe('data:undefined'); await waitForTime(1000); expect(wrapper.text()).toBe('data:1'); await waitForTime(2000); expect(wrapper.text()).toBe('data:2'); // mock tab hide Object.defineProperty(document, 'visibilityState', { value: 'hidden', writable: true, }); await waitForTime(2000); expect(wrapper.text()).toBe('data:3'); await waitForTime(2000); expect(wrapper.text()).toBe('data:3'); // mock tab show Object.defineProperty(document, 'visibilityState', { value: 'visible', writable: true, }); jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1000); expect(wrapper.text()).toBe('data:4'); await waitForTime(2000); expect(wrapper.text()).toBe('data:5'); }); test('pollingWhenHidden be true should work', async () => { let count = 0; const wrapper = shallowMount( defineComponent({ setup() { const { data } = useRequest(() => request((count += 1)), { pollingInterval: 1000, pollingWhenHidden: true, }); return () => <button>{`data:${data.value}`}</button>; }, }), ); expect(wrapper.text()).toBe('data:undefined'); await waitForTime(1000); expect(wrapper.text()).toBe('data:1'); await waitForTime(2000); expect(wrapper.text()).toBe('data:2'); // mock tab hide Object.defineProperty(document, 'visibilityState', { value: 'hidden', writable: true, }); await waitForTime(2000); expect(wrapper.text()).toBe('data:3'); await waitForTime(2000); expect(wrapper.text()).toBe('data:4'); // mock tab show Object.defineProperty(document, 'visibilityState', { value: 'visible', writable: true, }); jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1000); // because pollingWhenHidden is true, so refresh never trigger expect(wrapper.text()).toBe('data:4'); await waitForTime(2000); expect(wrapper.text()).toBe('data:5'); }); test('refreshOnWindowFocus should work', async () => { let count = 0; const wrapper = shallowMount( defineComponent({ setup() { const { data, run } = useRequest(() => request((count += 1)), { refreshOnWindowFocus: true, }); return () => ( <button onClick={() => run()}>{`data:${data.value}`}</button> ); }, }), ); expect(wrapper.text()).toBe('data:undefined'); await waitForTime(1000); expect(wrapper.text()).toBe('data:1'); await wrapper.find('button').trigger('click'); await waitForTime(1000); expect(wrapper.text()).toBe('data:2'); // mock tab visible jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1000); expect(wrapper.text()).toBe('data:3'); jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1000); expect(wrapper.text()).toBe('data:3'); // wait for 5s await waitForTime(4000); jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1000); expect(wrapper.text()).toBe('data:4'); }); test('refocusTimespan should work', async () => { let count = 0; const wrapper = shallowMount( defineComponent({ setup() { const { data, run } = useRequest(() => request((count += 1)), { refreshOnWindowFocus: true, refocusTimespan: 3000, }); return () => ( <button onClick={() => run()}>{`data:${data.value}`}</button> ); }, }), ); expect(wrapper.text()).toBe('data:undefined'); await waitForTime(1000); expect(wrapper.text()).toBe('data:1'); await wrapper.find('button').trigger('click'); await waitForTime(1000); expect(wrapper.text()).toBe('data:2'); // mock tab visible jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1000); expect(wrapper.text()).toBe('data:3'); jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1000); expect(wrapper.text()).toBe('data:3'); // wait for 3s await waitForTime(2000); jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1000); expect(wrapper.text()).toBe('data:4'); }); test('debounceInterval should work', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { debounceInterval: 100, manual: true, }, ); return () => <button onClick={() => run()} />; }, }), ); for (let index = 0; index < 100; index++) { await wrapper.find('button').trigger('click'); await waitForTime(50); } await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(1); for (let index = 0; index < 100; index++) { await wrapper.find('button').trigger('click'); await waitForTime(50); } await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(2); }); test('debounceOptions should work: case 1', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { debounceInterval: 100, debounceOptions: { leading: true, trailing: false, }, manual: true, }, ); return () => <button onClick={() => run()} />; }, }), ); for (let index = 0; index < 100; index++) { await wrapper.find('button').trigger('click'); await waitForTime(50); } expect(mockFn).toHaveBeenCalledTimes(1); await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(1); for (let index = 0; index < 100; index++) { await wrapper.find('button').trigger('click'); await waitForTime(50); } expect(mockFn).toHaveBeenCalledTimes(2); await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(2); }); test('debounceOptions should work: case 2', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { debounceInterval: 100, debounceOptions: { leading: false, trailing: false, }, manual: true, }, ); return () => <button onClick={() => run()} />; }, }), ); for (let index = 0; index < 100; index++) { await wrapper.find('button').trigger('click'); await waitForTime(50); } expect(mockFn).toHaveBeenCalledTimes(0); await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(0); for (let index = 0; index < 100; index++) { await wrapper.find('button').trigger('click'); await waitForTime(50); } expect(mockFn).toHaveBeenCalledTimes(0); await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(0); }); test('debounceOptions should work: case 3', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { debounceInterval: 500, debounceOptions: { maxWait: 1000, }, manual: true, }, ); return () => <button onClick={() => run()} />; }, }), ); for (let index = 0; index < 100; index++) { await wrapper.find('button').trigger('click'); await waitForTime(50); } expect(mockFn).toHaveBeenCalledTimes(5); await waitForTime(1000); expect(mockFn).toHaveBeenCalledTimes(5); for (let index = 0; index < 100; index++) { await wrapper.find('button').trigger('click'); await waitForTime(50); } expect(mockFn).toHaveBeenCalledTimes(10); await waitForTime(1000); expect(mockFn).toHaveBeenCalledTimes(10); }); test('debounceInterval should work with cancel', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run, cancel } = useRequest( () => { mockFn(); return request(); }, { debounceInterval: 100, manual: true, }, ); return () => ( <div> <button id="run" onClick={() => run()} /> <button id="cancel" onClick={() => cancel()} /> </div> ); }, }), ); const run = () => wrapper.find('#run').trigger('click'); const cancel = () => wrapper.find('#cancel').trigger('click'); for (let index = 0; index < 100; index++) { await run(); await waitForTime(50); } await cancel(); await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(0); for (let index = 0; index < 100; index++) { await run(); await waitForTime(50); } await cancel(); await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(0); }); test('initial auto run should skip debounce', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { debounceInterval: 100, }, ); return () => <button onClick={() => run()} />; }, }), ); expect(mockFn).toHaveBeenCalledTimes(1); await wrapper.find('button').trigger('click'); await waitForTime(50); expect(mockFn).toHaveBeenCalledTimes(1); await waitForTime(100); expect(mockFn).toHaveBeenCalledTimes(2); }); test('throttleInterval should work', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { throttleInterval: 100, manual: true, }, ); return () => <button onClick={() => run()} />; }, }), ); await wrapper.find('button').trigger('click'); await waitForTime(50); await wrapper.find('button').trigger('click'); await waitForTime(50); await wrapper.find('button').trigger('click'); await waitForAll(); // have been call 3 times // because the function will invoking on the leading edge and trailing edge of the timeout expect(mockFn).toHaveBeenCalledTimes(3); }); test('throttleOptions should work, case: 1', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { throttleInterval: 100, throttleOptions: { leading: false, }, manual: true, }, ); return () => <button onClick={() => run()} />; }, }), ); await wrapper.find('button').trigger('click'); await waitForTime(50); await wrapper.find('button').trigger('click'); await waitForTime(50); await wrapper.find('button').trigger('click'); await waitForAll(); // have been call 2 times // because the function will only invoking on the trailing edge of the timeout expect(mockFn).toHaveBeenCalledTimes(2); }); test('throttleOptions should work, case: 2', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { throttleInterval: 100, throttleOptions: { trailing: false, }, manual: true, }, ); return () => <button onClick={() => run()} />; }, }), ); await wrapper.find('button').trigger('click'); await waitForTime(50); await wrapper.find('button').trigger('click'); await waitForTime(50); await wrapper.find('button').trigger('click'); await waitForAll(); // have been call 2 times // because the function will only invoking on the leading edge of the timeout expect(mockFn).toHaveBeenCalledTimes(2); }); test('throttleOptions should work, case: 3', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run } = useRequest( () => { mockFn(); return request(); }, { throttleInterval: 100, throttleOptions: { leading: false, trailing: false, }, manual: true, }, ); return () => <button onClick={() => run()} />; }, }), ); await wrapper.find('button').trigger('click'); await waitForTime(50); await wrapper.find('button').trigger('click'); await waitForTime(50); await wrapper.find('button').trigger('click'); await waitForAll(); expect(mockFn).toHaveBeenCalledTimes(0); }); test('throttleInterval should work with cancel', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run, cancel } = useRequest( () => { mockFn(); return request(); }, { throttleInterval: 100, manual: true, }, ); return () => ( <div> <button id="run" onClick={() => run()} /> <button id="cancel" onClick={() => cancel()} /> </div> ); }, }), ); const run = () => wrapper.find('#run').trigger('click'); const cancel = () => wrapper.find('#cancel').trigger('click'); await run(); // trigger by leading expect(mockFn).toHaveBeenCalledTimes(1); await waitForTime(10); await cancel(); await run(); // trigger by leading expect(mockFn).toHaveBeenCalledTimes(2); await waitForTime(10); await cancel(); await run(); // trigger by leading expect(mockFn).toHaveBeenCalledTimes(3); await waitForTime(50); await run(); await run(); await waitForAll(); // trigger by trailing expect(mockFn).toHaveBeenCalledTimes(4); }); test('cache should work', async () => { let count = 0; const TestComponent = defineComponent({ setup() { const { data, run } = useRequest(request, { cacheKey: 'cacheKey', cacheTime: 10000, }); return () => ( <button onClick={() => run((count += 1))}>{data.value}</button> ); }, }); let wrapper = shallowMount(TestComponent); expect(wrapper.find('button').text()).toBe(''); await waitForTime(1000); expect(wrapper.find('button').text()).toBe('success'); for (let index = 0; index < 5; index++) { await wrapper.find('button').trigger('click'); await waitForTime(1000); } expect(wrapper.find('button').text()).toBe('5'); wrapper.unmount(); // remount component wrapper = shallowMount(TestComponent); expect(wrapper.find('button').text()).toBe('5'); await waitForTime(1000); expect(wrapper.find('button').text()).toBe('5'); for (let index = 0; index < 5; index++) { await wrapper.find('button').trigger('click'); await waitForTime(1000); } expect(wrapper.find('button').text()).toBe('10'); wrapper.unmount(); // waiting for cache timeout waitForTime(10000); // remount component wrapper = shallowMount(TestComponent); expect(wrapper.find('button').text()).toBe(''); }); test('cache staleTime should work', async () => { let count = 0; const TestComponent = defineComponent({ setup() { const { data, run } = useRequest(request, { cacheKey: 'cacheKey', staleTime: 5000, }); return () => ( <button onClick={() => run((count += 1))}>{data.value}</button> ); }, }); let wrapper = shallowMount(TestComponent); expect(wrapper.find('button').text()).toBe(''); await waitForTime(1000); expect(wrapper.find('button').text()).toBe('success'); for (let index = 0; index < 5; index++) { await wrapper.find('button').trigger('click'); await waitForTime(1000); } expect(wrapper.find('button').text()).toBe('5'); wrapper.unmount(); // remount component wrapper = shallowMount(TestComponent); expect(wrapper.find('button').text()).toBe('5'); await waitForTime(1000); expect(wrapper.find('button').text()).toBe('5'); for (let index = 0; index < 5; index++) { await wrapper.find('button').trigger('click'); await waitForTime(1000); } expect(wrapper.find('button').text()).toBe('10'); wrapper.unmount(); // waiting for stale timeout jest.setSystemTime(new Date().getTime() + 5000); // remount component wrapper = shallowMount(TestComponent); expect(wrapper.find('button').text()).toBe('10'); await waitForTime(1000); expect(wrapper.find('button').text()).toBe('10'); }); test('queryKey should work : case 1', async () => { const wrapper = shallowMount( defineComponent({ setup() { // auto run with empty params const { loading, params, data } = useRequest(request, { queryKey: id => id, }); return () => ( <div> <div id="loading">{`${loading.value}`}</div> <div id="data">{`${data.value}`}</div> <div id="params">{`${params.value.length}`}</div> </div> ); }, }), ); expect(wrapper.find('#loading').text()).toBe('true'); await waitForTime(1000); expect(wrapper.find('#loading').text()).toBe('false'); expect(wrapper.find('#data').text()).toBe('success'); expect(wrapper.find('#params').text()).toBe('0'); }); test('queryKey should work : case 2', async () => { const users = [ { id: '1', username: 'A' }, { id: '2', username: 'B' }, { id: '3', username: 'C' }, ]; const wrapper = shallowMount( defineComponent({ setup() { const { run, queries, data, loading } = useRequest(request, { manual: true, queryKey: id => id, }); return () => ( <div> <div id="data">{data.value}</div> <div id="loading">{loading.value.toString()}</div> <ul> {users.map(item => ( <li key={item.id} id={item.username} onClick={() => run(item.id)} > {queries[item.id]?.loading ? 'loading' : item.username} </li> ))} </ul> </div> ); }, }), ); for (let i = 0; i < users.length; i++) { const userName = users[i].username; const currentId = users[i].id; await wrapper.find(`#${userName}`).trigger('click'); expect(wrapper.find(`#${userName}`).text()).toBe('loading'); expect(wrapper.find('#data').text()).toBe(''); expect(wrapper.find('#loading').text()).toBe('true'); await waitForTime(1000); expect(wrapper.find(`#${userName}`).text()).toBe(userName); expect(wrapper.find('#data').text()).toBe(currentId); expect(wrapper.find('#loading').text()).toBe('false'); } }); test('queryKey should work : case 3', async () => { // swr const users = [ { id: '1', username: 'A' }, { id: '2', username: 'B' }, { id: '3', username: 'C' }, ]; const Child = defineComponent({ setup() { const { run, queries } = useRequest(request, { queryKey: id => id, cacheKey: 'users', }); return () => ( <div> <ul id="child"> {users.map(item => ( <li key={item.id} id={item.username} onClick={() => run(item.id)} > {queries[item.id]?.loading ? 'loading' : item.username} </li> ))} </ul> </div> ); }, }); const Parent = mount( defineComponent({ props: { show: { type: Boolean, default: false, }, }, setup(props) { return () => <div>{props.show && <Child />}</div>; }, }), ); await Parent.setProps({ show: true, }); for (let i = 0; i < users.length; i++) { const userName = users[i].username; await Parent.find(`#${userName}`).trigger('click'); expect(Parent.find(`#${userName}`).text()).toBe('loading'); await waitForTime(1000); expect(Parent.find(`#${userName}`).text()).toBe(userName); } // unmount Child await Parent.setProps({ show: false, }); // remount Child await Parent.setProps({ show: true, }); // all queries will auto refresh for (let i = 0; i < users.length; i++) { const userName = users[i].username; expect(Parent.find(`#${userName}`).text()).toBe('loading'); } await waitForTime(1000); for (let i = 0; i < users.length; i++) { const userName = users[i].username; expect(Parent.find(`#${userName}`).text()).toBe(userName); } }); test('queryKey should work : case 4', async () => { const users = [ { id: '1', username: 'A' }, { id: '2', username: 'B' }, { id: '3', username: 'C' }, ]; const wrapper = shallowMount( defineComponent({ setup() { const { run, queries, data, loading } = useRequest(request, { manual: true, refreshOnWindowFocus: true, queryKey: id => id, }); return () => ( <div> <div id="data">{data.value}</div> <div id="loading">{loading.value.toString()}</div> <ul> {users.map(item => ( <li key={item.id} id={item.username} onClick={() => run(item.id)} > {queries[item.id]?.loading ? 'loading' : queries[item.id]?.data} </li> ))} </ul> </div> ); }, }), ); for (let i = 0; i < users.length; i++) { const userName = users[i].username; const currentId = users[i].id; await wrapper.find(`#${userName}`).trigger('click'); expect(wrapper.find(`#${userName}`).text()).toBe('loading'); expect(wrapper.find('#data').text()).toBe(''); expect(wrapper.find('#loading').text()).toBe('true'); await waitForTime(1000); expect(wrapper.find(`#${userName}`).text()).toBe(currentId); expect(wrapper.find('#data').text()).toBe(currentId); expect(wrapper.find('#loading').text()).toBe('false'); } // mock tab visible jsdom.window.dispatchEvent(new Event('visibilitychange')); await waitForTime(1); for (let i = 0; i < users.length; i++) { const userName = users[i].username; expect(wrapper.find(`#${userName}`).text()).toBe('loading'); } await waitForTime(1000); for (let i = 0; i < users.length; i++) { const userName = users[i].username; const currentId = users[i].id; expect(wrapper.find(`#${userName}`).text()).toBe(currentId); } }); test('queryKey should work with root level `cancel`, `mutate`, `refresh`', async () => { const users = [ { id: '1', username: 'A' }, { id: '2', username: 'B' }, { id: '3', username: 'C' }, ]; const wrapper = shallowMount( defineComponent({ setup() { const { run, queries, mutate, refresh, cancel } = useRequest( request, { manual: true, refreshOnWindowFocus: true, queryKey: id => id, }, ); return () => ( <div> <div id="mutate" onClick={() => mutate('new data')} /> <div id="refresh" onClick={() => refresh()} /> <div id="cancel" onClick={() => cancel()} /> <ul> {users.map(item => ( <li key={item.id} id={item.username} onClick={() => run(item.id)} > {queries[item.id]?.loading ? 'loading' : queries[item.id]?.data} </li> ))} </ul> </div> ); }, }), ); const mutate = () => wrapper.find('#mutate').trigger('click'); const refresh = () => wrapper.find('#refresh').trigger('click'); const cancel = () => wrapper.find('#cancel').trigger('click'); for (let i = 0; i < users.length; i++) { const userName = users[i].username; const currentId = users[i].id; const userElement = wrapper.find(`#${userName}`); await userElement.trigger('click'); expect(userElement.text()).toBe('loading'); await waitForTime(1000); expect(userElement.text()).toBe(currentId); await mutate(); expect(userElement.text()).toBe('new data'); await userElement.trigger('click'); expect(userElement.text()).toBe('loading'); await waitForTime(100); await cancel(); expect(userElement.text()).toBe('new data'); await refresh(); expect(userElement.text()).toBe('loading'); } }); test('errorRetry should work. case 1', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { run, loading } = useRequest(failedRequest, { manual: true, errorRetryCount: 2, errorRetryInterval: 1000, }); const handleClick = () => run(); return () => ( <button onClick={handleClick}>{`${loading.value}`}</button> ); }, }), ); for (let oIndex = 0; oIndex < 10; oIndex++) { await wrapper.find('button').trigger('click'); expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('false'); // retrying for (let index = 0; index < 2; index++) { await waitForTime(1000); expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('false'); } // stop retry await waitForTime(1000); expect(wrapper.text()).toBe('false'); } }); test('errorRetry should work. case 2', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { loading, cancel } = useRequest(failedRequest, { errorRetryCount: 3, errorRetryInterval: 1000, }); return () => ( <button onClick={() => cancel()}>{`${loading.value}`}</button> ); }, }), ); expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('false'); // first retry await waitForTime(1000); expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('false'); // second retry await waitForTime(1000); expect(wrapper.text()).toBe('true'); // trigger cancel await wrapper.find('button').trigger('click'); expect(wrapper.text()).toBe('false'); await waitForTime(1000); expect(wrapper.text()).toBe('false'); }); test('errorRetry should work. case 3', async () => { const mockFn = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { run, loading } = useRequest(failedRequest, { manual: true, errorRetryCount: 10, onError: () => mockFn(), }); const handleClick = () => run(); return () => ( <button onClick={handleClick}>{`${loading.value}`}</button> ); }, }), ); await wrapper.find('button').trigger('click'); expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('false'); // retrying for (let index = 0; index < 10; index++) { await waitForAll(); expect(wrapper.text()).toBe('false'); } // stop retry await waitForAll(); expect(wrapper.text()).toBe('false'); expect(mockFn).toHaveBeenCalledTimes(11); }); test('errorRetry should work with debounce', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { run, loading, error } = useRequest(failedRequest, { manual: true, debounceInterval: 1000, errorRetryCount: 4, errorRetryInterval: 1000, }); const handleClick = () => run(); return () => ( <button onClick={handleClick}> {`${loading.value || error.value?.message}`} </button> ); }, }), ); // request await wrapper.find('button').trigger('click'); await waitForTime(2001); expect(wrapper.text()).toBe('fail'); // retrying 1 await waitForTime(1000); expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('fail'); // retrying 2 await waitForTime(1000); expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('fail'); // trigger button to reset retry count await wrapper.find('button').trigger('click'); await waitForTime(2001); expect(wrapper.text()).toBe('fail'); for (let index = 0; index < 4; index++) { await waitForTime(1000); expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('fail'); } await waitForTime(1000); expect(wrapper.text()).toBe('fail'); await waitForTime(1000); expect(wrapper.text()).toBe('fail'); }); test('errorRetry should work with pollingInterval', async () => { let flag = true; const mixinRequest = () => { return new Promise((resolve, reject) => { setTimeout(() => { if (flag) { resolve('success'); } else { reject(new Error('fail')); } }, 1000); }); }; const wrapper = shallowMount( defineComponent({ setup() { const { loading, error, data } = useRequest(mixinRequest, { errorRetryCount: 3, errorRetryInterval: 600, pollingInterval: 500, }); return () => ( <button> {`${loading.value || data.value || error.value?.message}`} </button> ); }, }), ); // normal API request for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('success'); await waitForTime(500); } // mock API error request flag = false; // retrying for (let index = 0; index < 3; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('fail'); await waitForTime(600); } // stop retry expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('fail'); await waitForTime(600); expect(wrapper.text()).toBe('fail'); }); test('pollingInterval always receive a error request', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { loading, error } = useRequest(failedRequest, { pollingInterval: 1000, }); return () => ( <button>{`${loading.value || error.value?.message}`}</button> ); }, }), ); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('fail'); await waitForTime(1000); } }); test('pollingInterval always receive a error request and errorRetryCount is -1', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { loading, error } = useRequest(failedRequest, { errorRetryCount: -1, pollingInterval: 500, errorRetryInterval: 600, }); return () => ( <button>{`${loading.value || error.value?.message}`}</button> ); }, }), ); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe('fail'); await waitForTime(600); } }); test('reset loadingDelay correctly when rerun or refresh', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { loading, run, refresh } = useRequest(request, { loadingDelay: 500, }); return () => ( <div> <div id="loading">{`${loading.value}`}</div> <button id="run" onClick={() => { run(); }} /> <button id="refresh" onClick={() => { refresh(); }} /> </div> ); }, }), ); const loadingRes = () => wrapper.find('#loading').text(); const run = () => wrapper.find('#run').trigger('click'); const refresh = () => wrapper.find('#refresh').trigger('click'); await waitForTime(300); expect(loadingRes()).toBe('false'); run(); await waitForTime(300); expect(loadingRes()).toBe('false'); await waitForTime(200); expect(loadingRes()).toBe('true'); refresh(); await waitForTime(300); expect(loadingRes()).toBe('false'); await waitForTime(200); expect(loadingRes()).toBe('true'); }); test('reset polling correctly when rerun or refresh', async () => { enum RequestType { run, refresh, polling, } const requestTypeRef = ref<RequestType>(RequestType.run); const runCountRef = ref(0); const refreshCountRef = ref(0); const pollingCountRef = ref(0); const expectCount = (param: Ref<number>, value: number) => { expect(param.value).toBe(value); }; const triggerWithCorrectType = (source: Function, type: RequestType) => { requestTypeRef.value = type; source(); }; const wrapper = shallowMount( defineComponent({ setup() { const { run, refresh } = useRequest( () => { switch (requestTypeRef.value) { case RequestType.polling: pollingCountRef.value += 1; break; case RequestType.run: runCountRef.value += 1; break; case RequestType.refresh: refreshCountRef.value += 1; break; } if ( requestTypeRef.value === RequestType.run || requestTypeRef.value === RequestType.refresh ) { requestTypeRef.value = RequestType.polling; } return request(); }, { pollingInterval: 500, }, ); return () => ( <div> <button id="run" onClick={() => { run(); }} /> <button id="refresh" onClick={() => { refresh(); }} /> </div> ); }, }), ); const run = () => wrapper.find('#run').trigger('click'); const refresh = () => wrapper.find('#refresh').trigger('click'); /* ------------------------------------- run ------------------------------------- */ expectCount(runCountRef, 1); expectCount(pollingCountRef, 0); // auto run await waitForTime(1000); for (let index = 1; index <= 100; index++) { // wait for polling await waitForTime(500); // request complete await waitForTime(1000); expectCount(runCountRef, 1); expectCount(pollingCountRef, index); } // polling is pending await waitForTime(200); triggerWithCorrectType(run, RequestType.run); await waitForTime(1000); expectCount(runCountRef, 2); expectCount(pollingCountRef, 100); for (let index = 1; index <= 100; index++) { // wait for polling await waitForTime(500); // request complete await waitForTime(1000); expectCount(pollingCountRef, index + 100); } /* ------------------------------------- refresh ------------------------------------- */ expectCount(runCountRef, 2); expectCount(refreshCountRef, 0); expectCount(pollingCountRef, 200); // polling is pending await waitForTime(200); triggerWithCorrectType(refresh, RequestType.refresh); expectCount(refreshCountRef, 1); expectCount(pollingCountRef, 200); // refresh complete await waitForTime(1000); for (let index = 1; index <= 100; index++) { // wait for polling await waitForTime(500); // request complete await waitForTime(1000); expectCount(pollingCountRef, index + 200); } expectCount(runCountRef, 2); expectCount(refreshCountRef, 1); expectCount(pollingCountRef, 300); }); test('reset error retry correctly when rerun or refresh', async () => { enum RequestType { run, refresh, errorRetry, } const requestTypeRef = ref<RequestType>(RequestType.run); const runCountRef = ref(0); const refreshCountRef = ref(0); const errorRetryCountRef = ref(0); const expectCount = (param: Ref<number>, value: number) => { expect(param.value).toBe(value); }; const triggerWithCorrectType = (source: Function, type: RequestType) => { requestTypeRef.value = type; source(); }; const wrapper = shallowMount( defineComponent({ setup() { const { run, refresh, error } = useRequest( () => { switch (requestTypeRef.value) { case RequestType.errorRetry: errorRetryCountRef.value += 1; break; case RequestType.run: runCountRef.value += 1; break; case RequestType.refresh: refreshCountRef.value += 1; break; } if ( requestTypeRef.value === RequestType.run || requestTypeRef.value === RequestType.refresh ) { requestTypeRef.value = RequestType.errorRetry; } return failedRequest(); }, { errorRetryCount: 5, errorRetryInterval: 500, }, ); return () => ( <div> <div id="error">{`${error.value?.message}`}</div> <button id="run" onClick={() => { run(); }} /> <button id="refresh" onClick={() => { refresh(); }} /> </div> ); }, }), ); const errorRes = () => wrapper.find('#error').text(); const run = () => wrapper.find('#run').trigger('click'); const refresh = () => wrapper.find('#refresh').trigger('click'); /* ------------------------------------- run ------------------------------------- */ expectCount(runCountRef, 1); expectCount(errorRetryCountRef, 0); expect(errorRes()).toBe('undefined'); // wait for request await waitForTime(1000); // receive a error result expect(errorRes()).not.toBe('undefined'); // wait for error retry await waitForTime(500); expectCount(runCountRef, 1); expectCount(errorRetryCountRef, 1); await waitForTime(1000); // error retry is pending await waitForTime(300); triggerWithCorrectType(run, RequestType.run); expectCount(runCountRef, 2); expectCount(errorRetryCountRef, 1); await waitForTime(1000); await waitForTime(500); expectCount(runCountRef, 2); expectCount(errorRetryCountRef, 2); /* ------------------------------------- refresh ------------------------------------- */ await waitForTime(1000); expectCount(runCountRef, 2); expectCount(errorRetryCountRef, 2); triggerWithCorrectType(refresh, RequestType.refresh); expectCount(refreshCountRef, 1); expectCount(errorRetryCountRef, 2); await waitForTime(1000); await waitForTime(500); expectCount(refreshCountRef, 1); expectCount(errorRetryCountRef, 3); await waitForTime(1000); // error retry is pending await waitForTime(300); triggerWithCorrectType(refresh, RequestType.refresh); expectCount(refreshCountRef, 2); expectCount(errorRetryCountRef, 3); // receive a error result await waitForTime(1000); // start error retry for (let index = 0; index < 100; index++) { await waitForTime(1000); await waitForTime(500); } expectCount(runCountRef, 2); expectCount(refreshCountRef, 2); // 5 times is the retry count expectCount(errorRetryCountRef, 3 + 5); }); test('pollingWhenOffline should work. case 1', async () => { let count = 0; const wrapper = shallowMount( defineComponent({ setup() { const { data, loading } = useRequest(() => request((count += 1)), { pollingInterval: 500, }); return () => <button>{`${loading.value || data.value}`}</button>; }, }), ); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`${index + 1}`); await waitForTime(500); } // mock offline Object.defineProperty(window.navigator, 'onLine', { value: false, writable: true, }); // last request expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`1001`); await waitForTime(500); expect(wrapper.text()).toBe(`1001`); // mock online Object.defineProperty(window.navigator, 'onLine', { value: true, writable: true, }); jsdom.window.dispatchEvent(new Event('online')); await waitForTime(1); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`${1001 + index + 1}`); await waitForTime(500); } }); test('pollingWhenOffline should work. case 2', async () => { let count = 0; const wrapper = shallowMount( defineComponent({ setup() { const { data, loading } = useRequest(() => request((count += 1)), { pollingInterval: 500, pollingWhenOffline: true, }); return () => <button>{`${loading.value || data.value}`}</button>; }, }), ); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`${index + 1}`); await waitForTime(500); } // mock offline Object.defineProperty(window.navigator, 'onLine', { value: false, writable: true, }); // last request expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`1001`); await waitForTime(500); expect(wrapper.text()).toBe(`true`); // mock online Object.defineProperty(window.navigator, 'onLine', { value: true, writable: true, }); jsdom.window.dispatchEvent(new Event('online')); await waitForTime(1); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`${1001 + index + 1}`); await waitForTime(500); } }); test('pollingWhenOffline should work with pollingWhenHidden', async () => { let count = 0; const wrapper = shallowMount( defineComponent({ setup() { const { data, loading } = useRequest(() => request((count += 1)), { pollingInterval: 500, }); return () => <button>{`${loading.value || data.value}`}</button>; }, }), ); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`${index + 1}`); await waitForTime(500); } // mock offline Object.defineProperty(window.navigator, 'onLine', { value: false, writable: true, }); // last request expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`1001`); await waitForTime(500); expect(wrapper.text()).toBe(`1001`); // mock tab show Object.defineProperty(document, 'visibilityState', { value: 'visible', writable: true, }); jsdom.window.dispatchEvent(new Event('visibilitychange')); // wait 1ms make to sure event has trigger await waitForTime(1); expect(wrapper.text()).toBe(`1001`); // mock online Object.defineProperty(window.navigator, 'onLine', { value: true, writable: true, }); jsdom.window.dispatchEvent(new Event('online')); // wait 1ms to make sure event has trigger await waitForTime(1); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`${1001 + index + 1}`); await waitForTime(500); } }); test('listener should unsubscribe when the component was unmounted', async () => { let count = 0; const wrapper = shallowMount( defineComponent({ setup() { const { data, loading } = useRequest(() => request((count += 1)), { pollingInterval: 500, }); return () => <button>{`${loading.value || data.value}`}</button>; }, }), ); for (let index = 0; index < 1000; index++) { expect(wrapper.text()).toBe('true'); await waitForTime(1000); expect(wrapper.text()).toBe(`${index + 1}`); await waitForTime(500); } expect(RECONNECT_LISTENER.size).toBe(1); wrapper.unmount(); expect(RECONNECT_LISTENER.size).toBe(0); }); test('global options should work', async () => { const ComponentA = defineComponent({ setup() { const { data, run } = useRequest(request); return () => <button onClick={() => run()}>{data.value}</button>; }, }); const ComponentB = defineComponent({ setup() { const { data, run } = useRequest(request); return () => <button onClick={() => run()}>{data.value}</button>; }, }); setGlobalOptions({ manual: true }); let wrapperA = shallowMount(ComponentA); let wrapperB = shallowMount(ComponentB); expect(wrapperA.find('button').text()).toBe(''); expect(wrapperB.find('button').text()).toBe(''); await waitForTime(1000); expect(wrapperA.find('button').text()).toBe(''); expect(wrapperB.find('button').text()).toBe(''); await wrapperA.find('button').trigger('click'); await wrapperB.find('button').trigger('click'); await waitForTime(1000); expect(wrapperA.find('button').text()).toBe('success'); expect(wrapperB.find('button').text()).toBe('success'); // clear global options clearGlobalOptions(); wrapperA = shallowMount(ComponentA); wrapperB = shallowMount(ComponentB); expect(wrapperA.find('button').text()).toBe(''); expect(wrapperB.find('button').text()).toBe(''); await waitForTime(1000); expect(wrapperA.find('button').text()).toBe('success'); expect(wrapperB.find('button').text()).toBe('success'); }); test('RequestConfig should work', async () => { const createComponent = (id: string, requestOptions: GlobalOptions = {}) => defineComponent({ setup() { const { loading, run } = useRequest(request, requestOptions); return () => ( <button id={id} onClick={run}> {`${loading.value}`} </button> ); }, }); const ComponentA = createComponent('A'); const ComponentB = createComponent('B'); const ComponentC = createComponent('C'); const ComponentD = createComponent('D'); const ComponentE = createComponent('E', { loadingDelay: 800 }); setGlobalOptions({ manual: true, loadingDelay: 500, }); const Wrapper = defineComponent({ setup() { return () => ( <div id="root"> <RequestConfig config={{ loadingDelay: 0 }}> <ComponentA /> </RequestConfig> <RequestConfig config={{ manual: false }}> <ComponentB /> <ComponentE /> {/* nested */} <RequestConfig config={{ manual: true, loadingDelay: 200 }}> <ComponentC /> </RequestConfig> </RequestConfig> <ComponentD /> </div> ); }, }); const wrapperA = mount(Wrapper); expect(wrapperA.find('#A').text()).toBe('false'); expect(wrapperA.find('#B').text()).toBe('false'); expect(wrapperA.find('#C').text()).toBe('false'); expect(wrapperA.find('#D').text()).toBe('false'); expect(wrapperA.find('#E').text()).toBe('false'); await wrapperA.find('#A').trigger('click'); await wrapperA.find('#C').trigger('click'); await wrapperA.find('#D').trigger('click'); expect(wrapperA.find('#A').text()).toBe('true'); expect(wrapperA.find('#B').text()).toBe('false'); expect(wrapperA.find('#C').text()).toBe('false'); expect(wrapperA.find('#D').text()).toBe('false'); expect(wrapperA.find('#E').text()).toBe('false'); await waitForTime(200); expect(wrapperA.find('#A').text()).toBe('true'); expect(wrapperA.find('#B').text()).toBe('false'); expect(wrapperA.find('#C').text()).toBe('true'); expect(wrapperA.find('#D').text()).toBe('false'); expect(wrapperA.find('#E').text()).toBe('false'); await waitForTime(300); expect(wrapperA.find('#A').text()).toBe('true'); expect(wrapperA.find('#B').text()).toBe('true'); expect(wrapperA.find('#C').text()).toBe('true'); expect(wrapperA.find('#D').text()).toBe('true'); expect(wrapperA.find('#E').text()).toBe('false'); await waitForTime(300); expect(wrapperA.find('#A').text()).toBe('true'); expect(wrapperA.find('#B').text()).toBe('true'); expect(wrapperA.find('#C').text()).toBe('true'); expect(wrapperA.find('#D').text()).toBe('true'); expect(wrapperA.find('#E').text()).toBe('true'); await waitForTime(200); expect(wrapperA.find('#A').text()).toBe('false'); expect(wrapperA.find('#B').text()).toBe('false'); expect(wrapperA.find('#C').text()).toBe('false'); expect(wrapperA.find('#D').text()).toBe('false'); expect(wrapperA.find('#E').text()).toBe('false'); wrapperA.unmount(); // clear global options clearGlobalOptions(); const wrapperB = mount(Wrapper); expect(wrapperB.find('#A').text()).toBe('true'); expect(wrapperB.find('#B').text()).toBe('true'); expect(wrapperB.find('#C').text()).toBe('false'); expect(wrapperB.find('#D').text()).toBe('true'); expect(wrapperB.find('#E').text()).toBe('false'); await wrapperB.find('#C').trigger('click'); await waitForTime(200); expect(wrapperB.find('#A').text()).toBe('true'); expect(wrapperB.find('#B').text()).toBe('true'); expect(wrapperB.find('#C').text()).toBe('true'); expect(wrapperB.find('#D').text()).toBe('true'); expect(wrapperB.find('#E').text()).toBe('false'); await waitForTime(600); expect(wrapperB.find('#A').text()).toBe('true'); expect(wrapperB.find('#B').text()).toBe('true'); expect(wrapperB.find('#C').text()).toBe('true'); expect(wrapperB.find('#D').text()).toBe('true'); expect(wrapperB.find('#E').text()).toBe('true'); await waitForTime(200); expect(wrapperB.find('#A').text()).toBe('false'); expect(wrapperB.find('#B').text()).toBe('false'); expect(wrapperB.find('#C').text()).toBe('false'); expect(wrapperB.find('#D').text()).toBe('false'); expect(wrapperB.find('#E').text()).toBe('false'); }); test('reload should work: case 1', async () => { const wrapper = shallowMount( defineComponent({ setup() { const { run, reload, reloading, data } = useRequest(request, { defaultParams: ['hello'], }); return () => ( <div> <div class="reloading">{`${reloading.value}`}</div> <button class="run" onClick={() => run('hi there')}></button> <button class="reload" onClick={() => reload()}></button> <div class="data">{data.value}</div> </div> ); }, }), ); const dataEl = wrapper.find('.data'); const runEl = wrapper.find('.run'); const reloadingEl = wrapper.find('.reloading'); const reloadEl = wrapper.find('.reload'); expect(reloadingEl.text()).toBe('false'); await waitForTime(1000); expect(reloadingEl.text()).toBe('false'); expect(dataEl.text()).toBe('hello'); await runEl.trigger('click'); expect(reloadingEl.text()).toBe('false'); await waitForTime(1000); expect(reloadingEl.text()).toBe('false'); expect(dataEl.text()).toEqual('hi there'); await reloadEl.trigger('click'); expect(reloadingEl.text()).toBe('true'); await waitForTime(1000); expect(reloadingEl.text()).toBe('false'); expect(dataEl.text()).toEqual('hello'); await runEl.trigger('click'); expect(reloadingEl.text()).toBe('false'); await waitForTime(1000); expect(reloadingEl.text()).toBe('false'); expect(dataEl.text()).toEqual('hi there'); }); test('reload should work: case 2', async () => { const users = [ { id: '1', username: 'A' }, { id: '2', username: 'B' }, { id: '3', username: 'C' }, ]; const wrapper = shallowMount( defineComponent({ setup() { const { run, queries, data, loading, reload } = useRequest(request, { manual: true, refreshOnWindowFocus: true, queryKey: id => id, }); return () => ( <div> <div id="data">{data.value}</div> <div id="loading">{loading.value.toString()}</div> <div id="reload" onClick={() => reload()} /> <ul> {users.map(item => ( <li key={item.id} id={item.username} onClick={() => run(item.id)} > {queries[item.id]?.loading ? 'loading' : queries[item.id]?.data} </li> ))} </ul> </div> ); }, }), ); const dataEl = wrapper.find('#data'); const loadingEl = wrapper.find('#loading'); const reloadEl = wrapper.find('#reload'); expect(FOCUS_LISTENER.size).toBe(1); expect(VISIBLE_LISTENER.size).toBe(2); expect(RECONNECT_LISTENER.size).toBe(1); for (let i = 0; i < users.length; i++) { const userName = users[i].username; const currentId = users[i].id; await wrapper.find(`#${userName}`).trigger('click'); expect(wrapper.find(`#${userName}`).text()).toBe('loading'); expect(dataEl.text()).toBe(''); expect(loadingEl.text()).toBe('true'); await waitForTime(1000); expect(wrapper.find(`#${userName}`).text()).toBe(currentId); expect(dataEl.text()).toBe(currentId); expect(loadingEl.text()).toBe('false'); } expect(FOCUS_LISTENER.size).toBe(4); expect(VISIBLE_LISTENER.size).toBe(8); expect(RECONNECT_LISTENER.size).toBe(4); await reloadEl.trigger('click'); for (let i = 0; i < users.length; i++) { const userName = users[i].username; expect(wrapper.find(`#${userName}`).text()).toBe(''); expect(dataEl.text()).toBe(''); } expect(FOCUS_LISTENER.size).toBe(1); expect(VISIBLE_LISTENER.size).toBe(2); expect(RECONNECT_LISTENER.size).toBe(1); for (let i = 0; i < users.length; i++) { const userName = users[i].username; const currentId = users[i].id; await wrapper.find(`#${userName}`).trigger('click'); expect(wrapper.find(`#${userName}`).text()).toBe('loading'); expect(dataEl.text()).toBe(''); expect(loadingEl.text()).toBe('true'); await waitForTime(1000); expect(wrapper.find(`#${userName}`).text()).toBe(currentId); expect(dataEl.text()).toBe(currentId); expect(loadingEl.text()).toBe('false'); } expect(FOCUS_LISTENER.size).toBe(4); expect(VISIBLE_LISTENER.size).toBe(8); expect(RECONNECT_LISTENER.size).toBe(4); }); test('onBefore and onAfter hooks can use', async () => { const onBefore = jest.fn(); const onAfter = jest.fn(); const wrapper = shallowMount( defineComponent({ setup() { const { data, run } = useRequest(request, { onBefore, onAfter, }); return () => ( <button onClick={() => run()}>{`data:${data.value}`}</button> ); }, }), ); expect(onBefore).toHaveBeenCalledTimes(1); expect(onAfter).toHaveBeenCalledTimes(0); await waitForTime(100); expect(onBefore).toHaveBeenCalledTimes(1); expect(onAfter).toHaveBeenCalledTimes(0); await waitForTime(800); expect(onBefore).toHaveBeenCalledTimes(1); expect(onAfter).toHaveBeenCalledTimes(0); await waitForTime(100); expect(onBefore).toHaveBeenCalledTimes(1); expect(onAfter).toHaveBeenCalledTimes(1); }); });
Example #17
Source File: NeonLink.spec.ts From neon with MIT License | 4 votes |
describe('NeonLink', () => {
it('renders default slot contents external link', () => {
// given
const slotValue = 'xd';
const href = 'http://www.getskeleton.com';
const wrapper = shallowMount(NeonLink, {
propsData: { href },
slots: {
default: `<p>${slotValue}</p>`,
},
stubs: {
RouterLink: RouterLinkStub,
},
});
// when / then
expect(wrapper.find('.neon-link p').text()).toEqual(slotValue);
});
it('renders default slot contents router link', () => {
// given
const slotValue = 'xd';
const href = '/xd';
const wrapper = shallowMount(NeonLink, {
propsData: { href },
slots: {
default: `<p>${slotValue}</p>`,
},
stubs: {
RouterLink: RouterLinkStub,
},
});
// when / then
expect(wrapper.find('.neon-link p').text()).toEqual(slotValue);
});
it('renders external link with indicator', () => {
// given
const href = 'http://www.getskeleton.com';
const wrapper = shallowMount(NeonLink, {
propsData: { href, externalIndicator: true },
stubs: {
RouterLink: RouterLinkStub,
},
});
// when / then
expect(wrapper.find('.neon-link--external-link').element).toBeDefined();
expect(wrapper.find('.neon-link--with-external-indicator').element).toBeDefined();
});
it('renders external link without indicator', () => {
// given
const href = 'http://www.getskeleton.com';
const wrapper = shallowMount(NeonLink, {
propsData: { href },
stubs: {
RouterLink: RouterLinkStub,
},
});
// when / then
expect(wrapper.find('.neon-link--external-link').element).toBeDefined();
expect(wrapper.find('.neon-link--with-external-indicator').element).toBeUndefined();
});
it('renders router link', () => {
// given
const href = '/xd';
const wrapper = shallowMount(NeonLink, {
propsData: { href },
stubs: {
RouterLink: RouterLinkStub,
},
});
// when / then
expect(wrapper.find('.neon-link--router-link').element).toBeDefined();
});
it('renders no style class', () => {
// given
const href = '/xd';
const wrapper = shallowMount(NeonLink, {
propsData: { href, noStyle: true },
stubs: {
RouterLink: RouterLinkStub,
},
});
// when / then
expect(wrapper.find('.neon-link--no-style').element).toBeDefined();
});
it('renders default outline style', () => {
// given
const href = '/xd';
const wrapper = shallowMount(NeonLink, {
propsData: { href },
stubs: {
RouterLink: RouterLinkStub,
},
});
// when / then
expect(wrapper.find('.neon-link--outline-text').element).toBeDefined();
});
it('renders provided outline style', () => {
// given
const href = '/xd';
const wrapper = shallowMount(NeonLink, {
propsData: { href, outlineStyle: NeonOutlineStyle.Border },
stubs: {
RouterLink: RouterLinkStub,
},
});
// when / then
expect(wrapper.find('.neon-link--outline-border').element).toBeDefined();
});
it('emits click event', () => {
// given
const wrapper = shallowMount(NeonLink, {
propsData: {},
stubs: {
RouterLink: RouterLinkStub,
},
});
// when
wrapper.find('.neon-link').trigger('click');
// then
expect(wrapper.emitted().click[0]).toBeDefined();
});
it('emits click event on enter keydown', () => {
// given
const wrapper = shallowMount(NeonLink, {
propsData: {},
stubs: {
RouterLink: RouterLinkStub,
},
});
// when
wrapper.find('.neon-link').trigger('keydown.enter');
// then
expect(wrapper.emitted().click[0]).toBeDefined();
});
});
Example #18
Source File: claimBnt.spec.ts From webapp with MIT License | 4 votes |
describe('ClaimBnt.vue', () => {
let state: any;
let actions: any;
let mutations: any;
let getters: any;
let store: any;
const localVue = createLocalVue();
localVue.use(Vuex);
beforeEach(() => {
state = {
darkMode: false,
countryCode: 'KOR'
}
actions = {
}
mutations = {
}
getters = {
}
store = new Vuex.Store({
modules: {
general: {
namespaced: true,
state,
actions,
mutations,
getters
}
}
});
})
afterEach(() => {
jest.clearAllTimers();
});
/* check props */
it("shows timer, when time left", () => {
const item = {
id: '1',
amount: 100,
lockedUntil: (Date.now()+10000) / 1000,
usdValue: 10
}
const wrapper = shallowMount(ClaimBnt, {
propsData: {
item
},
store,
localVue,
i18n
});
expect(wrapper.find('.img-avatar').exists()).toBe(true);
expect(wrapper.find('.time-left').exists()).toBe(true);
expect(wrapper.find('.btn').exists()).toBe(false);
})
it("hide timer, after unlock time period", () => {
const item = {
id: '1',
amount: 100,
lockedUntil: (Date.now()-10000) / 1000,
usdValue: 10
}
const wrapper = shallowMount(ClaimBnt, {
propsData: {
item
},
store,
localVue,
i18n
});
expect(wrapper.find('.time-left').exists()).toBe(false);
})
it('should unlock after locking period', () => {
jest.useFakeTimers();
const item = {
id: '1',
amount: 100,
lockedUntil: (Date.now()+2000) / 1000,
usdValue: 10
}
const wrapper = shallowMount(ClaimBnt, {
propsData: {
item
},
store,
localVue,
i18n
});
expect(setInterval).toHaveBeenCalledTimes(1);
expect(setInterval).toHaveBeenLastCalledWith(expect.any(Function), 1000);
jest.advanceTimersByTime(2200);
// should be unlocked
expect(wrapper.find('.time-left').exists()).toBe(true);
expect(wrapper.find('.btn').exists()).toBe(false);
})
it('should emit "refresh" event after locking period', () => {
jest.useFakeTimers();
const item = {
id: '1',
amount: 100,
lockedUntil: (Date.now()+2000) / 1000,
usdValue: 10
}
const wrapper = shallowMount(ClaimBnt, {
propsData: {
item
},
store,
localVue,
i18n
});
jest.advanceTimersByTime(2200);
expect(wrapper.emitted().refresh).toBeTruthy();
expect(wrapper.emitted().refresh?.length).toBe(1);
})
})
Example #19
Source File: global-actions.test.ts From vuex-composition-helpers with MIT License | 4 votes |
describe('"useActions" - global store actions helpers', () => {
let localVue: typeof Vue;
beforeEach(() => {
localVue = getLocalVue();
});
describe('when given store and map', () => {
it('should dispatch action with given payload', () => {
const clickValue = 'demo-click-' + Math.random();
const dispatcher = jest.fn();
const store = new Vuex.Store({
state: {
val: 'test-demo' + Math.random()
},
actions: {
doTest: ({state}, payload) => {
dispatcher(state, payload);
}
}
});
const wrapper = shallowMount({
template: '<div @click="doTest(\'' + clickValue + '\')">click</div>',
setup() {
const {doTest} = useActions(store, ['doTest']);
return {
doTest
}
}
},
{localVue}
);
expect(dispatcher).not.toBeCalled();
wrapper.find('div').trigger('click');
expect(dispatcher).toBeCalledTimes(1);
expect(dispatcher).toBeCalledWith(store.state, clickValue);
});
});
describe('when given map only', () => {
it('should dispatch action with given payload', () => {
const clickValue = 'demo-click-' + Math.random();
const dispatcher = jest.fn();
const store = new Vuex.Store({
state: {
val: 'test-demo' + Math.random()
},
actions: {
doTest: ({state}, payload) => {
dispatcher(state, payload);
}
}
});
const wrapper = shallowMount({
template: '<div @click="doTest(\'' + clickValue + '\')">click</div>',
setup() {
const {doTest} = useActions(['doTest']);
return {
doTest
}
}
},
{localVue, store}
);
expect(dispatcher).not.toBeCalled();
wrapper.find('div').trigger('click');
expect(dispatcher).toBeCalledTimes(1);
expect(dispatcher).toBeCalledWith(store.state, clickValue);
});
it('should dispatch a typed action with given payload', () => {
const clickValue = 'demo-click-' + Math.random();
const dispatcher = jest.fn();
interface Actions extends ActionTree<any, any> {
doTest: (ctx: any, payload: string) => void
}
const store = new Vuex.Store({
state: {
val: 'test-demo' + Math.random()
},
actions: {
doTest: ({state}, payload) => {
dispatcher(state, payload);
}
}
});
const wrapper = shallowMount({
template: '<div @click="onClicked">click</div>',
setup() {
const {doTest} = useActions<Actions>(['doTest']);
const onClicked = () => doTest(clickValue);
return {
onClicked,
doTest
}
}
},
{localVue, store}
);
expect(dispatcher).not.toBeCalled();
wrapper.find('div').trigger('click');
expect(dispatcher).toBeCalledTimes(1);
expect(dispatcher).toBeCalledWith(store.state, clickValue);
});
it('should dispatch a typed async action with given payload', async () => {
const clickValue = 'demo-click-' + Math.random();
const dispatcher = jest.fn();
interface Actions {
doTest: (ctx: any, payload: string) => Promise<void>
}
const store = new Vuex.Store({
state: {
val: 'test-demo' + Math.random()
},
actions: {
doTest: async ({state}, payload) => {
await new Promise(resolve => setTimeout(resolve));
dispatcher(state, payload);
}
}
});
const wrapper = shallowMount({
template: '<div></div>',
setup() {
const {doTest} = useActions<Actions>(['doTest']);
const onClicked = async () => await doTest(clickValue);
return {
onClicked,
doTest
}
}
},
{localVue, store}
);
expect(dispatcher).not.toBeCalled();
await (wrapper.vm as any).onClicked();
await wrapper.vm.$nextTick();
expect(dispatcher).toBeCalledTimes(1);
expect(dispatcher).toBeCalledWith(store.state, clickValue);
});
});
describe('when given namespace and map', () => {
it('should dispatch action with given payload', () => {
const clickValue = 'demo-click-' + Math.random();
const dispatcher = jest.fn();
const storeModule: Module<any, any> = {
namespaced: true,
state: {
val: 'test-demo' + Math.random()
},
actions: {
doTest: ({state}, payload) => {
dispatcher(state, payload);
}
}
};
const store = new Vuex.Store({
state: {},
modules: {
foo: storeModule
}
});
const wrapper = shallowMount({
template: '<div @click="doTest(\'' + clickValue + '\')">click</div>',
setup() {
const {doTest} = useActions('foo', ['doTest']);
return {
doTest
}
}
},
{localVue, store}
);
expect(dispatcher).not.toBeCalled();
wrapper.find('div').trigger('click');
expect(dispatcher).toBeCalledTimes(1);
expect(dispatcher).toBeCalledWith(storeModule.state, clickValue);
});
it('should dispatch a typed action with given payload', () => {
const clickValue = 'demo-click-' + Math.random();
const dispatcher = jest.fn();
interface Actions {
doTest: (ctx: any, payload: string) => void
}
const storeModule: Module<any, any> = {
namespaced: true,
state: {
val: 'test-demo' + Math.random()
},
actions: {
doTest: ({state}, payload) => {
dispatcher(state, payload);
}
}
};
const store = new Vuex.Store({
state: {},
modules: {
foo: storeModule
}
});
const wrapper = shallowMount({
template: '<div @click="onClicked">click</div>',
setup() {
const {doTest} = useActions<Actions>('foo', ['doTest']);
const onClicked = () => doTest(clickValue);
return {
onClicked,
doTest
}
}
},
{localVue, store}
);
expect(dispatcher).not.toBeCalled();
wrapper.find('div').trigger('click');
expect(dispatcher).toBeCalledTimes(1);
expect(dispatcher).toBeCalledWith(storeModule.state, clickValue);
});
});
});