mirror of
https://github.com/nathonius/obsidian-github-link.git
synced 2026-07-22 09:20:25 +00:00
🚨 test: Add more tests
This commit is contained in:
parent
ebb30a8940
commit
6e143d00ce
4 changed files with 118 additions and 0 deletions
|
|
@ -3,6 +3,7 @@ import { PluginMock } from "./obsidian/Plugin";
|
|||
import { ModalMock } from "./obsidian/Modal";
|
||||
import { PluginSettingTabMock } from "./obsidian/PluginSettingTab";
|
||||
import { NoticeMock } from "./obsidian/Notice";
|
||||
import { setIconMock } from "./obsidian/setIcon";
|
||||
|
||||
module.exports = {
|
||||
App: AppMock,
|
||||
|
|
@ -10,4 +11,5 @@ module.exports = {
|
|||
Modal: ModalMock,
|
||||
PluginSettingTab: PluginSettingTabMock,
|
||||
Notice: NoticeMock,
|
||||
setIcon: setIconMock,
|
||||
};
|
||||
|
|
|
|||
5
__mocks__/obsidian/setIcon.ts
Normal file
5
__mocks__/obsidian/setIcon.ts
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
export function setIconMock(parent: HTMLElement, iconId: string): void {
|
||||
const icon = document.createElement("span");
|
||||
icon.innerText = iconId;
|
||||
parent.appendChild(icon);
|
||||
}
|
||||
45
src/inline/inline.spec.ts
Normal file
45
src/inline/inline.spec.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import { test, describe, expect, beforeAll } from "@jest/globals";
|
||||
import { elementTestSetup } from "../../test/element";
|
||||
import { createTag } from "./inline";
|
||||
|
||||
const selectors = {
|
||||
org: ".github-link-inline-org",
|
||||
repo: ".github-link-inline-repo",
|
||||
issueTitle: ".github-link-inline-issue-title",
|
||||
prTitle: ".github-link-inline-pr-title",
|
||||
};
|
||||
|
||||
describe("createTag", () => {
|
||||
beforeAll(() => {
|
||||
elementTestSetup();
|
||||
});
|
||||
test.each([
|
||||
{ url: "https://github.com/nathonius", user: "nathonius" },
|
||||
{ url: "https://github.com/nathonius/", user: "nathonius" },
|
||||
{ url: "https://github.com/sam.lake", user: "sam.lake" },
|
||||
{ url: "https://github.com/abraham_lincoln", user: "abraham_lincoln" },
|
||||
])("user only $user", ({ url, user }) => {
|
||||
const tag = createTag(url);
|
||||
expect(tag).toBeTruthy();
|
||||
const org = tag?.querySelector(selectors.org) as HTMLSpanElement;
|
||||
expect(org.innerText).toEqual(user);
|
||||
[selectors.repo, selectors.issueTitle, selectors.prTitle].forEach((s) => {
|
||||
expect(tag?.querySelector(s)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
test.each([
|
||||
{ url: "https://github.com/nathonius/obsidian-github-link", user: "nathonius", repo: "obsidian-github-link" },
|
||||
{ url: "https://github.com/nathonius/obsidian.github.link", user: "nathonius", repo: "obsidian.github.link" },
|
||||
])("repo $repo", ({ url, user, repo }) => {
|
||||
const tag = createTag(url);
|
||||
expect(tag).toBeTruthy();
|
||||
const org = tag?.querySelector(selectors.org) as HTMLSpanElement;
|
||||
const repoEl = tag?.querySelector(selectors.repo) as HTMLSpanElement;
|
||||
expect(org.innerText).toEqual(user);
|
||||
expect(repoEl.innerText).toEqual(repo);
|
||||
[selectors.issueTitle, selectors.prTitle].forEach((s) => {
|
||||
expect(tag?.querySelector(s)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
66
test/element.ts
Normal file
66
test/element.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* Local version of obsidian's 'createEl' function, copied from
|
||||
* https://ryotaushio.github.io/the-hobbyist-dev/obsidian/api-&-internals/createel.html
|
||||
*/
|
||||
function createEl<K extends keyof HTMLElementTagNameMap>(
|
||||
tag: K,
|
||||
options?: string | DomElementInfo,
|
||||
callback?: (el: HTMLElementTagNameMap[K]) => void,
|
||||
): HTMLElementTagNameMap[K] {
|
||||
const el = document.createElement(tag);
|
||||
if (typeof options === "string") options = { cls: options };
|
||||
options = options || {};
|
||||
|
||||
if (options.cls) Array.isArray(options.cls) ? (el.className = options.cls.join(" ")) : (el.className = options.cls);
|
||||
if (options.text) el.setText(options.text);
|
||||
if (options.attr) {
|
||||
for (const [k, v] of Object.entries(options.attr)) {
|
||||
el.setAttribute(k, String(v));
|
||||
}
|
||||
}
|
||||
if (options.title !== undefined) el.title = options.title;
|
||||
if (
|
||||
options.value !== undefined &&
|
||||
(el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLOptionElement)
|
||||
) {
|
||||
el.value = options.value;
|
||||
}
|
||||
if (options.type && el instanceof HTMLInputElement) el.type = options.type;
|
||||
if (options.type && el instanceof HTMLStyleElement) el.setAttribute("type", options.type);
|
||||
if (options.placeholder && el instanceof HTMLInputElement) el.placeholder = options.placeholder;
|
||||
if (
|
||||
options.href &&
|
||||
(el instanceof HTMLAnchorElement || el instanceof HTMLLinkElement || el instanceof HTMLBaseElement)
|
||||
)
|
||||
el.href = options.href;
|
||||
callback?.(el);
|
||||
if (options.parent) {
|
||||
if (options.prepend) options.parent.insertBefore(el, options.parent.firstChild);
|
||||
else options.parent.appendChild(el);
|
||||
}
|
||||
// add event listeners (e.g. { onclick: () => {} })
|
||||
for (const key in options) {
|
||||
if (Object.prototype.hasOwnProperty.call(options, key) && key.startsWith("on")) {
|
||||
const value = options[key as keyof DomElementInfo];
|
||||
if (typeof value === "function") el.addEventListener(key.substring(2), value);
|
||||
}
|
||||
}
|
||||
return el;
|
||||
}
|
||||
|
||||
function createSpan(options?: string | DomElementInfo, callback?: (el: HTMLSpanElement) => void) {
|
||||
return createEl("span", options, callback);
|
||||
}
|
||||
|
||||
function createDiv(options?: string | DomElementInfo, callback?: (el: HTMLDivElement) => void) {
|
||||
return createEl("div", options, callback);
|
||||
}
|
||||
|
||||
export function elementTestSetup() {
|
||||
HTMLElement.prototype.setText = function (text: string) {
|
||||
this.innerText = text;
|
||||
};
|
||||
window.createEl = createEl;
|
||||
window.createSpan = createSpan;
|
||||
window.createDiv = createDiv;
|
||||
}
|
||||
Loading…
Reference in a new issue