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:
@@ -13,6 +13,9 @@ bun.lockb
|
|||||||
/.svelte-kit
|
/.svelte-kit
|
||||||
/build
|
/build
|
||||||
|
|
||||||
|
# Local tests
|
||||||
|
/tests/
|
||||||
|
|
||||||
# Nix
|
# Nix
|
||||||
/result
|
/result
|
||||||
|
|
||||||
|
|||||||
@@ -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