| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398 |
- import * as fs from 'fs/promises';
- import * as node from '../source/node.js';
- import * as path from 'path';
- import * as url from 'url';
- import * as worker_threads from 'worker_threads';
- const mock = {};
- mock.Context = class {
- constructor(host, folder, identifier, stream, entries) {
- this._host = host;
- this._folder = folder;
- this._identifier = identifier;
- this._stream = stream;
- this._entries = entries;
- }
- get identifier() {
- return this._identifier;
- }
- get stream() {
- return this._stream;
- }
- get entries() {
- return this._entries;
- }
- async request(file, encoding, base) {
- return this._host.request(file, encoding, base === undefined ? this._folder : base);
- }
- async require(id) {
- return this._host.require(id);
- }
- error(error, fatal) {
- this._host.exception(error, fatal);
- }
- };
- class CSSStyleDeclaration {
- constructor() {
- this._properties = new Map();
- }
- setProperty(name, value) {
- this._properties.set(name, value);
- }
- removeProperty(name) {
- this._properties.delete(name);
- }
- }
- class DOMTokenList {
- constructor(element) {
- this._element = element;
- }
- add(...tokens) {
- const value = this._element.getAttribute('class') || '';
- const set = new Set(value.split(' ').concat(...tokens));
- this._element.setAttribute('class', Array.from(set).filter((s) => s).join(' '));
- }
- contains(token) {
- const value = this._element.getAttribute('class');
- if (value === null || value.indexOf(token) === -1) {
- return false;
- }
- return value.split(' ').some((s) => s === token);
- }
- }
- class HTMLElement {
- constructor(document) {
- this._document = document;
- this._childNodes = [];
- this._attributes = new Map();
- this._style = new CSSStyleDeclaration();
- }
- get style() {
- return this._style;
- }
- get childNodes() {
- return this._childNodes;
- }
- get firstChild() {
- return this._childNodes.length > 0 ? this._childNodes[0] : null;
- }
- get lastChild() {
- const index = this._childNodes.length - 1;
- if (index >= 0) {
- return this._childNodes[index];
- }
- return null;
- }
- appendChild(node) {
- this._childNodes.push(node);
- }
- insertBefore(newNode, referenceNode) {
- const index = this._childNodes.indexOf(referenceNode);
- if (index !== -1) {
- this._childNodes.splice(index, 0, newNode);
- }
- }
- removeChild(node) {
- const index = this._childNodes.lastIndexOf(node);
- if (index !== -1) {
- this._childNodes.splice(index, 1);
- this._document._removeElement(node);
- }
- }
- replaceChildren(...nodes) {
- for (const child of this._childNodes) {
- this._document._removeElement(child);
- }
- this._childNodes = [...nodes];
- }
- replaceChild(newChild, oldChild) {
- const index = this._childNodes.indexOf(oldChild);
- if (index !== -1) {
- this._childNodes[index] = newChild;
- }
- return oldChild;
- }
- setAttribute(name, value) {
- if (name === 'id') {
- this._document._updateElementId(this, value);
- }
- this._attributes.set(name, value);
- }
- hasAttribute(name) {
- return this._attributes.has(name);
- }
- getAttribute(name) {
- return this._attributes.has(name) ? this._attributes.get(name) : null;
- }
- getElementsByClassName(name) {
- const elements = [];
- for (const node of this._childNodes) {
- if (node instanceof HTMLElement) {
- elements.push(...node.getElementsByClassName(name));
- if (node.classList.contains(name)) {
- elements.push(node);
- }
- }
- }
- return elements;
- }
- addEventListener(/* event, callback */) {
- }
- removeEventListener(/* event, callback */) {
- }
- get classList() {
- this._classList = this._classList || new DOMTokenList(this);
- return this._classList;
- }
- getBBox() {
- return { x: 0, y: 0, width: 10, height: 10 };
- }
- getBoundingClientRect() {
- return { left: 0, top: 0, width: 0, height: 0 };
- }
- scrollTo() {
- }
- focus() {
- }
- }
- class Document {
- constructor() {
- this._elements = new Map();
- this._documentElement = new HTMLElement(this);
- this._body = new HTMLElement(this);
- this._documentElement.appendChild(this._body);
- }
- get documentElement() {
- return this._documentElement;
- }
- get body() {
- return this._body;
- }
- createElement(name) {
- const element = new HTMLElement(this);
- element.tagName = name.toUpperCase();
- return element;
- }
- createElementNS(namespace, name) {
- const element = new HTMLElement(this);
- element.namespaceURI = namespace;
- element.tagName = name;
- return element;
- }
- createTextNode(text) {
- const element = new HTMLElement(this);
- element.textContent = text;
- return element;
- }
- addEventListener(/* event, callback */) {
- }
- removeEventListener(/* event, callback */) {
- }
- getElementById(id) {
- return this._elements.get(id) || null;
- }
- _removeElement(element) {
- this._updateElementId(element, null);
- for (const child of element.childNodes) {
- this._removeElement(child);
- }
- }
- _updateElementId(element, newId) {
- const previous = element.getAttribute('id');
- if (previous) {
- this._elements.delete(previous);
- }
- if (newId) {
- this._elements.set(newId, element);
- }
- }
- }
- class Window {
- constructor() {
- this._document = new Document();
- }
- get document() {
- return this._document;
- }
- addEventListener(/* event, callback */) {
- }
- removeEventListener(/* event, callback */) {
- }
- requestAnimationFrame(callback) {
- callback();
- }
- setTimeout(code, delay) {
- return global.setTimeout(code, delay);
- }
- clearTimeout(timeoutID) {
- global.clearTimeout(timeoutID);
- }
- }
- mock.Host = class {
- constructor(environment) {
- this._environment = environment;
- this._errors = [];
- mock.Host.source = mock.Host.source || this._dirname('..', 'source');
- if (!mock.Host.window) {
- mock.Host.window = new Window();
- const document = mock.Host.window.document;
- for (const id of ['target', 'sidebar']) {
- const element = document.createElement('div');
- element.setAttribute('id', id);
- document.body.appendChild(element);
- }
- }
- }
- async view(/* view */) {
- }
- async start() {
- }
- get window() {
- return mock.Host.window;
- }
- get document() {
- return this.window.document;
- }
- get errors() {
- return this._errors;
- }
- get type() {
- return 'Test';
- }
- environment(name) {
- return this._environment[name];
- }
- update() {
- }
- screen(/* name */) {
- }
- async require(id) {
- const file = path.join(mock.Host.source, `${id}.js`);
- return await import(`file://${file}`);
- }
- worker(id) {
- const file = path.join(mock.Host.source, `${id}.js`);
- const worker = new worker_threads.Worker(file);
- worker.addEventListener = (type, listener) => {
- worker.on(type, (message) => listener({ data: message }));
- };
- return worker;
- }
- async request(file, encoding, basename) {
- const pathname = path.join(basename || mock.Host.source, file);
- const exists = await this._access(pathname);
- if (!exists) {
- throw new Error(`The file '${file}' does not exist.`);
- }
- const stats = await fs.stat(pathname);
- if (stats.isDirectory()) {
- throw new Error(`The path '${file}' is a directory.`);
- }
- if (encoding) {
- return await fs.readFile(pathname, encoding);
- }
- return new node.FileStream(pathname, 0, stats.size, stats.mtimeMs);
- }
- event(/* name, params */) {
- }
- exception(error /*, fatal */) {
- this._errors.push(error);
- }
- message() {
- }
- async _access(path) {
- try {
- await fs.access(path);
- return true;
- } catch {
- return false;
- }
- }
- _dirname(...args) {
- const file = url.fileURLToPath(import.meta.url);
- const dir = path.dirname(file);
- return path.join(dir, ...args);
- }
- };
- export const Host = mock.Host;
- export const Context = mock.Context;
|