From dffc814aa680aea1ccb019d3c608022ece885260 Mon Sep 17 00:00:00 2001 From: Denys Otrishko Date: Mon, 14 Sep 2020 14:50:08 +0300 Subject: [PATCH] fix: prioritizedEntries class sort order Fixes: https://github.com/metarhia/metadoc/issues/104 PR-URL: https://github.com/metarhia/metadoc/pull/105 --- lib/generator.js | 69 ++++++++++++++++++++++---------------------- test/example.js | 22 ++++++++++++++ test/example.md | 31 ++++++++++++++++++++ test/testConfig.json | 4 +++ 4 files changed, 92 insertions(+), 34 deletions(-) diff --git a/lib/generator.js b/lib/generator.js index 87131c3..d2a903d 100644 --- a/lib/generator.js +++ b/lib/generator.js @@ -4,6 +4,8 @@ const common = require('@metarhia/common'); const types = require('./types'); +const { iter } = common; + const ALL_TYPES = new Set(types.STANDARD_TYPES); const MAX_LINE_LENGTH = 80; @@ -41,14 +43,12 @@ const links = [ ]; const getLinks = (usedTypes, customLinks) => - common - .iter( - common - .iter(links) - .chain(customLinks) - .filter(([type]) => usedTypes.has(type)) - .collectTo(Map) - ) + iter( + iter(links) + .chain(customLinks) + .filter(([type]) => usedTypes.has(type)) + .collectTo(Map) + ) .map(([type, link]) => '[' + type.toLowerCase() + ']: ' + link) .collectTo(Set); @@ -465,34 +465,35 @@ const generateContentsTable = (buf, levelLimit = 0) => { }; const sortMethods = (methods, prioritizedEntries) => { - const result = []; - const other = []; - for (const [method, sig] of methods) { - for (const entry of prioritizedEntries) { - if ( - method === entry || - (method.startsWith(entry) && method.slice(entry.length).startsWith('.')) - ) { - result.push([method, sig]); - } + const sortFn = ([a], [b]) => { + if (a === b) return 0; + let aIdx = prioritizedEntries.indexOf(a); + let bIdx = prioritizedEntries.indexOf(b); + if (aIdx === -1) aIdx = Infinity; + if (bIdx === -1) bIdx = Infinity; + if (aIdx < bIdx) return -1; + if (aIdx > bIdx) return 1; + if (a < b) return -1; + if (a > b) return 1; + return 0; + }; + const other = Symbol('other'); + const grouped = iter(methods).groupBy( + ([m]) => + prioritizedEntries.find(e => m === e || m.startsWith(e + '.')) || other + ); + let result = iter([]); + for (const p of prioritizedEntries) { + const entries = grouped.get(p); + if (entries) { + const [other, sorted] = iter(entries).partition( + ([m]) => !!prioritizedEntries.find(e => m === e) + ); + result = result.chain(sorted.sort(sortFn)).chain(other); } - other.push([method, sig]); } - result - .sort(([a], [b]) => { - if (a === b) return 0; - let aIdx = prioritizedEntries.indexOf(a); - let bIdx = prioritizedEntries.indexOf(b); - if (aIdx === -1) aIdx = Infinity; - if (bIdx === -1) bIdx = Infinity; - if (aIdx < bIdx) return -1; - if (aIdx > bIdx) return 1; - if (a < b) return -1; - if (a > b) return 1; - return 0; - }) - .push(...other); - return new Map(result); + result = result.chain(grouped.get(other)); + return result.collectTo(Map); }; // Generate md from interfaces inventory diff --git a/test/example.js b/test/example.js index ca10aa6..9fec409 100644 --- a/test/example.js +++ b/test/example.js @@ -273,6 +273,26 @@ class UndocumentedClass extends AnotherClass { } } +// Order1Class should be ordered correctly. +class Order1Class { + constructor(abc) {} + + order1Method() {} + + order2Method() {} + + order3Method() {} +} + +// Order2Class should be ordered correctly. +class Order2Class { + constructor(abc) {} + + aMethod() {} + + order2Method() {} +} + // PrototypeClass description description // Note that classes on prototypes will not have constructors and will be // treated as a regular . @@ -412,4 +432,6 @@ module.exports = { nullObject: null, nullObjectCreate: Object.create(null), + Order1Class, + Order2Class, }; diff --git a/test/example.md b/test/example.md index ff16fb3..c3d84e0 100644 --- a/test/example.md +++ b/test/example.md @@ -1,4 +1,13 @@ - [Interface example](#interface-example) + - [Order2Class](#class-order2class) + - [Order2Class.prototype.constructor](#order2classprototypeconstructorabc) + - [Order2Class.prototype.aMethod](#order2classprototypeamethod) + - [Order2Class.prototype.order2Method](#order2classprototypeorder2method) + - [Order1Class](#class-order1class) + - [Order1Class.prototype.order2Method](#order1classprototypeorder2method) + - [Order1Class.prototype.order1Method](#order1classprototypeorder1method) + - [Order1Class.prototype.constructor](#order1classprototypeconstructorabc) + - [Order1Class.prototype.order3Method](#order1classprototypeorder3method) - [methodName](#methodnamenum-str-arg-flag-arr-data-obj-cb) - [noTitleFunction](#notitlefunctionstr-num) - [typeFunction](#typefunctionobj-arg1-arg2-arg3) @@ -37,6 +46,28 @@ # Interface: example +## class Order2Class + +Order2Class should be ordered correctly. + +### Order2Class.prototype.constructor(abc) + +### Order2Class.prototype.aMethod() + +### Order2Class.prototype.order2Method() + +## class Order1Class + +Order1Class should be ordered correctly. + +### Order1Class.prototype.order2Method() + +### Order1Class.prototype.order1Method() + +### Order1Class.prototype.constructor(abc) + +### Order1Class.prototype.order3Method() + ## methodName(num, str, arg, flag\[, arr\[, data\]\], obj, cb) - `num`: [``][number] argument description diff --git a/test/testConfig.json b/test/testConfig.json index f914eaf..ac2c89e 100644 --- a/test/testConfig.json +++ b/test/testConfig.json @@ -9,6 +9,10 @@ "ExampleClass#getProp1": "#prototypeclassprototypegetprop1" }, "prioritizedEntries": [ + "Order2Class", + "Order1Class", + "Order1Class.prototype.order2Method", + "Order1Class.prototype.order1Method", "methodName", "noTitleFunction", "typeFunction",