From 4a45dd4801135a6a0df2a1440092547922e71abb Mon Sep 17 00:00:00 2001 From: curo1305 Date: Mon, 15 Jun 2026 20:09:21 +0200 Subject: [PATCH] test(10-01): add failing AppIcon tests for icon registry contract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 6 tests covering name→path rendering, class forwarding, dual-path (cog), svg attrs, unknown-name warn, and path stroke attrs - RED phase: AppIcon.vue does not exist yet; tests fail on import --- .../components/ui/__tests__/AppIcon.test.js | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 frontend/src/components/ui/__tests__/AppIcon.test.js diff --git a/frontend/src/components/ui/__tests__/AppIcon.test.js b/frontend/src/components/ui/__tests__/AppIcon.test.js new file mode 100644 index 0000000..d4c96ed --- /dev/null +++ b/frontend/src/components/ui/__tests__/AppIcon.test.js @@ -0,0 +1,56 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest' +import { mount } from '@vue/test-utils' +import AppIcon from '../AppIcon.vue' + +describe('AppIcon', () => { + beforeEach(() => { + vi.restoreAllMocks() + }) + + it('renders with the correct d attribute for a known single-path icon (folder)', () => { + const wrapper = mount(AppIcon, { props: { name: 'folder' } }) + const path = wrapper.find('path') + expect(path.exists()).toBe(true) + expect(path.attributes('d')).toMatch(/^M3 7a2 2 0 012-2h4l2 2h8a2 2 0 012 2v9/) + }) + + it('forwards consumer class to the element', () => { + const wrapper = mount(AppIcon, { + props: { name: 'folder' }, + attrs: { class: 'w-4 h-4 text-amber-500' }, + }) + const svg = wrapper.find('svg') + expect(svg.classes()).toContain('w-4') + expect(svg.classes()).toContain('h-4') + expect(svg.classes()).toContain('text-amber-500') + }) + + it('renders TWO elements for a dual-path icon (cog)', () => { + const wrapper = mount(AppIcon, { props: { name: 'cog' } }) + expect(wrapper.findAll('path').length).toBe(2) + }) + + it('renders the standard SVG attrs (fill=none, stroke=currentColor, viewBox=0 0 24 24)', () => { + const wrapper = mount(AppIcon, { props: { name: 'folder' } }) + const svg = wrapper.find('svg') + expect(svg.attributes('fill')).toBe('none') + expect(svg.attributes('stroke')).toBe('currentColor') + expect(svg.attributes('viewBox')).toBe('0 0 24 24') + }) + + it('renders no svg and calls console.warn when name is unknown', () => { + const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {}) + const wrapper = mount(AppIcon, { props: { name: 'bogus-name' } }) + expect(wrapper.find('svg').exists()).toBe(false) + expect(warnSpy).toHaveBeenCalledOnce() + expect(warnSpy.mock.calls[0][0]).toContain('bogus-name') + }) + + it('path elements use stroke-linecap=round, stroke-linejoin=round, stroke-width=2', () => { + const wrapper = mount(AppIcon, { props: { name: 'folder' } }) + const path = wrapper.find('path') + expect(path.attributes('stroke-linecap')).toBe('round') + expect(path.attributes('stroke-linejoin')).toBe('round') + expect(path.attributes('stroke-width')).toBe('2') + }) +})