UNPKG

@furystack/shades-common-components

Version:

Common UI components for FuryStack Shades

278 lines 12.6 kB
import { createComponent, flushUpdates } from '@furystack/shades'; import { describe, expect, it } from 'vitest'; import { Card, CardActions, CardContent, CardHeader, CardMedia } from './card.js'; describe('Card', () => { it('should be defined', () => { expect(Card).toBeDefined(); expect(typeof Card).toBe('function'); }); it('should create a card element', () => { const el = (createComponent(Card, null)); expect(el).toBeDefined(); expect(el.tagName?.toLowerCase()).toBe('shade-card'); }); it('should render children', async () => { const el = (createComponent("div", null, createComponent(Card, null, createComponent("span", null, "Content")))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.querySelector('span')).not.toBeNull(); }); it('should set data-variant to elevation by default', async () => { const el = (createComponent("div", null, createComponent(Card, null))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.getAttribute('data-variant')).toBe('elevation'); }); it('should set data-variant to outlined when specified', async () => { const el = (createComponent("div", null, createComponent(Card, { variant: "outlined" }))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.getAttribute('data-variant')).toBe('outlined'); }); it('should set data-elevation to 1 by default', async () => { const el = (createComponent("div", null, createComponent(Card, null))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.getAttribute('data-elevation')).toBe('1'); }); it('should set data-elevation to the provided value', async () => { const el = (createComponent("div", null, createComponent(Card, { elevation: 3 }))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.getAttribute('data-elevation')).toBe('3'); }); it('should set data-clickable when clickable is true', async () => { const el = (createComponent("div", null, createComponent(Card, { clickable: true }))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.hasAttribute('data-clickable')).toBe(true); }); it('should set data-clickable when onclick handler is provided', async () => { const el = (createComponent("div", null, createComponent(Card, { onclick: () => { } }))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.hasAttribute('data-clickable')).toBe(true); }); it('should not set data-clickable by default', async () => { const el = (createComponent("div", null, createComponent(Card, null))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.hasAttribute('data-clickable')).toBe(false); }); }); describe('CardHeader', () => { it('should be defined', () => { expect(CardHeader).toBeDefined(); expect(typeof CardHeader).toBe('function'); }); it('should create a card-header element', () => { const el = (createComponent(CardHeader, { title: "Title" })); expect(el).toBeDefined(); expect(el.tagName?.toLowerCase()).toBe('shade-card-header'); }); it('should render a title', async () => { const el = (createComponent("div", null, createComponent(CardHeader, { title: "My Title" }))); const header = el.firstElementChild; header.updateComponent(); await flushUpdates(); const titleEl = header.querySelector('.card-header-title'); expect(titleEl).not.toBeNull(); expect(titleEl?.textContent).toBe('My Title'); }); it('should render a subheader when provided', async () => { const el = (createComponent("div", null, createComponent(CardHeader, { title: "Title", subheader: "Subheader text" }))); const header = el.firstElementChild; header.updateComponent(); await flushUpdates(); const subheaderEl = header.querySelector('.card-header-subheader'); expect(subheaderEl).not.toBeNull(); expect(subheaderEl?.textContent).toBe('Subheader text'); }); it('should not render a subheader when not provided', async () => { const el = (createComponent("div", null, createComponent(CardHeader, { title: "Title" }))); const header = el.firstElementChild; header.updateComponent(); await flushUpdates(); const subheaderEl = header.querySelector('.card-header-subheader'); expect(subheaderEl).toBeNull(); }); it('should render an avatar when provided', async () => { const el = (createComponent("div", null, createComponent(CardHeader, { title: "Title", avatar: createComponent("span", { className: "test-avatar" }, "A") }))); const header = el.firstElementChild; header.updateComponent(); await flushUpdates(); const avatarContainer = header.querySelector('.card-header-avatar'); expect(avatarContainer).not.toBeNull(); expect(avatarContainer?.querySelector('.test-avatar')).not.toBeNull(); }); it('should not render avatar container when not provided', async () => { const el = (createComponent("div", null, createComponent(CardHeader, { title: "Title" }))); const header = el.firstElementChild; header.updateComponent(); await flushUpdates(); expect(header.querySelector('.card-header-avatar')).toBeNull(); }); it('should render an action when provided', async () => { const el = (createComponent("div", null, createComponent(CardHeader, { title: "Title", action: createComponent("button", { className: "test-action" }, "X") }))); const header = el.firstElementChild; header.updateComponent(); await flushUpdates(); const actionContainer = header.querySelector('.card-header-action'); expect(actionContainer).not.toBeNull(); expect(actionContainer?.querySelector('.test-action')).not.toBeNull(); }); it('should not render action container when not provided', async () => { const el = (createComponent("div", null, createComponent(CardHeader, { title: "Title" }))); const header = el.firstElementChild; header.updateComponent(); await flushUpdates(); expect(header.querySelector('.card-header-action')).toBeNull(); }); }); describe('CardContent', () => { it('should be defined', () => { expect(CardContent).toBeDefined(); expect(typeof CardContent).toBe('function'); }); it('should create a card-content element', () => { const el = (createComponent(CardContent, null)); expect(el).toBeDefined(); expect(el.tagName?.toLowerCase()).toBe('shade-card-content'); }); it('should render children', async () => { const el = (createComponent("div", null, createComponent(CardContent, null, createComponent("p", null, "Some text content")))); const content = el.firstElementChild; content.updateComponent(); await flushUpdates(); expect(content.querySelector('p')).not.toBeNull(); }); }); describe('CardMedia', () => { it('should be defined', () => { expect(CardMedia).toBeDefined(); expect(typeof CardMedia).toBe('function'); }); it('should create a card-media element', () => { const el = (createComponent(CardMedia, { image: "https://example.com/img.jpg" })); expect(el).toBeDefined(); expect(el.tagName?.toLowerCase()).toBe('shade-card-media'); }); it('should render an img element with the provided src', async () => { const el = (createComponent("div", null, createComponent(CardMedia, { image: "https://example.com/photo.jpg", alt: "Test photo" }))); const media = el.firstElementChild; media.updateComponent(); await flushUpdates(); const img = media.querySelector('img'); expect(img).not.toBeNull(); expect(img.getAttribute('src')).toBe('https://example.com/photo.jpg'); expect(img.getAttribute('alt')).toBe('Test photo'); }); it('should set height on the element', async () => { const el = (createComponent("div", null, createComponent(CardMedia, { image: "https://example.com/photo.jpg", height: "300px" }))); const media = el.firstElementChild; media.updateComponent(); await flushUpdates(); expect(media.style.height).toBe('300px'); }); it('should default height to 200px', async () => { const el = (createComponent("div", null, createComponent(CardMedia, { image: "https://example.com/photo.jpg" }))); const media = el.firstElementChild; media.updateComponent(); await flushUpdates(); expect(media.style.height).toBe('200px'); }); it('should default alt to empty string', async () => { const el = (createComponent("div", null, createComponent(CardMedia, { image: "https://example.com/photo.jpg" }))); const media = el.firstElementChild; media.updateComponent(); await flushUpdates(); const img = media.querySelector('img'); expect(img.getAttribute('alt')).toBe(''); }); }); describe('CardActions', () => { it('should be defined', () => { expect(CardActions).toBeDefined(); expect(typeof CardActions).toBe('function'); }); it('should create a card-actions element', () => { const el = (createComponent(CardActions, null)); expect(el).toBeDefined(); expect(el.tagName?.toLowerCase()).toBe('shade-card-actions'); }); it('should render children', async () => { const el = (createComponent("div", null, createComponent(CardActions, null, createComponent("button", null, "Action")))); const actions = el.firstElementChild; actions.updateComponent(); await flushUpdates(); expect(actions.querySelector('button')).not.toBeNull(); }); it('should set data-disable-spacing when disableSpacing is true', async () => { const el = (createComponent("div", null, createComponent(CardActions, { disableSpacing: true }))); const actions = el.firstElementChild; actions.updateComponent(); await flushUpdates(); expect(actions.hasAttribute('data-disable-spacing')).toBe(true); }); it('should not set data-disable-spacing by default', async () => { const el = (createComponent("div", null, createComponent(CardActions, null))); const actions = el.firstElementChild; actions.updateComponent(); await flushUpdates(); expect(actions.hasAttribute('data-disable-spacing')).toBe(false); }); }); describe('Card composition', () => { it('should compose Card with all sub-components', async () => { const el = (createComponent("div", null, createComponent(Card, null, createComponent(CardMedia, { image: "https://example.com/img.jpg", alt: "Photo" }), createComponent(CardHeader, { title: "Title", subheader: "Subheader" }), createComponent(CardContent, null, createComponent("p", null, "Body text")), createComponent(CardActions, null, createComponent("button", null, "Learn More"))))); const card = el.firstElementChild; card.updateComponent(); await flushUpdates(); expect(card.querySelector('shade-card-media')).not.toBeNull(); expect(card.querySelector('shade-card-header')).not.toBeNull(); expect(card.querySelector('shade-card-content')).not.toBeNull(); expect(card.querySelector('shade-card-actions')).not.toBeNull(); }); }); //# sourceMappingURL=card.spec.js.map