Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions examples/app-vitest-full/components/OptionsApiEmits.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<template>
<div />
</template>

<script>
export default {
emits: ['event-from-setup', 'event-from-before-mount', 'event-from-mounted'],
setup(_props, context) {
context.emit('event-from-setup', 1)

setTimeout(() => {
context.emit('event-from-setup', 2)
}, 1)
},
beforeMount() {
this.$emit('event-from-before-mount', 1)

setTimeout(() => {
this.$emit('event-from-before-mount', 2)
}, 1)
},
mounted() {
this.$emit('event-from-mounted', 1)

setTimeout(() => {
this.$emit('event-from-mounted', 2)
}, 1)
},
}
</script>
46 changes: 46 additions & 0 deletions examples/app-vitest-full/components/OptionsApiWatch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<template>
<pre data-testid="set-by-watches">{{ setByWatches }}</pre>
</template>

<script>
const externalStore = reactive({
dataFromExternalReactiveStore: 'data-from-external-reactive-store',
})

export default {
emits: [
'event-from-internal-data-object',
'event-mapped-from-external-reactive-store',
],
data() {
return {
dataFromInternalDataObject: 'data-from-internal-data-object',
setByWatches: {
dataFromInternalDataObject: 'initial-data-from-data-function',
dataMappedFromExternalReactiveStore: 'initial-data-from-data-function',
},
}
},
computed: {
dataMappedFromExternalReactiveStore() {
return externalStore.dataFromExternalReactiveStore
},
},
watch: {
dataFromInternalDataObject: {
immediate: true,
handler(v) {
this.$emit('event-from-internal-data-object', 1)
return this.setByWatches.dataFromInternalDataObject = v
},
},
dataMappedFromExternalReactiveStore: {
immediate: true,
handler(v) {
this.$emit('event-mapped-from-external-reactive-store', 1)
return this.setByWatches.dataMappedFromExternalReactiveStore = v
},
},
},
}
</script>
35 changes: 35 additions & 0 deletions examples/app-vitest-full/components/ScriptSetupEmits.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<template>
<div />
</template>

<script setup lang="ts">
import { onBeforeMount, onMounted } from 'vue'

const emit = defineEmits<{
'event-from-setup': [number]
'event-from-before-mount': [number]
'event-from-mounted': [number]
}>()

emit('event-from-setup', 1)

setTimeout((): void => {
emit('event-from-setup', 2)
}, 1)

onBeforeMount(() => {
emit('event-from-before-mount', 1)

setTimeout(() => {
emit('event-from-before-mount', 2)
}, 1)
})

onMounted(() => {
emit('event-from-mounted', 1)

setTimeout(() => {
emit('event-from-mounted', 2)
}, 1)
})
</script>
85 changes: 85 additions & 0 deletions examples/app-vitest-full/components/ScriptSetupWatch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<template>
<pre data-testid="set-by-watches">{{ setByWatches }}</pre>
</template>

<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'

const reactiveString = ref(
'data-from-reactive-string',
)

const reactiveObject = reactive({
data: 'data-from-reactive-object',
})

const emit = defineEmits<{
'event-from-watch-effect-on-computed-from-reactive-object': [number]
'event-from-watch-effect-on-reactive-object': [number]
'event-from-watch-effect-on-reactive-string': [number]
'event-from-watch-on-computed-from-reactive-object': [number]
'event-from-watch-on-reactive-object': [number]
'event-from-watch-on-reactive-string': [number]
}>()

const setByWatches = reactive({
dataFromWatchEffectOnComputedFromReactiveObject: 'initial-data-from-setup',
dataFromWatchEffectOnReactiveObject: 'initial-data-from-setup',
dataFromWatchEffectOnReactiveString: 'initial-data-from-setup',
dataFromWatchOnComputedFromReactiveObject: 'initial-data-from-setup',
dataFromWatchOnReactiveObject: 'initial-data-from-setup',
dataFromWatchOnReactiveString: 'initial-data-from-setup',
})

const computedFromReactiveObject = computed(() => {
return reactiveObject.data
})

watchEffect(
() => {
emit('event-from-watch-effect-on-reactive-string', 1)
setByWatches.dataFromWatchEffectOnReactiveString = reactiveString.value
},
)

watchEffect(
() => {
emit('event-from-watch-effect-on-reactive-object', 1)
setByWatches.dataFromWatchEffectOnReactiveObject = reactiveObject.data
},
)

watchEffect(
() => {
emit('event-from-watch-effect-on-computed-from-reactive-object', 1)
setByWatches.dataFromWatchEffectOnComputedFromReactiveObject = computedFromReactiveObject.value
},
)

