mirror of
https://gitlab.com/ArkHost/HelixNotes.git
synced 2026-09-19 09:27:29 +02:00
Keep local tests out of repository
This commit is contained in:
@@ -1,80 +0,0 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import test from 'node:test';
|
||||
import { Schema } from '@tiptap/pm/model';
|
||||
import { transformWithEsbuild } from 'vite';
|
||||
|
||||
const source = await readFile(
|
||||
new URL('../src/lib/editor/mixedLists.ts', import.meta.url),
|
||||
'utf8'
|
||||
);
|
||||
const { code } = await transformWithEsbuild(source, 'mixedLists.ts', {
|
||||
loader: 'ts',
|
||||
format: 'esm',
|
||||
target: 'esnext'
|
||||
});
|
||||
const { convertListNode } = await import(
|
||||
`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`
|
||||
);
|
||||
|
||||
const schema = new Schema({
|
||||
nodes: {
|
||||
doc: { content: 'block+' },
|
||||
paragraph: { content: 'text*', group: 'block' },
|
||||
text: { group: 'inline' },
|
||||
bulletList: { content: 'listItem+', group: 'block' },
|
||||
listItem: { content: 'paragraph block*' },
|
||||
taskList: { content: 'taskItem+', group: 'block' },
|
||||
taskItem: {
|
||||
attrs: { checked: { default: false } },
|
||||
content: 'paragraph block*'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function paragraph(text) {
|
||||
return schema.node('paragraph', null, [schema.text(text)]);
|
||||
}
|
||||
|
||||
test('converts every task item in a list to a bullet item', () => {
|
||||
const sourceList = schema.node('taskList', null, [
|
||||
schema.node('taskItem', { checked: true }, [paragraph('First')]),
|
||||
schema.node('taskItem', { checked: false }, [paragraph('Second')])
|
||||
]);
|
||||
|
||||
const converted = convertListNode(schema, sourceList, 'bulletList');
|
||||
|
||||
assert.equal(converted.type.name, 'bulletList');
|
||||
assert.deepEqual(
|
||||
converted.content.content.map((item) => item.type.name),
|
||||
['listItem', 'listItem']
|
||||
);
|
||||
assert.equal(converted.textContent, 'FirstSecond');
|
||||
assert.equal(sourceList.type.name, 'taskList');
|
||||
});
|
||||
|
||||
test('converts bullet items to unchecked tasks without dropping nested blocks', () => {
|
||||
const nestedBullets = schema.node('bulletList', null, [
|
||||
schema.node('listItem', null, [paragraph('Nested note')])
|
||||
]);
|
||||
const sourceList = schema.node('bulletList', null, [
|
||||
schema.node('listItem', null, [paragraph('Parent'), nestedBullets])
|
||||
]);
|
||||
|
||||
const converted = convertListNode(schema, sourceList, 'taskList');
|
||||
const taskItem = converted.firstChild;
|
||||
|
||||
assert.equal(converted.type.name, 'taskList');
|
||||
assert.equal(taskItem.type.name, 'taskItem');
|
||||
assert.equal(taskItem.attrs.checked, false);
|
||||
assert.equal(taskItem.lastChild.type.name, 'bulletList');
|
||||
assert.equal(taskItem.textContent, 'ParentNested note');
|
||||
});
|
||||
|
||||
test('leaves a list alone when it already has the requested type', () => {
|
||||
const bullets = schema.node('bulletList', null, [
|
||||
schema.node('listItem', null, [paragraph('Unchanged')])
|
||||
]);
|
||||
|
||||
assert.equal(convertListNode(schema, bullets, 'bulletList'), null);
|
||||
});
|
||||
@@ -1,28 +0,0 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import test from 'node:test';
|
||||
import { transformWithEsbuild } from 'vite';
|
||||
|
||||
const source = await readFile(
|
||||
new URL('../src/lib/utils/note-drag.ts', import.meta.url),
|
||||
'utf8'
|
||||
);
|
||||
const { code } = await transformWithEsbuild(source, 'note-drag.ts', {
|
||||
loader: 'ts',
|
||||
format: 'esm',
|
||||
target: 'esnext'
|
||||
});
|
||||
const noteDrag = await import(`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`);
|
||||
|
||||
test('round-trips every selected note path in a drag payload', () => {
|
||||
const paths = ['/vault/Alpha.md', '/vault/Projects/Beta.md'];
|
||||
assert.deepEqual(noteDrag.decodeNoteDragPaths(noteDrag.encodeNoteDragPaths(paths)), paths);
|
||||
});
|
||||
|
||||
test('keeps single-note and Windows path payloads compatible', () => {
|
||||
assert.deepEqual(noteDrag.decodeNoteDragPaths('/vault/Alpha.md'), ['/vault/Alpha.md']);
|
||||
assert.deepEqual(
|
||||
noteDrag.decodeNoteDragPaths('C:\\Vault\\Alpha.md\r\nC:\\Vault\\Beta.md'),
|
||||
['C:\\Vault\\Alpha.md', 'C:\\Vault\\Beta.md']
|
||||
);
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
|
||||
const source = await import(new URL('../src/lib/utils/notebook-icons.ts', import.meta.url));
|
||||
|
||||
const {
|
||||
NOTEBOOK_ICON_OPTIONS,
|
||||
decodeBuiltinNotebookIcon,
|
||||
encodeBuiltinNotebookIcon
|
||||
} = source;
|
||||
|
||||
test('built-in notebook icons have stable unique storage values', () => {
|
||||
assert.equal(NOTEBOOK_ICON_OPTIONS.length, 16);
|
||||
assert.equal(new Set(NOTEBOOK_ICON_OPTIONS.map(({ id }) => id)).size, NOTEBOOK_ICON_OPTIONS.length);
|
||||
|
||||
for (const { id } of NOTEBOOK_ICON_OPTIONS) {
|
||||
const stored = encodeBuiltinNotebookIcon(id);
|
||||
assert.equal(stored, `builtin:${id}`);
|
||||
assert.equal(decodeBuiltinNotebookIcon(stored), id);
|
||||
}
|
||||
});
|
||||
|
||||
test('custom paths and unknown built-in values remain outside the icon codec', () => {
|
||||
assert.equal(decodeBuiltinNotebookIcon('.helixnotes/attachments/notebook-icon.png'), null);
|
||||
assert.equal(decodeBuiltinNotebookIcon('builtin:unknown'), null);
|
||||
assert.equal(decodeBuiltinNotebookIcon(null), null);
|
||||
});
|
||||
@@ -1,31 +0,0 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import test from 'node:test';
|
||||
|
||||
const sidebar = await readFile(
|
||||
new URL('../src/lib/components/Sidebar.svelte', import.meta.url),
|
||||
'utf8'
|
||||
);
|
||||
|
||||
test('mobile notebook rows expose an accessible actions button', () => {
|
||||
assert.match(sidebar, /\{#if isMobile\}[\s\S]{0,500}class="notebook-actions-btn"/);
|
||||
assert.match(sidebar, /aria-label=\{`Actions for \$\{nb\.name\}`\}/);
|
||||
assert.match(sidebar, /onclick=\{\(e\) => openNotebookMenu\(e, nb\)\}/);
|
||||
});
|
||||
|
||||
test('the notebook context menu receives its mobile styling outside the sidebar', () => {
|
||||
assert.match(sidebar, /class="context-menu" class:mobile=\{isMobile\}/);
|
||||
assert.match(sidebar, /\.context-menu\.mobile\s*\{/);
|
||||
});
|
||||
|
||||
test('mobile action sheets stay inside every safe area and prevent tap-through', () => {
|
||||
assert.match(sidebar, /class="context-menu-backdrop"/);
|
||||
assert.match(sidebar, /safe-area-inset-left/);
|
||||
assert.match(sidebar, /safe-area-inset-right/);
|
||||
assert.match(sidebar, /safe-area-inset-top/);
|
||||
assert.match(sidebar, /safe-area-inset-bottom/);
|
||||
});
|
||||
|
||||
test('the actions button remains inside the notebook manual-sort drop target', () => {
|
||||
assert.match(sidebar, /<div class="notebook-row" data-nb-path=\{nb\.path\}>/);
|
||||
});
|
||||
@@ -1,60 +0,0 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import test from 'node:test';
|
||||
import { transformWithEsbuild } from 'vite';
|
||||
|
||||
const source = await readFile(
|
||||
new URL('../src/lib/utils/startup-view.ts', import.meta.url),
|
||||
'utf8'
|
||||
);
|
||||
const { code } = await transformWithEsbuild(source, 'startup-view.ts', {
|
||||
loader: 'ts',
|
||||
format: 'esm',
|
||||
target: 'esnext'
|
||||
});
|
||||
const startup = await import(`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`);
|
||||
|
||||
test('normalizes every supported default view and falls back to All Notes', () => {
|
||||
for (const view of ['all', 'quickaccess', 'tasks', 'daily']) {
|
||||
assert.equal(startup.normalizeStartupView(view), view);
|
||||
}
|
||||
assert.equal(startup.normalizeStartupView('notebook'), 'all');
|
||||
assert.equal(startup.normalizeStartupView(undefined), 'all');
|
||||
});
|
||||
|
||||
test('uses the configured default when session restoration is disabled', () => {
|
||||
assert.deepEqual(startup.resolveStartupTarget({
|
||||
startupView: 'tasks',
|
||||
restoreLastSession: false,
|
||||
lastViewMode: 'daily',
|
||||
lastNotebook: null,
|
||||
lastTag: null
|
||||
}), { mode: 'tasks' });
|
||||
});
|
||||
|
||||
test('restores a supported previous list when restoration is enabled', () => {
|
||||
assert.deepEqual(startup.resolveStartupTarget({
|
||||
startupView: 'daily',
|
||||
restoreLastSession: true,
|
||||
lastViewMode: 'quickaccess',
|
||||
lastNotebook: null,
|
||||
lastTag: null
|
||||
}), { mode: 'quickaccess' });
|
||||
});
|
||||
|
||||
test('restores notebook and tag identifiers, otherwise uses the configured default', () => {
|
||||
assert.deepEqual(startup.resolveStartupTarget({
|
||||
startupView: 'all',
|
||||
restoreLastSession: true,
|
||||
lastViewMode: 'notebook',
|
||||
lastNotebook: 'Projects',
|
||||
lastTag: null
|
||||
}), { mode: 'notebook', notebookPath: 'Projects' });
|
||||
assert.deepEqual(startup.resolveStartupTarget({
|
||||
startupView: 'tasks',
|
||||
restoreLastSession: true,
|
||||
lastViewMode: 'tag',
|
||||
lastNotebook: null,
|
||||
lastTag: null
|
||||
}), { mode: 'tasks' });
|
||||
});
|
||||
Reference in New Issue
Block a user