Skip to content

Generated v-if output is not compatible with coverage tooling #13261

Closed
@AriPerkkio

Description

@AriPerkkio

Vue version

3.5.2

Link to minimal reproduction

https://play.vuejs.org/#eNp9UU9PwyAU/yqE82yz6Gl2JmqWqAc16pFL0762TAoEHl2Tpd/dB83qDss4EPj94/fCkT9amw0B+IYXvnLSIvOAwTJV6nYrOHrBH4SujPbIaK8lSqPZljWl8nAvdJHPNhLRBaG3qkSgG2NFt2bDjWwoZnGmNEbrBZQy7GCcqpM279bEFPlZAl/R8+RsZJvtvdHU8Ri1Ma63UoH7sDGTKm5YYiJXUu7hLWHoAqxOeNVB9XsB3/sxYoJ/OvDgBhB84bB0LeBM777fYaTzQvamDorUV8gv8EaFee4oewq6ptpnutT2tbfGodTtj9+NCNqfhopFo3JKesHpo56vjP5f9za7Sz6hJz79AZNSn8I=

Steps to reproduce

Example with Vitest: https://stackblitz.com/~/edit/vue-coverage

Any Javascript testing tool with coverage tooling would do.

What is expected?

Created this image by modifying Vue compilers output result's code and source maps

  • <script> should not be included in source maps, so that it would be excluded from coverage.
  • Ideally v-if would not create a single return with ternary, so that proper line coverage could be achieved

What is actually happening?

  • <script> is marked as branch, as its pointing to generated ternary's alternate node
  • Lines 7 is not present in line coverage, as transpiled output contained a single return statement

System Info

https://stackblitz.com

Any additional comments?

Coverage tools have hard time remapping Vue's generated code back to original sources. This is mostly caused by Vue compiler's code transforms and source map generation.

These tools take the transpiled code, run it, and then start remapping each covered part of the transpiled code back to source code using source maps. Any code that is present in source maps is included in coverage report as users' source code. If source file's original language contains a conditional branch, this should represent conditional branch in transpiled Javascript too.

Currently Vue compiler is including generated code in source maps, e.g. top-level <script> is pointing to a _createCommentVNode("v-if", true) if source code contained v-if. This makes coverage tools show <script> as uncovered if the condition of v-if is not met. There's likely issues with other template syntax too, but I'll use v-if as example in this issue.

When position for the ReturnStatement is attempted to calculate, we get start at line: 6, and end at line: 1. It ended before it started.

Vue is also transforming users code into very compact format. In the linked examples below it's wrapping 3-lines of v-if into a single inlined ternary. In coverage this is a single statement, and adds 1 line of coverage instead of 3. If the compiler outputted an actual if-statement with 3 lines, it would be counted as 3 lines of coverage.

The more the transpiled code resembles the orignal source code, the easier it will be for coverage tools to process it.

So please:

  • Remove generated code from source maps
  • Try to make transformed code resemble the original code as much as possible
  • Add test cases for coverage mapping, check that v-if creates branches on correct locations

These issues are typical in other transpiled languages too:

Downstream issue:

Metadata

Metadata

Assignees

No one assigned

    Labels

    🔨 p3-minor-bugPriority 3: this fixes a bug, but is an edge case that only affects very specific usage.has workaroundA workaround has been found to avoid the problemscope: sfc

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions