forked from EXT/VR180-Web-Player
191 lines
4.7 KiB
JavaScript
191 lines
4.7 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
createMediaAdapter,
|
|
ImageMediaAdapter,
|
|
VideoMediaAdapter
|
|
} from '../vr180player/media/media-adapter.js';
|
|
|
|
function createClassList() {
|
|
return {
|
|
values: [],
|
|
add(...values) {
|
|
this.values.push(...values);
|
|
}
|
|
};
|
|
}
|
|
|
|
function createVideo({
|
|
ended = false,
|
|
paused = false,
|
|
source = 'https://cdn.example.com/videos/demo-video.mp4',
|
|
title = ''
|
|
} = {}) {
|
|
return {
|
|
HAVE_METADATA: 1,
|
|
classList: createClassList(),
|
|
ended,
|
|
loadCount: 0,
|
|
paused,
|
|
readyState: 0,
|
|
style: { display: '' },
|
|
tagName: 'VIDEO',
|
|
addEventListener() {},
|
|
getAttribute(name) {
|
|
return name === 'title' ? title : '';
|
|
},
|
|
load() {
|
|
this.loadCount += 1;
|
|
},
|
|
querySelector(selector) {
|
|
if (selector !== 'source' || !source) {
|
|
return null;
|
|
}
|
|
|
|
return { src: source };
|
|
}
|
|
};
|
|
}
|
|
|
|
function createImage({
|
|
alt = '',
|
|
complete = true,
|
|
naturalWidth = 1920,
|
|
source = 'https://cdn.example.com/images/demo-image.png',
|
|
title = ''
|
|
} = {}) {
|
|
return {
|
|
alt,
|
|
classList: createClassList(),
|
|
complete,
|
|
currentSrc: source,
|
|
naturalWidth,
|
|
src: source,
|
|
style: { display: '' },
|
|
tagName: 'IMG',
|
|
addEventListener() {},
|
|
getAttribute(name) {
|
|
if (name === 'title') return title;
|
|
if (name === 'alt') return alt;
|
|
return '';
|
|
}
|
|
};
|
|
}
|
|
|
|
test('VideoMediaAdapter exposes video capabilities and lifecycle helpers', () => {
|
|
const video = createVideo({ title: 'Demo Title' });
|
|
const adapter = new VideoMediaAdapter(video);
|
|
|
|
assert.deepEqual(adapter.capabilities, {
|
|
audio: true,
|
|
dynamicTexture: true,
|
|
playback: true,
|
|
timeline: true
|
|
});
|
|
assert.equal(adapter.element, video);
|
|
assert.equal(adapter.textureSource, video);
|
|
assert.equal(adapter.getTitle(), 'Demo Title');
|
|
|
|
adapter.hideElement();
|
|
assert.equal(video.style.display, 'none');
|
|
|
|
adapter.showElement();
|
|
assert.equal(video.style.display, '');
|
|
|
|
adapter.load();
|
|
assert.equal(video.loadCount, 1);
|
|
});
|
|
|
|
test('VideoMediaAdapter falls back to source filename and tracks texture update state', () => {
|
|
const video = createVideo({ source: 'https://cdn.example.com/media/flat-sbs-demo.mp4' });
|
|
const adapter = new VideoMediaAdapter(video);
|
|
|
|
assert.equal(adapter.getTitle(), 'flat sbs demo');
|
|
assert.equal(adapter.shouldUpdateTexture(), true);
|
|
|
|
video.paused = true;
|
|
assert.equal(adapter.shouldUpdateTexture(), false);
|
|
|
|
video.paused = false;
|
|
video.ended = true;
|
|
assert.equal(adapter.shouldUpdateTexture(), false);
|
|
});
|
|
|
|
test('ImageMediaAdapter exposes static image capabilities and lifecycle helpers', async () => {
|
|
const image = createImage({ alt: 'Alt Title' });
|
|
const adapter = new ImageMediaAdapter(image);
|
|
let readyCount = 0;
|
|
|
|
adapter.bindLoadState({
|
|
onError: () => {},
|
|
onReady: () => {
|
|
readyCount += 1;
|
|
}
|
|
});
|
|
|
|
await new Promise((resolve) => setImmediate(resolve));
|
|
|
|
assert.deepEqual(adapter.capabilities, {
|
|
audio: false,
|
|
dynamicTexture: false,
|
|
playback: false,
|
|
timeline: false
|
|
});
|
|
assert.equal(adapter.element, image);
|
|
assert.equal(adapter.textureSource, image);
|
|
assert.equal(adapter.getTitle(), 'Alt Title');
|
|
assert.equal(adapter.shouldUpdateTexture(), false);
|
|
assert.equal(readyCount, 1);
|
|
|
|
adapter.hideElement();
|
|
assert.equal(image.style.display, 'none');
|
|
|
|
adapter.showElement();
|
|
assert.equal(image.style.display, '');
|
|
});
|
|
|
|
test('ImageMediaAdapter falls back to source filename', () => {
|
|
const image = createImage({ alt: '', source: 'https://cdn.example.com/media/static-sbs-demo.png' });
|
|
const adapter = new ImageMediaAdapter(image);
|
|
|
|
assert.equal(adapter.getTitle(), 'static sbs demo');
|
|
});
|
|
|
|
test('createMediaAdapter finds and marks the supported video element', () => {
|
|
const video = createVideo();
|
|
const playerContainer = {
|
|
querySelectorAll(selector) {
|
|
return selector === 'video,img' ? [video] : [];
|
|
}
|
|
};
|
|
|
|
const adapter = createMediaAdapter(playerContainer);
|
|
|
|
assert.ok(adapter instanceof VideoMediaAdapter);
|
|
assert.equal(adapter.element, video);
|
|
assert.deepEqual(video.classList.values, ['vrwp-media', 'vrwp-video']);
|
|
});
|
|
|
|
test('createMediaAdapter finds and marks the supported image element', () => {
|
|
const image = createImage();
|
|
const playerContainer = {
|
|
querySelectorAll(selector) {
|
|
return selector === 'video,img' ? [image] : [];
|
|
}
|
|
};
|
|
|
|
const adapter = createMediaAdapter(playerContainer);
|
|
|
|
assert.ok(adapter instanceof ImageMediaAdapter);
|
|
assert.equal(adapter.element, image);
|
|
assert.deepEqual(image.classList.values, ['vrwp-media', 'vrwp-image']);
|
|
});
|
|
|
|
test('createMediaAdapter refuses missing or ambiguous media elements', () => {
|
|
const video = createVideo();
|
|
const image = createImage();
|
|
|
|
assert.equal(createMediaAdapter({ querySelectorAll: () => [] }), null);
|
|
assert.equal(createMediaAdapter({ querySelectorAll: () => [video, image] }), null);
|
|
});
|