mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
182 lines
6.3 KiB
TypeScript
182 lines
6.3 KiB
TypeScript
import { afterAll, beforeAll, describe, expect, it, type MockInstance, vi } from 'vitest';
|
|
|
|
/**
|
|
* Tests that composite define files register all expected custom elements
|
|
* and that provider/parent elements are defined before consumer/child elements.
|
|
*
|
|
* Tests run sequentially. Each dynamically imports a composite define file and
|
|
* checks the batch of `customElements.define()` calls that resulted. Because
|
|
* modules are cached within a test file, shared sub-elements (e.g. slider parts)
|
|
* are only registered by the first composite that imports them — subsequent
|
|
* composites skip them via `safeDefine`. This is intentional and tested.
|
|
*/
|
|
describe('composite define registration', () => {
|
|
let spy: MockInstance;
|
|
|
|
/** Tag names registered since `offset` (the call count before an import). */
|
|
function batchSince(offset: number): string[] {
|
|
return spy.mock.calls.slice(offset).map((call) => call[0] as string);
|
|
}
|
|
|
|
beforeAll(() => {
|
|
spy = vi.spyOn(customElements, 'define');
|
|
});
|
|
|
|
afterAll(() => {
|
|
spy.mockRestore();
|
|
});
|
|
|
|
// ── Player composites ────────────────────────────────────────────────
|
|
|
|
describe('video/player', () => {
|
|
it('registers video-player before media-container', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../video/player');
|
|
const batch = batchSince(before);
|
|
|
|
expect(batch).toContain('video-player');
|
|
expect(batch).toContain('media-container');
|
|
expect(batch.indexOf('video-player')).toBeLessThan(batch.indexOf('media-container'));
|
|
});
|
|
});
|
|
|
|
describe('audio/player', () => {
|
|
it('registers audio-player', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../audio/player');
|
|
const batch = batchSince(before);
|
|
|
|
expect(batch).toContain('audio-player');
|
|
// media-container already registered by video/player — safeDefine skips it
|
|
expect(batch).not.toContain('media-container');
|
|
});
|
|
});
|
|
|
|
describe('background/player', () => {
|
|
it('registers background-video-player', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../background/player');
|
|
const batch = batchSince(before);
|
|
|
|
expect(batch).toContain('background-video-player');
|
|
expect(batch).not.toContain('media-container');
|
|
});
|
|
});
|
|
|
|
// ── Slider composites ────────────────────────────────────────────────
|
|
|
|
describe('ui/time-slider', () => {
|
|
it('registers media-time-slider before sub-elements', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../ui/time-slider');
|
|
const batch = batchSince(before);
|
|
|
|
// Parent slider must be first (provider for sliderContext)
|
|
expect(batch[0]).toBe('media-time-slider');
|
|
|
|
// All sub-elements registered (first composite to claim them)
|
|
expect(batch).toContain('media-slider-buffer');
|
|
expect(batch).toContain('media-slider-fill');
|
|
expect(batch).toContain('media-slider-thumb');
|
|
expect(batch).toContain('media-slider-track');
|
|
expect(batch).toContain('media-slider-value');
|
|
});
|
|
});
|
|
|
|
describe('ui/volume-slider', () => {
|
|
it('registers media-volume-slider and skips already-defined sub-elements', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../ui/volume-slider');
|
|
const batch = batchSince(before);
|
|
|
|
expect(batch).toContain('media-volume-slider');
|
|
|
|
// Sub-elements already registered by time-slider — safeDefine skips them
|
|
expect(batch).not.toContain('media-slider-fill');
|
|
expect(batch).not.toContain('media-slider-thumb');
|
|
expect(batch).not.toContain('media-slider-track');
|
|
expect(batch).not.toContain('media-slider-value');
|
|
});
|
|
});
|
|
|
|
describe('ui/slider', () => {
|
|
it('registers media-slider', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../ui/slider');
|
|
const batch = batchSince(before);
|
|
|
|
expect(batch).toContain('media-slider');
|
|
});
|
|
});
|
|
|
|
// ── Other composites ─────────────────────────────────────────────────
|
|
|
|
describe('ui/time', () => {
|
|
it('registers media-time before sub-elements', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../ui/time');
|
|
const batch = batchSince(before);
|
|
|
|
expect(batch[0]).toBe('media-time');
|
|
expect(batch).toContain('media-time-group');
|
|
expect(batch).toContain('media-time-separator');
|
|
});
|
|
});
|
|
|
|
describe('ui/controls', () => {
|
|
it('registers media-controls before sub-elements', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../ui/controls');
|
|
const batch = batchSince(before);
|
|
|
|
expect(batch[0]).toBe('media-controls');
|
|
expect(batch).toContain('media-controls-group');
|
|
});
|
|
});
|
|
|
|
describe('video/ui', () => {
|
|
it('registers media-text for skin template labels', async () => {
|
|
const before = spy.mock.calls.length;
|
|
await import('../video/ui');
|
|
const batch = batchSince(before);
|
|
|
|
expect(batch).toContain('media-text');
|
|
});
|
|
});
|
|
|
|
// ── Final state ──────────────────────────────────────────────────────
|
|
|
|
describe('registry completeness', () => {
|
|
it('all expected elements are registered after importing all composites', () => {
|
|
const expected = [
|
|
// Players + container
|
|
'video-player',
|
|
'audio-player',
|
|
'background-video-player',
|
|
'media-container',
|
|
// Sliders
|
|
'media-slider',
|
|
'media-time-slider',
|
|
'media-volume-slider',
|
|
// Slider sub-elements
|
|
'media-slider-buffer',
|
|
'media-slider-fill',
|
|
'media-slider-thumb',
|
|
'media-slider-track',
|
|
'media-slider-value',
|
|
// Time
|
|
'media-time',
|
|
'media-time-group',
|
|
'media-time-separator',
|
|
// Controls
|
|
'media-controls',
|
|
'media-controls-group',
|
|
];
|
|
|
|
for (const tagName of expected) {
|
|
expect(customElements.get(tagName), `${tagName} should be registered`).toBeDefined();
|
|
}
|
|
});
|
|
});
|
|
});
|