vuejs / vue-test-utils

Component Test Utils for Vue 2
https://vue-test-utils.vuejs.org
MIT License
3.57k stars 668 forks source link

RangeError: Maximum call stack size exceeded at Array.forEach #647

Closed BTCLTC closed 6 years ago

BTCLTC commented 6 years ago

Version

1.0.0-beta.16

Reproduction link

https://github.com/yunweb/vue-jest-iview

Steps to reproduce

I was reporting an error when testing my project with Jest. After various investigations, I found that the problem was caused by the use of vue-i18n. When I had each internationalization file (en-US.js, zh-CN When .js, zh-TW.js, vi-VN.js, etc.) exceed 500 lines, it will appear RangeError: Maximum call stack size exceeded at Array.forEach () at orderDeps (nodemodules/@vue_test-utils@1.0.0-beta.16@/dist/vue-test-utils.js:3006:16)

What is expected?

PASS

What is actually happening?

RangeError: Maximum call stack size exceeded at Array.forEach ()

  at orderDeps (node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3006:16)
      at Array.forEach (<anonymous>)
  at node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3011:14
      at Array.forEach (<anonymous>)
  at orderDeps (node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3006:16)
      at Array.forEach (<anonymous>)
  at node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3011:14
      at Array.forEach (<anonymous>)
  at orderDeps (node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3006:16)
      at Array.forEach (<anonymous>)
  at node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3011:14
      at Array.forEach (<anonymous>)
  at orderDeps (node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3006:16)
      at Array.forEach (<anonymous>)
  at node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3011:14
      at Array.forEach (<anonymous>)
  at orderDeps (node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3006:16)
      at Array.forEach (<anonymous>)
  at node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3011:14
      at Array.forEach (<anonymous>)
  at orderDeps (node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3006:16)
      at Array.forEach (<anonymous>)
  at node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3011:14
      at Array.forEach (<anonymous>)
  at orderDeps (node_modules/_@vue_test-utils@1.0.0-beta.16@@vue/test-utils/dist/vue-test-utils.js:3006:16)
      at Array.forEach (<anonymous>)

Internationalization related code:

import VueI18n from 'vue-i18n';
import localVue from './localVue';
import en from 'iview/dist/locale/en-US';
import zh from 'iview/dist/locale/zh-CN';
import zhTW from 'iview/dist/locale/zh-TW';
import viVI from 'iview/dist/locale/vi-VN';
import zhCn from '@/assets/lang/zh-cn';
import zhTw from '@/assets/lang/zh-tw';
import enUS from '@/assets/lang/en-us';
import vi from '@/assets/lang/vi-vi';

localVue.use(VueI18n);

const messages = {
'zh-CN': Object.assign(zhCn, zh),
'zh-TW': Object.assign(zhTw, zhTW),
'en-US': Object.assign(enUS, en),
'vi-VI': Object.assign(viVI, vi),
};

const i18n = new VueI18n({
locale: 'zh-CN',
messages
});

export default i18n;

Test assertion related code:

import VueRouter from 'vue-router';
import iView from 'iview';
import { mount, localVue, i18n } from './utils';

import Register from '@/components/register/register.vue'; 
import method from '@/utils/vueExtend/method';
import filters from '@/utils/vueExtend/filters';

localVue.use(iView);
localVue.use(VueRouter);
localVue.use(method);
localVue.use(filters);

const wrapper = mount(Register, {
  i18n,
  localVue,
  stubs: ['router-link', 'router-view']
});

describe('register.vue', () => {
  it('test data is edit', () => {
    wrapper.setData({
    regPhoneFromData: {
      telephone: '13800138000',
      auth_code: '123456',
      password: 'qaz123456',
      confirmPwd: 'qaz123456'
    }
  });
  expect(wrapper.vm.regPhoneFromData).toEqual({
    telephone: '13800138000',
    auth_code: '123456',
    password: 'qaz123456',
    confirmPwd: 'qaz123456'
  });
});
});
BTCLTC commented 6 years ago

What should I do?I use Vue but not localVue,it's can work。

BTCLTC commented 6 years ago

@eddyerburgh I use Vue but not localVue,have error: TypeError: Cannot read property '_location' of null at Window.get location [as location] (/node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/browser/Window.js:187:79)

My code contains: window.location.href

eddyerburgh commented 6 years ago

This is a bug caused by setting watchers to sync. I'm looking into a fix, one solution is a change to Vue core—https://github.com/vuejs/vue/issues/8200

The temporary solution is to use Vue.nextTick and set sync to false to make sure Vue is behaving correctly with updates:

test('use Vue.nextTick', (done) => {
  const wrapper = mount(TestComponent, { sync: false })
  wrapper.trigger('click')
  Vue.nextTick(() => {
    expect(wrapper.text()).toBe('updated')
    done()
  })
})
BTCLTC commented 6 years ago

@eddyerburgh Thank you. It's done.

maksnester commented 5 years ago

Had the same issue when specified Component.ts file instead of Component.vue file. Component.ts is the script used in Component.vue script section via <scipt src="./Component.ts">

eddyerburgh commented 5 years ago

Although you had the same error, I believe this is a different issue @Alendorff .

Could you open a new issue with a minimal reproduction that I can debug?

maksnester commented 5 years ago

@eddyerburgh it works fine with correct import, so I don't think it's really necessary.

Overdrivr commented 5 years ago

@eddyerburgh This is still a problem with latest vue 2.5.22, workaround is still required. Is this normal ?

eddyerburgh commented 5 years ago

@Overdrivr Could you open a new issue with a minimal reproduction that I can debug?

Overdrivr commented 5 years ago

I'm swamped with work as of now, but I'll try ;)