watch(
reactiveString,
(v) => {
emit('event-from-watch-on-reactive-string', 1)
setByWatches.dataFromWatchOnReactiveString = v
},
{ immediate: true },
)

watch(
reactiveObject,
(v) => {
emit('event-from-watch-on-reactive-object', 1)
setByWatches.dataFromWatchOnReactiveObject = v.data
},
{ immediate: true },
)

watch(
computedFromReactiveObject,
(v) => {
emit('event-from-watch-on-computed-from-reactive-object', 1)
setByWatches.dataFromWatchOnComputedFromReactiveObject = v
},
{ immediate: true },
)
</script>
71 changes: 71 additions & 0 deletions examples/app-vitest-full/tests/nuxt/mount-suspended.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@ import ExportDefaultComponent from '~/components/ExportDefaultComponent.vue'
import ExportDefineComponent from '~/components/ExportDefineComponent.vue'
import ExportDefaultWithRenderComponent from '~/components/ExportDefaultWithRenderComponent.vue'
import ExportDefaultReturnsRenderComponent from '~/components/ExportDefaultReturnsRenderComponent.vue'
import ScriptSetupEmits from '~/components/ScriptSetupEmits.vue'
import ScriptSetupWatch from '~/components/ScriptSetupWatch.vue'
import OptionsApiPage from '~/pages/other/options-api.vue'
import OptionsApiComputed from '~/components/OptionsApiComputed.vue'
import OptionsApiEmits from '~/components/OptionsApiEmits.vue'
import OptionsApiWatch from '~/components/OptionsApiWatch.vue'
import ComponentWithAttrs from '~/components/ComponentWithAttrs.vue'
import ComponentWithReservedProp from '~/components/ComponentWithReservedProp.vue'
import ComponentWithReservedState from '~/components/ComponentWithReservedState.vue'
Expand Down Expand Up @@ -227,6 +231,42 @@ describe('mountSuspended', () => {
expect(component.find('[foo="bar"]').exists()).toBe(true)
})

it('should capture emits from script setup and early hooks', async () => {
const component = await mountSuspended(ScriptSetupEmits)
await expect.poll(() => component.emitted()).toEqual({
'event-from-setup': [[1], [2]],
'event-from-before-mount': [[1], [2]],
'event-from-mounted': [[1], [2]],
})
})

it('should handle data set from immediate watches', async () => {
const component = await mountSuspended(ScriptSetupWatch)
await expect.poll(
() =>
JSON.parse(component.find('[data-testid="set-by-watches"]').text()),
).toEqual({
dataFromWatchEffectOnComputedFromReactiveObject: 'data-from-reactive-object',
dataFromWatchEffectOnReactiveObject: 'data-from-reactive-object',
dataFromWatchEffectOnReactiveString: 'data-from-reactive-string',
dataFromWatchOnComputedFromReactiveObject: 'data-from-reactive-object',
dataFromWatchOnReactiveObject: 'data-from-reactive-object',
dataFromWatchOnReactiveString: 'data-from-reactive-string',
})
})

it('should handle events emitted from immediate watches', async () => {
const component = await mountSuspended(ScriptSetupWatch)
await expect.poll(() => component.emitted()).toEqual({
'event-from-watch-effect-on-computed-from-reactive-object': [[1]],
'event-from-watch-effect-on-reactive-object': [[1]],
'event-from-watch-effect-on-reactive-string': [[1]],
'event-from-watch-on-computed-from-reactive-object': [[1]],
'event-from-watch-on-reactive-object': [[1]],
'event-from-watch-on-reactive-string': [[1]],
})
})

