Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

export default *some functional component* is broken #332

Closed
0x009922 opened this issue Apr 7, 2021 · 5 comments
Closed

export default *some functional component* is broken #332

0x009922 opened this issue Apr 7, 2021 · 5 comments
Labels

Comments

@0x009922
Copy link
Contributor

0x009922 commented Apr 7, 2021

Repo: https://github.com/0x009922/vue-jest-default-export-issue

Problem

Something goes wrong when i am exporting function as default export from .vue file. It is common case when my component is functional.

MyTest.vue:

<script lang="ts">
import { FunctionalComponent, h } from 'vue'

const component: FunctionalComponent = () => h('div', {}, '._.')

// console.log for debug, you will see
console.log('Component in MyTest.vue', component);

export default component;
</script>

MyTest.spec.ts:

import {mount } from '@vue/test-utils'
import MyTest from './MyTest.vue'

// for debug, see output
console.log('MyTest in spec.ts', MyTest)

test('test', () => {
    const wrapper = mount(MyTest);

    expect(wrapper.html()).toEqual('<div>._.</div>')
})

And when i have run jest, i got this output:

 FAIL  src/MyTest.spec.ts
  × test (17 ms)

  ● test

    expect(received).toEqual(expected) // deep equality

    Received: "<!---->"
         |                            ^
      10 | })

      at Object.<anonymous> (src/MyTest.spec.ts:9:28)

  console.log
    Component in MyTest.vue [Function: component]

  console.log
    MyTest in spec.ts {}

      at Object.<anonymous> (src/MyTest.spec.ts:4:9)

  console.warn
    [Vue warn]: Component is missing template or render function.
      at <Anonymous ref="VTU_COMPONENT" >
      at <VTUROOT>

      at warn (node_modules/.pnpm/@vue/runtime-core@3.0.9/node_modules/@vue/runtime-core/dist/runtime-core.cjs.js:40:17)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        2.306 s
Ran all test suites.
 ERROR  Test failed. See above for more details.

In console.log results you can see, that MyTest component in the MyTest.spec.ts is not a function. But it is in the MyTest.vue.

@lmiller1990
Copy link
Member

Thanks for the bug report!

Debugging these is super painful. What I do is console.log inside here and see what's going on. Looks like the render function is not assigned correctly.

I can look at this in the near-ish future, but if you want to take a look, happy to help out with debugging.

@0x009922
Copy link
Contributor Author

@lmiller1990, the problem is on this line:

node.add(';exports.default = {...exports.default};')

In my case, tempOutput looks like this:

"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var vue_1 = require("vue");

var component = function () {
  return vue_1.h('div', {}, '._.');
};

console.log('Component in MyTest.vue', component);
exports.default = component;

{...exports.default} doesn't make the new object a function if the previous one was.
See this example:

> const a = () => console.log('i am a function')
undefined
> a.someField = 'test'
'test'
> const b = {...a}
undefined
> a
[Function: a] { someField: 'test' }
> b
{ someField: 'test' }
> a()
i am a function
undefined
> b()
Uncaught TypeError: b is not a function

So the solution may look something like this:

node.add(`;
  if (typeof exports.default === 'function') {
    const fn = exports.default;
    exports.default = (...args) => fn(...args);
    Object.assign(exports.default, fn)
  } else {
    exports.default = {...exports.default};
  }
`)

Anyway, what is the reason to copy default export's fields to itself?

@lmiller1990
Copy link
Member

Hi - I completed missed this notification! Sorry.

I don't remember how or why I wrote the code like that. Doesn't make much sense - as long as the test suite passes, you can probably remove it.

Would you like to make a PR with you fix? I will do a release in the next few days, since we merged a few nice bug fixes lately. I normally just add my test case here. You could add your functional component in here.

@0x009922
Copy link
Contributor Author

0x009922 commented May 6, 2021

@lmiller1990, i created a PR. Here it is: #335

@lmiller1990
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants