@datametria/vue-components 1.1.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +548 -590
- package/dist/index.es.js +2460 -1440
- package/dist/index.umd.js +10 -10
- package/dist/vue-components.css +1 -1
- package/package.json +102 -98
- package/src/components/DatametriaAlert.vue +38 -24
- package/src/components/DatametriaAutocomplete.vue +184 -138
- package/src/components/DatametriaAvatar.vue +177 -33
- package/src/components/DatametriaBadge.vue +31 -23
- package/src/components/DatametriaBreadcrumb.vue +21 -21
- package/src/components/DatametriaButton.vue +38 -18
- package/src/components/DatametriaCard.vue +12 -12
- package/src/components/DatametriaCheckbox.vue +8 -8
- package/src/components/DatametriaChip.vue +29 -33
- package/src/components/DatametriaContainer.vue +4 -4
- package/src/components/DatametriaDatePicker.vue +686 -68
- package/src/components/DatametriaDivider.vue +13 -13
- package/src/components/DatametriaFileUpload.vue +272 -140
- package/src/components/DatametriaGrid.vue +3 -3
- package/src/components/DatametriaInput.vue +15 -15
- package/src/components/DatametriaMenu.vue +604 -619
- package/src/components/DatametriaModal.vue +16 -16
- package/src/components/DatametriaNavbar.vue +57 -54
- package/src/components/DatametriaPasswordInput.vue +430 -0
- package/src/components/DatametriaProgress.vue +18 -18
- package/src/components/DatametriaRadio.vue +20 -20
- package/src/components/DatametriaSelect.vue +15 -15
- package/src/components/DatametriaSkeleton.vue +243 -239
- package/src/components/DatametriaSlider.vue +395 -407
- package/src/components/DatametriaSortableTable.vue +585 -0
- package/src/components/DatametriaSpinner.vue +7 -7
- package/src/components/DatametriaSwitch.vue +16 -16
- package/src/components/DatametriaTable.vue +14 -14
- package/src/components/DatametriaTextarea.vue +28 -28
- package/src/components/DatametriaTimePicker.vue +285 -285
- package/src/components/DatametriaToast.vue +32 -19
- package/src/components/DatametriaTooltip.vue +408 -408
- package/src/components/__tests__/DatametriaAlert.test.js +36 -0
- package/src/components/__tests__/DatametriaAlert.test.ts +190 -0
- package/src/components/__tests__/DatametriaAutocomplete.test.ts +180 -0
- package/src/components/__tests__/DatametriaAvatar.test.ts +152 -0
- package/src/components/__tests__/DatametriaBadge.test.js +30 -0
- package/src/components/__tests__/DatametriaBadge.test.ts +167 -0
- package/src/components/__tests__/DatametriaBreadcrumb.test.ts +75 -0
- package/src/components/__tests__/DatametriaButton.test.js +31 -0
- package/src/components/__tests__/DatametriaButton.test.ts +283 -0
- package/src/components/__tests__/DatametriaCard.test.ts +201 -0
- package/src/components/__tests__/DatametriaCheckbox.test.ts +47 -0
- package/src/components/__tests__/DatametriaChip.test.js +39 -0
- package/src/components/__tests__/DatametriaContainer.test.ts +52 -0
- package/src/components/__tests__/DatametriaDatePicker.test.ts +234 -0
- package/src/components/__tests__/DatametriaDivider.test.ts +54 -0
- package/src/components/__tests__/DatametriaFileUpload.test.ts +291 -0
- package/src/components/__tests__/DatametriaGrid.test.ts +31 -0
- package/src/components/__tests__/DatametriaInput.test.ts +72 -0
- package/src/components/__tests__/DatametriaMenu.test.ts +366 -0
- package/src/components/__tests__/DatametriaModal.test.ts +86 -0
- package/src/components/__tests__/DatametriaNavbar.test.js +49 -0
- package/src/components/__tests__/DatametriaNavbar.test.ts +203 -0
- package/src/components/__tests__/DatametriaPasswordInput.test.js +305 -0
- package/src/components/__tests__/DatametriaProgress.test.ts +90 -0
- package/src/components/__tests__/DatametriaRadio.test.ts +77 -0
- package/src/components/__tests__/DatametriaSelect.test.ts +77 -0
- package/src/components/__tests__/DatametriaSlider.test.ts +261 -0
- package/src/components/__tests__/DatametriaSortableTable.test.js +168 -0
- package/src/components/__tests__/DatametriaSpinner.test.ts +156 -0
- package/src/components/__tests__/DatametriaSwitch.test.ts +64 -0
- package/src/components/__tests__/DatametriaTable.test.ts +97 -0
- package/src/components/__tests__/DatametriaTextarea.test.ts +66 -0
- package/src/components/__tests__/DatametriaToast.test.js +49 -0
- package/src/components/__tests__/DatametriaToast.test.ts +99 -0
- package/src/composables/useAccessibilityScale.ts +94 -94
- package/src/composables/useBreakpoints.ts +82 -82
- package/src/composables/useHapticFeedback.ts +439 -439
- package/src/composables/useRipple.ts +218 -218
- package/src/index.ts +68 -61
- package/src/stories/Variants.stories.js +96 -0
- package/src/styles/design-tokens.css +623 -623
- package/src/theme/ThemeProvider.vue +96 -0
- package/src/theme/__tests__/ThemeProvider.test.ts +208 -0
- package/src/theme/__tests__/constants.test.ts +31 -0
- package/src/theme/__tests__/presets.test.ts +166 -0
- package/src/theme/__tests__/tokens.test.ts +155 -0
- package/src/theme/__tests__/types.test.ts +153 -0
- package/src/theme/__tests__/useTheme.test.ts +146 -0
- package/src/theme/constants.ts +14 -0
- package/src/theme/index.ts +12 -0
- package/src/theme/presets/datametria.ts +94 -0
- package/src/theme/presets/default.ts +94 -0
- package/src/theme/presets/index.ts +8 -0
- package/src/theme/tokens/colors.ts +28 -0
- package/src/theme/tokens/index.ts +47 -0
- package/src/theme/tokens/spacing.ts +21 -0
- package/src/theme/tokens/typography.ts +35 -0
- package/src/theme/types.ts +111 -0
- package/src/theme/useTheme.ts +28 -0
- package/src/types/index.ts +19 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import DatametriaPasswordInput from '../DatametriaPasswordInput.vue'
|
|
4
|
+
|
|
5
|
+
describe('DatametriaPasswordInput', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
8
|
+
props: {
|
|
9
|
+
label: 'Senha'
|
|
10
|
+
}
|
|
11
|
+
})
|
|
12
|
+
expect(wrapper.find('.datametria-password-input').exists()).toBe(true)
|
|
13
|
+
expect(wrapper.find('label').text()).toContain('Senha')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('toggles password visibility', async () => {
|
|
17
|
+
const wrapper = mount(DatametriaPasswordInput)
|
|
18
|
+
const input = wrapper.find('input')
|
|
19
|
+
const toggleButton = wrapper.find('.datametria-password-input__toggle')
|
|
20
|
+
|
|
21
|
+
expect(input.attributes('type')).toBe('password')
|
|
22
|
+
|
|
23
|
+
await toggleButton.trigger('click')
|
|
24
|
+
expect(input.attributes('type')).toBe('text')
|
|
25
|
+
|
|
26
|
+
await toggleButton.trigger('click')
|
|
27
|
+
expect(input.attributes('type')).toBe('password')
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('validates password strength', async () => {
|
|
31
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
32
|
+
props: {
|
|
33
|
+
modelValue: '',
|
|
34
|
+
showStrength: true
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
// Weak password
|
|
39
|
+
await wrapper.setProps({ modelValue: 'abc' })
|
|
40
|
+
expect(wrapper.find('.datametria-password-input__strength-text--weak').exists()).toBe(true)
|
|
41
|
+
|
|
42
|
+
// Strong password
|
|
43
|
+
await wrapper.setProps({ modelValue: 'Abc123!@#' })
|
|
44
|
+
expect(wrapper.find('.datametria-password-input__strength-text--strong').exists()).toBe(true)
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('shows requirements when focused', async () => {
|
|
48
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
49
|
+
props: {
|
|
50
|
+
showRequirements: true
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
const input = wrapper.find('input')
|
|
55
|
+
|
|
56
|
+
expect(wrapper.find('.datametria-password-input__requirements').exists()).toBe(false)
|
|
57
|
+
|
|
58
|
+
await input.trigger('focus')
|
|
59
|
+
expect(wrapper.find('.datametria-password-input__requirements').exists()).toBe(true)
|
|
60
|
+
|
|
61
|
+
await input.trigger('blur')
|
|
62
|
+
expect(wrapper.find('.datametria-password-input__requirements').exists()).toBe(false)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it('validates all requirements', async () => {
|
|
66
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
67
|
+
props: {
|
|
68
|
+
modelValue: 'Abc123!@#',
|
|
69
|
+
showRequirements: true
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
await wrapper.find('input').trigger('focus')
|
|
74
|
+
|
|
75
|
+
const requirements = wrapper.findAll('.datametria-password-input__requirements-list li')
|
|
76
|
+
expect(requirements).toHaveLength(5)
|
|
77
|
+
|
|
78
|
+
// All requirements should be valid
|
|
79
|
+
requirements.forEach(req => {
|
|
80
|
+
expect(req.classes()).toContain('valid')
|
|
81
|
+
})
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
it('emits update:modelValue on input', async () => {
|
|
85
|
+
const wrapper = mount(DatametriaPasswordInput)
|
|
86
|
+
const input = wrapper.find('input')
|
|
87
|
+
|
|
88
|
+
await input.setValue('test123')
|
|
89
|
+
expect(wrapper.emitted('update:modelValue')).toBeTruthy()
|
|
90
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['test123'])
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
it('emits strength-change event', async () => {
|
|
94
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
95
|
+
props: {
|
|
96
|
+
modelValue: ''
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
await wrapper.setProps({ modelValue: 'Abc123!@#' })
|
|
101
|
+
await wrapper.vm.$nextTick()
|
|
102
|
+
|
|
103
|
+
expect(wrapper.emitted('strength-change')).toBeTruthy()
|
|
104
|
+
expect(wrapper.emitted('strength-change')?.[0]?.[0]).toBe(100)
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
it('shows error message', () => {
|
|
108
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
109
|
+
props: {
|
|
110
|
+
errorMessage: 'Senha inválida'
|
|
111
|
+
}
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
expect(wrapper.find('.datametria-password-input__error').text()).toBe('Senha inválida')
|
|
115
|
+
expect(wrapper.find('input').classes()).toContain('datametria-password-input__field--error')
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
it('shows help text', () => {
|
|
119
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
120
|
+
props: {
|
|
121
|
+
helpText: 'Use uma senha forte'
|
|
122
|
+
}
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
expect(wrapper.find('.datametria-password-input__help').text()).toBe('Use uma senha forte')
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
it('marks required field', () => {
|
|
129
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
130
|
+
props: {
|
|
131
|
+
label: 'Senha',
|
|
132
|
+
required: true
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
expect(wrapper.find('.datametria-password-input__required').exists()).toBe(true)
|
|
137
|
+
expect(wrapper.find('input').attributes('required')).toBeDefined()
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('disables input when disabled prop is true', () => {
|
|
141
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
142
|
+
props: {
|
|
143
|
+
disabled: true
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
const input = wrapper.find('input')
|
|
148
|
+
expect(input.attributes('disabled')).toBeDefined()
|
|
149
|
+
expect(input.classes()).toContain('datametria-password-input__field--disabled')
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('sets correct autocomplete attribute', () => {
|
|
153
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
154
|
+
props: {
|
|
155
|
+
autocomplete: 'new-password'
|
|
156
|
+
}
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
expect(wrapper.find('input').attributes('autocomplete')).toBe('new-password')
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
it('has proper ARIA attributes', async () => {
|
|
163
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
164
|
+
props: {
|
|
165
|
+
errorMessage: 'Senha inválida',
|
|
166
|
+
showRequirements: true
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
const input = wrapper.find('input')
|
|
171
|
+
|
|
172
|
+
expect(input.attributes('aria-invalid')).toBe('true')
|
|
173
|
+
|
|
174
|
+
await input.trigger('focus')
|
|
175
|
+
expect(input.attributes('aria-describedby')).toBeTruthy()
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
it('toggle button has proper accessibility', () => {
|
|
179
|
+
const wrapper = mount(DatametriaPasswordInput)
|
|
180
|
+
const toggleButton = wrapper.find('.datametria-password-input__toggle')
|
|
181
|
+
|
|
182
|
+
expect(toggleButton.attributes('aria-label')).toBe('Mostrar senha')
|
|
183
|
+
expect(toggleButton.attributes('type')).toBe('button')
|
|
184
|
+
expect(toggleButton.attributes('tabindex')).toBe('-1')
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
describe('CSS Variables Integration', () => {
|
|
188
|
+
it('uses semantic color tokens for strength indicators', async () => {
|
|
189
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
190
|
+
props: {
|
|
191
|
+
modelValue: 'Abc123!@#',
|
|
192
|
+
showStrength: true
|
|
193
|
+
}
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
expect(wrapper.find('.datametria-password-input__strength-fill--strong').exists()).toBe(true)
|
|
197
|
+
expect(wrapper.find('.datametria-password-input__strength-text--strong').exists()).toBe(true)
|
|
198
|
+
})
|
|
199
|
+
|
|
200
|
+
it('uses error token for error states', () => {
|
|
201
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
202
|
+
props: {
|
|
203
|
+
errorMessage: 'Error'
|
|
204
|
+
}
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
expect(wrapper.find('.datametria-password-input__field--error').exists()).toBe(true)
|
|
208
|
+
expect(wrapper.find('.datametria-password-input__error').exists()).toBe(true)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
it('uses warning token for caps lock warning', async () => {
|
|
212
|
+
const wrapper = mount(DatametriaPasswordInput)
|
|
213
|
+
const input = wrapper.find('input')
|
|
214
|
+
|
|
215
|
+
const event = new KeyboardEvent('keyup', { key: 'A' })
|
|
216
|
+
Object.defineProperty(event, 'getModifierState', {
|
|
217
|
+
value: vi.fn(() => true)
|
|
218
|
+
})
|
|
219
|
+
|
|
220
|
+
await input.element.dispatchEvent(event)
|
|
221
|
+
await wrapper.vm.$nextTick()
|
|
222
|
+
|
|
223
|
+
expect(wrapper.find('.datametria-password-input__warning').exists()).toBe(true)
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
it('uses success token for valid requirements', async () => {
|
|
227
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
228
|
+
props: {
|
|
229
|
+
modelValue: 'Abc123!@#',
|
|
230
|
+
showRequirements: true
|
|
231
|
+
}
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
await wrapper.find('input').trigger('focus')
|
|
235
|
+
const validItems = wrapper.findAll('.datametria-password-input__requirements-list li.valid')
|
|
236
|
+
expect(validItems.length).toBe(5)
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
it('uses spacing tokens consistently', () => {
|
|
240
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
241
|
+
props: {
|
|
242
|
+
label: 'Password',
|
|
243
|
+
showRequirements: true
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
expect(wrapper.find('.datametria-password-input').exists()).toBe(true)
|
|
248
|
+
expect(wrapper.find('.datametria-password-input__field').exists()).toBe(true)
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
it('uses typography tokens for text elements', () => {
|
|
252
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
253
|
+
props: {
|
|
254
|
+
label: 'Password',
|
|
255
|
+
helpText: 'Help text'
|
|
256
|
+
}
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
expect(wrapper.find('.datametria-password-input__label').exists()).toBe(true)
|
|
260
|
+
expect(wrapper.find('.datametria-password-input__help').exists()).toBe(true)
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
it('uses transition tokens for animations', async () => {
|
|
264
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
265
|
+
props: {
|
|
266
|
+
modelValue: '',
|
|
267
|
+
showStrength: true
|
|
268
|
+
}
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
await wrapper.setProps({ modelValue: 'test' })
|
|
272
|
+
expect(wrapper.find('.datametria-password-input__strength-fill').exists()).toBe(true)
|
|
273
|
+
})
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
describe('Backward Compatibility', () => {
|
|
277
|
+
it('works without ThemeProvider', () => {
|
|
278
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
279
|
+
props: {
|
|
280
|
+
label: 'Password',
|
|
281
|
+
modelValue: 'Abc123!@#',
|
|
282
|
+
showStrength: true,
|
|
283
|
+
showRequirements: true
|
|
284
|
+
}
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
expect(wrapper.find('.datametria-password-input').exists()).toBe(true)
|
|
288
|
+
expect(wrapper.find('.datametria-password-input__strength').exists()).toBe(true)
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
it('maintains original visual appearance with fallback values', async () => {
|
|
292
|
+
const wrapper = mount(DatametriaPasswordInput, {
|
|
293
|
+
props: {
|
|
294
|
+
modelValue: 'weak',
|
|
295
|
+
showStrength: true
|
|
296
|
+
}
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
expect(wrapper.find('.datametria-password-input__strength-fill--weak').exists()).toBe(true)
|
|
300
|
+
|
|
301
|
+
await wrapper.setProps({ modelValue: 'Abc123!@#' })
|
|
302
|
+
expect(wrapper.find('.datametria-password-input__strength-fill--strong').exists()).toBe(true)
|
|
303
|
+
})
|
|
304
|
+
})
|
|
305
|
+
})
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import DatametriaProgress from '../DatametriaProgress.vue'
|
|
4
|
+
|
|
5
|
+
describe('DatametriaProgress', () => {
|
|
6
|
+
it('renders with value', () => {
|
|
7
|
+
const wrapper = mount(DatametriaProgress, {
|
|
8
|
+
props: { value: 50 }
|
|
9
|
+
})
|
|
10
|
+
expect(wrapper.find('.dm-progress').exists()).toBe(true)
|
|
11
|
+
expect(wrapper.find('.dm-progress__bar').attributes('style')).toContain('width: 50%')
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
it('renders with label', () => {
|
|
15
|
+
const wrapper = mount(DatametriaProgress, {
|
|
16
|
+
props: { value: 75, label: 'Loading' }
|
|
17
|
+
})
|
|
18
|
+
expect(wrapper.find('.dm-progress__label').text()).toBe('Loading')
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('shows value by default', () => {
|
|
22
|
+
const wrapper = mount(DatametriaProgress, {
|
|
23
|
+
props: { value: 60, label: 'Test' }
|
|
24
|
+
})
|
|
25
|
+
expect(wrapper.find('.dm-progress__value').text()).toBe('60%')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('hides value when showValue is false', () => {
|
|
29
|
+
const wrapper = mount(DatametriaProgress, {
|
|
30
|
+
props: { value: 60, label: 'Test', showValue: false }
|
|
31
|
+
})
|
|
32
|
+
expect(wrapper.find('.dm-progress__value').exists()).toBe(false)
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('clamps value to 0-100 range', () => {
|
|
36
|
+
const wrapper1 = mount(DatametriaProgress, { props: { value: -10 } })
|
|
37
|
+
expect(wrapper1.find('.dm-progress__bar').attributes('style')).toContain('width: 0%')
|
|
38
|
+
|
|
39
|
+
const wrapper2 = mount(DatametriaProgress, { props: { value: 150 } })
|
|
40
|
+
expect(wrapper2.find('.dm-progress__bar').attributes('style')).toContain('width: 100%')
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
it('renders primary variant', () => {
|
|
44
|
+
const wrapper = mount(DatametriaProgress, {
|
|
45
|
+
props: { value: 50, variant: 'primary' }
|
|
46
|
+
})
|
|
47
|
+
expect(wrapper.find('.dm-progress__bar--primary').exists()).toBe(true)
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('renders success variant', () => {
|
|
51
|
+
const wrapper = mount(DatametriaProgress, {
|
|
52
|
+
props: { value: 50, variant: 'success' }
|
|
53
|
+
})
|
|
54
|
+
expect(wrapper.find('.dm-progress__bar--success').exists()).toBe(true)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('renders warning variant', () => {
|
|
58
|
+
const wrapper = mount(DatametriaProgress, {
|
|
59
|
+
props: { value: 50, variant: 'warning' }
|
|
60
|
+
})
|
|
61
|
+
expect(wrapper.find('.dm-progress__bar--warning').exists()).toBe(true)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('renders error variant', () => {
|
|
65
|
+
const wrapper = mount(DatametriaProgress, {
|
|
66
|
+
props: { value: 50, variant: 'error' }
|
|
67
|
+
})
|
|
68
|
+
expect(wrapper.find('.dm-progress__bar--error').exists()).toBe(true)
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('has correct ARIA attributes', () => {
|
|
72
|
+
const wrapper = mount(DatametriaProgress, {
|
|
73
|
+
props: { value: 75, label: 'Progress' }
|
|
74
|
+
})
|
|
75
|
+
const track = wrapper.find('.dm-progress__track')
|
|
76
|
+
expect(track.attributes('role')).toBe('progressbar')
|
|
77
|
+
expect(track.attributes('aria-valuenow')).toBe('75')
|
|
78
|
+
expect(track.attributes('aria-valuemin')).toBe('0')
|
|
79
|
+
expect(track.attributes('aria-valuemax')).toBe('100')
|
|
80
|
+
expect(track.attributes('aria-label')).toBe('Progress')
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('works without ThemeProvider', () => {
|
|
84
|
+
const wrapper = mount(DatametriaProgress, {
|
|
85
|
+
props: { value: 80, label: 'Test', variant: 'success' }
|
|
86
|
+
})
|
|
87
|
+
expect(wrapper.find('.dm-progress__bar--success').exists()).toBe(true)
|
|
88
|
+
expect(wrapper.find('.dm-progress__bar').attributes('style')).toContain('width: 80%')
|
|
89
|
+
})
|
|
90
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import DatametriaRadio from '../DatametriaRadio.vue'
|
|
4
|
+
|
|
5
|
+
describe('DatametriaRadio', () => {
|
|
6
|
+
it('renders correctly', () => {
|
|
7
|
+
const wrapper = mount(DatametriaRadio, {
|
|
8
|
+
props: { value: 'option1' }
|
|
9
|
+
})
|
|
10
|
+
expect(wrapper.find('.dm-radio').exists()).toBe(true)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('renders label when provided', () => {
|
|
14
|
+
const wrapper = mount(DatametriaRadio, {
|
|
15
|
+
props: { value: 'option1', label: 'Option 1' }
|
|
16
|
+
})
|
|
17
|
+
expect(wrapper.find('.dm-radio__text').text()).toBe('Option 1')
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('checks radio when modelValue matches value', () => {
|
|
21
|
+
const wrapper = mount(DatametriaRadio, {
|
|
22
|
+
props: { value: 'option1', modelValue: 'option1' }
|
|
23
|
+
})
|
|
24
|
+
expect((wrapper.find('input').element as HTMLInputElement).checked).toBe(true)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('emits update:modelValue on change', async () => {
|
|
28
|
+
const wrapper = mount(DatametriaRadio, {
|
|
29
|
+
props: { value: 'option1' }
|
|
30
|
+
})
|
|
31
|
+
await wrapper.find('input').trigger('change')
|
|
32
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['option1'])
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('applies disabled state', () => {
|
|
36
|
+
const wrapper = mount(DatametriaRadio, {
|
|
37
|
+
props: { value: 'option1', disabled: true }
|
|
38
|
+
})
|
|
39
|
+
expect(wrapper.find('input').attributes('disabled')).toBeDefined()
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('does not emit when disabled', async () => {
|
|
43
|
+
const wrapper = mount(DatametriaRadio, {
|
|
44
|
+
props: { value: 'option1', disabled: true }
|
|
45
|
+
})
|
|
46
|
+
await wrapper.find('input').trigger('change')
|
|
47
|
+
expect(wrapper.emitted('update:modelValue')).toBeUndefined()
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it('shows error message when provided', () => {
|
|
51
|
+
const wrapper = mount(DatametriaRadio, {
|
|
52
|
+
props: { value: 'option1', name: 'test', error: 'Error text' }
|
|
53
|
+
})
|
|
54
|
+
expect(wrapper.find('.dm-radio__error').text()).toBe('Error text')
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
it('applies name attribute', () => {
|
|
58
|
+
const wrapper = mount(DatametriaRadio, {
|
|
59
|
+
props: { value: 'option1', name: 'radio-group' }
|
|
60
|
+
})
|
|
61
|
+
expect(wrapper.find('input').attributes('name')).toBe('radio-group')
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('applies aria-label', () => {
|
|
65
|
+
const wrapper = mount(DatametriaRadio, {
|
|
66
|
+
props: { value: 'option1', ariaLabel: 'Select option' }
|
|
67
|
+
})
|
|
68
|
+
expect(wrapper.find('input').attributes('aria-label')).toBe('Select option')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('uses CSS variables with fallbacks', () => {
|
|
72
|
+
const wrapper = mount(DatametriaRadio, {
|
|
73
|
+
props: { value: 'option1' }
|
|
74
|
+
})
|
|
75
|
+
expect(wrapper.html()).toContain('dm-radio')
|
|
76
|
+
})
|
|
77
|
+
})
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest'
|
|
2
|
+
import { mount } from '@vue/test-utils'
|
|
3
|
+
import DatametriaSelect from '../DatametriaSelect.vue'
|
|
4
|
+
|
|
5
|
+
describe('DatametriaSelect', () => {
|
|
6
|
+
const options = [
|
|
7
|
+
{ value: '1', label: 'Option 1' },
|
|
8
|
+
{ value: '2', label: 'Option 2' },
|
|
9
|
+
{ value: '3', label: 'Option 3' }
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
it('renders correctly', () => {
|
|
13
|
+
const wrapper = mount(DatametriaSelect, {
|
|
14
|
+
props: { options }
|
|
15
|
+
})
|
|
16
|
+
expect(wrapper.find('.datametria-select').exists()).toBe(true)
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
it('renders label when provided', () => {
|
|
20
|
+
const wrapper = mount(DatametriaSelect, {
|
|
21
|
+
props: { options, label: 'Select Label' }
|
|
22
|
+
})
|
|
23
|
+
expect(wrapper.find('.datametria-select__label').text()).toContain('Select Label')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('shows required indicator', () => {
|
|
27
|
+
const wrapper = mount(DatametriaSelect, {
|
|
28
|
+
props: { options, label: 'Test', required: true }
|
|
29
|
+
})
|
|
30
|
+
expect(wrapper.find('.datametria-select__required').exists()).toBe(true)
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
it('renders all options', () => {
|
|
34
|
+
const wrapper = mount(DatametriaSelect, {
|
|
35
|
+
props: { options }
|
|
36
|
+
})
|
|
37
|
+
const optionElements = wrapper.findAll('option')
|
|
38
|
+
expect(optionElements.length).toBeGreaterThanOrEqual(3)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
it('renders placeholder option', () => {
|
|
42
|
+
const wrapper = mount(DatametriaSelect, {
|
|
43
|
+
props: { options, placeholder: 'Choose option' }
|
|
44
|
+
})
|
|
45
|
+
const firstOption = wrapper.find('option')
|
|
46
|
+
expect(firstOption.text()).toBe('Choose option')
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('binds modelValue correctly', () => {
|
|
50
|
+
const wrapper = mount(DatametriaSelect, {
|
|
51
|
+
props: { options, modelValue: '2' }
|
|
52
|
+
})
|
|
53
|
+
expect((wrapper.find('select').element as HTMLSelectElement).value).toBe('2')
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('emits update:modelValue on change', async () => {
|
|
57
|
+
const wrapper = mount(DatametriaSelect, {
|
|
58
|
+
props: { options }
|
|
59
|
+
})
|
|
60
|
+
await wrapper.find('select').setValue('2')
|
|
61
|
+
expect(wrapper.emitted('update:modelValue')?.[0]).toEqual(['2'])
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('shows error message', () => {
|
|
65
|
+
const wrapper = mount(DatametriaSelect, {
|
|
66
|
+
props: { options, errorMessage: 'Error text' }
|
|
67
|
+
})
|
|
68
|
+
expect(wrapper.find('.datametria-select__error').text()).toBe('Error text')
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
it('applies disabled state', () => {
|
|
72
|
+
const wrapper = mount(DatametriaSelect, {
|
|
73
|
+
props: { options, disabled: true }
|
|
74
|
+
})
|
|
75
|
+
expect(wrapper.find('select').attributes('disabled')).toBeDefined()
|
|
76
|
+
})
|
|
77
|
+
})
|