Skip to content

Commit

Permalink
Merge pull request #91 from rtablada/rt/order-meta-debug
Browse files Browse the repository at this point in the history
Throw Errors When Meta Order Does Not Match Available Pages
  • Loading branch information
NullVoxPopuli committed Jul 11, 2024
2 parents f349bf4 + fc0a859 commit fb86317
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 34 deletions.
2 changes: 1 addition & 1 deletion docs-app/public/docs/meta.jsonc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
// We want usage to be first, which breaks the
// default sort order provided by the filesystem: Alphabetical
"order": ["usage", "components", "plugins"],
"order": ["usage", "plugins"],
}
2 changes: 1 addition & 1 deletion docs-app/public/docs/usage/meta.jsonc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
// This is in order of need-to-know
"order": ["setup", "rendering-pages", "ordering-pages"],
"order": ["setup", "rendering-pages", "ordering-pages", "testing"],
}
Empty file added fixtures/discover/c/index.md
Empty file.
2 changes: 1 addition & 1 deletion fixtures/discover/c/meta.jsonc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"order": ["c-b", "c-a"],
"order": ["c-b", "c-a", "d", "e"],
}
2 changes: 1 addition & 1 deletion fixtures/discover/meta.jsonc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"order": ["b", "a"],
"order": ["c"],
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
"build:declarations": "tsc --declaration",
"_syncPnpm": "pnpm sync-dependencies-meta-injected",
"start:typedoc": "typedoc --options ./typedoc.config.json --watch",
"test:node": "vitest --run"
"test:node": "vitest --run",
"test:dev": "vitest dev"
},
"peerDependencies": {
"@ember/test-waiters": "^3.1.0",
Expand Down
10 changes: 8 additions & 2 deletions src/plugins/markdown-pages/discover.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ describe('discover', () => {

expect(result.groups[0]?.tree).toMatchInlineSnapshot(`
{
"first": "/c/c-b.md",
"first": "/c/index.md",
"name": "root",
"pages": [
{
"first": "/c/c-b.md",
"first": "/c/index.md",
"name": "c",
"pages": [
{
"cleanedName": "index",
"groupName": "c",
"name": "index",
"path": "/c/index.md",
},
{
"cleanedName": "c b",
"groupName": "c",
Expand Down
43 changes: 29 additions & 14 deletions src/plugins/markdown-pages/sort.applyPredestinedOrder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { applyPredestinedOrder } from './sort.js';

describe('applyPredestinedOrder', () => {
test('it works', () => {
expect(applyPredestinedOrder(['c', 'b', 'a'], ['a', 'c'])).deep.equal(['a', 'c', 'b']);
expect(applyPredestinedOrder(['c', 'b', 'a'], ['a', 'c', 'b'])).deep.equal(['a', 'c', 'b']);
});

test('it works with objects', () => {
expect(
applyPredestinedOrder(
[{ name: 'c' }, { name: 'b' }, { name: 'a' }],
['a', 'c'],
['a', 'c', 'b'],
(item) => item.name
)
).deep.equal([{ name: 'a' }, { name: 'c' }, { name: 'b' }]);
Expand All @@ -21,19 +21,34 @@ describe('applyPredestinedOrder', () => {
expect(applyPredestinedOrder(['c', 'a'], ['a', 'c'])).deep.equal(['a', 'c']);
});

test('it works when the order specifies things that do not exist', () => {
expect(applyPredestinedOrder(['c', 'b', 'a'], ['a', 'c', 'x', 'y', 'z'])).deep.equal([
'a',
'c',
'b',
]);
test('it handles index pages as always first', () => {
expect(applyPredestinedOrder(['c', 'a', 'index'], ['a', 'c'])).deep.equal(['index', 'a', 'c']);
});

test('it works when the order specifies duplicates', () => {
expect(applyPredestinedOrder(['c', 'b', 'a'], ['a', 'c', 'a', 'c'])).deep.equal([
'a',
'c',
'b',
]);
test('it errors when the order specifies things that do not exist', () => {
expect(() => applyPredestinedOrder(['c', 'b', 'a'], ['a', 'c', 'x'])).toThrow(
'Order configuration specified "x" but it was not found in the list. Pages are ["c","b","a"]'
);
});

test('it errors when order is a different length than list', () => {
expect(() => applyPredestinedOrder(['c', 'b', 'a', 'd'], ['a', 'c', 'b']))
.toThrow(`Order configuration specified different number of arguments than available pages:
Order: ["a","c","b"]
Actual: ["c","b","a","d"]`);
});

test('it errors if duplicate pages are specified', () => {
expect(() => applyPredestinedOrder(['c', 'b', 'a'], ['a', 'c', 'a', 'c']))
.toThrow(`Order configuration specified duplicate pages:
Unique: ["a","c"]
Order: ["a","c","a","c"]
Actual: ["c","b","a"]`);
});

test('it errors if a configuration order option is empty', () => {
expect(() => applyPredestinedOrder(['c', 'b', 'a'], ['a', '', 'd'])).toThrow(
`Order configuration found an empty string at index 1`
);
});
});
62 changes: 53 additions & 9 deletions src/plugins/markdown-pages/sort.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
/**
* @param {unknown[]} arr
* @returns {unknown[]}
*/
function uniq(arr) {
return Array.from(new Set(arr));
}

/**
* @param {string} path
* @returns {string}
*/
function findPathForJsonc(path) {
return path.replace(/\/meta\.jsonc?$/, '');
}

/**
* Tutorials (and groups) are all 123-name
* This is so that we can sort them manually on the file system.
Expand Down Expand Up @@ -49,21 +65,39 @@ export function betterSort(property) {
* @param {Item[]} list
* @param {string[]} order
* @param {(item: Item) => any} [ find ]
* @throws {Error}
* @returns {Item[]}
*/
export function applyPredestinedOrder(list, order, find = (x) => x) {
let result = [];
let indexPage = list.find((x) => find(x) === 'index');
let result = indexPage ? [indexPage] : [];

list = list.filter((a) => a !== indexPage);

let remaining = [...list];

let remaining = list;
if (uniq(order).length !== order.length)
throw new Error(`Order configuration specified duplicate pages:
Unique: ${JSON.stringify(uniq(order))}
Order: ${JSON.stringify(order)}
Actual: ${JSON.stringify(list.map(find))}`);

for (let i = 0; i < Math.max(list.length, order.length); i++) {
if (order.length !== list.length)
throw new Error(`Order configuration specified different number of arguments than available pages:
Order: ${JSON.stringify(order)}
Actual: ${JSON.stringify(list.map(find))}`);

for (let i = 0; i < order.length; i++) {
let current = order[i];

if (!current) break;
if (!current) throw new Error(`Order configuration found an empty string at index ${i}`);

let foundIndex = remaining.findIndex((x) => find(x) === current);

if (foundIndex < 0) continue;
if (foundIndex < 0)
throw new Error(
`Order configuration specified "${current}" but it was not found in the list. Pages are ${JSON.stringify(list.map(find))}`
);

// remove
let [found] = remaining.splice(foundIndex, 1);
Expand All @@ -73,7 +107,11 @@ export function applyPredestinedOrder(list, order, find = (x) => x) {
result.push(found);
}

result.push(...remaining);
if (remaining.length > 0) {
throw new Error(
`Order configuration did not specify all pages. Remaining pages are ${JSON.stringify(remaining.map(find))}`
);
}

return result;
}
Expand All @@ -93,16 +131,22 @@ export function sortTree(tree, configs, parents = []) {

if (configs.length > 0) {
let subPath = `${[...parents, tree.name].join('/')}`;
let config = configs.filter(Boolean).find((config) => config.path.startsWith(subPath))?.config;
let config = configs
.filter(Boolean)
.find((config) => findPathForJsonc(config.path) === subPath)?.config;

if (!config?.order) {
return tree;
}

// Should the name always avoid the extension?
let replacementPages = applyPredestinedOrder(tree.pages, config.order, (page) => page.name);
try {
let replacementPages = applyPredestinedOrder(tree.pages, config.order, (page) => page.name);

tree.pages = replacementPages;
tree.pages = replacementPages;
} catch (error) {
throw new Error(`Error while sorting tree at ${subPath}.\n${error}`);
}
}

return tree;
Expand Down
8 changes: 4 additions & 4 deletions src/plugins/markdown-pages/sort.sortTree.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,20 @@ describe('sortTree', () => {
name: 'top',
pages: [
{
name: 'second',
name: 'child',
pages: [
{
path: '/top/second/second',
path: '/top/child/second',
name: 'second',
groupName: 'top',
cleanedName: 'second',
},
{ name: 'first', path: '/top/second/first', groupName: 'top', cleanedName: 'first' },
{ name: 'first', path: '/top/child/first', groupName: 'top', cleanedName: 'first' },
],
},
],
},
[{ path: 'top/second/meta.jsonc', config: { order: ['first', 'second'] } }]
[{ path: 'top/child/meta.jsonc', config: { order: ['first', 'second'] } }]
);

expect(result.pages.length).toEqual(1);
Expand Down

0 comments on commit fb86317

Please sign in to comment.