import { afterEach, describe, expect, it, vi } from 'vite-plus/test' import { cloneElement } from './cloneElement.js' describe('cloneElement', () => { afterEach(() => { vi.restoreAllMocks() }) describe('without properties filter', () => { it('copies computed styles to the clone', () => { const element = document.createElement('p') const child = document.createElement('span') element.appendChild(child) vi.spyOn(window, 'getComputedStyle').mockImplementation((node: Element) => { const styles = node === element ? ['margin-top', 'color'] : ['font-weight'] return { length: styles.length, 0: styles[0], 1: styles[1], getPropertyValue: (property: string) => { if (property === 'margin-top') { return '24px' } if (property === 'color') { return 'rgb(1, 2, 3)' } if (property === 'font-weight') { return '700' } return '' }, } as unknown as CSSStyleDeclaration }) const clone = cloneElement(element) expect(clone.style.cssText).toContain('margin-top: 24px;') expect(clone.style.cssText).toContain('color: rgb(1, 2, 3);') expect((clone.firstElementChild as HTMLElement).style.cssText).toContain('font-weight: 700;') }) }) describe('with properties filter', () => { it('copies only the listed properties to the clone', () => { const element = document.createElement('p') const child = document.createElement('span') element.appendChild(child) vi.spyOn(window, 'getComputedStyle').mockImplementation(() => { return { length: 6, 0: 'margin-top', 1: 'color', 2: 'font-weight', 3: 'background-color', 4: 'opacity', 5: 'font-size', getPropertyValue: (property: string) => { if (property === 'margin-top') { return '24px' } if (property === 'color') { return 'rgb(1, 2, 3)' } if (property === 'font-weight') { return '700' } if (property === 'background-color') { return 'rgb(255, 0, 0)' } if (property === 'opacity') { return '0.5' } if (property === 'font-size') { return '16px' } return '' }, } as unknown as CSSStyleDeclaration }) const clone = cloneElement(element, ['margin-top', 'color']) // Listed properties should be present expect(clone.style.cssText).toContain('margin-top: 24px;') expect(clone.style.cssText).toContain('color: rgb(1, 2, 3);') // Non-listed properties should not be present expect(clone.style.cssText).not.toContain('font-weight') expect(clone.style.cssText).not.toContain('background-color') expect(clone.style.cssText).not.toContain('opacity') expect(clone.style.cssText).not.toContain('font-size') }) it('trims surrounding whitespace before reading the property', () => { const element = document.createElement('p') vi.spyOn(window, 'getComputedStyle').mockImplementation(() => { return { length: 1, 0: 'margin-top', getPropertyValue: (property: string) => (property === 'margin-top' ? '24px' : ''), } as unknown as CSSStyleDeclaration }) const clone = cloneElement(element, [' margin-top ']) expect(clone.style.cssText).toContain('margin-top: 24px;') }) it('returns an empty cssText when the properties list is empty', () => { const element = document.createElement('p') vi.spyOn(window, 'getComputedStyle').mockImplementation(() => { return { length: 1, 0: 'color', getPropertyValue: () => 'red', } as unknown as CSSStyleDeclaration }) const clone = cloneElement(element, []) expect(clone.style.cssText).toBe('') }) }) })