@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
278 lines • 12.6 kB
JavaScript
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