Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[jest-docblock] add docblock.print() #4517

Merged
merged 9 commits into from
Sep 28, 2017
Merged

Conversation

azz
Copy link
Contributor

@azz azz commented Sep 20, 2017

Summary

Prettier is implementing a --insertPragma flag to add /** @format */ to docblock, and ideally we'd be able to augment existing docblocks rather than prepending a new one, which will break tools which only look at the first one.

Context: prettier/prettier#2865 (comment)

This PR adds a simple docblock.print() function.

docblock.print({pragmas: {flow: ''}}); 
/** @flow */

docblock.print({pragmas: {providesModule: "x/y"}, comments: "My module"});
/**
 * My module
 *
 * @providesModule x/y
 */

In practice:

const {pragmas} = docblock.parse("/** @flow */");
const updated = docblock.print({pragmas: {...pragmas, format: ''}});
/**
 * @flow
 * @format
 */

Test plan

Unit tests are covering most cases are included.

@cpojer
Copy link
Member

cpojer commented Sep 20, 2017

I like it.

@codecov-io
Copy link

codecov-io commented Sep 20, 2017

Codecov Report

Merging #4517 into master will increase coverage by 0.12%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #4517      +/-   ##
==========================================
+ Coverage   56.01%   56.14%   +0.12%     
==========================================
  Files         185      185              
  Lines        6264     6282      +18     
  Branches        3        3              
==========================================
+ Hits         3509     3527      +18     
  Misses       2754     2754              
  Partials        1        1
Impacted Files Coverage Δ
packages/jest-haste-map/src/worker.js 93.75% <ø> (ø) ⬆️
packages/jest-runner/src/run_test.js 2.22% <ø> (ø) ⬆️
packages/jest-docblock/src/index.js 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9e3c423...12a25b5. Read the comment docs.


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!"))

@samouri
Copy link
Contributor

samouri commented Sep 20, 2017

@azz, this is awesome and will definitely help with implementing --prependPragma!

I have one question on it though. Wouldn't the prependPragma use-case also need to be able to extract the non-pragma portion of the docblock?

That way if the docblock in a file looks like this:

License 2017 (c) Something Inc.
@providesFruit tomatoes

we'd want to somehow be able to call:

docblock.print({ format: '', providesFruit: 'tomatoes' }, "License 2017 (c) Something Inc." );

Which would then output:

License 2017 (c) Something Inc.
@format
@providesFruit tomatoes

The options I can think of are either:

  1. create a new exported function extractWithoutPragmas
  2. make a breaking change to parse so that it instead returns { pragmas: {...}, comment: 'text' }

@@ -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

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...


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 🙂

Copy link
Member

@cpojer cpojer left a comment

Choose a reason for hiding this comment

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

See @SimenB's comments. I'll let this bake for a little longer until you guys figure out what the right way for this module is :)

@azz azz changed the title [jest-docblock]: add docblock.print() [WIP] [jest-docblock] add docblock.print() Sep 21, 2017
@azz
Copy link
Contributor Author

azz commented Sep 21, 2017

I've added a new function, parseWithComments with the signature:

parseWithComments(docblock: string): { comments: string, pragmas: {[key: string]: string} }

How does that sound?

Still WIP - need to address the EOL comments and add more test cases.

@azz azz changed the title [WIP] [jest-docblock] add docblock.print() [jest-docblock] add docblock.print() Sep 21, 2017
}

exports.extract = extract;
exports.parse = parse;
export default {extract, parse, parseWithComments, print};
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was required for existing code that does import docblock from 'jest-docblock' to work without changes.

@SimenB should I leave this here or update the existing imports?

Copy link
Member

Choose a reason for hiding this comment

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

Either way works for me. @cpojer thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

Fine to make a breaking change here, I'll publish 21.2 tomorrow or so, and for minor releases we can break the boundaries between Jest's modules.

@samouri
Copy link
Contributor

samouri commented Sep 21, 2017

The parseWithComments signature looks good! It even seems like it could be the default behavior for parse.

@azz
Copy link
Contributor Author

azz commented Sep 21, 2017

Only reason I didn't do that is it would be a breaking change. @cpojer What do you prefer?

BREAKING CHANGE: Changes jest-docblock to an ES module without a default export,
requires `import * as docblock from 'jest-docbloc'`
os.EOL +
' */';
expect(docblock.parseWithComments(code)).toEqual({
comments: 'hello' + os.EOL + os.EOL + 'world',
Copy link
Contributor

@samouri samouri Sep 22, 2017

Choose a reason for hiding this comment

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

With respect to this case of:

/**
 * hello 
 * @flow yes
 *
 * world
 */

I'd expect the result of parseWithComments to only have a single EOL between the hello and world like:

{ 
  comments: 'hello' + os.EOL + 'world',
  pragmas { flow: 'yes' }
}

Copy link
Contributor

Choose a reason for hiding this comment

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

I modified the test case here to show what I mean: https://github.com/azz/jest/pull/1/files

Copy link
Contributor Author

@azz azz Sep 23, 2017

Choose a reason for hiding this comment

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

This was actually intended. Because we'll be reprinting comments above pragmas, it made sense to me that:

/**
 * My module does special snowflake
 * thing x really well.
 * @flow
 *
 * Copyright (c) 1234 Some Guy
 */

print(parseWithComments(text)) to reformat to:

/**
 * My module does special snowflake
 * thing x really well.
 *
 * Copyright (c) 1234 Some Guy
 *
 * @flow
 */

@azz
Copy link
Contributor Author

azz commented Sep 27, 2017

Best merge conflict ever.

@cpojer cpojer merged commit 80bd4cd into jestjs:master Sep 28, 2017
@cpojer
Copy link
Member

cpojer commented Sep 28, 2017

Published jest@test for you guys to use this stuff in prettier.

@azz azz deleted the docblock-print branch September 30, 2017 02:35
tabrindle pushed a commit to tabrindle/jest that referenced this pull request Oct 2, 2017
* [jest-docblock]: add docblock.print()

* Add missing flow type, clean up

* Fix docs typo

* Fix doc typo

* [WIP] add docblock.parseWithComments()

* Detect newline character, consolidate API

* Fixup types

* Remove default export from jest-docblock

BREAKING CHANGE: Changes jest-docblock to an ES module without a default export,
requires `import * as docblock from 'jest-docbloc'`
@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants