Skip to content

Commit

Permalink
feat(prettier-plugin-jsdoc): add function to sort tags
Browse files Browse the repository at this point in the history
  • Loading branch information
homer0 committed Oct 6, 2020
1 parent 7828864 commit 3d26343
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/fns/sortTags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const R = require('ramda');
const { getIndexOrFallback } = require('./utils');
/**
* @typedef {import('../types').CommentTag} CommentTag
* @typedef {import('../types').PJPTagsOptions} PJPTagsOptions
*/

/**
* Creates the function used by `Array.sort` to actually sort the tags based on a reference list.
*
* @param {string[]} ref The reference list with the order for the tags.
* @returns {Function}
*/
const createSorter = (ref) => {
const fallback = getIndexOrFallback(ref, ref.length, 'other');
const getTagWeight = getIndexOrFallback(ref, fallback);
return (a, b) => getTagWeight(a.tag) - getTagWeight(b.tag);
};

/**
* Sorts a list of tags based on reference list from the plugin options.
*
* @param {CommentTag[]} tags The list of tags to sort.
* @param {PJPTagsOptions} options The options that tell the function how to sort them.
* @returns {CommentTag[]}
*/
const sortTags = R.curry((tags, options) => R.sort(createSorter(options.jsdocTagsOrder))(tags));

module.exports.sortTags = sortTags;
22 changes: 22 additions & 0 deletions src/fns/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,27 @@ const capitalize = R.compose(
R.juxt([R.compose(R.toUpper, R.head), R.tail]),
);

/**
* Gets the item of an item of a list or a fallback value.
*
* @callback GetIndexOrFallbackFn
* @param {Array} list The list where the function will look for the item.
* @param {number} fallback The fallback index in case one is not found for the item.
* @param {*} item The item to look for.
* @returns {number}
*/

/**
* @type {GetIndexOrFallbackFn}
*/
const getIndexOrFallback = R.curry((list, fallback, item) => R.compose(
R.when(
R.equals(-1),
R.always(fallback),
),
R.indexOf(item),
)(list));

module.exports.ensureArray = ensureArray;
module.exports.findTagIndex = findTagIndex;
module.exports.appendIfNotPresent = appendIfNotPresent;
Expand All @@ -172,3 +193,4 @@ module.exports.hasItems = hasItems;
module.exports.isMatch = isMatch;
module.exports.replaceDotOnTypeGeneric = replaceDotOnTypeGeneric;
module.exports.capitalize = capitalize;
module.exports.getIndexOrFallback = getIndexOrFallback;
73 changes: 73 additions & 0 deletions test/fns/sortTags.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
jest.unmock('../../src/fns/sortTags');
jest.unmock('../../src/fns/utils');

const { sortTags } = require('../../src/fns/sortTags');

describe('sortTags', () => {
const cases = [
{
it: 'should sort the tags and correctly use \'other\' as fallback',
input: [
{ tag: 'param' },
{ tag: 'description' },
{ tag: 'param' },
{ tag: 'returns' },
{ tag: 'todo' },
{ tag: 'throws' },
],
output: [
{ tag: 'description' },
{ tag: 'param' },
{ tag: 'param' },
{ tag: 'returns' },
{ tag: 'throws' },
{ tag: 'todo' },
],
options: {
jsdocTagsOrder: [
'description',
'param',
'returns',
'other',
'todo',
],
},
},
{
it: 'should send the tag to the end of the list of \'other\' is not present',
input: [
{ tag: 'throws' },
{ tag: 'param' },
{ tag: 'description' },
{ tag: 'param' },
{ tag: 'returns' },
{ tag: 'todo' },
],
output: [
{ tag: 'description' },
{ tag: 'param' },
{ tag: 'param' },
{ tag: 'returns' },
{ tag: 'todo' },
{ tag: 'throws' },
],
options: {
jsdocTagsOrder: [
'description',
'param',
'returns',
'todo',
],
},
},
];

it.each(cases)('should correctly format the case %#', (caseInfo) => {
// Given
let result = null;
// When
result = sortTags(caseInfo.input, caseInfo.options);
// Then
expect(result).toEqual(caseInfo.output);
});
});

0 comments on commit 3d26343

Please sign in to comment.