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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(coverage): trim URL parameters from file paths in istanbul coverage #2232

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/coverage-istanbul/src/provider.ts
Expand Up @@ -79,6 +79,8 @@ export class IstanbulCoverageProvider implements CoverageProvider {
return

const sourceMap = pluginCtx.getCombinedSourcemap()
sourceMap.sources = sourceMap.sources.map(removeQueryParameters)

const code = this.instrumenter.instrumentSync(sourceCode, id, sourceMap as any)
const map = this.instrumenter.lastSourceMap() as any

Expand Down Expand Up @@ -227,3 +229,12 @@ function resolveIstanbulOptions(options: CoverageIstanbulOptions, root: string)

return resolved as ResolvedCoverageOptions & { provider: 'istanbul' }
}

/**
* Remove possible query parameters from filenames
* - From `/src/components/Header.component.ts?vue&type=script&src=true&lang.ts`
* - To `/src/components/Header.component.ts`
*/
function removeQueryParameters(filename: string) {
return filename.split('?')[0]
}
14 changes: 12 additions & 2 deletions test/coverage-test/coverage-test/coverage.istanbul.test.ts
Expand Up @@ -3,7 +3,7 @@ import { resolve } from 'pathe'
import { expect, test } from 'vitest'

test('istanbul html report', async () => {
const coveragePath = resolve('./coverage')
const coveragePath = resolve('./coverage/src')
const files = fs.readdirSync(coveragePath)

expect(files).toContain('index.html')
Expand All @@ -24,8 +24,18 @@ test('istanbul lcov report', async () => {
})

test('all includes untested files', () => {
const coveragePath = resolve('./coverage')
const coveragePath = resolve('./coverage/src')
const files = fs.readdirSync(coveragePath)

expect(files).toContain('untested-file.ts.html')
})

test('files should not contain query parameters', () => {
const coveragePath = resolve('./coverage/src/Counter')
const files = fs.readdirSync(coveragePath)

expect(files).toContain('index.html')
expect(files).toContain('Counter.vue.html')
expect(files).toContain('Counter.component.ts.html')
expect(files).not.toContain('Counter.component.ts?vue&type=script&src=true&lang.ts.html')
})
21 changes: 21 additions & 0 deletions test/coverage-test/src/Counter/Counter.component.ts
@@ -0,0 +1,21 @@
import { defineComponent, ref } from 'vue'

export default defineComponent({
name: 'Counter',

setup() {
const count = ref(0)
return { count }
},

methods: {
uncoveredMethod() {
return 'This line should not be covered'
},

coveredMethod() {
return 'This line should be covered'
},
},
})

15 changes: 15 additions & 0 deletions test/coverage-test/src/Counter/Counter.vue
@@ -0,0 +1,15 @@
<script lang="ts" src="./Counter.component.ts"></script>

<template>
<button @click="count++">
{{ count }}
</button>

<div v-if="count > 10">
{{ uncoveredMethod() }}
</div>
<div v-else>
{{ coveredMethod() }}
</div>
</template>

4 changes: 4 additions & 0 deletions test/coverage-test/src/Counter/index.ts
@@ -0,0 +1,4 @@
import CounterComponent from './Counter.component'
import CounterVue from './Counter.vue'

export { CounterComponent, CounterVue }
8 changes: 8 additions & 0 deletions test/coverage-test/test/vue.test.ts
Expand Up @@ -6,6 +6,7 @@ import { expect, test } from 'vitest'
import { mount } from '@vue/test-utils'
import Hello from '../src/Hello.vue'
import Defined from '../src/Defined.vue'
import { CounterVue } from '../src/Counter'

test('vue 3 coverage', async () => {
expect(Hello).toBeTruthy()
Expand Down Expand Up @@ -35,3 +36,10 @@ test('define package in vm', () => {

expect(wrapper.text()).toContain(MY_CONSTANT)
})

test('vue non-SFC, uses query parameters in file imports', async () => {
const wrapper = mount(CounterVue)

await wrapper.find('button').trigger('click')
expect(wrapper.text()).contain(1)
})