Ctrl K
ComunidadGuías…

test/icon-strip-tooltip.test.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
var test = require("node:test");
var assert = require("node:assert/strict");
var path = require("node:path");
var pathToFileURL = require("node:url").pathToFileURL;

function ClassList(element) { this.element = element; }
ClassList.prototype.values = function () { return this.element.className ? this.element.className.split(/\s+/).filter(Boolean) : []; };
ClassList.prototype.add = function (value) { var values = this.values(); if (values.indexOf(value) === -1) values.push(value); this.element.className = values.join(" "); };
ClassList.prototype.contains = function (value) { return this.values().indexOf(value) !== -1; };

function FakeElement(tag, documentRef) {
  this.tagName = String(tag).toUpperCase();
  this.ownerDocument = documentRef;
  this.children = [];
  this.parentNode = null;
  this.listeners = {};
  this.attributes = {};
  this.dataset = {};
  this.style = {};
  this.className = "";
  this.classList = new ClassList(this);
  this._textContent = "";
  this.offsetHeight = 28;
  this.offsetWidth = 120;
}
FakeElement.prototype.appendChild = function (child) { child.parentNode = this; this.children.push(child); return child; };
FakeElement.prototype.remove = function () { if (!this.parentNode) return; var index = this.parentNode.children.indexOf(this); if (index !== -1) this.parentNode.children.splice(index, 1); this.parentNode = null; };
FakeElement.prototype.setAttribute = function (name, value) { this.attributes[name] = String(value); };
FakeElement.prototype.getAttribute = function (name) { return this.attributes[name] === undefined ? null : this.attributes[name]; };
FakeElement.prototype.addEventListener = function (type, handler) { this.listeners[type] = this.listeners[type] || []; this.listeners[type].push(handler); };
FakeElement.prototype.emit = function (type, event) { var value = Object.assign({ type: type, target: this }, event || {}); var handlers = (this.listeners[type] || []).slice(); for (var i = 0; i < handlers.length; i++) handlers[i](value); };
FakeElement.prototype.getBoundingClientRect = function () { return { top: 20, left: 12, right: 60, bottom: 68, width: 48, height: 48 }; };
FakeElement.prototype.querySelector = function (selector) {
  var className = selector.charAt(0) === "." ? selector.substring(1) : "";
  var queue = this.children.slice();
  while (queue.length) {
    var node = queue.shift();
    if (className && node.classList.contains(className)) return node;
    queue = queue.concat(node.children);
  }
  return null;
};
Object.defineProperty(FakeElement.prototype, "isConnected", { get: function () { var node = this; while (node) { if (node === this.ownerDocument.body) return true; node = node.parentNode; } return false; } });
Object.defineProperty(FakeElement.prototype, "textContent", {
  get: function () { return this._textContent; },
  set: function (value) { this._textContent = String(value); this.children = []; },
});

function installDom() {
  var prior = { document: global.document, requestAnimationFrame: global.requestAnimationFrame, window: global.window };
  var documentRef = {};
  documentRef.createElement = function (tag) { return new FakeElement(tag, documentRef); };
  documentRef.body = new FakeElement("body", documentRef);
  global.document = documentRef;
  global.window = { innerWidth: 1024 };
  global.requestAnimationFrame = function (callback) { callback(); return 1; };
  return { document: documentRef, restore: function () { global.document = prior.document; global.requestAnimationFrame = prior.requestAnimationFrame; global.window = prior.window; } };
}

test("project and Mate rail tooltips alternate across hover and focus without parsing names", async function () {
  var dom = installDom();
  try {
    var modulePath = path.join(__dirname, "../lib/public/modules/icon-strip-tooltip.js");
    var tooltip = await import(pathToFileURL(modulePath).href);
    var project = dom.document.createElement("a");
    var mate = dom.document.createElement("button");
    mate.setAttribute("aria-label", "에코, 연구, Mate, working, 2 unread");
    dom.document.body.appendChild(project);
    dom.document.body.appendChild(mate);

    tooltip.bindIconTooltip(project, { text: "Studio, North", kind: "project" });
    tooltip.bindIconTooltip(mate, function () {
      return { text: "에코, 연구", kind: "mate", avatarUrl: "data:image/png;base64,mate" };
    });

    project.emit("mouseenter");
    var projectTip = dom.document.body.children[2];
    assert.equal(projectTip.dataset.tooltipKind, "project");
    assert.equal(projectTip.textContent, "Studio, North");
    assert.equal(projectTip.classList.contains("icon-strip-tooltip-mate"), false);

    mate.emit("focus");
    assert.equal(dom.document.body.children.length, 3, "the singleton replaces the project tooltip");
    var mateTip = dom.document.body.children[2];
    assert.equal(mateTip.dataset.tooltipKind, "mate");
    assert.equal(mateTip.classList.contains("icon-strip-tooltip-mate"), true);
    assert.equal(mateTip.querySelector(".icon-strip-tooltip-label").textContent, "에코, 연구");
    assert.equal(mateTip.querySelector(".icon-strip-tooltip-mate-avatar").src, "data:image/png;base64,mate");
    assert.equal(mate.getAttribute("aria-label"), "에코, 연구, Mate, working, 2 unread", "accessible status remains descriptive");

    tooltip.bindIconTooltip(mate, { text: "<img src=x onerror=bad>", kind: "mate", avatarUrl: "data:image/png;base64,new" });
    mate.emit("mouseenter");
    var safeTip = dom.document.body.children[2];
    var safeLabel = safeTip.querySelector(".icon-strip-tooltip-label");
    assert.equal(safeLabel.textContent, "<img src=x onerror=bad>");
    assert.equal(safeLabel.children.length, 0, "the visible name is text, not HTML");

    project.emit("focus");
    var restoredProject = dom.document.body.children[2];
    assert.equal(restoredProject.dataset.tooltipKind, "project");
    assert.equal(restoredProject.querySelector(".icon-strip-tooltip-mate-avatar"), null, "Mate styling and avatar do not leak to projects");
    project.emit("keydown", { key: "Escape" });
    assert.equal(dom.document.body.children.length, 2);
  } finally {
    dom.restore();
  }
});