Skip to content

Commit 779017d

Browse files
committed
test: add tests to ensure isolation between tests
1 parent 5a49d4c commit 779017d

File tree

4 files changed

+123
-1
lines changed

4 files changed

+123
-1
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
const { isPositive } = useCounter()
3+
const { data } = useLazyAsyncData(async () => {
4+
return isPositive() ? 'positive' : 'zero-or-negative'
5+
})
6+
</script>
7+
8+
<template>
9+
<div v-if="data === 'positive'">
10+
Positive count
11+
</div>
12+
<div v-else>
13+
Zero or negative count
14+
</div>
15+
</template>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script setup lang="ts">
2+
const { title } = defineProps<{ title: string }>()
3+
4+
const testState = useState('testState')
5+
6+
watch(testState, (newTestState) => {
7+
console.log(`Test state has changed in component ${title}: `, newTestState)
8+
})
9+
</script>
10+
11+
<template>
12+
<div>
13+
{{ title }}
14+
</div>
15+
</template>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export const useCounter = () => {
2+
const count = ref(0)
3+
4+
function isPositive() {
5+
return count.value > 0
6+
}
7+
8+
return {
9+
count,
10+
isPositive,
11+
}
12+
}

examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'
22

3-
import { mountSuspended } from '@nuxt/test-utils/runtime'
3+
import { mockNuxtImport, mountSuspended } from '@nuxt/test-utils/runtime'
44
import { satisfies } from 'semver'
55
import { version as nuxtVersion } from 'nuxt/package.json'
66

@@ -25,11 +25,13 @@ import ComponentWithAttrs from '~/components/ComponentWithAttrs.vue'
2525
import ComponentWithReservedProp from '~/components/ComponentWithReservedProp.vue'
2626
import ComponentWithReservedState from '~/components/ComponentWithReservedState.vue'
2727
import ComponentWithImports from '~/components/ComponentWithImports.vue'
28+
import GenericStateComponent from '~/components/GenericStateComponent.vue'
2829

2930
import { BoundAttrs } from '#components'
3031
import DirectiveComponent from '~/components/DirectiveComponent.vue'
3132
import CustomComponent from '~/components/CustomComponent.vue'
3233
import WrapperElement from '~/components/WrapperElement.vue'
34+
import WatcherComponent from '~/components/WatcherComponent.vue'
3335

3436
const formats = {
3537
ExportDefaultComponent,
@@ -454,3 +456,81 @@ it('element should be changed', async () => {
454456

455457
expect(component.element.tagName).toBe('SPAN')
456458
})
459+
460+
describe('composable state isolation', () => {
461+
const { useCounterMock } = vi.hoisted(() => {
462+
return {
463+
useCounterMock: vi.fn(() => {
464+
return {
465+
isPositive: (): boolean => false,
466+
}
467+
}),
468+
}
469+
})
470+
471+
mockNuxtImport('useCounter', () => {
472+
return useCounterMock
473+
})
474+
475+
it('shows zero or negative state by default', async () => {
476+
const component = await mountSuspended(GenericStateComponent)
477+
expect(component.text()).toMatchInlineSnapshot('"Zero or negative count"')
478+
})
479+
480+
it('shows positive state when counter is positive', async () => {
481+
useCounterMock.mockRestore()
482+
useCounterMock.mockImplementation(() => ({
483+
isPositive: () => true,
484+
}))
485+
const component = await mountSuspended(GenericStateComponent)
486+
expect(component.text()).toMatchInlineSnapshot('"Positive count"')
487+
})
488+
})
489+
490+
describe('watcher cleanup validation', () => {
491+
let watcherCallCount = 0
492+
beforeEach(() => {
493+
watcherCallCount = 0
494+
// Mock console.log to count watcher calls
495+
vi.spyOn(console, 'log').mockImplementation((message) => {
496+
if (typeof message === 'string' && message.includes('Test state has changed')) {
497+
watcherCallCount++
498+
}
499+
})
500+
})
501+
502+
afterEach(() => {
503+
vi.restoreAllMocks()
504+
})
505+
506+
it('mounts component in test 1', async () => {
507+
await mountSuspended(WatcherComponent, {
508+
props: {
509+
title: 'Component 1',
510+
},
511+
})
512+
513+
expect(watcherCallCount).toBe(0) // No state changes yet
514+
})
515+
516+
it('mounts component in test 2 and validates watcher cleanup', async () => {
517+
await mountSuspended(WatcherComponent, {
518+
props: {
519+
title: 'Component 2',
520+
},
521+
})
522+
523+
// Reset counter after mounting
524+
watcherCallCount = 0
525+
526+
// Change the state - this should only trigger Component 2's watcher
527+
const state = useState('testState')
528+
state.value = 'new state'
529+
530+
await nextTick()
531+
532+
// Before the fix: would see 2 watcher calls (Component 1 and Component 2)
533+
// After the fix: should only see 1 watcher call (Component 2 only)
534+
expect(watcherCallCount).toBe(1)
535+
})
536+
})

0 commit comments

Comments
 (0)