Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion packages/jest-docblock/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Pragmas can also take arguments:
`jest-docblock` can:
* extract the docblock from some code as a string
* parse a docblock string's pragmas into an object
* print an object and some comments back to a string

## Installation
```sh
Expand All @@ -56,13 +57,15 @@ const code = `
}
`;

const { extract, parse } = require("jest-docblock");
const { extract, parse, print } = require("jest-docblock");

const docblock = extract(code);
console.log(docblock); // "/**\n * Everything is awesome!\n * \n * @everything is:awesome\n * @flow\n */"

const pragmas = parse(docblock);
console.log(pragmas); // { everything: "is:awesome", flow: "" }

console.log(print(pragmas), "hi!") // /**\n * hi!\n *\n * @everything is:awesome\n * @flow\n */;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be

console.log(print(pragmas, "hi!"))

```

## API Documentation
Expand All @@ -72,3 +75,6 @@ Extracts a docblock from some file contents. Returns the docblock contained in `

### `parse(docblock: string): {[key: string]: string}`
Parses the pragmas in a docblock string into an object whose keys are the pragma tags and whose values are the arguments to those pragmas.

### `print(object: {[key: string]: string}, comments?: string): string`
Prints an object of key-value pairs back into a docblock. If `comments` are provided, they will be positioned on the top of the docblock.
76 changes: 76 additions & 0 deletions packages/jest-docblock/src/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,4 +213,80 @@ describe('docblock', () => {
providesModule: 'apple/banana',
});
});

it('prints docblocks with no keys as empty string', () => {
const object = {};
expect(docblock.print(object)).toEqual('');
});

it('prints docblocks with one key on one line', () => {
const object = {flow: ''};
expect(docblock.print(object)).toEqual('/** @flow */');
});

it('prints docblocks with multiple keys on multiple lines', () => {
const object = {
flow: '',
format: '',
};
expect(docblock.print(object)).toEqual(
'/**' + os.EOL + ' * @flow' + os.EOL + ' * @format' + os.EOL + ' */',
);
});

it('prints docblocks with values', () => {
const object = {
flow: 'foo',
providesModule: 'x/y/z',
};
expect(docblock.print(object)).toEqual(
'/**' +
os.EOL +
' * @flow foo' +
os.EOL +
' * @providesModule x/y/z' +
os.EOL +
' */',
);
});

it('prints docblocks with comments', () => {
const object = {flow: 'foo'};
const comments = 'hello';
expect(docblock.print(object, comments)).toEqual(
'/**' +
os.EOL +
' * hello' +
os.EOL +
' *' +
os.EOL +
' * @flow foo' +
os.EOL +
' */',
);
});

it('prints docblocks with comments and no keys', () => {
const object = {};
const comments = 'Copyright 2004-present Facebook. All Rights Reserved.';
expect(docblock.print(object, comments)).toEqual(
'/**' + os.EOL + ' * ' + comments + os.EOL + ' */',
);
});

it('prints docblocks with multiline comments', () => {
const object = {};
const comments = 'hello' + os.EOL + 'world';
expect(docblock.print(object, comments)).toEqual(
'/**' + os.EOL + ' * hello' + os.EOL + ' * world' + os.EOL + ' */',
);
});

it('prints docblocks that are parseable', () => {
const object = {a: 'b', c: ''};
const comments = 'hello world!';
const formatted = docblock.print(object, comments);
const parsed = docblock.parse(formatted);
expect(parsed).toEqual(object);
});
});
47 changes: 47 additions & 0 deletions packages/jest-docblock/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* @flow
*/

const os = require('os');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should use import


const commentEndRe = /\*\/$/;
const commentStartRe = /^\/\*\*/;
const docblockRe = /^\s*(\/\*\*?(.|\r?\n)*?\*\/)/;
Expand Down Expand Up @@ -47,5 +49,50 @@ function parse(docblock: string): {[key: string]: string} {
return result;
}

function print(
object: {[key: string]: string} = {},
comments: string = '',
): string {
const head = '/**';
const start = ' *';
const tail = ' */';

const keys = Object.keys(object);
const line = os.EOL;

const printedObject = keys
.map(key => start + ' ' + printKeyValue(key, object[key]) + line)
.join('');

if (!comments) {
if (keys.length === 0) {
return '';
}
if (keys.length === 1) {
return `${head} ${printKeyValue(keys[0], object[keys[0]])}${tail}`;
}
}

const printedComments =
comments
.split(os.EOL)
Copy link
Member

@SimenB SimenB Sep 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we detect the original EOL in the comment instead (https://www.npmjs.com/package/detect-newline)? People might use LF even if they're on Windows (e.g. airbnb eslint config requires LF regardless of OS)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I do the same for the existing parse, which has a hard-coded \n?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that makes sense, yeah 🙂

.map(textLine => `${start} ${textLine}`)
.join(os.EOL) + os.EOL;

return (
head +
line +
(comments ? printedComments : '') +
(comments && keys.length ? start + line : '') +
printedObject +
tail
);
}

function printKeyValue(key, value) {
return `@${key} ${value}`.trim();
}

exports.extract = extract;
exports.parse = parse;
exports.print = print;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these can probably be separate export functions. Not sure why I didn't convert them in my PR for ESM exports...