describe('Options API', () => {
beforeEach(() => {
vi.spyOn(console, 'error').mockImplementation((message) => {
Expand Down Expand Up @@ -270,6 +310,37 @@ describe('mountSuspended', () => {
expect(component.find('[data-testid="object-with-get-and-set"]').text()).toBe('object-with-get-and-set')
expect(console.error).not.toHaveBeenCalled()
})

it('should capture emits from setup and early hooks', async () => {
const component = await mountSuspended(OptionsApiEmits)
await expect.poll(() => component.emitted()).toEqual({
'event-from-setup': [[1], [2]],
'event-from-before-mount': [[1], [2]],
'event-from-mounted': [[1], [2]],
})
expect(console.error).not.toHaveBeenCalled()
})

it('should handle data set from immediate watches', async () => {
const component = await mountSuspended(OptionsApiWatch)
await expect.poll(
() =>
JSON.parse(component.find('[data-testid="set-by-watches"]').text()),
).toEqual({
dataFromInternalDataObject: 'data-from-internal-data-object',
dataMappedFromExternalReactiveStore: 'data-from-external-reactive-store',
})
expect(console.error).not.toHaveBeenCalled()
})

it('should handle events emitted from immediate watches', async () => {
const component = await mountSuspended(OptionsApiWatch)
await expect.poll(() => component.emitted()).toEqual({
'event-from-internal-data-object': [[1]],
'event-mapped-from-external-reactive-store': [[1]],
})
expect(console.error).not.toHaveBeenCalled()
})
})
})

Expand Down
69 changes: 68 additions & 1 deletion examples/app-vitest-full/tests/nuxt/render-suspended.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import ExportDefaultWithRenderComponent from '~/components/ExportDefaultWithRend
import ExportDefaultReturnsRenderComponent from '~/components/ExportDefaultReturnsRenderComponent.vue'
import OptionsApiPage from '~/pages/other/options-api.vue'

import { BoundAttrs } from '#components'
import { BoundAttrs, OptionsApiEmits, OptionsApiWatch, ScriptSetupEmits, ScriptSetupWatch } from '#components'

const formats = {
ExportDefaultComponent,
Expand Down Expand Up @@ -134,6 +134,42 @@ describe('renderSuspended', () => {
`)
})

it('should capture emits from script setup and early hooks', async () => {
const { emitted } = await renderSuspended(ScriptSetupEmits)
await expect.poll(() => emitted()).toEqual({
'event-from-setup': [[1], [2]],
'event-from-before-mount': [[1], [2]],
'event-from-mounted': [[1], [2]],
})
})

it('should handle data set from immediate watches', async () => {
const { getByTestId } = await renderSuspended(ScriptSetupWatch)
await expect.poll(
() =>
JSON.parse(getByTestId('set-by-watches').textContent || '{}'),
).toEqual({
dataFromWatchEffectOnComputedFromReactiveObject: 'data-from-reactive-object',
dataFromWatchEffectOnReactiveObject: 'data-from-reactive-object',
dataFromWatchEffectOnReactiveString: 'data-from-reactive-string',
dataFromWatchOnComputedFromReactiveObject: 'data-from-reactive-object',
dataFromWatchOnReactiveObject: 'data-from-reactive-object',
dataFromWatchOnReactiveString: 'data-from-reactive-string',
})
})

it('should handle events emitted from immediate watches', async () => {
const { emitted } = await renderSuspended(ScriptSetupWatch)
await expect.poll(() => emitted()).toEqual({
'event-from-watch-effect-on-computed-from-reactive-object': [[1]],
'event-from-watch-effect-on-reactive-object': [[1]],
'event-from-watch-effect-on-reactive-string': [[1]],
'event-from-watch-on-computed-from-reactive-object': [[1]],
'event-from-watch-on-reactive-object': [[1]],
'event-from-watch-on-reactive-string': [[1]],
})
})

describe('Options API', () => {
beforeEach(() => {
vi.spyOn(console, 'error').mockImplementation((message) => {
Expand Down Expand Up @@ -169,6 +205,37 @@ describe('renderSuspended', () => {
await fireEvent.click(getByTestId('test-button'))
expect(console.error).not.toHaveBeenCalled()
})

it('should capture emits from setup and early hooks', async () => {
const { emitted } = await renderSuspended(OptionsApiEmits)
await expect.poll(() => emitted()).toEqual({
'event-from-setup': [[1], [2]],
'event-from-before-mount': [[1], [2]],
'event-from-mounted': [[1], [2]],
})
expect(console.error).not.toHaveBeenCalled()
})

it('should handle data set from immediate watches', async () => {
const { getByTestId } = await renderSuspended(OptionsApiWatch)
await expect.poll(
() =>
JSON.parse(getByTestId('set-by-watches').textContent || '{}'),
).toEqual({
dataFromInternalDataObject: 'data-from-internal-data-object',
dataMappedFromExternalReactiveStore: 'data-from-external-reactive-store',
})
expect(console.error).not.toHaveBeenCalled()
})

it('should handle events emitted from immediate watches', async () => {
const { emitted } = await renderSuspended(OptionsApiWatch)
await expect.poll(() => emitted()).toEqual({
'event-from-internal-data-object': [[1]],
'event-mapped-from-external-reactive-store': [[1]],
})
expect(console.error).not.toHaveBeenCalled()
})
})
})

Expand Down
Loading
Loading