UNPKG

@datametria/vue-components

Version:

DATAMETRIA Vue.js 3 Component Library with Multi-Brand Theming - 51 components + 10 composables with theming support, WCAG 2.2 AA, dark mode, responsive system

209 lines (171 loc) 5.75 kB
/** * ThemeProvider Tests * @author Vander Loto - CTO DATAMETRIA * @date 13/11/2025 */ import { describe, it, expect } from 'vitest' import { mount } from '@vue/test-utils' import { h } from 'vue' import ThemeProvider from '../ThemeProvider.vue' import { useTheme } from '../useTheme' import { defaultTokens } from '../tokens' import type { Theme } from '../types' const testTheme: Theme = { name: 'Test Theme', tokens: defaultTokens } const customTheme: Theme = { name: 'Custom Theme', tokens: { ...defaultTokens, colors: { ...defaultTokens.colors, primary: '#FF0000', secondary: '#00FF00' } } } describe('ThemeProvider', () => { it('should render children', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div class="test-child">Child Content</div>' } }) expect(wrapper.text()).toContain('Child Content') expect(wrapper.find('.test-child').exists()).toBe(true) }) it('should apply default theme class', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) expect(wrapper.classes()).toContain('dm-theme') }) it('should apply custom prefix class', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme, prefix: 'custom' }, slots: { default: '<div>Content</div>' } }) expect(wrapper.classes()).toContain('custom-theme') }) it('should generate CSS variables for colors', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) const style = wrapper.attributes('style') expect(style).toContain('--dm-primary') expect(style).toContain('#0072CE') expect(style).toContain('--dm-secondary') expect(style).toContain('#4B0078') }) it('should generate CSS variables for neutral colors', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) const style = wrapper.attributes('style') expect(style).toContain('--dm-neutral-50') expect(style).toContain('--dm-neutral-900') }) it('should generate CSS variables for typography', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) const style = wrapper.attributes('style') expect(style).toContain('--dm-font-sans') expect(style).toContain('--dm-text-base') expect(style).toContain('--dm-font-bold') }) it('should generate CSS variables for spacing', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) const style = wrapper.attributes('style') expect(style).toContain('--dm-space-4') expect(style).toContain('1rem') }) it('should generate CSS variables for radius', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) const style = wrapper.attributes('style') expect(style).toContain('--dm-radius-md') }) it('should generate CSS variables for shadows', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) const style = wrapper.attributes('style') expect(style).toContain('--dm-shadow-md') }) it('should generate CSS variables for transitions', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) const style = wrapper.attributes('style') expect(style).toContain('--dm-transition-base') }) it('should use custom prefix for CSS variables', () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme, prefix: 'custom' }, slots: { default: '<div>Content</div>' } }) const style = wrapper.attributes('style') expect(style).toContain('--custom-primary') expect(style).not.toContain('--dm-primary') }) it('should update CSS variables when theme changes', async () => { const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: '<div>Content</div>' } }) let style = wrapper.attributes('style') expect(style).toContain('#0072CE') await wrapper.setProps({ theme: customTheme }) style = wrapper.attributes('style') expect(style).toContain('#FF0000') }) it('should provide theme to child components', () => { const ChildComponent = { setup() { const theme = useTheme() return () => h('div', { class: 'child' }, theme.value.name) } } const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: h(ChildComponent) } }) expect(wrapper.text()).toContain('Test Theme') }) it('should provide updated theme when changed', async () => { const ChildComponent = { setup() { const theme = useTheme() return () => h('div', { class: 'child' }, `${theme.value.name}-${theme.value.tokens.colors.primary}`) } } const wrapper = mount(ThemeProvider, { props: { theme: testTheme }, slots: { default: h(ChildComponent) } }) expect(wrapper.text()).toContain('Test Theme') expect(wrapper.text()).toContain('#0072CE') await wrapper.setProps({ theme: customTheme }) await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Custom Theme') expect(wrapper.text()).toContain('#FF0000') }) })