Files

97 lines
6.6 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { classify, readLibrary } from '../src/index.mjs';
import { BASE, mapping, repo } from './helpers.mjs';
// Playgrounds at three levels (ruling after r11, C2-01c). The fixture's harbor keeps its book-level
// prefix and gains a universe-level one. A hybrid with no books has a universe-level prefix, and a
// draft has its own.
const levels = () => mapping(e => {
e.universes.harbor.playground = ['Book One/Playground/', 'Harbor Ideas/'];
e.universes.cross = { kind: 'hybrid', name: 'Cross', sources: ['harbor', 'second'], books: [], playground: ['Crossover Ideas/'] };
e.universes.idea = { kind: 'draft', name: 'New World', playground: ['Drafts/New World/'] };
return e;
});
test('C2-01c: each level gives its universe, and its book or null', () => {
const m = levels();
assert.deepEqual(classify(m, 'Book One/Playground/Characters/New.md'),
{ scope: 'playground', universe: 'harbor', book: 'Book One', type: 'character', folder: 'Characters' });
assert.deepEqual(classify(m, 'Harbor Ideas/Places/Island.md'),
{ scope: 'playground', universe: 'harbor', book: null, type: 'place', folder: 'Places' });
assert.deepEqual(classify(m, 'Harbor Ideas/Loose.md'), { scope: 'playground', universe: 'harbor', book: null, type: null, folder: null });
assert.deepEqual(classify(m, 'Crossover Ideas/Chapters/Meeting.md'),
{ scope: 'playground', universe: 'cross', book: null, type: 'manuscript', folder: 'Chapters' });
assert.deepEqual(classify(m, 'Drafts/New World/Characters/Ana.md'),
{ scope: 'playground', universe: 'idea', book: null, type: 'character', folder: 'Characters' });
for (const path of ['Harbor Ideas/Board.canvas', 'Crossover Ideas/Sketch.canvas', 'Drafts/New World/Map.canvas',
'Drafts/Other.md', 'Drafts/New World.md', 'Harbor Ideasx/a.md'])
assert.deepEqual(classify(m, path), { scope: 'unmapped' }, path);
});
test('C2-01c: prefixes come first: in a book that holds a prefix, a file outside it is canon and one under it playground', () => {
const m = levels();
assert.deepEqual(classify(m, 'Book One/Places/Dock.md'), { scope: 'canon', universe: 'harbor', book: 'Book One', type: 'place', folder: 'Places' });
assert.deepEqual(classify(m, 'Book One/Playground.md'), { scope: 'canon', universe: 'harbor', book: 'Book One', type: null, folder: null });
assert.deepEqual(classify(m, 'Book One/Playground/What If.md'),
{ scope: 'playground', universe: 'harbor', book: 'Book One', type: null, folder: null });
assert.deepEqual(classify(m, 'Second World/Chapters/01.md'), { scope: 'canon', universe: 'second', book: 'Second World', type: 'manuscript', folder: 'Chapters' });
});
test('C2-01c: a canon file linking into a draft gives R6, and into its own universe-level prefix gives R5', async t => {
const r = repo(t, { ...BASE, 'Harbor Ideas/Island.md': 'An island.\n', 'Drafts/New World/Ana.md': 'Ana.\n',
'Book One/Places/Dock.md': 'See [[Island]].\n', 'Book One/Places/Pier.md': 'Like [[Ana]].\n' });
const result = await readLibrary({ repo: r.repo, commit: r.commit, mapping: levels() });
const codes = path => result.problems.filter(p => p.path === path).map(p => p.code).sort();
const file = path => result.files.find(f => f.path === path);
assert.deepEqual(codes('Book One/Places/Dock.md'), ['R5']);
// Any playground gives R5. A draft is never a source, so it gives R6 as well.
assert.deepEqual(codes('Book One/Places/Pier.md'), ['R5', 'R6']);
assert.deepEqual(file('Book One/Places/Pier.md').links.map(l => l.path), ['Drafts/New World/Ana.md']);
for (const [path, universe] of [['Harbor Ideas/Island.md', 'harbor'], ['Drafts/New World/Ana.md', 'idea']]) {
assert.deepEqual([file(path).scope, file(path).universe, file(path).book], ['playground', universe, null], path);
assert.deepEqual(codes(path), [], path);
}
});
// Supporting prefixes at three levels (C2-01d). Harbor's book-level prefix sits in both lists, and a
// second book-level prefix is supporting only.
const supporting = () => mapping(e => {
e.universes.harbor.playground = ['Book One/Playground/', 'Book One/Sketches/'];
e.universes.harbor.supporting = ['Book One/Playground/', 'Book One/Notes/', 'Harbor Notes/'];
e.universes.idea = { kind: 'draft', name: 'New World', playground: ['Drafts/New World/'], supporting: ['Drafts/New World Notes/'] };
return e;
});
test('C2-01d: each supporting level gives its universe, and its book or null', () => {
const m = supporting();
assert.deepEqual(classify(m, 'Book One/Notes/Characters/Mara.md'),
{ scope: 'supporting', universe: 'harbor', book: 'Book One', type: 'character', folder: 'Characters' });
assert.deepEqual(classify(m, 'Harbor Notes/Places/Island.md'),
{ scope: 'supporting', universe: 'harbor', book: null, type: 'place', folder: 'Places' });
assert.deepEqual(classify(m, 'Harbor Notes/Loose.md'), { scope: 'supporting', universe: 'harbor', book: null, type: null, folder: null });
assert.deepEqual(classify(m, 'Drafts/New World Notes/Chapters/Open.md'),
{ scope: 'supporting', universe: 'idea', book: null, type: 'manuscript', folder: 'Chapters' });
assert.deepEqual(classify(m, 'Drafts/New World/Ana.md'), { scope: 'playground', universe: 'idea', book: null, type: null, folder: null });
assert.deepEqual(classify(m, 'Book One/Places/Dock.md'), { scope: 'canon', universe: 'harbor', book: 'Book One', type: 'place', folder: 'Places' });
});
test('C2-01d: supporting comes before playground; a folder in both lists is supporting, one in the playground only stays playground', () => {
const m = supporting();
assert.deepEqual(classify(m, 'Book One/Playground/What If.md'),
{ scope: 'supporting', universe: 'harbor', book: 'Book One', type: null, folder: null });
assert.deepEqual(classify(m, 'Book One/Sketches/Research/Tides.md'),
{ scope: 'playground', universe: 'harbor', book: 'Book One', type: 'research', folder: 'Research' });
// A playground may hold a supporting prefix of its own entry: the inner folder is supporting.
const nested = mapping(e => { e.universes.harbor.supporting = ['Book One/Playground/Notes/']; return e; });
assert.equal(classify(nested, 'Book One/Playground/Notes/A.md').scope, 'supporting');
assert.equal(classify(nested, 'Book One/Playground/A.md').scope, 'playground');
});
test('C2-01d: only .md files are supporting; a .canvas or .base under a supporting prefix is unmapped', () => {
const m = supporting();
for (const path of ['Book One/Notes/Board.canvas', 'Harbor Notes/Table.base', 'Drafts/New World Notes/Map.canvas',
'Harbor Notes/cover.png', 'Harbor Notesx/a.md'])
assert.deepEqual(classify(m, path), { scope: 'unmapped' }, path);
});