🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
DemoInstallSign in
Socket

@homer0/prettier-plugin-jsdoc

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@homer0/prettier-plugin-jsdoc - npm Package Compare versions

Comparing version

to
7.0.0

tests/e2e/fixtures/shebang.fixture.js

13

CHANGELOG.md

@@ -6,2 +6,15 @@ # Change Log

# [7.0.0](https://github.com/homer0/packages/compare/@homer0/prettier-plugin-jsdoc@6.0.5...@homer0/prettier-plugin-jsdoc@7.0.0) (2023-07-16)
### Bug Fixes
- **monorepo:** update all dependencies ([c3d837e](https://github.com/homer0/packages/commit/c3d837e5820d27a27e97322211478d880000c064))
- **prettier-config:** hardcode languages ([f5ea277](https://github.com/homer0/packages/commit/f5ea27794d1559c2770e35a48b4a65dc57351545))
- **prettier-plugin-jsdoc:** add support for Prettier v3 ([a64de80](https://github.com/homer0/packages/commit/a64de8086f7ec00ca69107de58149abb140cbdc3))
- **prettier-plugin-jsdoc:** update Prettier version ([23128e5](https://github.com/homer0/packages/commit/23128e5f27af899c85538c77fc6050f777b6fff9))
### BREAKING CHANGES
- **prettier-plugin-jsdoc:** This plugin now uses Prettier v3
## [6.0.5](https://github.com/homer0/packages/compare/@homer0/prettier-plugin-jsdoc@6.0.4...@homer0/prettier-plugin-jsdoc@6.0.5) (2023-06-18)

@@ -8,0 +21,0 @@

17

package.json
{
"name": "@homer0/prettier-plugin-jsdoc",
"description": "A Prettier plugin to format JSDoc blocks.",
"version": "6.0.5",
"version": "7.0.0",
"repository": {

@@ -22,11 +22,12 @@ "type": "git",

},
"type": "commonjs",
"dependencies": {
"comment-parser": "^1.3.1",
"prettier": "^2.8.8",
"prettier": "^3.0.0",
"ramda": "0.29.0"
},
"devDependencies": {
"@homer0/eslint-plugin": "10.3.1",
"jest": "^29.5.0",
"jest-environment-node": "^29.5.0"
"@homer0/eslint-plugin": "10.3.2",
"jest": "^29.6.1",
"jest-environment-node": "^29.6.1"
},

@@ -40,7 +41,7 @@ "engine-strict": true,

"lint": "eslint .",
"test:unit": "jest -c ./.jestrc-unit.js",
"test:e2e": "jest -c ./.jestrc-e2e.js",
"test:unit": "NODE_OPTIONS=--experimental-vm-modules jest -c ./.jestrc-unit.js",
"test:e2e": "NODE_OPTIONS=--experimental-vm-modules jest -c ./.jestrc-e2e.js",
"test": "pnpm run test:unit && pnpm run test:e2e"
},
"gitHead": "05356cf2f7d8f158a139c3e2a3fed025f60bbaad"
"gitHead": "bab3ed6af9cf27c0d64e4169dc1f4825a978a717"
}
const { provider } = require('./app');
/**
* @typedef {import('../types').PrettierSupportLanguage} PrettierSupportLanguage
*/
/**
* Gets a dictionary where the keys are old tags' names, and values the current tag name

@@ -84,5 +88,150 @@ * for which they are synonym.

*
* @returns {string[]}
* @returns {PrettierSupportLanguage[]}
*/
const getSupportedLanguages = () => ['JavaScript', 'Flow', 'JSX', 'TSX', 'TypeScript'];
const getSupportedLanguages = () => [
{
linguistLanguageId: 183,
name: 'JavaScript',
type: 'programming',
tmScope: 'source.js',
aceMode: 'javascript',
codemirrorMode: 'javascript',
codemirrorMimeType: 'text/javascript',
color: '#f1e05a',
aliases: ['js', 'node'],
extensions: [
'.js',
'._js',
'.bones',
'.cjs',
'.es',
'.es6',
'.frag',
'.gs',
'.jake',
'.javascript',
'.jsb',
'.jscad',
'.jsfl',
'.jslib',
'.jsm',
'.jspre',
'.jss',
'.mjs',
'.njs',
'.pac',
'.sjs',
'.ssjs',
'.xsjs',
'.xsjslib',
'.wxs',
],
filenames: ['Jakefile'],
interpreters: [
'chakra',
'd8',
'gjs',
'js',
'node',
'nodejs',
'qjs',
'rhino',
'v8',
'v8-shell',
'zx',
],
parsers: [
'babel',
'acorn',
'espree',
'meriyah',
'babel-flow',
'babel-ts',
'flow',
'typescript',
],
vscodeLanguageIds: ['javascript', 'mongo'],
},
{
linguistLanguageId: 183,
name: 'Flow',
type: 'programming',
tmScope: 'source.js',
aceMode: 'javascript',
codemirrorMode: 'javascript',
codemirrorMimeType: 'text/javascript',
color: '#f1e05a',
aliases: [],
extensions: ['.js.flow'],
filenames: [],
interpreters: [
'chakra',
'd8',
'gjs',
'js',
'node',
'nodejs',
'qjs',
'rhino',
'v8',
'v8-shell',
],
parsers: ['flow', 'babel-flow'],
vscodeLanguageIds: ['javascript'],
},
{
linguistLanguageId: 183,
name: 'JSX',
type: 'programming',
tmScope: 'source.js.jsx',
aceMode: 'javascript',
codemirrorMode: 'jsx',
codemirrorMimeType: 'text/jsx',
color: undefined,
aliases: undefined,
extensions: ['.jsx'],
filenames: undefined,
interpreters: undefined,
parsers: [
'babel',
'babel-flow',
'babel-ts',
'flow',
'typescript',
'espree',
'meriyah',
],
vscodeLanguageIds: ['javascriptreact'],
group: 'JavaScript',
},
{
linguistLanguageId: 378,
name: 'TypeScript',
type: 'programming',
color: '#3178c6',
aliases: ['ts'],
interpreters: ['deno', 'ts-node'],
extensions: ['.ts', '.cts', '.mts'],
tmScope: 'source.ts',
aceMode: 'typescript',
codemirrorMode: 'javascript',
codemirrorMimeType: 'application/typescript',
parsers: ['typescript', 'babel-ts'],
vscodeLanguageIds: ['typescript'],
},
{
linguistLanguageId: 94901924,
name: 'TSX',
type: 'programming',
color: '#3178c6',
group: 'TypeScript',
extensions: ['.tsx'],
tmScope: 'source.tsx',
aceMode: 'javascript',
codemirrorMode: 'jsx',
codemirrorMimeType: 'text/jsx',
parsers: ['typescript', 'babel-ts'],
vscodeLanguageIds: ['typescriptreact'],
},
];

@@ -89,0 +238,0 @@ module.exports.getTagsSynonyms = getTagsSynonyms;

const R = require('ramda');
const { hasValidProperty } = require('./utils');
const { hasValidProperty, composeWithPromise } = require('./utils');
const { formatTSTypes } = require('./formatTSTypes');

@@ -9,2 +9,3 @@ const { formatStringLiterals } = require('./formatStringLiterals');

const { get, provider } = require('./app');
const { reduceWithPromise } = require('./utils');

@@ -32,3 +33,3 @@ /**

* @param {number} column The column where the comment will be rendered.
* @returns {TypeFormatter}
* @returns {Promise<TypeFormatter>}
*/

@@ -56,3 +57,3 @@ const getTypeFormatter = (options, column) => {

return fns.length ? R.compose(...fns.reverse()) : R.identity;
return fns.length ? get(composeWithPromise)(...fns.reverse()) : R.identity;
};

@@ -67,3 +68,3 @@

* @param {CommentTag} tag The tag which type will be formatted.
* @returns {CommentTag}
* @returns {Promise<CommentTag>}
*/

@@ -75,3 +76,3 @@

const formatTagType = R.curry((formatter, tag) =>
R.compose((type) => ({ ...tag, type }), formatter, R.prop('type'))(tag),
get(composeWithPromise)((type) => ({ ...tag, type }), formatter, R.prop('type'))(tag),
);

@@ -88,3 +89,3 @@

* involve Prettier itself.
* @returns {CommentTag[]}
* @returns {Promise<CommentTag[]>}
*/

@@ -95,11 +96,15 @@

*/
const formatTagsTypes = R.curry((tags, options, column) =>
R.map(
R.when(
get(hasValidProperty)('type'),
get(formatTagType)(get(getTypeFormatter)(options, column)),
),
)(tags),
);
const formatTagsTypes = R.curry(async (tags, options, column) => {
const hasValidPropertyFn = get(hasValidProperty)('type');
const getTypeFormatterFn = get(getTypeFormatter)(options, column);
const formatTagTypeFn = get(formatTagType)(getTypeFormatterFn);
return get(reduceWithPromise)(tags, async (tag) => {
if (hasValidPropertyFn(tag)) {
return formatTagTypeFn(tag);
}
return tag;
});
});
module.exports.formatTagsTypes = formatTagsTypes;

@@ -106,0 +111,0 @@ module.exports.getTypeFormatter = getTypeFormatter;

@@ -26,3 +26,3 @@ const { format } = require('prettier');

* @param {string} tag The type will be formatted.
* @returns {string}
* @returns {Promise<string>}
*/

@@ -33,3 +33,3 @@

*/
const formatPrettyType = R.curry((options, column, type) => {
const formatPrettyType = R.curry(async (options, column, type) => {
let result;

@@ -40,11 +40,8 @@ try {

const prefix = 'type complex = ';
const newType = format(`${prefix}${useType}`, {
const newType = await format(`${prefix}${useType}`, {
...options,
printWidth,
parser: 'typescript',
})
.substr(prefix.length)
.trim()
.replace(/;$/, '');
result = newType;
});
result = newType.substring(prefix.length).trim().replace(/;$/, '');
} catch (ignore) {

@@ -68,3 +65,3 @@ result = type;

* that Prettier can use.
* @returns {CommentTag}
* @returns {Promise<CommentTag>}
*/

@@ -71,0 +68,0 @@

@@ -0,7 +1,7 @@

const babelParser = require('prettier/plugins/babel');
const flowParser = require('prettier/plugins/flow');
const tsParser = require('prettier/plugins/typescript');
const R = require('ramda');
const { parse: commentParser } = require('comment-parser');
const babelParser = require('prettier/parser-babel');
const flowParser = require('prettier/parser-flow');
const tsParser = require('prettier/parser-typescript');
const { isMatch } = require('./utils');
const { isMatch, composeWithPromise, reduceWithPromise } = require('./utils');
const { formatDescription } = require('./formatDescription');

@@ -169,15 +169,18 @@ const { formatTags } = require('./formatTags');

*/
const processComments = R.curry((options, nodes, formatterFn, processorFn) =>
R.compose(
R.forEach(
R.compose(
R.ifElse(shouldIgnoreComment(options), R.identity, processorFn),
formatterFn,
get(generateCommentData),
),
),
R.filter(R.allPass([get(isComment), get(matchesBlock)])),
)(nodes),
);
const processComments = R.curry(async (options, nodes, formatterFn, processorFn) => {
const useNodes = nodes.filter(R.allPass([get(isComment), get(matchesBlock)]));
const shouldIgnoreFn = shouldIgnoreComment(options);
const generateCommentDataFn = get(generateCommentData);
return get(reduceWithPromise)(useNodes, async (node) => {
const info = generateCommentDataFn(node);
const formatted = await formatterFn(info);
const shouldIgnore = await shouldIgnoreFn(formatted);
if (shouldIgnore) {
return formatted;
}
return processorFn(formatted);
});
});
/**

@@ -211,3 +214,3 @@ * Runs all the formatting functions that require the context of a comment block, not only

* @param {ParsingInformation} info The parsed information of the comment.
* @returns {ParsingInformation}
* @returns {Promise<ParsingInformation>}
*/

@@ -219,3 +222,3 @@

const formatCommentTags = R.curry((options, info) =>
R.compose(
get(composeWithPromise)(
R.assocPath(['block', 'tags'], R.__, info),

@@ -244,3 +247,3 @@ get(formatTagsTypes)(R.__, options, info.column),

const prepareCommentTags = R.curry((options, info) =>
R.compose(
get(composeWithPromise)(
R.assocPath(['block', 'tags'], R.__, info),

@@ -292,25 +295,28 @@ get(prepareTags)(R.__, options, info.column),

*/
const createParser = (originalParser, checkExtendOption) => (text, parsers, options) => {
const ast = originalParser(text, parsers, options);
if (
options &&
options.jsdocPluginEnabled &&
(!checkExtendOption || !options.jsdocPluginExtended)
) {
const formatter = R.compose(
get(prepareCommentTags)(options),
get(formatCommentTags)(options),
get(formatCommentBlock)(options),
);
const renderer = getRenderer(options);
if (ast.comments && ast.comments.length) {
get(processComments)(options, ast.comments, formatter, (info) => {
const { comment, column, block } = info;
comment.value = renderer(column, block);
});
const createParser =
(originalParser, checkExtendOption) => async (text, parsers, options) => {
const ast = originalParser(text, parsers, options);
if (
options &&
options.jsdocPluginEnabled &&
(!checkExtendOption || !options.jsdocPluginExtended)
) {
const formatter = get(composeWithPromise)(
get(prepareCommentTags)(options),
get(formatCommentTags)(options),
get(formatCommentBlock)(options),
);
const renderer = getRenderer(options);
if (ast.comments && ast.comments.length) {
await get(processComments)(options, ast.comments, formatter, (info) => {
const { comment, column, block } = info;
const value = renderer(column, block);
comment.value = value;
return info;
});
}
}
}
return ast;
};
return ast;
};

@@ -350,14 +356,17 @@ /**

},
get typescript() {
return useExtendParser(tsParser.parsers.typescript);
},
/* istanbul ignore next */
get 'babel-flow'() {
return useExtendParser(babelParser.parsers['babel-flow']);
},
/* istanbul ignore next */
get 'babel-ts'() {
return useExtendParser(babelParser.parsers['babel-ts']);
},
/* istanbul ignore next */
get flow() {
return useExtendParser(flowParser.parsers.flow);
},
get typescript() {
return useExtendParser(tsParser.parsers.typescript);
},
};

@@ -364,0 +373,0 @@ };

@@ -1,2 +0,2 @@

const { getLanguages } = require('./getLanguages');
const { getSupportedLanguages } = require('./constants');
const { getParsers } = require('./getParsers');

@@ -35,3 +35,3 @@ const { getOptions, getDefaultOptions } = require('./getOptions');

const getPlugin = (checkExtendOption) => ({
languages: get(getLanguages)(),
languages: get(getSupportedLanguages)(),
options: get(getOptions)(),

@@ -38,0 +38,0 @@ defaultOptions: get(getDefaultOptions)(),

const { format } = require('prettier');
const R = require('ramda');
const { isTag, prefixLines, splitLinesAndClean } = require('./utils');
const { isTag, prefixLines, splitLinesAndClean, reduceWithPromise } = require('./utils');
const { get, provider } = require('./app');

@@ -27,5 +27,5 @@

* @param {string} example The example code.
* @returns {string}
* @returns {Promise<string>}
*/
const formatExample = (options, column, example) => {
const formatExample = async (options, column, example) => {
let code;

@@ -40,3 +40,3 @@ let indent;

code = format(example, {
code = await format(example, {
...options,

@@ -65,18 +65,16 @@ printWidth,

* @param {string} example The example code.
* @returns {CommentTagExample[]}
* @returns {Promise<CommentTagExample[]>}
*/
const splitExamples = (options, column, example) => {
const useSplitLinesAndClean = get(splitLinesAndClean);
return R.compose(
R.map(
R.compose(
([caption, code]) => ({
caption,
code: get(formatExample)(options, column, code),
}),
useSplitLinesAndClean(/<\s*\/\s*caption\s*>/i),
),
),
useSplitLinesAndClean(/<\s*caption\s*>/i),
)(example);
const splitExamples = async (options, column, example) => {
const splitLinesAndCleanFn = get(splitLinesAndClean);
const splitEndFn = splitLinesAndCleanFn(/<\s*\/\s*caption\s*>/i);
const splitted = splitLinesAndCleanFn(/<\s*caption\s*>/i)(example);
const formatExampleFn = get(formatExample);
return get(reduceWithPromise)(splitted, async (item) => {
const [caption, code] = splitEndFn(item);
return {
caption,
code: await formatExampleFn(options, column, code),
};
});
};

@@ -99,8 +97,9 @@

*/
const formatExampleTag = R.curry((options, column, tag) => {
const formatExampleTag = R.curry(async (options, column, tag) => {
let examples;
if (tag.description.match(/<\s*caption\s*>/i)) {
examples = get(splitExamples)(options, column, tag.description);
examples = await get(splitExamples)(options, column, tag.description);
} else if (tag.description.trim()) {
examples = [{ code: get(formatExample)(options, column, tag.description) }];
const code = await get(formatExample)(options, column, tag.description);
examples = [{ code }];
} else {

@@ -107,0 +106,0 @@ examples = [];

@@ -6,2 +6,3 @@ const R = require('ramda');

const { get, provider } = require('./app');
const { composeWithPromise, reduceWithPromise } = require('./utils');

@@ -25,3 +26,3 @@ /**

* to call Prettier.
* @returns {CommentTag[]}
* @returns {Promise<CommentTag[]>}
*/

@@ -32,3 +33,3 @@

*/
const prepareTags = R.curry((tags, options, column) => {
const prepareTags = R.curry(async (tags, options, column) => {
const fns = [get(prepareTagName)];

@@ -44,3 +45,4 @@

return R.map(R.compose(...fns.reverse()), tags);
const pipeline = get(composeWithPromise)(...fns.reverse());
return get(reduceWithPromise)(tags, pipeline);
});

@@ -47,0 +49,0 @@

@@ -354,2 +354,49 @@ const R = require('ramda');

/**
* A version of Rambdas `compose` that can handle promises.
*
* @param {...*} args The list of functions to compose.
* @returns {*}
* @see https://gist.github.com/ehpc/2a524b78729ee6b4e8111f89c66d7ff5
*/
const composeWithPromise = (...args) =>
R.composeWith((f, val) => {
if (val && val.then) {
return val.then(f);
}
return f(val);
})(args);
/**
* @callback ReduceWithPromiseFn
* @param {TItem} item The item to process.
* @returns {Promise<TOutput>}
* @template TItem The type of the items on the list.
* @template TOutput The type of the item that will be returned.
*/
/**
* A utility function that will process a list of items and return a promise with the
* results.
* The idea of this function is to replace a `for` loop with `await` inside.
*
* @param {TItem[]} items The list of items to process.
* @param {ReduceWithPromiseFn<TItem, TOutput>} fn The function that will process each
* item.
* @returns {Promise<TOutput[]>}
* @template TItem The type of the items on the list.
* @template TOutput The type of the item that will be returned by the reducer.
*/
const reduceWithPromise = (items, fn) =>
items.reduce(
(accPromise, item) =>
accPromise.then(async (acc) => {
const result = await fn(item);
acc.push(result);
return acc;
}),
Promise.resolve([]),
);
module.exports.ensureArray = ensureArray;

@@ -373,2 +420,4 @@ module.exports.findTagIndex = findTagIndex;

module.exports.ensureSentence = ensureSentence;
module.exports.composeWithPromise = composeWithPromise;
module.exports.reduceWithPromise = reduceWithPromise;
module.exports.provider = provider('utils', module.exports);

@@ -18,3 +18,2 @@ const path = require('path');

'formatTypeAsCode',
'getLanguages',
'getOptions',

@@ -21,0 +20,0 @@ 'getParsers',

@@ -15,2 +15,9 @@ //# input

/**
* @type {Object} SomethingToIgnore
* @description transform this into a sentence
* @see {@link SomethingElse} to see how this is not broken, as the parser thinks the link is a type.
* @prettierignore
*/
/**
* @description logs something.

@@ -70,2 +77,9 @@ * @param {string} [name='batman'] the name

/**
* @type {Object} SomethingToIgnore
* @description transform this into a sentence
* @see {@link SomethingElse} to see how this is not broken, as the parser thinks the link is a type.
* @prettierignore
*/
/**
* Logs something.

@@ -72,0 +86,0 @@ *

@@ -14,13 +14,12 @@ const prettier = require('prettier');

const fixtures = global.e2eFixtures;
fixtures.forEach((fixture) => {
it(`should format fixture: ${fixture.name}`, () => {
const output = prettier
.format(fixture.input, {
plugins: [...(fixture.plugins || []), prettierPluginJSDoc],
...fixture.options,
})
.trim();
expect(output).toBe(fixture.output);
it(`should format fixture: ${fixture.name}`, async () => {
const output = await prettier.format(fixture.input, {
plugins: [...(fixture.plugins || []), prettierPluginJSDoc],
...fixture.options,
});
expect(output.trim()).toBe(fixture.output);
});
});
});

@@ -17,3 +17,3 @@ jest.unmock('../../../src/fns/formatTagsTypes');

it('should apply all the transformations', () => {
it('should apply all the transformations', async () => {
// Given

@@ -62,3 +62,3 @@ const input = [

// When
result = formatTagsTypes(input, options, 0);
result = await formatTagsTypes(input, options, 0);
// Then

@@ -88,3 +88,3 @@ expect(result).toEqual(output);

it('should only format objects', () => {
it('should only format objects', async () => {
// Given

@@ -132,3 +132,3 @@ const input = [

// When
result = formatTagsTypes(input, options, 2);
result = await formatTagsTypes(input, options, 2);
// Then

@@ -138,3 +138,3 @@ expect(result).toEqual(output);

it('should only format arrays', () => {
it('should only format arrays', async () => {
// Given

@@ -183,3 +183,3 @@ const input = [

// When
result = formatTagsTypes(input, options, 4);
result = await formatTagsTypes(input, options, 4);
// Then

@@ -189,3 +189,3 @@ expect(result).toEqual(output);

it("shouldn't format anything", () => {
it("shouldn't format anything", async () => {
// Given

@@ -233,3 +233,3 @@ const input = [

// When
result = formatTagsTypes(input, options, 2);
result = await formatTagsTypes(input, options, 2);
// Then

@@ -236,0 +236,0 @@ expect(result).toEqual(output);

@@ -12,3 +12,3 @@ jest.unmock('../../../src/fns/formatTypeAsCode');

it('should ignore a basic type', () => {
it('should ignore a basic type', async () => {
// Given

@@ -19,3 +19,3 @@ const input = 'string';

// When
result = formatTypeAsCode(input, {}, 0);
result = await formatTypeAsCode(input, {}, 0);
// Then

@@ -26,3 +26,3 @@ expect(result).toEqual(output);

it('should call prettier for a complex type', () => {
it('should call prettier for a complex type', async () => {
// Given

@@ -42,3 +42,3 @@ const prettierResponse = 'prettier-response';

// When
result = formatTypeAsCode(input, options, 0);
result = await formatTypeAsCode(input, options, 0);
// Then

@@ -54,3 +54,3 @@ expect(result).toEqual(output);

it('should return the original type if prettier throws an error', () => {
it('should return the original type if prettier throws an error', async () => {
// Given

@@ -69,3 +69,3 @@ format.mockImplementationOnce(() => {

// When
result = formatTypeAsCode(input, options, 2);
result = await formatTypeAsCode(input, options, 2);
// Then

@@ -72,0 +72,0 @@ expect(result).toEqual(output);

jest.mock('comment-parser');
jest.mock('prettier/parser-babel');
jest.mock('prettier/parser-flow');
jest.mock('prettier/parser-typescript');
jest.mock('prettier/parser-babel', () => ({
parsers: {
babel: {
parse: jest.fn(),
},
'babel-flow': {
parse: jest.fn(),
},
'babel-ts': {
parse: jest.fn(),
},
},
}));
jest.mock('prettier/parser-flow', () => ({
parsers: {
flow: {
parse: jest.fn(),
},
},
}));
jest.mock('prettier/parser-typescript', () => ({
parsers: {
typescript: {
parse: jest.fn(),
},
},
}));
jest.unmock('../../../src/fns/getParsers');

@@ -35,3 +59,3 @@

it("shouldn't do anything if there are no comments on the AST", () => {
it("shouldn't do anything if there are no comments on the AST", async () => {
// Given

@@ -80,9 +104,11 @@ const astBase = {

sut = getParsers();
parsersToTest.forEach((info) => {
sut[info.name].parse(text, parsers, options);
expect(info.ast).toEqual(astBase);
});
await Promise.all(
parsersToTest.map(async (info) => {
await sut[info.name].parse(text, parsers, options);
expect(info.ast).toEqual(astBase);
}),
);
});
it("shouldn't do anything if the plugin is disabled", () => {
it("shouldn't do anything if the plugin is disabled", async () => {
// Given

@@ -143,9 +169,11 @@ const commentStr = '*\n * @typedef {string} MyStr\n ';

sut = getParsers();
parsersToTest.forEach((info) => {
sut[info.name].parse(text, parsers, options);
expect(info.ast).toEqual(astBase);
});
await Promise.all(
parsersToTest.map(async (info) => {
await sut[info.name].parse(text, parsers, options);
expect(info.ast).toEqual(astBase);
}),
);
});
it("shouldn't do anything if the plugin is being extended", () => {
it("shouldn't do anything if the plugin is being extended", async () => {
// Given

@@ -207,9 +235,11 @@ const commentStr = '*\n * @typedef {string} MyStr\n ';

sut = getParsers(true);
parsersToTest.forEach((info) => {
sut[info.name].parse(text, parsers, options);
expect(info.ast).toEqual(astBase);
});
await Promise.all(
parsersToTest.map(async (info) => {
await sut[info.name].parse(text, parsers, options);
expect(info.ast).toEqual(astBase);
}),
);
});
it('should render a comment', () => {
it('should ignore comment with @prettierignore', async () => {
// Given

@@ -267,3 +297,3 @@ const commentStr = '*\n * @typedef {string} MyStr\n ';

sut = getParsers();
sut.typescript.parse(text, parsers, options);
await sut.typescript.parse(text, parsers, options);
// Then

@@ -306,4 +336,64 @@ expect(ast).toEqual({

it('should render an inline comment', () => {
it('should render a comment', async () => {
// Given
const commentStr = '*\n * @typedef {string} MyStr\n * @prettierignore\n ';
const column = 2;
const astBase = {
comments: [
{
type: 'CommentBlock',
value: commentStr,
loc: {
start: {
column,
},
},
},
],
};
const ast = R.clone(astBase);
const tagsList = [
{
tag: 'typedef',
type: 'string',
name: 'MyStr',
description: '',
},
{
tag: 'prettierignore',
description: '',
},
];
const parsed = [
{
description: '',
tags: tagsList,
},
];
commentParser.mockImplementationOnce(() => parsed);
const formatTagsTypesRest = jest.fn((tags) => tags);
formatTagsTypes.mockImplementationOnce(() => formatTagsTypesRest);
const formatTagsRest = jest.fn((tags) => tags);
formatTags.mockImplementationOnce(() => formatTagsRest);
const formatDescriptionRest = jest.fn((tags) => tags);
formatDescription.mockImplementationOnce(() => formatDescriptionRest);
const prepareTagsRest = jest.fn((tags) => tags);
prepareTags.mockImplementationOnce(() => prepareTagsRest);
tsParser.parsers.typescript.parse.mockImplementationOnce(() => ast);
const text = 'lorem ipsum';
const parsers = ['ts'];
const options = {
jsdocPluginEnabled: true,
printWidth: 80,
};
let sut = null;
// When
sut = getParsers();
await sut.typescript.parse(text, parsers, options);
// Then
expect(ast).toEqual(astBase);
});
it('should render an inline comment', async () => {
// Given
const commentStr = '*\n * @type {MyStr}\n ';

@@ -362,3 +452,3 @@ const column = 2;

sut = getParsers();
sut['babel-flow'].parse(text, parsers, options);
await sut['babel-flow'].parse(text, parsers, options);
// Then

@@ -380,3 +470,3 @@ expect(ast).toEqual({

it('should fix a tag without a space between name and type', () => {
it('should fix a tag without a space between name and type', async () => {
// Given

@@ -434,3 +524,3 @@ const commentStr = '*\n * @typedef{string} MyStr\n ';

sut = getParsers();
sut.typescript.parse(text, parsers, options);
await sut.typescript.parse(text, parsers, options);
// Then

@@ -437,0 +527,0 @@ expect(ast).toEqual({

@@ -1,4 +0,1 @@

jest.mock('../../../src/fns/getLanguages', () => ({
getLanguages: () => 'languages',
}));
jest.mock('../../../src/fns/getParsers', () => ({

@@ -16,6 +13,24 @@ getParsers: () => 'parsers',

describe('getPlugin', () => {
it('should generate the plugin main exports', () => {
// Given/When/Then
expect(getPlugin()).toEqual({
languages: 'languages',
it('should generate the plugin main exports', async () => {
// Given/When
const result = await getPlugin();
// Then
expect(result).toEqual({
languages: expect.arrayContaining([
expect.objectContaining({
name: 'JavaScript',
}),
expect.objectContaining({
name: 'JSX',
}),
expect.objectContaining({
name: 'TypeScript',
}),
expect.objectContaining({
name: 'TSX',
}),
expect.objectContaining({
name: 'Flow',
}),
]),
options: 'options',

@@ -22,0 +37,0 @@ defaultOptions: 'defaultOptions',

@@ -12,3 +12,3 @@ jest.unmock('../../../src/fns/prepareExampleTag');

it("should ignore a tag that's not @example", () => {
it("should ignore a tag that's not @example", async () => {
// Given

@@ -23,3 +23,3 @@ const input = {

// When
result = prepareExampleTag(input, {}, 0);
result = await prepareExampleTag(input, {}, 0);
// Then

@@ -30,3 +30,3 @@ expect(result).toEqual(output);

it('should call prettier for an example tag', () => {
it('should call prettier for an example tag', async () => {
// Given

@@ -55,3 +55,3 @@ const prettierResponse = 'prettier-response';

// When
result = prepareExampleTag(input, options, 2);
result = await prepareExampleTag(input, options, 2);
// Then

@@ -66,3 +66,3 @@ expect(result).toEqual(output);

it('should indent formatted text', () => {
it('should indent formatted text', async () => {
// Given

@@ -91,3 +91,3 @@ const prettierResponse = 'prettier-response';

// When
result = prepareExampleTag(input, options, 2);
result = await prepareExampleTag(input, options, 2);
// Then

@@ -102,3 +102,3 @@ expect(result).toEqual(output);

it('should indent unformatted text', () => {
it('should indent unformatted text', async () => {
// Given

@@ -128,3 +128,3 @@ format.mockImplementationOnce(() => {

// When
result = prepareExampleTag(input, options, 0);
result = await prepareExampleTag(input, options, 0);
// Then

@@ -139,3 +139,3 @@ expect(result).toEqual(output);

it('should detect an example caption', () => {
it('should detect an example caption', async () => {
// Given

@@ -165,3 +165,3 @@ const prettierResponse = 'prettier-response';

// When
result = prepareExampleTag(input, options, 0);
result = await prepareExampleTag(input, options, 0);
// Then

@@ -176,3 +176,3 @@ expect(result).toEqual(output);

it('should detect multiple captions', () => {
it('should detect multiple captions', async () => {
// Given

@@ -210,3 +210,3 @@ const prettierResponse = 'prettier-response';

// When
result = prepareExampleTag(input, options, 0);
result = await prepareExampleTag(input, options, 0);
// Then

@@ -225,3 +225,3 @@ expect(result).toEqual(output);

it('should detect an empty example tag', () => {
it('should detect an empty example tag', async () => {
// Given

@@ -242,3 +242,3 @@ const input = {

// When
result = prepareExampleTag(input, options, 0);
result = await prepareExampleTag(input, options, 0);
// Then

@@ -245,0 +245,0 @@ expect(result).toEqual(output);

@@ -15,3 +15,3 @@ jest.unmock('../../../src/fns/prepareTags');

it('should prepare types and tags names on a tags list', () => {
it('should prepare types and tags names on a tags list', async () => {
// Given

@@ -52,3 +52,3 @@ const input = [

// When
result = prepareTags(input, options, 0);
result = await prepareTags(input, options, 0);
// Then

@@ -58,3 +58,3 @@ expect(result).toEqual(output);

it('should prepare examples', () => {
it('should prepare examples', async () => {
// Given

@@ -116,3 +116,3 @@ const prettierResponse = 'prettier-response';

// When
result = prepareTags(input, options, 2);
result = await prepareTags(input, options, 2);
// Then

@@ -127,3 +127,3 @@ expect(result).toEqual(output);

it('should prepare descriptions', () => {
it('should prepare descriptions', async () => {
// Given

@@ -156,3 +156,3 @@ const input = [

// When
result = prepareTags(input, options, 0);
result = await prepareTags(input, options, 0);
// Then

@@ -159,0 +159,0 @@ expect(result).toEqual(output);