forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1import { describe, expect, it } from 'vitest'
2import { mountSuspended } from '@nuxt/test-utils/runtime'
3import InputBase from '~/components/Input/Base.vue'
4
5describe('InputBase', () => {
6 describe('rendering', () => {
7 it('renders with default empty value', async () => {
8 const component = await mountSuspended(InputBase)
9 const input = component.find('input')
10 expect((input.element as HTMLInputElement).value).toBe('')
11 })
12
13 it('renders with initial modelValue', async () => {
14 const component = await mountSuspended(InputBase, {
15 props: { modelValue: 'hello' },
16 })
17 const input = component.find('input')
18 expect((input.element as HTMLInputElement).value).toBe('hello')
19 })
20
21 it('renders empty string when modelValue is undefined or null', async () => {
22 const withUndefined = await mountSuspended(InputBase, {
23 props: { modelValue: undefined },
24 })
25 expect((withUndefined.find('input').element as HTMLInputElement).value).toBe('')
26
27 const withNull = await mountSuspended(InputBase, {
28 props: { modelValue: null as unknown as string },
29 })
30 expect((withNull.find('input').element as HTMLInputElement).value).toBe('')
31 })
32 })
33
34 describe('v-model', () => {
35 it('updates modelValue when user types', async () => {
36 const component = await mountSuspended(InputBase, {
37 props: { modelValue: '' },
38 })
39 const input = component.find('input')
40 await input.setValue('test')
41 expect(component.emitted('update:modelValue')).toBeTruthy()
42 expect(component.emitted('update:modelValue')?.at(-1)).toEqual(['test'])
43 })
44
45 it('reflects modelValue prop changes', async () => {
46 const component = await mountSuspended(InputBase, {
47 props: { modelValue: 'initial' },
48 })
49 await component.setProps({ modelValue: 'updated' })
50 const input = component.find('input')
51 expect((input.element as HTMLInputElement).value).toBe('updated')
52 })
53 })
54
55 describe('noCorrect prop', () => {
56 it('applies noCorrect attributes when noCorrect is true (default)', async () => {
57 const component = await mountSuspended(InputBase)
58 const input = component.find('input')
59 expect(input.attributes('autocapitalize')).toBe('off')
60 expect(input.attributes('autocomplete')).toBe('off')
61 expect(input.attributes('autocorrect')).toBe('off')
62 expect(input.attributes('spellcheck')).toBe('false')
63 })
64
65 it('does not apply noCorrect attributes when noCorrect is false', async () => {
66 const component = await mountSuspended(InputBase, {
67 props: { noCorrect: false },
68 })
69 const input = component.find('input')
70 expect(input.attributes('autocapitalize')).toBeUndefined()
71 expect(input.attributes('autocomplete')).toBeUndefined()
72 expect(input.attributes('autocorrect')).toBeUndefined()
73 expect(input.attributes('spellcheck')).toBeUndefined()
74 })
75 })
76
77 describe('focus and blur', () => {
78 it('emits focus when input is focused', async () => {
79 const component = await mountSuspended(InputBase)
80 const input = component.find('input')
81 await input.trigger('focus')
82 expect(component.emitted('focus')).toHaveLength(1)
83 })
84
85 it('emits blur when input loses focus', async () => {
86 const component = await mountSuspended(InputBase)
87 const input = component.find('input')
88 await input.trigger('focus')
89 await input.trigger('blur')
90 expect(component.emitted('blur')).toHaveLength(1)
91 })
92 })
93
94 describe('exposed API', () => {
95 it('exposes focus() that focuses the input', async () => {
96 const container = document.createElement('div')
97 document.body.appendChild(container)
98 const component = await mountSuspended(InputBase, { attachTo: container })
99 const input = component.find('input')
100 expect(container.contains(document.activeElement)).toBe(false)
101 component.vm.focus()
102 await component.vm.$nextTick()
103 expect(container.contains(document.activeElement)).toBe(true)
104 expect(document.activeElement).toBe(input.element)
105 container.remove()
106 })
107
108 it('exposes blur() that blurs the input', async () => {
109 const container = document.createElement('div')
110 document.body.appendChild(container)
111 const component = await mountSuspended(InputBase, { attachTo: container })
112 const input = component.find('input')
113 input.element.focus()
114 expect(container.contains(document.activeElement)).toBe(true)
115 expect(document.activeElement).toBe(input.element)
116 component.vm.blur()
117 await component.vm.$nextTick()
118 expect(container.contains(document.activeElement)).toBe(false)
119 expect(document.activeElement).not.toBe(input.element)
120 container.remove()
121 })
122 })
123
124 describe('accessibility (attrs fallthrough)', () => {
125 it('accepts placeholder via attrs', async () => {
126 const component = await mountSuspended(InputBase, {
127 attrs: { 'placeholder': 'Search packages...', 'aria-label': 'Search input' },
128 })
129 const input = component.find('input')
130 expect(input.attributes('placeholder')).toBe('Search packages...')
131 expect(input.attributes('aria-label')).toBe('Search input')
132 })
133
134 it('accepts disabled via attrs', async () => {
135 const component = await mountSuspended(InputBase, {
136 attrs: { disabled: '' },
137 })
138 const input = component.find('input')
139 expect(input.attributes('disabled')).toBeDefined()
140 expect((input.element as HTMLInputElement).disabled).toBe(true)
141 })
142 })
143})